From 16c0bfa0f5855ce030239b14a9b1b806b5447cd6 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Fri, 1 Jan 2016 17:31:24 -0600 Subject: [PATCH 001/185] Better __eq__ for triangular module morphisms. --- .../combinat/ncsf_qsym/generic_basis_code.py | 22 ++++ src/sage/modules/with_basis/morphism.py | 112 +++++++++++++++++- 2 files changed, 131 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/ncsf_qsym/generic_basis_code.py b/src/sage/combinat/ncsf_qsym/generic_basis_code.py index ea514d73de7..6431936c8af 100644 --- a/src/sage/combinat/ncsf_qsym/generic_basis_code.py +++ b/src/sage/combinat/ncsf_qsym/generic_basis_code.py @@ -1082,6 +1082,28 @@ def __init__(self, domain, on_generators, position = 0, codomain = None, categor self._on_generators = on_generators ModuleMorphismByLinearity.__init__(self, domain = domain, codomain = codomain, position = position, category = category) + def __eq__(self, other): + """ + Check equality. + + EXAMPLES:: + + sage: Psi = NonCommutativeSymmetricFunctions(QQ).Psi() + sage: Phi = NonCommutativeSymmetricFunctions(QQ).Phi() + sage: f = Psi.algebra_morphism(Phi.antipode_on_generators, codomain=Phi) + sage: g = Psi.algebra_morphism(Phi.antipode_on_generators, codomain=Phi) + sage: f == g + True + sage: f is g + False + """ + return (self.__class__ is other.__class__ and self.parent() == other.parent() + and self._zero == other._zero + and self._on_generators == other._on_generators + and self._position == other._position + and self._is_module_with_basis_over_same_base_ring + == other._is_module_with_basis_over_same_base_ring) + def _on_basis(self, c): r""" Computes the image of this morphism on the basis element indexed by diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index 17f1d211f2f..d344695dbef 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -107,7 +107,7 @@ from sage.categories.fields import Fields from sage.categories.modules import Modules from sage.misc.misc import attrcall -from sage.misc.cachefunc import cached_method, cached_function +#from sage.misc.cachefunc import cached_method, cached_function # The identity function would deserve a more canonical location from sage.misc.c3_controlled import identity from sage.misc.superseded import deprecated_function_alias, deprecation @@ -318,6 +318,8 @@ def __init__(self, domain, on_basis=None, codomain=None, category=None, def __eq__(self, other): """ + Check equality. + EXAMPLES:: sage: X = CombinatorialFreeModule(ZZ, [-2, -1, 1, 2]) @@ -330,8 +332,11 @@ def __eq__(self, other): sage: f == g, f == h1, f == h2, f == h3, f == 1, 1 == f (True, False, False, False, False, False) """ - return self.__class__ is other.__class__ and parent(self) == parent(other) and self.__dict__ == other.__dict__ - + return (self.__class__ is other.__class__ and parent(self) == parent(other) + and self._zero == other._zero and self._on_basis == other._on_basis + and self._position == other._position + and self._is_module_with_basis_over_same_base_ring + == other._is_module_with_basis_over_same_base_ring) def on_basis(self): """ @@ -676,6 +681,42 @@ def __init__(self, triangular="upper", unitriangular=False, invertible = True self._invertible=invertible + def __eq__(self, other): + """ + Check equality. + + EXAMPLES:: + + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() + sage: def ut(i): return (x[1] + x[2] if i == 1 else x[2] + (x[3] if i == 3 else 0)) + sage: perm = [0, 2, 1, 3] + sage: our_cmp = lambda a, b: cmp(perm[a], perm[b]) + sage: phi = X.module_morphism(ut, triangular="upper", codomain=X, + ....: cmp=our_cmp) + sage: def ut2(i): return (x[1] + 7*x[2] if i == 1 else x[2] + (x[3] if i == 3 else 0)) + sage: phi2 = X.module_morphism(ut2, triangular="upper", codomain=X, + ....: cmp=our_cmp) + sage: def lt(i): return (x[1] + x[2] + x[3] if i == 2 else x[i]) + sage: psi = X.module_morphism(lt, triangular="lower", codomain=X, + ....: cmp=our_cmp) + sage: phi == phi + True + sage: phi == phi2 + False + sage: from sage.modules.with_basis.morphism import TriangularModuleMorphism + sage: TriangularModuleMorphism.__eq__(phi, phi2) # I don't like this :/ + True + sage: phi == psi + False + """ + return (self.__class__ is other.__class__ and self.parent() == other.parent() + and self._triangular == other._triangular + and self._unitriangular == other._unitriangular + and self._inverse_on_support == other._inverse_on_support + and self._invertible == other._invertible + and self._dominant_item == other._dominant_item + and self._cmp == other._cmp) + def _test_triangular(self, **options): """ Test that ``self`` is actually triangular @@ -1137,6 +1178,23 @@ def __init__(self, domain, on_basis, codomain=None, category=None, **keywords): domain=domain, codomain=codomain, category=category) TriangularModuleMorphism.__init__(self, **keywords) + def __eq__(self, other): + """ + Check equality. + + EXAMPLES:: + + sage: X = CombinatorialFreeModule(QQ, ZZ) + sage: from sage.modules.with_basis.morphism import TriangularModuleMorphismByLinearity + sage: def on_basis(i): return X.sum_of_monomials(range(i-2,i+1)) + sage: phi = TriangularModuleMorphismByLinearity( + ....: X, on_basis=on_basis, codomain=X) + sage: phi == phi + True + """ + return (ModuleMorphismByLinearity.__eq__(self, other) + and TriangularModuleMorphism.__eq__(self, other)) + class TriangularModuleMorphismFromFunction(ModuleMorphismFromFunction, TriangularModuleMorphism): r""" A concrete class for triangular module morphisms implemented by a function. @@ -1293,6 +1351,35 @@ def __init__(self, domain, matrix, codomain=None, category=None, side="left"): domain=domain, codomain=codomain, category=category) + def __eq__(self, other): + """ + Check equality. + + EXAMPLES:: + + sage: from sage.modules.with_basis.morphism import ModuleMorphismFromMatrix + sage: X = CombinatorialFreeModule(ZZ, [1,2]); X.rename("X"); x = X.basis() + sage: Y = CombinatorialFreeModule(ZZ, [3,4]); Y.rename("Y"); y = Y.basis() + sage: m = matrix([[1,2],[3,5]]) + sage: phi = ModuleMorphismFromMatrix(matrix=m, domain=X, codomain=Y, side="right") + sage: phi2 = ModuleMorphismFromMatrix(matrix=m, domain=X, codomain=Y, side="right") + sage: phi == phi2 + True + sage: phi is phi2 + False + sage: m2 = matrix([[1,2],[4,5]]) + sage: phi2 = ModuleMorphismFromMatrix(matrix=m2, domain=X, codomain=Y, side="right") + sage: phi == phi2 + False + """ + # We skip the on_basis check since the matrix defines the morphism + return (self.__class__ is other.__class__ and parent(self) == parent(other) + and self._zero == other._zero + and self._position == other._position + and self._is_module_with_basis_over_same_base_ring + == other._is_module_with_basis_over_same_base_ring + and self._matrix == other._matrix) + class DiagonalModuleMorphism(ModuleMorphismByLinearity): r""" A class for diagonal module morphisms. @@ -1358,6 +1445,23 @@ def __init__(self, domain, diagonal, codomain=None, category=None): self, domain=domain, codomain=codomain, category=category) self._diagonal=diagonal + def __eq__(self, other): + """ + Check equality. + + EXAMPLES:: + + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") + sage: phi = X.module_morphism(diagonal=factorial, codomain=X) + sage: psi = X.module_morphism(diagonal=factorial, codomain=X) + sage: phi == psi + True + sage: phi is psi + False + """ + return (ModuleMorphismByLinearity.__eq__(self, other) + and self._diagonal == other._diagonal) + def _on_basis(self, i): """ Return the image by ``self`` of the basis element indexed by ``i``. @@ -1446,6 +1550,8 @@ class PointwiseInverseFunction(SageObject): def __eq__(self, other): """ + Check equality. + TESTS:: sage: from sage.modules.with_basis.morphism import PointwiseInverseFunction From f8a1bbb2cade40a8d21cc43d35db6ec5bd1c922f Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Tue, 19 Jul 2016 15:28:07 -0500 Subject: [PATCH 002/185] Use a_realization() instead of realizations()[0]. --- src/sage/categories/sets_cat.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/sage/categories/sets_cat.py b/src/sage/categories/sets_cat.py index 30c0b2b6af2..92d346a7e63 100644 --- a/src/sage/categories/sets_cat.py +++ b/src/sage/categories/sets_cat.py @@ -2639,8 +2639,18 @@ def _an_element_(self): The subset algebra of {1, 2, 3} over Rational Field sage: A.an_element() # indirect doctest F[{}] + 2*F[{1}] + 3*F[{2}] + F[{1, 2}] + + TESTS: + + 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_() + 2*E[0] + 2*E[1] + 3*E[2] """ - return self.realizations()[0].an_element() + return self.a_realization().an_element() # TODO: maybe this could be taken care of by Sets.Facade()? def __contains__(self, x): From 777b4ecbc01082cf18062e6aefdfb678d6d13194 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Sun, 24 Jul 2016 19:43:40 -0400 Subject: [PATCH 003/185] Trac 21087: make sip a new style package --- build/pkgs/sip/SPKG.txt | 15 +++++++++++++++ build/pkgs/sip/checksums.ini | 4 ++++ build/pkgs/sip/dependencies | 5 +++++ build/pkgs/sip/package-version.txt | 1 + build/pkgs/sip/spkg-install | 12 ++++++++++++ build/pkgs/sip/type | 1 + 6 files changed, 38 insertions(+) create mode 100644 build/pkgs/sip/SPKG.txt create mode 100644 build/pkgs/sip/checksums.ini create mode 100644 build/pkgs/sip/dependencies create mode 100644 build/pkgs/sip/package-version.txt create mode 100755 build/pkgs/sip/spkg-install create mode 100644 build/pkgs/sip/type diff --git a/build/pkgs/sip/SPKG.txt b/build/pkgs/sip/SPKG.txt new file mode 100644 index 00000000000..f45ebd1c93d --- /dev/null +++ b/build/pkgs/sip/SPKG.txt @@ -0,0 +1,15 @@ += SIP = + +== Description == + +Python extension module generator for C and C++ libraries + +== Upstream contact == + + https://www.riverbankcomputing.com/software/sip/ + https://pypi.python.org/pypi/SIP + +== License == + + SIP is copyright (c) Riverbank Computing Limited. Its homepage is + https://www.riverbankcomputing.com/software/sip/. diff --git a/build/pkgs/sip/checksums.ini b/build/pkgs/sip/checksums.ini new file mode 100644 index 00000000000..af0fdce5737 --- /dev/null +++ b/build/pkgs/sip/checksums.ini @@ -0,0 +1,4 @@ +tarball=sip-VERSION.tar.gz +sha1=6704854bc684de3b76c9db61ce54a74e7de5cf45 +md5=78724bf2a79878201c3bc81a1d8248ea +cksum=429231662 diff --git a/build/pkgs/sip/dependencies b/build/pkgs/sip/dependencies new file mode 100644 index 00000000000..304d0c987a2 --- /dev/null +++ b/build/pkgs/sip/dependencies @@ -0,0 +1,5 @@ +$(PYTHON) + +---------- +All lines of this file are ignored except the first. +It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sip/package-version.txt b/build/pkgs/sip/package-version.txt new file mode 100644 index 00000000000..fdaefe3468b --- /dev/null +++ b/build/pkgs/sip/package-version.txt @@ -0,0 +1 @@ +4.18 diff --git a/build/pkgs/sip/spkg-install b/build/pkgs/sip/spkg-install new file mode 100755 index 00000000000..dc9729498e6 --- /dev/null +++ b/build/pkgs/sip/spkg-install @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +if [ -z "$SAGE_LOCAL" ]; then + echo >&2 "Error: SAGE_LOCAL undefined - exiting..." + echo >&2 "Maybe run 'sage -sh'?" + exit 1 +fi + +cd src/ +python configure.py +make +make install diff --git a/build/pkgs/sip/type b/build/pkgs/sip/type new file mode 100644 index 00000000000..134d9bc32d5 --- /dev/null +++ b/build/pkgs/sip/type @@ -0,0 +1 @@ +optional From 19315aea3ab8819dfdd29467c2b46ad565f46f29 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Mon, 25 Jul 2016 14:10:33 -0400 Subject: [PATCH 004/185] Trac 21087: cleaner spkg-install --- build/pkgs/sip/spkg-install | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/build/pkgs/sip/spkg-install b/build/pkgs/sip/spkg-install index dc9729498e6..63107d871d1 100755 --- a/build/pkgs/sip/spkg-install +++ b/build/pkgs/sip/spkg-install @@ -1,12 +1,30 @@ #!/usr/bin/env bash -if [ -z "$SAGE_LOCAL" ]; then +if [ -z "${SAGE_LOCAL}" ]; then echo >&2 "Error: SAGE_LOCAL undefined - exiting..." echo >&2 "Maybe run 'sage -sh'?" exit 1 fi cd src/ + python configure.py -make -make install +if [ $? -ne 0 ] +then + echo "Configuration of sip failed" + exit 1 +fi + +${MAKE} +if [ $? -ne 0 ] +then + echo "Build of sip failed" + exit 1 +fi + +${MAKE} install +if [ $? -ne 0 ] +then + echo "Installation of sip failed" + exit 1 +fi From 65d256162e1c6e8daa295bd3028cc6632d0198cf Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Tue, 26 Jul 2016 12:07:46 -0400 Subject: [PATCH 005/185] Trac 21087: tab -> 4 spaces --- build/pkgs/sip/spkg-install | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build/pkgs/sip/spkg-install b/build/pkgs/sip/spkg-install index 63107d871d1..82921ef4910 100755 --- a/build/pkgs/sip/spkg-install +++ b/build/pkgs/sip/spkg-install @@ -11,20 +11,20 @@ cd src/ python configure.py if [ $? -ne 0 ] then - echo "Configuration of sip failed" - exit 1 + echo "Configuration of sip failed" + exit 1 fi ${MAKE} if [ $? -ne 0 ] then - echo "Build of sip failed" - exit 1 + echo "Build of sip failed" +exit 1 fi ${MAKE} install if [ $? -ne 0 ] then - echo "Installation of sip failed" - exit 1 + echo "Installation of sip failed" + exit 1 fi From e9e59a508de9975ff2083d98714bde6e6b250246 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Tue, 26 Jul 2016 12:07:59 -0400 Subject: [PATCH 006/185] Trac 21087: license information --- build/pkgs/sip/SPKG.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/pkgs/sip/SPKG.txt b/build/pkgs/sip/SPKG.txt index f45ebd1c93d..d253236fc9b 100644 --- a/build/pkgs/sip/SPKG.txt +++ b/build/pkgs/sip/SPKG.txt @@ -11,5 +11,8 @@ Python extension module generator for C and C++ libraries == License == + SIP is released under the GPL v2, GPL v3 licenses, and under a license + similar to the BSD license. + SIP is copyright (c) Riverbank Computing Limited. Its homepage is https://www.riverbankcomputing.com/software/sip/. From 2884837b51b874cf4630fbf593df642f30733b6c Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Tue, 25 Oct 2016 23:32:41 +0200 Subject: [PATCH 007/185] Initial packaging of curl : unconditionnal installation. --- build/pkgs/curl/SPKG.txt | 23 +++++++++++++++++++++++ build/pkgs/curl/checksums.ini | 4 ++++ build/pkgs/curl/dependencies | 5 +++++ build/pkgs/curl/package-version.txt | 1 + build/pkgs/curl/spkg-check | 4 ++++ build/pkgs/curl/spkg-install | 21 +++++++++++++++++++++ build/pkgs/curl/type | 1 + 7 files changed, 59 insertions(+) create mode 100644 build/pkgs/curl/SPKG.txt create mode 100644 build/pkgs/curl/checksums.ini create mode 100644 build/pkgs/curl/dependencies create mode 100644 build/pkgs/curl/package-version.txt create mode 100755 build/pkgs/curl/spkg-check create mode 100755 build/pkgs/curl/spkg-install create mode 100644 build/pkgs/curl/type diff --git a/build/pkgs/curl/SPKG.txt b/build/pkgs/curl/SPKG.txt new file mode 100644 index 00000000000..682d4e60574 --- /dev/null +++ b/build/pkgs/curl/SPKG.txt @@ -0,0 +1,23 @@ += curl = + +== Description == + +Multiprotocols data transfer library (and utility). + +== License == + +"MIT style license" : see file "COPYING" at the root of the source +tarball, explanations at https://curl.haxx.se/docs/copyright.html. + +== Upstream Contact == + +According to the file README at the root of the tarball, contact is +done by mailing https://curl.haxx.se/mail/ + +== Dependencies == + +None listed. + +== Special Update/Build Instructions == + +None. diff --git a/build/pkgs/curl/checksums.ini b/build/pkgs/curl/checksums.ini new file mode 100644 index 00000000000..4075aaaa452 --- /dev/null +++ b/build/pkgs/curl/checksums.ini @@ -0,0 +1,4 @@ +tarball=curl-7.50.3.tar.gz +sha1=be0065afc76a3d8568f5f78d8efddadb6310f9d7 +md5=870e16fd88a88b52e26a4f04dfc161db +cksum=2034871736 diff --git a/build/pkgs/curl/dependencies b/build/pkgs/curl/dependencies new file mode 100644 index 00000000000..3546cda4614 --- /dev/null +++ b/build/pkgs/curl/dependencies @@ -0,0 +1,5 @@ +# no dependencies + +---------- +All lines of this file are ignored except the first. +It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/curl/package-version.txt b/build/pkgs/curl/package-version.txt new file mode 100644 index 00000000000..7efeb81ee46 --- /dev/null +++ b/build/pkgs/curl/package-version.txt @@ -0,0 +1 @@ +7.50.3 diff --git a/build/pkgs/curl/spkg-check b/build/pkgs/curl/spkg-check new file mode 100755 index 00000000000..35f04fc8862 --- /dev/null +++ b/build/pkgs/curl/spkg-check @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +cd src +$MAKE check diff --git a/build/pkgs/curl/spkg-install b/build/pkgs/curl/spkg-install new file mode 100755 index 00000000000..063d76a7c15 --- /dev/null +++ b/build/pkgs/curl/spkg-install @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +cd src + +./configure --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" +if [ $? -ne 0 ]; then + echo >&2 "Error configuring curl." + exit 1 +fi + +$MAKE +if [ $? -ne 0 ]; then + echo >&2 "Error building curl." + exit 1 +fi + +$MAKE install +if [ $? -ne 0 ]; then + echo >&2 "Error installing curl." + exit 1 +fi diff --git a/build/pkgs/curl/type b/build/pkgs/curl/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/curl/type @@ -0,0 +1 @@ +standard From 1588558c94c80f698b40a6033155ebf6d78e77e7 Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Wed, 26 Oct 2016 19:07:03 +0200 Subject: [PATCH 008/185] Packaging polish. --- build/pkgs/curl/spkg-check | 2 +- build/pkgs/curl/spkg-install | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/build/pkgs/curl/spkg-check b/build/pkgs/curl/spkg-check index 35f04fc8862..5fedf7faa0f 100755 --- a/build/pkgs/curl/spkg-check +++ b/build/pkgs/curl/spkg-check @@ -1,4 +1,4 @@ #!/usr/bin/env bash cd src -$MAKE check +$MAKE check V=1 diff --git a/build/pkgs/curl/spkg-install b/build/pkgs/curl/spkg-install index 063d76a7c15..d587d7d4b93 100755 --- a/build/pkgs/curl/spkg-install +++ b/build/pkgs/curl/spkg-install @@ -1,20 +1,35 @@ #!/usr/bin/env bash +if [ -z "$SAGE_LOCAL" ] ; then + echo >&2 "Error - SAGE_LOCAL undefined ... exiting" + echo >&2 "Maybe run 'sage -sh'?" + exit 1 +fi cd src +# Patch sources. +for patch in ../patches/*.patch; do + [ -r "$patch" ] || continue # Skip non-existing or non-readable patches + patch -p1 <"$patch" + if [ $? -ne 0 ]; then + echo >&2 "Error applying '$patch'" + exit 1 + fi +done + ./configure --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" if [ $? -ne 0 ]; then echo >&2 "Error configuring curl." exit 1 fi -$MAKE +$MAKE V=1 if [ $? -ne 0 ]; then echo >&2 "Error building curl." exit 1 fi -$MAKE install +$MAKE install V=1 if [ $? -ne 0 ]; then echo >&2 "Error installing curl." exit 1 From a8d77b5c25a0f20c209f04c3a5377b673683cd6e Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Wed, 26 Oct 2016 20:47:16 +0200 Subject: [PATCH 009/185] Initial packaging of pcre : unconditionnal installation. --- build/pkgs/pcre/SPKG.txt | 21 ++++++++++++++++ build/pkgs/pcre/checksums.ini | 4 ++++ build/pkgs/pcre/dependencies | 5 ++++ build/pkgs/pcre/package-version.txt | 1 + build/pkgs/pcre/spkg-check | 4 ++++ build/pkgs/pcre/spkg-install | 37 +++++++++++++++++++++++++++++ build/pkgs/pcre/type | 1 + 7 files changed, 73 insertions(+) create mode 100644 build/pkgs/pcre/SPKG.txt create mode 100644 build/pkgs/pcre/checksums.ini create mode 100644 build/pkgs/pcre/dependencies create mode 100644 build/pkgs/pcre/package-version.txt create mode 100755 build/pkgs/pcre/spkg-check create mode 100644 build/pkgs/pcre/spkg-install create mode 100644 build/pkgs/pcre/type diff --git a/build/pkgs/pcre/SPKG.txt b/build/pkgs/pcre/SPKG.txt new file mode 100644 index 00000000000..db08f9fa9c5 --- /dev/null +++ b/build/pkgs/pcre/SPKG.txt @@ -0,0 +1,21 @@ += pcre = + +== Description == + +Perl-compatible regular expressions library. + +== License == + +BSD License ; see LICENCE (sic) at the root of the original tarball. + +== Upstream Contact == + +Mailing list at https://lists.exim.org/mailman/listinfo/pcre-dev + +== Dependencies == + +None listed. + +== Special Update/Build Instructions == + +None applicable (see README at tarball's root). diff --git a/build/pkgs/pcre/checksums.ini b/build/pkgs/pcre/checksums.ini new file mode 100644 index 00000000000..f367739cd98 --- /dev/null +++ b/build/pkgs/pcre/checksums.ini @@ -0,0 +1,4 @@ +tarball=pcre-8.39.tar.gz +sha1=b3aec1f643d9701841e2f9d57ac121a7ff448fc8 +md5=26a76d97e04c89fe9ce22ecc1cd0b315 +cksum=157808039 diff --git a/build/pkgs/pcre/dependencies b/build/pkgs/pcre/dependencies new file mode 100644 index 00000000000..e1acdc8fb49 --- /dev/null +++ b/build/pkgs/pcre/dependencies @@ -0,0 +1,5 @@ +# no dependencies + +---------- +All lines of this file are ignored except the first. +It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. \ No newline at end of file diff --git a/build/pkgs/pcre/package-version.txt b/build/pkgs/pcre/package-version.txt new file mode 100644 index 00000000000..803ed032518 --- /dev/null +++ b/build/pkgs/pcre/package-version.txt @@ -0,0 +1 @@ +8.39 diff --git a/build/pkgs/pcre/spkg-check b/build/pkgs/pcre/spkg-check new file mode 100755 index 00000000000..5fedf7faa0f --- /dev/null +++ b/build/pkgs/pcre/spkg-check @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +cd src +$MAKE check V=1 diff --git a/build/pkgs/pcre/spkg-install b/build/pkgs/pcre/spkg-install new file mode 100644 index 00000000000..06dec0f4b50 --- /dev/null +++ b/build/pkgs/pcre/spkg-install @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +if [ -z "$SAGE_LOCAL" ] ; then + echo >&2 "Error - SAGE_LOCAL undefined ... exiting" + echo >&2 "Maybe run 'sage -sh'?" + exit 1 +fi +cd src + +# Patch sources. +for patch in ../patches/*.patch; do + [ -r "$patch" ] || continue # Skip non-existing or non-readable patches + patch -p1 <"$patch" + if [ $? -ne 0 ]; then + echo >&2 "Error applying '$patch'" + exit 1 + fi +done + +./configure --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" \ + --enable-utf --enable-unicode-properties --enable-jit +if [ $? -ne 0 ]; then + echo >&2 "Error configuring pcre." + exit 1 +fi + +$MAKE V=1 +if [ $? -ne 0 ]; then + echo >&2 "Error building pcre." + exit 1 +fi + +$MAKE install V=1 +if [ $? -ne 0 ]; then + echo >&2 "Error installing pcre." + exit 1 +fi diff --git a/build/pkgs/pcre/type b/build/pkgs/pcre/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/pcre/type @@ -0,0 +1 @@ +standard From 81e3341358690d10e8ec0d14e1d7e53b8b8bf16c Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Thu, 27 Oct 2016 08:30:53 +0200 Subject: [PATCH 010/185] Removed patches handling. --- build/pkgs/curl/spkg-install | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/build/pkgs/curl/spkg-install b/build/pkgs/curl/spkg-install index d587d7d4b93..222d90f9218 100755 --- a/build/pkgs/curl/spkg-install +++ b/build/pkgs/curl/spkg-install @@ -7,16 +7,6 @@ if [ -z "$SAGE_LOCAL" ] ; then fi cd src -# Patch sources. -for patch in ../patches/*.patch; do - [ -r "$patch" ] || continue # Skip non-existing or non-readable patches - patch -p1 <"$patch" - if [ $? -ne 0 ]; then - echo >&2 "Error applying '$patch'" - exit 1 - fi -done - ./configure --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" if [ $? -ne 0 ]; then echo >&2 "Error configuring curl." From 21ce3e75574d3a08266324b7fac41e044e0ef280 Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Thu, 27 Oct 2016 08:39:33 +0200 Subject: [PATCH 011/185] Removed patches handling. --- build/pkgs/pcre/spkg-install | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/build/pkgs/pcre/spkg-install b/build/pkgs/pcre/spkg-install index 06dec0f4b50..29862b72be3 100644 --- a/build/pkgs/pcre/spkg-install +++ b/build/pkgs/pcre/spkg-install @@ -7,16 +7,6 @@ if [ -z "$SAGE_LOCAL" ] ; then fi cd src -# Patch sources. -for patch in ../patches/*.patch; do - [ -r "$patch" ] || continue # Skip non-existing or non-readable patches - patch -p1 <"$patch" - if [ $? -ne 0 ]; then - echo >&2 "Error applying '$patch'" - exit 1 - fi -done - ./configure --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" \ --enable-utf --enable-unicode-properties --enable-jit if [ $? -ne 0 ]; then From c02cb61da261e9e9b5eb960eadeede6d034f2240 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Wed, 2 Nov 2016 14:43:41 +0000 Subject: [PATCH 012/185] Update Curl to 7.51.0. --- build/pkgs/curl/checksums.ini | 8 ++++---- build/pkgs/curl/package-version.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/pkgs/curl/checksums.ini b/build/pkgs/curl/checksums.ini index 4075aaaa452..058027b2288 100644 --- a/build/pkgs/curl/checksums.ini +++ b/build/pkgs/curl/checksums.ini @@ -1,4 +1,4 @@ -tarball=curl-7.50.3.tar.gz -sha1=be0065afc76a3d8568f5f78d8efddadb6310f9d7 -md5=870e16fd88a88b52e26a4f04dfc161db -cksum=2034871736 +tarball=curl-VERSION.tar.bz2 +sha1=f02a14bbe580d2a8cf3bf45a79d39eb595220ac7 +md5=09a7c5769a7eae676d5e2c86d51f167e +cksum=1653697676 diff --git a/build/pkgs/curl/package-version.txt b/build/pkgs/curl/package-version.txt index 7efeb81ee46..a260e0b3f4f 100644 --- a/build/pkgs/curl/package-version.txt +++ b/build/pkgs/curl/package-version.txt @@ -1 +1 @@ -7.50.3 +7.51.0 From d31c5607d0f4cc3ebad13388fa9d6d630dd23c11 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Wed, 2 Nov 2016 14:43:52 +0000 Subject: [PATCH 013/185] Add a fat mode to curl. --- build/pkgs/curl/spkg-install | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/build/pkgs/curl/spkg-install b/build/pkgs/curl/spkg-install index 222d90f9218..2528aee8183 100755 --- a/build/pkgs/curl/spkg-install +++ b/build/pkgs/curl/spkg-install @@ -5,9 +5,17 @@ if [ -z "$SAGE_LOCAL" ] ; then echo >&2 "Maybe run 'sage -sh'?" exit 1 fi + cd src -./configure --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" +if [ "$SAGE_FAT_BINARY" = yes ]; then + # Let's disable a bunch of stuff which might get linked. + # SSL/TLS still depends on the compilation environment. + CURL_CONFIGURE="--disable-ldap --disable-ldaps --disable-rtsp --disable-ares --disable-crypto-auth --without-libpsl --without-libmetalink --without-libssh2 --without-librtmp --without-libidn --without-nghttp2 --without-gssapi $CURL_CONFIGURE" +fi + +./configure --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" \ + $CURL_CONFIGURE if [ $? -ne 0 ]; then echo >&2 "Error configuring curl." exit 1 From aa5fd5cb069d93c6b6ea1ad7cb99a35ea37d3d88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Tue, 15 Nov 2016 01:38:56 -0500 Subject: [PATCH 014/185] fixed typo --- src/sage/categories/homset.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/categories/homset.py b/src/sage/categories/homset.py index 089a1f74410..e3cdcd24ae0 100644 --- a/src/sage/categories/homset.py +++ b/src/sage/categories/homset.py @@ -928,8 +928,8 @@ class of ``C`` will be inherited by *all* subcategories of algebraic properties of domain and codomain, it should be implemented in ``C.MorphismMethods``. - At this point, the homset element classes takes precedence over - the morphism classes. But this may be subject to change. + At this point, the homset element classes take precedence over the + morphism classes. But this may be subject to change. .. TODO:: From 689028182d31068228562360264e86af492aadf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Tue, 15 Nov 2016 03:04:34 -0500 Subject: [PATCH 015/185] Implement is_injective as a MorphismMethod instead of implementing it in subclasses of Map. Currently, most ring homomorphism inherit from Morphism but not from RingHomomorphism so there is no good place to implement is_injective otherwise. I did not rely on a check like `f.is_one()` or `f == 1` to check whether an endomorphism is the identity morphism in `is_injective` since the one element of the monoid of endomorphisms is not correctly implemented in many places, e.g., over polynomial rings where `.one()` is the map that maps the variable to one. --- src/sage/categories/map.pyx | 15 ----- src/sage/categories/rings.py | 97 +++++++++++++++++++++++++++ src/sage/categories/sets_cat.py | 26 +++++++ src/sage/rings/function_field/maps.py | 15 ----- src/sage/rings/morphism.pyx | 18 ----- 5 files changed, 123 insertions(+), 48 deletions(-) diff --git a/src/sage/categories/map.pyx b/src/sage/categories/map.pyx index 5fd7637bc56..e5d353ea12b 100644 --- a/src/sage/categories/map.pyx +++ b/src/sage/categories/map.pyx @@ -1183,21 +1183,6 @@ cdef class Map(Element): else: return self.post_compose(connecting.__copy__()) - def is_injective(self): - """ - Tells whether the map is injective (not implemented in the base class). - - TEST:: - - sage: from sage.categories.map import Map - sage: f = Map(Hom(QQ, ZZ, Rings())) - sage: f.is_injective() - Traceback (most recent call last): - ... - NotImplementedError: - """ - raise NotImplementedError(type(self)) - def is_surjective(self): """ Tells whether the map is surjective (not implemented in the base class). diff --git a/src/sage/categories/rings.py b/src/sage/categories/rings.py index 484b8f6b202..8da38282311 100644 --- a/src/sage/categories/rings.py +++ b/src/sage/categories/rings.py @@ -58,6 +58,103 @@ class Rings(CategoryWithAxiom): _base_category_class_and_axiom = (Rngs, "Unital") + class MorphismMethods: + def is_injective(self): + """ + Return whether or not this morphism is injective. + + EXAMPLES: + + This often raises a ``NotImplementedError`` as many homomorphisms do + not implement this method:: + + sage: R. = QQ[] + sage: f = R.hom([x + 1]); f + Ring endomorphism of Univariate Polynomial Ring in x over Rational Field + Defn: x |--> x + 1 + sage: f.is_injective() + Traceback (most recent call last): + ... + NotImplementedError + + If the domain is a field, the homomorphism is injective:: + + sage: K. = FunctionField(QQ) + sage: L. = FunctionField(QQ) + sage: f = K.hom([y]); f + Function Field morphism: + From: Rational function field in x over Rational Field + To: Rational function field in y over Rational Field + Defn: x |--> y + sage: f.is_injective() + True + + Unless the codomain is the zero ring:: + + sage: codomain = Integers(1) + sage: f = K.hom([codomain(1)]); f + Function Field morphism: + From: Rational function field in x over Rational Field + To: Ring of integers modulo 1 + Defn: x |--> 0 + sage: f.is_injective() + False + + Homomorphism from rings of characteristic zero to rings of positive + characteristic can not be injective:: + + sage: R. = ZZ[] + sage: f = R.hom([GF(3)(1)]); f + Ring morphism: + From: Univariate Polynomial Ring in x over Integer Ring + To: Finite Field of size 3 + Defn: x |--> 1 + sage: f.is_injective() + False + + A morphism whose domain is an order in a number field is injective if + the codomain has characteristic zero:: + + sage: K. = FunctionField(QQ) + sage: f = ZZ.hom(K); f + Ring Coercion morphism: + From: Integer Ring + To: Rational function field in x over Rational Field + sage: f.is_injective() + True + + """ + if self.domain().is_zero(): + return True + if self.codomain().is_zero(): + # the only map to the zero ring that is injective is the map from itself + return False + + from sage.categories.fields import Fields + if self.domain() in Fields(): + # A ring homomorphism from a field to a ring is injective + # (unless the codomain is the zero ring.) Note that ring + # homomorphism must send the 1 element to the 1 element + return True + + if self.domain().characteristic() == 0: + if self.codomain().characteristic() != 0: + return False + else: + from sage.categories.integral_domains import IntegralDomains + if self.domain() in IntegralDomains(): + # if all elements of the domain are algebraic over ZZ, + # then the homomorphism must be injective (in + # particular if the domain is ZZ) + from sage.categories.number_fields import NumberFields + if self.domain().fraction_field() in NumberFields(): + return True + + if self.domain().cardinality() > self.codomain().cardinality(): + return False + + raise NotImplementedError + class SubcategoryMethods: def NoZeroDivisors(self): diff --git a/src/sage/categories/sets_cat.py b/src/sage/categories/sets_cat.py index 22b1262669d..da8262babd7 100644 --- a/src/sage/categories/sets_cat.py +++ b/src/sage/categories/sets_cat.py @@ -1734,6 +1734,32 @@ def __invert__(self): raising ``NotImplementedError`` could be provided instead. """ + def is_injective(self): + r""" + Return whether this map is injective. + + EXAMPLES:: + + sage: f = ZZ.hom(GF(3)); f + sage: f.is_injective() + False + + Note that many maps do not implement this method:: + + sage: R. = ZZ[] + sage: f = R.hom([x]) + sage: f.is_injective() + Traceback (most recent call last): + ... + NotImplementedError + + """ + if self.domain().cardinality() <= 1: + return True + if self.domain().cardinality() > self.codomain().cardinality(): + return False + raise NotImplementedError + Enumerated = LazyImport('sage.categories.enumerated_sets', 'EnumeratedSets', at_startup=True) Facade = LazyImport('sage.categories.facade_sets', 'FacadeSets') Finite = LazyImport('sage.categories.finite_sets', 'FiniteSets', at_startup=True) diff --git a/src/sage/rings/function_field/maps.py b/src/sage/rings/function_field/maps.py index 7e1a284a6b7..ca5dd6f872d 100644 --- a/src/sage/rings/function_field/maps.py +++ b/src/sage/rings/function_field/maps.py @@ -463,21 +463,6 @@ def __init__(self, parent, im_gen, base_morphism): self._im_gen = im_gen self._base_morphism = base_morphism - def is_injective(self): - """ - Returns True since homomorphisms of fields are injective. - - EXAMPLES:: - - sage: K. = FunctionField(QQ) - sage: f = K.hom(1/x); f - Function Field endomorphism of Rational function field in x over Rational Field - Defn: x |--> 1/x - sage: f.is_injective() - True - """ - return True - def _repr_type(self): r""" Return the type of this map (a morphism of function fields), for the diff --git a/src/sage/rings/morphism.pyx b/src/sage/rings/morphism.pyx index 851408e69ad..6ab55153df1 100644 --- a/src/sage/rings/morphism.pyx +++ b/src/sage/rings/morphism.pyx @@ -795,24 +795,6 @@ cdef class RingHomomorphism(RingMap): pass return sage.categories.map.Map._composition_(self, right, homset) - def is_injective(self): - """ - Return whether or not this morphism is injective, or raise - a ``NotImplementedError``. - - EXAMPLES: - - Note that currently this is not implemented in most - interesting cases:: - - sage: f = ZZ.hom(QQ) - sage: f.is_injective() - Traceback (most recent call last): - ... - NotImplementedError - """ - raise NotImplementedError - def is_zero(self): r""" Return ``True`` if this is the zero map and ``False`` otherwise. From e10a257f1179a6bc34f251d52f091aa23487e9dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Tue, 15 Nov 2016 03:37:52 -0500 Subject: [PATCH 016/185] Cache is_injective --- src/sage/categories/rings.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/categories/rings.py b/src/sage/categories/rings.py index 8da38282311..9c29d00534e 100644 --- a/src/sage/categories/rings.py +++ b/src/sage/categories/rings.py @@ -17,6 +17,7 @@ from sage.categories.rngs import Rngs from sage.structure.element import Element from functools import reduce +from sage.misc.cachefunc import cached_method class Rings(CategoryWithAxiom): """ @@ -59,6 +60,7 @@ class Rings(CategoryWithAxiom): _base_category_class_and_axiom = (Rngs, "Unital") class MorphismMethods: + @cached_method def is_injective(self): """ Return whether or not this morphism is injective. From 363ece8ce62dc8cb7a510607d0f34778adc4b74f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Tue, 15 Nov 2016 03:38:03 -0500 Subject: [PATCH 017/185] Remove redundant is_subring() implementations --- src/sage/rings/integer_ring.pyx | 19 ------------------- src/sage/rings/rational_field.py | 32 -------------------------------- src/sage/rings/ring.pyx | 11 ++++++++++- 3 files changed, 10 insertions(+), 52 deletions(-) diff --git a/src/sage/rings/integer_ring.pyx b/src/sage/rings/integer_ring.pyx index 91d64a973e4..65371b57414 100644 --- a/src/sage/rings/integer_ring.pyx +++ b/src/sage/rings/integer_ring.pyx @@ -632,25 +632,6 @@ cdef class IntegerRing_class(PrincipalIdealDomain): else: None - - def is_subring(self, other): - r""" - Return ``True`` if `\ZZ` is a subring of other in a natural way. - - Every ring of characteristic `0` contains `\ZZ` as a subring. - - EXAMPLES:: - - sage: ZZ.is_subring(QQ) - True - """ - if not ring.is_Ring(other): - raise TypeError("other must be a ring") - if other.characteristic() == 0: - return True - else: - return False - def random_element(self, x=None, y=None, distribution=None): r""" Return a random integer. diff --git a/src/sage/rings/rational_field.py b/src/sage/rings/rational_field.py index 21ca8f5344f..582980f0918 100644 --- a/src/sage/rings/rational_field.py +++ b/src/sage/rings/rational_field.py @@ -778,38 +778,6 @@ def is_absolute(self): """ return True - def is_subring(self, K): - r""" - Return ``True`` if `\QQ` is a subring of `K`. - - We are only able to determine this in some cases, e.g., when - `K` is a field or of positive characteristic. - - EXAMPLES:: - - sage: QQ.is_subring(QQ) - True - sage: QQ.is_subring(QQ['x']) - True - sage: QQ.is_subring(GF(7)) - False - sage: QQ.is_subring(CyclotomicField(7)) - True - sage: QQ.is_subring(ZZ) - False - sage: QQ.is_subring(Frac(ZZ)) - True - """ - if K.is_field(): - return K.characteristic() == 0 - if K.characteristic() != 0: - return False - try: - self.embeddings(K) - except (TypeError, ValueError): - return False - return True - def is_field(self, proof = True): """ Return ``True``, since the rational field is a field. diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index e8e0f3bb102..14289380622 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -837,7 +837,16 @@ cdef class Ring(ParentWithGens): sage: ZZ.is_subring(GF(19)) False - TESTS: + TESTS:: + + sage: QQ.is_subring(QQ['x']) + True + sage: QQ.is_subring(GF(7)) + False + sage: QQ.is_subring(CyclotomicField(7)) + True + sage: QQ.is_subring(ZZ) + False Every ring is a subring of itself, :trac:`17287`:: From 2f641e23f91a98b333ab106b69590d95a79e59e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Thu, 17 Nov 2016 19:29:02 -0500 Subject: [PATCH 018/185] Add missing doctest output --- src/sage/categories/sets_cat.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sage/categories/sets_cat.py b/src/sage/categories/sets_cat.py index da8262babd7..d7db842f012 100644 --- a/src/sage/categories/sets_cat.py +++ b/src/sage/categories/sets_cat.py @@ -1741,6 +1741,9 @@ def is_injective(self): EXAMPLES:: sage: f = ZZ.hom(GF(3)); f + Ring Coercion morphism: + From: Integer Ring + To: Finite Field of size 3 sage: f.is_injective() False From f3f468da2b05cf53b99a4af3bfa9d2736b3ea63e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Sat, 19 Nov 2016 20:32:31 -0500 Subject: [PATCH 019/185] Implement __eq__ for PointwiseInverse properly --- src/sage/modules/with_basis/morphism.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index d01d4429a94..f53134f4ff9 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -1562,6 +1562,17 @@ class PointwiseInverseFunction(SageObject): sage: f(0), f(1), f(2), f(3) (1, 1, 1/2, 1/6) """ + def __init__(self, f): + """ + TESTS:: + + sage: from sage.modules.with_basis.morphism import PointwiseInverseFunction + sage: f = PointwiseInverseFunction(factorial) + sage: f(0), f(1), f(2), f(3) + (1, 1, 1/2, 1/6) + sage: TestSuite(f).run() + """ + self._pointwise_inverse = f def __eq__(self, other): """ @@ -1577,19 +1588,7 @@ def __eq__(self, other): sage: f == g True """ - return self.__class__ is other.__class__ and self.__dict__ == other.__dict__ - - def __init__(self, f): - """ - TESTS:: - - sage: from sage.modules.with_basis.morphism import PointwiseInverseFunction - sage: f = PointwiseInverseFunction(factorial) - sage: f(0), f(1), f(2), f(3) - (1, 1, 1/2, 1/6) - sage: TestSuite(f).run() - """ - self._pointwise_inverse = f + return self.__class__ is other.__class__ and self._pointwise_inverse == other._pointwise_inverse def __call__(self, *args): """ From c6093d57c987134506027600df3cfe24e15b5172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Sat, 19 Nov 2016 22:45:06 -0500 Subject: [PATCH 020/185] Also implement __ne__ as it is not magically added from somewhere else --- src/sage/modules/with_basis/morphism.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index f53134f4ff9..c95f3bbfe28 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -1587,9 +1587,25 @@ def __eq__(self, other): False sage: f == g True + """ return self.__class__ is other.__class__ and self._pointwise_inverse == other._pointwise_inverse + def __ne__(self, other): + r""" + Return whether this function is not equal to ``other``. + + TESTS:: + + sage: from sage.modules.with_basis.morphism import PointwiseInverseFunction + sage: f = PointwiseInverseFunction(factorial) + sage: g = PointwiseInverseFunction(factorial) + sage: f != g + False + + """ + return not self == other + def __call__(self, *args): """ TESTS:: From 55ab282177ee959e276c72893bc19caeb940c60f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Sat, 19 Nov 2016 22:45:39 -0500 Subject: [PATCH 021/185] Implement _richcmp_ for ModuleMorphismByLinearity instead of __eq__, so we also get != --- src/sage/modules/with_basis/morphism.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index c95f3bbfe28..6bdf8bd92d5 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -317,11 +317,11 @@ def __init__(self, domain, on_basis=None, codomain=None, category=None, category=category, affine=(zero != codomain.zero())) - def __eq__(self, other): - """ - Check equality. + def _richcmp_(self, other, op): + r""" + Return whether this morphism and ``other`` satisfy ``op``. - EXAMPLES:: + TESTS:: sage: X = CombinatorialFreeModule(ZZ, [-2, -1, 1, 2]) sage: Y = CombinatorialFreeModule(ZZ, [1, 2]) @@ -332,12 +332,18 @@ def __eq__(self, other): sage: h3 = X.module_morphism(on_basis=Y.monomial * abs, category=Modules(ZZ)) sage: f == g, f == h1, f == h2, f == h3, f == 1, 1 == f (True, False, False, False, False, False) + """ - return (self.__class__ is other.__class__ and parent(self) == parent(other) - and self._zero == other._zero and self._on_basis == other._on_basis - and self._position == other._position - and self._is_module_with_basis_over_same_base_ring - == other._is_module_with_basis_over_same_base_ring) + if op == 2: # == + return (self.__class__ is other.__class__ + and parent(self) == parent(other) + and self._zero == other._zero + and self._on_basis == other._on_basis + and self._position == other._position + and self._is_module_with_basis_over_same_base_ring == other._is_module_with_basis_over_same_base_ring) + if op == 3: # != + return not (self == other) + raise NotImplementedError("Operator not implemented") def on_basis(self): """ From 031d86cd3b0448314c5879799153a459c4265f03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Sat, 19 Nov 2016 22:46:39 -0500 Subject: [PATCH 022/185] Implement TriangularModuleMorphism._richcmp_ instead of __eq__, so we also get !=. I also removed the _cmp comparison, I don't understand where this attribute should come from. --- src/sage/modules/with_basis/morphism.py | 42 +++++++++++++------------ 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index 6bdf8bd92d5..04bbabb597a 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -702,41 +702,43 @@ def __init__(self, triangular="upper", unitriangular=False, invertible = True self._invertible=invertible - def __eq__(self, other): - """ - Check equality. + def _richcmp_(self, other, op): + r""" + Return whether this morphism and ``other`` satisfy ``op``. - EXAMPLES:: + TESTS:: sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() sage: def ut(i): return (x[1] + x[2] if i == 1 else x[2] + (x[3] if i == 3 else 0)) sage: perm = [0, 2, 1, 3] sage: our_cmp = lambda a, b: cmp(perm[a], perm[b]) - sage: phi = X.module_morphism(ut, triangular="upper", codomain=X, - ....: cmp=our_cmp) + sage: phi = X.module_morphism(ut, triangular="upper", codomain=X, cmp=our_cmp) + doctest:warning + ... + DeprecationWarning: the 'cmp' keyword is deprecated, use 'key' instead + See http://trac.sagemath.org/21043 for details. sage: def ut2(i): return (x[1] + 7*x[2] if i == 1 else x[2] + (x[3] if i == 3 else 0)) - sage: phi2 = X.module_morphism(ut2, triangular="upper", codomain=X, - ....: cmp=our_cmp) + sage: phi2 = X.module_morphism(ut2, triangular="upper", codomain=X, cmp=our_cmp) sage: def lt(i): return (x[1] + x[2] + x[3] if i == 2 else x[i]) - sage: psi = X.module_morphism(lt, triangular="lower", codomain=X, - ....: cmp=our_cmp) + sage: psi = X.module_morphism(lt, triangular="lower", codomain=X, cmp=our_cmp) sage: phi == phi True sage: phi == phi2 False - sage: from sage.modules.with_basis.morphism import TriangularModuleMorphism - sage: TriangularModuleMorphism.__eq__(phi, phi2) # I don't like this :/ - True sage: phi == psi False + """ - return (self.__class__ is other.__class__ and self.parent() == other.parent() - and self._triangular == other._triangular - and self._unitriangular == other._unitriangular - and self._inverse_on_support == other._inverse_on_support - and self._invertible == other._invertible - and self._dominant_item == other._dominant_item - and self._cmp == other._cmp) + if op == 2: # == + return (self.__class__ is other.__class__ and self.parent() == other.parent() + and self._triangular == other._triangular + and self._unitriangular == other._unitriangular + and self._inverse_on_support == other._inverse_on_support + and self._invertible == other._invertible + and self._dominant_item == other._dominant_item) + if op == 3: # != + return not (self == other) + raise NotImplementedError("Operator not implemented") def _test_triangular(self, **options): """ From b7c99e74453d1a9c831df1615a843aa1816291d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Sat, 19 Nov 2016 22:47:17 -0500 Subject: [PATCH 023/185] Implement TriangularModuleMorphismByLinearity._richcmp_ instead of __eq__, so we also get !=. --- src/sage/modules/with_basis/morphism.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index 04bbabb597a..7b8d0cafc77 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -1201,11 +1201,11 @@ def __init__(self, domain, on_basis, codomain=None, category=None, **keywords): domain=domain, codomain=codomain, category=category) TriangularModuleMorphism.__init__(self, **keywords) - def __eq__(self, other): - """ - Check equality. + def _richcmp_(self, other, op): + r""" + Return whether this morphism and ``other`` satisfy ``op``. - EXAMPLES:: + TESTS:: sage: X = CombinatorialFreeModule(QQ, ZZ) sage: from sage.modules.with_basis.morphism import TriangularModuleMorphismByLinearity @@ -1214,9 +1214,14 @@ def __eq__(self, other): ....: X, on_basis=on_basis, codomain=X) sage: phi == phi True + """ - return (ModuleMorphismByLinearity.__eq__(self, other) - and TriangularModuleMorphism.__eq__(self, other)) + if op == 2: # == + return (ModuleMorphismByLinearity._richcmp_(self, other, op) + and TriangularModuleMorphism._richcmp_(self, other, op)) + if op == 3: # != + return not (self == other) + raise NotImplementedError("Operator not implemented") class TriangularModuleMorphismFromFunction(ModuleMorphismFromFunction, TriangularModuleMorphism): r""" From edef6c31d024e3b179e89013abe0fd69a8f44895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Sat, 19 Nov 2016 22:47:43 -0500 Subject: [PATCH 024/185] Implement ModuleMorphismFromMatrix._richcmp_ instead of __eq__, so we also get !=. --- src/sage/modules/with_basis/morphism.py | 27 +++++++++++++++---------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index 7b8d0cafc77..e9f1f96d7c8 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -1379,11 +1379,11 @@ def __init__(self, domain, matrix, codomain=None, category=None, side="left"): domain=domain, codomain=codomain, category=category) - def __eq__(self, other): - """ - Check equality. + def _richcmp_(self, other, op): + r""" + Return whether this morphism and ``other`` satisfy ``op``. - EXAMPLES:: + TESTS:: sage: from sage.modules.with_basis.morphism import ModuleMorphismFromMatrix sage: X = CombinatorialFreeModule(ZZ, [1,2]); X.rename("X"); x = X.basis() @@ -1399,14 +1399,19 @@ def __eq__(self, other): sage: phi2 = ModuleMorphismFromMatrix(matrix=m2, domain=X, codomain=Y, side="right") sage: phi == phi2 False + """ - # We skip the on_basis check since the matrix defines the morphism - return (self.__class__ is other.__class__ and parent(self) == parent(other) - and self._zero == other._zero - and self._position == other._position - and self._is_module_with_basis_over_same_base_ring - == other._is_module_with_basis_over_same_base_ring - and self._matrix == other._matrix) + if op == 2: # == + # We skip the on_basis check since the matrix defines the morphism + return (self.__class__ is other.__class__ + and parent(self) == parent(other) + and self._zero == other._zero + and self._position == other._position + and self._is_module_with_basis_over_same_base_ring == other._is_module_with_basis_over_same_base_ring + and self._matrix == other._matrix) + if op == 3: # != + return not (self == other) + raise NotImplementedError("Operator not implemented") class DiagonalModuleMorphism(ModuleMorphismByLinearity): r""" From 0a9a17fb35ff08ccf5400939b971afe130ccb2c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Sat, 19 Nov 2016 22:48:20 -0500 Subject: [PATCH 025/185] Implement DiagonalModuleMorphism._richcmp_ instead of __eq__, so we get !=. Also, do not rely on the super class: Comparing the bound on_basis implementation causes an infinite recursion because comparison methods depends on comparison of their "self" objects. --- src/sage/modules/with_basis/morphism.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index e9f1f96d7c8..35a924bd24a 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -1478,11 +1478,11 @@ def __init__(self, domain, diagonal, codomain=None, category=None): self, domain=domain, codomain=codomain, category=category) self._diagonal=diagonal - def __eq__(self, other): - """ - Check equality. + def _richcmp_(self, other, op): + r""" + Return whether this morphism and ``other`` satisfy ``op``. - EXAMPLES:: + TESTS:: sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") sage: phi = X.module_morphism(diagonal=factorial, codomain=X) @@ -1491,9 +1491,15 @@ def __eq__(self, other): True sage: phi is psi False + """ - return (ModuleMorphismByLinearity.__eq__(self, other) - and self._diagonal == other._diagonal) + if op == 2: # == + return (self.__class__ is other.__class__ + and parent(self) == parent(other) + and self._diagonal == other._diagonal) + if op == 3: # != + return not (self == other) + raise NotImplementedError("Operator not implemented") def _on_basis(self, i): """ From 6f6f0d337cd53ccb0886e19d37e2731f625e4426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Sat, 19 Nov 2016 22:49:37 -0500 Subject: [PATCH 026/185] Change __eq__ docstring wording --- src/sage/modules/with_basis/morphism.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index 35a924bd24a..3b83354a0e4 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -1599,8 +1599,8 @@ def __init__(self, f): self._pointwise_inverse = f def __eq__(self, other): - """ - Check equality. + r""" + Return whether this function is equal to ``other``. TESTS:: From 256f4879fac574b963f4decb8e12a72c833ef844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Sun, 20 Nov 2016 07:49:03 -0500 Subject: [PATCH 027/185] expanded tabs --- src/sage/modules/with_basis/morphism.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index 3b83354a0e4..174aa1094d4 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -713,10 +713,10 @@ def _richcmp_(self, other, op): sage: perm = [0, 2, 1, 3] sage: our_cmp = lambda a, b: cmp(perm[a], perm[b]) sage: phi = X.module_morphism(ut, triangular="upper", codomain=X, cmp=our_cmp) - doctest:warning + doctest:warning ... - DeprecationWarning: the 'cmp' keyword is deprecated, use 'key' instead - See http://trac.sagemath.org/21043 for details. + DeprecationWarning: the 'cmp' keyword is deprecated, use 'key' instead + See http://trac.sagemath.org/21043 for details. sage: def ut2(i): return (x[1] + 7*x[2] if i == 1 else x[2] + (x[3] if i == 3 else 0)) sage: phi2 = X.module_morphism(ut2, triangular="upper", codomain=X, cmp=our_cmp) sage: def lt(i): return (x[1] + x[2] + x[3] if i == 2 else x[i]) From af447b267f33d568a1dfcf9a60c7aa2e07f30dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Thu, 24 Nov 2016 18:24:39 -0500 Subject: [PATCH 028/185] Expand cmp to make the code Python3 friendly --- src/sage/modules/with_basis/morphism.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index 174aa1094d4..9e720be379c 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -711,7 +711,7 @@ def _richcmp_(self, other, op): sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() sage: def ut(i): return (x[1] + x[2] if i == 1 else x[2] + (x[3] if i == 3 else 0)) sage: perm = [0, 2, 1, 3] - sage: our_cmp = lambda a, b: cmp(perm[a], perm[b]) + sage: our_cmp = lambda a, b: (perm[a] > perm[b]) - (perm[a] < perm[b]) sage: phi = X.module_morphism(ut, triangular="upper", codomain=X, cmp=our_cmp) doctest:warning ... From 65e6c10c2da5e4d20bbc6f7f225ade3f4778fc0c Mon Sep 17 00:00:00 2001 From: Peleg Michaeli Date: Fri, 25 Nov 2016 23:25:42 +0200 Subject: [PATCH 029/185] positive ** positive = real (doctest only) #21940 --- src/sage/symbolic/expression.pyx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 11d7b3de7e4..e8c24ba9f95 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -1981,6 +1981,9 @@ cdef class Expression(CommutativeRingElement): False sage: (t0*t1).is_real() True + sage: t2 = SR.symbol("t1", domain='positive') + sage: (t1**t2).is_real() + True sage: (t0*x).is_real() False From 7162b738df71af32e8c98eecd1cc2a6412e8ac2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Wed, 7 Dec 2016 00:10:04 -0500 Subject: [PATCH 030/185] Forward do_pickle to CachedFunction's constructor The `do_pickle` parameter was not properly passed on in `CachedInParentMethod` so that parameter actually never worked (the default was used instead which meant no pickling of caches.) The doctest did not catch it since the parent was not pickled and unpickled because `_parent` of the class had been assigned, not of the instance. --- src/sage/misc/cachefunc.pyx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sage/misc/cachefunc.pyx b/src/sage/misc/cachefunc.pyx index 77c3ae87280..8692e6ed77b 100644 --- a/src/sage/misc/cachefunc.pyx +++ b/src/sage/misc/cachefunc.pyx @@ -3228,7 +3228,7 @@ cdef class CachedInParentMethod(CachedMethod): sage: class Foo: ....: def __init__(self, x): ....: self._x = x - ....: _parent = MyParent() + ....: self._parent = MyParent() ....: def parent(self): ....: return self._parent ....: @cached_in_parent_method #indirect doctest @@ -3289,7 +3289,8 @@ cdef class CachedInParentMethod(CachedMethod): Pickling can be enabled with ``do_pickle``:: sage: class A(object): - ....: _parent = MyParent() + ....: def __init__(self): + ....: self._parent = MyParent() ....: def parent(self): return self._parent ....: @cached_in_parent_method(do_pickle=True) ....: def f(self, x): return x @@ -3299,13 +3300,13 @@ cdef class CachedInParentMethod(CachedMethod): 1 sage: len(a.f.cache) 1 - sage: b= loads(dumps(a)) + sage: b = loads(dumps(a)) sage: len(b.f.cache) 1 """ self._cache_name = '_cache__' + 'element_' + (name or f.__name__) - self._cachedfunc = CachedFunction(f, classmethod=True, name=name, key=key) + self._cachedfunc = CachedFunction(f, classmethod=True, name=name, key=key, do_pickle=do_pickle) cpdef _get_instance_cache(self, inst): """ From d9a4a75c1ad295650cd7f5bd172ab37a26d55bf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Sun, 11 Dec 2016 12:36:45 -0500 Subject: [PATCH 031/185] Do not use magic constants in richcmp --- src/sage/modules/with_basis/morphism.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index 9e720be379c..fd9be8e2841 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -119,6 +119,7 @@ from sage.categories.sets_cat import Sets from sage.categories.sets_with_partial_maps import SetsWithPartialMaps from sage.structure.element import parent +from sage.structure.sage_object import op_EQ, op_NE from sage.matrix.matrix import is_Matrix class ModuleMorphism(Morphism): @@ -334,14 +335,14 @@ def _richcmp_(self, other, op): (True, False, False, False, False, False) """ - if op == 2: # == + if op == op_EQ: return (self.__class__ is other.__class__ and parent(self) == parent(other) and self._zero == other._zero and self._on_basis == other._on_basis and self._position == other._position and self._is_module_with_basis_over_same_base_ring == other._is_module_with_basis_over_same_base_ring) - if op == 3: # != + if op == op_NE: return not (self == other) raise NotImplementedError("Operator not implemented") @@ -729,14 +730,14 @@ def _richcmp_(self, other, op): False """ - if op == 2: # == + if op == op_EQ: return (self.__class__ is other.__class__ and self.parent() == other.parent() and self._triangular == other._triangular and self._unitriangular == other._unitriangular and self._inverse_on_support == other._inverse_on_support and self._invertible == other._invertible and self._dominant_item == other._dominant_item) - if op == 3: # != + if op == op_NE: return not (self == other) raise NotImplementedError("Operator not implemented") @@ -1216,10 +1217,10 @@ def _richcmp_(self, other, op): True """ - if op == 2: # == + if op == op_EQ: return (ModuleMorphismByLinearity._richcmp_(self, other, op) and TriangularModuleMorphism._richcmp_(self, other, op)) - if op == 3: # != + if op == op_NE: return not (self == other) raise NotImplementedError("Operator not implemented") @@ -1401,7 +1402,7 @@ def _richcmp_(self, other, op): False """ - if op == 2: # == + if op == op_EQ: # We skip the on_basis check since the matrix defines the morphism return (self.__class__ is other.__class__ and parent(self) == parent(other) @@ -1409,7 +1410,7 @@ def _richcmp_(self, other, op): and self._position == other._position and self._is_module_with_basis_over_same_base_ring == other._is_module_with_basis_over_same_base_ring and self._matrix == other._matrix) - if op == 3: # != + if op == op_NE: return not (self == other) raise NotImplementedError("Operator not implemented") @@ -1493,11 +1494,11 @@ def _richcmp_(self, other, op): False """ - if op == 2: # == + if op == op_EQ: return (self.__class__ is other.__class__ and parent(self) == parent(other) and self._diagonal == other._diagonal) - if op == 3: # != + if op == op_NE: return not (self == other) raise NotImplementedError("Operator not implemented") From c88329909934b9561314344347a7bd7c3c0ec755 Mon Sep 17 00:00:00 2001 From: Ralf Stephan Date: Tue, 20 Dec 2016 16:40:33 +0100 Subject: [PATCH 032/185] 21940: add one doctest --- src/sage/symbolic/expression.pyx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 9eb7c473574..cc0b4d8024f 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -1986,6 +1986,8 @@ cdef class Expression(CommutativeRingElement): True sage: (t0*x).is_real() False + sage: (2^t0).is_real() + True The following is real, but we cannot deduce that.:: From c0306ee08b94061ef1f525cdc71d24c17e004ce3 Mon Sep 17 00:00:00 2001 From: John Cremona Date: Fri, 13 Jan 2017 11:39:51 +0000 Subject: [PATCH 033/185] #22164: add dealloc method to ECModularSymbol class in eclib interface --- src/sage/libs/eclib/newforms.pyx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sage/libs/eclib/newforms.pyx b/src/sage/libs/eclib/newforms.pyx index 8785ed018f9..5b231bc1195 100644 --- a/src/sage/libs/eclib/newforms.pyx +++ b/src/sage/libs/eclib/newforms.pyx @@ -212,6 +212,9 @@ cdef class ECModularSymbol: self.nfs.createfromcurve(sign,CR[0]) sig_off() + def __dealloc__(self): + del self.nfs + def __repr__(self): """ TESTS:: From 03df05eeeaa7c9a58c8c84193d93ee77303c9827 Mon Sep 17 00:00:00 2001 From: John Cremona Date: Tue, 24 Jan 2017 13:46:33 +0000 Subject: [PATCH 034/185] minor change to eclib interface --- src/sage/libs/eclib/__init__.pxd | 3 +++ src/sage/libs/eclib/newforms.pyx | 16 ++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/sage/libs/eclib/__init__.pxd b/src/sage/libs/eclib/__init__.pxd index 6f0b88af94a..ba35e5e7a44 100644 --- a/src/sage/libs/eclib/__init__.pxd +++ b/src/sage/libs/eclib/__init__.pxd @@ -44,16 +44,19 @@ cdef extern from "eclib/isogs.h": cdef extern from "eclib/curve.h": cdef cppclass Curve: + Curve() Curve(bigint aa1, bigint aa2, bigint aa3, bigint aa4, bigint aa6) void getai(bigint a1, bigint a2, bigint a3, bigint a4, bigint a6) cdef cppclass Curvedata: + Curvedata() Curvedata(Curve C, int m) Curvedata(bigint a1, bigint a2, bigint a3, bigint a4, bigint a6, int min_on_init) void getai(bigint a1, bigint a2, bigint a3, bigint a4, bigint a6) cdef cppclass CurveRed: + CurveRed() CurveRed(Curvedata CD) bigint getconductor(CurveRed CR) diff --git a/src/sage/libs/eclib/newforms.pyx b/src/sage/libs/eclib/newforms.pyx index 5b231bc1195..13643063f4b 100644 --- a/src/sage/libs/eclib/newforms.pyx +++ b/src/sage/libs/eclib/newforms.pyx @@ -178,9 +178,9 @@ cdef class ECModularSymbol: TypeError: the elliptic curve must have coefficients in the rational numbers """ cdef ZZ_c a1, a2, a3, a4, a6, N - cdef Curve *C - cdef Curvedata *CD - cdef CurveRed *CR + cdef Curve C + cdef Curvedata CD + cdef CurveRed CR cdef int n if E.base_field() is not QQ: @@ -197,10 +197,10 @@ cdef class ECModularSymbol: mpz_to_ZZ(&a6, mpq_numref(((E.a6())).value)) sig_on() - C = new Curve(a1,a2,a3,a4,a6) - CD = new Curvedata(C[0],0) - CR = new CurveRed(CD[0]) - N = getconductor(CR[0]) + C = Curve(a1,a2,a3,a4,a6) + CD = Curvedata(C,0) + CR = CurveRed(CD) + N = getconductor(CR) n = I2int(N) self.n = n if not (sign==0 or sign==1): @@ -209,7 +209,7 @@ cdef class ECModularSymbol: self.sign = sign self.nfs = new newforms(n,0) - self.nfs.createfromcurve(sign,CR[0]) + self.nfs.createfromcurve(sign,CR) sig_off() def __dealloc__(self): From 290f0458f5cb8e3e676bd5e423dfe33f111b0d3a Mon Sep 17 00:00:00 2001 From: John Cremona Date: Fri, 27 Jan 2017 09:10:08 +0000 Subject: [PATCH 035/185] update eclib to v20170122 (memory leak fix) --- build/pkgs/eclib/checksums.ini | 6 +++--- build/pkgs/eclib/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/eclib/checksums.ini b/build/pkgs/eclib/checksums.ini index e6422a4142a..6cefb639448 100644 --- a/build/pkgs/eclib/checksums.ini +++ b/build/pkgs/eclib/checksums.ini @@ -1,4 +1,4 @@ tarball=eclib-VERSION.tar.bz2 -sha1=b5098fe705dcea8f492e5e331ad8a69f5721898f -md5=af8c339c44155ed813cb40f39fcfe344 -cksum=2757924773 +sha1=53be45c962d6df0e62010a00327817d0a1e63c3c +md5=8a7e40c25d6621100ba57717a0cb99e2 +cksum=1122336657 diff --git a/build/pkgs/eclib/package-version.txt b/build/pkgs/eclib/package-version.txt index 9b4c593d3cf..75c0cd5c778 100644 --- a/build/pkgs/eclib/package-version.txt +++ b/build/pkgs/eclib/package-version.txt @@ -1 +1 @@ -20170104 +20170122 From 193620adad64103ae7c4d09b89a1c0a7a9bae8cb Mon Sep 17 00:00:00 2001 From: John Cremona Date: Thu, 2 Feb 2017 10:11:00 +0000 Subject: [PATCH 036/185] #22164 added test to show leak fixed --- src/sage/libs/eclib/newforms.pyx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/sage/libs/eclib/newforms.pyx b/src/sage/libs/eclib/newforms.pyx index 13643063f4b..87a7cf61c23 100644 --- a/src/sage/libs/eclib/newforms.pyx +++ b/src/sage/libs/eclib/newforms.pyx @@ -122,7 +122,19 @@ cdef class ECModularSymbol: sage: all((M3(r,-1)==M1(r,-1)) for r in QQ.range_by_height(10)) True + TESTS: + Until :trac:`22164`, eclib had a memory leak. Here we test that + it has gone:: + + sage: from sage.libs.eclib.newforms import ECModularSymbol + sage: E = EllipticCurve([1,1,0,-108,-432]) # conductor 930 + sage: mem = get_memory_usage() + sage: for _ in range(10): M = ECModularSymbol(E) # long time + sage: mem2 = get_memory_usage() + sage: mem2-mem # random + 0.75 + sage: assert(mem2-mem < 1) """ def __init__(self, E, sign=1): """ From 2e6bcbf4f35973677dd985c545a188aa0982bfd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Fri, 3 Feb 2017 23:37:55 +0100 Subject: [PATCH 037/185] remove deprecated function `is_inexact` --- src/sage/functions/special.py | 2 +- src/sage/symbolic/function.pyx | 27 --------------------------- 2 files changed, 1 insertion(+), 28 deletions(-) diff --git a/src/sage/functions/special.py b/src/sage/functions/special.py index e2d59c67c09..d4ba3c93554 100644 --- a/src/sage/functions/special.py +++ b/src/sage/functions/special.py @@ -165,7 +165,7 @@ from sage.rings.all import ZZ, RR, RDF, CDF from sage.functions.other import real, imag, log_gamma from sage.symbolic.constants import pi -from sage.symbolic.function import BuiltinFunction, is_inexact +from sage.symbolic.function import BuiltinFunction from sage.symbolic.expression import Expression from sage.calculus.calculus import maxima from sage.structure.element import parent diff --git a/src/sage/symbolic/function.pyx b/src/sage/symbolic/function.pyx index dcb0987c657..1145c56e2e6 100644 --- a/src/sage/symbolic/function.pyx +++ b/src/sage/symbolic/function.pyx @@ -1515,30 +1515,3 @@ def unpickle_wrapper(p): return None return unpickle_function(p) -def is_inexact(x): - """ - Returns True if the argument is an inexact object. - - TESTS:: - - sage: from sage.symbolic.function import is_inexact - sage: is_inexact(5) - doctest:...: DeprecationWarning: The is_inexact() function is deprecated, use the _is_numerical() method of the Function class instead - See http://trac.sagemath.org/17130 for details. - False - sage: is_inexact(5.) - True - sage: is_inexact(pi) - True - sage: is_inexact(5r) - False - sage: is_inexact(5.4r) - True - """ - from sage.misc.superseded import deprecation - deprecation(17130, 'The is_inexact() function is deprecated, use the _is_numerical() method of the Function class instead') - if isinstance(x, (float, complex)): - return True - if isinstance(x, Element): - return not (x)._parent.is_exact() - return False From 5281cf4faf91d67d95e29230d3f8120008598307 Mon Sep 17 00:00:00 2001 From: Andrey Novoseltsev Date: Sun, 5 Feb 2017 19:17:27 -0700 Subject: [PATCH 038/185] Use PPL for facet normals of full-dimensional polytopes --- src/sage/geometry/lattice_polytope.py | 32 ++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 842d6d21f78..a5991978f82 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -729,7 +729,37 @@ def _compute_facets(self): """ assert not hasattr(self, "_facet_normals") if self.dim() == self.lattice_dim(): - self._read_equations(self.poly_x("e")) + N = self.dual_lattice() + normals = [] + constants = [] + for c in self._PPL().minimized_constraints(): + assert c.is_inequality() + normals.append(N(c.coefficients())) + normals[-1].set_immutable() + constants.append(c.inhomogeneous_term()) + # Sort normals if facets are vertices + if (self.dim() == 1 + and normals[0] * self.vertex(0) + constants[0] != 0): + normals = (normals[1], normals[0]) + constants = (constants[1], constants[0]) + self.is_reflexive.set_cache(all(c == 1 for c in constants)) + if self.is_reflexive(): + polar = LatticePolytope( + normals, compute_vertices=False, lattice=N) + polar._dim = self._dim + polar.is_reflexive.set_cache(True) + polar._polar = self + self._polar = polar + self._facet_normals = polar._vertices + polar._facet_normals = self._vertices + self._facet_constants = vector(ZZ, [1] * polar.nvertices()) + self._facet_constants.set_immutable() + polar._facet_constants = vector(ZZ, [1] * self.nvertices()) + polar._facet_constants.set_immutable() + else: + self._facet_normals = PointCollection(normals, N) + self._facet_constants = vector(ZZ, constants) + self._facet_constants.set_immutable() else: sp = self._sublattice_polytope N = self.dual_lattice() From d24479380a46e868d64c9fe8a228813259ad9414 Mon Sep 17 00:00:00 2001 From: Andrey Novoseltsev Date: Sun, 5 Feb 2017 20:44:02 -0700 Subject: [PATCH 039/185] Update a lot of toric doctests for the new facet order --- src/sage/geometry/fan.py | 68 ++++----- src/sage/geometry/fan_morphism.py | 20 +-- src/sage/geometry/lattice_polytope.py | 182 ++++++++++++------------- src/sage/schemes/toric/fano_variety.py | 78 +++++------ src/sage/schemes/toric/variety.py | 26 ++-- 5 files changed, 187 insertions(+), 187 deletions(-) diff --git a/src/sage/geometry/fan.py b/src/sage/geometry/fan.py index 3eebaa02b47..085c92c2246 100644 --- a/src/sage/geometry/fan.py +++ b/src/sage/geometry/fan.py @@ -76,50 +76,50 @@ The last output is not very illuminating. Let's try to improve it:: sage: for cone in fan1: print(cone.rays()) - M(1, 0, 0), - M(0, 1, 0), - M(0, 0, -1) - in 3-d lattice M - M( 0, 1, 0), - M(-1, 0, 0), - M( 0, 0, -1) + M( 0, 1, 0), + M( 0, 0, 1), + M(-1, 0, 0) in 3-d lattice M - M(1, 0, 0), - M(0, -1, 0), - M(0, 0, -1) + M( 0, 0, 1), + M(-1, 0, 0), + M( 0, -1, 0) in 3-d lattice M M(-1, 0, 0), M( 0, -1, 0), M( 0, 0, -1) in 3-d lattice M + M( 0, 1, 0), + M(-1, 0, 0), + M( 0, 0, -1) + in 3-d lattice M + M(1, 0, 0), + M(0, 1, 0), + M(0, 0, -1) + in 3-d lattice M M(1, 0, 0), M(0, 1, 0), M(0, 0, 1) in 3-d lattice M - M( 0, 1, 0), - M( 0, 0, 1), - M(-1, 0, 0) - in 3-d lattice M M(1, 0, 0), M(0, 0, 1), M(0, -1, 0) in 3-d lattice M - M( 0, 0, 1), - M(-1, 0, 0), - M( 0, -1, 0) + M(1, 0, 0), + M(0, -1, 0), + M(0, 0, -1) in 3-d lattice M You can also do :: sage: for cone in fan1: print(cone.ambient_ray_indices()) - (0, 1, 5) - (1, 3, 5) - (0, 4, 5) + (1, 2, 3) + (2, 3, 4) (3, 4, 5) + (1, 3, 5) + (0, 1, 5) (0, 1, 2) - (1, 2, 3) (0, 2, 4) - (2, 3, 4) + (0, 4, 5) to see indices of rays of the fan corresponding to each cone. @@ -618,17 +618,17 @@ def FaceFan(polytope, lattice=None): M( 0, -1) in 2-d lattice M sage: for cone in P1xP1: print(cone.rays()) - M(1, 0), - M(0, -1) - in 2-d lattice M M(-1, 0), M( 0, -1) in 2-d lattice M + M( 0, 1), + M(-1, 0) + in 2-d lattice M M(1, 0), M(0, 1) in 2-d lattice M - M( 0, 1), - M(-1, 0) + M(1, 0), + M(0, -1) in 2-d lattice M TESTS:: @@ -720,12 +720,12 @@ def NormalFan(polytope, lattice=None): sage: P1xP1.rays() N( 1, 0), N( 0, 1), - N( 0, -1), - N(-1, 0) + N(-1, 0), + N( 0, -1) in 2-d lattice N sage: for cone in P1xP1: print(cone.rays()) - N( 0, -1), - N(-1, 0) + N(-1, 0), + N( 0, -1) in 2-d lattice N N(1, 0), N(0, -1) @@ -2799,11 +2799,11 @@ def is_smooth(self, codim=None): sage: fan.is_smooth(codim=1) True sage: fan.generating_cone(0).rays() - N(-1, 1), - N(-1, -1) + N(-1, -1), + N(-1, 1) in 2-d lattice N sage: fan.generating_cone(0).rays().matrix().det() - 2 + -2 """ if codim is None or codim < 0: codim = 0 diff --git a/src/sage/geometry/fan_morphism.py b/src/sage/geometry/fan_morphism.py index 245f659904f..c1a82b2399e 100644 --- a/src/sage/geometry/fan_morphism.py +++ b/src/sage/geometry/fan_morphism.py @@ -47,18 +47,18 @@ Domain fan: Rational polyhedral fan in 2-d lattice N Codomain fan: Rational polyhedral fan in 2-d lattice N sage: fm.domain_fan().rays() - N(-1, 1), N( 1, 1), - N(-1, -1), N( 1, -1), + N(-1, -1), + N(-1, 1), N( 0, -1), N( 0, 1) in 2-d lattice N sage: normal.rays() - N(-1, 1), N( 1, 1), + N( 1, -1), N(-1, -1), - N( 1, -1) + N(-1, 1) in 2-d lattice N As you see, it was necessary to insert two new rays (to prevent "upper" and @@ -358,14 +358,14 @@ def _RISGIS(self): sage: fm = FanMorphism(identity_matrix(2), ....: normal, face, subdivide=True) sage: fm._RISGIS() - (frozenset({3}), - frozenset({2}), - frozenset({1}), + (frozenset({2}), + frozenset({3}), frozenset({0}), - frozenset({1, 3}), + frozenset({1}), frozenset({0, 1}), - frozenset({0, 2}), - frozenset({2, 3})) + frozenset({0, 3}), + frozenset({2, 3}), + frozenset({1, 2})) """ if "_RISGIS_" not in self.__dict__: try: diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index a5991978f82..d65e138f867 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -721,10 +721,10 @@ def _compute_facets(self): sage: p = LatticePolytope([(1,0,0), (0,1,0), (-1,0,0), (0,-1,0)]) sage: p._compute_facets() sage: p._facet_normals - N(-1, 1, 0), N( 1, 1, 0), + N( 1, -1, 0), N(-1, -1, 0), - N( 1, -1, 0) + N(-1, 1, 0) in 3-d lattice N """ assert not hasattr(self, "_facet_normals") @@ -1355,16 +1355,16 @@ def affine_transform(self, a=1, b=0): in 2-d lattice M sage: a = matrix(QQ, 2, [1/2, 0, 0, 3/2]) sage: o.polar().vertices() - N(-1, 1), N( 1, 1), + N( 1, -1), N(-1, -1), - N( 1, -1) + N(-1, 1) in 2-d lattice N sage: o.polar().affine_transform(a, (1/2, -1/2)).vertices() - M(0, 1), M(1, 1), + M(1, -2), M(0, -2), - M(1, -2) + M(0, 1) in 2-d lattice M While you can use rational transformation, the result must be integer:: @@ -1437,7 +1437,7 @@ def ambient_facet_indices(self): sage: face = o.faces(1)[0] sage: face.ambient_facet_indices() - (0, 4) + (4, 5) sage: face.vertices() M(1, 0, 0), M(0, 1, 0) @@ -1465,7 +1465,7 @@ def ambient_point_indices(self): sage: cube = lattice_polytope.cross_polytope(3).polar() sage: face = cube.facets()[0] sage: face.ambient_point_indices() - (0, 2, 4, 6, 8, 9, 10, 11, 12) + (4, 5, 6, 7, 8, 9, 10, 11, 12) sage: cube.points(face.ambient_point_indices()) == face.points() True """ @@ -1490,7 +1490,7 @@ def ambient_ordered_point_indices(self): sage: cube = lattice_polytope.cross_polytope(3).polar() sage: face = cube.facets()[0] sage: face.ambient_ordered_point_indices() - (4, 8, 0, 9, 10, 11, 6, 12, 2) + (5, 8, 4, 9, 10, 11, 6, 12, 7) sage: cube.points(face.ambient_ordered_point_indices()) N(-1, -1, -1), N(-1, -1, 0), @@ -1542,10 +1542,10 @@ def boundary_point_indices(self): sage: square = lattice_polytope.cross_polytope(2).polar() sage: square.points() - N(-1, 1), N( 1, 1), - N(-1, -1), N( 1, -1), + N(-1, -1), + N(-1, 1), N(-1, 0), N( 0, -1), N( 0, 0), @@ -1559,8 +1559,8 @@ def boundary_point_indices(self): sage: face = square.edges()[0] sage: face.points() - N(-1, 1), N(-1, -1), + N(-1, 1), N(-1, 0) in 2-d lattice N sage: face.boundary_point_indices() @@ -1584,10 +1584,10 @@ def boundary_points(self): sage: square = lattice_polytope.cross_polytope(2).polar() sage: square.boundary_points() - N(-1, 1), N( 1, 1), - N(-1, -1), N( 1, -1), + N(-1, -1), + N(-1, 1), N(-1, 0), N( 0, -1), N( 0, 1), @@ -1598,8 +1598,8 @@ def boundary_points(self): sage: face = square.edges()[0] sage: face.boundary_points() - N(-1, 1), - N(-1, -1) + N(-1, -1), + N(-1, 1) in 2-d lattice N """ return self.points(self.boundary_point_indices()) @@ -1648,24 +1648,24 @@ def distances(self, point=None): sage: o = lattice_polytope.cross_polytope(3) sage: o.distances() - [0 0 2 2 2 0 1] - [2 0 2 0 2 0 1] - [0 2 2 2 0 0 1] + [2 0 0 0 2 2 1] + [2 2 0 0 0 2 1] [2 2 2 0 0 0 1] + [2 0 2 0 2 0 1] + [0 0 2 2 2 0 1] [0 0 0 2 2 2 1] - [2 0 0 0 2 2 1] [0 2 0 2 0 2 1] - [2 2 0 0 0 2 1] + [0 2 2 2 0 0 1] Distances from facets to the point (1,2,3):: sage: o.distances([1,2,3]) - (1, 3, 5, 7, -5, -3, -1, 1) + (-3, 1, 7, 3, 1, -5, -1, 5) It is OK to use RATIONAL coordinates:: sage: o.distances([1,2,3/2]) - (-1/2, 3/2, 7/2, 11/2, -7/2, -3/2, 1/2, 5/2) + (-3/2, 5/2, 11/2, 3/2, -1/2, -7/2, 1/2, 7/2) sage: o.distances([1,2,sqrt(2)]) Traceback (most recent call last): ... @@ -1675,12 +1675,12 @@ def distances(self, point=None): sage: p = LatticePolytope([(1,0,0), (0,1,0), (-1,0,0), (0,-1,0)]) sage: p.distances() - [0 2 2 0 1] [2 2 0 0 1] - [0 0 2 2 1] [2 0 0 2 1] + [0 0 2 2 1] + [0 2 2 0 1] sage: p.distances((1/2, 3, 0)) - (7/2, 9/2, -5/2, -3/2) + (9/2, -3/2, -5/2, 7/2) sage: p.distances((1, 1, 1)) Traceback (most recent call last): ... @@ -2040,7 +2040,7 @@ def facet_constant(self, i): M( 0, 0, -1) in 3-d lattice M sage: o.facet_normal(0) - N(-1, -1, 1) + N(1, -1, -1) sage: o.facet_constant(0) 1 sage: p = LatticePolytope(o.vertices()(1,2,3,4,5)) @@ -2063,7 +2063,7 @@ def facet_constant(self, i): M(0, 0, -1) in 3-d lattice M sage: p.facet_normal(0) - N(0, -1, 1) + N(0, 1, 1) sage: p.facet_constant(0) 1 @@ -2079,10 +2079,10 @@ def facet_constant(self, i): in 4-d lattice M sage: fns = [p.facet_normal(i) for i in range(p.nfacets())] sage: fns - [N(11, -1, 1, 3), N(-11, -1, 1, 3), N(0, 1, -1, -3)] + [N(11, -1, 1, 3), N(0, 1, -1, -3), N(-11, -1, 1, 3)] sage: fcs = [p.facet_constant(i) for i in range(p.nfacets())] sage: fcs - [0, 0, 11] + [0, 11, 0] Now we manually compute the distance matrix of this polytope. Since it is a triangle, each line (corresponding to a facet) should have two @@ -2093,8 +2093,8 @@ def facet_constant(self, i): ....: for j in range(p.nvertices())] ....: for i in range(p.nfacets())]) [22 0 0] - [ 0 22 0] [ 0 0 11] + [ 0 22 0] """ return self.facet_constants()[i] @@ -2134,7 +2134,7 @@ def facet_constants(self): M(-1, -1, 1, 3) in 4-d lattice M sage: p.facet_constants() - (0, 0, 0, 10) + (0, 0, 10, 0) """ try: return self._facet_constants @@ -2173,7 +2173,7 @@ def facet_normal(self, i): M( 0, 0, -1) in 3-d lattice M sage: o.facet_normal(0) - N(-1, -1, 1) + N(1, -1, -1) sage: o.facet_constant(0) 1 sage: p = LatticePolytope(o.vertices()(1,2,3,4,5)) @@ -2196,7 +2196,7 @@ def facet_normal(self, i): M(0, 0, -1) in 3-d lattice M sage: p.facet_normal(0) - N(0, -1, 1) + N(0, 1, 1) sage: p.facet_constant(0) 1 @@ -2226,10 +2226,10 @@ def facet_normal(self, i): ....: + p.facet_constant(i) ....: for j in range(p.nvertices())] ....: for i in range(p.nfacets())]) - [ 0 0 0 20] - [ 0 0 20 0] [ 0 20 0 0] + [ 0 0 20 0] [10 0 0 0] + [ 0 0 0 20] """ return self.facet_normals()[i] @@ -2256,14 +2256,14 @@ def facet_normals(self): M( 0, 0, -1) in 3-d lattice M sage: o.facet_normals() - N(-1, -1, 1), - N( 1, -1, 1), - N(-1, 1, 1), + N( 1, -1, -1), + N( 1, 1, -1), N( 1, 1, 1), + N( 1, -1, 1), + N(-1, -1, 1), N(-1, -1, -1), - N( 1, -1, -1), N(-1, 1, -1), - N( 1, 1, -1) + N(-1, 1, 1) in 3-d lattice N Here is an example of a 3-dimensional polytope in a 4-dimensional @@ -2278,10 +2278,10 @@ def facet_normals(self): M(-1, -1, 1, 3) in 4-d lattice M sage: p.facet_normals() - N(-10, 0, 1, 3), - N( 10, -10, 0, 0), N( 0, 10, 1, 3), - N( 0, 0, -1, -3) + N( 10, -10, 0, 0), + N( 0, 0, -1, -3), + N(-10, 0, 1, 3) in 4-d lattice N """ try: @@ -2420,10 +2420,10 @@ def interior_point_indices(self): sage: square = lattice_polytope.cross_polytope(2).polar() sage: square.points() - N(-1, 1), N( 1, 1), - N(-1, -1), N( 1, -1), + N(-1, -1), + N(-1, 1), N(-1, 0), N( 0, -1), N( 0, 0), @@ -2437,8 +2437,8 @@ def interior_point_indices(self): sage: face = square.edges()[0] sage: face.points() - N(-1, 1), N(-1, -1), + N(-1, 1), N(-1, 0) in 2-d lattice N sage: face.interior_point_indices() @@ -2930,7 +2930,7 @@ def _palp_modified_normal_form(self, permutation=False): M( 0, 1), M( 0, -1), M(-1, 0) - in 2-d lattice M, (1,2,3)) + in 2-d lattice M, (3,4)) """ PM = self.vertex_facet_pairing_matrix() PM_max = PM.permutation_normal_form() @@ -2983,7 +2983,7 @@ def _palp_native_normal_form(self, permutation=False): M( 0, 1), M( 0, -1), M(-1, 0) - in 2-d lattice M, (1,4,2,3)) + in 2-d lattice M, (1,3,2,4)) """ PM_max, permutations = self._palp_PM_max(check=True) out = _palp_canonical_order(self.vertices(), PM_max, permutations) @@ -3600,14 +3600,14 @@ def points(self, *args, **kwds): in 3-d lattice M sage: cube = o.polar() sage: cube.points() - N(-1, -1, 1), - N( 1, -1, 1), - N(-1, 1, 1), + N( 1, -1, -1), + N( 1, 1, -1), N( 1, 1, 1), + N( 1, -1, 1), + N(-1, -1, 1), N(-1, -1, -1), - N( 1, -1, -1), N(-1, 1, -1), - N( 1, 1, -1), + N(-1, 1, 1), N(-1, -1, 0), N(-1, 0, -1), N(-1, 0, 0), @@ -3743,7 +3743,7 @@ def poly_x(self, keys, reduce_dimension=False): sage: BIG = lattice_polytope.cross_polytope(7) sage: BIG - 7-d lattice polytope in 7-d lattice M + 7-d reflexive polytope in 7-d lattice M sage: BIG.poly_x("e") # possibly different output depending on your system Traceback (most recent call last): ... @@ -3885,7 +3885,7 @@ def traverse_boundary(self): sage: p = lattice_polytope.cross_polytope(2).polar() sage: p.traverse_boundary() - [2, 0, 1, 3] + [3, 0, 1, 2] """ if self.dim() != 2: raise ValueError("Boundary can be traversed only for 2-polytopes!") @@ -3934,14 +3934,14 @@ def vertex_facet_pairing_matrix(self): sage: L = lattice_polytope.cross_polytope(3) sage: L.vertex_facet_pairing_matrix() - [0 0 2 2 2 0] - [2 0 2 0 2 0] - [0 2 2 2 0 0] + [2 0 0 0 2 2] + [2 2 0 0 0 2] [2 2 2 0 0 0] + [2 0 2 0 2 0] + [0 0 2 2 2 0] [0 0 0 2 2 2] - [2 0 0 0 2 2] [0 2 0 2 0 2] - [2 2 0 0 0 2] + [0 2 2 2 0 0] """ V = self.vertices() nv = self.nvertices() @@ -3977,14 +3977,14 @@ def vertices(self, *args, **kwds): in 3-d lattice M sage: cube = o.polar() sage: cube.vertices() - N(-1, -1, 1), - N( 1, -1, 1), - N(-1, 1, 1), + N( 1, -1, -1), + N( 1, 1, -1), N( 1, 1, 1), + N( 1, -1, 1), + N(-1, -1, 1), N(-1, -1, -1), - N( 1, -1, -1), N(-1, 1, -1), - N( 1, 1, -1) + N(-1, 1, 1) in 3-d lattice N """ if args or kwds: @@ -4127,13 +4127,13 @@ class NefPartition(SageObject, Nef-partition {0, 1, 2} U {3, 4} U {5, 6, 7} sage: np.nabla_polar().vertices() N(-1, -1, 0), - N( 0, -1, 0), N(-1, 0, 0), - N( 0, 0, 1), + N( 0, -1, 0), N( 0, 0, -1), - N( 1, 1, 0), + N( 0, 0, 1), + N( 1, 0, 0), N( 0, 1, 0), - N( 1, 0, 0) + N( 1, 1, 0) in 3-d lattice N Of course, `\nabla^\circ` is `\Delta^\circ` from the point of view of the @@ -4362,14 +4362,14 @@ def Delta(self, i=None): sage: np.Delta().polar() is o True sage: np.Delta().vertices() - N(-1, -1, 1), - N( 1, -1, 1), - N(-1, 1, 1), + N( 1, -1, -1), + N( 1, 1, -1), N( 1, 1, 1), + N( 1, -1, 1), + N(-1, -1, 1), N(-1, -1, -1), - N( 1, -1, -1), N(-1, 1, -1), - N( 1, 1, -1) + N(-1, 1, 1) in 3-d lattice N sage: np.Delta(0).vertices() N(-1, -1, 0), @@ -4423,14 +4423,14 @@ def Deltas(self): sage: np Nef-partition {0, 1, 3} U {2, 4, 5} sage: np.Delta().vertices() - N(-1, -1, 1), - N( 1, -1, 1), - N(-1, 1, 1), + N( 1, -1, -1), + N( 1, 1, -1), N( 1, 1, 1), + N( 1, -1, 1), + N(-1, -1, 1), N(-1, -1, -1), - N( 1, -1, -1), N(-1, 1, -1), - N( 1, 1, -1) + N(-1, 1, 1) in 3-d lattice N sage: [Delta_i.vertices() for Delta_i in np.Deltas()] [N(-1, -1, 0), @@ -4444,14 +4444,14 @@ def Deltas(self): N(0, 1, -1) in 3-d lattice N] sage: np.nabla_polar().vertices() + N(-1, -1, 0), N( 1, -1, 0), N( 1, 0, 0), - N(-1, -1, 0), N(-1, 0, 0), + N( 0, 1, -1), N( 0, 1, 1), N( 0, 0, 1), - N( 0, 0, -1), - N( 0, 1, -1) + N( 0, 0, -1) in 3-d lattice N """ return self.dual().nablas() @@ -4577,13 +4577,13 @@ def nabla(self, i=None): in 3-d lattice M sage: np.nabla().vertices() M(-1, 0, 1), + M(-1, 0, -1), M( 1, 0, 1), + M( 1, 0, -1), M( 0, 1, 1), - M(-1, -1, 0), - M(-1, 0, -1), + M( 0, 1, -1), M( 1, -1, 0), - M( 1, 0, -1), - M( 0, 1, -1) + M(-1, -1, 0) in 3-d lattice M """ if i is None: @@ -4609,14 +4609,14 @@ def nabla_polar(self): sage: np Nef-partition {0, 1, 3} U {2, 4, 5} sage: np.nabla_polar().vertices() + N(-1, -1, 0), N( 1, -1, 0), N( 1, 0, 0), - N(-1, -1, 0), N(-1, 0, 0), + N( 0, 1, -1), N( 0, 1, 1), N( 0, 0, 1), - N( 0, 0, -1), - N( 0, 1, -1) + N( 0, 0, -1) in 3-d lattice N sage: np.nabla_polar() is np.dual().Delta_polar() True @@ -4979,7 +4979,7 @@ def _palp_canonical_order(V, PM_max, permutations): M( 0, 1), M( 0, -1), M(-1, 0) - in 2-d lattice M, (1,4,2,3)) + in 2-d lattice M, (1,3,2,4)) """ n_v = PM_max.ncols() n_f = PM_max.nrows() diff --git a/src/sage/schemes/toric/fano_variety.py b/src/sage/schemes/toric/fano_variety.py index f521b8d61a4..d2580fa613b 100644 --- a/src/sage/schemes/toric/fano_variety.py +++ b/src/sage/schemes/toric/fano_variety.py @@ -334,16 +334,16 @@ def CPRFanoToricVariety(Delta=None, sage: square = diamond.polar() sage: square.vertices() - N(-1, 1), N( 1, 1), + N( 1, -1), N(-1, -1), - N( 1, -1) + N(-1, 1) in 2-d lattice N sage: square.points() - N(-1, 1), N( 1, 1), - N(-1, -1), N( 1, -1), + N(-1, -1), + N(-1, 1), N(-1, 0), N( 0, -1), N( 0, 0), @@ -355,10 +355,10 @@ def CPRFanoToricVariety(Delta=None, sage: FTV = CPRFanoToricVariety(Delta_polar=square) sage: FTV.fan().rays() - N(-1, 1), N( 1, 1), + N( 1, -1), N(-1, -1), - N( 1, -1) + N(-1, 1) in 2-d lattice N sage: FTV.gens() (z0, z1, z2, z3) @@ -366,10 +366,10 @@ def CPRFanoToricVariety(Delta=None, sage: FTV = CPRFanoToricVariety(Delta_polar=square, ....: coordinate_points=[0,1,2,3,8]) sage: FTV.fan().rays() - N(-1, 1), N( 1, 1), - N(-1, -1), N( 1, -1), + N(-1, -1), + N(-1, 1), N( 1, 0) in 2-d lattice N sage: FTV.gens() @@ -380,10 +380,10 @@ def CPRFanoToricVariety(Delta=None, ....: coordinate_names="x+") sage: FTV.fan().rays() N( 1, 0), - N(-1, 1), - N(-1, -1), N( 1, 1), - N( 1, -1) + N(-1, -1), + N( 1, -1), + N(-1, 1) in 2-d lattice N sage: FTV.gens() (x8, x0, x2, x1, x3) @@ -392,10 +392,10 @@ def CPRFanoToricVariety(Delta=None, ....: coordinate_points="all", ....: coordinate_names="x y Z+") sage: FTV.fan().rays() - N(-1, 1), N( 1, 1), - N(-1, -1), N( 1, -1), + N(-1, -1), + N(-1, 1), N(-1, 0), N( 0, -1), N( 0, 1), @@ -454,7 +454,7 @@ def CPRFanoToricVariety(Delta=None, Now we will use the possibility to specify initial charts:: - sage: charts = [(0,1), (1,3), (3,2), (2,0)] + sage: charts = [(0,1), (1,2), (2,3), (3,0)] (these charts actually form exactly the face fan of our square) :: @@ -462,18 +462,18 @@ def CPRFanoToricVariety(Delta=None, ....: coordinate_points=[0,1,2,3,4], ....: charts=charts) sage: FTV.fan().rays() - N(-1, 1), N( 1, 1), - N(-1, -1), N( 1, -1), + N(-1, -1), + N(-1, 1), N(-1, 0) in 2-d lattice N sage: [cone.ambient_ray_indices() for cone in FTV.fan()] - [(0, 1), (1, 3), (2, 3), (0, 4), (2, 4)] + [(0, 1), (1, 2), (3, 4), (2, 4), (0, 3)] If charts are wrong, it should be detected:: - sage: bad_charts = charts + [(2,0)] + sage: bad_charts = charts + [(3,0)] sage: FTV = CPRFanoToricVariety(Delta_polar=square, ....: coordinate_points=[0,1,2,3,4], ....: charts=bad_charts) @@ -502,13 +502,13 @@ def CPRFanoToricVariety(Delta=None, Here are some other possible mistakes:: - sage: bad_charts = charts + [(0,3)] + sage: bad_charts = charts + [(0,2)] sage: FTV = CPRFanoToricVariety(Delta_polar=square, ....: coordinate_points=[0,1,2,3,4], ....: charts=bad_charts) Traceback (most recent call last): ... - ValueError: (0, 3) does not form a chart of a subdivision of + ValueError: (0, 2) does not form a chart of a subdivision of the face fan of 2-d reflexive polytope #14 in 2-d lattice N! sage: bad_charts = charts[:-1] @@ -1145,10 +1145,10 @@ def nef_complete_intersection(self, nef_partition, **kwds): sage: X.nef_complete_intersection(np) # long time Closed subscheme of 3-d CPR-Fano toric variety covered by 10 affine patches defined by: - a2*z1*z4^2*z5^2*z7^3 + a1*z2*z4*z5*z6*z7^2*z8^2 - + a3*z2*z3*z4*z7*z8 + a0*z0*z2, - b2*z1*z4*z5^2*z6^2*z7^2*z8^2 + b0*z2*z5*z6^3*z7*z8^4 - + b5*z1*z3*z4*z5*z6*z7*z8 + b3*z2*z3*z6^2*z8^3 + a0*z1*z4^2*z5^2*z7^3 + a2*z2*z4*z5*z6*z7^2*z8^2 + + a3*z2*z3*z4*z7*z8 + a1*z0*z2, + b3*z1*z4*z5^2*z6^2*z7^2*z8^2 + b0*z2*z5*z6^3*z7*z8^4 + + b5*z1*z3*z4*z5*z6*z7*z8 + b2*z2*z3*z6^2*z8^3 + b1*z1*z3^2*z4 + b4*z0*z1*z5*z6 Now we include only monomials associated to vertices of `\Delta_i`:: @@ -1156,10 +1156,10 @@ def nef_complete_intersection(self, nef_partition, **kwds): sage: X.nef_complete_intersection(np, monomial_points="vertices") # long time Closed subscheme of 3-d CPR-Fano toric variety covered by 10 affine patches defined by: - a2*z1*z4^2*z5^2*z7^3 + a1*z2*z4*z5*z6*z7^2*z8^2 - + a3*z2*z3*z4*z7*z8 + a0*z0*z2, - b2*z1*z4*z5^2*z6^2*z7^2*z8^2 + b0*z2*z5*z6^3*z7*z8^4 - + b3*z2*z3*z6^2*z8^3 + b1*z1*z3^2*z4 + b4*z0*z1*z5*z6 + a0*z1*z4^2*z5^2*z7^3 + a2*z2*z4*z5*z6*z7^2*z8^2 + + a3*z2*z3*z4*z7*z8 + a1*z0*z2, + b3*z1*z4*z5^2*z6^2*z7^2*z8^2 + b0*z2*z5*z6^3*z7*z8^4 + + b2*z2*z3*z6^2*z8^3 + b1*z1*z3^2*z4 + b4*z0*z1*z5*z6 (effectively, we set ``b5=0``). Next we provide coefficients explicitly instead of using default generic names:: @@ -1169,10 +1169,10 @@ def nef_complete_intersection(self, nef_partition, **kwds): ....: coefficients=[("a", "a^2", "a/e", "c_i"), list(range(1,6))]) Closed subscheme of 3-d CPR-Fano toric variety covered by 10 affine patches defined by: - a/e*z1*z4^2*z5^2*z7^3 + a^2*z2*z4*z5*z6*z7^2*z8^2 - + c_i*z2*z3*z4*z7*z8 + a*z0*z2, - 3*z1*z4*z5^2*z6^2*z7^2*z8^2 + z2*z5*z6^3*z7*z8^4 - + 4*z2*z3*z6^2*z8^3 + 2*z1*z3^2*z4 + 5*z0*z1*z5*z6 + a*z1*z4^2*z5^2*z7^3 + a/e*z2*z4*z5*z6*z7^2*z8^2 + + c_i*z2*z3*z4*z7*z8 + a^2*z0*z2, + 4*z1*z4*z5^2*z6^2*z7^2*z8^2 + z2*z5*z6^3*z7*z8^4 + + 3*z2*z3*z6^2*z8^3 + 2*z1*z3^2*z4 + 5*z0*z1*z5*z6 Finally, we take a look at the generic representative of these complete intersections in a completely resolved ambient toric variety:: @@ -1182,12 +1182,12 @@ def nef_complete_intersection(self, nef_partition, **kwds): sage: X.nef_complete_intersection(np) # long time Closed subscheme of 3-d CPR-Fano toric variety covered by 22 affine patches defined by: - a1*z2*z4*z5*z6*z7^2*z8^2*z9^2*z10^2*z11*z12*z13 - + a2*z1*z4^2*z5^2*z7^3*z9*z10^2*z12*z13 - + a3*z2*z3*z4*z7*z8*z9*z10*z11*z12 + a0*z0*z2, + a2*z2*z4*z5*z6*z7^2*z8^2*z9^2*z10^2*z11*z12*z13 + + a0*z1*z4^2*z5^2*z7^3*z9*z10^2*z12*z13 + + a3*z2*z3*z4*z7*z8*z9*z10*z11*z12 + a1*z0*z2, b0*z2*z5*z6^3*z7*z8^4*z9^3*z10^2*z11^2*z12*z13^2 - + b2*z1*z4*z5^2*z6^2*z7^2*z8^2*z9^2*z10^2*z11*z12*z13^2 - + b3*z2*z3*z6^2*z8^3*z9^2*z10*z11^2*z12*z13 + + b3*z1*z4*z5^2*z6^2*z7^2*z8^2*z9^2*z10^2*z11*z12*z13^2 + + b2*z2*z3*z6^2*z8^3*z9^2*z10*z11^2*z12*z13 + b5*z1*z3*z4*z5*z6*z7*z8*z9*z10*z11*z12*z13 + b1*z1*z3^2*z4*z11*z12 + b4*z0*z1*z5*z6*z13 """ @@ -1377,7 +1377,7 @@ class AnticanonicalHypersurface(AlgebraicScheme_subscheme_toric): sage: ftv.AnticanonicalHypersurface(P1xP1) Closed subscheme of 2-d CPR-Fano toric variety covered by 4 affine patches defined by: - a1*s^2*x^2 + a0*t^2*x^2 + a6*s*t*x*y + a3*s^2*y^2 + a2*t^2*y^2 + a0*s^2*x^2 + a3*t^2*x^2 + a6*s*t*x*y + a1*s^2*y^2 + a2*t^2*y^2 See :meth:`~CPRFanoToricVariety_field.anticanonical_hypersurface()` for a more elaborate example. @@ -1395,7 +1395,7 @@ def __init__(self, P_Delta, monomial_points=None, coefficient_names=None, sage: ftv.AnticanonicalHypersurface(P1xP1) Closed subscheme of 2-d CPR-Fano toric variety covered by 4 affine patches defined by: - a1*s^2*x^2 + a0*t^2*x^2 + a6*s*t*x*y + a3*s^2*y^2 + a2*t^2*y^2 + a0*s^2*x^2 + a3*t^2*x^2 + a6*s*t*x*y + a1*s^2*y^2 + a2*t^2*y^2 Check that finite fields are handled correctly :trac:`14899`:: diff --git a/src/sage/schemes/toric/variety.py b/src/sage/schemes/toric/variety.py index 2d9c1de3a44..6e243626f6f 100644 --- a/src/sage/schemes/toric/variety.py +++ b/src/sage/schemes/toric/variety.py @@ -177,10 +177,10 @@ True sage: TV = ToricVariety(NormalFan(diamond)) sage: TV.fan().rays() - N(-1, 1), N( 1, 1), + N( 1, -1), N(-1, -1), - N( 1, -1) + N(-1, 1) in 2-d lattice N sage: TV.is_orbifold() True @@ -191,14 +191,14 @@ sage: TV3 = ToricVariety(NormalFan(lattice_polytope.cross_polytope(3))) sage: TV3.fan().rays() - N(-1, -1, 1), - N( 1, -1, 1), - N(-1, 1, 1), + N( 1, -1, -1), + N( 1, 1, -1), N( 1, 1, 1), + N( 1, -1, 1), + N(-1, -1, 1), N(-1, -1, -1), - N( 1, -1, -1), N(-1, 1, -1), - N( 1, 1, -1) + N(-1, 1, 1) in 3-d lattice N sage: TV3.is_orbifold() False @@ -970,15 +970,15 @@ def affine_patch(self, i): Scheme morphism: From: 2-d affine toric variety To: 2-d toric variety covered by 4 affine patches - Defn: Defined on coordinates by sending [x : t] to - [x : 1 : 1 : t] + Defn: Defined on coordinates by sending [y : t] to + [1 : 1 : y : t] sage: patch1 = P1xP1.affine_patch(1) sage: patch1.embedding_morphism() Scheme morphism: From: 2-d affine toric variety To: 2-d toric variety covered by 4 affine patches - Defn: Defined on coordinates by sending [y : t] to - [1 : 1 : y : t] + Defn: Defined on coordinates by sending [s : y] to + [1 : s : y : 1] sage: patch1 is P1xP1.affine_patch(1) True """ @@ -1118,8 +1118,8 @@ def embedding_morphism(self): Scheme morphism: From: 2-d affine toric variety To: 2-d toric variety covered by 4 affine patches - Defn: Defined on coordinates by sending [x : t] to - [x : 1 : 1 : t] + Defn: Defined on coordinates by sending [y : t] to + [1 : 1 : y : t] """ try: return self._embedding_morphism From efff0c4593822a80695a1ba19d164ce26c3c188d Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Sat, 11 Feb 2017 16:34:46 +0100 Subject: [PATCH 040/185] Test that sage library is (not) valid Python 3 --- src/sage/tests/py3_syntax.py | 175 +++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 src/sage/tests/py3_syntax.py diff --git a/src/sage/tests/py3_syntax.py b/src/sage/tests/py3_syntax.py new file mode 100644 index 00000000000..6f37b6a7d8e --- /dev/null +++ b/src/sage/tests/py3_syntax.py @@ -0,0 +1,175 @@ +""" +Test that the Sage library uses Python 3 syntax + +EXAMPLES:: + + sage: from sage.tests.py3_syntax import Python3SyntaxTest + sage: py3_syntax = Python3SyntaxTest('sage', 'sage_setup') + sage: py3_syntax.run_tests('.py') # long time + Invalid Python 3 syntax found: + File "src/sage/combinat/growth.py", line 259 + self._covers_1 = lambda (a,b): True + ^ + SyntaxError: invalid syntax +""" + +from __future__ import print_function + +import os +import sys +import itertools +import subprocess + +from sage.env import SAGE_SRC + + +class SortedDirectoryWalkerABC(object): + + def __init__(self, *directories): + """ + Walk directory tree in a reproducible manner + + INPUT: + + -- ``*directories`` - Roots of the directory trees to walk. + + EXAMPLES:: + + sage: from sage.tests.py3_syntax import Python3SyntaxTest + sage: Python3SyntaxTest('sage/tests') + + """ + self._directories = tuple( + os.path.join(SAGE_SRC, d) for d in directories + ) + + def __iter__(self): + """ + Iterate over files + + OUTPUT: + + Iterator over triples consisting of path, filename, and file + extension. The iteration order only depends on the filenames + and not on filesystem layout. + + EXAMPLES:: + + sage: from sage.tests.py3_syntax import Python3SyntaxTest + sage: test = Python3SyntaxTest('sage/tests/french_book') + sage: next(iter(test)) + ('src/sage/tests/french_book', 'README', '') + """ + tree_walk = itertools.chain(*map(os.walk, self._directories)) + for path, dirs, files in tree_walk: + path = os.path.relpath(path) + dirs.sort() + files.sort() + for filename in files: + if filename.startswith('.'): + continue + _, ext = os.path.splitext(filename) + yield (path, filename, ext) + + def run_tests(self, *extensions): + """ + Run tests + + The abstract :meth:`test` is called on each file with a + matching extension. + + INPUT: + + -- ``*extensions`` - the file extensions (including the leading dot) + to check. + + EXAMPLES:: + sage: from sage.tests.py3_syntax import SortedDirectoryWalkerABC + sage: walker = SortedDirectoryWalkerABC('sage/tests/french_book') + sage: walker.run_tests('.py') + Traceback (most recent call last): + ... + NotImplementedError: to be implemented in derived class + """ + buf = [] + for (path, filename, ext) in self: + if ext in extensions: + fqn = os.path.join(path, filename) + buf.append(fqn) + if len(buf) > 20: + self.test(*buf) + buf = [] + self.test(*buf) + + def test(self, *filenames): + """ + Test the given filenames + + To be implemented in derived classes. + + INPUT: + + -- ``*filename`` -- string. The full qualified filenames to check. + + EXAMPLES:: + + sage: from sage.tests.py3_syntax import SortedDirectoryWalkerABC + sage: walker = SortedDirectoryWalkerABC() + sage: from sage.env import SAGE_SRC + sage: filename = os.path.join(SAGE_SRC, 'sage', 'tests', 'py3_syntax.py') + sage: walker.test(filename) + Traceback (most recent call last): + ... + NotImplementedError: to be implemented in derived class + """ + raise NotImplementedError('to be implemented in derived class') + + +PYTHON3_ENV = dict(os.environ) +PYTHON3_ENV.pop('PYTHONPATH', None) + + +class Python3SyntaxTest(SortedDirectoryWalkerABC): + + def test(self, *filenames): + r""" + Test that the given filenames are valid Python 3 syntax + + INPUT: + + -- ``filename`` -- string. The full qualified filename to check. + + EXAMPLES:: + + sage: import os, tempfile + sage: src = tempfile.NamedTemporaryFile(suffix='.py', delete=False) + sage: src.write('print "invalid print statement') + sage: src.close() + sage: from sage.tests.py3_syntax import Python3SyntaxTest + sage: py3_syntax = Python3SyntaxTest() + sage: py3_syntax.test(src.name) + Invalid Python 3 syntax found: + File "...py", line 1 + print "invalid print statement + ^ + SyntaxError: Missing parentheses in call to 'print' + sage: os.unlink(src.name) + """ + cmd = [ + 'python3', + '-m', 'py_compile' + ] + list(filenames) + process = subprocess.Popen( + cmd, + env=PYTHON3_ENV, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + stdout, stderr = process.communicate() + if process.returncode == 0: + return + print('Invalid Python 3 syntax found:') + if stdout: + print(stdout) + if stderr: + print(stderr) From 9ac02b5fd3dbb0252c6d96bd16be9fadedc76c8a Mon Sep 17 00:00:00 2001 From: John Cremona Date: Mon, 13 Feb 2017 16:28:32 +0000 Subject: [PATCH 041/185] #22164 one more doctest after review --- src/sage/libs/eclib/newforms.pyx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sage/libs/eclib/newforms.pyx b/src/sage/libs/eclib/newforms.pyx index 413cf7d4014..7857f79b9d3 100644 --- a/src/sage/libs/eclib/newforms.pyx +++ b/src/sage/libs/eclib/newforms.pyx @@ -134,6 +134,9 @@ cdef class ECModularSymbol: sage: mem2 = get_memory_usage() sage: (mem2-mem < 1) or (mem2 - mem) True + + sage: ECModularSymbol.__new__(ECModularSymbol) + Modular symbol with sign 0 over Rational Field attached to None """ def __init__(self, E, sign=1): """ From 47969450c6e7e449a126438d55fcdaf040a281ac Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Mon, 12 Dec 2016 21:58:13 +0100 Subject: [PATCH 042/185] Bug in Poset.is_slender(?) --- src/sage/combinat/posets/posets.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 343aa8e9e24..5cec398948a 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -6379,10 +6379,11 @@ def is_slender(self, certificate=False): for y in self.upper_covers(x): for c in self.upper_covers(y): d[c] = d.get(c, 0) + 1 - if not all(y < 3 for y in itervalues(d)): - if certificate: - return (False, (x, c)) - return False + for c, y in six.iteritems(d): + if y >= 3: + if certificate: + return (False, (x, c)) + return False if certificate: return (True, None) return True From eeeca4e18188129045fd5ca5bfa1df8bcffad293 Mon Sep 17 00:00:00 2001 From: John Cremona Date: Thu, 16 Feb 2017 10:46:12 +0000 Subject: [PATCH 043/185] #22164 improve doctest --- src/sage/libs/eclib/newforms.pyx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/libs/eclib/newforms.pyx b/src/sage/libs/eclib/newforms.pyx index 7857f79b9d3..1f7667a15fd 100644 --- a/src/sage/libs/eclib/newforms.pyx +++ b/src/sage/libs/eclib/newforms.pyx @@ -125,14 +125,16 @@ cdef class ECModularSymbol: TESTS: Until :trac:`22164`, eclib had a memory leak. Here we test that - it has gone:: + it has gone. After one call to create an ECModularSymbol, which + may use up some memory, further calls use no more:: sage: from sage.libs.eclib.newforms import ECModularSymbol sage: E = EllipticCurve([1,1,0,-108,-432]) # conductor 930 + sage: for _ in range(2): M = ECModularSymbol(E) # long time sage: mem = get_memory_usage() sage: for _ in range(10): M = ECModularSymbol(E) # long time sage: mem2 = get_memory_usage() - sage: (mem2-mem < 1) or (mem2 - mem) + sage: (mem2==mem) or (mem2 - mem) True sage: ECModularSymbol.__new__(ECModularSymbol) From e4e56651e3252781f3eb04af00082f7c63be816b Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Sat, 18 Feb 2017 23:01:40 +0100 Subject: [PATCH 044/185] Upgraded curl to 7.52.1 --- build/pkgs/curl/checksums.ini | 6 +++--- build/pkgs/curl/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/curl/checksums.ini b/build/pkgs/curl/checksums.ini index 058027b2288..02da2005459 100644 --- a/build/pkgs/curl/checksums.ini +++ b/build/pkgs/curl/checksums.ini @@ -1,4 +1,4 @@ tarball=curl-VERSION.tar.bz2 -sha1=f02a14bbe580d2a8cf3bf45a79d39eb595220ac7 -md5=09a7c5769a7eae676d5e2c86d51f167e -cksum=1653697676 +sha1=aa9f2300096d806c68c7ba8c50771853d1b43eb4 +md5=dd014df06ff1d12e173de86873f9f77a +cksum=2873185834 diff --git a/build/pkgs/curl/package-version.txt b/build/pkgs/curl/package-version.txt index a260e0b3f4f..adeee46ddd0 100644 --- a/build/pkgs/curl/package-version.txt +++ b/build/pkgs/curl/package-version.txt @@ -1 +1 @@ -7.51.0 +7.52.1 From e2ed0148c1d7a3314564752a29d8deaed50e79da Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Sat, 20 Aug 2016 12:52:58 +0200 Subject: [PATCH 045/185] Upgrade R to 3.3.1 (correct on Linux). --- build/pkgs/r/SPKG.txt | 2 ++ build/pkgs/r/checksums.ini | 6 ++-- build/pkgs/r/package-version.txt | 2 +- build/pkgs/r/patches/R.sh.patch | 5 ++- build/pkgs/r/patches/configure.patch | 12 ++++--- .../dont_lose_libz_libbz2_in_configure.patch | 29 +++++------------ .../pkgs/r/patches/large_address_aware.patch | 32 ------------------- build/pkgs/r/patches/parent_sig_handler.patch | 11 +++---- .../pkgs/r/patches/scripts.Makefile.in.patch | 4 +-- 9 files changed, 30 insertions(+), 73 deletions(-) delete mode 100644 build/pkgs/r/patches/large_address_aware.patch diff --git a/build/pkgs/r/SPKG.txt b/build/pkgs/r/SPKG.txt index 87cd8ac7189..73fe0e31732 100644 --- a/build/pkgs/r/SPKG.txt +++ b/build/pkgs/r/SPKG.txt @@ -39,5 +39,7 @@ much code written for S runs unaltered under R. #9668. * large_address_aware.patch: don't pass --large-address-aware to ld on Cygwin64. + This patch is lost since R.3.3.1, which no longer has cygwin-specific + info in configure.ac or Makefile.in. Fixed upstream ? * parent_sig_handler.patch: make sure the parent_sig_handler function is defined before getting used. diff --git a/build/pkgs/r/checksums.ini b/build/pkgs/r/checksums.ini index 9d30a3c85ab..db7aa117dc4 100644 --- a/build/pkgs/r/checksums.ini +++ b/build/pkgs/r/checksums.ini @@ -1,4 +1,4 @@ tarball=R-VERSION.tar.gz -sha1=54d8b02b4564655f1be84b4a830813f8452b5e9c -md5=552b0c8088bab08ca4188797b919a58f -cksum=3467446071 +sha1=df853188d3e2b1c2d32393016401c432a5192c4d +md5=f50a659738b73036e2f5635adbd229c5 +cksum=3471175850 diff --git a/build/pkgs/r/package-version.txt b/build/pkgs/r/package-version.txt index bc738ca130e..5d2bbf510a5 100644 --- a/build/pkgs/r/package-version.txt +++ b/build/pkgs/r/package-version.txt @@ -1 +1 @@ -3.2.4-revised.p0 +3.3.1.p0 diff --git a/build/pkgs/r/patches/R.sh.patch b/build/pkgs/r/patches/R.sh.patch index cf496406564..1af2db2e636 100644 --- a/build/pkgs/r/patches/R.sh.patch +++ b/build/pkgs/r/patches/R.sh.patch @@ -1,6 +1,5 @@ -diff -ru src/src/scripts/R.sh.in src.new/src/scripts/R.sh.in ---- src/src/scripts/R.sh.in 2011-10-03 00:02:35.000000000 +0200 -+++ src.new/src/scripts/R.sh.in 2012-03-30 17:17:12.409254535 +0200 +--- R-3.3.1_original/src/scripts/R.sh.in 2015-03-19 00:04:01.000000000 +0100 ++++ R-3.3.1_patched/src/scripts/R.sh.in 2016-08-20 11:00:30.903135744 +0200 @@ -26,6 +26,14 @@ esac fi diff --git a/build/pkgs/r/patches/configure.patch b/build/pkgs/r/patches/configure.patch index 10450b347c0..9a3c205b46b 100644 --- a/build/pkgs/r/patches/configure.patch +++ b/build/pkgs/r/patches/configure.patch @@ -1,7 +1,9 @@ -diff -ru src/configure src.configure/configure ---- src/configure 2011-10-24 00:05:54.000000000 +0200 -+++ src.configure/configure 2012-03-30 16:31:51.409247321 +0200 -@@ -22877,7 +22493,7 @@ +In searching verbose option, search for '-###' first. + +diff -ru R-3.3.1_original/configure R-3.3.1_patched/configure +--- R-3.3.1_original/configure 2016-06-14 00:16:32.000000000 +0200 ++++ R-3.3.1_patched/configure 2016-08-20 09:45:26.658178374 +0200 +@@ -24682,7 +24682,7 @@ if ac_fn_f77_try_compile "$LINENO"; then : ac_cv_prog_f77_v= # Try some options frequently used verbose output @@ -10,7 +12,7 @@ diff -ru src/configure src.configure/configure cat > conftest.$ac_ext <<_ACEOF program main -@@ -23233,7 +22809,7 @@ +@@ -25038,7 +25038,7 @@ if ac_fn_c_try_compile "$LINENO"; then : r_cv_prog_c_v= # Try some options frequently used verbose output diff --git a/build/pkgs/r/patches/dont_lose_libz_libbz2_in_configure.patch b/build/pkgs/r/patches/dont_lose_libz_libbz2_in_configure.patch index 707d2893920..605ae91a5d8 100644 --- a/build/pkgs/r/patches/dont_lose_libz_libbz2_in_configure.patch +++ b/build/pkgs/r/patches/dont_lose_libz_libbz2_in_configure.patch @@ -2,10 +2,9 @@ Fix bug in R_PCRE autoconf macro which leads to 'configure' losing '-lz' and/or '-lbz2' from LIBS (under certain circumstances, and only relevant if "system" versions of these libraries are used). (cf. #18229) - ---- R-3.2.0/m4/R.m4 2015-03-19 00:02:06.000000000 +0100 -+++ R-3.2.0/m4/R.m4 2015-05-04 18:09:13.742304005 +0200 -@@ -3107,11 +3107,11 @@ +--- R-3.3.1_original/m4/R.m4 2016-03-17 00:02:06.000000000 +0100 ++++ R-3.3.1_patched/m4/R.m4 2016-08-20 10:17:08.663006152 +0200 +@@ -3193,7 +3193,6 @@ #endif } ]])], [r_cv_have_pcre810=yes], [r_cv_have_pcre810=no], [r_cv_have_pcre810=no])]) @@ -13,23 +12,11 @@ if "system" versions of these libraries are used). (cf. #18229) if test "x${r_cv_have_pcre810}" != xyes; then have_pcre=no LIBS="${r_save_LIBS}" +@@ -3216,6 +3215,7 @@ + } + ]])], [r_cv_have_pcre832=yes], [r_cv_have_pcre832=no], [r_cv_have_pcre832=no])]) fi +fi - AC_MSG_CHECKING([whether PCRE support needs to be compiled]) - if test "x${r_cv_have_pcre810}" = xyes; then - AC_MSG_RESULT([no]) ---- R-3.2.0/configure 2015-04-09 00:16:36.000000000 +0200 -+++ R-3.2.0/configure 2015-05-04 18:19:37.942304048 +0200 -@@ -34543,11 +34543,11 @@ - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $r_cv_have_pcre810" >&5 - $as_echo "$r_cv_have_pcre810" >&6; } --fi + + AC_MSG_CHECKING([whether PCRE support suffices]) if test "x${r_cv_have_pcre810}" != xyes; then - have_pcre=no - LIBS="${r_save_LIBS}" - fi -+fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether PCRE support needs to be compiled" >&5 - $as_echo_n "checking whether PCRE support needs to be compiled... " >&6; } - if test "x${r_cv_have_pcre810}" = xyes; then diff --git a/build/pkgs/r/patches/large_address_aware.patch b/build/pkgs/r/patches/large_address_aware.patch deleted file mode 100644 index 48bfa8f8023..00000000000 --- a/build/pkgs/r/patches/large_address_aware.patch +++ /dev/null @@ -1,32 +0,0 @@ -diff -druN r-3.0.2.orig/configure.ac r-3.0.2/configure.ac ---- r-3.0.2.orig/configure.ac 2013-08-26 15:05:06.000000000 -0700 -+++ r-3.0.2/configure.ac 2014-01-18 09:35:57.516091309 -0800 -@@ -1310,7 +1321,11 @@ - SHLIB_EXT=".dll" - dylib_undefined_allowed=no - is_cygwin=yes -- main_ldflags="${wl}--large-address-aware ${wl}--stack=0xA00000" -+ if test "${host_cpu}" = "x86_64"; then -+ main_ldflags="${wl}--stack=0xA00000" -+ else -+ main_ldflags="${wl}--large-address-aware ${wl}--stack=0xA00000" -+ fi - ;; - darwin*) - darwin_pic="-fPIC" -diff -druN r-3.0.2.orig/configure r-3.0.2/configure ---- r-3.0.2.orig/configure 2013-09-17 15:06:13.000000000 -0700 -+++ r-3.0.2/configure 2014-01-18 09:38:03.426103900 -0800 -@@ -26313,7 +26247,11 @@ - SHLIB_EXT=".dll" - dylib_undefined_allowed=no - is_cygwin=yes -- main_ldflags="${wl}--large-address-aware ${wl}--stack=0xA00000" -+ if test "${host_cpu}" = "x86_64"; then -+ main_ldflags="${wl}--stack=0xA00000" -+ else -+ main_ldflags="${wl}--large-address-aware ${wl}--stack=0xA00000" -+ fi - ;; - darwin*) - darwin_pic="-fPIC" diff --git a/build/pkgs/r/patches/parent_sig_handler.patch b/build/pkgs/r/patches/parent_sig_handler.patch index 5906aab68f1..7f71c081d98 100644 --- a/build/pkgs/r/patches/parent_sig_handler.patch +++ b/build/pkgs/r/patches/parent_sig_handler.patch @@ -1,14 +1,13 @@ -diff -druN R-3.1.1/src/library/parallel/src/fork.c R-3.1.1.patched/src/library/parallel/src/fork.c ---- R-3.1.1/src/library/parallel/src/fork.c 2014-05-27 15:15:04.000000000 -0700 -+++ R-3.1.1.patched/src/library/parallel/src/fork.c 2014-11-14 07:37:12.567530830 -0800 -@@ -227,15 +227,15 @@ +--- R-3.3.1_original/src/library/parallel/src/fork.c 2016-03-17 00:02:50.000000000 +0100 ++++ R-3.3.1_patched/src/library/parallel/src/fork.c 2016-08-20 10:54:42.799029599 +0200 +@@ -227,15 +227,16 @@ #else /* sigaction is not viable, so use the "dumb" way to clean up anything that comes our way */ -static void setup_sig_handler() { - signal(SIGCHLD, parent_sig_handler); -} -- + static void parent_sig_handler(int sig) { /* clean up when a child terminates */ if (sig == SIGCHLD) @@ -20,4 +19,4 @@ diff -druN R-3.1.1/src/library/parallel/src/fork.c R-3.1.1.patched/src/library/p +} #endif - /* from Defn.h */ + SEXP mc_fork(SEXP sEstranged) diff --git a/build/pkgs/r/patches/scripts.Makefile.in.patch b/build/pkgs/r/patches/scripts.Makefile.in.patch index 1d38a935dcd..0a7d53bb473 100644 --- a/build/pkgs/r/patches/scripts.Makefile.in.patch +++ b/build/pkgs/r/patches/scripts.Makefile.in.patch @@ -1,5 +1,5 @@ ---- src/src/scripts/Makefile.in 2012-03-01 15:02:25.000000000 -0800 -+++ src/src/scripts/Makefile.in 2013-03-17 08:48:56.000000000 -0700 +--- R-3.3.1_original/src/scripts/Makefile.in 2013-08-05 00:05:05.000000000 +0200 ++++ R-3.3.1_patched/src/scripts/Makefile.in 2016-08-20 11:06:19.103189078 +0200 @@ -90,10 +90,7 @@ install: installdirs install-cmds @rm -f $(DESTDIR)$(bindir)/R From f52cf730ab855ca4426a5f8f6e2a611bb322b9ba Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Wed, 31 Aug 2016 07:59:29 +0000 Subject: [PATCH 046/185] Update patches set for R upgrade. --- build/pkgs/r/SPKG.txt | 23 +-- build/pkgs/r/patches/R.sh.patch | 17 -- ...nfigure.patch => autoconf_verb_dash.patch} | 14 +- build/pkgs/r/patches/cygwin.patch | 155 ++++++++++++++++++ build/pkgs/r/patches/hardcoded_dirs.patch | 37 +++++ ..._in_configure.patch => m4_macro_bug.patch} | 0 build/pkgs/r/patches/parent_sig_handler.patch | 9 +- .../pkgs/r/patches/scripts.Makefile.in.patch | 14 -- build/pkgs/r/patches/undefined_symbols.patch | 13 ++ build/pkgs/r/spkg-install | 20 +-- 10 files changed, 226 insertions(+), 76 deletions(-) delete mode 100644 build/pkgs/r/patches/R.sh.patch rename build/pkgs/r/patches/{configure.patch => autoconf_verb_dash.patch} (65%) mode change 100644 => 100755 create mode 100755 build/pkgs/r/patches/cygwin.patch create mode 100755 build/pkgs/r/patches/hardcoded_dirs.patch rename build/pkgs/r/patches/{dont_lose_libz_libbz2_in_configure.patch => m4_macro_bug.patch} (100%) mode change 100644 => 100755 mode change 100644 => 100755 build/pkgs/r/patches/parent_sig_handler.patch delete mode 100644 build/pkgs/r/patches/scripts.Makefile.in.patch create mode 100755 build/pkgs/r/patches/undefined_symbols.patch diff --git a/build/pkgs/r/SPKG.txt b/build/pkgs/r/SPKG.txt index 73fe0e31732..f455817542c 100644 --- a/build/pkgs/r/SPKG.txt +++ b/build/pkgs/r/SPKG.txt @@ -21,25 +21,4 @@ much code written for S runs unaltered under R. * GNU patch * iconv * Readline - * ATLAS - -== Special Update/Build Instructions == - -=== Patches === - * configure.patch: Use -### instead of -v to detect linker options. - See Sage ticket #12787 and upstream ticket - https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=14865 - The corresponding patch to m4/clibs.m4 is not included, as - autoconf-2.68 gives errors, even on the clean upstream sources. - * R.sh.in: Set R_HOME_DIR to "${SAGE_LOCAL}/lib/R/" when running R. - * scripts.Makefile.in.patch: the file src/src/scripts/R.sh.in - defines R_SHARE_DIR, R_INCLUDE_DIR, and R_DOC_DIR relative to - R_HOME_DIR, but scripts/Makefile.in hardcodes these - locations. This patch removes this hardcoding. See Sage trac - #9668. - * large_address_aware.patch: don't pass --large-address-aware to ld on - Cygwin64. - This patch is lost since R.3.3.1, which no longer has cygwin-specific - info in configure.ac or Makefile.in. Fixed upstream ? - * parent_sig_handler.patch: make sure the parent_sig_handler function is - defined before getting used. + * BLAS/LAPACK diff --git a/build/pkgs/r/patches/R.sh.patch b/build/pkgs/r/patches/R.sh.patch deleted file mode 100644 index 1af2db2e636..00000000000 --- a/build/pkgs/r/patches/R.sh.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- R-3.3.1_original/src/scripts/R.sh.in 2015-03-19 00:04:01.000000000 +0100 -+++ R-3.3.1_patched/src/scripts/R.sh.in 2016-08-20 11:00:30.903135744 +0200 -@@ -26,6 +26,14 @@ - esac - fi - -+# R in the Sage installation, we set this to allow moving the Sage -+# install tree. -+# This script is also used during R's spkg-install, do not change -+# R_HOME_DIR then (spkg-install sets SAGE_BUILDING_R=yes). -+if test x$SAGE_BUILDING_R = x; then -+ R_HOME_DIR="$SAGE_LOCAL/lib/R/" -+fi -+ - if test -n "${R_HOME}" && \ - test "${R_HOME}" != "${R_HOME_DIR}"; then - echo "WARNING: ignoring environment value of R_HOME" diff --git a/build/pkgs/r/patches/configure.patch b/build/pkgs/r/patches/autoconf_verb_dash.patch old mode 100644 new mode 100755 similarity index 65% rename from build/pkgs/r/patches/configure.patch rename to build/pkgs/r/patches/autoconf_verb_dash.patch index 9a3c205b46b..46c4656a520 --- a/build/pkgs/r/patches/configure.patch +++ b/build/pkgs/r/patches/autoconf_verb_dash.patch @@ -1,9 +1,9 @@ -In searching verbose option, search for '-###' first. - -diff -ru R-3.3.1_original/configure R-3.3.1_patched/configure ---- R-3.3.1_original/configure 2016-06-14 00:16:32.000000000 +0200 -+++ R-3.3.1_patched/configure 2016-08-20 09:45:26.658178374 +0200 -@@ -24682,7 +24682,7 @@ +Bug in autoconf and R macros. +See https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=14865 +diff -ru src/configure src.configure/configure +--- src/configure 2011-10-24 00:05:54.000000000 +0200 ++++ src.configure/configure 2012-03-30 16:31:51.409247321 +0200 +@@ -22877,7 +22493,7 @@ if ac_fn_f77_try_compile "$LINENO"; then : ac_cv_prog_f77_v= # Try some options frequently used verbose output @@ -12,7 +12,7 @@ diff -ru R-3.3.1_original/configure R-3.3.1_patched/configure cat > conftest.$ac_ext <<_ACEOF program main -@@ -25038,7 +25038,7 @@ +@@ -23233,7 +22809,7 @@ if ac_fn_c_try_compile "$LINENO"; then : r_cv_prog_c_v= # Try some options frequently used verbose output diff --git a/build/pkgs/r/patches/cygwin.patch b/build/pkgs/r/patches/cygwin.patch new file mode 100755 index 00000000000..6657214bf63 --- /dev/null +++ b/build/pkgs/r/patches/cygwin.patch @@ -0,0 +1,155 @@ +Add Cygwin support into configure. +Taken from Cygwin's R-conf.patch. +--- orig/configure.ac 2016-03-17 00:04:40.000000000 +0100 ++++ new/configure.ac 2016-06-26 15:52:27.680611400 +0200 +@@ -1316,6 +1316,15 @@ + shlib_cxxldflags="-shared ${shlib_cxxldflags}" + fi + ;; ++ cygwin*) ++ ## All Windows code is PIC ++ cpicflags= ++ cxxpicflags= ++ fpicflags= ++ fcpicflags= ++ SHLIB_EXT=".dll" ++ dylib_undefined_allowed=no ++ ;; + darwin*) + darwin_pic="-fPIC" + dylib_undefined_allowed=no +@@ -1576,7 +1585,7 @@ + : ${CPICFLAGS="${cpicflags}"} + if test -z "${CPICFLAGS}"; then + case "${host_os}" in +- aix*|irix*|mingw*|osf*) ++ aix*|cygwin*|irix*|mingw*|osf*) + ;; + *) + AC_MSG_WARN([I could not determine CPICFLAGS.]) +@@ -1588,7 +1597,7 @@ + : ${FPICFLAGS="${fpicflags}"} + if test -z "${FPICFLAGS}"; then + case "${host_os}" in +- aix*|irix*|mingw*|osf*) ++ aix*|cygwin*|irix*|mingw*|osf*) + ;; + *) + AC_MSG_WARN([I could not determine FPICFLAGS.]) +@@ -1600,7 +1619,7 @@ + : ${CXXPICFLAGS="${cxxpicflags}"} + if test -z "${CXXPICFLAGS}"; then + case "${host_os}" in +- aix*|irix*|mingw*|osf*) ++ aix*|cygwin*|irix*|mingw*|osf*) + ;; + *) + warn_cxxpicflags="I could not determine CXXPICFLAGS." +@@ -1655,6 +1664,9 @@ + # RLAPACK_LDFLAGS="${wl}-bE:\$(top_builddir)/etc/Rlapack.exp" + # LAPACK_LDFLAGS="${wl}-bI:\$(R_HOME)/etc/Rlapack.exp" + ;; ++ cygwin*) ++ dylib_ldflags="${SHLIB_LDFLAGS} ${wl}--out-implib ${wl}\$@.a" ++ ;; + darwin*) + DYLIB_EXT=".dylib" + dylib_ldflags="${darwin_dylib_ldflags}" + +Manually autogenerated stuff from the above. +--- orig/configure 2016-03-17 00:04:40.000000000 +0100 ++++ new/configure 2016-06-26 15:52:27.680611400 +0200 +@@ -28113,6 +28113,15 @@ + shlib_cxxldflags="-shared ${shlib_cxxldflags}" + fi + ;; ++ cygwin*) ++ ## All Windows code is PIC ++ cpicflags= ++ cxxpicflags= ++ fpicflags= ++ fcpicflags= ++ SHLIB_EXT=".dll" ++ dylib_undefined_allowed=no ++ ;; + darwin*) + darwin_pic="-fPIC" + dylib_undefined_allowed=no +@@ -28389,7 +28398,7 @@ + : ${CPICFLAGS="${cpicflags}"} + if test -z "${CPICFLAGS}"; then + case "${host_os}" in +- aix*|irix*|mingw*|osf*) ++ aix*|cygwin*|irix*|mingw*|osf*) + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: I could not determine CPICFLAGS." >&5 +@@ -28402,7 +28411,7 @@ + : ${FPICFLAGS="${fpicflags}"} + if test -z "${FPICFLAGS}"; then + case "${host_os}" in +- aix*|irix*|mingw*|osf*) ++ aix*|cygwin*|irix*|mingw*|osf*) + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: I could not determine FPICFLAGS." >&5 +@@ -28415,7 +28424,7 @@ + : ${CXXPICFLAGS="${cxxpicflags}"} + if test -z "${CXXPICFLAGS}"; then + case "${host_os}" in +- aix*|irix*|mingw*|osf*) ++ aix*|cygwin*|irix*|mingw*|osf*) + ;; + *) + warn_cxxpicflags="I could not determine CXXPICFLAGS." +@@ -28485,6 +28494,9 @@ + # RLAPACK_LDFLAGS="${wl}-bE:\$(top_builddir)/etc/Rlapack.exp" + # LAPACK_LDFLAGS="${wl}-bI:\$(R_HOME)/etc/Rlapack.exp" + ;; ++ cygwin*) ++ dylib_ldflags="${SHLIB_LDFLAGS} ${wl}--out-implib ${wl}\$@.a" ++ ;; + darwin*) + DYLIB_EXT=".dylib" + dylib_ldflags="${darwin_dylib_ldflags}" + +Chunks to install import libraries. +Taken from Cygwin's R-makeconf.patch. +--- orig/src/main/Makefile.in 2016-03-17 00:04:14.000000000 +0100 ++++ new/src/main/Makefile.in 2016-06-27 09:53:05.263801100 +0200 +@@ -198,7 +198,8 @@ + @$(SHELL) $(top_srcdir)/tools/copy-if-change $(R_binary) "$(DESTDIR)$(Rexecbindir2)/R" + install-lib: installdirs + @$(MKINSTALLDIRS) "$(DESTDIR)$(Rexeclibdir)" +- @$(SHELL) $(top_srcdir)/tools/copy-if-change $(libR_la) "$(DESTDIR)$(Rexeclibdir)/$(libR_la)" ++ @$(SHELL) $(top_srcdir)/tools/copy-if-change $(libR_la) "$(DESTDIR)$(bindir)/$(libR_la)" ++ @$(SHELL) $(top_srcdir)/tools/copy-if-change libR.dll.a "$(DESTDIR)$(Rexeclibdir)/libR.dll.a" + install-static: installdirs + @$(MKINSTALLDIRS) "$(DESTDIR)$(Rexeclibdir)" + @$(SHELL) $(top_srcdir)/tools/copy-if-change libR.a "$(DESTDIR)$(Rexeclibdir)/libR.a" +--- orig/src/nmath/standalone/Makefile.in 2015-12-11 00:15:18.000000000 +0100 ++++ new/src/nmath/standalone/Makefile.in 2016-06-27 10:28:26.614932800 +0200 +@@ -134,7 +134,8 @@ + -L. -lRmath $(LIBM) + + install: installdirs install-header @WANT_R_FRAMEWORK_FALSE@ install-pc +-@WANT_R_FRAMEWORK_FALSE@ @!(test -f $(libRmath_la)) || $(SHELL) $(top_srcdir)/tools/copy-if-change $(libRmath_la) $(DESTDIR)$(libdir)/$(libRmath_la) ++@WANT_R_FRAMEWORK_FALSE@ @!(test -f $(libRmath_la)) || $(SHELL) $(top_srcdir)/tools/copy-if-change $(libRmath_la) $(DESTDIR)$(bindir)/$(libRmath_la) ++@WANT_R_FRAMEWORK_FALSE@ @!(test -f libRmath.dll.a) || $(SHELL) $(top_srcdir)/tools/copy-if-change libRmath.dll.a $(DESTDIR)$(libdir)/libRmath.dll.a + @WANT_R_FRAMEWORK_FALSE@ @!(test -f libRmath.a) || $(SHELL) $(top_srcdir)/tools/copy-if-change libRmath.a $(DESTDIR)$(libdir)/libRmath.a + @WANT_R_FRAMEWORK_TRUE@ @!(test -f $(libRmath_la)) || cp $(libRmath_la) $(R_FRAMEWORK_DIR)/Versions/$(FW_VERSION)/Resources/lib/$(libRmath_la) && install_name_tool -id $(R_FRAMEWORK_DIR)/Versions/$(FW_VERSION)/Resources/lib/$(libRmath_la) $(R_FRAMEWORK_DIR)/Versions/$(FW_VERSION)/Resources/lib/$(libRmath_la) + @WANT_R_FRAMEWORK_TRUE@ @!(test -f libRmath.a) || $(SHELL) $(top_srcdir)/tools/copy-if-change libRmath.a $(R_FRAMEWORK_DIR)/Versions/$(FW_VERSION)/Resources/lib/libRmath.a + +Make sure the R install command finds the R executable. +Taken from Cygwin's 2.12-install-arch.patch. +--- orig/src/library/tools/R/install.R 2011-02-15 17:05:01.000000000 -0600 ++++ new/src/library/tools/R/install.R 2011-03-07 20:28:34.946411600 -0600 +@@ -712,7 +712,7 @@ + setwd(owd) + test_archs <- archs + for(arch in archs) { +- if (arch == "R") { ++ if (arch == "R" || arch == "R.exe") { + ## top-level, so one arch without subdirs + has_error <- run_shlib(pkg_name, srcs, instdir, "") + } else { diff --git a/build/pkgs/r/patches/hardcoded_dirs.patch b/build/pkgs/r/patches/hardcoded_dirs.patch new file mode 100755 index 00000000000..1313bc868ac --- /dev/null +++ b/build/pkgs/r/patches/hardcoded_dirs.patch @@ -0,0 +1,37 @@ +Make R_HOME_DIR relative to SAGE_LOCAL. +This allows to move Sage install tree. +diff -ru src/src/scripts/R.sh.in src.new/src/scripts/R.sh.in +--- src/src/scripts/R.sh.in 2011-10-03 00:02:35.000000000 +0200 ++++ src.new/src/scripts/R.sh.in 2012-03-30 17:17:12.409254535 +0200 +@@ -26,6 +26,12 @@ + esac + fi + ++# Make R_HOME_DIR relative to SAGE_LOCAL ++# unless SAGE_BUILDING_R is set (as spkg-install does). ++if -z $SAGE_BUILDING_R; then ++ R_HOME_DIR="$SAGE_LOCAL/lib/R/" ++fi ++ + if test -n "${R_HOME}" && \ + test "${R_HOME}" != "${R_HOME_DIR}"; then + echo "WARNING: ignoring environment value of R_HOME" + +Remove the sed scripts hardcoding R_*_DIR's in the "frontend" R script. +--- src/src/scripts/Makefile.in 2012-03-01 15:02:25.000000000 -0800 ++++ src/src/scripts/Makefile.in 2013-03-17 08:48:56.000000000 -0700 +@@ -89,12 +89,7 @@ + + install: installdirs install-cmds + @rm -f $(DESTDIR)$(bindir)/R +- @(d=`$(ECHO) '$(rhome)' | sed 's,/,\\\/,g';`; \ +- d2=`$(ECHO) '$(rsharedir)' | sed 's,/,\\\/,g';`; \ +- d3=`$(ECHO) '$(rincludedir)' | sed 's,/,\\\/,g';`; \ +- d4=`$(ECHO) '$(rdocdir)' | sed 's,/,\\\/,g';`; \ +- sed -e "1,/R_HOME_DIR=/s/\\(R_HOME_DIR=\\).*/\\1$${d}/;" -e "s/\\(R_SHARE_DIR=\\).*/\\1$${d2}/;" -e "s/\\(R_INCLUDE_DIR=\\).*/\\1$${d3}/;" -e "s/\\(R_DOC_DIR=\\).*/\\1$${d4}/;"\ +- < R.fe > "$(DESTDIR)$(Rexecbindir)/R") ++ @cat R.fe > "$(DESTDIR)$(Rexecbindir)/R" + @$(INSTALL_SCRIPT) "$(DESTDIR)$(Rexecbindir)/R" "$(DESTDIR)$(bindir)/R" + @chmod 755 "$(DESTDIR)$(bindir)/R" "$(DESTDIR)$(Rexecbindir)/R" + ## why of all the scripts does this alone chmod just one copy? + diff --git a/build/pkgs/r/patches/dont_lose_libz_libbz2_in_configure.patch b/build/pkgs/r/patches/m4_macro_bug.patch old mode 100644 new mode 100755 similarity index 100% rename from build/pkgs/r/patches/dont_lose_libz_libbz2_in_configure.patch rename to build/pkgs/r/patches/m4_macro_bug.patch diff --git a/build/pkgs/r/patches/parent_sig_handler.patch b/build/pkgs/r/patches/parent_sig_handler.patch old mode 100644 new mode 100755 index 7f71c081d98..b196eba5083 --- a/build/pkgs/r/patches/parent_sig_handler.patch +++ b/build/pkgs/r/patches/parent_sig_handler.patch @@ -1,13 +1,14 @@ ---- R-3.3.1_original/src/library/parallel/src/fork.c 2016-03-17 00:02:50.000000000 +0100 -+++ R-3.3.1_patched/src/library/parallel/src/fork.c 2016-08-20 10:54:42.799029599 +0200 -@@ -227,15 +227,16 @@ +diff -druN R-3.1.1/src/library/parallel/src/fork.c R-3.1.1.patched/src/library/parallel/src/fork.c +--- R-3.1.1/src/library/parallel/src/fork.c 2014-05-27 15:15:04.000000000 -0700 ++++ R-3.1.1.patched/src/library/parallel/src/fork.c 2014-11-14 07:37:12.567530830 -0800 +@@ -227,15 +227,15 @@ #else /* sigaction is not viable, so use the "dumb" way to clean up anything that comes our way */ -static void setup_sig_handler() { - signal(SIGCHLD, parent_sig_handler); -} - +- static void parent_sig_handler(int sig) { /* clean up when a child terminates */ if (sig == SIGCHLD) diff --git a/build/pkgs/r/patches/scripts.Makefile.in.patch b/build/pkgs/r/patches/scripts.Makefile.in.patch deleted file mode 100644 index 0a7d53bb473..00000000000 --- a/build/pkgs/r/patches/scripts.Makefile.in.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- R-3.3.1_original/src/scripts/Makefile.in 2013-08-05 00:05:05.000000000 +0200 -+++ R-3.3.1_patched/src/scripts/Makefile.in 2016-08-20 11:06:19.103189078 +0200 -@@ -90,10 +90,7 @@ - install: installdirs install-cmds - @rm -f $(DESTDIR)$(bindir)/R - @(d=`$(ECHO) '$(rhome)' | sed 's,/,\\\/,g';`; \ -- d2=`$(ECHO) '$(rsharedir)' | sed 's,/,\\\/,g';`; \ -- d3=`$(ECHO) '$(rincludedir)' | sed 's,/,\\\/,g';`; \ -- d4=`$(ECHO) '$(rdocdir)' | sed 's,/,\\\/,g';`; \ -- sed -e "1,/R_HOME_DIR=/s/\\(R_HOME_DIR=\\).*/\\1$${d}/;" -e "s/\\(R_SHARE_DIR=\\).*/\\1$${d2}/;" -e "s/\\(R_INCLUDE_DIR=\\).*/\\1$${d3}/;" -e "s/\\(R_DOC_DIR=\\).*/\\1$${d4}/;"\ -+ sed -e "1,/R_HOME_DIR=/s/\\(R_HOME_DIR=\\).*/\\1$${d}/;"\ - < R.fe > "$(DESTDIR)$(Rexecbindir)/R") - @$(INSTALL_SCRIPT) "$(DESTDIR)$(Rexecbindir)/R" "$(DESTDIR)$(bindir)/R" - @chmod 755 "$(DESTDIR)$(bindir)/R" "$(DESTDIR)$(Rexecbindir)/R" diff --git a/build/pkgs/r/patches/undefined_symbols.patch b/build/pkgs/r/patches/undefined_symbols.patch new file mode 100755 index 00000000000..68dcf4aa6d3 --- /dev/null +++ b/build/pkgs/r/patches/undefined_symbols.patch @@ -0,0 +1,13 @@ +Properly list needed libs. +Taken from Cygwin's R-makeconf.patch. +--- orig/etc/Makeconf.in 2016-03-17 00:04:44.000000000 +0100 ++++ new/etc/Makeconf.in 2016-06-26 17:38:05.398615000 +0200 +@@ -123,7 +123,7 @@ + ALL_OBJCXXFLAGS = $(PKG_OBJCXXFLAGS) $(CXXPICFLAGS) $(SHLIB_CXXFLAGS) $(OBJCXXFLAGS) + ALL_FFLAGS = $(R_XTRA_FFLAGS) $(PKG_FFLAGS) $(FPICFLAGS) $(SHLIB_FFLAGS) $(FFLAGS) + ## LIBR here as a couple of packages use this without SHLIB_LINK +-ALL_LIBS = $(PKG_LIBS) $(SHLIB_LIBADD) $(LIBR)@DYLIB_UNDEFINED_ALLOWED_FALSE@ $(LIBINTL) ++ALL_LIBS = $(PKG_LIBS) $(SHLIB_LIBADD) $(LIBR)@DYLIB_UNDEFINED_ALLOWED_FALSE@ $(LIBINTL) $(LIBS) + + .SUFFIXES: + .SUFFIXES: .c .cc .cpp .d .f .f90 .f95 .m .mm .M .o diff --git a/build/pkgs/r/spkg-install b/build/pkgs/r/spkg-install index 6f5a4af9804..3c16934d90f 100755 --- a/build/pkgs/r/spkg-install +++ b/build/pkgs/r/spkg-install @@ -87,12 +87,6 @@ if [ "$UNAME" = "Darwin" ]; then fi fi -if [ "$UNAME" = "CYGWIN" ]; then - # Cygwin libm does not provide "long double" functions - # and we do not install Cephes on Cygwin at the moment - R_CONFIGURE="--disable-long-double $R_CONFIGURE" -fi - if [ "$SAGE_FAT_BINARY" = yes ]; then echo "Disabling ICU, OpenMP for a binary build" R_CONFIGURE="--without-ICU --disable-openmp $R_CONFIGURE" @@ -124,12 +118,14 @@ export SAGE_BUILDING_R=yes config() { ./configure \ - --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" \ - --with-readline=yes \ - --with-x=$XSUPPORT \ - "$R_CONFIGURE_BLAS" \ - "$R_CONFIGURE_LAPACK" \ - $R_CONFIGURE + --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" \ + --enable-R-shlib \ + --with-recommended-packages \ + --with-readline=yes \ + --with-x=$XSUPPORT \ + "$R_CONFIGURE_BLAS" \ + "$R_CONFIGURE_LAPACK" \ + $R_CONFIGURE } config From a2daccdd1ad2006bce0a17197a1af36bff1d3ac5 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Thu, 1 Sep 2016 07:25:29 +0000 Subject: [PATCH 047/185] Remove duplicated "--enable-R-shlib". --- build/pkgs/r/spkg-install | 5 ----- 1 file changed, 5 deletions(-) diff --git a/build/pkgs/r/spkg-install b/build/pkgs/r/spkg-install index 3c16934d90f..fafbde6cc51 100755 --- a/build/pkgs/r/spkg-install +++ b/build/pkgs/r/spkg-install @@ -39,11 +39,6 @@ if [ "$UNAME" = "Darwin" ]; then cp patches/javac "$SAGE_LOCAL"/bin fi - -# Determine special configure options $R_CONFIGURE (don't put paths in -# this variable as this can cause problems with quoting) -R_CONFIGURE="--enable-R-shlib $R_CONFIGURE" - # Note by Karl-Dieter Crisman, April 12th 2010. X support would be nice # to have in OSX, but see # http://CRAN.R-project.org/bin/macosx/RMacOSX-FAQ.html#X11-window-server-_0028optional_0029 From 2dc7c4f1142d545d95629ee56a92fc36f348b33d Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Thu, 1 Sep 2016 07:28:30 +0000 Subject: [PATCH 048/185] Replace tabs by spaces in R spkg-install. --- build/pkgs/r/spkg-install | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build/pkgs/r/spkg-install b/build/pkgs/r/spkg-install index fafbde6cc51..c71ed00dce5 100755 --- a/build/pkgs/r/spkg-install +++ b/build/pkgs/r/spkg-install @@ -113,14 +113,14 @@ export SAGE_BUILDING_R=yes config() { ./configure \ - --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" \ + --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" \ --enable-R-shlib \ --with-recommended-packages \ - --with-readline=yes \ - --with-x=$XSUPPORT \ - "$R_CONFIGURE_BLAS" \ - "$R_CONFIGURE_LAPACK" \ - $R_CONFIGURE + --with-readline=yes \ + --with-x=$XSUPPORT \ + "$R_CONFIGURE_BLAS" \ + "$R_CONFIGURE_LAPACK" \ + $R_CONFIGURE } config From c5e99f6ad8244d84120bd4c5ee51294d07de7055 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Thu, 1 Sep 2016 07:49:00 +0000 Subject: [PATCH 049/185] Apply some R patches only on Cygwin. --- build/pkgs/r/patches/{ => cygwin}/cygwin.patch | 0 .../patches/{ => cygwin}/undefined_symbols.patch | 1 + build/pkgs/r/spkg-install | 16 ++++++++++++++++ 3 files changed, 17 insertions(+) rename build/pkgs/r/patches/{ => cygwin}/cygwin.patch (100%) rename build/pkgs/r/patches/{ => cygwin}/undefined_symbols.patch (91%) diff --git a/build/pkgs/r/patches/cygwin.patch b/build/pkgs/r/patches/cygwin/cygwin.patch similarity index 100% rename from build/pkgs/r/patches/cygwin.patch rename to build/pkgs/r/patches/cygwin/cygwin.patch diff --git a/build/pkgs/r/patches/undefined_symbols.patch b/build/pkgs/r/patches/cygwin/undefined_symbols.patch similarity index 91% rename from build/pkgs/r/patches/undefined_symbols.patch rename to build/pkgs/r/patches/cygwin/undefined_symbols.patch index 68dcf4aa6d3..888443f3c95 100755 --- a/build/pkgs/r/patches/undefined_symbols.patch +++ b/build/pkgs/r/patches/cygwin/undefined_symbols.patch @@ -1,5 +1,6 @@ Properly list needed libs. Taken from Cygwin's R-makeconf.patch. +Might be needed on other system as well to avoid underlinking. --- orig/etc/Makeconf.in 2016-03-17 00:04:44.000000000 +0100 +++ new/etc/Makeconf.in 2016-06-26 17:38:05.398615000 +0200 @@ -123,7 +123,7 @@ diff --git a/build/pkgs/r/spkg-install b/build/pkgs/r/spkg-install index c71ed00dce5..cf28ef86346 100755 --- a/build/pkgs/r/spkg-install +++ b/build/pkgs/r/spkg-install @@ -100,6 +100,22 @@ fi cd src +# Move patches only applied on Cygwin. +if [ "$UNAME" = "CYGWIN" ]; then + mv patches/cygwin/*.patch patches/ +fi + +# Apply patches. +for patch in ../patches/*.patch; do + [ -r "$patch" ] || continue + patch -p1 <"$patch" + if [ $? -ne 0 ]; then + echo >&2 "Error applying '$patch'" + exit 1 + fi +done + + if [ "$UNAME" = "Darwin" ]; then # Fixing install_name(s) sed -i -e 's:\"-install_name :\"-install_name ${libdir}/R/lib/:' configure From c1aba6f7b3e5ccd5dc30aaf68c8ebe4d85fa40bb Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Thu, 1 Sep 2016 07:50:29 +0000 Subject: [PATCH 050/185] Fix permission of R patches. --- build/pkgs/r/patches/autoconf_verb_dash.patch | 0 build/pkgs/r/patches/cygwin/cygwin.patch | 0 build/pkgs/r/patches/cygwin/undefined_symbols.patch | 0 build/pkgs/r/patches/hardcoded_dirs.patch | 0 build/pkgs/r/patches/m4_macro_bug.patch | 0 build/pkgs/r/patches/parent_sig_handler.patch | 0 6 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 build/pkgs/r/patches/autoconf_verb_dash.patch mode change 100755 => 100644 build/pkgs/r/patches/cygwin/cygwin.patch mode change 100755 => 100644 build/pkgs/r/patches/cygwin/undefined_symbols.patch mode change 100755 => 100644 build/pkgs/r/patches/hardcoded_dirs.patch mode change 100755 => 100644 build/pkgs/r/patches/m4_macro_bug.patch mode change 100755 => 100644 build/pkgs/r/patches/parent_sig_handler.patch diff --git a/build/pkgs/r/patches/autoconf_verb_dash.patch b/build/pkgs/r/patches/autoconf_verb_dash.patch old mode 100755 new mode 100644 diff --git a/build/pkgs/r/patches/cygwin/cygwin.patch b/build/pkgs/r/patches/cygwin/cygwin.patch old mode 100755 new mode 100644 diff --git a/build/pkgs/r/patches/cygwin/undefined_symbols.patch b/build/pkgs/r/patches/cygwin/undefined_symbols.patch old mode 100755 new mode 100644 diff --git a/build/pkgs/r/patches/hardcoded_dirs.patch b/build/pkgs/r/patches/hardcoded_dirs.patch old mode 100755 new mode 100644 diff --git a/build/pkgs/r/patches/m4_macro_bug.patch b/build/pkgs/r/patches/m4_macro_bug.patch old mode 100755 new mode 100644 diff --git a/build/pkgs/r/patches/parent_sig_handler.patch b/build/pkgs/r/patches/parent_sig_handler.patch old mode 100755 new mode 100644 From b05ec4b418325635374d2c95c9a2a7d15180790d Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Thu, 1 Sep 2016 07:56:50 +0000 Subject: [PATCH 051/185] Make description of patches more verbose. --- build/pkgs/r/patches/autoconf_verb_dash.patch | 6 +++++- build/pkgs/r/patches/hardcoded_dirs.patch | 8 ++++++-- build/pkgs/r/patches/parent_sig_handler.patch | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/build/pkgs/r/patches/autoconf_verb_dash.patch b/build/pkgs/r/patches/autoconf_verb_dash.patch index 46c4656a520..591cd84d8f8 100644 --- a/build/pkgs/r/patches/autoconf_verb_dash.patch +++ b/build/pkgs/r/patches/autoconf_verb_dash.patch @@ -1,5 +1,9 @@ Bug in autoconf and R macros. -See https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=14865 +Use -### instead of -v to detect linker options. +See Sage ticket #12787 and R ticket +* https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=14865 +The corresponding patch to m4/clibs.m4 is not included, as +autoconf-2.68 gives errors, even on the clean upstream sources. diff -ru src/configure src.configure/configure --- src/configure 2011-10-24 00:05:54.000000000 +0200 +++ src.configure/configure 2012-03-30 16:31:51.409247321 +0200 diff --git a/build/pkgs/r/patches/hardcoded_dirs.patch b/build/pkgs/r/patches/hardcoded_dirs.patch index 1313bc868ac..fe09161ab40 100644 --- a/build/pkgs/r/patches/hardcoded_dirs.patch +++ b/build/pkgs/r/patches/hardcoded_dirs.patch @@ -1,4 +1,9 @@ -Make R_HOME_DIR relative to SAGE_LOCAL. +Make R_HOME_DIR relative to SAGE_LOCAL by setting +R_HOME_DIR to "${SAGE_LOCAL}/lib/R/" when running R. + +Also remove the sed scripts hardcoding R_*_DIR's in the "frontend" R script. +See Sage trac #9668. + This allows to move Sage install tree. diff -ru src/src/scripts/R.sh.in src.new/src/scripts/R.sh.in --- src/src/scripts/R.sh.in 2011-10-03 00:02:35.000000000 +0200 @@ -17,7 +22,6 @@ diff -ru src/src/scripts/R.sh.in src.new/src/scripts/R.sh.in test "${R_HOME}" != "${R_HOME_DIR}"; then echo "WARNING: ignoring environment value of R_HOME" -Remove the sed scripts hardcoding R_*_DIR's in the "frontend" R script. --- src/src/scripts/Makefile.in 2012-03-01 15:02:25.000000000 -0800 +++ src/src/scripts/Makefile.in 2013-03-17 08:48:56.000000000 -0700 @@ -89,12 +89,7 @@ diff --git a/build/pkgs/r/patches/parent_sig_handler.patch b/build/pkgs/r/patches/parent_sig_handler.patch index b196eba5083..ad7d8907b62 100644 --- a/build/pkgs/r/patches/parent_sig_handler.patch +++ b/build/pkgs/r/patches/parent_sig_handler.patch @@ -1,3 +1,4 @@ +make sure the parent_sig_handler function is defined before getting used. diff -druN R-3.1.1/src/library/parallel/src/fork.c R-3.1.1.patched/src/library/parallel/src/fork.c --- R-3.1.1/src/library/parallel/src/fork.c 2014-05-27 15:15:04.000000000 -0700 +++ R-3.1.1.patched/src/library/parallel/src/fork.c 2014-11-14 07:37:12.567530830 -0800 From 3b58ad092c8cfc9dda7a738d965f8e2ace753f4c Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Thu, 1 Sep 2016 08:36:40 +0000 Subject: [PATCH 052/185] Fix SAGE_BUILDING_R patch. --- build/pkgs/r/patches/hardcoded_dirs.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/r/patches/hardcoded_dirs.patch b/build/pkgs/r/patches/hardcoded_dirs.patch index fe09161ab40..150b3796f56 100644 --- a/build/pkgs/r/patches/hardcoded_dirs.patch +++ b/build/pkgs/r/patches/hardcoded_dirs.patch @@ -14,7 +14,7 @@ diff -ru src/src/scripts/R.sh.in src.new/src/scripts/R.sh.in +# Make R_HOME_DIR relative to SAGE_LOCAL +# unless SAGE_BUILDING_R is set (as spkg-install does). -+if -z $SAGE_BUILDING_R; then ++if test -z "$SAGE_BUILDING_R"; then + R_HOME_DIR="$SAGE_LOCAL/lib/R/" +fi + From fecbfc003dab34596d7869bb25d03976519c2cf9 Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Sun, 23 Oct 2016 23:30:48 +0200 Subject: [PATCH 053/185] Three-keystroke patch ; depend on xz. --- build/pkgs/r/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/r/dependencies b/build/pkgs/r/dependencies index 179a318c491..ee74acfdd1e 100644 --- a/build/pkgs/r/dependencies +++ b/build/pkgs/r/dependencies @@ -1,4 +1,4 @@ -$(BLAS) iconv readline | pkgconf +$(BLAS) iconv readline xz | pkgconf ---------- All lines of this file are ignored except the first. From 3a4eb9c923b5ab0edc4c9a297d91401da9e731c6 Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Wed, 30 Nov 2016 23:17:23 +0100 Subject: [PATCH 054/185] Updating R source to 3.3.2. --- build/pkgs/r/checksums.ini | 6 +++--- build/pkgs/r/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/r/checksums.ini b/build/pkgs/r/checksums.ini index db7aa117dc4..4c348a19482 100644 --- a/build/pkgs/r/checksums.ini +++ b/build/pkgs/r/checksums.ini @@ -1,4 +1,4 @@ tarball=R-VERSION.tar.gz -sha1=df853188d3e2b1c2d32393016401c432a5192c4d -md5=f50a659738b73036e2f5635adbd229c5 -cksum=3471175850 +sha1=0e39e9c2d28fe6bab9c55ca23e08ba8727fd2fca +md5=2437014ef40641cdc9673e89c040b7a8 +cksum=1781035256 diff --git a/build/pkgs/r/package-version.txt b/build/pkgs/r/package-version.txt index 5d2bbf510a5..e5691ee639c 100644 --- a/build/pkgs/r/package-version.txt +++ b/build/pkgs/r/package-version.txt @@ -1 +1 @@ -3.3.1.p0 +3.3.2.p0 From 55a8aa40b5d85c54b0c325bf942734e337523e8b Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Thu, 1 Dec 2016 21:05:00 +0100 Subject: [PATCH 055/185] R's strig representation of source code has changed. Updated docstrings accordingly. --- src/sage/interfaces/r.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/interfaces/r.py b/src/sage/interfaces/r.py index a13406593b8..2fd9562d07f 100644 --- a/src/sage/interfaces/r.py +++ b/src/sage/interfaces/r.py @@ -595,7 +595,7 @@ def _source(self, s): EXAMPLES:: sage: print(r._source("c")) - function (..., recursive = FALSE) .Primitive("c") + function (...) .Primitive("c") """ if s[-2:] == "()": s = s[-2:] @@ -614,7 +614,7 @@ def source(self, s): EXAMPLES:: sage: print(r.source("c")) - function (..., recursive = FALSE) .Primitive("c") + function (...) .Primitive("c") """ return self._source(s) From 00fcc86787adbe81e7e000cd04ae1c7630ea9c94 Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Sat, 18 Feb 2017 18:20:14 +0100 Subject: [PATCH 056/185] Depend on PCRE --- build/pkgs/r/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/r/dependencies b/build/pkgs/r/dependencies index ee74acfdd1e..6fc56843cde 100644 --- a/build/pkgs/r/dependencies +++ b/build/pkgs/r/dependencies @@ -1,4 +1,4 @@ -$(BLAS) iconv readline xz | pkgconf +$(BLAS) iconv readline xz pcre | pkgconf ---------- All lines of this file are ignored except the first. From 23f9471c1235759b4906361112f32cd179134a1b Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Sat, 18 Feb 2017 18:35:35 +0100 Subject: [PATCH 057/185] Update spkg-install to conform to #20692. --- build/pkgs/r/spkg-install | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/build/pkgs/r/spkg-install b/build/pkgs/r/spkg-install index cf28ef86346..7552f634ade 100755 --- a/build/pkgs/r/spkg-install +++ b/build/pkgs/r/spkg-install @@ -100,22 +100,6 @@ fi cd src -# Move patches only applied on Cygwin. -if [ "$UNAME" = "CYGWIN" ]; then - mv patches/cygwin/*.patch patches/ -fi - -# Apply patches. -for patch in ../patches/*.patch; do - [ -r "$patch" ] || continue - patch -p1 <"$patch" - if [ $? -ne 0 ]; then - echo >&2 "Error applying '$patch'" - exit 1 - fi -done - - if [ "$UNAME" = "Darwin" ]; then # Fixing install_name(s) sed -i -e 's:\"-install_name :\"-install_name ${libdir}/R/lib/:' configure @@ -130,8 +114,6 @@ config() { ./configure \ --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" \ - --enable-R-shlib \ - --with-recommended-packages \ --with-readline=yes \ --with-x=$XSUPPORT \ "$R_CONFIGURE_BLAS" \ From 22974b8e19e5df9fb6a0fb402b220729dcd14477 Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Sat, 18 Feb 2017 19:16:05 +0100 Subject: [PATCH 058/185] R-shlib is needed in configurefor the (standard) rpy2 package. --- build/pkgs/r/spkg-install | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/pkgs/r/spkg-install b/build/pkgs/r/spkg-install index 7552f634ade..84fa953817b 100755 --- a/build/pkgs/r/spkg-install +++ b/build/pkgs/r/spkg-install @@ -114,6 +114,8 @@ config() { ./configure \ --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" \ + --enable-R-shlib \ + --with-recommended-packages \ --with-readline=yes \ --with-x=$XSUPPORT \ "$R_CONFIGURE_BLAS" \ From d8736709ee4e7e914e4c289a885ad7abefa829b7 Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Sat, 18 Feb 2017 23:08:30 +0100 Subject: [PATCH 059/185] Added curl to dependencies. --- build/pkgs/r/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/r/dependencies b/build/pkgs/r/dependencies index 6fc56843cde..eb7d7b7870c 100644 --- a/build/pkgs/r/dependencies +++ b/build/pkgs/r/dependencies @@ -1,4 +1,4 @@ -$(BLAS) iconv readline xz pcre | pkgconf +$(BLAS) iconv readline xz pcre curl | pkgconf ---------- All lines of this file are ignored except the first. From 8e0761131da60b81249e559694659c78ccfcf6cc Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Mon, 20 Feb 2017 21:41:03 +0100 Subject: [PATCH 060/185] Reinsert Cygwin-specific patches (lost in the mist of battle). --- build/pkgs/r/spkg-install | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build/pkgs/r/spkg-install b/build/pkgs/r/spkg-install index 84fa953817b..9cea0c33963 100755 --- a/build/pkgs/r/spkg-install +++ b/build/pkgs/r/spkg-install @@ -110,6 +110,11 @@ fi # See patches/R.sh.patch export SAGE_BUILDING_R=yes +# Move patches only applied on Cygwin. +if [ "$UNAME" = "CYGWIN" ]; then + mv patches/cygwin/*.patch patches/ +fi + config() { ./configure \ From c71e098f033bfed64a63d72657e001d270e262c4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 20 Feb 2017 16:44:21 -0800 Subject: [PATCH 061/185] RealSet: Fix pickling, category initialization --- src/sage/sets/real_set.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/sage/sets/real_set.py b/src/sage/sets/real_set.py index 992f7112328..def43c44eb8 100644 --- a/src/sage/sets/real_set.py +++ b/src/sage/sets/real_set.py @@ -64,6 +64,7 @@ class RealSet. from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation +from sage.categories.sets_cat import Sets from sage.rings.all import ZZ from sage.rings.real_lazy import LazyFieldElement, RLF from sage.rings.infinity import infinity, minus_infinity @@ -615,8 +616,12 @@ def __classcall__(cls, *args): EXAMPLES:: - sage: RealSet(RealSet.open_closed(0,1), RealSet.closed_open(2,3)) + sage: R = RealSet(RealSet.open_closed(0,1), RealSet.closed_open(2,3)); R (0, 1] + [2, 3) + + TESTS:: + + sage: TestSuite(R).run() """ if len(args) == 1 and isinstance(args[0], RealSet): return args[0] # common optimization @@ -644,9 +649,9 @@ def __classcall__(cls, *args): else: raise ValueError(str(arg) + ' does not determine real interval') intervals = RealSet.normalize(intervals) - return UniqueRepresentation.__classcall__(cls, intervals) + return UniqueRepresentation.__classcall__(cls, *intervals) - def __init__(self, intervals): + def __init__(self, *intervals): """ A subset of the real line @@ -671,6 +676,7 @@ def __init__(self, intervals): sage: RealSet(i, [3,4]) # list of two numbers = closed set (0, 1) + [3, 4] """ + Parent.__init__(self, category = Sets()) self._intervals = intervals def __cmp__(self, other): From bfc26ef6badfd02ca88dcd69bd5e86684d1dce41 Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Tue, 21 Feb 2017 11:38:52 +0100 Subject: [PATCH 062/185] Wups. chmod +x spkg-install... --- build/pkgs/pcre/spkg-install | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 build/pkgs/pcre/spkg-install diff --git a/build/pkgs/pcre/spkg-install b/build/pkgs/pcre/spkg-install old mode 100644 new mode 100755 From 6bdcdee6c48bbebdd3674fc3c2469a9f3d2e9bb9 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Thu, 23 Feb 2017 13:15:35 +0000 Subject: [PATCH 063/185] Draft update to singular 4.1.0p2. --- build/pkgs/singular/checksums.ini | 6 +- build/pkgs/singular/package-version.txt | 2 +- build/pkgs/singular/patches/fgets.patch | 22 ----- build/pkgs/singular/patches/grobner.patch | 22 ----- .../singular/patches/libnamebuf_length.patch | 97 ------------------- build/pkgs/singular/patches/nfCoeffName.patch | 37 ------- .../pkgs/singular/patches/nrnCoeffName.patch | 45 --------- .../pkgs/singular/patches/xalloc_unused.patch | 28 ------ src/sage/libs/singular/decl.pxd | 4 +- src/sage/libs/singular/ring.pyx | 4 +- .../multi_polynomial_libsingular.pyx | 28 +++--- .../polynomial/polynomial_quotient_ring.py | 2 +- .../polynomial_singular_interface.py | 34 +++---- src/sage/rings/polynomial/term_order.py | 4 +- src/sage/rings/quotient_ring.py | 2 +- src/sage/rings/quotient_ring_element.py | 2 +- 16 files changed, 40 insertions(+), 299 deletions(-) delete mode 100644 build/pkgs/singular/patches/fgets.patch delete mode 100644 build/pkgs/singular/patches/grobner.patch delete mode 100644 build/pkgs/singular/patches/libnamebuf_length.patch delete mode 100644 build/pkgs/singular/patches/nfCoeffName.patch delete mode 100644 build/pkgs/singular/patches/nrnCoeffName.patch delete mode 100644 build/pkgs/singular/patches/xalloc_unused.patch diff --git a/build/pkgs/singular/checksums.ini b/build/pkgs/singular/checksums.ini index 2fce3e6b89b..095fbdcd445 100644 --- a/build/pkgs/singular/checksums.ini +++ b/build/pkgs/singular/checksums.ini @@ -1,4 +1,4 @@ tarball=singular-VERSION.tar.gz -sha1=f85ba08b4b676bbedbda74ef74a627e952e85e9d -md5=fee4999c27050ff2a0b8512ed59ac766 -cksum=3934325236 +sha1=74822e905a19475281753274f1121f90f7848ead +md5=98ba5874e4c42b782c77572670bb5e2a +cksum=1099301299 diff --git a/build/pkgs/singular/package-version.txt b/build/pkgs/singular/package-version.txt index bd2a330b800..cf689942371 100644 --- a/build/pkgs/singular/package-version.txt +++ b/build/pkgs/singular/package-version.txt @@ -1 +1 @@ -4.1.0p1 +4.1.0p2 diff --git a/build/pkgs/singular/patches/fgets.patch b/build/pkgs/singular/patches/fgets.patch deleted file mode 100644 index d4e42dcd512..00000000000 --- a/build/pkgs/singular/patches/fgets.patch +++ /dev/null @@ -1,22 +0,0 @@ -Make sure Singular does not choke if its stdin gets closed. -diff --git a/kernel/oswrapper/feread.cc b/kernel/oswrapper/feread.cc -index 0513c9c..87b9214 100644 ---- a/kernel/oswrapper/feread.cc -+++ b/kernel/oswrapper/feread.cc -@@ -325,12 +325,13 @@ char * fe_fgets(const char *pr,char *s, int size) - /* NULL can mean various things... */ - switch(errno) - { -- case 0: return NULL; /*EOF */ -+ case 0: return NULL; /* EOF */ -+ case EBADF: return NULL; /* stdin got closed */ - case EINTR: return strcpy(s,"\n"); /* CTRL-C or other signal */ - default: /* other error */ - { -- int errsv = errno; -- fprintf(stderr,"fgets() failed with errno %d\n",errsv); -+ int errsv = errno; -+ fprintf(stderr,"fgets() failed with errno %d\n%s\n",errsv,strerror(errsv)); - return NULL; - } - } diff --git a/build/pkgs/singular/patches/grobner.patch b/build/pkgs/singular/patches/grobner.patch deleted file mode 100644 index 1992c619757..00000000000 --- a/build/pkgs/singular/patches/grobner.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 589e8eab0d5415b844ad43ec150a72e4004e1114 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Hans=20Sch=C3=B6nemann?= -Date: Wed, 21 Dec 2016 19:00:51 +0100 -Subject: [PATCH] fix: charstr in standard::groebner for ZZ, ZZ/m - ---- - Singular/LIB/standard.lib | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Singular/LIB/standard.lib b/Singular/LIB/standard.lib -index d657b98..f7ee564 100644 ---- a/Singular/LIB/standard.lib -+++ b/Singular/LIB/standard.lib -@@ -881,7 +881,7 @@ EXAMPLE: example groebner; shows an example" - else {ideal i=i_par; } // int, poly, number, ideal - kill i_par; - // check for integer etc coefficients -- if (charstr(basering)[1]=="i") // either integer or integer,q -+ if (attrib(basering,"ring_cf")==1) // either integer or integer,q - { - if (find(option(),"prot")) { "calling std for ideals in ring with ring coefficients"; } - return (std(i)); diff --git a/build/pkgs/singular/patches/libnamebuf_length.patch b/build/pkgs/singular/patches/libnamebuf_length.patch deleted file mode 100644 index 9b81b5151fe..00000000000 --- a/build/pkgs/singular/patches/libnamebuf_length.patch +++ /dev/null @@ -1,97 +0,0 @@ -Increase the hardcoded library file name buffer size - -See https://trac.sagemath.org/ticket/22175 - ---- -diff --git a/Singular/fehelp.cc b/Singular/fehelp.cc -index df00135..2fb2f5d 100644 ---- a/Singular/fehelp.cc -+++ b/Singular/fehelp.cc -@@ -702,7 +702,7 @@ static BOOLEAN heOnlineHelp(char* s) - return FALSE; - } - -- char libnamebuf[128]; -+ char libnamebuf[1024]; - FILE *fp=NULL; - // first, search for library of that name - if ((str[1]!='\0') && -diff --git a/Singular/iparith.cc b/Singular/iparith.cc -index 9843bb1..a1472e8 100644 ---- a/Singular/iparith.cc -+++ b/Singular/iparith.cc -@@ -5193,7 +5193,7 @@ BOOLEAN jjWAITALL1(leftv res, leftv u) - - BOOLEAN jjLOAD(const char *s, BOOLEAN autoexport) - { -- char libnamebuf[256]; -+ char libnamebuf[1024]; - lib_types LT = type_of_LIB(s, libnamebuf); - - #ifdef HAVE_DYNAMIC_LOADING -@@ -5228,7 +5228,7 @@ BOOLEAN jjLOAD(const char *s, BOOLEAN autoexport) - package savepack=currPack; - currPack=IDPACKAGE(pl); - IDPACKAGE(pl)->loaded=TRUE; -- char libnamebuf[256]; -+ char libnamebuf[1024]; - FILE * fp = feFopen( s, "r", libnamebuf, TRUE ); - BOOLEAN bo=iiLoadLIB(fp, libnamebuf, s, pl, autoexport, TRUE); - currPack=savepack; -diff --git a/Singular/iplib.cc b/Singular/iplib.cc -index a0fdff9..2bd6e7b 100644 ---- a/Singular/iplib.cc -+++ b/Singular/iplib.cc -@@ -656,7 +656,7 @@ iiGetBuiltinModInit(const char* libname) - BOOLEAN iiTryLoadLib(leftv v, const char *id) - { - BOOLEAN LoadResult = TRUE; -- char libnamebuf[128]; -+ char libnamebuf[1024]; - char *libname = (char *)omAlloc(strlen(id)+5); - const char *suffix[] = { "", ".lib", ".so", ".sl", NULL }; - int i = 0; -@@ -672,7 +672,7 @@ BOOLEAN iiTryLoadLib(leftv v, const char *id) - { - char *s=omStrDup(libname); - #ifdef HAVE_DYNAMIC_LOADING -- char libnamebuf[256]; -+ char libnamebuf[1024]; - #endif - - if (LT==LT_SINGULAR) -@@ -717,7 +717,7 @@ BOOLEAN iiLocateLib(const char* lib, char* where) - - BOOLEAN iiLibCmd( char *newlib, BOOLEAN autoexport, BOOLEAN tellerror, BOOLEAN force ) - { -- char libnamebuf[128]; -+ char libnamebuf[1024]; - // procinfov pi; - // idhdl h; - idhdl pl; -diff --git a/Singular/libparse.cc b/Singular/libparse.cc -index 333999f..b468ed1 100644 ---- a/Singular/libparse.cc -+++ b/Singular/libparse.cc -@@ -1093,7 +1093,7 @@ BOOLEAN p_static = FALSE; - int old_state = 0; - lib_cmds last_cmd = LP_NONE; - --char libnamebuf[128]; -+char libnamebuf[1024]; - char *text_buffer=NULL; - long string_start; - -diff --git a/Singular/libparse.ll b/Singular/libparse.ll -index 3cd7abc..f85bb3b 100644 ---- a/Singular/libparse.ll -+++ b/Singular/libparse.ll -@@ -44,7 +44,7 @@ BOOLEAN p_static = FALSE; - int old_state = 0; - lib_cmds last_cmd = LP_NONE; - --char libnamebuf[128]; -+char libnamebuf[1024]; - char *text_buffer=NULL; - long string_start; - diff --git a/build/pkgs/singular/patches/nfCoeffName.patch b/build/pkgs/singular/patches/nfCoeffName.patch deleted file mode 100644 index a1d6b9c4503..00000000000 --- a/build/pkgs/singular/patches/nfCoeffName.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 61e85543ff6e6160d3d8c6b8fba50eb327f41679 Mon Sep 17 00:00:00 2001 -From: Hans Schoenemann -Date: Mon, 5 Dec 2016 10:13:42 +0100 -Subject: [PATCH] add: nfCoeffString (ffields.cc) - ---- - libpolys/coeffs/ffields.cc | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/libpolys/coeffs/ffields.cc b/libpolys/coeffs/ffields.cc -index b43162b..885dac6 100644 ---- a/libpolys/coeffs/ffields.cc -+++ b/libpolys/coeffs/ffields.cc -@@ -826,6 +826,15 @@ static char* nfCoeffString(const coeffs r) - return s; - } - -+static char nfCoeffName_buf[32]; -+static char* nfCoeffName(const coeffs r) -+{ -+ const char *p=n_ParameterNames(r)[0]; -+ nfCoeffName_buf[31]='\0'; -+ snprintf(nfCoeffName_buf,31,"ZZ/%ds[%s]",r->m_nfCharQ,p); -+ return nfCoeffName_buf; -+} -+ - static number nfRandom(siRandProc p,number ,number, const coeffs cf) - { - return (number)(long)(p() %(cf->m_nfCharQ+1)); -@@ -840,6 +849,7 @@ BOOLEAN nfInitChar(coeffs r, void * parameter) - r->cfKillChar=nfKillChar; - r->nCoeffIsEqual=nfCoeffIsEqual; - r->cfCoeffString=nfCoeffString; -+ r->cfCoeffName=nfCoeffName; - - r->cfMult = nfMult; - r->cfSub = nfSub; diff --git a/build/pkgs/singular/patches/nrnCoeffName.patch b/build/pkgs/singular/patches/nrnCoeffName.patch deleted file mode 100644 index 3ceb91e278c..00000000000 --- a/build/pkgs/singular/patches/nrnCoeffName.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 3f7f11c9a4692a3c651413c8cd45f6c9f01960d9 Mon Sep 17 00:00:00 2001 -From: Hans Schoenemann -Date: Sat, 3 Dec 2016 16:17:38 +0100 -Subject: [PATCH] add: nrnCoeffName for rmodulon.cc - ---- - libpolys/coeffs/rmodulon.cc | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/libpolys/coeffs/rmodulon.cc b/libpolys/coeffs/rmodulon.cc -index e2b55bd..80258e8 100644 ---- a/libpolys/coeffs/rmodulon.cc -+++ b/libpolys/coeffs/rmodulon.cc -@@ -86,6 +86,23 @@ void nrnCoeffWrite (const coeffs r, BOOLEAN /*details*/) - omFreeSize((ADDRESS)s, l); - } - -+static char* nrnCoeffName_buff=NULL; -+static char* nrnCoeffName(const coeffs r) -+{ -+ if(nrnCoeffName_buff==NULL) omFree(nrnCoeffName_buff); -+ size_t l = (size_t)mpz_sizeinbase(r->modBase, 10) + 2; -+ nrnCoeffName_buff=(char*)omAlloc(l+6); -+ char* s = (char*) omAlloc(l); -+ s= mpz_get_str (s, 10, r->modBase); -+ if (nCoeff_is_Ring_ModN(r)) -+ snprintf(nrnCoeffName_buff,l+6,"ZZ/%s",s); -+ else if (nCoeff_is_Ring_PtoM(r)) -+ snprintf(nrnCoeffName_buff,l+6,"ZZ/%s^lu",s,r->modExponent); -+ omFreeSize((ADDRESS)s, l); -+ return nrnCoeffName_buff; -+} -+ -+ - static BOOLEAN nrnCoeffsEqual(const coeffs r, n_coeffType n, void * parameter) - { - /* test, if r is an instance of nInitCoeffs(n,parameter) */ -@@ -213,6 +230,7 @@ BOOLEAN nrnInitChar (coeffs r, void* p) - r->cfExtGcd = nrnExtGcd; - r->cfXExtGcd = nrnXExtGcd; - r->cfQuotRem = nrnQuotRem; -+ r->cfCoeffName = nrnCoeffName; - r->cfCoeffWrite = nrnCoeffWrite; - r->nCoeffIsEqual = nrnCoeffsEqual; - r->cfKillChar = nrnKillChar; diff --git a/build/pkgs/singular/patches/xalloc_unused.patch b/build/pkgs/singular/patches/xalloc_unused.patch deleted file mode 100644 index 093a8ffccee..00000000000 --- a/build/pkgs/singular/patches/xalloc_unused.patch +++ /dev/null @@ -1,28 +0,0 @@ -commit 67e67da7e75dd2a71a25010346c18f728afb4a77 -Author: Jean-Pierre Flori -Date: Tue Dec 20 09:43:03 2016 +0000 - - Mark unused params as unused to get rid of compiler warnings. - -diff --git a/xalloc/omalloc.h b/xalloc/omalloc.h -index 80ae08d..473277d 100644 ---- a/xalloc/omalloc.h -+++ b/xalloc/omalloc.h -@@ -86,7 +86,7 @@ static inline void *omRealloc(void *d, size_t ns) - } - } - #define omReallocAligned(A,B) omRealloc(A,B) --static inline void *omReallocSize(void *d, size_t os, size_t ns) -+static inline void *omReallocSize(void *d, __attribute__((unused)) size_t os, size_t ns) - { if (d==NULL) return omAlloc(ns); - else - { -@@ -113,7 +113,7 @@ static inline void *omRealloc0(void *d, size_t ns) - } - return n; - } --static inline void omFreeSize(void *d, size_t s) -+static inline void omFreeSize(void *d, __attribute__((unused)) size_t s) - { if (d!=NULL) { long *dd=(long*)d; dd--; free(dd);}} - - static inline char * omStrDup(const char *s) diff --git a/src/sage/libs/singular/decl.pxd b/src/sage/libs/singular/decl.pxd index 4afc0cc4c0b..2dec5d82d4b 100644 --- a/src/sage/libs/singular/decl.pxd +++ b/src/sage/libs/singular/decl.pxd @@ -484,8 +484,8 @@ cdef extern from "singular/Singular/libsingular.h": ring *rDefault(int char , int nvars, char **names) ring *rDefault(const n_Procs_s* cf, int nvars, char **names) - ring *rDefault(int ch , int nvars, char **names,int ord_size, int *ord, int *block0, int *block1, int **wvhdl) - ring *rDefault(const n_Procs_s* cf, int nvars, char **names,int ord_size, int *ord, int *block0, int *block1, int **wvhdl) + ring *rDefault(int ch , int nvars, char **names,int ord_size, rRingOrder_t *ord, int *block0, int *block1, int **wvhdl) + ring *rDefault(const n_Procs_s* cf, int nvars, char **names,int ord_size, rRingOrder_t *ord, int *block0, int *block1, int **wvhdl) diff --git a/src/sage/libs/singular/ring.pyx b/src/sage/libs/singular/ring.pyx index 7a696975e01..c0a7a5d6b60 100644 --- a/src/sage/libs/singular/ring.pyx +++ b/src/sage/libs/singular/ring.pyx @@ -21,7 +21,7 @@ from sage.libs.gmp.mpz cimport mpz_init_set_ui, mpz_init_set from sage.libs.singular.decl cimport number, poly, ring, currRing from sage.libs.singular.decl cimport rChangeCurrRing, rCopy0, rComplete, rDelete, idInit from sage.libs.singular.decl cimport omAlloc0, omStrDup, omAlloc, omAlloc0Bin, sip_sring_bin, rnumber_bin -from sage.libs.singular.decl cimport ringorder_dp, ringorder_Dp, ringorder_lp, ringorder_rp, ringorder_ds, ringorder_Ds, ringorder_ls, ringorder_M, ringorder_C, ringorder_wp, ringorder_Wp, ringorder_ws, ringorder_Ws, ringorder_a +from sage.libs.singular.decl cimport ringorder_dp, ringorder_Dp, ringorder_lp, ringorder_rp, ringorder_ds, ringorder_Ds, ringorder_ls, ringorder_M, ringorder_C, ringorder_wp, ringorder_Wp, ringorder_ws, ringorder_Ws, ringorder_a, rRingOrder_t from sage.libs.singular.decl cimport p_Copy, prCopyR from sage.libs.singular.decl cimport n_unknown, n_Zp, n_Q, n_R, n_GF, n_long_R, n_algExt,n_transExt,n_long_C, n_Z, n_Zn, n_Znm, n_Z2m, n_CF from sage.libs.singular.decl cimport n_coeffType, cfInitCharProc @@ -165,7 +165,7 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: ## q q : GF(q=p^n) *names TRUE (todo) _wvhdl = omAlloc0((nblcks + 2) * sizeof(int *)) - _order = omAlloc0((nblcks + 2) * sizeof(int)) + _order = omAlloc0((nblcks + 2) * sizeof(int)) _block0 = omAlloc0((nblcks + 2) * sizeof(int)) _block1 = omAlloc0((nblcks + 2) * sizeof(int)) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 46a08c9b10b..62f1ce7b82c 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -591,7 +591,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: P._singular_() polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 3 // block 1 : ordering dp // : names x y z @@ -1179,7 +1179,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: P. = QQ[] sage: P._singular_() polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 3 // block 1 : ordering dp // : names x y z @@ -1195,7 +1195,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: P. = PolynomialRing(k,3) sage: P._singular_() polynomial ring, over a field, global ordering - // characteristic : 3 + // coefficients: ZZ/3 // 1 parameter : a // minpoly : (a^3-a+1) // number of vars : 3 @@ -1213,7 +1213,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: P. = QQ[] sage: P._singular_() polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 1 // block 1 : ordering lp // : names x @@ -1253,7 +1253,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: P. = QQ[] sage: P._singular_init_() polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 3 // block 1 : ordering dp // : names x y z @@ -1268,7 +1268,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: R. = PolynomialRing(NumberField(w^2+1,'s')) sage: singular(R) polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // 1 parameter : s // minpoly : (s^2+1) // number of vars : 2 @@ -1299,7 +1299,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: R = PolynomialRing(QQ,2,'x', order='invlex') sage: singular(R) polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 2 // block 1 : ordering rp // : names x0 x1 @@ -1308,7 +1308,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: R = PolynomialRing(QQ,2,'x', order='degneglex') sage: singular(R) polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 2 // block 1 : ordering a // : names x0 x1 @@ -1320,7 +1320,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: R = PolynomialRing(QQ,'x') sage: singular(R) polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 1 // block 1 : ordering lp // : names x @@ -1329,7 +1329,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: R = PolynomialRing(GF(127),'x') sage: singular(R) polynomial ring, over a field, global ordering - // characteristic : 127 + // coefficients: // number of vars : 1 // block 1 : ordering lp // : names x @@ -1338,7 +1338,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: R = ZZ['x,y'] sage: singular(R) polynomial ring, over a domain, global ordering - // coeff. ring is : ZZ + // coefficients: ZZ // number of vars : 2 // block 1 : ordering dp // : names x y @@ -1347,7 +1347,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: R = IntegerModRing(1024)['x,y'] sage: singular(R) polynomial ring, over a ring (with zero-divisors), global ordering - // coeff. ring is : Z/2^10 + // coefficients: Z/2^10 // number of vars : 2 // block 1 : ordering dp // : names x y @@ -1356,7 +1356,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: R = IntegerModRing(15)['x,y'] sage: singular(R) polynomial ring, over a ring (with zero-divisors), global ordering - // coeff. ring is : ZZ/15 + // coefficients: ZZ/15 // number of vars : 2 // block 1 : ordering dp // : names x y @@ -1367,7 +1367,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: P. = QQ[] sage: P._singular_init_() polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 1 // block 1 : ordering lp // : names x diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index 46a4b580ed2..a1c5a9752e7 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -601,7 +601,7 @@ def _singular_init_(self, S=None): sage: Q = P.quo([(x^2+1)]) sage: singular(Q) # indirect doctest polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 1 // block 1 : ordering lp // : names xbar diff --git a/src/sage/rings/polynomial/polynomial_singular_interface.py b/src/sage/rings/polynomial/polynomial_singular_interface.py index 3f0d1d055fb..1230a5e0337 100644 --- a/src/sage/rings/polynomial/polynomial_singular_interface.py +++ b/src/sage/rings/polynomial/polynomial_singular_interface.py @@ -81,9 +81,7 @@ def _singular_(self, singular=singular): sage: R. = PolynomialRing(CC,'x',2) sage: singular(R) polynomial ring, over a field, global ordering - // characteristic : 0 (complex:15 digits, additional 0 digits) - // 1 parameter : I - // minpoly : (I^2+1) + // coefficients: float[I](complex:15 digits, additional 0 digits)/(I^2+1) // number of vars : 2 // block 1 : ordering dp // : names x y @@ -91,7 +89,7 @@ def _singular_(self, singular=singular): sage: R. = PolynomialRing(RealField(100),'x',2) sage: singular(R) polynomial ring, over a field, global ordering - // characteristic : 0 (real) + // coefficients: float // number of vars : 2 // block 1 : ordering dp // : names x y @@ -101,9 +99,7 @@ def _singular_(self, singular=singular): sage: R. = PolynomialRing(NumberField(w^2+1,'s')) sage: singular(R) polynomial ring, over a field, global ordering - // characteristic : 0 - // 1 parameter : s - // minpoly : (s^2+1) + // coefficients: QQ[s]/(s^2+1) // number of vars : 1 // block 1 : ordering lp // : names x @@ -112,7 +108,7 @@ def _singular_(self, singular=singular): sage: R = PolynomialRing(GF(127),1,'x') sage: singular(R) polynomial ring, over a field, global ordering - // characteristic : 127 + // coefficients: ZZ/127 // number of vars : 1 // block 1 : ordering lp // : names x @@ -121,7 +117,7 @@ def _singular_(self, singular=singular): sage: R = PolynomialRing(QQ,1,'x') sage: singular(R) polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 1 // block 1 : ordering lp // : names x @@ -130,7 +126,7 @@ def _singular_(self, singular=singular): sage: R = PolynomialRing(QQ,'x') sage: singular(R) polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 1 // block 1 : ordering lp // : names x @@ -139,7 +135,7 @@ def _singular_(self, singular=singular): sage: R = PolynomialRing(GF(127),'x') sage: singular(R) polynomial ring, over a field, global ordering - // characteristic : 127 + // coefficients: ZZ/127 // number of vars : 1 // block 1 : ordering lp // : names x @@ -148,9 +144,7 @@ def _singular_(self, singular=singular): sage: R = Frac(ZZ['a,b'])['x,y'] sage: singular(R) polynomial ring, over a field, global ordering - // characteristic : 0 - // 2 parameter : a b - // minpoly : 0 + // coefficients: QQ(a, b) // number of vars : 2 // block 1 : ordering dp // : names x y @@ -160,7 +154,7 @@ def _singular_(self, singular=singular): sage: R = IntegerModRing(1024)['x,y'] sage: singular(R) polynomial ring, over a ring (with zero-divisors), global ordering - // coeff. ring is : Z/2^10 + // coefficients: Z/2^10 // number of vars : 2 // block 1 : ordering dp // : names x y @@ -169,7 +163,7 @@ def _singular_(self, singular=singular): sage: R = IntegerModRing(15)['x,y'] sage: singular(R) polynomial ring, over a ring (with zero-divisors), global ordering - // coeff. ring is : ZZ/15 + // coefficients: ZZ/bigint(15) // number of vars : 2 // block 1 : ordering dp // : names x y @@ -178,7 +172,7 @@ def _singular_(self, singular=singular): sage: R = ZZ['x,y'] sage: singular(R) polynomial ring, over a domain, global ordering - // coeff. ring is : ZZ + // coefficients: ZZ // number of vars : 2 // block 1 : ordering dp // : names x y @@ -190,9 +184,7 @@ def _singular_(self, singular=singular): sage: S = K['y'] sage: singular(S) polynomial ring, over a field, global ordering - // characteristic : 5 - // 1 parameter : x - // minpoly : 0 + // coefficients: ZZ/5(x) // number of vars : 2 // block 1 : ordering lp // : names a y @@ -234,7 +226,7 @@ def _singular_init_(self, singular=singular): sage: PolynomialRing(QQ,'u_ba')._singular_init_() polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 1 // block 1 : ordering lp // : names u_ba diff --git a/src/sage/rings/polynomial/term_order.py b/src/sage/rings/polynomial/term_order.py index e14a4be474a..a5bc6a1d2e9 100644 --- a/src/sage/rings/polynomial/term_order.py +++ b/src/sage/rings/polynomial/term_order.py @@ -1756,7 +1756,7 @@ def singular_str(self): '(lp(3),Dp(5),lp(2))' sage: P._singular_() polynomial ring, over a field, global ordering - // characteristic : 127 + // coefficients: ZZ/127 // number of vars : 10 // block 1 : ordering lp // : names x0 x1 x2 @@ -1784,7 +1784,7 @@ def singular_str(self): '(a(1:2),ls(2),a(1:2),ls(2))' sage: P._singular_() polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 4 // block 1 : ordering a // : names x0 x1 diff --git a/src/sage/rings/quotient_ring.py b/src/sage/rings/quotient_ring.py index 18195e597ef..119b23d369c 100644 --- a/src/sage/rings/quotient_ring.py +++ b/src/sage/rings/quotient_ring.py @@ -1174,7 +1174,7 @@ def _singular_(self, singular=singular_default): sage: S = R.quotient_ring(x^2+y^2) sage: S._singular_() polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 2 // block 1 : ordering dp // : names x y diff --git a/src/sage/rings/quotient_ring_element.py b/src/sage/rings/quotient_ring_element.py index 75d932d0653..f2ec0ff7f12 100644 --- a/src/sage/rings/quotient_ring_element.py +++ b/src/sage/rings/quotient_ring_element.py @@ -786,7 +786,7 @@ def _singular_(self, singular=singular_default): sage: Q = P.quo(I) sage: Q._singular_() polynomial ring, over a field, global ordering - // characteristic : 2 + // coefficients: ZZ/2 // number of vars : 2 // block 1 : ordering dp // : names x y From a204dfc0e0b79c8a81bdfc50aca0e7976875d5fb Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Thu, 23 Feb 2017 18:01:17 +0000 Subject: [PATCH 064/185] Further easy fixes. --- .../polynomial/multi_polynomial_element.py | 2 +- .../rings/polynomial/multi_polynomial_ideal.py | 10 ++++++---- .../multi_polynomial_libsingular.pyx | 18 ++++++------------ src/sage/rings/polynomial/pbori.pyx | 2 +- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py index 9f7fcdb1e38..3b1c4d3141f 100644 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -2024,7 +2024,7 @@ def degree_lowest_rational_function(r,x): :: sage: r = f/g; r - (-2*b*c^2 - 1)/(2*a*b^3*c^6 + a*c) + (-b*c^2 + 2)/(a*b^3*c^6 - 2*a*c) sage: degree_lowest_rational_function(r,a) (-1, 3) sage: degree_lowest_rational_function(r,b) diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index 9d30e70ff80..50e71a9990b 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -190,7 +190,7 @@ 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() - [x + 3*y + 11*z, y^2 + 3*y, y*z + 11*y + 4, 2*y + 6, z^2 + 3, 2*z + 10] + [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:: @@ -3645,11 +3645,13 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal sage: P. = PolynomialRing(Zmod(1000),3) sage: I = P * (a + 2*b + 2*c - 1, a^2 - a + 2*b^2 + 2*c^2, 2*a*b + 2*b*c - b) sage: I.groebner_basis() - [b*c^2 + 992*b*c + 712*c^2 + 332*b + 96*c, - 2*c^3 + 214*b*c + 862*c^2 + 762*b + 268*c, + [b*c^2 + 732*b*c + 808*b, + 2*c^3 + 884*b*c + 666*c^2 + 320*b, b^2 + 438*b*c + 281*b, 5*b*c + 156*c^2 + 112*b + 948*c, - 50*c^2 + 600*b + 650*c, a + 2*b + 2*c + 999, 125*b] + 50*c^2 + 600*b + 650*c, + a + 2*b + 2*c + 999, + 125*b] :: diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 62f1ce7b82c..af9a1cc0c4e 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -1195,9 +1195,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: P. = PolynomialRing(k,3) sage: P._singular_() polynomial ring, over a field, global ordering - // coefficients: ZZ/3 - // 1 parameter : a - // minpoly : (a^3-a+1) + // coefficients: ZZ/3[a]/(a^3-a+1) // number of vars : 3 // block 1 : ordering dp // : names x y z @@ -1268,9 +1266,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: R. = PolynomialRing(NumberField(w^2+1,'s')) sage: singular(R) polynomial ring, over a field, global ordering - // coefficients: QQ - // 1 parameter : s - // minpoly : (s^2+1) + // coefficients: QQ[s]/(s^2+1) // number of vars : 2 // block 1 : ordering dp // : names x y @@ -1279,9 +1275,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: R = PolynomialRing(GF(2**8,'a'),10,'x', order='invlex') sage: singular(R) polynomial ring, over a field, global ordering - // characteristic : 2 - // 1 parameter : a - // minpoly : (a^8+a^4+a^3+a^2+1) + // coefficients: ZZ/2[a]/(a^8+a^4+a^3+a^2+1) // number of vars : 10 // block 1 : ordering rp // : names x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 @@ -1290,7 +1284,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: R = PolynomialRing(GF(127),2,'x', order='invlex') sage: singular(R) polynomial ring, over a field, global ordering - // characteristic : 127 + // coefficients: ZZ/127 // number of vars : 2 // block 1 : ordering rp // : names x0 x1 @@ -1329,7 +1323,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: R = PolynomialRing(GF(127),'x') sage: singular(R) polynomial ring, over a field, global ordering - // coefficients: + // coefficients: ZZ/127 // number of vars : 1 // block 1 : ordering lp // : names x @@ -1356,7 +1350,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_generic): sage: R = IntegerModRing(15)['x,y'] sage: singular(R) polynomial ring, over a ring (with zero-divisors), global ordering - // coefficients: ZZ/15 + // coefficients: ZZ/bigint(15) // number of vars : 2 // block 1 : ordering dp // : names x y diff --git a/src/sage/rings/polynomial/pbori.pyx b/src/sage/rings/polynomial/pbori.pyx index 8238d8df824..8cb7bf8428b 100644 --- a/src/sage/rings/polynomial/pbori.pyx +++ b/src/sage/rings/polynomial/pbori.pyx @@ -1410,7 +1410,7 @@ cdef class BooleanPolynomialRing(MPolynomialRing_generic): sage: B. = BooleanPolynomialRing(2) sage: B._singular_() # indirect doctest polynomial ring, over a field, global ordering - // characteristic : 2 + // coefficients: ZZ/2 // number of vars : 2 // block 1 : ordering lp // : names x y From e8a265b2ebc7a5714a82764f09cbbbb81fe833d6 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Fri, 24 Feb 2017 13:08:12 +0000 Subject: [PATCH 065/185] Further doctest changes. --- src/doc/de/tutorial/interfaces.rst | 2 +- .../en/constructions/algebraic_geometry.rst | 10 ++++---- src/doc/en/constructions/rings.rst | 2 +- src/doc/en/developer/coding_in_other.rst | 2 +- src/doc/en/tutorial/interfaces.rst | 2 +- src/doc/fr/tutorial/interfaces.rst | 2 +- src/doc/ja/tutorial/interfaces.rst | 2 +- src/doc/pt/tutorial/interfaces.rst | 2 +- src/doc/ru/tutorial/interfaces.rst | 2 +- src/sage/categories/pushout.py | 2 +- src/sage/interfaces/expect.py | 2 +- src/sage/interfaces/interface.py | 2 +- src/sage/interfaces/singular.py | 24 +++++++++---------- src/sage/libs/singular/function.pyx | 2 +- src/sage/schemes/curves/projective_curve.py | 2 +- 15 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/doc/de/tutorial/interfaces.rst b/src/doc/de/tutorial/interfaces.rst index edc59c58dff..83a8a8bd56e 100644 --- a/src/doc/de/tutorial/interfaces.rst +++ b/src/doc/de/tutorial/interfaces.rst @@ -198,7 +198,7 @@ Sages Singular-Schnittstelle (ohne die ``....:``): sage: R1 = singular.ring(0, '(x,y)', 'dp') sage: R1 polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 2 // block 1 : ordering dp // : names x y diff --git a/src/doc/en/constructions/algebraic_geometry.rst b/src/doc/en/constructions/algebraic_geometry.rst index f7e663d2314..a3125485b27 100644 --- a/src/doc/en/constructions/algebraic_geometry.rst +++ b/src/doc/en/constructions/algebraic_geometry.rst @@ -164,7 +164,7 @@ Other methods sage: klein1 = f.Adj_div(); print(klein1) [1]: [1]: - // characteristic : 2 + // coefficients: ZZ/2 // number of vars : 2 // block 1 : ordering lp // : names x y @@ -187,13 +187,13 @@ Other methods sage: print(klein1) [1]: [1]: - // characteristic : 2 + // coefficients: ZZ/2 // number of vars : 2 // block 1 : ordering lp // : names x y // block 2 : ordering C [2]: - // characteristic : 2 + // coefficients: ZZ/2 // number of vars : 3 // block 1 : ordering lp // : names x y z @@ -210,7 +210,7 @@ Other methods [5]: [1]: [1]: - // characteristic : 2 + // coefficients: ZZ/2 // number of vars : 3 // block 1 : ordering ls // : names x y t @@ -325,7 +325,7 @@ Singular itself to help an understanding of how the wrapper works. sage: X = Curve(f); pts = X.rational_points() sage: D = X.divisor([ (3, pts[0]), (-1,pts[1]), (10, pts[5]) ]) sage: X.riemann_roch_basis(D) - [(-2*x + y)/(x + y), (-x + z)/(x + y)] + [(-x - 2*y)/(-2*x - 2*y), (-x + z)/(x + y)] - Using Singular's ``BrillNoether`` command (for details see the section Brill-Noether in the Singular online documentation diff --git a/src/doc/en/constructions/rings.rst b/src/doc/en/constructions/rings.rst index 58abf8a479e..076184ea245 100644 --- a/src/doc/en/constructions/rings.rst +++ b/src/doc/en/constructions/rings.rst @@ -57,7 +57,7 @@ Here's an example using the Singular interface: sage: I = singular.ideal(['a+b+c+d', 'ab+ad+bc+cd', 'abc+abd+acd+bcd', 'abcd-1']) sage: R polynomial ring, over a field, global ordering - // characteristic : 97 + // coefficients: ZZ/97 // number of vars : 4 // block 1 : ordering lp // : names a b c d diff --git a/src/doc/en/developer/coding_in_other.rst b/src/doc/en/developer/coding_in_other.rst index 640c8acd49a..b1728ea383a 100644 --- a/src/doc/en/developer/coding_in_other.rst +++ b/src/doc/en/developer/coding_in_other.rst @@ -402,7 +402,7 @@ interface to Singular:: sage: singular.LIB("brnoeth.lib") sage: singular.ring(5,'(x,y)','lp') polynomial ring, over a field, global ordering - // characteristic : 5 + // coefficients: ZZ/5 // number of vars : 2 // block 1 : ordering lp // : names x y diff --git a/src/doc/en/tutorial/interfaces.rst b/src/doc/en/tutorial/interfaces.rst index 5a276310349..ca7ae7ac9ad 100644 --- a/src/doc/en/tutorial/interfaces.rst +++ b/src/doc/en/tutorial/interfaces.rst @@ -197,7 +197,7 @@ Singular (do not type the ``....:``): sage: R1 = singular.ring(0, '(x,y)', 'dp') sage: R1 polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 2 // block 1 : ordering dp // : names x y diff --git a/src/doc/fr/tutorial/interfaces.rst b/src/doc/fr/tutorial/interfaces.rst index 75f36a46f9b..8109a67359d 100644 --- a/src/doc/fr/tutorial/interfaces.rst +++ b/src/doc/fr/tutorial/interfaces.rst @@ -199,7 +199,7 @@ fournie par Sage (n'entrez pas les ``....:``) : sage: R1 = singular.ring(0, '(x,y)', 'dp') sage: R1 polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 2 // block 1 : ordering dp // : names x y diff --git a/src/doc/ja/tutorial/interfaces.rst b/src/doc/ja/tutorial/interfaces.rst index 560032a7b8f..64381030bb9 100644 --- a/src/doc/ja/tutorial/interfaces.rst +++ b/src/doc/ja/tutorial/interfaces.rst @@ -173,7 +173,7 @@ Singularは,グレブナー基底,多変数多項式のgcd,平面曲線の sage: R1 = singular.ring(0, '(x,y)', 'dp') sage: R1 polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 2 // block 1 : ordering dp // : names x y diff --git a/src/doc/pt/tutorial/interfaces.rst b/src/doc/pt/tutorial/interfaces.rst index 5f611f837fc..4539bf619d2 100644 --- a/src/doc/pt/tutorial/interfaces.rst +++ b/src/doc/pt/tutorial/interfaces.rst @@ -197,7 +197,7 @@ digite ``...``): sage: R1 = singular.ring(0, '(x,y)', 'dp') sage: R1 polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 2 // block 1 : ordering dp // : names x y diff --git a/src/doc/ru/tutorial/interfaces.rst b/src/doc/ru/tutorial/interfaces.rst index 234731a507c..bc2983c1c48 100644 --- a/src/doc/ru/tutorial/interfaces.rst +++ b/src/doc/ru/tutorial/interfaces.rst @@ -191,7 +191,7 @@ Singular предоставляет массивную и продуманную sage: R1 = singular.ring(0, '(x,y)', 'dp') sage: R1 polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 2 // block 1 : ordering dp // : names x y diff --git a/src/sage/categories/pushout.py b/src/sage/categories/pushout.py index 125e1ec6a44..d6100a40c0f 100644 --- a/src/sage/categories/pushout.py +++ b/src/sage/categories/pushout.py @@ -3202,7 +3202,7 @@ class BlackBoxConstructionFunctor(ConstructionFunctor): Gap sage: FS(QQ['t']) polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 1 // block 1 : ordering lp // : names t diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index c86a9bdddba..71647889d10 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -1213,7 +1213,7 @@ def _synchronize(self, cmd='1+%s;\n'): sage: R. = QQ[]; f = x^3 + x + 1; g = x^3 - x - 1; r = f.resultant(g); gap(ZZ); singular(R) Integers polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 1 // block 1 : ordering lp // : names x diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index 77b929b9d47..2b328d70185 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -734,7 +734,7 @@ def __reduce__(self): sage: S = singular.ring(0, ('x')) sage: loads(dumps(S)) polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 1 // block 1 : ordering lp // : names x diff --git a/src/sage/interfaces/singular.py b/src/sage/interfaces/singular.py index 5420c48fc11..1120eb77251 100644 --- a/src/sage/interfaces/singular.py +++ b/src/sage/interfaces/singular.py @@ -65,7 +65,7 @@ sage: R1 = singular.ring(0, '(x,y)', 'dp') sage: R1 polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 2 // block 1 : ordering dp // : names x y @@ -243,7 +243,7 @@ sage: singular.lib('poly.lib') sage: singular.ring(32003, '(a,b,c,d,e,f)', 'lp') polynomial ring, over a field, global ordering - // characteristic : 32003 + // coefficients: ZZ/32003 // number of vars : 6 // block 1 : ordering lp // : names a b c d e f @@ -1000,7 +1000,7 @@ def ring(self, char=0, vars='(x)', order='lp', check=True): sage: R = singular.ring(0, '(x,y,z)', 'dp') sage: R polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 3 // block 1 : ordering dp // : names x y z @@ -1080,7 +1080,7 @@ def set_ring(self, R): sage: S = singular.ring('real', '(a,b)', 'lp') sage: singular.current_ring() polynomial ring, over a field, global ordering - // characteristic : 0 (real) + // coefficients: float // number of vars : 2 // block 1 : ordering lp // : names a b @@ -1088,7 +1088,7 @@ def set_ring(self, R): sage: singular.set_ring(R) sage: singular.current_ring() polynomial ring, over a field, local ordering - // characteristic : 7 + // coefficients: ZZ/7 // number of vars : 2 // block 1 : ordering ds // : names a b @@ -1130,14 +1130,14 @@ def current_ring(self): sage: r = PolynomialRing(GF(127),3,'xyz', order='invlex') sage: r._singular_() polynomial ring, over a field, global ordering - // characteristic : 127 + // coefficients: ZZ/127 // number of vars : 3 // block 1 : ordering rp // : names x y z // block 2 : ordering C sage: singular.current_ring() polynomial ring, over a field, global ordering - // characteristic : 127 + // coefficients: ZZ/127 // number of vars : 3 // block 1 : ordering rp // : names x y z @@ -1360,7 +1360,7 @@ def __copy__(self): sage: cpQ.set_ring() sage: cpQ polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 2 // block 1 : ordering dp // : names x y @@ -1911,7 +1911,7 @@ def _sage_(self, R=None): sage: singular('basering') polynomial ring, over a domain, global ordering - // coeff. ring is : ZZ + // coefficients: ZZ // number of vars : 3 // block 1 : ordering lp // : names x y z @@ -1996,7 +1996,7 @@ def set_ring(self): sage: S = singular.ring('real', '(a,b)', 'lp') sage: singular.current_ring() polynomial ring, over a field, global ordering - // characteristic : 0 (real) + // coefficients: float // number of vars : 2 // block 1 : ordering lp // : names a b @@ -2004,7 +2004,7 @@ def set_ring(self): sage: R.set_ring() sage: singular.current_ring() polynomial ring, over a field, local ordering - // characteristic : 7 + // coefficients: ZZ/7 // number of vars : 2 // block 1 : ordering ds // : names a b @@ -2260,7 +2260,7 @@ def reduce_load(): sage: loads(dumps(singular.ring())) polynomial ring, over a field, global ordering - // characteristic : 0 + // coefficients: QQ // number of vars : 1 // block 1 : ordering lp // : names x diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index da3cdbb364c..46765b17871 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -282,7 +282,7 @@ cdef class RingWrap: sage: l = ringlist(P) sage: ring = singular_function("ring") sage: ring(l, ring=P)._output() - // characteristic : 0 + // coefficients: QQ // number of vars : 3 // block 1 : ordering dp // : names x y z diff --git a/src/sage/schemes/curves/projective_curve.py b/src/sage/schemes/curves/projective_curve.py index 3e83b2c218b..d0cc0bd2dea 100644 --- a/src/sage/schemes/curves/projective_curve.py +++ b/src/sage/schemes/curves/projective_curve.py @@ -1830,7 +1830,7 @@ def riemann_roch_basis(self, D): sage: C = Curve(f); pts = C.rational_points() sage: D = C.divisor([ (3, pts[0]), (-1,pts[1]), (10, pts[5]) ]) sage: C.riemann_roch_basis(D) - [(-2*x + y)/(x + y), (-x + z)/(x + y)] + [(-x - 2*y)/(-2*x - 2*y), (-x + z)/(x + y)] .. NOTE:: From 400fce181981a49abea6e13ee469ff9b44a7ceb3 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Fri, 24 Feb 2017 13:10:06 +0000 Subject: [PATCH 066/185] Fix Singular's make check with upstream patch. --- build/pkgs/singular/patches/make_check.patch | 216 +++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 build/pkgs/singular/patches/make_check.patch diff --git a/build/pkgs/singular/patches/make_check.patch b/build/pkgs/singular/patches/make_check.patch new file mode 100644 index 00000000000..9cc48030616 --- /dev/null +++ b/build/pkgs/singular/patches/make_check.patch @@ -0,0 +1,216 @@ +From 3f253bdb1a2093b790df2d04741171aa027ff07d Mon Sep 17 00:00:00 2001 +From: Hans Schoenemann +Date: Mon, 20 Feb 2017 18:33:27 +0100 +Subject: [PATCH] make check + +--- + Singular/test.cc | 1 - + kernel/GBEngine/Makefile.am | 2 +- + kernel/GBEngine/test.cc | 2 +- + kernel/Makefile.am | 2 +- + kernel/combinatorics/Makefile.am | 2 +- + kernel/combinatorics/test.cc | 2 +- + kernel/fglm/test.cc | 2 +- + kernel/groebner_walk/test.cc | 2 +- + kernel/linear_algebra/test.cc | 2 +- + kernel/maps/test.cc | 2 +- + kernel/numeric/test.cc | 2 +- + kernel/oswrapper/test.cc | 2 +- + kernel/spectrum/test.cc | 2 +- + kernel/test.cc | 2 +- + libpolys/tests/rings_test.h | 2 +- + 15 files changed, 14 insertions(+), 15 deletions(-) + +diff --git a/Singular/test.cc b/Singular/test.cc +index d5b64e7..45ed707 100644 +--- a/Singular/test.cc ++++ b/Singular/test.cc +@@ -194,7 +194,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/kernel/GBEngine/Makefile.am b/kernel/GBEngine/Makefile.am +index 3efdcf0..fb8bec3 100644 +--- a/kernel/GBEngine/Makefile.am ++++ b/kernel/GBEngine/Makefile.am +@@ -17,7 +17,7 @@ TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}' + TESTS = test + check_PROGRAMS = $(TESTS) + test_SOURCES = test.cc +-test_LDADD = libGBEngine.la ${builddir}/../combinatorics/libcombinatorics.la ${builddir}/../linear_algebra/liblinear_algebra.la ${builddir}/../libkernelCommon.la ++test_LDADD = libGBEngine.la ${builddir}/../combinatorics/libcombinatorics.la ${builddir}/../linear_algebra/liblinear_algebra.la ${builddir}/../libkernelCommon.la ${builddir}/../../Singular/libSingular.la + + CLEANFILES = $(TESTS) + +diff --git a/kernel/GBEngine/test.cc b/kernel/GBEngine/test.cc +index 436a1c8..5336737 100644 +--- a/kernel/GBEngine/test.cc ++++ b/kernel/GBEngine/test.cc +@@ -93,7 +93,7 @@ void TestGBEngine() + + + const int D = 3; +- int *order = (int *) omAlloc0(D* sizeof(int)); ++ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); + int *block0 = (int *)omAlloc0(D * sizeof(int)); + int *block1 = (int *)omAlloc0(D * sizeof(int)); + +diff --git a/kernel/Makefile.am b/kernel/Makefile.am +index 86f6d47..575f215 100644 +--- a/kernel/Makefile.am ++++ b/kernel/Makefile.am +@@ -51,7 +51,7 @@ TESTS = test + check_PROGRAMS = $(TESTS) + + test_SOURCES = test.cc +-test_LDADD = libkernel.la ++test_LDADD = libkernel.la ${builddir}/../Singular/libSingular.la + + # These files are built first + # BUILT_SOURCES = MOD +diff --git a/kernel/combinatorics/Makefile.am b/kernel/combinatorics/Makefile.am +index 63a52ec..f8074fe 100644 +--- a/kernel/combinatorics/Makefile.am ++++ b/kernel/combinatorics/Makefile.am +@@ -17,6 +17,6 @@ TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}' + TESTS = test + check_PROGRAMS = $(TESTS) + test_SOURCES = test.cc +-test_LDADD = libcombinatorics.la ${builddir}/../libkernelCommon.la ++test_LDADD = libcombinatorics.la ${builddir}/../libkernelCommon.la ${builddir}/../../Singular/libSingular.la + + CLEANFILES = $(TESTS) +diff --git a/kernel/combinatorics/test.cc b/kernel/combinatorics/test.cc +index 056fd57..32e7ae5 100644 +--- a/kernel/combinatorics/test.cc ++++ b/kernel/combinatorics/test.cc +@@ -99,7 +99,7 @@ void TestGBEngine() + + + const int D = 3; +- int *order = (int *) omAlloc0(D* sizeof(int)); ++ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); + int *block0 = (int *)omAlloc0(D * sizeof(int)); + int *block1 = (int *)omAlloc0(D * sizeof(int)); + +diff --git a/kernel/fglm/test.cc b/kernel/fglm/test.cc +index c5182db..597053b 100644 +--- a/kernel/fglm/test.cc ++++ b/kernel/fglm/test.cc +@@ -97,7 +97,7 @@ void TestGBEngine() + + + const int D = 3; +- int *order = (int *) omAlloc0(D* sizeof(int)); ++ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); + int *block0 = (int *)omAlloc0(D * sizeof(int)); + int *block1 = (int *)omAlloc0(D * sizeof(int)); + +diff --git a/kernel/groebner_walk/test.cc b/kernel/groebner_walk/test.cc +index c5182db..597053b 100644 +--- a/kernel/groebner_walk/test.cc ++++ b/kernel/groebner_walk/test.cc +@@ -97,7 +97,7 @@ void TestGBEngine() + + + const int D = 3; +- int *order = (int *) omAlloc0(D* sizeof(int)); ++ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); + int *block0 = (int *)omAlloc0(D * sizeof(int)); + int *block1 = (int *)omAlloc0(D * sizeof(int)); + +diff --git a/kernel/linear_algebra/test.cc b/kernel/linear_algebra/test.cc +index c5182db..597053b 100644 +--- a/kernel/linear_algebra/test.cc ++++ b/kernel/linear_algebra/test.cc +@@ -97,7 +97,7 @@ void TestGBEngine() + + + const int D = 3; +- int *order = (int *) omAlloc0(D* sizeof(int)); ++ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); + int *block0 = (int *)omAlloc0(D * sizeof(int)); + int *block1 = (int *)omAlloc0(D * sizeof(int)); + +diff --git a/kernel/maps/test.cc b/kernel/maps/test.cc +index c5182db..597053b 100644 +--- a/kernel/maps/test.cc ++++ b/kernel/maps/test.cc +@@ -97,7 +97,7 @@ void TestGBEngine() + + + const int D = 3; +- int *order = (int *) omAlloc0(D* sizeof(int)); ++ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); + int *block0 = (int *)omAlloc0(D * sizeof(int)); + int *block1 = (int *)omAlloc0(D * sizeof(int)); + +diff --git a/kernel/numeric/test.cc b/kernel/numeric/test.cc +index c5182db..597053b 100644 +--- a/kernel/numeric/test.cc ++++ b/kernel/numeric/test.cc +@@ -97,7 +97,7 @@ void TestGBEngine() + + + const int D = 3; +- int *order = (int *) omAlloc0(D* sizeof(int)); ++ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); + int *block0 = (int *)omAlloc0(D * sizeof(int)); + int *block1 = (int *)omAlloc0(D * sizeof(int)); + +diff --git a/kernel/oswrapper/test.cc b/kernel/oswrapper/test.cc +index c5182db..597053b 100644 +--- a/kernel/oswrapper/test.cc ++++ b/kernel/oswrapper/test.cc +@@ -97,7 +97,7 @@ void TestGBEngine() + + + const int D = 3; +- int *order = (int *) omAlloc0(D* sizeof(int)); ++ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); + int *block0 = (int *)omAlloc0(D * sizeof(int)); + int *block1 = (int *)omAlloc0(D * sizeof(int)); + +diff --git a/kernel/spectrum/test.cc b/kernel/spectrum/test.cc +index c5182db..597053b 100644 +--- a/kernel/spectrum/test.cc ++++ b/kernel/spectrum/test.cc +@@ -97,7 +97,7 @@ void TestGBEngine() + + + const int D = 3; +- int *order = (int *) omAlloc0(D* sizeof(int)); ++ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); + int *block0 = (int *)omAlloc0(D * sizeof(int)); + int *block1 = (int *)omAlloc0(D * sizeof(int)); + +diff --git a/kernel/test.cc b/kernel/test.cc +index e27acf7..a0c418e 100644 +--- a/kernel/test.cc ++++ b/kernel/test.cc +@@ -203,7 +203,7 @@ void TestGBEngine() + + + const int D = 3; +- int *order = (int *) omAlloc0(D* sizeof(int)); ++ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); + int *block0 = (int *)omAlloc0(D * sizeof(int)); + int *block1 = (int *)omAlloc0(D * sizeof(int)); + +diff --git a/libpolys/tests/rings_test.h b/libpolys/tests/rings_test.h +index f8a66b5..22c92f6 100644 +--- a/libpolys/tests/rings_test.h ++++ b/libpolys/tests/rings_test.h +@@ -208,7 +208,7 @@ class PolysTestSuite : public CxxTest::TestSuite + + const int D = 2; + /*order: lp,0*/ +- int *order = (int *) omAlloc0(D* sizeof(int)); ++ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); + int *block0 = (int *)omAlloc0(D * sizeof(int)); + int *block1 = (int *)omAlloc0(D * sizeof(int)); + /* ringorder dp for the first block: var 1..N */ From d9d75ad63acd37a47bb8af2cfe4e44f28c46992e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jori=20M=C3=A4ntysalo?= Date: Sun, 26 Feb 2017 23:44:35 +0200 Subject: [PATCH 067/185] Add lattice of congruences. --- src/sage/combinat/posets/lattices.py | 88 ++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/src/sage/combinat/posets/lattices.py b/src/sage/combinat/posets/lattices.py index 751f2df7ee4..c61fb24fc07 100644 --- a/src/sage/combinat/posets/lattices.py +++ b/src/sage/combinat/posets/lattices.py @@ -61,6 +61,9 @@ :meth:`~FiniteLatticePoset.is_dismantlable` | Return ``True`` if the lattice is dismantlable. :meth:`~FiniteLatticePoset.is_vertically_decomposable` | Return ``True`` if the lattice is vertically decomposable. :meth:`~FiniteLatticePoset.is_simple` | Return ``True`` if the lattice has no nontrivial congruences. + :meth:`~FiniteLatticePoset.is_isoform` | Return ``True`` if all congruences of the lattice consists of isoform blocks. + :meth:`~FiniteLatticePoset.is_uniform` | Return ``True`` if all congruences of the lattice consists of equal-sized blocks. + :meth:`~FiniteLatticePoset.is_regular` | Return ``True`` if all congruences of lattice are determined by any of the congruence block. :meth:`~FiniteLatticePoset.is_subdirectly_reducible` | Return ``True`` if the lattice is a sublattice of the product of smaller lattices. :meth:`~FiniteLatticePoset.breadth` | Return the breadth of the lattice. @@ -114,6 +117,7 @@ :meth:`~FiniteLatticePoset.day_doubling` | Return the lattice with Alan Day's doubling construction of a subset. :meth:`~FiniteLatticePoset.congruence` | Return the congruence generated by lists of elements. :meth:`~FiniteLatticePoset.quotient` | Return the quotient lattice by a congruence. + :meth:`~FiniteLatticePoset.congruences_lattice` | Return the lattice of congruences. """ #***************************************************************************** # Copyright (C) 2008 Peter Jipsen , @@ -3869,6 +3873,90 @@ def quotient(self, congruence, labels='tuple'): H.relabel(lambda m: self.sublattice(part_dict[m])) return LatticePoset(H) + def congruences_lattice(self, labels='congruence'): + r""" + Return the lattice of congruences. + + A congruence of a lattice is a partition of elements to classes + compatible with both meet- and join-operation; see :meth:`congruence`. + Elements of the *congruence lattice* are congruences ordered by + refinement; i.e. if every class of a congruence `\Theta` is + contained in some class of `\Phi`, then `\Theta \le \Phi` + in the congruence lattice. + + INPUT: + + - ``labels``, a string -- type of elements of resulting lattice + + OUTPUT: + + A distributive lattice. + + - If ``labels='congruence'``, then elements of the + result will be congruences given as + :class:`sage.combinat.set_partition.SetPartition`. + - If ``labels='integers'``, result is a lattice on + integers isomorphic to the congruence lattice. + + EXAMPLES:: + + sage: N5 = Posets.PentagonPoset() + sage: CL = N5.congruences_lattice(); CL + Finite lattice containing 5 elements + sage: CL.atoms() + [{{0}, {1}, {2, 3}, {4}}] + sage: CL.coatoms() + [{{0, 1}, {2, 3, 4}}, {{0, 2, 3}, {1, 4}}] + + sage: C4 = Posets.ChainPoset(4) + sage: CL = C4.congruences_lattice(labels='integer') + sage: CL.is_isomorphic(Posets.BooleanLattice(3)) + True + + TESTS:: + + sage: Posets.ChainPoset(0).congruences_lattice() + Finite lattice containing 1 elements + sage: Posets.ChainPoset(1).congruences_lattice() + Finite lattice containing 1 elements + sage: Posets.ChainPoset(2).congruences_lattice() + Finite lattice containing 2 elements + sage: Posets.ChainPoset(3).congruences_lattice() + Finite lattice containing 4 elements + """ + from sage.sets.set import Set + from sage.sets.disjoint_set import DisjointSet + from sage.combinat.set_partition import SetPartition + if labels not in ['integer', 'congruence']: + raise ValueError("'labels' must be 'integer' or 'congruence'") + + cong_ji, congs = self._hasse_diagram.principal_congruences_poset() + + # Form of the lattice of congruences can be computed much faster than + # all congruences. + if labels == 'integer': + tmp = Poset(cong_ji).order_ideals_lattice(as_ideals=False) + return tmp.relabel(tmp._element_to_vertex_dict) + + # To compute full lattice of congruences we "extend" already computed + # parts of a congruence. + L = cong_ji.order_ideals_lattice() + C = {} + C[Set()] = DisjointSet(self.cardinality()) # the bottom element + for e in L: + low = L.lower_covers(e) + if len(low) == 1: # a join-irreducible element + C[e] = congs[max(e, key=lambda x: cong_ji._element_to_vertex(x))] + if len(low) > 1: # "extending" congruence to avoid re-computation + low_0 = min(low, key=lambda x: C[x].number_of_subsets()) + for new_pair in e: + if new_pair not in low_0: + break + C[e] = self._hasse_diagram.congruence([new_pair], start=C[low_0]) + + return L.relabel(lambda e: SetPartition([[self._vertex_to_element(v) + for v in p] for p in C[e]])) + def _log_2(n): """ Return the 2-based logarithm of `n` rounded up. From f902b3a14a7dec67932262d412390b31142d1acf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jori=20M=C3=A4ntysalo?= Date: Sun, 26 Feb 2017 23:50:29 +0200 Subject: [PATCH 068/185] Add note of antichains order. --- src/sage/combinat/posets/hasse_diagram.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sage/combinat/posets/hasse_diagram.py b/src/sage/combinat/posets/hasse_diagram.py index 13f1523cab8..03a07df7c09 100644 --- a/src/sage/combinat/posets/hasse_diagram.py +++ b/src/sage/combinat/posets/hasse_diagram.py @@ -1819,6 +1819,9 @@ def antichains_iterator(self): sage: list(H.antichains_iterator()) [[]] """ + # NOTE: Ordering of antichains as a prefix tree is crusial for + # congruences_iterator() to work. Change it, if you change this. + # Complexity note: # antichains_queues never grows longer than self.cardinality(). # Indeed, if a appears before b in antichains_queues, then From 65f4c8c59d7a0f3ee84f55a6ad1ebe5aa020d97f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jori=20M=C3=A4ntysalo?= Date: Mon, 27 Feb 2017 10:09:56 +0200 Subject: [PATCH 069/185] Add subdirect_decomposition(). --- src/sage/combinat/posets/lattices.py | 74 ++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/src/sage/combinat/posets/lattices.py b/src/sage/combinat/posets/lattices.py index 751f2df7ee4..88065be29ba 100644 --- a/src/sage/combinat/posets/lattices.py +++ b/src/sage/combinat/posets/lattices.py @@ -112,6 +112,7 @@ :meth:`~FiniteLatticePoset.quantum_moebius_algebra` | Return the quantum Möbius algebra of the lattice. :meth:`~FiniteLatticePoset.vertical_composition` | Return ordinal sum of lattices with top/bottom element unified. :meth:`~FiniteLatticePoset.day_doubling` | Return the lattice with Alan Day's doubling construction of a subset. + :meth:`~FiniteLatticePoset.subdirect_decomposition` | Return the subdirect decomposition of the lattice. :meth:`~FiniteLatticePoset.congruence` | Return the congruence generated by lists of elements. :meth:`~FiniteLatticePoset.quotient` | Return the quotient lattice by a congruence. """ @@ -3713,6 +3714,79 @@ def is_simple(self, certificate=False): return (False, SetPartition([[self._vertex_to_element(v) for v in s] for s in cong])) + def subdirect_decomposition(self): + r""" + Return the subdirect decomposition of the lattice. + + The subdirect decomposition of a lattice `L` is the list + of smaller lattices `L_1, \ldots, L_n` such that `L` is + a sublattice of `L_1 \times \ldots \times L_n`, none + of `L_i` can be decomposed further and `L` is not a sublattice + of any `L_i`. (Except when the list has only one element, i.e. + when the lattice is subdirectly irreducible.) + + EXAMPLES:: + + sage: Posets.ChainPoset(3).subdirect_decomposition() + [Finite lattice containing 2 elements, Finite lattice containing 2 elements] + + sage: L = LatticePoset({1: [2, 4], 2: [3], 3: [6, 7], 4: [5, 7], + ....: 5: [9, 8], 6: [9], 7: [9], 8: [10], 9: [10]}) + sage: Ldecomp = L.subdirect_decomposition() + sage: [fac.cardinality() for fac in Ldecomp] + [2, 5, 7] + sage: Ldecomp[1].is_isomorphic(Posets.PentagonPoset()) + True + + TESTS:: + + sage: Posets.ChainPoset(0).subdirect_decomposition() + [Finite lattice containing 0 elements] + sage: Posets.ChainPoset(1).subdirect_decomposition() + [Finite lattice containing 1 elements] + sage: Posets.ChainPoset(2).subdirect_decomposition() + [Finite lattice containing 2 elements] + + The pentagon is subdirectly irreducible, i.e. the decomposition + has only one element:: + + sage: N5 = Posets.PentagonPoset() + sage: N5.subdirect_decomposition() + [Finite lattice containing 5 elements] + """ + H = self._hasse_diagram + cong_ji, congs = H.principal_congruences_poset() + + if self.cardinality() <= 2 or cong_ji.has_bottom(): + return [self.relabel(self._element_to_vertex_dict)] + + L_ = cong_ji.order_ideals_lattice() + c = L_.canonical_meetands(L_.bottom()) + L = L_.subposet(L_.order_ideal(c)) + + C = {} + for e in L: + low = L.lower_covers(e) + if len(low) == 1: # a join-irreducible element + C[e] = congs[max(e, key=lambda x: cong_ji._element_to_vertex(x))] + if len(low) > 1: # "extending" congruence to avoid re-computation + low_0 = min(low, key=lambda x: C[x].number_of_subsets()) + for new_pair in e: + if new_pair not in low_0: + break + C[e] = self._hasse_diagram.congruence([new_pair], start=C[low_0]) + + decomposing_congruences = [C[m] for m in L.maximal_elements()] + decomposing_congruences.sort(key=lambda x: x.number_of_subsets()) + + result = [] + for congruence in decomposing_congruences: + part_bottoms = [min(part) for part in congruence] + F = H.transitive_closure().subgraph(part_bottoms) + result.append(LatticePoset(F)) + + return result + def congruence(self, S): """ Return the congruence generated by set of sets `S`. From 98b01fdb83e11280f150636239c5db2265a8c5b1 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Tue, 28 Feb 2017 12:06:52 +0100 Subject: [PATCH 070/185] Replace _pari_ -> __pari__ --- src/doc/en/developer/coding_in_other.rst | 2 +- src/sage/arith/misc.py | 2 +- src/sage/functions/exp_integral.py | 4 +- src/sage/groups/pari_group.py | 2 +- src/sage/libs/cypari2/gen.pyx | 4 +- src/sage/libs/pari/convert_flint.pyx | 2 +- src/sage/libs/pari/convert_gmp.pyx | 2 +- src/sage/libs/pari/tests.py | 42 +++++++++---------- src/sage/matrix/matrix1.pyx | 2 +- src/sage/matrix/matrix2.pyx | 6 +-- src/sage/matrix/matrix_integer_dense.pyx | 16 +++---- src/sage/matrix/matrix_rational_dense.pyx | 6 +-- src/sage/modular/btquotients/btquotient.py | 10 ++--- src/sage/modular/overconvergent/genus0.py | 8 ++-- src/sage/modules/free_module_element.pyx | 6 +-- src/sage/modules/free_module_integer.py | 2 +- src/sage/quadratic_forms/qfsolve.py | 4 +- src/sage/quadratic_forms/quadratic_form.py | 6 +-- .../quadratic_form__automorphisms.py | 10 ++--- .../quadratic_form__equivalence_testing.py | 2 +- .../quadratic_form__local_field_invariants.py | 4 +- .../quadratic_form__ternary_Tornaria.py | 4 +- src/sage/rings/complex_double.pyx | 18 ++++---- src/sage/rings/complex_mpc.pyx | 26 ++++++------ src/sage/rings/complex_number.pyx | 34 +++++++-------- src/sage/rings/factorint.pyx | 2 +- src/sage/rings/finite_rings/element_base.pyx | 16 +++---- .../rings/finite_rings/element_ext_pari.py | 8 ++-- .../rings/finite_rings/element_givaro.pyx | 2 +- .../rings/finite_rings/element_ntl_gf2e.pyx | 2 +- .../rings/finite_rings/element_pari_ffelt.pyx | 6 +-- src/sage/rings/finite_rings/integer_mod.pyx | 12 +++--- .../rings/finite_rings/integer_mod_ring.py | 2 +- .../function_field/function_field_element.pyx | 10 ++--- src/sage/rings/infinity.py | 2 +- src/sage/rings/integer.pxd | 2 +- src/sage/rings/integer.pyx | 36 ++++++++-------- .../rings/multi_power_series_ring_element.py | 8 ++-- src/sage/rings/number_field/galois_group.py | 2 +- src/sage/rings/number_field/maps.py | 2 +- src/sage/rings/number_field/number_field.py | 10 ++--- .../number_field/number_field_element.pyx | 42 +++++++++---------- .../rings/number_field/number_field_ideal.py | 12 +++--- .../rings/number_field/number_field_rel.py | 4 +- .../rings/number_field/splitting_field.py | 2 +- .../rings/padics/padic_ZZ_pX_CA_element.pyx | 2 +- .../rings/padics/padic_ZZ_pX_CR_element.pyx | 2 +- .../rings/padics/padic_ZZ_pX_FM_element.pyx | 2 +- .../padics/padic_capped_absolute_element.pyx | 2 +- .../padics/padic_capped_relative_element.pyx | 2 +- .../rings/padics/padic_fixed_mod_element.pyx | 4 +- .../rings/padics/padic_generic_element.pyx | 6 +-- .../polynomial/padics/polynomial_padic.py | 2 +- .../polynomial_padic_capped_relative_dense.py | 2 +- .../rings/polynomial/polynomial_element.pyx | 24 +++++------ .../polynomial/polynomial_element_generic.py | 2 +- src/sage/rings/polynomial/polynomial_gf2x.pyx | 2 +- .../polynomial_integer_dense_flint.pyx | 6 +-- .../polynomial_integer_dense_ntl.pyx | 4 +- .../polynomial/polynomial_modn_dense_ntl.pyx | 2 +- .../polynomial_quotient_ring_element.py | 4 +- src/sage/rings/power_series_pari.pyx | 28 ++++++------- src/sage/rings/power_series_poly.pyx | 2 +- src/sage/rings/power_series_ring.py | 2 +- src/sage/rings/power_series_ring_element.pyx | 6 +-- src/sage/rings/qqbar.py | 2 +- src/sage/rings/quotient_ring_element.py | 4 +- src/sage/rings/rational.pyx | 4 +- src/sage/rings/real_double.pyx | 4 +- src/sage/rings/real_mpfr.pyx | 26 ++++++------ .../elliptic_curves/ell_finite_field.py | 2 +- .../schemes/elliptic_curves/ell_generic.py | 4 +- .../elliptic_curves/ell_number_field.py | 4 +- src/sage/schemes/elliptic_curves/ell_point.py | 12 +++--- src/sage/schemes/elliptic_curves/ell_wp.py | 2 +- src/sage/schemes/elliptic_curves/gp_simon.py | 4 +- .../schemes/projective/projective_morphism.py | 2 +- src/sage/structure/factorization.py | 2 +- src/sage/structure/sage_object.pyx | 2 +- src/sage/tests/benchmark.py | 8 ++-- 80 files changed, 297 insertions(+), 297 deletions(-) diff --git a/src/doc/en/developer/coding_in_other.rst b/src/doc/en/developer/coding_in_other.rst index 640c8acd49a..6375ba4cbb3 100644 --- a/src/doc/en/developer/coding_in_other.rst +++ b/src/doc/en/developer/coding_in_other.rst @@ -138,7 +138,7 @@ convert output from PARI to Sage objects:: if not self.is_square(): raise ArithmeticError("frobenius matrix of non-square matrix not defined.") - v = self._pari_().matfrobenius(flag) + v = self.__pari__().matfrobenius(flag) if flag==0: return self.matrix_space()(v.python()) elif flag==1: diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index 22f884637d9..b3876f9b0ae 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -3301,7 +3301,7 @@ def binomial(x, m, **kwds): # case 3: rational, real numbers, complex numbers -> use pari if isinstance(x, (Rational, RealNumber, ComplexNumber)): - return P(x._pari_().binomial(m)) + return P(x.__pari__().binomial(m)) # case 4: naive method if m < ZZ.zero(): diff --git a/src/sage/functions/exp_integral.py b/src/sage/functions/exp_integral.py index 1dd857000cd..7280bf34bcb 100644 --- a/src/sage/functions/exp_integral.py +++ b/src/sage/functions/exp_integral.py @@ -1490,12 +1490,12 @@ def exponential_integral_1(x, n=0): # Add extra bits to the input. # (experimentally verified -- Jeroen Demeyer) inprec = prec + 5 + math.ceil(math.log(prec)) - x = RealField(inprec)(x)._pari_() + x = RealField(inprec)(x).__pari__() return R(x.eint1()) else: # PARI's algorithm is less precise as n grows larger: # add extra bits. # (experimentally verified -- Jeroen Demeyer) inprec = prec + 1 + math.ceil(1.4427 * math.log(n)) - x = RealField(inprec)(x)._pari_() + x = RealField(inprec)(x).__pari__() return [R(z) for z in x.eint1(n)] diff --git a/src/sage/groups/pari_group.py b/src/sage/groups/pari_group.py index 5c3496e8c20..ad806a1e06e 100644 --- a/src/sage/groups/pari_group.py +++ b/src/sage/groups/pari_group.py @@ -53,7 +53,7 @@ def __cmp__(self, other): return cmp(type(self), type(other)) return cmp((self.__x, self.__degree), (other.__x, other.__degree)) - def _pari_(self): + def __pari__(self): return self.__x def degree(self): diff --git a/src/sage/libs/cypari2/gen.pyx b/src/sage/libs/cypari2/gen.pyx index e4c5855e139..7729b7b199a 100644 --- a/src/sage/libs/cypari2/gen.pyx +++ b/src/sage/libs/cypari2/gen.pyx @@ -4430,7 +4430,7 @@ cpdef Gen objtogen(s): """ Convert any Sage/Python object to a PARI :class:`Gen`. - For Sage types, this uses the ``_pari_()`` method on the object. + For Sage types, this uses the ``__pari__()`` method on the object. Basic Python types like ``int`` are converted directly. For other types, the string representation is used. @@ -4520,7 +4520,7 @@ cpdef Gen objtogen(s): if isinstance(s, Gen): return s try: - return s._pari_() + return s.__pari__() except AttributeError: pass diff --git a/src/sage/libs/pari/convert_flint.pyx b/src/sage/libs/pari/convert_flint.pyx index 5fbda4085f5..9d8ec66e0a1 100644 --- a/src/sage/libs/pari/convert_flint.pyx +++ b/src/sage/libs/pari/convert_flint.pyx @@ -86,7 +86,7 @@ cdef Gen integer_matrix(fmpz_mat_t B, Py_ssize_t nr, Py_ssize_t nc, bint permute """ EXAMPLES:: - sage: matrix(ZZ,2,[1..6])._pari_() # indirect doctest + sage: matrix(ZZ,2,[1..6]).__pari__() # indirect doctest [1, 2, 3; 4, 5, 6] """ sig_on() diff --git a/src/sage/libs/pari/convert_gmp.pyx b/src/sage/libs/pari/convert_gmp.pyx index da1a15b0ebf..ef4b9e0176a 100644 --- a/src/sage/libs/pari/convert_gmp.pyx +++ b/src/sage/libs/pari/convert_gmp.pyx @@ -171,7 +171,7 @@ cdef Gen rational_matrix(mpq_t** B, long nr, long nc): EXAMPLES:: - sage: matrix(QQ,2,[1..6])._pari_() # indirect doctest + sage: matrix(QQ,2,[1..6]).__pari__() # indirect doctest [1, 2, 3; 4, 5, 6] """ sig_on() diff --git a/src/sage/libs/pari/tests.py b/src/sage/libs/pari/tests.py index cb6e45aecac..ced54948e87 100644 --- a/src/sage/libs/pari/tests.py +++ b/src/sage/libs/pari/tests.py @@ -1021,7 +1021,7 @@ ] sage: M = diagonal_matrix([1,1,-1]) - sage: P = M._pari_().qfparam([0,1,-1]); P + sage: P = M.__pari__().qfparam([0,1,-1]); P [0, -2, 0; 1, 0, -1; -1, 0, -1] sage: R. = QQ[] sage: v = P.sage() * vector([x^2, x*y, y^2]); v @@ -1034,22 +1034,22 @@ True sage: M = diagonal_matrix([1,2,3,4,-5]) - sage: M._pari_().qfsolve() + sage: M.__pari__().qfsolve() [0, 1, -1, 0, -1]~ sage: M = diagonal_matrix([4,-9]) - sage: M._pari_().qfsolve() + sage: M.__pari__().qfsolve() [6, 4]~ sage: M = diagonal_matrix([1,1,1,1,1]) - sage: M._pari_().qfsolve() + sage: M.__pari__().qfsolve() -1 sage: M = diagonal_matrix([1,1,-3]) - sage: M._pari_().qfsolve() + sage: M.__pari__().qfsolve() 3 sage: M = diagonal_matrix([1,-42]) - sage: M._pari_().qfsolve() + sage: M.__pari__().qfsolve() -2 sage: M = diagonal_matrix([1,-1,0,0]) - sage: M._pari_().qfsolve().sage() + sage: M.__pari__().qfsolve().sage() [0 0] [0 0] [1 0] @@ -1164,7 +1164,7 @@ 82718061255302767487140869206996285356581211090087890624 sage: g.fforder( (5^80-1, factor(5^80-1)) ) 82718061255302767487140869206996285356581211090087890624 - sage: k(2)._pari_().fforder(o=4) + sage: k(2).__pari__().fforder(o=4) 4 p-adic functions:: @@ -1545,7 +1545,7 @@ 0 sage: F = QuadraticField(5, 'alpha') - sage: nf = F._pari_() + sage: nf = F.__pari__() sage: P = F.ideal(F.gen()) sage: Q = F.ideal(2) sage: moduli = pari.matrix(2,2,[P.pari_prime(),4,Q.pari_prime(),4]) @@ -1557,7 +1557,7 @@ True sage: F = NumberField(x^3-2, 'alpha') - sage: nf = F._pari_() + sage: nf = F.__pari__() sage: x = pari('[1, -1, 2]~') sage: y = pari('[1, -1, 3]~') sage: nf.idealcoprime(x, y) @@ -1576,7 +1576,7 @@ [[65, 8; 0, 1], [65, 47; 0, 1], [65, 18; 0, 1], [65, 57; 0, 1]] sage: F = NumberField(x^3-2, 'alpha') - sage: nf = F._pari_() + sage: nf = F.__pari__() sage: I = pari('[1, -1, 2]~') sage: bid = nf.idealstar(I) sage: nf.ideallog(5, bid) @@ -1590,7 +1590,7 @@ sage: x = polygen(ZZ) sage: F = NumberField(x^3 - 2, 'alpha') - sage: nf = F._pari_() + sage: nf = F.__pari__() sage: I = pari('[1, -1, 2]~') sage: nf.idealstar(I) [[[43, 9, 5; 0, 1, 0; 0, 0, 1], [0]], [42, [42]], Mat([[43, [9, 1, 0]~, 1, 1, [-5, 2, -18; -9, -5, 2; 1, -9, -5]], 1]), [[[[[42], [3], [3], [Vecsmall([])], 1, [43, 9, 5; 0, 1, 0; 0, 0, 1]]]], [[], [], [], Vecsmall([])], Vecsmall([0])], Mat(1)] @@ -1677,17 +1677,17 @@ sage: F = NumberField(x^3-2,'alpha') sage: G = NumberField(x^3-2,'beta') - sage: F._pari_().nfisisom(G._pari_()) + sage: F.__pari__().nfisisom(G.__pari__()) [y] sage: GG = NumberField(x^3-4,'gamma') - sage: F._pari_().nfisisom(GG._pari_()) + sage: F.__pari__().nfisisom(GG.__pari__()) [1/2*y^2] - sage: F._pari_().nfisisom(GG.pari_nf()) + sage: F.__pari__().nfisisom(GG.pari_nf()) [1/2*y^2] - sage: F.pari_nf().nfisisom(GG._pari_()[0]) + sage: F.pari_nf().nfisisom(GG.__pari__()[0]) [y^2] sage: H = NumberField(x^2-2,'alpha') - sage: F._pari_().nfisisom(H._pari_()) + sage: F.__pari__().nfisisom(H.__pari__()) 0 sage: K. = NumberField(x^2 + x + 1) sage: L. = NumberField(x^2 + 3) @@ -1736,14 +1736,14 @@ sage: x = SR.symbol('x') sage: F = NumberField(x^3-2,'alpha') - sage: F._pari_()[0].nfdisc() + sage: F.__pari__()[0].nfdisc() -108 sage: G = NumberField(x^5-11,'beta') - sage: G._pari_()[0].nfdisc() + sage: G.__pari__()[0].nfdisc() 45753125 sage: f = x^3-2 - sage: f._pari_() + sage: f.__pari__() x^3 - 2 - sage: f._pari_().nfdisc() + sage: f.__pari__().nfdisc() -108 """ diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index 940d511049b..dcd24c80443 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -60,7 +60,7 @@ cdef class Matrix(matrix0.Matrix): v.append( ','.join(tmp)) return 'Mat([%s])'%(';'.join(v)) - def _pari_(self): + def __pari__(self): """ Return the Pari matrix corresponding to self. diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 259ce011cf6..328cd02f47f 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -1605,7 +1605,7 @@ cdef class Matrix(matrix1.Matrix): # word, use PARI. ch = R.characteristic() if ch.is_prime() and ch < (2*sys.maxsize): - d = R(self._pari_().matdet()) + d = R(self.__pari__().matdet()) else: # Lift to ZZ and compute there. d = R(self.apply_map(lambda x : x.lift_centered()).det()) @@ -2560,7 +2560,7 @@ cdef class Matrix(matrix1.Matrix): if not is_NumberField(K): raise ValueError("_charpoly_over_number_field called with base ring (%s) not a number field" % K) - paripoly = self._pari_().charpoly() + paripoly = self.__pari__().charpoly() return K[var](paripoly) def fcp(self, var='x'): @@ -3071,7 +3071,7 @@ cdef class Matrix(matrix1.Matrix): [0 0 1] """ tm = verbose("computing right kernel matrix over a number field for %sx%s matrix" % (self.nrows(), self.ncols()),level=1) - basis = self._pari_().matker() + basis = self.__pari__().matker() # Coerce PARI representations into the number field R = self.base_ring() basis = [[R(x) for x in row] for row in basis] diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx index 8a35f304ad7..90048617e53 100644 --- a/src/sage/matrix/matrix_integer_dense.pyx +++ b/src/sage/matrix/matrix_integer_dense.pyx @@ -2221,7 +2221,7 @@ cdef class Matrix_integer_dense(Matrix_dense): # dense or sparse if algorithm == 'linbox': raise ValueError("linbox too broken -- currently Linbox SNF is disabled.") if algorithm == 'pari': - d = self._pari_().matsnf(0).sage() + d = self.__pari__().matsnf(0).sage() i = d.count(0) d.sort() if i > 0: @@ -2307,7 +2307,7 @@ cdef class Matrix_integer_dense(Matrix_dense): # dense or sparse :meth:`elementary_divisors` """ - v = self._pari_().matsnf(1).sage() + v = self.__pari__().matsnf(1).sage() if self._ncols == 0: v[0] = self.matrix_space(ncols = self._nrows)(1) if self._nrows == 0: v[1] = self.matrix_space(nrows = self._ncols)(1) # need to reverse order of rows of U, columns of V, and both of D. @@ -2388,7 +2388,7 @@ cdef class Matrix_integer_dense(Matrix_dense): # dense or sparse if not self.is_square(): raise ArithmeticError("frobenius matrix of non-square matrix not defined.") - v = self._pari_().matfrobenius(flag) + v = self.__pari__().matfrobenius(flag) if flag==0: return self.matrix_space()(v.sage()) elif flag==1: @@ -2543,7 +2543,7 @@ cdef class Matrix_integer_dense(Matrix_dense): # dense or sparse K = self._rational_kernel_flint().transpose().saturation(proof=proof) format = 'computed-flint-int' elif algorithm == 'pari': - K = self._pari_().matkerint().mattranspose().sage() + K = self.__pari__().matkerint().mattranspose().sage() format = 'computed-pari-int' elif algorithm == 'padic': proof = kwds.pop('proof', None) @@ -2570,7 +2570,7 @@ cdef class Matrix_integer_dense(Matrix_dense): # dense or sparse [ 6 -12 6] [ -3 6 -3] """ - return self.parent()(self._pari_().matadjoint().sage()) + return self.parent()(self.__pari__().matadjoint().sage()) def _ntl_(self): r""" @@ -2635,7 +2635,7 @@ cdef class Matrix_integer_dense(Matrix_dense): # dense or sparse n = self.nrows() # maybe should be /unimodular/ matrices ? - P = self._pari_() + P = self.__pari__() try: U = P.lllgramint() except (RuntimeError, ArithmeticError) as msg: @@ -5383,14 +5383,14 @@ cdef class Matrix_integer_dense(Matrix_dense): # dense or sparse [nr - t for t in reversed(row_divs)]) return A - def _pari_(self): + def __pari__(self): """ Return PARI C-library version of this matrix. EXAMPLES:: sage: a = matrix(ZZ,2,2,[1,2,3,4]) - sage: a._pari_() + sage: a.__pari__() [1, 2; 3, 4] sage: pari(a) [1, 2; 3, 4] diff --git a/src/sage/matrix/matrix_rational_dense.pyx b/src/sage/matrix/matrix_rational_dense.pyx index 5abf74b3575..40c1413b8da 100644 --- a/src/sage/matrix/matrix_rational_dense.pyx +++ b/src/sage/matrix/matrix_rational_dense.pyx @@ -1172,7 +1172,7 @@ cdef class Matrix_rational_dense(Matrix_dense): [ 2/27 -4/27 2/27] [-1/27 2/27 -1/27] """ - return self.parent()(self._pari_().matadjoint().sage()) + return self.parent()(self.__pari__().matadjoint().sage()) def _magma_init_(self, magma): """ @@ -2594,13 +2594,13 @@ cdef class Matrix_rational_dense(Matrix_dense): clear_stack() return A - def _pari_(self): + def __pari__(self): """ Return pari version of this matrix. EXAMPLES:: - sage: matrix(QQ,2,[1/5,-2/3,3/4,4/9])._pari_() + sage: matrix(QQ,2,[1/5,-2/3,3/4,4/9]).__pari__() [1/5, -2/3; 3/4, 4/9] """ return rational_matrix(self._matrix, self._nrows, self._ncols) diff --git a/src/sage/modular/btquotients/btquotient.py b/src/sage/modular/btquotients/btquotient.py index 024b1889d6b..af684187ca8 100644 --- a/src/sage/modular/btquotients/btquotient.py +++ b/src/sage/modular/btquotients/btquotient.py @@ -2873,9 +2873,9 @@ def get_units_of_order(self): ] """ OM = self.get_eichler_order_quadmatrix() - v = pari('qfminim(%s,2,0, flag = 2)' % (OM._pari_())) + v = pari('qfminim(%s,2,0, flag = 2)' % (OM.__pari__())) n_units = Integer(v[0].sage() / 2) - v = pari('qfminim(%s,2,%s, flag = 2)' % ((OM._pari_()), n_units)) + v = pari('qfminim(%s,2,%s, flag = 2)' % ((OM.__pari__()), n_units)) O_units = [] for jj in range(n_units): vec = Matrix(ZZ, 4, 1, [v[2][ii, jj].sage() for ii in range(4)]) @@ -3254,7 +3254,7 @@ def _stabilizer(self, e, as_edge=True): n_units = len(self.get_units_of_order()) ## Using PARI to get the shortest vector in the lattice (via LLL) ## We used to pass qfminim flag = 2 - mat = pari('qfminim(%s,,%s,flag = 2)' % (A._pari_(), 2 * n_units))[2].sage().transpose() + mat = pari('qfminim(%s,,%s,flag = 2)' % (A.__pari__(), 2 * n_units))[2].sage().transpose() n_vecs = mat.nrows() stabs = [] for jj in range(n_vecs): @@ -3320,7 +3320,7 @@ def _nebentype_check(self, vec, twom, E, A, flag = 2): if not self._use_magma or len(self._extra_level) == 0: return E * vec, True m = ZZ(twom / 2) - mat = pari('qfminim(%s,,%s,flag = %s)' % (A._pari_(), 1000, flag))[2].sage().transpose() + mat = pari('qfminim(%s,,%s,flag = %s)' % (A.__pari__(), 1000, flag))[2].sage().transpose() n_vecs = mat.nrows() p = self._p pinv = Zmod(self._character.modulus())(p) ** -1 @@ -3388,7 +3388,7 @@ def _are_equivalent(self, v1, v2, as_edges=False, twom=None, return None E, A = self._find_lattice(v1, v2, as_edges, twom) ## Using PARI to get the shortest vector in the lattice (via LLL) - vec = pari('qfminim(%s,,1,flag = 2)' % (A._pari_()))[2].sage() + vec = pari('qfminim(%s,,1,flag = 2)' % (A.__pari__()))[2].sage() vect = vec.transpose() nrd = Integer((vect * A * vec)[0, 0] / 2) diff --git a/src/sage/modular/overconvergent/genus0.py b/src/sage/modular/overconvergent/genus0.py index e450a71724c..06c28f19070 100644 --- a/src/sage/modular/overconvergent/genus0.py +++ b/src/sage/modular/overconvergent/genus0.py @@ -1053,13 +1053,13 @@ def eigenfunctions(self, n, F = None, exact_arith=True): if d != 1: continue - mr = (m._pari_() - r._pari_()) + mr = (m.__pari__() - r.__pari__()) # Annoying thing: r isn't quite as precise as it claims to be # (bug reported to sage-support list) while F(mr.matdet()) != 0: verbose("p-adic solver returned wrong result in slope %s; refining" % r.valuation(), level=2) r = r - cp(r)/cp.derivative()(r) - mr2 = (m._pari_() - r._pari_()) + mr2 = (m.__pari__() - r.__pari__()) if mr2.matdet().valuation(self.prime()) > mr.matdet().valuation(self.prime()): mr = mr2 else: @@ -1648,7 +1648,7 @@ def base_extend(self, R): S = self.parent().base_extend(R) return S(self) - def _pari_(self): + def __pari__(self): r""" Return the Pari object corresponding to self, which is just the `q`-expansion of self as a formal power series. @@ -1661,4 +1661,4 @@ def _pari_(self): sage: pari(f.base_extend(Qp(3))) # indirect doctest (3^3 + O(3^23))*q + (3^4 + 3^5 + O(3^24))*q^2 + (3^5 + 3^7 + O(3^25))*q^3 + (3^3 + 3^4 + 2*3^5 + 2*3^8 + O(3^23))*q^4 + (2*3^4 + 3^5 + 3^6 + 2*3^7 + 3^10 + O(3^24))*q^5 + (3^6 + 3^7 + 3^8 + 3^9 + 3^10 + 3^11 + O(3^26))*q^6 + (2*3^3 + 3^4 + 2*3^6 + 2*3^7 + 2*3^8 + 3^9 + 3^10 + 2*3^11 + 3^12 + O(3^23))*q^7 + (2*3^4 + 3^5 + 3^8 + 2*3^9 + 2*3^10 + 2*3^13 + O(3^24))*q^8 + (3^7 + 2*3^9 + 2*3^12 + 2*3^14 + O(3^27))*q^9 + (2*3^5 + 3^8 + 3^9 + 2*3^10 + 2*3^13 + 2*3^15 + O(3^25))*q^10 + (3^4 + 2*3^5 + 2*3^6 + 3^8 + 2*3^9 + 3^12 + 3^14 + 2*3^16 + O(3^24))*q^11 + (3^5 + 3^6 + 2*3^8 + 2*3^9 + 2*3^10 + 2*3^12 + 3^14 + 2*3^15 + 2*3^16 + 3^17 + O(3^25))*q^12 + (2*3^3 + 2*3^4 + 2*3^5 + 3^8 + 2*3^9 + 2*3^11 + 3^13 + 2*3^14 + 2*3^17 + 3^18 + O(3^23))*q^13 + (2*3^4 + 2*3^6 + 2*3^7 + 3^8 + 2*3^9 + 3^10 + 3^12 + 3^14 + 2*3^15 + 2*3^16 + 3^18 + 3^19 + O(3^24))*q^14 + (2*3^6 + 3^7 + 3^9 + 3^10 + 3^11 + 2*3^14 + 3^15 + 2*3^16 + 3^17 + 3^18 + 3^20 + O(3^26))*q^15 + (3^3 + 2*3^4 + 2*3^7 + 2*3^8 + 3^9 + 3^10 + 2*3^11 + 3^12 + 2*3^14 + 2*3^15 + 3^17 + 3^18 + 2*3^19 + 2*3^20 + O(3^23))*q^16 + (2*3^5 + 2*3^7 + 2*3^8 + 3^10 + 3^11 + 2*3^12 + 2*3^13 + 3^14 + 3^15 + 3^17 + 2*3^18 + 3^19 + 2*3^21 + O(3^25))*q^17 + (3^8 + 3^9 + 2*3^10 + 2*3^11 + 3^12 + 3^14 + 3^15 + 3^16 + 3^17 + 2*3^21 + 3^22 + O(3^28))*q^18 + (2*3^3 + 3^5 + 2*3^6 + 2*3^8 + 2*3^9 + 3^11 + 2*3^12 + 3^13 + 3^14 + 2*3^15 + 3^16 + 3^17 + 2*3^18 + 3^19 + 2*3^21 + O(3^23))*q^19 + O(q^20) """ - return self.q_expansion()._pari_() + return self.q_expansion().__pari__() diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index f82a0f5690c..71e81cdb443 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -854,7 +854,7 @@ cdef class FreeModuleElement(Vector): # abstract base class """ return self.list() - def _pari_(self): + def __pari__(self): """ Convert ``self`` to a PARI vector. @@ -865,9 +865,9 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector(range(4)) - sage: v._pari_() + sage: v.__pari__() [0, 1, 2, 3] - sage: v._pari_().type() + sage: v.__pari__().type() 't_VEC' A list of vectors:: diff --git a/src/sage/modules/free_module_integer.py b/src/sage/modules/free_module_integer.py index 1f57eb25fae..84a1e9f878e 100644 --- a/src/sage/modules/free_module_integer.py +++ b/src/sage/modules/free_module_integer.py @@ -624,7 +624,7 @@ def shortest_vector(self, update_reduced_basis=True, algorithm="fplll", *args, * B = self.reduced_basis.LLL() qf = B*B.transpose() - count, length, vectors = qf._pari_().qfminim() + count, length, vectors = qf.__pari__().qfminim() v = vectors.sage().columns()[0] w = v*B elif algorithm == "fplll": diff --git a/src/sage/quadratic_forms/qfsolve.py b/src/sage/quadratic_forms/qfsolve.py index 707b01fc1bb..e5a54d38dd2 100644 --- a/src/sage/quadratic_forms/qfsolve.py +++ b/src/sage/quadratic_forms/qfsolve.py @@ -72,7 +72,7 @@ def qfsolve(G): sage: qfsolve(M) (3, -4, -3, -2) """ - ret = G._pari_().qfsolve() + ret = G.__pari__().qfsolve() if ret.type() == 't_COL': return vector(QQ, ret) return ZZ(ret) @@ -112,7 +112,7 @@ def qfparam(G, sol): """ R = QQ['t'] t = R.gen() - mat = G._pari_().qfparam(sol) + mat = G.__pari__().qfparam(sol) # Interpret the rows of mat as coefficients of polynomials return vector(R, mat.Col()) diff --git a/src/sage/quadratic_forms/quadratic_form.py b/src/sage/quadratic_forms/quadratic_form.py index 981018f655f..b185d52fd6f 100644 --- a/src/sage/quadratic_forms/quadratic_form.py +++ b/src/sage/quadratic_forms/quadratic_form.py @@ -499,18 +499,18 @@ def list_external_initializations(self): return deepcopy(self._external_initialization_list) - def _pari_(self): + def __pari__(self): """ Return a PARI-formatted Hessian matrix for Q. EXAMPLES:: sage: Q = QuadraticForm(ZZ, 2, [1,0,5]) - sage: Q._pari_() + sage: Q.__pari__() [2, 0; 0, 10] """ - return self.matrix()._pari_() + return self.matrix().__pari__() def _pari_init_(self): """ diff --git a/src/sage/quadratic_forms/quadratic_form__automorphisms.py b/src/sage/quadratic_forms/quadratic_form__automorphisms.py index 47aa75e2407..274c8bbd0b3 100644 --- a/src/sage/quadratic_forms/quadratic_form__automorphisms.py +++ b/src/sage/quadratic_forms/quadratic_form__automorphisms.py @@ -54,7 +54,7 @@ def basis_of_short_vectors(self, show_lengths=False, safe_flag=None): Max_number_of_vectors = 10000 ## Generate a PARI matrix for the associated Hessian matrix - M_pari = self._pari_() + M_pari = self.__pari__() ## Run through all possible minimal lengths to find a spanning set of vectors n = self.dim() @@ -177,10 +177,10 @@ def short_vector_list_up_to_length(self, len_bound, up_to_sign_flag=False): sage: Q = QuadraticForm(matrix(2, [72, 12, 12, 120])) sage: len_bound_pari = 2*22953421 - 2; len_bound_pari 45906840 - sage: vs = list(Q._pari_().qfminim(len_bound_pari)[2]) # long time (18s on sage.math, 2014) + sage: vs = list(Q.__pari__().qfminim(len_bound_pari)[2]) # long time (18s on sage.math, 2014) sage: v = vs[0]; v # long time [66, -623]~ - sage: v.Vec() * Q._pari_() * v # long time + sage: v.Vec() * Q.__pari__() * v # long time 45902280 """ if not self.is_positive_definite() : @@ -198,7 +198,7 @@ def short_vector_list_up_to_length(self, len_bound, up_to_sign_flag=False): len_bound_pari = 2*(len_bound - 1) # Call PARI's qfminim() - parilist = self._pari_().qfminim(len_bound_pari)[2].Vec() + parilist = self.__pari__().qfminim(len_bound_pari)[2].Vec() # List of lengths parilens = pari(r"(M,v) -> vector(#v, i, (v[i]~ * M * v[i])\2)")(self, parilist) @@ -279,7 +279,7 @@ def _compute_automorphisms(self): if hasattr(self, "__automorphisms_pari"): return - A = self._pari_().qfauto() + A = self.__pari__().qfauto() self.__number_of_automorphisms = A[0] self.__automorphisms_pari = A[1] diff --git a/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py b/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py index 5ba21755ffa..480645688ff 100644 --- a/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py +++ b/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py @@ -95,7 +95,7 @@ def is_globally_equivalent_to(self, other, return_matrix=False, check_theta_to_p if not self.is_definite() or not other.is_definite(): raise ValueError("not a definite form in QuadraticForm.is_globally_equivalent_to()") - mat = other._pari_().qfisom(self) + mat = other.__pari__().qfisom(self) if not mat: return False diff --git a/src/sage/quadratic_forms/quadratic_form__local_field_invariants.py b/src/sage/quadratic_forms/quadratic_form__local_field_invariants.py index 30d78bcfc60..cf3b57ec26e 100644 --- a/src/sage/quadratic_forms/quadratic_form__local_field_invariants.py +++ b/src/sage/quadratic_forms/quadratic_form__local_field_invariants.py @@ -138,7 +138,7 @@ def rational_diagonal_form(self, return_matrix=False): This example cannot be computed by PARI:: sage: Q = QuadraticForm(RIF, 4, range(10)) - sage: Q._pari_() + sage: Q.__pari__() Traceback (most recent call last): ... TypeError @@ -229,7 +229,7 @@ def _rational_diagonal_form_and_transformation(self): try: # Try PARI if the type is supported - pariself = self._pari_() + pariself = self.__pari__() # Check that conversion back works MS(pariself.sage()) except Exception: diff --git a/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py b/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py index 06eee7c28ec..f2b8fe5f5dd 100644 --- a/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +++ b/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py @@ -543,7 +543,7 @@ def representation_number_list(self, B): [1, 16, 112, 448, 1136, 2016, 3136, 5504, 9328, 12112] """ - ans = pari(1).concat(self._pari_().qfrep(B-1, 1) * 2) + ans = pari(1).concat(self.__pari__().qfrep(B-1, 1) * 2) return ans.sage() @@ -571,7 +571,7 @@ def representation_vector_list(self, B, maxvectors = 10**8): [1, 4, 4, 0, 4, 8, 0, 0, 4, 4] """ - n, m, vs = self._pari_().qfminim(2*(B-1), maxvectors) + n, m, vs = self.__pari__().qfminim(2*(B-1), maxvectors) if n != 2 * len(vs): raise RuntimeError("insufficient number of vectors") ms = [[] for _ in range(B)] diff --git a/src/sage/rings/complex_double.pyx b/src/sage/rings/complex_double.pyx index 17529945036..417db2eb128 100644 --- a/src/sage/rings/complex_double.pyx +++ b/src/sage/rings/complex_double.pyx @@ -1112,13 +1112,13 @@ cdef class ComplexDoubleElement(FieldElement): s = str(self).replace('*I', 'i') return re.sub(r"e\+?(-?\d+)", r" \\times 10^{\1}", s) - def _pari_(self): + def __pari__(self): """ Return PARI version of ``self``, as ``t_COMPLEX`` or ``t_REAL``. EXAMPLES:: - sage: CDF(1,2)._pari_() + sage: CDF(1,2).__pari__() 1.00000000000000 + 2.00000000000000*I sage: pari(CDF(1,2)) 1.00000000000000 + 2.00000000000000*I @@ -2178,7 +2178,7 @@ cdef class ComplexDoubleElement(FieldElement): return ComplexDoubleElement(0,0) cdef int flag = 0 if omit_frac else 1 - return pari_to_cdf(self._pari_().eta(flag)) + return pari_to_cdf(self.__pari__().eta(flag)) def agm(self, right, algorithm="optimal"): r""" @@ -2241,7 +2241,7 @@ cdef class ComplexDoubleElement(FieldElement): cdef double d, e, eps = 2.0**-51 if algorithm == "pari": - return pari_to_cdf(self._pari_().agm(right)) + return pari_to_cdf(self.__pari__().agm(right)) if not isinstance(right, ComplexDoubleElement): right = CDF(right) @@ -2291,7 +2291,7 @@ cdef class ComplexDoubleElement(FieldElement): sage: CDF(10000000,10000000).dilog() -134.411774490731 + 38.79396299904504*I """ - return pari_to_cdf(self._pari_().dilog()) + return pari_to_cdf(self.__pari__().dilog()) def gamma(self): r""" @@ -2319,7 +2319,7 @@ cdef class ComplexDoubleElement(FieldElement): return CC(self).gamma() except TypeError: pass - return pari_to_cdf(self._pari_().gamma()) + return pari_to_cdf(self.__pari__().gamma()) def gamma_inc(self, t): r""" @@ -2334,7 +2334,7 @@ cdef class ComplexDoubleElement(FieldElement): sage: CDF(2,0).gamma_inc(CDF(1,1)) 0.7070920963459381 - 0.4203536409598115*I """ - return pari_to_cdf(self._pari_().incgam(t)) + return pari_to_cdf(self.__pari__().incgam(t)) def zeta(self): """ @@ -2353,7 +2353,7 @@ cdef class ComplexDoubleElement(FieldElement): if self._complex.dat[0] == 1 and self._complex.dat[1] == 0: from .infinity import unsigned_infinity return unsigned_infinity - return pari_to_cdf(self._pari_().zeta()) + return pari_to_cdf(self.__pari__().zeta()) def algdep(self, long n): """ @@ -2386,7 +2386,7 @@ cdef class ComplexDoubleElement(FieldElement): from .polynomial.polynomial_ring_constructor import PolynomialRing from .integer_ring import ZZ R = PolynomialRing(ZZ ,'x') - return R(self._pari_().algdep(n)) + return R(self.__pari__().algdep(n)) cdef class FloatToCDF(Morphism): diff --git a/src/sage/rings/complex_mpc.pyx b/src/sage/rings/complex_mpc.pyx index 500a13baca4..6f85e856619 100644 --- a/src/sage/rings/complex_mpc.pyx +++ b/src/sage/rings/complex_mpc.pyx @@ -1174,7 +1174,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): rnd = (self._parent).__rnd return complex(mpfr_get_d(self.value.re, rnd_re(rnd)), mpfr_get_d(self.value.im, rnd_im(rnd))) - def _pari_(self): + def __pari__(self): r""" Convert ``self`` to a PARI object. @@ -1185,7 +1185,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): sage: MPC = MPComplexField() sage: a = MPC(2,1) - sage: a._pari_() + sage: a.__pari__() 2.00000000000000 + 1.00000000000000*I sage: pari(a) 2.00000000000000 + 1.00000000000000*I @@ -1203,18 +1203,18 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): The precision is preserved, rounded up to the wordsize:: sage: MPC = MPComplexField(250) - sage: MPC(1,2)._pari_().bitprecision() + sage: MPC(1,2).__pari__().bitprecision() 256 - sage: MPC(pi)._pari_().bitprecision() + sage: MPC(pi).__pari__().bitprecision() 256 """ if mpfr_zero_p(self.value.re): re = pari.PARI_ZERO else: - re = self.real()._pari_() + re = self.real().__pari__() if mpfr_zero_p(self.value.im): return re - im = self.imag()._pari_() + im = self.imag().__pari__() return pari.complex(re, im) cpdef int _cmp_(self, other) except -2: @@ -2191,7 +2191,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): sage: c.dilog() 0 """ - return self._parent(self._pari_().dilog()) + return self._parent(self.__pari__().dilog()) def eta(self, omit_frac=False): r""" @@ -2224,7 +2224,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): 0.742048775836565 + 0.198831370229911*I """ try: - return self._parent(self._pari_().eta(not omit_frac)) + return self._parent(self.__pari__().eta(not omit_frac)) except sage.libs.pari.all.PariError: raise ValueError("value must be in the upper half plane") @@ -2250,7 +2250,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): Infinity """ try: - return self._parent(self._pari_().gamma()) + return self._parent(self.__pari__().gamma()) except sage.libs.pari.all.PariError: from sage.rings.infinity import UnsignedInfinityRing return UnsignedInfinityRing.gen() @@ -2270,7 +2270,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): 0.70709210 - 0.42035364*I """ - return self._parent(self._pari_().incgam(t, precision=self.prec())) + return self._parent(self.__pari__().incgam(t, precision=self.prec())) def zeta(self): """ @@ -2283,7 +2283,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): sage: z.zeta() 0.58215806 - 0.92684856*I """ - return self._parent(self._pari_().zeta()) + return self._parent(self.__pari__().zeta()) def agm(self, right, algorithm="optimal"): """ @@ -2302,8 +2302,8 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): -0.410522769709397 + 4.60061063922097*I """ if algorithm=="pari": - t = self._parent(right)._pari_() - return self._parent(self._pari_().agm(t)) + t = self._parent(right).__pari__() + return self._parent(self.__pari__().agm(t)) cdef MPComplexNumber a, b, d, s, res cdef mpfr_t sn,dn diff --git a/src/sage/rings/complex_number.pyx b/src/sage/rings/complex_number.pyx index ff4212f91c0..67f2cdda417 100644 --- a/src/sage/rings/complex_number.pyx +++ b/src/sage/rings/complex_number.pyx @@ -542,7 +542,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): s = self.str().replace('*I', 'i').replace('infinity','\\infty') return re.sub(r"e(-?\d+)", r" \\times 10^{\1}", s) - def _pari_(self): + def __pari__(self): r""" Coerces ``self`` into a PARI ``t_COMPLEX`` object, or a ``t_REAL`` if ``self`` is real. @@ -558,9 +558,9 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): 't_COMPLEX' sage: type(pari(a)) - sage: a._pari_() + sage: a.__pari__() 2.00000000000000 + 1.00000000000000*I - sage: type(a._pari_()) + sage: type(a.__pari__()) sage: a = CC(pi) sage: pari(a) @@ -572,7 +572,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): 1.41421356237310*I """ if self.is_real(): - return self.real()._pari_() + return self.real().__pari__() return sage.libs.pari.all.pari.complex(self.real() or 0, self.imag()) def _mpmath_(self, prec=None, rounding=None): @@ -1243,7 +1243,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): sage: (1+CC(I)).arccos() 0.904556894302381 - 1.06127506190504*I """ - return self._parent(self._pari_().acos()) + return self._parent(self.__pari__().acos()) def arccosh(self): """ @@ -1254,7 +1254,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): sage: (1+CC(I)).arccosh() 1.06127506190504 + 0.904556894302381*I """ - return self._parent(self._pari_().acosh()) + return self._parent(self.__pari__().acosh()) def arcsin(self): """ @@ -1265,7 +1265,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): sage: (1+CC(I)).arcsin() 0.666239432492515 + 1.06127506190504*I """ - return self._parent(self._pari_().asin()) + return self._parent(self.__pari__().asin()) def arcsinh(self): """ @@ -1276,7 +1276,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): sage: (1+CC(I)).arcsinh() 1.06127506190504 + 0.666239432492515*I """ - return self._parent(self._pari_().asinh()) + return self._parent(self.__pari__().asinh()) def arctan(self): """ @@ -1287,7 +1287,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): sage: (1+CC(I)).arctan() 1.01722196789785 + 0.402359478108525*I """ - return self._parent(self._pari_().atan()) + return self._parent(self.__pari__().atan()) def arctanh(self): """ @@ -1298,7 +1298,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): sage: (1+CC(I)).arctanh() 0.402359478108525 + 1.01722196789785*I """ - return self._parent(self._pari_().atanh()) + return self._parent(self.__pari__().atanh()) def coth(self): """ @@ -1525,7 +1525,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): 0.742048775836565 + 0.198831370229911*I """ try: - return self._parent(self._pari_().eta(not omit_frac)) + return self._parent(self.__pari__().eta(not omit_frac)) except sage.libs.pari.all.PariError: raise ValueError("value must be in the upper half plane") @@ -1760,8 +1760,8 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 """ if algorithm=="pari": - t = self._parent(right)._pari_() - return self._parent(self._pari_().agm(t)) + t = self._parent(right).__pari__() + return self._parent(self.__pari__().agm(t)) cdef ComplexNumber a, b, a1, b1, d, e, res cdef mp_exp_t rel_prec @@ -1958,7 +1958,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): sage: c.dilog() 0.000000000000000 """ - return self._parent(self._pari_().dilog()) + return self._parent(self.__pari__().dilog()) def exp(ComplexNumber self): r""" @@ -2005,7 +2005,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): Infinity """ try: - return self._parent(self._pari_().gamma()) + return self._parent(self.__pari__().gamma()) except sage.libs.pari.all.PariError: from sage.rings.infinity import UnsignedInfinityRing return UnsignedInfinityRing.gen() @@ -2036,7 +2036,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): 0.121515644664508695525971545977439666159749344176962379708992904126499444842886620664991650378432544392118359044438541515 + 0.101533909079826033296475736021224621546966200987295663190553587086145836461236284668967411665020429964946098113930918850*I """ - return self._parent(self._pari_().incgam(t, precision=self.prec())) + return self._parent(self.__pari__().incgam(t, precision=self.prec())) def log(self,base=None): r""" @@ -2358,7 +2358,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): """ if mpfr_zero_p(self.__im) and mpfr_cmp_ui(self.__re, 1) == 0: return infinity.unsigned_infinity - return self._parent(self._pari_().zeta()) + return self._parent(self.__pari__().zeta()) def algdep(self, n, **kwds): """ diff --git a/src/sage/rings/factorint.pyx b/src/sage/rings/factorint.pyx index 29815302dff..63808b8aea3 100644 --- a/src/sage/rings/factorint.pyx +++ b/src/sage/rings/factorint.pyx @@ -349,7 +349,7 @@ def factor_using_pari(n, int_=False, debug_level=0, proof=None): if prev != debug_level: pari.set_debug_level(debug_level) - p, e = n._pari_().factor(proof=proof) + p, e = n.__pari__().factor(proof=proof) if int_: return [(int(p[i]), int(e[i])) for i in range(len(p))] else: diff --git a/src/sage/rings/finite_rings/element_base.pyx b/src/sage/rings/finite_rings/element_base.pyx index c253b4035a5..e39a6be73b6 100644 --- a/src/sage/rings/finite_rings/element_base.pyx +++ b/src/sage/rings/finite_rings/element_base.pyx @@ -168,7 +168,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): if algorithm == 'pari': from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing R = PolynomialRing(self.parent().prime_subfield(), var) - return R(self._pari_().minpoly('x').lift()) + return R(self.__pari__().minpoly('x').lift()) elif algorithm == 'matrix': return self._matrix_().minpoly(var) else: @@ -299,7 +299,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): else: return str(self) - def _pari_(self, var=None): + def __pari__(self, var=None): r""" Return PARI representation of this finite field element. @@ -310,9 +310,9 @@ cdef class FinitePolyExtElement(FiniteRingElement): EXAMPLES:: sage: k. = GF(5^3) - sage: a._pari_() + sage: a.__pari__() a - sage: a._pari_('b') + sage: a.__pari__('b') b sage: t = 3*a^2 + 2*a + 4 sage: t_string = t._pari_init_('y') @@ -320,7 +320,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): 'Mod(Mod(3, 5)*y^2 + Mod(2, 5)*y + Mod(4, 5), Mod(1, 5)*y^3 + Mod(3, 5)*y + Mod(3, 5))' sage: type(t_string) <... 'str'> - sage: t_element = t._pari_('b') + sage: t_element = t.__pari__('b') sage: t_element 3*b^2 + 2*b + 4 sage: type(t_element) @@ -362,7 +362,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): 'Mod(Mod(1, 3)*d, Mod(1, 3)*d^4 + Mod(2, 3)*d^3 + Mod(2, 3))' sage: (d^2+2*d+1)._pari_init_("p") 'Mod(Mod(1, 3)*p^2 + Mod(2, 3)*p + Mod(1, 3), Mod(1, 3)*p^4 + Mod(2, 3)*p^3 + Mod(2, 3))' - sage: d._pari_() + sage: d.__pari__() d sage: K. = GF(2^8) @@ -417,7 +417,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): if algorithm == 'pari': from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing R = PolynomialRing(self.parent().prime_subfield(), var) - return R(self._pari_().charpoly('x').lift()) + return R(self.__pari__().charpoly('x').lift()) elif algorithm == 'matrix': return self._matrix_().charpoly(var) else: @@ -479,7 +479,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): sage: z + z^5 + z^25 2 """ - return self.parent().prime_subfield()(self._pari_().trace().lift()) + return self.parent().prime_subfield()(self.__pari__().trace().lift()) def multiplicative_order(self): r""" diff --git a/src/sage/rings/finite_rings/element_ext_pari.py b/src/sage/rings/finite_rings/element_ext_pari.py index 26d78656717..4f1bdc89aee 100644 --- a/src/sage/rings/finite_rings/element_ext_pari.py +++ b/src/sage/rings/finite_rings/element_ext_pari.py @@ -215,9 +215,9 @@ def __init__(self, parent, value, value_from_pari=False): sage: from sage.rings.finite_rings.element_ext_pari import FiniteField_ext_pariElement sage: a = FiniteField_ext_pariElement(K,pari(0),value_from_pari=True) - sage: a._pari_().type() + sage: a.__pari__().type() 't_INT' - sage: K(0)._pari_().type() + sage: K(0).__pari__().type() 't_POLMOD' """ element.FieldElement.__init__(self, parent) @@ -358,7 +358,7 @@ def __copy__(self): """ return FiniteField_ext_pariElement(self.parent(), self.__value, value_from_pari=True) - def _pari_(self, var=None): + def __pari__(self, var=None): """ Return PARI object corresponding to this finite field element. @@ -366,7 +366,7 @@ def _pari_(self, var=None): sage: k. = FiniteField(3**3, 'a', impl='pari_mod') sage: b = a**2 + 2*a + 1 - sage: b._pari_() + sage: b.__pari__() Mod(Mod(1, 3)*a^2 + Mod(2, 3)*a + Mod(1, 3), Mod(1, 3)*a^3 + Mod(2, 3)*a + Mod(1, 3)) Looking at the PARI representation of a finite field element, it's diff --git a/src/sage/rings/finite_rings/element_givaro.pyx b/src/sage/rings/finite_rings/element_givaro.pyx index d5c3baa4932..0cebc63c5ea 100644 --- a/src/sage/rings/finite_rings/element_givaro.pyx +++ b/src/sage/rings/finite_rings/element_givaro.pyx @@ -433,7 +433,7 @@ cdef class Cache_givaro(SageObject): elif isinstance(e, FiniteFieldElement_pari_ffelt) or isinstance(e, FiniteField_ext_pariElement): # Reduce to pari - e = e._pari_() + e = e.__pari__() elif sage.interfaces.gap.is_GapElement(e): from sage.interfaces.gap import gfq_gap_to_sage diff --git a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx index e6a7d94d33c..061616ff9f4 100644 --- a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx +++ b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx @@ -358,7 +358,7 @@ cdef class Cache_ntl_gf2e(SageObject): elif isinstance(e, FiniteFieldElement_pari_ffelt) or \ isinstance(e, FiniteField_ext_pariElement): # Reduce to pari - e = e._pari_() + e = e.__pari__() elif is_GapElement(e): from sage.interfaces.gap import gfq_gap_to_sage diff --git a/src/sage/rings/finite_rings/element_pari_ffelt.pyx b/src/sage/rings/finite_rings/element_pari_ffelt.pyx index 8a31c5a6229..c421f407d8f 100644 --- a/src/sage/rings/finite_rings/element_pari_ffelt.pyx +++ b/src/sage/rings/finite_rings/element_pari_ffelt.pyx @@ -649,7 +649,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): return self._parent.one() if exp < 0 and FF_equal0(self.val): raise ZeroDivisionError - exp = Integer(exp)._pari_() + exp = Integer(exp).__pari__() cdef FiniteFieldElement_pari_ffelt x = self._new() sig_on() x.construct(FF_pow(self.val, (exp).g)) @@ -1001,7 +1001,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): """ return float(self.lift()) - def _pari_(self, var=None): + def __pari__(self, var=None): """ Return a PARI object representing ``self``. @@ -1013,7 +1013,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): sage: k. = FiniteField(3^3, impl='pari_ffelt') sage: b = a**2 + 2*a + 1 - sage: b._pari_() + sage: b.__pari__() a^2 + 2*a + 1 """ sig_on() diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index a38d7a4209e..89980835cc3 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -434,8 +434,8 @@ cdef class IntegerMod_abstract(FiniteRingElement): def _pari_init_(self): return 'Mod(%s,%s)'%(str(self), self.__modulus.sageInteger) - def _pari_(self): - return self.lift()._pari_().Mod(self.__modulus.sageInteger) + def __pari__(self): + return self.lift().__pari__().Mod(self.__modulus.sageInteger) def _gap_init_(self): r""" @@ -854,7 +854,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): ....: n = p^ep * q^eq * r^er * 2^e2 ....: for _ in range(2): ....: a = Zmod(n).random_element() - ....: if a.is_square().__xor__(a._pari_().issquare()): + ....: if a.is_square().__xor__(a.__pari__().issquare()): ....: print(a, n) ALGORITHM: Calculate the Jacobi symbol @@ -893,7 +893,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): return 0 # We need to factor the modulus. We do it here instead of # letting PARI do it, so that we can cache the factorisation. - return lift._pari_().Zn_issquare(self._parent.factored_order()._pari_()) + return lift.__pari__().Zn_issquare(self._parent.factored_order().__pari__()) def sqrt(self, extend=True, all=False): r""" @@ -1618,7 +1618,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): ArithmeticError: multiplicative order of 0 not defined since it is not a unit modulo 5 """ try: - return sage.rings.integer.Integer(self._pari_().znorder()) + return sage.rings.integer.Integer(self.__pari__().znorder()) except PariError: raise ArithmeticError("multiplicative order of %s not defined since it is not a unit modulo %s"%( self, self.__modulus.sageInteger)) @@ -2679,7 +2679,7 @@ cdef class IntegerMod_int(IntegerMod_abstract): return 0 # We need to factor the modulus. We do it here instead of # letting PARI do it, so that we can cache the factorisation. - return lift._pari_().Zn_issquare(self._parent.factored_order()._pari_()) + return lift.__pari__().Zn_issquare(self._parent.factored_order().__pari__()) def sqrt(self, extend=True, all=False): r""" diff --git a/src/sage/rings/finite_rings/integer_mod_ring.py b/src/sage/rings/finite_rings/integer_mod_ring.py index 70fc75fa81d..e3a7e2c30b7 100644 --- a/src/sage/rings/finite_rings/integer_mod_ring.py +++ b/src/sage/rings/finite_rings/integer_mod_ring.py @@ -1479,7 +1479,7 @@ def unit_group(self, algorithm='sage'): gens.append(x) orders.append(o) elif algorithm == 'pari': - _, orders, gens = self.order()._pari_().znstar() + _, orders, gens = self.order().__pari__().znstar() gens = map(self, gens) orders = map(integer.Integer, orders) else: diff --git a/src/sage/rings/function_field/function_field_element.pyx b/src/sage/rings/function_field/function_field_element.pyx index 65c08035871..876c3de0e3f 100644 --- a/src/sage/rings/function_field/function_field_element.pyx +++ b/src/sage/rings/function_field/function_field_element.pyx @@ -89,7 +89,7 @@ cdef class FunctionFieldElement(FieldElement): x._parent = self._parent return x - def _pari_(self): + def __pari__(self): r""" Coerce this element to PARI. @@ -103,7 +103,7 @@ cdef class FunctionFieldElement(FieldElement): sage: K. = FunctionField(QQ) sage: R. = K[] sage: L. = K.extension(b^2-a) - sage: b._pari_() + sage: b.__pari__() Traceback (most recent call last): ... NotImplementedError: PARI does not support general function field elements. @@ -503,18 +503,18 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): FieldElement.__init__(self, parent) self._x = x - def _pari_(self): + def __pari__(self): r""" Coerce this element to PARI. EXAMPLES:: sage: K. = FunctionField(QQ) - sage: ((a+1)/(a-1))._pari_() + sage: ((a+1)/(a-1)).__pari__() (a + 1)/(a - 1) """ - return self.element()._pari_() + return self.element().__pari__() def element(self): """ diff --git a/src/sage/rings/infinity.py b/src/sage/rings/infinity.py index 65075da8d12..cc2386e5fa7 100644 --- a/src/sage/rings/infinity.py +++ b/src/sage/rings/infinity.py @@ -297,7 +297,7 @@ def _fricas_init_(self): else: return r"%minusInfinity" - def _pari_(self): + def __pari__(self): """ Convert ``self`` to a Pari object. diff --git a/src/sage/rings/integer.pxd b/src/sage/rings/integer.pxd index 426c114379a..c4bcfae9847 100644 --- a/src/sage/rings/integer.pxd +++ b/src/sage/rings/integer.pxd @@ -11,7 +11,7 @@ cdef class Integer(EuclideanDomainElement): cdef void set_from_mpz(self, mpz_t value) cdef hash_c(self) - cpdef _pari_(self) + cpdef __pari__(self) cpdef _shift_helper(Integer self, y, int sign) cdef _and(Integer self, Integer other) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 666757187dc..52f81d1a1e2 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -4394,7 +4394,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: (-64).perfect_power() (-4, 3) """ - parians = self._pari_().ispower() + parians = self.__pari__().ispower() return Integer(parians[1]), Integer(parians[0]) def global_height(self, prec=None): @@ -4751,9 +4751,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): proof = get_flag(proof, "arithmetic") if proof: - n, pari_p = self._pari_().isprimepower() + n, pari_p = self.__pari__().isprimepower() else: - n, pari_p = self._pari_().ispseudoprimepower() + n, pari_p = self.__pari__().ispseudoprimepower() if n: return (Integer(pari_p), smallInteger(n)) if get_data else True @@ -4830,9 +4830,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): from sage.structure.proof.proof import get_flag proof = get_flag(proof, "arithmetic") if proof: - return self._pari_().isprime() + return self.__pari__().isprime() else: - return self._pari_().ispseudoprime() + return self.__pari__().ispseudoprime() cdef bint _pseudoprime_is_prime(self, proof) except -1: """ @@ -4854,7 +4854,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): from sage.structure.proof.proof import get_flag proof = get_flag(proof, "arithmetic") if proof: - return self._pari_().isprime() + return self.__pari__().isprime() else: return True @@ -4879,7 +4879,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): True """ cdef Integer n = self if self >= 0 else -self - return n._pari_().isprime() + return n.__pari__().isprime() def is_pseudoprime(self): r""" @@ -4899,7 +4899,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: z.is_pseudoprime() False """ - return self._pari_().ispseudoprime() + return self.__pari__().ispseudoprime() def is_pseudoprime_power(self, get_data=False): r""" @@ -5302,7 +5302,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: 144168.next_probable_prime() 144169 """ - return Integer( self._pari_().nextprime(True) ) + return Integer( self.__pari__().nextprime(True) ) def next_prime(self, proof=None): r""" @@ -5338,9 +5338,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): 1009 """ # Use PARI to compute the next *pseudo*-prime - p = Integer(self._pari_().nextprime(True)) + p = Integer(self.__pari__().nextprime(True)) while not p._pseudoprime_is_prime(proof): - p = Integer(p._pari_().nextprime(True)) + p = Integer(p.__pari__().nextprime(True)) return p def previous_prime(self, proof=None): @@ -5385,10 +5385,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): if mpz_cmp_ui(self.value, 2) <= 0: raise ValueError("no prime less than 2") cdef Integer p = self-1 - p = Integer(p._pari_().precprime()) + p = Integer(p.__pari__().precprime()) while not p._pseudoprime_is_prime(proof): mpz_sub_ui(p.value, p.value, 1) - p = Integer(p._pari_().precprime()) + p = Integer(p.__pari__().precprime()) return p def next_prime_power(self, proof=None): @@ -5580,16 +5580,16 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: 0.is_squarefree() False """ - return self._pari_().issquarefree() + return self.__pari__().issquarefree() - cpdef _pari_(self): + cpdef __pari__(self): """ Returns the PARI version of this integer. EXAMPLES:: sage: n = 9390823 - sage: m = n._pari_(); m + sage: m = n.__pari__(); m 9390823 sage: type(m) @@ -5597,7 +5597,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): TESTS:: sage: n = 10^10000000 - sage: m = n._pari_() ## crash from trac 875 + sage: m = n.__pari__() ## crash from trac 875 sage: m % 1234567 1041334 @@ -6551,7 +6551,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): raise OverflowError("m must fit in an unsigned long") return x elif algorithm == 'pari': - return the_integer_ring(self._pari_().binomial(mm)) + return the_integer_ring(self.__pari__().binomial(mm)) else: raise ValueError("algorithm must be one of: 'pari', 'mpir'") diff --git a/src/sage/rings/multi_power_series_ring_element.py b/src/sage/rings/multi_power_series_ring_element.py index 9ae805e1da3..a3238a8d982 100644 --- a/src/sage/rings/multi_power_series_ring_element.py +++ b/src/sage/rings/multi_power_series_ring_element.py @@ -1737,7 +1737,7 @@ def egf(self): """ raise NotImplementedError("egf") - def _pari_(self): + def __pari__(self): """ Method from univariate power series not yet implemented @@ -1745,12 +1745,12 @@ def _pari_(self): sage: T. = PowerSeriesRing(ZZ,2) sage: f = a + b + a*b + T.O(5) - sage: f._pari_() + sage: f.__pari__() Traceback (most recent call last): ... - NotImplementedError: _pari_ + NotImplementedError: __pari__ """ - raise NotImplementedError("_pari_") + raise NotImplementedError("__pari__") diff --git a/src/sage/rings/number_field/galois_group.py b/src/sage/rings/number_field/galois_group.py index e39edce438e..92bb7f4516d 100644 --- a/src/sage/rings/number_field/galois_group.py +++ b/src/sage/rings/number_field/galois_group.py @@ -185,7 +185,7 @@ def __init__(self, number_field, names=None): else: self._galois_closure, self._gc_map = (number_field, number_field.hom(number_field.gen(), number_field)) - self._pari_gc = self._galois_closure._pari_() + self._pari_gc = self._galois_closure.__pari__() g = self._pari_gc.galoisinit() self._pari_data = g diff --git a/src/sage/rings/number_field/maps.py b/src/sage/rings/number_field/maps.py index cc79c546b2d..0e8fc58cdf7 100644 --- a/src/sage/rings/number_field/maps.py +++ b/src/sage/rings/number_field/maps.py @@ -285,7 +285,7 @@ def _call_(self, v): # Convert v to a PARI polynomial in x with coefficients that # are polynomials in y. _, to_B = B.structure() - h = pari([to_B(a)._pari_('y') for a in v]).Polrev() + h = pari([to_B(a).__pari__('y') for a in v]).Polrev() # Rewrite the polynomial in terms of an absolute generator for # the relative number field. g = K._pari_rnfeq()._eltreltoabs(h) diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index 716e74753cf..de690a76dc7 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -3406,7 +3406,7 @@ def pari_polynomial(self, name='x'): sage: k. = NumberField(y^2 - 3/2*y + 5/3) sage: k.pari_polynomial() x^2 - x + 40 - sage: k.polynomial()._pari_() + sage: k.polynomial().__pari__() x^2 - 3/2*x + 5/3 sage: k.pari_polynomial('a') a^2 - a + 40 @@ -3535,14 +3535,14 @@ def pari_zk(self): """ return self.pari_nf().nf_get_zk() - def _pari_(self): + def __pari__(self): """ Return the PARI number field corresponding to this field. EXAMPLES:: sage: k = NumberField(x^2 + x + 1, 'a') - sage: k._pari_() + sage: k.__pari__() [y^2 + y + 1, [0, 1], -3, 1, ... [1, y], [1, 0; 0, 1], [1, 0, 0, -1; 0, 1, 1, -1]] sage: pari(k) [y^2 + y + 1, [0, 1], -3, 1, ...[1, y], [1, 0; 0, 1], [1, 0, 0, -1; 0, 1, 1, -1]] @@ -4424,8 +4424,8 @@ def composite_fields(self, other, names=None, both_maps=False, preserve_embeddin f = self.absolute_polynomial() g = other.absolute_polynomial() R = f.parent() - f = f._pari_(); f /= f.content() - g = g._pari_(); g /= g.content() + f = f.__pari__(); f /= f.content() + g = g.__pari__(); g /= g.content() m = self.degree() n = other.absolute_degree() diff --git a/src/sage/rings/number_field/number_field_element.pyx b/src/sage/rings/number_field/number_field_element.pyx index 46f9736be7d..49556385b4c 100644 --- a/src/sage/rings/number_field/number_field_element.pyx +++ b/src/sage/rings/number_field/number_field_element.pyx @@ -588,7 +588,7 @@ cdef class NumberFieldElement(FieldElement): f = f(alpha).lift() return f.change_variable_name(name) - def _pari_(self, name='y'): + def __pari__(self, name='y'): r""" Return PARI representation of self. @@ -603,18 +603,18 @@ cdef class NumberFieldElement(FieldElement): EXAMPLES:: sage: K. = NumberField(x^3 + 2) - sage: K(1)._pari_() + sage: K(1).__pari__() Mod(1, y^3 + 2) - sage: (a + 2)._pari_() + sage: (a + 2).__pari__() Mod(y + 2, y^3 + 2) sage: L. = K.extension(x^2 + 2) - sage: (b + a)._pari_() + sage: (b + a).__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') Mod(j, j^2 + 1) sage: pari(j) Mod(y, y^2 + 1) @@ -633,14 +633,14 @@ cdef class NumberFieldElement(FieldElement): sage: R. = PolynomialRing(QQ) sage: K. = NumberField(theta^2 + 1) - sage: theta._pari_('theta') + sage: theta.__pari__('theta') Traceback (most recent call last): ... PariError: theta already exists with incompatible valence - sage: theta._pari_() + sage: theta.__pari__() Mod(y, y^2 + 1) sage: k. = QuadraticField(-1) - sage: I._pari_('I') + sage: I.__pari__('I') Traceback (most recent call last): ... PariError: I already exists with incompatible valence @@ -649,9 +649,9 @@ cdef class NumberFieldElement(FieldElement): sage: pari(I) Mod(y, y^2 + 1) - sage: I._pari_('i') + sage: I.__pari__('i') Mod(i, i^2 + 1) - sage: I._pari_('II') + sage: I.__pari__('II') Mod(II, II^2 + 1) Examples with relative number fields, which always yield an @@ -665,7 +665,7 @@ cdef class NumberFieldElement(FieldElement): 7 sage: pari(j)^2 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') Mod(7, x^6 - 21*x^4 + 4*x^3 + 147*x^2 + 84*x - 339) A tower of three number fields:: @@ -674,11 +674,11 @@ cdef class NumberFieldElement(FieldElement): 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__() Mod(y, y^4 + 2) - sage: M(b)._pari_('c') + sage: M(b).__pari__('c') Mod(-c^3, c^12 + 2) - sage: c._pari_('c') + sage: c.__pari__('c') Mod(c, c^12 + 2) """ f = self._pari_polynomial(name) @@ -723,7 +723,7 @@ cdef class NumberFieldElement(FieldElement): sage: pari(b) Mod(-8/27*y^3 + 2/3*y^2 - 1/2*y + 1/8, y^5 - y - 1) """ - return repr(self._pari_(name=name)) + return repr(self.__pari__(name=name)) def __getitem__(self, n): """ @@ -1696,7 +1696,7 @@ cdef class NumberFieldElement(FieldElement): raise ValueError("L (=%s) must be a relative number field with base field K (=%s) in rnfisnorm" % (L, K)) rnf_data = K.pari_rnfnorm_data(L, proof=proof) - x, q = self._pari_().rnfisnorm(rnf_data) + x, q = self.__pari__().rnfisnorm(rnf_data) return L(x, check=False), K(q, check=False) def _mpfr_(self, R): @@ -2463,7 +2463,7 @@ cdef class NumberFieldElement(FieldElement): sig_off() except NTLError: # In case NTL fails we fall back to PARI. - x = self._parent(~self._pari_()) + x = self._parent(~self.__pari__()) return x def _integer_(self, Z=None): @@ -3082,7 +3082,7 @@ cdef class NumberFieldElement(FieldElement): 3*z^3 + 4*z^2 + 2 """ if K is None: - trace = self._pari_('x').trace() + trace = self.__pari__('x').trace() return QQ(trace) if self._parent.is_field() else ZZ(trace) return self.matrix(K).trace() @@ -3158,7 +3158,7 @@ cdef class NumberFieldElement(FieldElement): 3*z^3 + 4*z^2 + 2 """ if K is None or (K in Fields and K.absolute_degree() == 1): - norm = self._pari_('x').norm() + norm = self.__pari__('x').norm() return QQ(norm) if self._parent in Fields else ZZ(norm) return self.matrix(K).determinant() @@ -4253,7 +4253,7 @@ cdef class NumberFieldElement_absolute(NumberFieldElement): algorithm = 'sage' R = self._parent.base_ring()[var] if algorithm == 'pari': - return R(self._pari_('x').charpoly()) + return R(self.__pari__('x').charpoly()) if algorithm == 'sage': return R(self.matrix().charpoly()) @@ -4601,7 +4601,7 @@ cdef class NumberFieldElement_relative(NumberFieldElement): algorithm = 'sage' R = QQ[var] if algorithm == 'pari': - return R(self._pari_().charpoly()) + return R(self.__pari__().charpoly()) if algorithm == 'sage': return R(self.matrix(QQ).charpoly()) diff --git a/src/sage/rings/number_field/number_field_ideal.py b/src/sage/rings/number_field/number_field_ideal.py index c532042452c..806aedb43fa 100644 --- a/src/sage/rings/number_field/number_field_ideal.py +++ b/src/sage/rings/number_field/number_field_ideal.py @@ -282,7 +282,7 @@ def _mul_(self, other): K=self.ring() K_pari=K.pari_nf() - return K.ideal(K_pari.idealmul(self._pari_(), other._pari_())) + return K.ideal(K_pari.idealmul(self.__pari__(), other.__pari__())) def coordinates(self, x): r""" @@ -519,7 +519,7 @@ def _gens_repr(self): else: return (two_gens[0],) - def _pari_(self): + def __pari__(self): """ Returns PARI Hermite Normal Form representations of this ideal. @@ -529,7 +529,7 @@ def _pari_(self): sage: K. = NumberField(x^2 + 23) sage: I = K.class_group().0.ideal(); I Fractional ideal (2, 1/2*w - 1/2) - sage: I._pari_() + sage: I.__pari__() [2, 0; 0, 1] """ return self.pari_hnf() @@ -545,7 +545,7 @@ def _pari_init_(self): sage: I._pari_init_() '[2, 0; 0, 1]' """ - return str(self._pari_()) + return str(self.__pari__()) def pari_hnf(self): """ @@ -2468,7 +2468,7 @@ def small_residue(self, f): if not self.is_integral(): raise ValueError("The ideal must be integral") k = self.number_field() - return k(k.pari_nf().nfeltreduce(f._pari_(), self.pari_hnf())) + return k(k.pari_nf().nfeltreduce(f.__pari__(), self.pari_hnf())) def _pari_bid_(self, flag=1): """ @@ -2658,7 +2658,7 @@ def ideallog(self, x, gens=None, check=True): #Now it is important to call _pari_bid_() with flag=2 to make sure #we fix a basis, since the log would be different for a different #choice of basis. - L = [ZZ(_) for _ in k.pari_nf().ideallog(x._pari_(), self._pari_bid_(2))] + L = [ZZ(_) for _ in k.pari_nf().ideallog(x.__pari__(), self._pari_bid_(2))] if gens is None: return L diff --git a/src/sage/rings/number_field/number_field_rel.py b/src/sage/rings/number_field/number_field_rel.py index 57986ce3bb0..da30bbc112e 100644 --- a/src/sage/rings/number_field/number_field_rel.py +++ b/src/sage/rings/number_field/number_field_rel.py @@ -1075,11 +1075,11 @@ def _element_constructor_(self, x, check=True): sage: K. = NumberField(y^2 + y + 1) sage: x = polygen(K) sage: L. = NumberField(x^4 + a*x + 2) - sage: e = a._pari_(); e + sage: e = a.__pari__(); e Mod(y, y^2 + y + 1) sage: L(e) # Conversion from PARI base field element a - sage: e = (a*b)._pari_('x'); e + sage: e = (a*b).__pari__('x'); e Mod(-x^4 - 2, x^8 - x^5 + 4*x^4 + x^2 - 2*x + 4) sage: L(e) # Conversion from PARI absolute number field element a*b diff --git a/src/sage/rings/number_field/splitting_field.py b/src/sage/rings/number_field/splitting_field.py index fbf8b6e8d23..c26d3e99096 100644 --- a/src/sage/rings/number_field/splitting_field.py +++ b/src/sage/rings/number_field/splitting_field.py @@ -354,7 +354,7 @@ def splitting_field(poly, name, map=False, degree_multiple=None, abort_degree=No # Fgen = the generator of F as element of Q[y]/Kpol # (only needed if map=True) if map: - Fgen = F.gen()._pari_() + Fgen = F.gen().__pari__() verbose("Starting field: %s"%Kpol) # L and Lred are lists of SplittingData. diff --git a/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx index ea3f44e7636..b624f3c31a8 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx @@ -310,7 +310,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): raise TypeError("Cannot coerce between p-adic parents with different primes.") if isinstance(x, pari_gen) or isinstance(x, GpElement): if isinstance(x, GpElement): - x = x._pari_() + x = x.__pari__() if x.type() == "t_PADIC": if x.variable() != self.prime_pow.prime: raise TypeError("Cannot coerce a pari p-adic with the wrong prime.") 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 f967b4cfedb..2371668b86b 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx @@ -331,7 +331,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): self._set_from_mpq_both(xlift.value, aprec, rprec) return if isinstance(x, GpElement): - x = x._pari_() + x = x.__pari__() if isinstance(x, pari_gen): if x.type() == "t_PADIC": if x.variable() != self.prime_pow.prime: 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 89f6bd3ad7c..457dce8ce60 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx @@ -209,7 +209,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): if parent.prime() != x.parent().prime(): raise TypeError("Cannot coerce between p-adic parents with different primes.") if isinstance(x, GpElement): - x = x._pari_() + x = x.__pari__() if isinstance(x, pari_gen): if x.type() == "t_PADIC": if x.variable() != self.prime_pow.prime: diff --git a/src/sage/rings/padics/padic_capped_absolute_element.pyx b/src/sage/rings/padics/padic_capped_absolute_element.pyx index aee32342d8e..a3b68f8126e 100644 --- a/src/sage/rings/padics/padic_capped_absolute_element.pyx +++ b/src/sage/rings/padics/padic_capped_absolute_element.pyx @@ -105,7 +105,7 @@ cdef class pAdicCappedAbsoluteElement(CAElement): mpz_set(ans.value, self.value) return ans - def _pari_(self): + def __pari__(self): """ Conversion to pari. diff --git a/src/sage/rings/padics/padic_capped_relative_element.pyx b/src/sage/rings/padics/padic_capped_relative_element.pyx index 2d028e8fb94..60e8c5d0391 100644 --- a/src/sage/rings/padics/padic_capped_relative_element.pyx +++ b/src/sage/rings/padics/padic_capped_relative_element.pyx @@ -189,7 +189,7 @@ cdef class pAdicCappedRelativeElement(CRElement): mpz_set(mpq_denref(ansr.value), self.prime_pow.pow_mpz_t_tmp(-self.ordp)) return ansr - def _pari_(self): + def __pari__(self): """ Converts this element to an equivalent pari element. diff --git a/src/sage/rings/padics/padic_fixed_mod_element.pyx b/src/sage/rings/padics/padic_fixed_mod_element.pyx index fac0d11f690..f0df5623903 100644 --- a/src/sage/rings/padics/padic_fixed_mod_element.pyx +++ b/src/sage/rings/padics/padic_fixed_mod_element.pyx @@ -171,7 +171,7 @@ cdef class pAdicFixedModElement(FMElement): mpz_set(ans.value, self.value) return ans - def _pari_(self): + def __pari__(self): """ Conversion to PARI. @@ -204,7 +204,7 @@ cdef class pAdicFixedModElement(FMElement): This checks that :trac:`15653` is fixed:: sage: x = polygen(ZpFM(3,10)) - sage: (x^3 + x + 1)._pari_().poldisc() + sage: (x^3 + x + 1).__pari__().poldisc() 2 + 3 + 2*3^2 + 3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + O(3^10) """ cdef long val diff --git a/src/sage/rings/padics/padic_generic_element.pyx b/src/sage/rings/padics/padic_generic_element.pyx index 50bfb515cf5..bad2c8dc813 100644 --- a/src/sage/rings/padics/padic_generic_element.pyx +++ b/src/sage/rings/padics/padic_generic_element.pyx @@ -192,7 +192,7 @@ cdef class pAdicGenericElement(LocalGenericElement): cdef bint _set_prec_both(self, long absprec, long relprec) except -1: return 0 - #def _pari_(self): + #def __pari__(self): # """ # Returns a pari version of this element. @@ -834,7 +834,7 @@ cdef class pAdicGenericElement(LocalGenericElement): 'on elements of Zp') parent = self.parent() if algorithm == 'pari': - return parent(self._pari_().gamma()) + return parent(self.__pari__().gamma()) elif algorithm == 'sage': from sage.misc.all import prod p = parent.prime() @@ -2413,7 +2413,7 @@ cdef class pAdicGenericElement(LocalGenericElement): from sage.libs.pari.all import PariError try: # use pari - ans = self.parent()(self._pari_().sqrt()) + ans = self.parent()(self.__pari__().sqrt()) if all: return [ans, -ans] else: diff --git a/src/sage/rings/polynomial/padics/polynomial_padic.py b/src/sage/rings/polynomial/padics/polynomial_padic.py index 75ddf5ba848..bcce29be56c 100644 --- a/src/sage/rings/polynomial/padics/polynomial_padic.py +++ b/src/sage/rings/polynomial/padics/polynomial_padic.py @@ -225,7 +225,7 @@ def factor(self): if self_normal.discriminant().valuation() >= absprec: raise PrecisionError( "p-adic factorization not well-defined since the discriminant is zero up to the requestion p-adic precision") - G = self_normal._pari_().factorpadic(self.base_ring().prime(), absprec) + G = self_normal.__pari__().factorpadic(self.base_ring().prime(), absprec) return _pari_padic_factorization_to_sage(G, self.parent(), self.leading_coefficient()) def _pari_padic_factorization_to_sage(G, R, leading_coeff): 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 255f2d8dc19..c076142dc38 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 @@ -727,7 +727,7 @@ def _unsafe_mutate(self, n, value): zero = self._base_ring()(0) self._list.extend([zero] * (n - len(self._list)) + [value]) - def _pari_(self, variable=None): + def __pari__(self, variable=None): """ Return ``self`` as a Pari object. """ diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 40824294432..92ef74e3596 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -4054,7 +4054,7 @@ cdef class Polynomial(CommutativeAlgebraElement): return Factorization(v, from_M(F.unit())) elif is_FiniteField(R): - v = [x._pari_("a") for x in self.list()] + v = [x.__pari__("a") for x in self.list()] f = pari(v).Polrev() G = list(f.factor()) @@ -5615,7 +5615,7 @@ cdef class Polynomial(CommutativeAlgebraElement): ALGORITHM: Uses PARI if `lengths` is `False`. """ if not lengths: - f = self._pari_() + f = self.__pari__() v = list(f.newtonpoly(p)) return [sage.rings.rational.Rational(x) for x in v] @@ -5731,7 +5731,7 @@ cdef class Polynomial(CommutativeAlgebraElement): ##################################################################### # Conversions to other systems ##################################################################### - def _pari_(self): + def __pari__(self): r""" Return polynomial as a PARI object. @@ -5819,7 +5819,7 @@ cdef class Polynomial(CommutativeAlgebraElement): def _pari_or_constant(self, name=None): r""" - Convert ``self`` to PARI. This behaves identical to :meth:`_pari_` + Convert ``self`` to PARI. This behaves identical to :meth:`__pari__` or :meth:`_pari_with_name` except for constant polynomials: then the constant is returned instead of a constant polynomial. @@ -5842,13 +5842,13 @@ cdef class Polynomial(CommutativeAlgebraElement): 7 sage: pol._pari_or_constant().type() 't_INT' - sage: pol._pari_().type() + sage: pol.__pari__().type() 't_POL' sage: PolynomialRing(IntegerModRing(101), 't')()._pari_or_constant() Mod(0, 101) """ if self.is_constant(): - return self[0]._pari_() + return self[0].__pari__() if name is None: name = self.parent().variable_name() return self._pari_with_name(name) @@ -5868,11 +5868,11 @@ cdef class Polynomial(CommutativeAlgebraElement): sage: (2*a^2 + a)._pari_with_name('y') 2*y^2 + y """ - vals = [x._pari_() for x in self.list()] + vals = [x.__pari__() for x in self.list()] return pari(vals).Polrev(name) def _pari_init_(self): - return repr(self._pari_()) + return repr(self.__pari__()) def _magma_init_(self, magma): """ @@ -6081,7 +6081,7 @@ cdef class Polynomial(CommutativeAlgebraElement): """ variable = self.variable_name() try: - res = self._pari_().polresultant(other._pari_(), variable) + res = self.__pari__().polresultant(other.__pari__(), variable) return self.parent().base_ring()(res) except (TypeError, ValueError, PariError, NotImplementedError): return self.sylvester_matrix(other).det() @@ -7172,7 +7172,7 @@ cdef class Polynomial(CommutativeAlgebraElement): if algorithm == 'pari': if not input_arbprec: self = self.change_ring(CC if input_complex else RR) - ext_rts = self._pari_().polroots(precision=L.prec()) + ext_rts = self.__pari__().polroots(precision=L.prec()) if output_complex: rts = sort_complex_numbers_for_display([L(root) for root in ext_rts]) @@ -8384,7 +8384,7 @@ cdef class Polynomial(CommutativeAlgebraElement): return f.is_cyclotomic(certificate=certificate, algorithm=algorithm) if algorithm == "pari": - ans = self._pari_().poliscyclo() + ans = self.__pari__().poliscyclo() return Integer(ans) if certificate else bool(ans) elif algorithm != "sage": @@ -8473,7 +8473,7 @@ cdef class Polynomial(CommutativeAlgebraElement): return False return f.is_cyclotomic_product() - return bool(self._pari_().poliscycloprod()) + return bool(self.__pari__().poliscycloprod()) def cyclotomic_part(self): """ diff --git a/src/sage/rings/polynomial/polynomial_element_generic.py b/src/sage/rings/polynomial/polynomial_element_generic.py index 8370a4ca2ac..060b0dae525 100644 --- a/src/sage/rings/polynomial/polynomial_element_generic.py +++ b/src/sage/rings/polynomial/polynomial_element_generic.py @@ -500,7 +500,7 @@ def list(self, copy=True): v[n] = x return v - #def _pari_(self, variable=None): + #def __pari__(self, variable=None): # if variable is None: # return self.__pari # else: diff --git a/src/sage/rings/polynomial/polynomial_gf2x.pyx b/src/sage/rings/polynomial/polynomial_gf2x.pyx index c802beea58b..b1ee6b3d5b2 100644 --- a/src/sage/rings/polynomial/polynomial_gf2x.pyx +++ b/src/sage/rings/polynomial/polynomial_gf2x.pyx @@ -83,7 +83,7 @@ cdef class Polynomial_GF2X(Polynomial_template): cdef long c = GF2_conv_to_long(GF2X_coeff(self.x, i)) return self._parent._base(c) - def _pari_(self, variable=None): + def __pari__(self, variable=None): """ EXAMPLE:: diff --git a/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx b/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx index 81183136a8b..d9510d0401c 100644 --- a/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx @@ -1399,7 +1399,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): # Alias for discriminant disc = discriminant - def _pari_(self, variable=None): + def __pari__(self, variable=None): """ EXAMPLES:: @@ -1407,7 +1407,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): sage: f = t^3 + 3*t - 17 sage: pari(f) t^3 + 3*t - 17 - sage: f._pari_(variable='y') + sage: f.__pari__(variable='y') y^3 + 3*y - 17 """ if variable is None: @@ -1610,7 +1610,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): raise ValueError("p must be prime") if all([c%p==0 for c in self.coefficients()]): raise ValueError("factorization of 0 not defined") - f = self._pari_() + f = self.__pari__() G = f.factormod(p) k = FiniteField(p) R = k[self.parent().variable_name()] diff --git a/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx b/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx index fc22438f9e4..4816af16035 100644 --- a/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx +++ b/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx @@ -842,7 +842,7 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): return x - def _pari_(self, variable=None): + def __pari__(self, variable=None): """ EXAMPLES:: @@ -1024,7 +1024,7 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): raise ValueError("p must be prime") if all([c%p==0 for c in self.coefficients()]): raise ValueError("factorization of 0 not defined") - f = self._pari_() + f = self.__pari__() G = f.factormod(p) k = FiniteField(p) R = k[self.parent().variable_name()] diff --git a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx index d110fbc1c96..10d18e0280a 100644 --- a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx +++ b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx @@ -160,7 +160,7 @@ cdef class Polynomial_dense_mod_n(Polynomial): def int_list(self): return eval(str(self.__poly).replace(' ',',')) - def _pari_(self, variable=None): + def __pari__(self, variable=None): """ EXAMPLES:: diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring_element.py b/src/sage/rings/polynomial/polynomial_quotient_ring_element.py index 896279c572a..cb99aa1184d 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring_element.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring_element.py @@ -195,7 +195,7 @@ def _latex_(self): """ return self._polynomial._latex_(self.parent().variable_name()) - def _pari_(self): + def __pari__(self): """ Pari representation of this quotient element. @@ -207,7 +207,7 @@ def _pari_(self): sage: pari(xb)^10 Mod(0, x^10) """ - return self._polynomial._pari_().Mod(self.parent().modulus()._pari_()) + return self._polynomial.__pari__().Mod(self.parent().modulus().__pari__()) ################################################## # Arithmetic diff --git a/src/sage/rings/power_series_pari.pyx b/src/sage/rings/power_series_pari.pyx index ed279640bf7..6676e5b27e9 100644 --- a/src/sage/rings/power_series_pari.pyx +++ b/src/sage/rings/power_series_pari.pyx @@ -152,45 +152,45 @@ cdef class PowerSeries_pari(PowerSeries): if f_parent is parent: if prec is infinity: prec = (f)._prec - g = f._pari_() + g = f.__pari__() elif R.has_coerce_map_from(f_parent): - g = R.coerce(f)._pari_() + g = R.coerce(f).__pari__() else: if prec is infinity: prec = f.prec() - g = f.polynomial().change_ring(R)._pari_() + g = f.polynomial().change_ring(R).__pari__() elif isinstance(f, Polynomial): f_parent = (f)._parent if f_parent is P: - g = f._pari_() + g = f.__pari__() elif R.has_coerce_map_from(f_parent): - g = R.coerce(f)._pari_() + g = R.coerce(f).__pari__() else: - g = P.coerce(f)._pari_() + g = P.coerce(f).__pari__() elif isinstance(f, pari_gen): g = f t = typ(g.g) if t == t_POL: - g = P(g)._pari_() + g = P(g).__pari__() elif t == t_SER and varn(g.g) == get_var(v): if valp(g.g) < 0: raise ValueError('series has negative valuation') if prec is infinity: prec = lg(g.g) - 2 + valp(g.g) - g = P(g.Pol(v))._pari_() + g = P(g.Pol(v)).__pari__() elif t == t_RFRAC: if prec is infinity: prec = parent.default_prec() - g = P.fraction_field()(g)._pari_() + g = P.fraction_field()(g).__pari__() g = g.Ser(v, prec - g.valuation(v)) elif t == t_VEC: - g = P(g.Polrev(v))._pari_() + g = P(g.Polrev(v)).__pari__() else: - g = R(g)._pari_() + g = R(g).__pari__() elif isinstance(f, (list, tuple)): g = pari([R.coerce(x) for x in f]).Polrev(v) else: - g = R.coerce(f)._pari_() + g = R.coerce(f).__pari__() if prec is infinity: self.g = g @@ -231,14 +231,14 @@ cdef class PowerSeries_pari(PowerSeries): """ return PowerSeries_pari, (self._parent, self.g, self._prec, False) - def _pari_(self): + def __pari__(self): """ Convert ``self`` to a PARI object. TESTS:: sage: R. = PowerSeriesRing(GF(7), implementation='pari') - sage: (3 - t^3 + O(t^5))._pari_() + sage: (3 - t^3 + O(t^5)).__pari__() Mod(3, 7) + Mod(6, 7)*t^3 + O(t^5) """ diff --git a/src/sage/rings/power_series_poly.pyx b/src/sage/rings/power_series_poly.pyx index 6b6c08bb3ee..35bd70d849a 100644 --- a/src/sage/rings/power_series_poly.pyx +++ b/src/sage/rings/power_series_poly.pyx @@ -1020,7 +1020,7 @@ cdef class PowerSeries_poly(PowerSeries): # first, try reversion with pari; this is faster than Lagrange inversion try: - f2 = f._pari_() + f2 = f.__pari__() g = f2.serreverse() return PowerSeries_poly(f.parent(), g.Vec(-out_prec), out_prec) except (TypeError,ValueError,AttributeError,PariError): diff --git a/src/sage/rings/power_series_ring.py b/src/sage/rings/power_series_ring.py index fafed02b31a..a6e5608a00b 100644 --- a/src/sage/rings/power_series_ring.py +++ b/src/sage/rings/power_series_ring.py @@ -560,7 +560,7 @@ def __init__(self, base_ring, name=None, default_prec=None, sparse=False, _CommutativeRings)) Nonexact.__init__(self, default_prec) if self.Element is PowerSeries_pari: - self.__generator = self.element_class(self, R.gen()._pari_()) + self.__generator = self.element_class(self, R.gen().__pari__()) else: self.__generator = self.element_class(self, R.gen(), is_gen=True) diff --git a/src/sage/rings/power_series_ring_element.pyx b/src/sage/rings/power_series_ring_element.pyx index 8fb340fc8cb..6e8bbd88fdb 100644 --- a/src/sage/rings/power_series_ring_element.pyx +++ b/src/sage/rings/power_series_ring_element.pyx @@ -2057,13 +2057,13 @@ cdef class PowerSeries(AlgebraElement): ogf = deprecated_function_alias(15705, egf_to_ogf) egf = deprecated_function_alias(15705, ogf_to_egf) - def _pari_(self): + def __pari__(self): """ Return a PARI representation of this series. 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_`` + ``sage.rings.polynomial.polynomial_element.Polynomial.__pari__`` EXAMPLES:: @@ -2087,7 +2087,7 @@ cdef class PowerSeries(AlgebraElement): O(x^0) """ n = self.prec() - s = self.truncate()._pari_() # PARI polynomial + s = self.truncate().__pari__() # PARI polynomial if n is not infinity: v = s.variable() s = s.Ser(v, n - s.valuation(v) if s else n) diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 4d0aa78cdd1..c12a5720c05 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -1711,7 +1711,7 @@ def do_polred(poly): sage: do_polred(x^4 - 4294967296*x^2 + 54265257667816538374400) (1/4*x, 4*x, x^4 - 268435456*x^2 + 211973662764908353025) """ - new_poly, elt_back = poly._pari_().polredbest(flag=1) + new_poly, elt_back = poly.__pari__().polredbest(flag=1) parent = poly.parent() elt_fwd = elt_back.modreverse() diff --git a/src/sage/rings/quotient_ring_element.py b/src/sage/rings/quotient_ring_element.py index 75d932d0653..01f91c05081 100644 --- a/src/sage/rings/quotient_ring_element.py +++ b/src/sage/rings/quotient_ring_element.py @@ -215,7 +215,7 @@ def _repr_(self): with localvars(R, P.variable_names(), normalize=False): return str(self.__rep) - def _pari_(self): + def __pari__(self): """ The Pari representation of this quotient element. @@ -244,7 +244,7 @@ def _pari_(self): gens = self.parent().defining_ideal().gens() if len(gens) != 1: raise ValueError("Pari does not support quotients by non-principal ideals") - return self.__rep._pari_().Mod(gens[0]._pari_()) + return self.__rep.__pari__().Mod(gens[0].__pari__()) def _add_(self, right): """ diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index 49c890312a9..75293440b9a 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -3621,14 +3621,14 @@ cdef class Rational(sage.structure.element.FieldElement): # Support for interfaces ################################################## - def _pari_(self): + def __pari__(self): """ Returns the PARI version of this rational number. EXAMPLES:: sage: n = 9390823/17 - sage: m = n._pari_(); m + sage: m = n.__pari__(); m 9390823/17 sage: type(m) diff --git a/src/sage/rings/real_double.pyx b/src/sage/rings/real_double.pyx index 69156fb00c1..a541858cb94 100644 --- a/src/sage/rings/real_double.pyx +++ b/src/sage/rings/real_double.pyx @@ -1573,13 +1573,13 @@ cdef class RealDoubleElement(FieldElement): """ return CDF(self._value) - def _pari_(self): + def __pari__(self): """ Return a PARI representation of ``self``. EXAMPLES:: - sage: RDF(1.5)._pari_() + sage: RDF(1.5).__pari__() 1.50000000000000 """ return new_gen_from_double(self._value) diff --git a/src/sage/rings/real_mpfr.pyx b/src/sage/rings/real_mpfr.pyx index 15dff6793f2..583bca861f3 100644 --- a/src/sage/rings/real_mpfr.pyx +++ b/src/sage/rings/real_mpfr.pyx @@ -1475,7 +1475,7 @@ cdef class RealNumber(sage.structure.element.RingElement): True sage: for i in range(100, 200): ....: assert(sqrt(pari(i)) == pari(sqrt(pari(i)).sage())) - sage: (-3.1415)._pari_().sage() + sage: (-3.1415).__pari__().sage() -3.14150000000000000 """ cdef int sgn @@ -3045,44 +3045,44 @@ cdef class RealNumber(sage.structure.element.RingElement): _fricas_ = _axiom_ - def _pari_(self): + def __pari__(self): """ Return ``self`` as a Pari floating-point number. EXAMPLES:: - sage: RR(2.0)._pari_() + sage: RR(2.0).__pari__() 2.00000000000000 The current Pari precision affects the printing of this number, but Pari does maintain the same 250-bit number on both 32-bit and 64-bit platforms:: - sage: RealField(250).pi()._pari_() + sage: RealField(250).pi().__pari__() 3.14159265358979 - sage: RR(0.0)._pari_() + sage: RR(0.0).__pari__() 0.E-19 - sage: RR(-1.234567)._pari_() + sage: RR(-1.234567).__pari__() -1.23456700000000 - sage: RR(2.0).sqrt()._pari_() + sage: RR(2.0).sqrt().__pari__() 1.41421356237310 - sage: RR(2.0).sqrt()._pari_().sage() + sage: RR(2.0).sqrt().__pari__().sage() 1.41421356237309515 - sage: RR(2.0).sqrt()._pari_().sage().prec() + sage: RR(2.0).sqrt().__pari__().sage().prec() 64 - sage: RealField(70)(pi)._pari_().sage().prec() + sage: RealField(70)(pi).__pari__().sage().prec() 96 # 32-bit 128 # 64-bit sage: for i in range(100, 200): - ....: assert(RR(i).sqrt() == RR(i).sqrt()._pari_().sage()) + ....: assert(RR(i).sqrt() == RR(i).sqrt().__pari__().sage()) TESTS: Check that we create real zeros without mantissa:: - sage: RDF(0)._pari_().sizeword() + sage: RDF(0).__pari__().sizeword() 2 - sage: RealField(100)(0.0)._pari_().sizeword() + sage: RealField(100)(0.0).__pari__().sizeword() 2 Check that the largest and smallest exponents representable by diff --git a/src/sage/schemes/elliptic_curves/ell_finite_field.py b/src/sage/schemes/elliptic_curves/ell_finite_field.py index 12bc266dc94..20aecfa1394 100644 --- a/src/sage/schemes/elliptic_curves/ell_finite_field.py +++ b/src/sage/schemes/elliptic_curves/ell_finite_field.py @@ -1082,7 +1082,7 @@ def cardinality_pari(self): k = self.base_ring() p = k.characteristic() if k.degree()==1: - return ZZ(p + 1 - int(self._pari_().ellap(p))) + return ZZ(p + 1 - int(self.__pari__().ellap(p))) else: raise ValueError("cardinality_pari() only works over prime fields.") diff --git a/src/sage/schemes/elliptic_curves/ell_generic.py b/src/sage/schemes/elliptic_curves/ell_generic.py index 90bdf12b7da..6ef4727e34f 100644 --- a/src/sage/schemes/elliptic_curves/ell_generic.py +++ b/src/sage/schemes/elliptic_curves/ell_generic.py @@ -2929,7 +2929,7 @@ def pari_curve(self): # This method is defined so that pari(E) returns exactly the same # as E.pari_curve(). This works even for classes that inherit from # EllipticCurve_generic, such as EllipticCurve_rational_field. - def _pari_(self): + def __pari__(self): """ Return the PARI curve corresponding to this elliptic curve with the default precision of 64 bits. @@ -2942,7 +2942,7 @@ def _pari_(self): Over a finite field:: - sage: EllipticCurve(GF(2), [0,0,1,1,1])._pari_() + sage: EllipticCurve(GF(2), [0,0,1,1,1]).__pari__() [0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, Vecsmall([4]), [1, [[Vecsmall([0, 1]), Vecsmall([0, 1]), Vecsmall([0, 1])], Vecsmall([0, 1]), [Vecsmall([0, 1]), Vecsmall([0]), Vecsmall([0]), Vecsmall([0])]]], [0, 0, 0, 0]] """ return self.pari_curve() diff --git a/src/sage/schemes/elliptic_curves/ell_number_field.py b/src/sage/schemes/elliptic_curves/ell_number_field.py index b2f33d21dd3..d5177128f20 100644 --- a/src/sage/schemes/elliptic_curves/ell_number_field.py +++ b/src/sage/schemes/elliptic_curves/ell_number_field.py @@ -890,7 +890,7 @@ def _reduce_model(self): r = ((-a2 + s*a1 +s*s)/3).round() t = ((-a3 - r*a1)/2).round('up') else: - pariK = K._pari_() + pariK = K.__pari__() s = K(pariK.nfeltdiveuc(-a1, 2)) r = K(pariK.nfeltdiveuc(-a2 + s*a1 + s*s, 3)) t = K(pariK.nfeltdiveuc(-a3 - r*a1, 2)) @@ -3335,7 +3335,7 @@ def lll_reduce(self, points, height_matrix=None, precision=None): r = len(points) if height_matrix is None: height_matrix = self.height_pairing_matrix(points, precision) - U = height_matrix._pari_().lllgram().sage() + U = height_matrix.__pari__().lllgram().sage() new_points = [sum([U[j, i]*points[j] for j in range(r)]) for i in range(r)] return new_points, U diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py index 494081b5469..e72f8a5f4d5 100644 --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -419,7 +419,7 @@ def __cmp__(self, other): return -1 return cmp(self._coords, other._coords) - def _pari_(self): + def __pari__(self): r""" Converts this point to PARI format. @@ -428,12 +428,12 @@ def _pari_(self): sage: E = EllipticCurve([0,0,0,3,0]) sage: O = E(0) sage: P = E.point([1,2]) - sage: O._pari_() + sage: O.__pari__() [0] - sage: P._pari_() + sage: P.__pari__() [1, 2] - The following implicitly calls O._pari_() and P._pari_():: + The following implicitly calls O.__pari__() and P.__pari__():: sage: pari(E).elladd(O,P) [1, 2] @@ -445,9 +445,9 @@ def _pari_(self): sage: E = EllipticCurve(GF(11), [0,0,0,3,0]) sage: O = E(0) sage: P = E.point([1,2]) - sage: O._pari_() + sage: O.__pari__() [0] - sage: P._pari_() + sage: P.__pari__() [Mod(1, 11), Mod(2, 11)] We no longer need to explicitly call ``pari(O)`` and ``pari(P)`` diff --git a/src/sage/schemes/elliptic_curves/ell_wp.py b/src/sage/schemes/elliptic_curves/ell_wp.py index 90bc21b2f21..e8f8bdecac8 100644 --- a/src/sage/schemes/elliptic_curves/ell_wp.py +++ b/src/sage/schemes/elliptic_curves/ell_wp.py @@ -177,7 +177,7 @@ def compute_wp_pari(E,prec): sage: compute_wp_pari(E, prec=30) z^-2 - 1/7*z^4 + 1/637*z^10 - 1/84721*z^16 + 3/38548055*z^22 - 4/8364927935*z^28 + O(z^30) """ - ep = E._pari_() + ep = E.__pari__() wpp = ep.ellwp(n=prec) k = E.base_ring() R = LaurentSeriesRing(k,'z') diff --git a/src/sage/schemes/elliptic_curves/gp_simon.py b/src/sage/schemes/elliptic_curves/gp_simon.py index 1231bc07033..c7b044e4ede 100644 --- a/src/sage/schemes/elliptic_curves/gp_simon.py +++ b/src/sage/schemes/elliptic_curves/gp_simon.py @@ -118,7 +118,7 @@ def simon_two_descent(E, verbose=0, lim1=None, lim3=None, limtriv=None, # The block below mimicks the defaults in Simon's scripts, and needs to be changed # when these are updated. if K is QQ: - cmd = 'ellrank(%s, %s);' % (list(E.ainvs()), [P._pari_() for P in known_points]) + cmd = 'ellrank(%s, %s);' % (list(E.ainvs()), [P.__pari__() for P in known_points]) if lim1 is None: lim1 = 5 if lim3 is None: @@ -126,7 +126,7 @@ def simon_two_descent(E, verbose=0, lim1=None, lim3=None, limtriv=None, if limtriv is None: limtriv = 3 else: - cmd = 'bnfellrank(K, %s, %s);' % (list(E.ainvs()), [P._pari_() for P in known_points]) + cmd = 'bnfellrank(K, %s, %s);' % (list(E.ainvs()), [P.__pari__() for P in known_points]) if lim1 is None: lim1 = 2 if lim3 is None: diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 4f705f8565b..562211c919c 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -1530,7 +1530,7 @@ def resultant(self, normalize=False): #however the coercion from a Pari object to a sage object breaks #in the case of QQbar, so we just pass it into the macaulay resultant try: - res = (f.lc() ** (d - g.degree()) * g.lc() ** (d - f.degree()) * f._pari_().polresultant(g, x)) + res = (f.lc() ** (d - g.degree()) * g.lc() ** (d - f.degree()) * f.__pari__().polresultant(g, x)) return(self.domain().base_ring()(res)) except (TypeError, PariError): pass diff --git a/src/sage/structure/factorization.py b/src/sage/structure/factorization.py index a965fdd367b..a9262984f15 100644 --- a/src/sage/structure/factorization.py +++ b/src/sage/structure/factorization.py @@ -899,7 +899,7 @@ def _latex_(self): return s @cached_method - def _pari_(self): + def __pari__(self): """ Return the PARI factorization matrix corresponding to ``self``. diff --git a/src/sage/structure/sage_object.pyx b/src/sage/structure/sage_object.pyx index 859f62bd32b..9fe86f7e1fc 100644 --- a/src/sage/structure/sage_object.pyx +++ b/src/sage/structure/sage_object.pyx @@ -900,7 +900,7 @@ cdef class SageObject: return self._interface_init_(I) # PARI (slightly different, since is via C library, hence instance is unique) - def _pari_(self): + def __pari__(self): if self._interface_is_cached_(): try: return self.__pari diff --git a/src/sage/tests/benchmark.py b/src/sage/tests/benchmark.py index 708e2454225..edfd1d4aa97 100644 --- a/src/sage/tests/benchmark.py +++ b/src/sage/tests/benchmark.py @@ -1658,8 +1658,8 @@ def pari(self): True """ - e = self.e._pari_() - f = self.f._pari_() + e = self.e.__pari__() + f = self.f.__pari__() t = cputime() v = [e*f for _ in range(self.__times)] return cputime(t) @@ -1782,8 +1782,8 @@ def pari(self): True """ - e = self.e._pari_() - f = self.f._pari_() + e = self.e.__pari__() + f = self.f.__pari__() t = cputime() v = [e+f for _ in range(self.__times)] return cputime(t) From dc949f3f9a6bbd9bede86a39a9eb46033d629658 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Tue, 28 Feb 2017 12:10:56 +0100 Subject: [PATCH 071/185] Remove unused code --- src/sage/rings/padics/padic_generic_element.pyx | 12 ------------ .../rings/polynomial/polynomial_element_generic.py | 6 ------ 2 files changed, 18 deletions(-) diff --git a/src/sage/rings/padics/padic_generic_element.pyx b/src/sage/rings/padics/padic_generic_element.pyx index bad2c8dc813..3a452927b66 100644 --- a/src/sage/rings/padics/padic_generic_element.pyx +++ b/src/sage/rings/padics/padic_generic_element.pyx @@ -192,18 +192,6 @@ cdef class pAdicGenericElement(LocalGenericElement): cdef bint _set_prec_both(self, long absprec, long relprec) except -1: return 0 - #def __pari__(self): - # """ - # Returns a pari version of this element. - - # EXAMPLES:: - - # sage: R = Zp(5) - # sage: pari(R(1777)) - # 2 + 5^2 + 4*5^3 + 2*5^4 + O(5^20) - # """ - # return pari(self._pari_init_()) - def __floordiv__(self, right): """ Divides self by right and throws away the nonintegral part if diff --git a/src/sage/rings/polynomial/polynomial_element_generic.py b/src/sage/rings/polynomial/polynomial_element_generic.py index 060b0dae525..462c549a20a 100644 --- a/src/sage/rings/polynomial/polynomial_element_generic.py +++ b/src/sage/rings/polynomial/polynomial_element_generic.py @@ -500,12 +500,6 @@ def list(self, copy=True): v[n] = x return v - #def __pari__(self, variable=None): - # if variable is None: - # return self.__pari - # else: - # return self.__pari.subst('x',variable) - def degree(self, gen=None): """ Return the degree of this sparse polynomial. From c7afe4918bc026ad99ffee8d475098cecb9e87c1 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Tue, 28 Feb 2017 12:17:26 +0100 Subject: [PATCH 072/185] Remove some superfluous calls to __pari__() --- src/sage/rings/finite_rings/integer_mod.pyx | 4 ++-- src/sage/rings/number_field/number_field_ideal.py | 6 +++--- src/sage/rings/polynomial/polynomial_element.pyx | 2 +- .../rings/polynomial/polynomial_quotient_ring_element.py | 2 +- src/sage/rings/quotient_ring_element.py | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index 89980835cc3..02cfd80731f 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -893,7 +893,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): return 0 # We need to factor the modulus. We do it here instead of # letting PARI do it, so that we can cache the factorisation. - return lift.__pari__().Zn_issquare(self._parent.factored_order().__pari__()) + return lift.__pari__().Zn_issquare(self._parent.factored_order()) def sqrt(self, extend=True, all=False): r""" @@ -2679,7 +2679,7 @@ cdef class IntegerMod_int(IntegerMod_abstract): return 0 # We need to factor the modulus. We do it here instead of # letting PARI do it, so that we can cache the factorisation. - return lift.__pari__().Zn_issquare(self._parent.factored_order().__pari__()) + return lift.__pari__().Zn_issquare(self._parent.factored_order()) def sqrt(self, extend=True, all=False): r""" diff --git a/src/sage/rings/number_field/number_field_ideal.py b/src/sage/rings/number_field/number_field_ideal.py index 806aedb43fa..7ad26e4b582 100644 --- a/src/sage/rings/number_field/number_field_ideal.py +++ b/src/sage/rings/number_field/number_field_ideal.py @@ -282,7 +282,7 @@ def _mul_(self, other): K=self.ring() K_pari=K.pari_nf() - return K.ideal(K_pari.idealmul(self.__pari__(), other.__pari__())) + return K.ideal(K_pari.idealmul(self, other)) def coordinates(self, x): r""" @@ -2468,7 +2468,7 @@ def small_residue(self, f): if not self.is_integral(): raise ValueError("The ideal must be integral") k = self.number_field() - return k(k.pari_nf().nfeltreduce(f.__pari__(), self.pari_hnf())) + return k(k.pari_nf().nfeltreduce(f, self.pari_hnf())) def _pari_bid_(self, flag=1): """ @@ -2658,7 +2658,7 @@ def ideallog(self, x, gens=None, check=True): #Now it is important to call _pari_bid_() with flag=2 to make sure #we fix a basis, since the log would be different for a different #choice of basis. - L = [ZZ(_) for _ in k.pari_nf().ideallog(x.__pari__(), self._pari_bid_(2))] + L = [ZZ(_) for _ in k.pari_nf().ideallog(x, self._pari_bid_(2))] if gens is None: return L diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 92ef74e3596..431ff2c2219 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -6081,7 +6081,7 @@ cdef class Polynomial(CommutativeAlgebraElement): """ variable = self.variable_name() try: - res = self.__pari__().polresultant(other.__pari__(), variable) + res = self.__pari__().polresultant(other, variable) return self.parent().base_ring()(res) except (TypeError, ValueError, PariError, NotImplementedError): return self.sylvester_matrix(other).det() diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring_element.py b/src/sage/rings/polynomial/polynomial_quotient_ring_element.py index cb99aa1184d..99e4f3d82d5 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring_element.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring_element.py @@ -207,7 +207,7 @@ def __pari__(self): sage: pari(xb)^10 Mod(0, x^10) """ - return self._polynomial.__pari__().Mod(self.parent().modulus().__pari__()) + return self._polynomial.__pari__().Mod(self.parent().modulus()) ################################################## # Arithmetic diff --git a/src/sage/rings/quotient_ring_element.py b/src/sage/rings/quotient_ring_element.py index 01f91c05081..016d122e45c 100644 --- a/src/sage/rings/quotient_ring_element.py +++ b/src/sage/rings/quotient_ring_element.py @@ -244,7 +244,7 @@ def __pari__(self): gens = self.parent().defining_ideal().gens() if len(gens) != 1: raise ValueError("Pari does not support quotients by non-principal ideals") - return self.__rep.__pari__().Mod(gens[0].__pari__()) + return self.__rep.__pari__().Mod(gens[0]) def _add_(self, right): """ From dc3c7cdb05126637ff92412a1362ed55ba573e85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 28 Feb 2017 17:09:09 +0100 Subject: [PATCH 073/185] trac 22357 change doctest, as tests do pass --- src/sage/tests/py3_syntax.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/sage/tests/py3_syntax.py b/src/sage/tests/py3_syntax.py index 6f37b6a7d8e..360e8b2020e 100644 --- a/src/sage/tests/py3_syntax.py +++ b/src/sage/tests/py3_syntax.py @@ -6,11 +6,6 @@ sage: from sage.tests.py3_syntax import Python3SyntaxTest sage: py3_syntax = Python3SyntaxTest('sage', 'sage_setup') sage: py3_syntax.run_tests('.py') # long time - Invalid Python 3 syntax found: - File "src/sage/combinat/growth.py", line 259 - self._covers_1 = lambda (a,b): True - ^ - SyntaxError: invalid syntax """ from __future__ import print_function From 6b65682846416c83883250b492305588b19c33c0 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Tue, 28 Feb 2017 15:32:42 +0100 Subject: [PATCH 074/185] Gen: clean up "new_ref" mechanism --- src/sage/libs/cypari2/closure.pyx | 2 +- src/sage/libs/cypari2/gen.pxd | 30 ++- src/sage/libs/cypari2/gen.pyx | 233 ++++++++---------- src/sage/libs/cypari2/pari_instance.pyx | 11 +- src/sage/libs/cypari2/stack.pxd | 2 +- src/sage/libs/cypari2/stack.pyx | 13 +- .../rings/finite_rings/element_pari_ffelt.pxd | 2 +- .../rings/finite_rings/element_pari_ffelt.pyx | 10 +- src/sage/rings/power_series_pari.pyx | 12 +- 9 files changed, 153 insertions(+), 162 deletions(-) diff --git a/src/sage/libs/cypari2/closure.pyx b/src/sage/libs/cypari2/closure.pyx index e4efae2ce5f..265948b0494 100644 --- a/src/sage/libs/cypari2/closure.pyx +++ b/src/sage/libs/cypari2/closure.pyx @@ -172,5 +172,5 @@ cpdef Gen objtoclosure(f): cdef GEN f_int = utoi(f) # Create a t_CLOSURE which calls call_python() with py_func equal to f cdef Gen c = new_gen(snm_closure(ep_call_python, mkvec(f_int))) - c.refers_to = {0:f} # c needs to keep a reference to f + c.cache(0, f) # c needs to keep a reference to f return c diff --git a/src/sage/libs/cypari2/gen.pxd b/src/sage/libs/cypari2/gen.pxd index d35bd0b8397..87acade17b2 100644 --- a/src/sage/libs/cypari2/gen.pxd +++ b/src/sage/libs/cypari2/gen.pxd @@ -3,14 +3,36 @@ cimport cython cdef class Gen_auto: + # The actual PARI GEN cdef GEN g - cdef pari_sp b - cdef dict refers_to + + # Chunk of memory containing g, typically allocated in + # deepcopy_to_python_heap(). + cdef void* chunk + + # Parent Gen: this is usually None, but it can be used when this + # Gen is a part of some other Gen. In that case, chunk will be NULL + # because the parent has allocated the memory. + cdef Gen_auto parent + + # A cache for __getitem__. Initially, this is None but it will be + # turned into a dict when needed. This is not just an optional + # cache, but it is required to implement __setitem__ correctly: + # __setitem__ will set an entry of one Gen to another Gen. To + # prevent Python from garbage collecting the other Gen, we must put + # it in itemcache. + cdef dict itemcache + + cdef inline int cache(self, key, value) except -1: + """Add ``(key, value)`` to ``self.itemcache``.""" + if self.itemcache is None: + self.itemcache = {key: value} + else: + self.itemcache[key] = value @cython.final cdef class Gen(Gen_auto): - pass + cdef new_ref(self, GEN g) -cdef Gen new_ref(GEN g, Gen parent) cdef Gen list_of_Gens_to_Gen(list s) cpdef Gen objtogen(s) diff --git a/src/sage/libs/cypari2/gen.pyx b/src/sage/libs/cypari2/gen.pyx index e4c5855e139..06cfb592629 100644 --- a/src/sage/libs/cypari2/gen.pyx +++ b/src/sage/libs/cypari2/gen.pyx @@ -93,7 +93,39 @@ cdef class Gen(Gen_auto): raise RuntimeError("PARI objects cannot be instantiated directly; use pari(x) to convert x to PARI") def __dealloc__(self): - sig_free(self.b) + sig_free(self.chunk) + + cdef new_ref(self, GEN g): + """ + Create a new ``Gen`` pointing to ``g``, which is a component + of ``self.g``. + + In this case, ``g`` should point to some location in the memory + allocated by ``self``. This will not allocate any new memory: + the newly returned ``Gen`` will point to the memory allocated + for ``self``. + + .. NOTE:: + + Usually, there is only one ``Gen`` pointing to a given PARI + ``GEN``. This function can be used when a complicated + ``GEN`` is allocated with a single ``Gen`` pointing to it, + and one needs a ``Gen`` pointing to one of its components. + + For example, doing ``x = pari("[1, 2]")`` allocates a ``Gen`` + pointing to the list ``[1, 2]``. To create a ``Gen`` pointing + to the first element, one can do ``x.new_ref(gel(x.g, 1))``. + See :meth:`Gen.__getitem__` for an example of usage. + + EXAMPLES:: + + sage: pari("[[1, 2], 3]")[0][1] # indirect doctest + 2 + """ + cdef Gen x = Gen.__new__(Gen) + x.g = g + x.parent = self + return x def __repr__(self): """ @@ -888,7 +920,8 @@ cdef class Gen(Gen_auto): sage: pari([])[::] [] """ - cdef Py_ssize_t k + cdef Py_ssize_t i, j, k + cdef object ind cdef int pari_type pari_type = typ(self.g) @@ -896,30 +929,23 @@ cdef class Gen(Gen_auto): if isinstance(n, tuple): if pari_type != t_MAT: raise TypeError("self must be of pari type t_MAT") - if len(n) != 2: - raise IndexError("index must be an integer or a 2-tuple (i,j)") - i = int(n[0]) - j = int(n[1]) - if i < 0 or i >= glength((self.g[1])): + i, j = n + + if i < 0 or i >= glength(gel(self.g, 1)): raise IndexError("row index out of range") if j < 0 or j >= glength(self.g): raise IndexError("column index out of range") - ind = (i,j) + ind = (i, j) - if self.refers_to is not None and ind in self.refers_to: - return self.refers_to[ind] + if self.itemcache is not None and ind in self.itemcache: + return self.itemcache[ind] else: - ## In this case, we're being asked to return - ## a GEN that has no Gen pointing to it, so - ## we need to create such a gen, add it to - ## self.refers_to, and return it. - val = new_ref(gmael(self.g, j+1, i+1), self) - if self.refers_to is None: - self.refers_to = {ind: val} - else: - self.refers_to[ind] = val + # Create a new Gen as child of self + # and store it in itemcache + val = self.new_ref(gmael(self.g, j+1, i+1)) + self.cache(ind, val) return val elif isinstance(n, slice): @@ -940,52 +966,51 @@ cdef class Gen(Gen_auto): # slow call return objtogen(self[i] for i in inds) + # Index is not a tuple or slice, convert to integer + i = n + ## there are no "out of bounds" problems ## for a polynomial or power series, so these go before ## bounds testing if pari_type == t_POL: - return self.polcoeff(n) + return self.polcoeff(i) elif pari_type == t_SER: bound = valp(self.g) + lg(self.g) - 2 - if n >= bound: + if i >= bound: raise IndexError("index out of range") - return self.polcoeff(n) + return self.polcoeff(i) elif pari_type in (t_INT, t_REAL, t_PADIC, t_QUAD, t_FFELT, t_INTMOD, t_POLMOD): # these are definitely scalar! raise TypeError("PARI object of type %r cannot be indexed" % self.type()) - elif n < 0 or n >= glength(self.g): + elif i < 0 or i >= glength(self.g): raise IndexError("index out of range") elif pari_type == t_VEC or pari_type == t_MAT: #t_VEC : row vector [ code ] [ x_1 ] ... [ x_k ] #t_MAT : matrix [ code ] [ col_1 ] ... [ col_k ] - if self.refers_to is not None and n in self.refers_to: - return self.refers_to[n] + ind = i + if self.itemcache is not None and ind in self.itemcache: + return self.itemcache[ind] else: - ## In this case, we're being asked to return - ## a GEN that has no Gen pointing to it, so - ## we need to create such a gen, add it to - ## self.refers_to, and return it. - val = new_ref(gel(self.g, n+1), self) - if self.refers_to is None: - self.refers_to = {n: val} - else: - self.refers_to[n] = val + # Create a new Gen as child of self + # and store it in itemcache + val = self.new_ref(gel(self.g, i+1)) + self.cache(ind, val) return val elif pari_type == t_VECSMALL: #t_VECSMALL: vec. small ints [ code ] [ x_1 ] ... [ x_k ] - return self.g[n+1] + return self.g[i+1] elif pari_type == t_STR: #t_STR : string [ code ] [ man_1 ] ... [ man_k ] - return chr( ((self.g+1))[n] ) + return chr(GSTR(self.g)[i]) elif pari_type == t_LIST: - return self.component(n+1) + return self.component(i+1) #elif pari_type in (t_FRAC, t_RFRAC): # generic code gives us: @@ -1003,7 +1028,7 @@ cdef class Gen(Gen_auto): else: ## generic code, which currently handles cases ## as mentioned above - return new_ref(gel(self.g,n+1), self) + return self.new_ref(gel(self.g, i+1)) def __setitem__(self, n, y): r""" @@ -1092,70 +1117,54 @@ cdef class Gen(Gen_auto): sage: type(v[0]) """ - cdef int i, j + cdef Py_ssize_t i, j, step cdef Gen x = objtogen(y) cdef long l - cdef Py_ssize_t ii, jj, step - sig_on() - try: - if isinstance(n, tuple): - if typ(self.g) != t_MAT: - raise TypeError("cannot index PARI type %s by tuple" % typ(self.g)) - - if len(n) != 2: - raise ValueError("matrix index must be of the form [row, column]") - - i = int(n[0]) - j = int(n[1]) - ind = (i,j) - - if i < 0 or i >= glength((self.g[1])): - raise IndexError("row i(=%s) must be between 0 and %s" % (i, self.nrows()-1)) - if j < 0 or j >= glength(self.g): - raise IndexError("column j(=%s) must be between 0 and %s" % (j, self.ncols()-1)) - if self.refers_to is None: - self.refers_to = {ind: x} - else: - self.refers_to[ind] = x - - ((self.g)[j+1])[i+1] = (x.g) - return - - elif isinstance(n, slice): - l = glength(self.g) - inds = xrange(*n.indices(l)) - k = len(inds) - if k > len(y): - raise ValueError("attempt to assign sequence of size %s to slice of size %s" % (len(y), k)) - - # actually set the values - for i,j in enumerate(inds): - self[j] = y[i] - return - - i = int(n) - - if i < 0 or i >= glength(self.g): - raise IndexError("index (%s) must be between 0 and %s" % (i, glength(self.g)-1)) - - # so python memory manager will work correctly - # and not free x if PARI part of self is the - # only thing pointing to it. - if self.refers_to is None: - self.refers_to = {i: x} - else: - self.refers_to[i] = x + if isinstance(n, tuple): + if typ(self.g) != t_MAT: + raise TypeError("cannot index PARI type %s by tuple" % typ(self.g)) + + i, j = n - ## correct indexing for t_POLs - if typ(self.g) == t_POL: - i = i + 1 + if i < 0 or i >= glength(gel(self.g, 1)): + raise IndexError("row i(=%s) must be between 0 and %s" % (i, self.nrows()-1)) + if j < 0 or j >= glength(self.g): + raise IndexError("column j(=%s) must be between 0 and %s" % (j, self.ncols()-1)) - ## actually set the value - (self.g)[i+1] = (x.g) + self.cache((i,j), x) + set_gcoeff(self.g, i+1, j+1, x.g) return - finally: - sig_off() + + elif isinstance(n, slice): + l = glength(self.g) + inds = xrange(*n.indices(l)) + k = len(inds) + if k > len(y): + raise ValueError("attempt to assign sequence of size %s to slice of size %s" % (len(y), k)) + + # actually set the values + for a, b in enumerate(inds): + self[b] = y[a] + return + + # Index is not a tuple or slice, convert to integer + i = n + + if i < 0 or i >= glength(self.g): + raise IndexError("index (%s) must be between 0 and %s" % (i, glength(self.g)-1)) + + # Add a reference to x to prevent Python from garbage + # collecting x. + self.cache(i, x) + + # Correct indexing for t_POLs + if typ(self.g) == t_POL: + i += 1 + + # Actually set the value + set_gel(self.g, i+1, x.g) + return def __len__(self): return glength(self.g) @@ -3897,7 +3906,7 @@ cdef class Gen(Gen_auto): if self.ncols() == 0: sig_off() return 0 - n = glength((self.g[1])) + n = glength(gel(self.g, 1)) sig_off() return n @@ -4363,36 +4372,6 @@ cdef class Gen(Gen_auto): raise NotImplementedError("the method allocatemem() should not be used; use pari.allocatemem() instead") -cdef Gen new_ref(GEN g, Gen parent): - """ - Create a new ``Gen`` pointing to ``g``, which is allocated as a - part of ``parent.g``. - - .. NOTE:: - - As a rule, there should never be more than one ``Gen`` - pointing to a given PARI ``GEN``. This function should only - be used when a complicated ``GEN`` is allocated with a single - ``Gen`` pointing to it, and one needs a ``Gen`` pointing to - one of its components. - - For example, doing ``x = pari("[1, 2]")`` allocates a ``Gen`` - pointing to the list ``[1, 2]``. To create a ``Gen`` pointing - to the first element, one can do ``new_ref(gel(x.g, 1), x)``. - See :meth:`Gen.__getitem__` for an example of usage. - - EXAMPLES:: - - sage: pari("[[1, 2], 3]")[0][1] # indirect doctest - 2 - """ - cdef Gen p = Gen.__new__(Gen) - p.g = g - p.b = 0 - p.refers_to = {-1: parent} - return p - - @cython.boundscheck(False) @cython.wraparound(False) cdef Gen list_of_Gens_to_Gen(list s): diff --git a/src/sage/libs/cypari2/pari_instance.pyx b/src/sage/libs/cypari2/pari_instance.pyx index b2436c3cf98..5ab25876ff7 100644 --- a/src/sage/libs/cypari2/pari_instance.pyx +++ b/src/sage/libs/cypari2/pari_instance.pyx @@ -1256,13 +1256,12 @@ cdef class Pari(Pari_auto): if len(entries) != m*n: raise IndexError("len of entries (=%s) must be %s*%s=%s"%(len(entries),m,n,m*n)) k = 0 - A.refers_to = {} - for i from 0 <= i < m: - for j from 0 <= j < n: + for i in range(m): + for j in range(n): x = self(entries[k]) - A.refers_to[(i,j)] = x - ((A.g)[j+1])[i+1] = (x.g) - k = k + 1 + A.cache((i,j), x) + set_gcoeff(A.g, i+1, j+1, x.g) + k += 1 return A def genus2red(self, P, P0=None): diff --git a/src/sage/libs/cypari2/stack.pxd b/src/sage/libs/cypari2/stack.pxd index 82fd9ee6b39..7e23f647d1a 100644 --- a/src/sage/libs/cypari2/stack.pxd +++ b/src/sage/libs/cypari2/stack.pxd @@ -2,6 +2,6 @@ from .types cimport GEN, pari_sp from .gen cimport Gen cdef void clear_stack() -cdef GEN deepcopy_to_python_heap(GEN x, pari_sp* address) +cdef GEN deepcopy_to_python_heap(GEN x, void** address) except NULL cdef Gen new_gen(GEN x) cdef Gen new_gen_noclear(GEN x) diff --git a/src/sage/libs/cypari2/stack.pyx b/src/sage/libs/cypari2/stack.pyx index 7fe4014f948..95ab4a92e3a 100644 --- a/src/sage/libs/cypari2/stack.pyx +++ b/src/sage/libs/cypari2/stack.pyx @@ -33,11 +33,11 @@ cdef inline void clear_stack(): avma = pari_mainstack.top sig_off() -cdef inline GEN deepcopy_to_python_heap(GEN x, pari_sp* address): - cdef size_t s = gsizebyte(x) - cdef pari_sp tmp_bot = sig_malloc(s) - cdef pari_sp tmp_top = tmp_bot + s +cdef inline GEN deepcopy_to_python_heap(GEN x, void** address) except NULL: + cdef size_t s = gsizebyte(x) + cdef void* tmp_bot = check_malloc(s) address[0] = tmp_bot + cdef pari_sp tmp_top = tmp_bot + s return gcopy_avma(x, &tmp_top) cdef inline Gen new_gen(GEN x): @@ -58,9 +58,6 @@ cdef inline Gen new_gen_noclear(GEN x): Create a new gen, but don't free any memory on the stack and don't call sig_off(). """ - cdef pari_sp address cdef Gen y = Gen.__new__(Gen) - y.g = deepcopy_to_python_heap(x, &address) - y.b = address - # y.refers_to (a dict which is None now) is initialised as needed + y.g = deepcopy_to_python_heap(x, &y.chunk) return y diff --git a/src/sage/rings/finite_rings/element_pari_ffelt.pxd b/src/sage/rings/finite_rings/element_pari_ffelt.pxd index 191052e00ce..940189aa98d 100644 --- a/src/sage/rings/finite_rings/element_pari_ffelt.pxd +++ b/src/sage/rings/finite_rings/element_pari_ffelt.pxd @@ -3,7 +3,7 @@ from sage.rings.finite_rings.element_base cimport FinitePolyExtElement cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): cdef GEN val # PARI t_FFELT describing the element - cdef void *block # memory block containing the data + cdef void* chunk # memory block containing the data cdef FiniteFieldElement_pari_ffelt _new(FiniteFieldElement_pari_ffelt self) cdef void construct(FiniteFieldElement_pari_ffelt self, GEN g) cdef void construct_from(FiniteFieldElement_pari_ffelt self, object x) except * diff --git a/src/sage/rings/finite_rings/element_pari_ffelt.pyx b/src/sage/rings/finite_rings/element_pari_ffelt.pyx index 8a31c5a6229..8d18066899b 100644 --- a/src/sage/rings/finite_rings/element_pari_ffelt.pyx +++ b/src/sage/rings/finite_rings/element_pari_ffelt.pyx @@ -155,17 +155,11 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): self._parent = parent self.construct_from(x) - # The Cython constructor __cinit__ is not necessary: according to - # the Cython documentation, C attributes are initialised to 0. - # def __cinit__(FiniteFieldElement_pari_ffelt self): - # self.block = NULL - def __dealloc__(FiniteFieldElement_pari_ffelt self): """ Cython deconstructor. """ - if self.block: - sig_free(self.block) + sig_free(self.chunk) cdef FiniteFieldElement_pari_ffelt _new(FiniteFieldElement_pari_ffelt self): """ @@ -183,7 +177,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): This should be called exactly once on every instance. """ - self.val = deepcopy_to_python_heap(g, &self.block) + self.val = deepcopy_to_python_heap(g, &self.chunk) clear_stack() cdef void construct_from(FiniteFieldElement_pari_ffelt self, object x) except *: diff --git a/src/sage/rings/power_series_pari.pyx b/src/sage/rings/power_series_pari.pyx index ed279640bf7..186a650943c 100644 --- a/src/sage/rings/power_series_pari.pyx +++ b/src/sage/rings/power_series_pari.pyx @@ -71,7 +71,7 @@ AUTHORS: from __future__ import absolute_import, division, print_function -from sage.libs.cypari2.gen cimport Gen as pari_gen, new_ref +from sage.libs.cypari2.gen cimport Gen as pari_gen from sage.libs.cypari2.pari_instance cimport get_var from sage.libs.cypari2.paridecl cimport gel, typ, lg, valp, varn, t_POL, t_SER, t_RFRAC, t_VEC from sage.libs.pari.all import pari @@ -678,7 +678,7 @@ cdef class PowerSeries_pari(PowerSeries): g = g.truncate() if typ(g.g) == t_POL and varn(g.g) == vn: # t_POL has 2 codewords. Use new_ref instead of g[i] for speed. - return [R(new_ref(gel(g.g, i), g)) for i in range(2, lg(g.g))] + return [R(g.new_ref(gel(g.g, i))) for i in range(2, lg(g.g))] else: return [R(g)] @@ -735,9 +735,9 @@ cdef class PowerSeries_pari(PowerSeries): if typ(g.g) == t_POL and varn(g.g) == get_var(self._parent.variable_name()): l = lg(g.g) - 2 # t_POL has 2 codewords if n <= l: - return [R(new_ref(gel(g.g, i + 2), g)) for i in range(n)] + return [R(g.new_ref(gel(g.g, i + 2))) for i in range(n)] else: - return ([R(new_ref(gel(g.g, i + 2), g)) for i in range(l)] + return ([R(g.new_ref(gel(g.g, i + 2))) for i in range(l)] + [R.zero()] * (n - l)) elif typ(g.g) == t_SER and varn(g.g) == get_var(self._parent.variable_name()): l = lg(g.g) - 2 # t_SER has 2 codewords @@ -746,10 +746,10 @@ cdef class PowerSeries_pari(PowerSeries): return [R.zero()] * n elif n <= l + m: return ([R.zero()] * m - + [R(new_ref(gel(g.g, i + 2), g)) for i in range(n - m)]) + + [R(g.new_ref(gel(g.g, i + 2))) for i in range(n - m)]) else: return ([R.zero()] * m - + [R(new_ref(gel(g.g, i + 2), g)) for i in range(l)] + + [R(g.new_ref(gel(g.g, i + 2))) for i in range(l)] + [R.zero()] * (n - l - m)) else: return [R(g)] + [R.zero()] * (n - 1) From afa82c0e3ec8718ac9837921d6f25b2a8302db5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 1 Mar 2017 08:17:01 +0100 Subject: [PATCH 075/185] trac 22357 details --- src/sage/tests/py3_syntax.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/tests/py3_syntax.py b/src/sage/tests/py3_syntax.py index 360e8b2020e..a093188c1e3 100644 --- a/src/sage/tests/py3_syntax.py +++ b/src/sage/tests/py3_syntax.py @@ -11,7 +11,6 @@ from __future__ import print_function import os -import sys import itertools import subprocess @@ -44,12 +43,12 @@ def __iter__(self): OUTPUT: - Iterator over triples consisting of path, filename, and file - extension. The iteration order only depends on the filenames + Iterator over triples consisting of path, filename, and file + extension. The iteration order only depends on the filenames and not on filesystem layout. EXAMPLES:: - + sage: from sage.tests.py3_syntax import Python3SyntaxTest sage: test = Python3SyntaxTest('sage/tests/french_book') sage: next(iter(test)) @@ -70,15 +69,16 @@ def run_tests(self, *extensions): """ Run tests - The abstract :meth:`test` is called on each file with a + The abstract :meth:`test` is called on each file with a matching extension. INPUT: - -- ``*extensions`` - the file extensions (including the leading dot) + -- ``*extensions`` - the file extensions (including the leading dot) to check. - EXAMPLES:: + EXAMPLES:: + sage: from sage.tests.py3_syntax import SortedDirectoryWalkerABC sage: walker = SortedDirectoryWalkerABC('sage/tests/french_book') sage: walker.run_tests('.py') @@ -135,7 +135,7 @@ def test(self, *filenames): -- ``filename`` -- string. The full qualified filename to check. EXAMPLES:: - + sage: import os, tempfile sage: src = tempfile.NamedTemporaryFile(suffix='.py', delete=False) sage: src.write('print "invalid print statement') From f7bc5b7ea8205e31ef4d98928d289c79c0f9e893 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 1 Mar 2017 09:26:28 +0100 Subject: [PATCH 076/185] Put sig_check() in inner loops --- src/sage/libs/cypari2/gen.pyx | 1 + src/sage/libs/cypari2/pari_instance.pyx | 1 + 2 files changed, 2 insertions(+) diff --git a/src/sage/libs/cypari2/gen.pyx b/src/sage/libs/cypari2/gen.pyx index 06cfb592629..8e3038f5afa 100644 --- a/src/sage/libs/cypari2/gen.pyx +++ b/src/sage/libs/cypari2/gen.pyx @@ -1145,6 +1145,7 @@ cdef class Gen(Gen_auto): # actually set the values for a, b in enumerate(inds): + sig_check() self[b] = y[a] return diff --git a/src/sage/libs/cypari2/pari_instance.pyx b/src/sage/libs/cypari2/pari_instance.pyx index 5ab25876ff7..131a29f25eb 100644 --- a/src/sage/libs/cypari2/pari_instance.pyx +++ b/src/sage/libs/cypari2/pari_instance.pyx @@ -1258,6 +1258,7 @@ cdef class Pari(Pari_auto): k = 0 for i in range(m): for j in range(n): + sig_check() x = self(entries[k]) A.cache((i,j), x) set_gcoeff(A.g, i+1, j+1, x.g) From 0279ad83f16822619933f7d3f990cfe2a871ceee Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 1 Mar 2017 09:38:08 +0100 Subject: [PATCH 077/185] Support _pari_ as deprecated alias of __pari__ --- src/sage/libs/cypari2/gen.pyx | 20 +++++++++++++++++++- src/sage/structure/sage_object.pyx | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/sage/libs/cypari2/gen.pyx b/src/sage/libs/cypari2/gen.pyx index 7729b7b199a..8eb569f30e4 100644 --- a/src/sage/libs/cypari2/gen.pyx +++ b/src/sage/libs/cypari2/gen.pyx @@ -4513,6 +4513,13 @@ cpdef Gen objtogen(s): Traceback (most recent call last): ... ValueError: Cannot convert None to pari + + sage: class OldStylePari: + ....: def _pari_(self): + ....: return pari(42) + sage: pari(OldStylePari()) + doctest:...: DeprecationWarning: the _pari_ method is deprecated, use __pari__ instead + 42 """ cdef GEN g cdef list L @@ -4520,9 +4527,20 @@ cpdef Gen objtogen(s): if isinstance(s, Gen): return s try: - return s.__pari__() + m = s.__pari__ + except AttributeError: + pass + else: + return m() + + try: + m = s._pari_ except AttributeError: pass + else: + from warnings import warn + warn("the _pari_ method is deprecated, use __pari__ instead", DeprecationWarning) + return m() # Check basic Python types. Start with strings, which are a very # common case. diff --git a/src/sage/structure/sage_object.pyx b/src/sage/structure/sage_object.pyx index 9fe86f7e1fc..d242c9fd39e 100644 --- a/src/sage/structure/sage_object.pyx +++ b/src/sage/structure/sage_object.pyx @@ -645,6 +645,24 @@ cdef class SageObject: def _sage_(self): return self + def _pari_(self): + """ + Deprecated alias for ``__pari__``. + + TESTS:: + + sage: class NewStylePari(SageObject): + ....: def __pari__(self): + ....: return pari(42) + sage: NewStylePari()._pari_() + doctest:...: DeprecationWarning: the _pari_ method is deprecated, use __pari__ instead + See http://trac.sagemath.org/22470 for details. + 42 + """ + from sage.misc.superseded import deprecation + deprecation(22470, 'the _pari_ method is deprecated, use __pari__ instead') + return self.__pari__() + def _interface_(self, I): """ Return coercion of self to an object of the interface I. From 0bb7f89295de31e3e99e43a74832af23d4eea5de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 2 Mar 2017 15:08:44 +0100 Subject: [PATCH 078/185] trac 22357, removed unused variable and change detail in the bad print --- src/sage/tests/py3_syntax.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/sage/tests/py3_syntax.py b/src/sage/tests/py3_syntax.py index a093188c1e3..2732064538c 100644 --- a/src/sage/tests/py3_syntax.py +++ b/src/sage/tests/py3_syntax.py @@ -55,9 +55,8 @@ def __iter__(self): ('src/sage/tests/french_book', 'README', '') """ tree_walk = itertools.chain(*map(os.walk, self._directories)) - for path, dirs, files in tree_walk: + for path, _, files in tree_walk: path = os.path.relpath(path) - dirs.sort() files.sort() for filename in files: if filename.startswith('.'): @@ -138,15 +137,15 @@ def test(self, *filenames): sage: import os, tempfile sage: src = tempfile.NamedTemporaryFile(suffix='.py', delete=False) - sage: src.write('print "invalid print statement') + sage: src.write('print "invalid print statement"') sage: src.close() sage: from sage.tests.py3_syntax import Python3SyntaxTest sage: py3_syntax = Python3SyntaxTest() sage: py3_syntax.test(src.name) Invalid Python 3 syntax found: File "...py", line 1 - print "invalid print statement - ^ + print "invalid print statement" + ^ SyntaxError: Missing parentheses in call to 'print' sage: os.unlink(src.name) """ From 764b83ce0572618241d96170ea0122a077aa6eca Mon Sep 17 00:00:00 2001 From: paulmasson Date: Thu, 2 Mar 2017 16:08:16 -0800 Subject: [PATCH 079/185] Add git trac try --- src/doc/en/developer/git_trac.rst | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/doc/en/developer/git_trac.rst b/src/doc/en/developer/git_trac.rst index a7307342ace..7e08b06351d 100644 --- a/src/doc/en/developer/git_trac.rst +++ b/src/doc/en/developer/git_trac.rst @@ -532,8 +532,7 @@ end: git downloads both Alice's conflicting commit and her resolution. Reviewing ========= -This section gives an example how to review using the ``sage`` command. For an -explanation of what should be checked by the reviewer, see +For an explanation of what should be checked by the reviewer, see :ref:`chapter-review`. If you go to the `web interface to the Sage trac development server @@ -552,3 +551,21 @@ to use the web interface: shows you what is being added, analogous to clicking on the "Branch:" field. +To review tickets with minimal recompiling, start on the "develop" branch, +that is, the latest beta. Just checking out an older ticket would most likely +reset the Sage tree to an older version, so you would have to compile older +versions of packages to make it work. Instead, you can create an anonymous +("detached HEAD") merge of the ticket and the develop branch:: + + $ git trac try 12345 + +This will only touch files that are really modified by the ticket. In particular, +if only Python files are changed by the ticket (which is true for most tickets) +then you just have to run ``sage -b`` to rebuild the Sage library. When you are +finished reviewing, just checkout a named branch, for example :: + + $ git checkout develop + +If you want to edit the ticket branch (that is, add additional commits) you cannot +use ``git trac try``. You must use ``git trac checkout`` to get the actual ticket +branch as a starting point. From d9f655481fc9c50264f71c830569782a620ff681 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 3 Mar 2017 22:43:21 +0100 Subject: [PATCH 080/185] fix bugs, allow SignedPermutations as input --- src/sage/combinat/growth.py | 91 +++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 35 deletions(-) diff --git a/src/sage/combinat/growth.py b/src/sage/combinat/growth.py index f941c9934de..b9fd5edf321 100644 --- a/src/sage/combinat/growth.py +++ b/src/sage/combinat/growth.py @@ -235,7 +235,9 @@ def __init__(self, ``shape``. Otherwise it can be a dictionary with keys being coordinates and integer values, a sequence of sequences of integers (including matrices), or a word with - integer letters (including permutations). + integer letters (including permutations). In the latter + case, words with negative letters but without repetitions + are allowed and interpreted as coloured permutations. - ``shape`` is a (possibly skew) partition or ``None``. In the latter case it is determined as the Ferrers shape given @@ -451,6 +453,11 @@ def to_word(self): w[i] = j+1 else: raise ValueError("Can only convert fillings with at most one entry per column to words.") + elif v == -1: + if w[i] == 0: + w[i] = -(j+1) + else: + raise ValueError("Can only convert fillings with at most one entry per column to words.") else: raise ValueError("Can only convert 0-1 fillings to words. Try ``to_biword``.") return w @@ -823,9 +830,12 @@ def _init_filling_and_shape_from_various_input(self, filling, shape): shape = [len(row) for row in filling] except TypeError: - # it is a word + # it is a word - for convenience we allow signed words for i, l in enumerate(filling): - F[(i, l-1)] = 1 + if l > 0: + F[(i, l-1)] = 1 + else: + F[(i, -l-1)] = -1 if shape is None: if F == {}: @@ -1812,6 +1822,22 @@ class GrowthDiagramDomino(GrowthDiagramOnPartitions): 1 2 4 1 3 3 3 3 4 4 + TESTS:: + + sage: G = GrowthDiagramDomino([[0,1,0],[0,0,-1],[1,0,0]]); G + 0 1 0 + 0 0 -1 + 1 0 0 + + sage: ascii_art(G.P_symbol(), G.Q_symbol()) + 1 1 1 1 + 2 3 2 2 + 2 3 3 3 + + sage: l = [GrowthDiagramDomino(pi) for pi in SignedPermutations(4)] + sage: len(Set([(G.P_symbol(), G.Q_symbol()) for G in l])) + 384 + .. automethod:: _forward_rule """ @staticmethod @@ -1850,7 +1876,7 @@ def _forward_rule(shape3, shape2, shape1, content): Rule 2:: sage: G._forward_rule([1,1], [1,1], [1,1], -1) - [2, 2] + [1, 1, 1, 1] Rule 3:: @@ -1876,31 +1902,33 @@ def _forward_rule(shape3, shape2, shape1, content): sage: G._forward_rule([1,1,1,1], [1,1], [1,1,1,1], 0) [2, 2, 1, 1] + + sage: G._forward_rule([2,1,1], [2], [4], 0) + [4, 1, 1] """ + def union(la, mu): + """ + Return the union of the two partitions. + """ + from six.moves import zip_longest + return [max(p,q) for (p,q) in zip_longest(la, mu, fillvalue=0)] + if content not in [0,1,-1]: raise ValueError("Domino: The content of the filling must be in {-1,0,1}") if content == 1: + assert shape1 == shape2 == shape3 if shape2 == []: shape4 = [2] else: shape4 = [shape2[0] + 2] + shape2[1:] elif content == -1: - if shape2 == []: - shape4 = [1,1] - elif len(shape2) == 1: - shape4 = [shape2[0] + 1] + [1] - else: - shape4 = [shape2[0] + 1, shape2[1] + 1] + shape2[2:] + assert shape1 == shape2 == shape3 + shape4 = shape2 + [1,1] elif content == 0 and (shape2 == shape1 or shape2 == shape3): - if len(shape1) > len(shape3): - shape4 = shape1 - elif len(shape1) < len(shape3): - shape4 = shape3 - else: - shape4 = [max(p,q) for (p,q) in zip(shape1, shape3)] + shape4 = union(shape1, shape3) else: # content == 0 and shape2 differs from shape1 and shape3 by @@ -1909,23 +1937,13 @@ def _forward_rule(shape3, shape2, shape1, content): # the following is certainly very slow gamma3 = set(SkewPartition([shape3, shape2]).cells()) gamma1 = set(SkewPartition([shape1, shape2]).cells()) - diff = gamma1.intersection(gamma3) cell1, cell2 = gamma3 - shape4 = copy(shape1) - if len(diff) == 0: - # add gamma3 to shape1 - if len(shape4) <= cell1[0]: - shape4 += [1] - else: - shape4[cell1[0]] += 1 - if len(shape4) <= cell2[0]: - shape4 += [1] - else: - shape4[cell2[0]] += 1 + shape4 = union(shape1, shape3) elif len(diff) == 1: + shape4 = copy(shape1) # diff is a single cell (k,l) = diff.pop() # add (k+1, l+1) to shape1 @@ -1940,22 +1958,25 @@ def _forward_rule(shape3, shape2, shape1, content): shape4[k+1] += 2 # diff has size 2, that is shape1 == shape3 - elif cell1[0] == cell2[0]: - # a horizontal domino + shape4 = copy(shape1) + # a horizontal domino - add 2 to row below of gamma if len(shape4) <= cell1[0]+1: shape4 += [2] else: shape4[cell1[0]+1] += 2 + else: - # a vertical domino - # find first row shorter than cell1[1] + shape4 = copy(shape1) + # a vertical domino - add 2 to column right of gamma + # find first row shorter than cell1[1]+1 for r, p in enumerate(shape4): - if p <= cell1[1]: + if p <= cell1[1]+1: shape4[r] += 1 shape4[r+1] += 1 + break else: - shape4[0] += 1 - shape4[1] += 1 + raise NotImplementedError("Domino: cannot call forward rule with shapes %s and content %s" + %((shape3, shape2, shape1), content)) return shape4 From 869a623f64754cd24a937de038486068215946b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Philippe=20Labb=C3=A9?= Date: Sun, 5 Mar 2017 12:51:42 +0100 Subject: [PATCH 081/185] First version --- src/sage/geometry/polyhedron/base.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index 2cb1a18e80e..70305f515c3 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -2275,6 +2275,21 @@ def gale_transform(self): A_ker = A.right_kernel() return A_ker.basis_matrix().transpose().rows() + @cached_method + def normal_fan(self): + r""" + Return the normal fan of a compact full-dimensional rational polyhedron. + + OUTPUT: + + A complete fan of the ambient space as a + :class:`~sage.geometry.fan.RationalPolyhedralFan`. + """ + + return NormalFan(self) + + + def triangulate(self, engine='auto', connected=True, fine=False, regular=None, star=None): r""" Returns a triangulation of the polytope. From b13f5958fbc1b090342583b1bb819cc93507aa70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Philippe=20Labb=C3=A9?= Date: Mon, 6 Mar 2017 11:01:42 +0100 Subject: [PATCH 082/185] Added also face fan and reference --- src/doc/en/reference/references/index.rst | 5 ++++- src/sage/geometry/polyhedron/base.py | 27 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index c9338391dd1..5e84ce89024 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -1640,9 +1640,12 @@ REFERENCES: constrained optimization. ACM Transactions on Mathematical Software, Vol 23, Num. 4, pp.550--560, 1997. -.. [Zie1998] G. Ziegler. *Shelling polyhedral 3-balls and +.. [Zie1998] G. M. Ziegler. *Shelling polyhedral 3-balls and 4-polytopes*. Discrete Comput. Geom. 19 (1998), 159-174. +.. [Zie2007] G. M. Ziegler. *Lectures on polytopes*, Volume + 152 of Graduate Texts in Mathematics, 7th printing of 1st edition, Springer, 2007. + .. [Zor2008] \A. Zorich "Explicit Jenkins-Strebel representatives of all strata of Abelian and quadratic differentials", Journal of Modern Dynamics, vol. 2, no 1, 139-185 (2008) diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index 70305f515c3..b8f45e54d9b 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -2284,11 +2284,38 @@ def normal_fan(self): A complete fan of the ambient space as a :class:`~sage.geometry.fan.RationalPolyhedralFan`. + + .. SEEALSO:: + + :meth:`~sage.geometry.polyhedron.base.face_fan`. + + REFERENCES: + + For more information, see Chapter 7 of [Zie2007]_. """ return NormalFan(self) + @cached_method + def face_fan(self): + r""" + Return the face fan of a compact full-dimensional rational polyhedron. + + OUTPUT: + + A complete fan of the ambient space as a + :class:`~sage.geometry.fan.RationalPolyhedralFan`. + + .. SEEALSO:: + + :meth:`~sage.geometry.polyhedron.base.normal_fan`. + + REFERENCES: + + For more information, see Chapter 7 of [Zie2007]_. + """ + return FaceFan(self) def triangulate(self, engine='auto', connected=True, fine=False, regular=None, star=None): r""" From 96e40991054c847b0d1fb97623aa36a61854411a Mon Sep 17 00:00:00 2001 From: Marcelo Forets Date: Mon, 6 Mar 2017 16:38:54 +0100 Subject: [PATCH 083/185] Integral of a polynomial over a polytope. --- src/sage/interfaces/latte.py | 124 +++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/src/sage/interfaces/latte.py b/src/sage/interfaces/latte.py index 455271bfacd..9cbb5834ad3 100644 --- a/src/sage/interfaces/latte.py +++ b/src/sage/interfaces/latte.py @@ -178,3 +178,127 @@ def count(arg, ehrhart_polynomial=False, multivariate_generating_function=False, else: from sage.rings.integer import Integer return Integer(ans) + +def integrate(arg, polynomial, raw_output=False, verbose=False, **kwds): + r""" + Call to the function integrate from LattE integrale, to compute the integral of a polynomial over a polytope. + + INPUT: + + - ``arg`` -- a cdd or LattE description string + + - ``polynomial`` -- the polynomial to be integrated, as + + - ``raw_output`` -- if ``True`` then return directly the output string from LattE + + - ``verbose`` -- if ``True`` then return directly verbose output from LattE + + - For all other options of the count program, consult the LattE manual + + OUTPUT: + + Either a string (if ``raw_output`` if set to ``True``) or a rational. + + EXAMPLES:: + + sage: from sage.interfaces.latte import integrate + sage: P = 2 * polytopes.cube() + sage: x, y, z = polygen(QQ, 'x, y, z') + + Integrating over a polynomial over a polytope in either the H or V representation:: + + sage: integrate(P.cdd_Hrepresentation(), x^2*y^2*z^2, cdd=True) # optional - latte_int + 4096/27 + sage: integrate(P.cdd_Vrepresentation(), x^2*y^2*z^2, cdd=True) # optional - latte_int + 4096/27 + + TESTS: + + Testing raw output:: + + sage: from sage.interfaces.latte import integrate + sage: P = polytopes.cuboctahedron() + sage: cddin = P.cdd_Vrepresentation() + sage: x, y, z = polygen(QQ, 'x, y, z') + sage: f = 3*x^2*y^4*z^6 + 7*y^3*z^5 + sage: integrate(cddin, f, cdd=True, raw_output=True) # optional - latte_int + '629/47775' + + Testing the ``verbose`` option:: + + sage: ans = integrate(cddin, f, cdd=True, verbose=True, raw_output=True) # optional - latte_int + This is LattE integrale ... + ... + Invocation: integrate --valuation=integrate --triangulate --redundancy-check=none --cdd --monomials=... /dev/stdin + ... + """ + from subprocess import Popen, PIPE + from sage.misc.misc import SAGE_TMP + from sage.rings.integer import Integer + + args = ['integrate'] + args.append('--valuation=integrate') + args.append('--triangulate') + + if 'redundancy_check' not in kwds: + args.append('--redundancy-check=none') + + for key,value in kwds.items(): + if value is None or value is False: + continue + + key = key.replace('_','-') + if value is True: + args.append('--{}'.format(key)) + else: + args.append('--{}={}'.format(key, value)) + + # transform polynomial to LattE description + coefficients_list = polynomial.coefficients() + exponents_list = [list(exponent_vector_i) for exponent_vector_i in polynomial.exponents()] + + # assuming that the order in coefficients() and exponents() methods match + monomials_list = zip(coefficients_list, exponents_list) + monomials_list = [list(monomial_i) for monomial_i in monomials_list] + monomials_list = str(monomials_list) + + # write the polynomial description to a temp file + from sage.misc.temporary_file import tmp_filename + filename_polynomial = tmp_filename() + + with open(filename_polynomial, 'w') as f: + f.write(monomials_list) + args += ['--monomials=' + filename_polynomial] + + args += ['/dev/stdin'] + + try: + # The cwd argument is needed because latte + # always produces diagnostic output files. + latte_proc = Popen(args, + stdin=PIPE, stdout=PIPE, + stderr=(None if verbose else PIPE), + cwd=str(SAGE_TMP)) + except OSError: + from sage.misc.package import PackageNotFoundError + raise PackageNotFoundError('latte_int') + + ans, err = latte_proc.communicate(arg) + ret_code = latte_proc.poll() + if ret_code: + if err is None: + err = ", see error message above" + else: + err = ":\n" + err + raise RuntimeError("LattE integrale program failed (exit code {})".format(ret_code) + err.strip()) + + ans = ans.splitlines() + ans = ans[-5].split() + assert(ans[0]=='Answer:') + ans = ans[1] + + if raw_output: + return ans + else: + from sage.rings.rational import Rational + return Rational(ans) From d3c95899bcff12e6a17dccd849a35d9274bb7bbd Mon Sep 17 00:00:00 2001 From: Marcelo Forets Date: Mon, 6 Mar 2017 17:03:18 +0100 Subject: [PATCH 084/185] Add volume function to generic latte_int interface. --- src/sage/interfaces/latte.py | 126 +++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/src/sage/interfaces/latte.py b/src/sage/interfaces/latte.py index 9cbb5834ad3..54d868b9b04 100644 --- a/src/sage/interfaces/latte.py +++ b/src/sage/interfaces/latte.py @@ -302,3 +302,129 @@ def integrate(arg, polynomial, raw_output=False, verbose=False, **kwds): else: from sage.rings.rational import Rational return Rational(ans) + +def volume(arg, algorithm='triangulate', raw_output=False, verbose=False, **kwds): + r""" + Call to the function integrate from LattE integrale, to compute the volume of a polytope. + + INPUT: + + - ``arg`` -- a cdd or LattE description string + + - ``algorithm`` -- (default: 'triangulate') the integration method. Use 'triangulate' for polytope triangulation + or 'cone-decompose' for tangent cone decomposition method. + + - ``raw_output`` -- if ``True`` then return directly the output string from LattE + + - ``verbose`` -- if ``True`` then return directly verbose output from LattE + + - For all other options of the count program, consult the LattE manual + + OUTPUT: + + Either a string (if ``raw_output`` if set to ``True``) or a rational. + + EXAMPLES:: + + sage: from sage.interfaces.latte import volume + sage: P = 2 * polytopes.cube() + + Computing the volume of a polytope in either the H or V representation:: + + sage: volume(P.cdd_Hrepresentation(), cdd=True) # optional - latte_int + 64 + sage: volume(P.cdd_Vrepresentation(), cdd=True) # optional - latte_int + 64 + + TESTS: + + Testing triangulate algorithm:: + + sage: from sage.interfaces.latte import integrate + sage: P = polytopes.cuboctahedron() + sage: cddin = P.cdd_Vrepresentation() + sage: volume(cddin, algorithm='triangulate', cdd=True) # optional - latte_int + 20/3 + + Testing convex decomposition algorithm:: + + sage: from sage.interfaces.latte import integrate + sage: P = polytopes.cuboctahedron() + sage: cddin = P.cdd_Vrepresentation() + sage: volume(cddin, algorithm='cone-decompose', cdd=True) # optional - latte_int + 20/3 + + Testing raw output:: + + sage: from sage.interfaces.latte import integrate + sage: P = polytopes.cuboctahedron() + sage: cddin = P.cdd_Vrepresentation() + sage: volume(cddin, cdd=True, raw_output=True) # optional - latte_int + '20/3' + + Testing the ``verbose`` option:: + + sage: ans = volume(cddin, cdd=True, verbose=True, raw_output=True) # optional - latte_int + This is LattE integrale ... + ... + Invocation: integrate --valuation=volume --triangulate --redundancy-check=none --cdd /dev/stdin + ... + """ + from subprocess import Popen, PIPE + from sage.misc.misc import SAGE_TMP + from sage.rings.integer import Integer + + args = ['integrate'] + args.append('--valuation=volume') + + if algorithm=='triangulate': + args.append('--triangulate') + elif algorithm=='cone-decompose': + args.append('--cone-decompose') + + if 'redundancy_check' not in kwds: + args.append('--redundancy-check=none') + + for key,value in kwds.items(): + if value is None or value is False: + continue + + key = key.replace('_','-') + if value is True: + args.append('--{}'.format(key)) + else: + args.append('--{}={}'.format(key, value)) + + args += ['/dev/stdin'] + + try: + # The cwd argument is needed because latte + # always produces diagnostic output files. + latte_proc = Popen(args, + stdin=PIPE, stdout=PIPE, + stderr=(None if verbose else PIPE), + cwd=str(SAGE_TMP)) + except OSError: + from sage.misc.package import PackageNotFoundError + raise PackageNotFoundError('latte_int') + + ans, err = latte_proc.communicate(arg) + ret_code = latte_proc.poll() + if ret_code: + if err is None: + err = ", see error message above" + else: + err = ":\n" + err + raise RuntimeError("LattE integrale program failed (exit code {})".format(ret_code) + err.strip()) + + ans = ans.splitlines() + + ans = ans[-5].split() + assert(ans[0]=='Answer:') + ans = ans[1] + + if raw_output: + return ans + else: + from sage.rings.rational import Rational + return Rational(ans) From 000bf8b56094cb83b11894e2c8195747e06c803f Mon Sep 17 00:00:00 2001 From: Marcelo Forets Date: Mon, 6 Mar 2017 18:57:30 +0100 Subject: [PATCH 085/185] Restructured the script, with an integrate function accepting different valuations. * (@mkoeppe) Here it is more logic to use the same LattE integrate interface which supports different valuations. * A helper function _to_latte_polynomial has been added to pass from Sage polynomials to their correponding LattE representation as a list of monomials (see LattE documentation for further information). --- src/sage/interfaces/latte.py | 171 +++++++++++------------------------ 1 file changed, 54 insertions(+), 117 deletions(-) diff --git a/src/sage/interfaces/latte.py b/src/sage/interfaces/latte.py index 54d868b9b04..01870f53c28 100644 --- a/src/sage/interfaces/latte.py +++ b/src/sage/interfaces/latte.py @@ -179,15 +179,19 @@ def count(arg, ehrhart_polynomial=False, multivariate_generating_function=False, from sage.rings.integer import Integer return Integer(ans) -def integrate(arg, polynomial, raw_output=False, verbose=False, **kwds): +def integrate(arg, polynomial=None, algorithm='triangulate', raw_output=False, verbose=False, **kwds): r""" - Call to the function integrate from LattE integrale, to compute the integral of a polynomial over a polytope. + Call to the function integrate from LattE integrale. INPUT: - ``arg`` -- a cdd or LattE description string - - ``polynomial`` -- the polynomial to be integrated, as + - ``polynomial`` -- polynomial that is integrated over the polytope. + If None, the volume of the polytope is computed. + + - ``algorithm`` -- (default: 'triangulate') the integration method. Use 'triangulate' for polytope triangulation + or 'cone-decompose' for tangent cone decomposition method. - ``raw_output`` -- if ``True`` then return directly the output string from LattE @@ -212,6 +216,13 @@ def integrate(arg, polynomial, raw_output=False, verbose=False, **kwds): sage: integrate(P.cdd_Vrepresentation(), x^2*y^2*z^2, cdd=True) # optional - latte_int 4096/27 + Computing the volume of a polytope in either the H or V representation:: + + sage: integrate(P.cdd_Hrepresentation(), cdd=True) # optional - latte_int + 64 + sage: integrate(P.cdd_Vrepresentation(), cdd=True) # optional - latte_int + 64 + TESTS: Testing raw output:: @@ -224,126 +235,20 @@ def integrate(arg, polynomial, raw_output=False, verbose=False, **kwds): sage: integrate(cddin, f, cdd=True, raw_output=True) # optional - latte_int '629/47775' - Testing the ``verbose`` option:: + Testing the ``verbose`` option to integrate over a polytope:: sage: ans = integrate(cddin, f, cdd=True, verbose=True, raw_output=True) # optional - latte_int This is LattE integrale ... ... Invocation: integrate --valuation=integrate --triangulate --redundancy-check=none --cdd --monomials=... /dev/stdin ... - """ - from subprocess import Popen, PIPE - from sage.misc.misc import SAGE_TMP - from sage.rings.integer import Integer - - args = ['integrate'] - args.append('--valuation=integrate') - args.append('--triangulate') - - if 'redundancy_check' not in kwds: - args.append('--redundancy-check=none') - - for key,value in kwds.items(): - if value is None or value is False: - continue - - key = key.replace('_','-') - if value is True: - args.append('--{}'.format(key)) - else: - args.append('--{}={}'.format(key, value)) - - # transform polynomial to LattE description - coefficients_list = polynomial.coefficients() - exponents_list = [list(exponent_vector_i) for exponent_vector_i in polynomial.exponents()] - - # assuming that the order in coefficients() and exponents() methods match - monomials_list = zip(coefficients_list, exponents_list) - monomials_list = [list(monomial_i) for monomial_i in monomials_list] - monomials_list = str(monomials_list) - - # write the polynomial description to a temp file - from sage.misc.temporary_file import tmp_filename - filename_polynomial = tmp_filename() - - with open(filename_polynomial, 'w') as f: - f.write(monomials_list) - args += ['--monomials=' + filename_polynomial] - - args += ['/dev/stdin'] - - try: - # The cwd argument is needed because latte - # always produces diagnostic output files. - latte_proc = Popen(args, - stdin=PIPE, stdout=PIPE, - stderr=(None if verbose else PIPE), - cwd=str(SAGE_TMP)) - except OSError: - from sage.misc.package import PackageNotFoundError - raise PackageNotFoundError('latte_int') - - ans, err = latte_proc.communicate(arg) - ret_code = latte_proc.poll() - if ret_code: - if err is None: - err = ", see error message above" - else: - err = ":\n" + err - raise RuntimeError("LattE integrale program failed (exit code {})".format(ret_code) + err.strip()) - - ans = ans.splitlines() - ans = ans[-5].split() - assert(ans[0]=='Answer:') - ans = ans[1] - - if raw_output: - return ans - else: - from sage.rings.rational import Rational - return Rational(ans) - -def volume(arg, algorithm='triangulate', raw_output=False, verbose=False, **kwds): - r""" - Call to the function integrate from LattE integrale, to compute the volume of a polytope. - - INPUT: - - - ``arg`` -- a cdd or LattE description string - - - ``algorithm`` -- (default: 'triangulate') the integration method. Use 'triangulate' for polytope triangulation - or 'cone-decompose' for tangent cone decomposition method. - - - ``raw_output`` -- if ``True`` then return directly the output string from LattE - - - ``verbose`` -- if ``True`` then return directly verbose output from LattE - - - For all other options of the count program, consult the LattE manual - - OUTPUT: - - Either a string (if ``raw_output`` if set to ``True``) or a rational. - - EXAMPLES:: - - sage: from sage.interfaces.latte import volume - sage: P = 2 * polytopes.cube() - - Computing the volume of a polytope in either the H or V representation:: - - sage: volume(P.cdd_Hrepresentation(), cdd=True) # optional - latte_int - 64 - sage: volume(P.cdd_Vrepresentation(), cdd=True) # optional - latte_int - 64 - - TESTS: Testing triangulate algorithm:: sage: from sage.interfaces.latte import integrate sage: P = polytopes.cuboctahedron() sage: cddin = P.cdd_Vrepresentation() - sage: volume(cddin, algorithm='triangulate', cdd=True) # optional - latte_int + sage: integrate(cddin, algorithm='triangulate', cdd=True) # optional - latte_int 20/3 Testing convex decomposition algorithm:: @@ -351,7 +256,7 @@ def volume(arg, algorithm='triangulate', raw_output=False, verbose=False, **kwds sage: from sage.interfaces.latte import integrate sage: P = polytopes.cuboctahedron() sage: cddin = P.cdd_Vrepresentation() - sage: volume(cddin, algorithm='cone-decompose', cdd=True) # optional - latte_int + sage: integrate(cddin, algorithm='cone-decompose', cdd=True) # optional - latte_int 20/3 Testing raw output:: @@ -359,12 +264,15 @@ def volume(arg, algorithm='triangulate', raw_output=False, verbose=False, **kwds sage: from sage.interfaces.latte import integrate sage: P = polytopes.cuboctahedron() sage: cddin = P.cdd_Vrepresentation() - sage: volume(cddin, cdd=True, raw_output=True) # optional - latte_int + sage: integrate(cddin, cdd=True, raw_output=True) # optional - latte_int '20/3' - Testing the ``verbose`` option:: + Testing the ``verbose`` option to compute the volume of a polytope:: - sage: ans = volume(cddin, cdd=True, verbose=True, raw_output=True) # optional - latte_int + sage: from sage.interfaces.latte import integrate + sage: P = polytopes.cuboctahedron() + sage: cddin = P.cdd_Vrepresentation() + sage: ans = integrate(cddin, cdd=True, raw_output=True, verbose=True) # optional - latte_int This is LattE integrale ... ... Invocation: integrate --valuation=volume --triangulate --redundancy-check=none --cdd /dev/stdin @@ -375,7 +283,13 @@ def volume(arg, algorithm='triangulate', raw_output=False, verbose=False, **kwds from sage.rings.integer import Integer args = ['integrate'] - args.append('--valuation=volume') + + got_polynomial = True if polynomial is not None else False + + if got_polynomial: + args.append('--valuation=integrate') + else: + args.append('--valuation=volume') if algorithm=='triangulate': args.append('--triangulate') @@ -395,6 +309,18 @@ def volume(arg, algorithm='triangulate', raw_output=False, verbose=False, **kwds else: args.append('--{}={}'.format(key, value)) + if got_polynomial: + # transform polynomial to LattE description + monomials_list = _to_latte_polynomial(polynomial) + + # write the polynomial description to a temp file + from sage.misc.temporary_file import tmp_filename + filename_polynomial = tmp_filename() + + with open(filename_polynomial, 'w') as f: + f.write(monomials_list) + args += ['--monomials=' + filename_polynomial] + args += ['/dev/stdin'] try: @@ -418,7 +344,6 @@ def volume(arg, algorithm='triangulate', raw_output=False, verbose=False, **kwds raise RuntimeError("LattE integrale program failed (exit code {})".format(ret_code) + err.strip()) ans = ans.splitlines() - ans = ans[-5].split() assert(ans[0]=='Answer:') ans = ans[1] @@ -428,3 +353,15 @@ def volume(arg, algorithm='triangulate', raw_output=False, verbose=False, **kwds else: from sage.rings.rational import Rational return Rational(ans) + +def _to_latte_polynomial(polynomial): + # Helper function to transform a polynomial to its LattE description + coefficients_list = polynomial.coefficients() + exponents_list = [list(exponent_vector_i) for exponent_vector_i in polynomial.exponents()] + + # assuming that the order in coefficients() and exponents() methods match + monomials_list = zip(coefficients_list, exponents_list) + monomials_list = [list(monomial_i) for monomial_i in monomials_list] + monomials_list = str(monomials_list) + + return monomials_list From 5aa669584a92f474fc1a797a3caad9c03c92d6cc Mon Sep 17 00:00:00 2001 From: Marcelo Forets Date: Tue, 7 Mar 2017 01:20:57 +0100 Subject: [PATCH 086/185] Added test for helper function _to_latte_polynomial. --- src/sage/interfaces/latte.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/sage/interfaces/latte.py b/src/sage/interfaces/latte.py index 01870f53c28..15f98dc8d8a 100644 --- a/src/sage/interfaces/latte.py +++ b/src/sage/interfaces/latte.py @@ -355,7 +355,28 @@ def integrate(arg, polynomial=None, algorithm='triangulate', raw_output=False, v return Rational(ans) def _to_latte_polynomial(polynomial): - # Helper function to transform a polynomial to its LattE description + r""" + Helper function to transform a polynomial to its LattE description. + + INPUT: + + - ``polynomial`` -- a multivariate polynomial. + + OUTPUT: + + A string that describes the monomials list and exponent vectors. + + TESTS: + + Testing a polynomial in three variables:: + + sage: from sage.interfaces.latte import _to_latte_polynomial + sage: x, y, z = polygen(QQ, 'x, y, z') + sage: f = 3*x^2*y^4*z^6 + 7*y^3*z^5 + sage: _to_latte_polynomial(f) # optional - latte_int + '[[3, [2, 4, 6]], [7, [0, 3, 5]]]' + """ + coefficients_list = polynomial.coefficients() exponents_list = [list(exponent_vector_i) for exponent_vector_i in polynomial.exponents()] From 72d03a12c6fc8b02e67a97d61538ca47c3996c3e Mon Sep 17 00:00:00 2001 From: Marcelo Forets Date: Tue, 7 Mar 2017 02:37:42 +0100 Subject: [PATCH 087/185] Minor changes to helper function and integrate. * Removed the underscore in to_latte_polynomial because it may be useful to other programs. * Added possibility to input the polynomial in any valid LattE description, just as a sring. * Doctests have been added. --- src/sage/interfaces/latte.py | 43 ++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/src/sage/interfaces/latte.py b/src/sage/interfaces/latte.py index 15f98dc8d8a..e609361cd9d 100644 --- a/src/sage/interfaces/latte.py +++ b/src/sage/interfaces/latte.py @@ -11,6 +11,8 @@ # http://www.gnu.org/licenses/ #***************************************************************************** +import six + def count(arg, ehrhart_polynomial=False, multivariate_generating_function=False, raw_output=False, verbose=False, **kwds): r""" Call to the program count from LattE integrale @@ -187,17 +189,20 @@ def integrate(arg, polynomial=None, algorithm='triangulate', raw_output=False, v - ``arg`` -- a cdd or LattE description string - - ``polynomial`` -- polynomial that is integrated over the polytope. - If None, the volume of the polytope is computed. + - ``polynomial`` -- if given, the valuation paraameter of LattE's + Integrate a polynomial over a polytope. Otherwise, the valuation is set + to volume. - - ``algorithm`` -- (default: 'triangulate') the integration method. Use 'triangulate' for polytope triangulation - or 'cone-decompose' for tangent cone decomposition method. + - ``algorithm`` -- (default: 'triangulate') the integration method. Use + 'triangulate' for polytope triangulation or 'cone-decompose' for tangent + cone decomposition method. - - ``raw_output`` -- if ``True`` then return directly the output string from LattE + - ``raw_output`` -- if ``True`` then return directly the output string from + LattE - ``verbose`` -- if ``True`` then return directly verbose output from LattE - - For all other options of the count program, consult the LattE manual + - For all other options of the integrate program, consult the LattE manual. OUTPUT: @@ -223,6 +228,11 @@ def integrate(arg, polynomial=None, algorithm='triangulate', raw_output=False, v sage: integrate(P.cdd_Vrepresentation(), cdd=True) # optional - latte_int 64 + Polynomials given as a string in LattE description are also accepted: + + sage: integrate(P.cdd_Hrepresentation(), ```[1,[2,2,2]]```, cdd=True) # optional - latte_int + 4096/27 + TESTS: Testing raw output:: @@ -267,6 +277,13 @@ def integrate(arg, polynomial=None, algorithm='triangulate', raw_output=False, v sage: integrate(cddin, cdd=True, raw_output=True) # optional - latte_int '20/3' + Testing polynomial given as a string in LattE description:: + + sage: from sage.interfaces.latte import integrate + sage: P = polytopes.cuboctahedron() + sage: 629/47775 #integrate(P.cdd_Hrepresentation(), ```[[3,[2,4,6]],[7,[0, 3, 5]]]```, cdd=True) # optional - latte_int + 629/47775 + Testing the ``verbose`` option to compute the volume of a polytope:: sage: from sage.interfaces.latte import integrate @@ -310,10 +327,12 @@ def integrate(arg, polynomial=None, algorithm='triangulate', raw_output=False, v args.append('--{}={}'.format(key, value)) if got_polynomial: - # transform polynomial to LattE description - monomials_list = _to_latte_polynomial(polynomial) + if not isinstance(polynomial, six.string_types): + # transform polynomial to LattE description + monomials_list = to_latte_polynomial(polynomial) + else: + monomials_list = str(polynomial) - # write the polynomial description to a temp file from sage.misc.temporary_file import tmp_filename filename_polynomial = tmp_filename() @@ -354,7 +373,7 @@ def integrate(arg, polynomial=None, algorithm='triangulate', raw_output=False, v from sage.rings.rational import Rational return Rational(ans) -def _to_latte_polynomial(polynomial): +def to_latte_polynomial(polynomial): r""" Helper function to transform a polynomial to its LattE description. @@ -370,10 +389,10 @@ def _to_latte_polynomial(polynomial): Testing a polynomial in three variables:: - sage: from sage.interfaces.latte import _to_latte_polynomial + sage: from sage.interfaces.latte import to_latte_polynomial sage: x, y, z = polygen(QQ, 'x, y, z') sage: f = 3*x^2*y^4*z^6 + 7*y^3*z^5 - sage: _to_latte_polynomial(f) # optional - latte_int + sage: to_latte_polynomial(f) '[[3, [2, 4, 6]], [7, [0, 3, 5]]]' """ From 16648a857b2e1366e2cab37c6f30b9d48da58474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Philippe=20Labb=C3=A9?= Date: Tue, 7 Mar 2017 11:55:17 +0100 Subject: [PATCH 088/185] Added examples and fixed import --- src/sage/geometry/polyhedron/base.py | 74 ++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index 5e68649aa2a..567f91a4049 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -463,7 +463,7 @@ def _is_subpolyhedron(self, other): for self_V in self.Vrepresentation()) def plot(self, - point=None, line=None, polygon=None, # None means unspecified by the user + point=None, line=None, polygon=None, # None means unspecified by the user wireframe='blue', fill='green', projection_direction=None, **kwds): @@ -1553,9 +1553,9 @@ def vertices_matrix(self, base_ring=None): if base_ring is None: base_ring = self.base_ring() m = matrix(base_ring, self.ambient_dim(), self.n_vertices()) - for i,v in enumerate(self.vertices()): + for i, v in enumerate(self.vertices()): for j in range(self.ambient_dim()): - m[j,i] = v[j] + m[j, i] = v[j] return m def ray_generator(self): @@ -2282,10 +2282,44 @@ def normal_fan(self): :meth:`~sage.geometry.polyhedron.base.face_fan`. + EXAMPLES:: + + sage: S = Polyhedron(vertices = [[0, 0], [1, 0], [0, 1]]) + sage: S.normal_fan() + Rational polyhedral fan in 2-d lattice N + + sage: C = polytopes.hypercube(4) + sage: NF = C.normal_fan(); NF + Rational polyhedral fan in 4-d lattice N + + 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.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.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))]]) + sage: R.normal_fan() + Traceback (most recent call last): + ... + NotImplementedError: normal fan handles only polytopes over the rationals + REFERENCES: For more information, see Chapter 7 of [Zie2007]_. """ + from sage.geometry.fan import NormalFan + + if not QQ.has_coerce_map_from(self.base_ring()): + raise NotImplementedError('normal fan handles only polytopes over the rationals') return NormalFan(self) @@ -2298,15 +2332,47 @@ def face_fan(self): A complete fan of the ambient space as a :class:`~sage.geometry.fan.RationalPolyhedralFan`. - + .. SEEALSO:: :meth:`~sage.geometry.polyhedron.base.normal_fan`. + EXAMPLES:: + + sage: T = polytopes.cuboctahedron() + sage: T.face_fan() + Rational polyhedral fan in 3-d lattice M + + The polytope should contain the origin in the interior:: + + 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! + + sage: Q = Polyhedron(vertices = [[-1, 1/2], [1, -1/2]]) + sage: Q.contains([0,0]) + True + sage: FF = Q.face_fan(); FF + Rational polyhedral fan in 2-d lattice M + + The polytope has to have rational coordinates:: + + sage: S = polytopes.dodecahedron() + sage: S.face_fan() + Traceback (most recent call last): + ... + NotImplementedError: face fan handles only polytopes over the rationals + REFERENCES: For more information, see Chapter 7 of [Zie2007]_. """ + from sage.geometry.fan import FaceFan + + if not QQ.has_coerce_map_from(self.base_ring()): + raise NotImplementedError('face fan handles only polytopes over the rationals') return FaceFan(self) From b5c49e6ec798b08ad4a9659791d7d80433919518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Philippe=20Labb=C3=A9?= Date: Tue, 7 Mar 2017 12:07:42 +0100 Subject: [PATCH 089/185] Corrected doc of face_fan --- src/sage/geometry/polyhedron/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index 567f91a4049..a50f58d75bf 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -2326,11 +2326,11 @@ def normal_fan(self): @cached_method def face_fan(self): r""" - Return the face fan of a compact full-dimensional rational polyhedron. + Return the face fan of a compact rational polyhedron. OUTPUT: - A complete fan of the ambient space as a + A fan of the ambient space as a :class:`~sage.geometry.fan.RationalPolyhedralFan`. .. SEEALSO:: From 6a474f92580914f1cf42595fd8ee7b882b244b5d Mon Sep 17 00:00:00 2001 From: Marcelo Forets Date: Tue, 7 Mar 2017 19:55:18 +0100 Subject: [PATCH 090/185] fixed a typo in the docstring --- src/sage/interfaces/latte.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/interfaces/latte.py b/src/sage/interfaces/latte.py index e609361cd9d..93052a9bf67 100644 --- a/src/sage/interfaces/latte.py +++ b/src/sage/interfaces/latte.py @@ -189,9 +189,9 @@ def integrate(arg, polynomial=None, algorithm='triangulate', raw_output=False, v - ``arg`` -- a cdd or LattE description string - - ``polynomial`` -- if given, the valuation paraameter of LattE's - Integrate a polynomial over a polytope. Otherwise, the valuation is set - to volume. + - ``polynomial`` -- multivariate polynomial or valid LattE polynomial + description string. If given, the valuation parameter of LattE is set + to integrate, and is set to volume otherwise. - ``algorithm`` -- (default: 'triangulate') the integration method. Use 'triangulate' for polytope triangulation or 'cone-decompose' for tangent @@ -230,7 +230,7 @@ def integrate(arg, polynomial=None, algorithm='triangulate', raw_output=False, v Polynomials given as a string in LattE description are also accepted: - sage: integrate(P.cdd_Hrepresentation(), ```[1,[2,2,2]]```, cdd=True) # optional - latte_int + sage: integrate(P.cdd_Hrepresentation(), ``[1,[2,2,2]]``, cdd=True) # optional - latte_int 4096/27 TESTS: @@ -281,7 +281,7 @@ def integrate(arg, polynomial=None, algorithm='triangulate', raw_output=False, v sage: from sage.interfaces.latte import integrate sage: P = polytopes.cuboctahedron() - sage: 629/47775 #integrate(P.cdd_Hrepresentation(), ```[[3,[2,4,6]],[7,[0, 3, 5]]]```, cdd=True) # optional - latte_int + sage: integrate(P.cdd_Hrepresentation(), '[[3,[2,4,6]],[7,[0, 3, 5]]]', cdd=True) # optional - latte_int 629/47775 Testing the ``verbose`` option to compute the volume of a polytope:: From af7a2a10f0a35af56bb644b94a95992138a1e939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 7 Mar 2017 22:41:43 +0100 Subject: [PATCH 091/185] py3: get rid of a few cmp() in py files --- src/sage/categories/finite_posets.py | 4 ++-- src/sage/finance/stock.py | 32 ++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/sage/categories/finite_posets.py b/src/sage/categories/finite_posets.py index 27355b8de2b..c18c7ce8769 100644 --- a/src/sage/categories/finite_posets.py +++ b/src/sage/categories/finite_posets.py @@ -1736,9 +1736,9 @@ def order_ideals_lattice(self, as_ideals=True, facade=None): @cached_function def is_above(a, xb): return any(self.is_lequal(xa, xb) for xa in a) - def cmp(a, b): + def compare(a, b): return all(is_above(a, xb) for xb in b) - return LatticePoset((antichains, cmp), facade=facade) + return LatticePoset((antichains, compare), facade=facade) @abstract_method(optional = True) def antichains(self): diff --git a/src/sage/finance/stock.py b/src/sage/finance/stock.py index 0ab793fb8e2..67a1c29be8a 100644 --- a/src/sage/finance/stock.py +++ b/src/sage/finance/stock.py @@ -76,7 +76,7 @@ def __repr__(self): return '%10s %4.2f %4.2f %4.2f %4.2f %10d'%(self.timestamp, self.open, self.high, self.low, self.close, self.volume) - def __cmp__(self, other): + def __eq__(self, other): """ Compare ``self`` and ``other``. @@ -84,13 +84,31 @@ def __cmp__(self, other): sage: ohlc = sage.finance.stock.OHLC('18-Aug-04', 100.01, 104.06, 95.96, 100.34, 22353092) sage: ohlc2 = sage.finance.stock.OHLC('18-Aug-04', 101.01, 104.06, 95.96, 100.34, 22353092) - sage: cmp(ohlc, ohlc2) - -1 + sage: ohlc == ohlc2 + False """ if not isinstance(other, OHLC): - return cmp(type(self), type(other)) - return cmp((self.timestamp, self.open, self.high, self.low, self.close, self.volume), - (other.timestamp, other.open, other.high, other.low, other.close, other.volume)) + return False + return (self.timestamp == other.timestamp and + self.open == other.open and + self.high == other.high and + self.low == other.low and + self.close == other.close and + self.volume == other.volume) + + def __ne__(self, other): + """ + Compare ``self`` and ``other``. + + EXAMPLES:: + + sage: ohlc = sage.finance.stock.OHLC('18-Aug-04', 100.01, 104.06, 95.96, 100.34, 22353092) + sage: ohlc2 = sage.finance.stock.OHLC('18-Aug-04', 101.01, 104.06, 95.96, 100.34, 22353092) + sage: ohlc != ohlc2 + True + """ + return not (self == other) + class Stock: """ @@ -155,7 +173,7 @@ def current_price_data(self): r""" Get Yahoo current price data for this stock. - This method returns a dictionary wit the following keys: + This method returns a dictionary with the following keys: .. csv-table:: From b211ac9de009963b683f5368373d8d93134797a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 8 Mar 2017 17:49:23 +0100 Subject: [PATCH 092/185] trac 22545 another cmp removal --- src/sage/finance/markov_multifractal.py | 41 ++++++++++++++++++------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/sage/finance/markov_multifractal.py b/src/sage/finance/markov_multifractal.py index 508726d683a..a664674c52d 100644 --- a/src/sage/finance/markov_multifractal.py +++ b/src/sage/finance/markov_multifractal.py @@ -54,28 +54,47 @@ def __init__(self, kbar, m0, sigma, gamma_kbar, b): self.__kbar = int(kbar) assert self.__kbar > 0, "kbar must be positive" - def __cmp__(self, other): + def __eq__(self, other): """ - Compare ``self`` and ``other``. + Test equality of ``self`` and ``other``. Comparison is done on the tuple ``(m0, sigma, b, gamma_kbar, kbar)``. EXAMPLES:: sage: msm = finance.MarkovSwitchingMultifractal(8,1.4,1.0,0.95,3) - sage: msm.__cmp__(3) # random - depends on memory layout - -1 - sage: msm.__cmp__(msm) - 0 + + sage: msm == msm + True sage: cad_usd = finance.MarkovSwitchingMultifractal(10,1.278,0.262,0.644,2.11); cad_usd Markov switching multifractal model with m0 = 1.278, sigma = 0.262, b = 2.11, and gamma_10 = 0.644 - sage: msm.__cmp__(cad_usd) - 1 + sage: msm == cad_usd + False """ if not isinstance(other, MarkovSwitchingMultifractal): - return cmp(type(self), type(other)) - return cmp((self.__m0, self.__sigma, self.__b, self.__gamma_kbar, self.__kbar), - (other.__m0, other.__sigma, other.__b, other.__gamma_kbar, other.__kbar)) + return False + return (self.__m0 == other.__m0 and + self.__sigma == other.__sigma and + self.__b == other.__b and + self.__gamma_kbar == other.__gamma_kbar and + self.__kbar == other.__kbar) + + def __ne__(self, other): + """ + Test inequality of ``self`` and ``other``. + + EXAMPLES:: + + sage: msm = finance.MarkovSwitchingMultifractal(8,1.4,1.0,0.95,3) + + sage: msm != msm + False + sage: cad_usd = finance.MarkovSwitchingMultifractal(10,1.278,0.262,0.644,2.11); cad_usd + Markov switching multifractal model with m0 = 1.278, sigma = 0.262, b = 2.11, and gamma_10 = 0.644 + sage: msm != cad_usd + True + """ + return not (self == other) def __repr__(self): """ From 4376fa7a03b1ceacd9a4d4b29dd5b1ef2e279503 Mon Sep 17 00:00:00 2001 From: paulmasson Date: Wed, 8 Mar 2017 13:59:41 -0800 Subject: [PATCH 093/185] Additional comments --- src/doc/en/developer/git_trac.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/doc/en/developer/git_trac.rst b/src/doc/en/developer/git_trac.rst index 7e08b06351d..8fe86130741 100644 --- a/src/doc/en/developer/git_trac.rst +++ b/src/doc/en/developer/git_trac.rst @@ -551,18 +551,19 @@ to use the web interface: shows you what is being added, analogous to clicking on the "Branch:" field. -To review tickets with minimal recompiling, start on the "develop" branch, -that is, the latest beta. Just checking out an older ticket would most likely -reset the Sage tree to an older version, so you would have to compile older -versions of packages to make it work. Instead, you can create an anonymous +To review tickets with minimal recompiling, start by building the "develop" +branch, that is, the latest beta. Just checking out an older ticket would most +likely reset the Sage tree to an older version, so you would have to compile +older versions of packages to make it work. Instead, you can create an anonymous ("detached HEAD") merge of the ticket and the develop branch:: $ git trac try 12345 This will only touch files that are really modified by the ticket. In particular, if only Python files are changed by the ticket (which is true for most tickets) -then you just have to run ``sage -b`` to rebuild the Sage library. When you are -finished reviewing, just checkout a named branch, for example :: +then you just have to run ``sage -b`` to rebuild the Sage library. If files other +than Python have been changed, you must run ``make``. When you are finished +reviewing, just checkout a named branch, for example :: $ git checkout develop From 0c0c6034c220f2658cf8b6b1512e11720d956c1e Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 9 Mar 2017 12:01:04 +0100 Subject: [PATCH 094/185] Write custom create_extension() for Cython --- build/pkgs/cython/package-version.txt | 2 +- .../cython/patches/create_extension.patch | 229 ++++++++++++++++++ src/sage_setup/util.py | 31 +++ src/setup.py | 140 +++++++---- 4 files changed, 348 insertions(+), 54 deletions(-) create mode 100644 build/pkgs/cython/patches/create_extension.patch create mode 100644 src/sage_setup/util.py diff --git a/build/pkgs/cython/package-version.txt b/build/pkgs/cython/package-version.txt index 166c9e29b70..3c8f135cf6d 100644 --- a/build/pkgs/cython/package-version.txt +++ b/build/pkgs/cython/package-version.txt @@ -1 +1 @@ -0.25.2 +0.25.2.p0 diff --git a/build/pkgs/cython/patches/create_extension.patch b/build/pkgs/cython/patches/create_extension.patch new file mode 100644 index 00000000000..0bf5fc91f63 --- /dev/null +++ b/build/pkgs/cython/patches/create_extension.patch @@ -0,0 +1,229 @@ +commit 9797efe065d50638b0cd19219e6b1f3f5edaddab +Author: Jeroen Demeyer +Date: Fri Nov 25 11:07:44 2016 +0100 + + Add support for create_extension() hook + +diff --git a/Cython/Build/Dependencies.py b/Cython/Build/Dependencies.py +index 6c2827d..aedbad3 100644 +--- a/Cython/Build/Dependencies.py ++++ b/Cython/Build/Dependencies.py +@@ -637,6 +637,20 @@ def create_dependency_tree(ctx=None, quiet=False): + return _dep_tree + + ++# If this changes, change also docs/src/reference/compilation.rst ++# which mentions this function ++def default_create_extension(template, kwds): ++ if 'depends' in kwds: ++ include_dirs = kwds.get('include_dirs', []) + ["."] ++ depends = resolve_depends(kwds['depends'], include_dirs) ++ kwds['depends'] = sorted(set(depends + template.depends)) ++ ++ t = template.__class__ ++ ext = t(**kwds) ++ metadata = dict(distutils=kwds, module_name=kwds['name']) ++ return (ext, metadata) ++ ++ + # This may be useful for advanced users? + def create_extension_list(patterns, exclude=None, ctx=None, aliases=None, quiet=False, language=None, + exclude_failures=False): +@@ -669,13 +683,16 @@ def create_extension_list(patterns, exclude=None, ctx=None, aliases=None, quiet= + Extension_distutils = Extension + class Extension_setuptools(Extension): pass + ++ # if no create_extension() function is defined, use a simple ++ # default function. ++ create_extension = ctx.options.create_extension or default_create_extension ++ + for pattern in patterns: + if isinstance(pattern, str): + filepattern = pattern +- template = None ++ template = Extension(pattern, []) # Fake Extension without sources + name = '*' + base = None +- exn_type = Extension + ext_language = language + elif isinstance(pattern, (Extension_distutils, Extension_setuptools)): + cython_sources = [s for s in pattern.sources +@@ -693,7 +710,6 @@ def create_extension_list(patterns, exclude=None, ctx=None, aliases=None, quiet= + template = pattern + name = template.name + base = DistutilsInfo(exn=template) +- exn_type = template.__class__ + ext_language = None # do not override whatever the Extension says + else: + msg = str("pattern is not of type str nor subclass of Extension (%s)" +@@ -727,39 +743,29 @@ def create_extension_list(patterns, exclude=None, ctx=None, aliases=None, quiet= + if key not in kwds: + kwds[key] = value + ++ kwds['name'] = module_name ++ + sources = [file] +- if template is not None: +- sources += [m for m in template.sources if m != filepattern] ++ sources += [m for m in template.sources if m != filepattern] + if 'sources' in kwds: + # allow users to add .c files etc. + for source in kwds['sources']: + source = encode_filename_in_py2(source) + if source not in sources: + sources.append(source) +- extra_sources = kwds['sources'] +- del kwds['sources'] +- else: +- extra_sources = None +- if 'depends' in kwds: +- depends = resolve_depends(kwds['depends'], (kwds.get('include_dirs') or []) + ["."]) +- if template is not None: +- # Always include everything from the template. +- depends = set(template.depends).union(depends) +- # Sort depends to make the metadata dump in the +- # Cython-generated C code predictable. +- kwds['depends'] = sorted(depends) ++ kwds['sources'] = sources + + if ext_language and 'language' not in kwds: + kwds['language'] = ext_language + +- module_list.append(exn_type( +- name=module_name, +- sources=sources, +- **kwds)) +- if extra_sources: +- kwds['sources'] = extra_sources +- module_metadata[module_name] = {'distutils': kwds, 'module_name': module_name} +- m = module_list[-1] ++ # Create the new extension ++ m, metadata = create_extension(template, kwds) ++ module_list.append(m) ++ ++ # Store metadata (this will be written as JSON in the ++ # generated C file but otherwise has no purpose) ++ module_metadata[module_name] = metadata ++ + if file not in m.sources: + # Old setuptools unconditionally replaces .pyx with .c + m.sources.remove(file.rsplit('.')[0] + '.c') +diff --git a/Cython/Compiler/Main.py b/Cython/Compiler/Main.py +index 3ba87d1..7ecd015 100644 +--- a/Cython/Compiler/Main.py ++++ b/Cython/Compiler/Main.py +@@ -753,4 +753,5 @@ default_options = dict( + output_dir=None, + build_dir=None, + cache=None, ++ create_extension=None, + ) +diff --git a/docs/src/reference/compilation.rst b/docs/src/reference/compilation.rst +index 06fce5d..5318cb5 100644 +--- a/docs/src/reference/compilation.rst ++++ b/docs/src/reference/compilation.rst +@@ -126,11 +126,15 @@ both might disagree about the class to use here. + + If your options are static (for example you do not need to call a tool like + ``pkg-config`` to determine them) you can also provide them directly in your +-.pyx source file using a special comment block at the start of the file:: ++.pyx or .pxd source file using a special comment block at the start of the file:: + + # distutils: libraries = spam eggs + # distutils: include_dirs = /opt/food/include + ++If you cimport multiple .pxd files defining libraries, then Cython ++merges the list of libraries, so this works as expected (similarly ++with other options, like ``include_dirs`` above). ++ + If you have some C files that have been wrapped with Cython and you want to + compile them into your extension, you can define the distutils ``sources`` + parameter:: +@@ -160,6 +164,57 @@ to find the ``.h`` and library files when linking to external libraries. + + .. _distutils documentation: http://docs.python.org/extending/building.html + ++Sometimes this is not enough and you need finer customization of the ++distutils :class:`Extension`. ++To do this, you can provide a custom function ``create_extension`` ++to create the final :class:`Extension` object after Cython has processed ++the sources, dependencies and ``# distutils`` directives but before the ++file is actually Cythonized. ++This function takes 2 arguments ``template`` and ``kwds``, where ++``template`` is the :class:`Extension` object given as input to Cython ++and ``kwds`` is a :class:`dict` with all keywords which should be used ++to create the :class:`Extension`. ++The function ``create_extension`` must return a 2-tuple ++``(extension, metadata)``, where ``extension`` is the created ++:class:`Extension` and ``metadata`` is metadata which will be written ++as JSON at the top of the generated C files. This metadata is only used ++for debugging purposes, so you can put whatever you want in there ++(as long as it can be converted to JSON). ++The default function (defined in ``Cython.Build.Dependencies``) is:: ++ ++ def default_create_extension(template, kwds): ++ if 'depends' in kwds: ++ include_dirs = kwds.get('include_dirs', []) + ["."] ++ depends = resolve_depends(kwds['depends'], include_dirs) ++ kwds['depends'] = sorted(set(depends + template.depends)) ++ ++ t = template.__class__ ++ ext = t(**kwds) ++ metadata = dict(distutils=kwds, module_name=kwds['name']) ++ return (ext, metadata) ++ ++In case that you pass a string instead of an :class:`Extension` to ++``cythonize()``, the ``template`` will be an :class:`Extension` without ++sources. For example, if you do ``cythonize("*.pyx")``, ++the ``template`` will be ``Extension(name="*.pyx", sources=[])``. ++ ++Just as an example, this adds ``mylib`` as library to every extension:: ++ ++ from Cython.Build.Dependencies import default_create_extension ++ ++ def my_create_extension(template, kwds): ++ libs = kwds.get('libraries', []) + ["mylib"] ++ kwds['libraries'] = libs ++ return default_create_extension(template, kwds) ++ ++ ext_modules = cythonize(..., create_extension=my_create_extension) ++ ++.. note:: ++ ++ If you Cythonize in parallel (using the ``nthreads`` argument), ++ then the argument to ``create_extension`` must be pickleable. ++ In particular, it cannot be a lambda function. ++ + + Distributing Cython modules + ---------------------------- +diff --git a/tests/compile/create_extension.srctree b/tests/compile/create_extension.srctree +new file mode 100644 +index 0000000..17851ad +--- /dev/null ++++ b/tests/compile/create_extension.srctree +@@ -0,0 +1,24 @@ ++PYTHON setup.py build_ext --inplace ++ ++######## setup.py ######## ++ ++from Cython.Build import cythonize ++from Cython.Distutils.extension import Extension ++ ++ext_modules = [ ++ Extension("foo", ["foo.pyx"]), ++] ++ ++# Example documented in docs/src/reference/compilation.rst ++from Cython.Build.Dependencies import default_create_extension ++ ++def my_create_extension(template, kwds): ++ libs = kwds.get('libraries', []) + ["mylib"] ++ kwds['libraries'] = libs ++ return default_create_extension(template, kwds) ++ ++ext_modules = cythonize(ext_modules, create_extension=my_create_extension) ++ ++assert ext_modules[0].libraries == ["mylib"] ++ ++######## foo.pyx ######## diff --git a/src/sage_setup/util.py b/src/sage_setup/util.py new file mode 100644 index 00000000000..90012aad4c2 --- /dev/null +++ b/src/sage_setup/util.py @@ -0,0 +1,31 @@ +r""" +Utility functions for building Sage +""" + +#***************************************************************************** +# Copyright (C) 2017 Jeroen Demeyer +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +def stable_uniq(L): + """ + Given an iterable L, remove duplicate items from L by keeping only + the last occurance of any item. + + The items must be hashable. + + EXAMPLES:: + + sage: from sage_setup.util import stable_uniq + sage: stable_uniq( (1, 2, 3, 4, 5, 6, 3, 7, 5, 1, 5, 9) ) + [2, 4, 6, 3, 7, 1, 5, 9] + """ + D = {} + for pos, item in enumerate(L): + D[item] = pos # Store the last position where an item appears + return sorted(D, key=lambda item: D[item]) diff --git a/src/setup.py b/src/setup.py index 4d20a0f0274..0bb2aa266f2 100755 --- a/src/setup.py +++ b/src/setup.py @@ -84,6 +84,9 @@ def excepthook(*exc): # this depends on SAGE_CYTHONIZED include_dirs = sage_include_directories(use_sources=True) +# Look for libraries in $SAGE_LOCAL/lib +library_dirs = [os.path.join(SAGE_LOCAL, "lib")] + # Manually add -fno-strict-aliasing, which is needed to compile Cython # and disappears from the default flags if the user has set CFLAGS. extra_compile_args = [ "-fno-strict-aliasing" ] @@ -163,12 +166,14 @@ def __call__(self, *args): os.unlink(sage.misc.lazy_import_cache.get_cache_file()) -###################################################################### -# CODE for generating C/C++ code from Cython and doing dependency -# checking, etc. In theory distutils would run Cython, but I don't -# trust it at all, and it won't have the more sophisticated dependency -# checking that we need. -###################################################################### +######################################################################## +## +## Customize the Extensions processed by Cython +## +######################################################################## + +from Cython.Build.Dependencies import default_create_extension +from sage_setup.util import stable_uniq # Do not put all, but only the most common libraries and their headers # (that are likely to change on an upgrade) here: @@ -179,30 +184,85 @@ def __call__(self, *args): "ntl": [ os.path.join(SAGE_INC, 'NTL', 'config.h') ] } -# In the loop below, don't append to any list, since many of these -# lists are actually identical Python objects. For every list, we need -# to write (at least the first time): -# -# list = list + [foo] -# -for m in ext_modules: - # Make everything depend on *this* setup.py file - m.depends = m.depends + [__file__] - # Add dependencies for the libraries - for lib in lib_headers: - if lib in m.libraries: - m.depends += lib_headers[lib] +def sage_create_extension(template, kwds): + """ + Create a distutils Extension given data from Cython + + This adjust the ``kwds`` in the following ways: + + - Make everything depend on *this* setup.py file + + - Add dependencies on header files for certain libraries + + - Ensure that C++ extensions link with -lstdc++ + + - Sort the libraries according to the library order + + - Add some default compile/link args and directories - m.extra_compile_args = m.extra_compile_args + extra_compile_args - m.extra_link_args = m.extra_link_args + extra_link_args - m.library_dirs = m.library_dirs + [os.path.join(SAGE_LOCAL, "lib")] - m.include_dirs = m.include_dirs + include_dirs + - Drop -std=c99 and similar from C++ extensions + + - Ensure that each flag, library, ... is listed at most once + """ + lang = kwds.get('language', 'c') + + # Libraries: add stdc++ if needed and sort them + libs = kwds.get('libraries', []) + if lang == 'c++': + libs = libs + ['stdc++'] + kwds['libraries'] = sorted(set(libs), + key=lambda lib: library_order.get(lib, 0)) + + # Dependencies: add setup.py and lib_headers + depends = kwds.get('depends', []) + [__file__] + for lib, headers in lib_headers.items(): + if lib in libs: + depends += headers + kwds['depends'] = depends # These are sorted and uniq'ed by Cython + + # Process extra_compile_args + cflags = [] + for flag in kwds.get('extra_compile_args', []): + if lang == "c++": + if flag.startswith("-std=") and "++" not in flag: + continue # Skip -std=c99 and similar for C++ + cflags.append(flag) + cflags = extra_compile_args + cflags + kwds['extra_compile_args'] = stable_uniq(cflags) + + # Process extra_link_args + ldflags = kwds.get('extra_link_args', []) + extra_link_args + kwds['extra_link_args'] = stable_uniq(ldflags) + + # Process library_dirs + lib_dirs = kwds.get('library_dirs', []) + library_dirs + kwds['library_dirs'] = stable_uniq(lib_dirs) + + # Process include_dirs + inc_dirs = kwds.get('include_dirs', []) + include_dirs + kwds['include_dirs'] = stable_uniq(inc_dirs) + + return default_create_extension(template, kwds) -############################################# -###### Parallel Cython execution -############################################# +######################################################################## +## +## Parallel gcc execution +## +## This code is responsible for making distutils dispatch the calls to +## build_ext in parallel. Since distutils doesn't seem to do this by +## default, we create our own extension builder and override the +## appropriate methods. Unfortunately, in distutils, the logic of +## deciding whether an extension needs to be recompiled and actually +## making the call to gcc to recompile the extension are in the same +## function. As a result, we can't just override one function and have +## everything magically work. Instead, we split this work between two +## functions. This works fine for our application, but it means that +## we can't use this modification to make the other parts of Sage that +## build with distutils call gcc in parallel. +## +######################################################################## def run_command(cmd): """ @@ -317,24 +377,6 @@ def plural(n,noun): print("Time to execute %s: %.2f seconds."%(plural(len(command_list),"command"), time.time() - t)) -######################################################################## -## -## Parallel gcc execution -## -## This code is responsible for making distutils dispatch the calls to -## build_ext in parallel. Since distutils doesn't seem to do this by -## default, we create our own extension builder and override the -## appropriate methods. Unfortunately, in distutils, the logic of -## deciding whether an extension needs to be recompiled and actually -## making the call to gcc to recompile the extension are in the same -## function. As a result, we can't just override one function and have -## everything magically work. Instead, we split this work between two -## functions. This works fine for our application, but it means that -## we can't use this modification to make the other parts of Sage that -## build with distutils call gcc in parallel. -## -######################################################################## - class sage_build_ext(build_ext): def finalize_options(self): build_ext.finalize_options(self) @@ -409,6 +451,7 @@ def run_cython(self): 'fast_getattr': True, 'profile': profile, }, + create_extension=sage_create_extension, # Debugging gdb_debug=debug, output_dir=SAGE_CYTHONIZED, @@ -569,15 +612,6 @@ def prepare_extension(self, ext): log.info("building '%s' extension", ext.name) need_to_compile = True - # If we need to compile, adjust the given extension - if need_to_compile: - libs = ext.libraries - if ext.language == 'c++' and 'stdc++' not in libs: - libs = libs + ['stdc++'] - - # Sort libraries according to library_order - ext.libraries = sorted(libs, key=lambda x: library_order.get(x, 0)) - return need_to_compile, (sources, ext, ext_filename) def build_extension(self, p): From 96f814daca82e4dfe60a5638f3a54981ca434b5d Mon Sep 17 00:00:00 2001 From: Eric Gourgoulhon Date: Fri, 10 Mar 2017 09:08:43 +0100 Subject: [PATCH 095/185] Fix treatment of pullback on parallelizable manifolds --- src/sage/manifolds/differentiable/diff_map.py | 52 ++++++++++++------- src/sage/manifolds/differentiable/metric.py | 3 ++ .../differentiable/tensorfield_paral.py | 8 ++- 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/sage/manifolds/differentiable/diff_map.py b/src/sage/manifolds/differentiable/diff_map.py index 3b4bda8ba6e..956ebb57bba 100644 --- a/src/sage/manifolds/differentiable/diff_map.py +++ b/src/sage/manifolds/differentiable/diff_map.py @@ -564,7 +564,7 @@ def differential(self, point): From: Tangent space at Point p on the 2-dimensional differentiable manifold M To: Tangent space at Point Phi(p) on the 3-dimensional differentiable manifold N sage: latex(dPhip) - \mathrm{d}\Phi_{p} + {\mathrm{d}\Phi}_{p} sage: dPhip.parent() Set of Morphisms from Tangent space at Point p on the 2-dimensional differentiable manifold M to Tangent space at Point Phi(p) on the @@ -634,8 +634,8 @@ def differential(self, point): else: name = None if self._latex_name is not None and point._latex_name is not None: - latex_name = r'\mathrm{d}%s_{%s}'%(self._latex_name, - point._latex_name) + latex_name = r'{\mathrm{d}%s}_{%s}'%(self._latex_name, + point._latex_name) else: latex_name = None return tsp_source.hom(tsp_image, matrix, bases=bases, @@ -908,18 +908,30 @@ def pullback(self, tensor): from sage.tensor.modules.comp import (Components, CompWithSym, CompFullySym, CompFullyAntiSym) - def _pullback_paral(self, tensor): + def _pullback_chart(diff_map, tensor): r""" - Pullback on parallelizable domains. + Helper function performing the pullback on chart domains. + + INPUT: + + - ``diff_map`` -- a restriction of ``self``, whose both domain and + codomain are chart domains + - ``tensor`` -- a covariant tensor field, whose domain is the codomain + of ``diff_map`` + + OUTPUT: + + - the pull back of ``tensor`` by ``diff_map`` + """ - dom1 = self._domain - dom2 = self._codomain + dom1 = diff_map._domain + dom2 = diff_map._codomain ncov = tensor._tensor_type[1] resu_name = None ; resu_latex_name = None - if self._name is not None and tensor._name is not None: - resu_name = self._name + '_*(' + tensor._name + ')' - if self._latex_name is not None and tensor._latex_name is not None: - resu_latex_name = self._latex_name + '_*' + tensor._latex_name + if diff_map._name is not None and tensor._name is not None: + resu_name = diff_map._name + '_*(' + tensor._name + ')' + if diff_map._latex_name is not None and tensor._latex_name is not None: + resu_latex_name = diff_map._latex_name + '_*' + tensor._latex_name fmodule1 = dom1.vector_field_module() ring1 = fmodule1._ring si1 = fmodule1._sindex @@ -932,7 +944,8 @@ def _pullback_paral(self, tensor): if isinstance(frame2, CoordFrame): chart2 = frame2._chart for chart1 in dom1._atlas: - if (chart1, chart2) in self._coord_expression: + if (chart1._domain is dom1 and (chart1, chart2) in + diff_map._coord_expression): # Computation at the component level: frame1 = chart1._frame tcomp = tensor._components[frame2] @@ -954,7 +967,7 @@ def _pullback_paral(self, tensor): ptcomp = Components(ring1, frame1, ncov, start_index=si1, output_formatter=of1) - phi = self._coord_expression[(chart1, chart2)] + phi = diff_map._coord_expression[(chart1, chart2)] jacob = phi.jacobian() # X2 coordinates expressed in terms of X1 ones via the # mapping: @@ -1010,7 +1023,7 @@ def _pullback_paral(self, tensor): else: # Case of tensor field of rank >= 1 if tensor._vmodule._dest_map is not tdom.identity_map(): - raise TypeError("the pullback in defined only for tensor " + + raise TypeError("the pullback is defined only for tensor " + "fields on {}".format(dom2)) resu_rst = [] for chart_pair in self._coord_expression: @@ -1019,7 +1032,7 @@ def _pullback_paral(self, tensor): if ch2dom.is_subset(tdom): self_r = self.restrict(chart1._domain, subcodomain=ch2dom) tensor_r = tensor.restrict(ch2dom) - resu_rst.append(_pullback_paral(self_r, tensor_r)) + resu_rst.append(_pullback_chart(self_r, tensor_r)) dom_resu = resu_rst[0]._domain for rst in resu_rst[1:]: dom_resu = dom_resu.union(rst._domain) @@ -1032,8 +1045,9 @@ def _pullback_paral(self, tensor): resu._restrictions[rst._domain] = rst if isinstance(resu, TensorFieldParal): for rst in resu_rst: - for frame, comp in rst._components.items(): - resu._components[frame] = comp + if rst._domain is resu._domain: + for frame, comp in rst._components.items(): + resu._components[frame] = comp return resu @@ -1105,8 +1119,8 @@ def pushforward(self, tensor): dom1 = tensor.domain() ambient_dom1 = dest_map.codomain() if not ambient_dom1.is_subset(self._domain): - raise ValueError("the {} does not take its values on the " + - "domain of the {}".format(tensor, self)) + raise ValueError("the {} does not take its ".format(tensor) + + "values on the domain of the {}".format(self)) (ncon, ncov) = tensor.tensor_type() if ncov != 0: raise ValueError("the pushforward cannot be taken on a tensor " + diff --git a/src/sage/manifolds/differentiable/metric.py b/src/sage/manifolds/differentiable/metric.py index c687d4e6ec6..9e859d91464 100644 --- a/src/sage/manifolds/differentiable/metric.py +++ b/src/sage/manifolds/differentiable/metric.py @@ -2165,6 +2165,9 @@ def set(self, symbiform): self._components.clear() for frame in symbiform._components: self._components[frame] = symbiform._components[frame].copy() + for dom, symbiform_rst in symbiform._restrictions.items(): + rst = self.restrict(dom) + rst.set(symbiform_rst) def inverse(self): r""" diff --git a/src/sage/manifolds/differentiable/tensorfield_paral.py b/src/sage/manifolds/differentiable/tensorfield_paral.py index de4ecd2509c..27c60615adc 100644 --- a/src/sage/manifolds/differentiable/tensorfield_paral.py +++ b/src/sage/manifolds/differentiable/tensorfield_paral.py @@ -853,7 +853,13 @@ class :class:`~sage.tensor.modules.comp.Components`; if such if basis._domain == self._domain: # Adding components on the tensor field domain: - return FreeModuleTensor.add_comp(self, basis=basis) + # We perform a backup of the restrictions, since + # they are deleted by FreeModuleTensor.add_comp (which + # invokes del_derived()), and restore them afterwards + restrictions_save = self._restrictions.copy() + comp = FreeModuleTensor.add_comp(self, basis=basis) + self._restrictions = restrictions_save + return comp # Adding components on a subdomain: # From 0f4e30a902ffed54b0217e6d5bff9d5fe7d4e78b Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Fri, 10 Mar 2017 12:09:07 +0100 Subject: [PATCH 096/185] Implement __iter__ for PARI Gen --- src/sage/libs/cypari2/gen.pyx | 126 ++++++++++++++++++++++++++++++---- 1 file changed, 113 insertions(+), 13 deletions(-) diff --git a/src/sage/libs/cypari2/gen.pyx b/src/sage/libs/cypari2/gen.pyx index 8e3038f5afa..1cd83f9b92e 100644 --- a/src/sage/libs/cypari2/gen.pyx +++ b/src/sage/libs/cypari2/gen.pyx @@ -193,12 +193,105 @@ cdef class Gen(Gen_auto): sig_off() return h - def list(self): + def __iter__(self): """ - Convert self to a list of PARI gens. + Iterate over the components of ``self``. EXAMPLES: + We can iterate over PARI vectors or columns:: + + sage: L = pari("vector(10,i,i^2)") + sage: L.__iter__() + + sage: [x for x in L] + [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] + sage: list(L) + [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] + sage: list(pari("vector(10,i,i^2)~")) + [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] + + For polynomials, we iterate over the list of coefficients:: + + sage: pol = pari("x^3 + 5/3*x"); list(pol) + [0, 5/3, 0, 1] + + For power series or Laurent series, we get all coefficients starting + from the lowest degree term. This includes trailing zeros:: + + sage: list(pari('x^2 + O(x^8)')) + [1, 0, 0, 0, 0, 0] + sage: list(pari('x^-2 + O(x^0)')) + [1, 0] + + For matrices, we iterate over the columns:: + + sage: M = pari.matrix(3,2,[1,4,2,5,3,6]); M + [1, 4; 2, 5; 3, 6] + sage: list(M) + [[1, 2, 3]~, [4, 5, 6]~] + + Other types are first converted to a vector using :meth:`Vec`:: + + sage: Q = pari('Qfb(1, 2, 3)') + sage: tuple(Q) + (1, 2, 3) + sage: Q.Vec() + [1, 2, 3] + + We get an error for "scalar" types or for types which cannot be + converted to a PARI vector:: + + sage: iter(pari(42)) + Traceback (most recent call last): + ... + TypeError: PARI object of type 't_INT' is not iterable + sage: iter(pari("x->x")) + Traceback (most recent call last): + ... + PariError: incorrect type in gtovec (t_CLOSURE) + + TESTS: + + The following are deprecated:: + + sage: tuple(pari('3/5')) + doctest:...: DeprecationWarning: iterating a PARI 't_FRAC' is deprecated + (3, 5) + sage: tuple(pari('1 + 5*I')) + doctest:...: DeprecationWarning: iterating a PARI 't_COMPLEX' is deprecated + (1, 5) + """ + cdef long t = typ(self.g) + + # First convert self to a vector type + cdef Gen v + if t == t_VEC or t == t_COL or t == t_MAT: + # These are vector-like and can be iterated over directly + v = self + elif t == t_POL: + v = self.Vecrev() + elif t == t_FRAC or t == t_RFRAC or t == t_COMPLEX: + # Also treat as vector + # Deprecated, make this an error in the future + from warnings import warn + warn(f"iterating a PARI {self.type()!r} is deprecated", DeprecationWarning) + v = self + elif is_scalar_t(t): + raise TypeError(f"PARI object of type {self.type()!r} is not iterable") + else: + v = self.Vec() + + # Now iterate over the vector v + cdef long i + return (v.new_ref(gel(v.g, i)) for i in range(1, lg(v.g))) + + def list(self): + """ + Convert ``self`` to a Python list with :class:`Gen` components. + + EXAMPLES:: + A PARI vector becomes a Python list:: sage: L = pari("vector(10,i,i^2)").list() @@ -229,14 +322,21 @@ cdef class Gen(Gen_auto): sage: M.list() [[1, 2, 3]~, [4, 5, 6]~] - For "scalar" types, we get a 1-element list containing ``self``:: + TESTS: + + For "scalar" types, this is deprecated. Currently, we get a + 1-element list containing ``self``:: - sage: pari("42").list() + sage: pari(42).list() + doctest:...: DeprecationWarning: calling list() on scalar PARI types is deprecated [42] """ - if typ(self.g) == t_POL: - return list(self.Vecrev()) - return list(self.Vec()) + if is_scalar_t(typ(self.g)): + # Deprecated, make this an error in the future + from warnings import warn + warn("calling list() on scalar PARI types is deprecated", DeprecationWarning) + return [self] + return [x for x in self] def __reduce__(self): """ @@ -884,12 +984,12 @@ cdef class Gen(Gen_auto): 3 sage: type(sv[2]) <... 'int'> - sage: tuple(pari('3/5')) - (3, 5) - sage: tuple(pari('1 + 5*I')) - (1, 5) - sage: tuple(pari('Qfb(1, 2, 3)')) - (1, 2, 3) + sage: [pari('3/5')[i] for i in range(2)] + [3, 5] + sage: [pari('1 + 5*I')[i] for i in range(2)] + [1, 5] + sage: [pari('Qfb(1, 2, 3)')[i] for i in range(3)] + [1, 2, 3] sage: pari(57)[0] Traceback (most recent call last): ... From 67eb1d7e74c7eaa0bf640550cdf60160a7a893ef Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 10 Mar 2017 15:05:56 +0100 Subject: [PATCH 097/185] Change Polyhedron_ZZ to inherit from Polyhedron_QQ, not Polyhedron_base --- src/sage/geometry/polyhedron/base_ZZ.py | 68 +------------------------ 1 file changed, 2 insertions(+), 66 deletions(-) diff --git a/src/sage/geometry/polyhedron/base_ZZ.py b/src/sage/geometry/polyhedron/base_ZZ.py index fbfea81a047..7ce361d61c4 100644 --- a/src/sage/geometry/polyhedron/base_ZZ.py +++ b/src/sage/geometry/polyhedron/base_ZZ.py @@ -17,13 +17,14 @@ from sage.rings.all import ZZ, QQ from sage.misc.all import cached_method from sage.modules.free_module_element import vector +from .base_QQ import Polyhedron_QQ from sage.arith.all import gcd from .constructor import Polyhedron from .base import Polyhedron_base ######################################################################### -class Polyhedron_ZZ(Polyhedron_base): +class Polyhedron_ZZ(Polyhedron_QQ): """ Base class for Polyhedra over `\ZZ` @@ -33,71 +34,6 @@ class Polyhedron_ZZ(Polyhedron_base): A 0-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex sage: TestSuite(p).run(skip='_test_pickling') """ - def _is_zero(self, x): - """ - Test whether ``x`` is zero. - - INPUT: - - - ``x`` -- a number in the base ring. - - OUTPUT: - - Boolean. - - EXAMPLES:: - - sage: p = Polyhedron([(0,0)], base_ring=ZZ) - sage: p._is_zero(0) - True - sage: p._is_zero(1/100000) - False - """ - return x==0 - - def _is_nonneg(self, x): - """ - Test whether ``x`` is nonnegative. - - INPUT: - - - ``x`` -- a number in the base ring. - - OUTPUT: - - Boolean. - - EXAMPLES:: - - sage: p = Polyhedron([(0,0)], base_ring=ZZ) - sage: p._is_nonneg(1) - True - sage: p._is_nonneg(-1/100000) - False - """ - return x>=0 - - def _is_positive(self, x): - """ - Test whether ``x`` is positive. - - INPUT: - - - ``x`` -- a number in the base ring. - - OUTPUT: - - Boolean. - - EXAMPLES:: - - sage: p = Polyhedron([(0,0)], base_ring=ZZ) - sage: p._is_positive(1) - True - sage: p._is_positive(0) - False - """ - return x>0 _base_ring = ZZ From 53385ed4769763b3c3c4370dff367f0b5888ce81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bissey?= Date: Sat, 11 Mar 2017 16:55:14 +1300 Subject: [PATCH 098/185] Remove patch already included in upstream tarball --- build/pkgs/singular/patches/make_check.patch | 216 ------------------- 1 file changed, 216 deletions(-) delete mode 100644 build/pkgs/singular/patches/make_check.patch diff --git a/build/pkgs/singular/patches/make_check.patch b/build/pkgs/singular/patches/make_check.patch deleted file mode 100644 index 9cc48030616..00000000000 --- a/build/pkgs/singular/patches/make_check.patch +++ /dev/null @@ -1,216 +0,0 @@ -From 3f253bdb1a2093b790df2d04741171aa027ff07d Mon Sep 17 00:00:00 2001 -From: Hans Schoenemann -Date: Mon, 20 Feb 2017 18:33:27 +0100 -Subject: [PATCH] make check - ---- - Singular/test.cc | 1 - - kernel/GBEngine/Makefile.am | 2 +- - kernel/GBEngine/test.cc | 2 +- - kernel/Makefile.am | 2 +- - kernel/combinatorics/Makefile.am | 2 +- - kernel/combinatorics/test.cc | 2 +- - kernel/fglm/test.cc | 2 +- - kernel/groebner_walk/test.cc | 2 +- - kernel/linear_algebra/test.cc | 2 +- - kernel/maps/test.cc | 2 +- - kernel/numeric/test.cc | 2 +- - kernel/oswrapper/test.cc | 2 +- - kernel/spectrum/test.cc | 2 +- - kernel/test.cc | 2 +- - libpolys/tests/rings_test.h | 2 +- - 15 files changed, 14 insertions(+), 15 deletions(-) - -diff --git a/Singular/test.cc b/Singular/test.cc -index d5b64e7..45ed707 100644 ---- a/Singular/test.cc -+++ b/Singular/test.cc -@@ -194,7 +194,6 @@ - #include - #include - #include --#include - #include - #include - #include -diff --git a/kernel/GBEngine/Makefile.am b/kernel/GBEngine/Makefile.am -index 3efdcf0..fb8bec3 100644 ---- a/kernel/GBEngine/Makefile.am -+++ b/kernel/GBEngine/Makefile.am -@@ -17,7 +17,7 @@ TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}' - TESTS = test - check_PROGRAMS = $(TESTS) - test_SOURCES = test.cc --test_LDADD = libGBEngine.la ${builddir}/../combinatorics/libcombinatorics.la ${builddir}/../linear_algebra/liblinear_algebra.la ${builddir}/../libkernelCommon.la -+test_LDADD = libGBEngine.la ${builddir}/../combinatorics/libcombinatorics.la ${builddir}/../linear_algebra/liblinear_algebra.la ${builddir}/../libkernelCommon.la ${builddir}/../../Singular/libSingular.la - - CLEANFILES = $(TESTS) - -diff --git a/kernel/GBEngine/test.cc b/kernel/GBEngine/test.cc -index 436a1c8..5336737 100644 ---- a/kernel/GBEngine/test.cc -+++ b/kernel/GBEngine/test.cc -@@ -93,7 +93,7 @@ void TestGBEngine() - - - const int D = 3; -- int *order = (int *) omAlloc0(D* sizeof(int)); -+ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); - int *block0 = (int *)omAlloc0(D * sizeof(int)); - int *block1 = (int *)omAlloc0(D * sizeof(int)); - -diff --git a/kernel/Makefile.am b/kernel/Makefile.am -index 86f6d47..575f215 100644 ---- a/kernel/Makefile.am -+++ b/kernel/Makefile.am -@@ -51,7 +51,7 @@ TESTS = test - check_PROGRAMS = $(TESTS) - - test_SOURCES = test.cc --test_LDADD = libkernel.la -+test_LDADD = libkernel.la ${builddir}/../Singular/libSingular.la - - # These files are built first - # BUILT_SOURCES = MOD -diff --git a/kernel/combinatorics/Makefile.am b/kernel/combinatorics/Makefile.am -index 63a52ec..f8074fe 100644 ---- a/kernel/combinatorics/Makefile.am -+++ b/kernel/combinatorics/Makefile.am -@@ -17,6 +17,6 @@ TESTS_ENVIRONMENT += SINGULAR_ROOT_DIR='${abs_top_builddir}' - TESTS = test - check_PROGRAMS = $(TESTS) - test_SOURCES = test.cc --test_LDADD = libcombinatorics.la ${builddir}/../libkernelCommon.la -+test_LDADD = libcombinatorics.la ${builddir}/../libkernelCommon.la ${builddir}/../../Singular/libSingular.la - - CLEANFILES = $(TESTS) -diff --git a/kernel/combinatorics/test.cc b/kernel/combinatorics/test.cc -index 056fd57..32e7ae5 100644 ---- a/kernel/combinatorics/test.cc -+++ b/kernel/combinatorics/test.cc -@@ -99,7 +99,7 @@ void TestGBEngine() - - - const int D = 3; -- int *order = (int *) omAlloc0(D* sizeof(int)); -+ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); - int *block0 = (int *)omAlloc0(D * sizeof(int)); - int *block1 = (int *)omAlloc0(D * sizeof(int)); - -diff --git a/kernel/fglm/test.cc b/kernel/fglm/test.cc -index c5182db..597053b 100644 ---- a/kernel/fglm/test.cc -+++ b/kernel/fglm/test.cc -@@ -97,7 +97,7 @@ void TestGBEngine() - - - const int D = 3; -- int *order = (int *) omAlloc0(D* sizeof(int)); -+ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); - int *block0 = (int *)omAlloc0(D * sizeof(int)); - int *block1 = (int *)omAlloc0(D * sizeof(int)); - -diff --git a/kernel/groebner_walk/test.cc b/kernel/groebner_walk/test.cc -index c5182db..597053b 100644 ---- a/kernel/groebner_walk/test.cc -+++ b/kernel/groebner_walk/test.cc -@@ -97,7 +97,7 @@ void TestGBEngine() - - - const int D = 3; -- int *order = (int *) omAlloc0(D* sizeof(int)); -+ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); - int *block0 = (int *)omAlloc0(D * sizeof(int)); - int *block1 = (int *)omAlloc0(D * sizeof(int)); - -diff --git a/kernel/linear_algebra/test.cc b/kernel/linear_algebra/test.cc -index c5182db..597053b 100644 ---- a/kernel/linear_algebra/test.cc -+++ b/kernel/linear_algebra/test.cc -@@ -97,7 +97,7 @@ void TestGBEngine() - - - const int D = 3; -- int *order = (int *) omAlloc0(D* sizeof(int)); -+ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); - int *block0 = (int *)omAlloc0(D * sizeof(int)); - int *block1 = (int *)omAlloc0(D * sizeof(int)); - -diff --git a/kernel/maps/test.cc b/kernel/maps/test.cc -index c5182db..597053b 100644 ---- a/kernel/maps/test.cc -+++ b/kernel/maps/test.cc -@@ -97,7 +97,7 @@ void TestGBEngine() - - - const int D = 3; -- int *order = (int *) omAlloc0(D* sizeof(int)); -+ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); - int *block0 = (int *)omAlloc0(D * sizeof(int)); - int *block1 = (int *)omAlloc0(D * sizeof(int)); - -diff --git a/kernel/numeric/test.cc b/kernel/numeric/test.cc -index c5182db..597053b 100644 ---- a/kernel/numeric/test.cc -+++ b/kernel/numeric/test.cc -@@ -97,7 +97,7 @@ void TestGBEngine() - - - const int D = 3; -- int *order = (int *) omAlloc0(D* sizeof(int)); -+ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); - int *block0 = (int *)omAlloc0(D * sizeof(int)); - int *block1 = (int *)omAlloc0(D * sizeof(int)); - -diff --git a/kernel/oswrapper/test.cc b/kernel/oswrapper/test.cc -index c5182db..597053b 100644 ---- a/kernel/oswrapper/test.cc -+++ b/kernel/oswrapper/test.cc -@@ -97,7 +97,7 @@ void TestGBEngine() - - - const int D = 3; -- int *order = (int *) omAlloc0(D* sizeof(int)); -+ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); - int *block0 = (int *)omAlloc0(D * sizeof(int)); - int *block1 = (int *)omAlloc0(D * sizeof(int)); - -diff --git a/kernel/spectrum/test.cc b/kernel/spectrum/test.cc -index c5182db..597053b 100644 ---- a/kernel/spectrum/test.cc -+++ b/kernel/spectrum/test.cc -@@ -97,7 +97,7 @@ void TestGBEngine() - - - const int D = 3; -- int *order = (int *) omAlloc0(D* sizeof(int)); -+ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); - int *block0 = (int *)omAlloc0(D * sizeof(int)); - int *block1 = (int *)omAlloc0(D * sizeof(int)); - -diff --git a/kernel/test.cc b/kernel/test.cc -index e27acf7..a0c418e 100644 ---- a/kernel/test.cc -+++ b/kernel/test.cc -@@ -203,7 +203,7 @@ void TestGBEngine() - - - const int D = 3; -- int *order = (int *) omAlloc0(D* sizeof(int)); -+ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); - int *block0 = (int *)omAlloc0(D * sizeof(int)); - int *block1 = (int *)omAlloc0(D * sizeof(int)); - -diff --git a/libpolys/tests/rings_test.h b/libpolys/tests/rings_test.h -index f8a66b5..22c92f6 100644 ---- a/libpolys/tests/rings_test.h -+++ b/libpolys/tests/rings_test.h -@@ -208,7 +208,7 @@ class PolysTestSuite : public CxxTest::TestSuite - - const int D = 2; - /*order: lp,0*/ -- int *order = (int *) omAlloc0(D* sizeof(int)); -+ rRingOrder_t *order = (rRingOrder_t *) omAlloc0(D* sizeof(rRingOrder_t)); - int *block0 = (int *)omAlloc0(D * sizeof(int)); - int *block1 = (int *)omAlloc0(D * sizeof(int)); - /* ringorder dp for the first block: var 1..N */ From 67bc8d63c829beea1dbcfae494f83354b8b4a724 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 9 Mar 2017 16:38:38 +0100 Subject: [PATCH 099/185] py3: some care for map --- src/sage/algebras/cluster_algebra.py | 4 ++-- src/sage/combinat/diagram_algebras.py | 2 +- src/sage/combinat/posets/posets.py | 4 ++-- src/sage/combinat/similarity_class_type.py | 24 ++++++++++++-------- src/sage/combinat/skew_tableau.py | 3 ++- src/sage/databases/findstat.py | 2 +- src/sage/graphs/strongly_regular_db.pyx | 14 +++++++----- src/sage/modular/dirichlet.py | 6 ++--- src/sage/rings/polynomial/polynomial_ring.py | 6 ++--- 9 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/sage/algebras/cluster_algebra.py b/src/sage/algebras/cluster_algebra.py index 8648818a500..1deae5fd5c5 100644 --- a/src/sage/algebras/cluster_algebra.py +++ b/src/sage/algebras/cluster_algebra.py @@ -331,7 +331,7 @@ over Integer Ring sage: A.b_matrix() == A1.b_matrix() False - sage: map(lambda (X, Y): X.has_coerce_map_from(Y), [(A, A1), (A1, A)]) + sage: [X.has_coerce_map_from(Y) for X, Y in [(A, A1), (A1, A)]] [False, False] """ @@ -1395,7 +1395,7 @@ def _coerce_map_from_(self, other): sage: g = A1.coerce_map_from(A3) sage: A3.find_g_vector((1, -2, 2)) [1, 2, 1, 0] - sage: map(lambda x: x-1, map(G.gen(0), map(lambda x: x+1, [1, 2, 1, 0]))) + sage: [G.gen(0)(x + 1) - 1 for x in [1, 2, 1, 0]] [2, 3, 2, 1] sage: S = A1.initial_seed(); S.mutate([2, 3, 2, 1]) sage: S.cluster_variable(1) == g(A3.cluster_variable((1, -2, 2))) diff --git a/src/sage/combinat/diagram_algebras.py b/src/sage/combinat/diagram_algebras.py index 64e96c3554a..6b627c3922f 100644 --- a/src/sage/combinat/diagram_algebras.py +++ b/src/sage/combinat/diagram_algebras.py @@ -987,7 +987,7 @@ def from_involution_permutation_triple(self, D1_D2_pi): raise ValueError("argument %s not in correct form; must be a tuple (D1, D2, pi)" % D1_D2_pi) D1 = [[abs(x) for x in b] for b in D1 if len(b) == 2] # not needed if argument correctly passed at outset. D2 = [[abs(x) for x in b] for b in D2 if len(b) == 2] # ditto. - nD2 = [map(lambda i: -i,b) for b in D2] + nD2 = [[-i for i in b] for b in D2] pi = list(pi) nn = set(range(1, self.order+1)) dom = sorted(nn.difference(flatten([list(x) for x in D1]))) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index dc39754282e..964b45759ac 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -5462,8 +5462,8 @@ def linear_extensions_graph(self): G.add_vertices(L) for i in range(len(L)): for j in range(i): - tmp = map(lambda x,y: x != y, L[i], L[j]) - if tmp.count(True) == 2 and tmp[tmp.index(True)+1]: + tmp = [x != y for x, y in zip(L[i], L[j])] + if tmp.count(True) == 2 and tmp[tmp.index(True) + 1]: G.add_edge(L[i], L[j]) return G diff --git a/src/sage/combinat/similarity_class_type.py b/src/sage/combinat/similarity_class_type.py index 878b0d2d0d6..088a917c594 100644 --- a/src/sage/combinat/similarity_class_type.py +++ b/src/sage/combinat/similarity_class_type.py @@ -550,11 +550,9 @@ def centralizer_group_card(self, q = None): q^8 - q^6 - q^4 + q^2 """ if q is None: - R = FractionField(ZZ['q']) - q = R.gen() - return self.statistic(centralizer_group_cardinality, q = q) - #p = q.parent()(prod(map(lambda n:fq(n, q = q), self.partition().to_exp()),1)) - #return q**self.centralizer_algebra_dim()*p.substitute(q = q**self.degree()) + q = FractionField(ZZ['q']).gen() + return self.statistic(centralizer_group_cardinality, q=q) + class PrimarySimilarityClassTypes(UniqueRepresentation, Parent): r""" @@ -1215,7 +1213,8 @@ def dictionary_from_generator(gen): setofkeys = list(set(item[0] for item in L)) return dict((key, sum(entry[1] for entry in (pair for pair in L if pair[0] == key))) for key in setofkeys) -def matrix_similarity_classes(n, q = None, invertible = False): + +def matrix_similarity_classes(n, q=None, invertible=False): r""" Return the number of matrix similarity classes over a finite field of order ``q``. @@ -1231,12 +1230,17 @@ def matrix_similarity_classes(n, q = None, invertible = False): 15 """ if q is None: - q = FractionField(QQ['q']).gen() + q = ZZ['q'].gen() + basering = q.parent() if n == 0: - return 1 + return basering.one() if invertible: - return sum([q**max(la)*((1-q**(-1))**map(lambda x: x>0, la.to_exp()).count(True)) for la in Partitions(n)]) - return sum([q**max(la) for la in Partitions(n)]) + tilde = 1 - ~q + return sum(q**max(la) * + tilde ** len([x for x in la.to_exp() if x > 0]) + for la in Partitions(n)) + return sum(q**max(la) for la in Partitions(n)) + def matrix_centralizer_cardinalities(n, q = None, invertible = False): """ diff --git a/src/sage/combinat/skew_tableau.py b/src/sage/combinat/skew_tableau.py index b57d58b9568..0d343f4d533 100644 --- a/src/sage/combinat/skew_tableau.py +++ b/src/sage/combinat/skew_tableau.py @@ -666,7 +666,8 @@ def restrict(self, n): [[None, 1], [1]] """ t = self[:] - return SkewTableau( [z for z in map(lambda x: [y for y in x if y is None or y <= n], t) if z != []] ) + return SkewTableau([z for z in [[y for y in x if y is None or y <= n] + for x in t] if z]) def restriction_outer_shape(self, n): """ diff --git a/src/sage/databases/findstat.py b/src/sage/databases/findstat.py index b9a457b9886..aec5a624702 100644 --- a/src/sage/databases/findstat.py +++ b/src/sage/databases/findstat.py @@ -125,7 +125,7 @@ def statistic(T): sage: print(list_f[0].code() + "\r\n" + list_f[1].code()) # optional -- internet,random def complement(elt): n = len(elt) - return elt.__class__(elt.parent(), map(lambda x: n - x + 1, elt) ) + return elt.__class__(elt.parent(), [n - x + 1 for x in elt]) def increasing_tree_shape(elt, compare=min): return elt.increasing_tree(compare).shape() diff --git a/src/sage/graphs/strongly_regular_db.pyx b/src/sage/graphs/strongly_regular_db.pyx index cb1053d2fbc..4e990a90165 100644 --- a/src/sage/graphs/strongly_regular_db.pyx +++ b/src/sage/graphs/strongly_regular_db.pyx @@ -2446,8 +2446,8 @@ def strongly_regular_from_two_intersection_set(M): EXAMPLE:: sage: from sage.graphs.strongly_regular_db import strongly_regular_from_two_intersection_set - sage: S=Matrix([(0,0,1),(0,1,0)] + map(lambda x: (1,x^2,x), GF(4,'b'))) - sage: g=strongly_regular_from_two_intersection_set(S) + sage: S = Matrix([(0,0,1),(0,1,0)] + [(1,x^2,x) for x in GF(4,'b')]) + sage: g = strongly_regular_from_two_intersection_set(S) sage: g.is_strongly_regular(parameters=True) (64, 18, 2, 6) @@ -2580,14 +2580,16 @@ def SRG_630_85_20_10(): from sage.graphs.generators.intersection import IntersectionGraph from sage.graphs.generators.smallgraphs import HoffmanSingletonGraph hs = HoffmanSingletonGraph() - P = list(range(5)) + list(range(30, 35)) # a Petersen in hs + P = list(range(5)) + list(range(30, 35)) # a Petersen in hs mc = [0, 1, 5, 6, 12, 13, 16, 17, 22, 23, 29, 33, 39, 42, 47] - assert(hs.subgraph(mc).is_regular(k=0)) # a maximum coclique + assert(hs.subgraph(mc).is_regular(k=0)) # a maximum coclique assert(hs.subgraph(P).is_regular(k=3)) - h = hs.automorphism_group().stabilizer(mc,action="OnSets") - l = h.orbit(tuple(map(lambda x: (x[0],x[1]), hs.subgraph(P).matching())),"OnSetsSets") + h = hs.automorphism_group().stabilizer(mc, action="OnSets") + l = h.orbit(tuple((x[0], x[1]) for x in hs.subgraph(P).matching()), + "OnSetsSets") return IntersectionGraph(l) + def SRG_126_50_13_24(): r""" Return a `(126,50,13,24)`-strongly regular graph diff --git a/src/sage/modular/dirichlet.py b/src/sage/modular/dirichlet.py index 1598fd7d31d..782ae172c8e 100644 --- a/src/sage/modular/dirichlet.py +++ b/src/sage/modular/dirichlet.py @@ -57,7 +57,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import print_function -from six.moves import range +from six.moves import range, zip import sage.categories.all as cat from sage.misc.all import prod @@ -252,14 +252,14 @@ def __init__(self, parent, x, check=True): raise ValueError("wrong number of values (= {}) on generators (want {})".format(x, len(orders))) if free_module_element.is_FreeModuleElement(x): x = parent._module(x) - if any(map(lambda u, v: v*u != 0, x, orders)): + if any(u * v for u, v in zip(x, orders)): raise ValueError("values (= {} modulo {}) must have additive orders dividing {}, respectively" .format(x, parent.zeta_order(), orders)) self.element.set_cache(x) else: R = parent.base_ring() x = tuple(map(R, x)) - if R.is_exact() and any(map(lambda u, v: u**v != 1, x, orders)): + if R.is_exact() and any(u**v != 1 for u, v in zip(x, orders)): raise ValueError("values (= {}) must have multiplicative orders dividing {}, respectively" .format(x, orders)) self.values_on_gens.set_cache(x) diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index 5b5263cd614..c81f2dbb0d3 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -1931,7 +1931,7 @@ def lagrange_polynomial(self, points, algorithm="divided_difference", previous_r # sage.tests.french_book.nonlinear_doctest where the base ring # is CC, but the function values lie in the symbolic ring. to_base_ring = self.base_ring() - points = map(lambda x: map(to_base_ring, x), points) + points = [[to_base_ring(u) for u in x] for x in points] var = self.gen() # use the method of divided-difference @@ -2296,9 +2296,9 @@ def alekh_rec(p, k, degree_bound, lvl): return [ (self.zero(),0) ] else: return [] - elif k==1 or degree_bound == 0: + elif k == 1 or degree_bound == 0: #Either one coefficient left to be computed, or p has only one coefficient - py = self(map(lambda c:c[0], p.list())) # py = p(x=0, y) + py = self([c[0] for c in p.list()]) # py = p(x=0, y) if py.is_zero(): return [ (self.zero(), 0) ] roots = py.roots(multiplicities=False) From 6ab5f636b5db2c2e6a5c7e234e1471ef002e4f13 Mon Sep 17 00:00:00 2001 From: Eric Gourgoulhon Date: Sat, 11 Mar 2017 14:33:38 +0100 Subject: [PATCH 100/185] Change the name of first argument to 'self' in nested method _pullback_chart of DiffMap --- src/sage/manifolds/differentiable/diff_map.py | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/sage/manifolds/differentiable/diff_map.py b/src/sage/manifolds/differentiable/diff_map.py index 956ebb57bba..40db29e939f 100644 --- a/src/sage/manifolds/differentiable/diff_map.py +++ b/src/sage/manifolds/differentiable/diff_map.py @@ -908,30 +908,29 @@ def pullback(self, tensor): from sage.tensor.modules.comp import (Components, CompWithSym, CompFullySym, CompFullyAntiSym) - def _pullback_chart(diff_map, tensor): + def _pullback_chart(self, tensor): r""" - Helper function performing the pullback on chart domains. + Helper function performing the pullback on chart domains + only. INPUT: - - ``diff_map`` -- a restriction of ``self``, whose both domain and - codomain are chart domains - - ``tensor`` -- a covariant tensor field, whose domain is the codomain - of ``diff_map`` + - ``tensor`` -- a covariant tensor field, whose domain is + the codomain of ``self`` OUTPUT: - - the pull back of ``tensor`` by ``diff_map`` + - the pull back of ``tensor`` by ``self`` """ - dom1 = diff_map._domain - dom2 = diff_map._codomain + dom1 = self._domain + dom2 = self._codomain ncov = tensor._tensor_type[1] resu_name = None ; resu_latex_name = None - if diff_map._name is not None and tensor._name is not None: - resu_name = diff_map._name + '_*(' + tensor._name + ')' - if diff_map._latex_name is not None and tensor._latex_name is not None: - resu_latex_name = diff_map._latex_name + '_*' + tensor._latex_name + if self._name is not None and tensor._name is not None: + resu_name = self._name + '_*(' + tensor._name + ')' + if self._latex_name is not None and tensor._latex_name is not None: + resu_latex_name = self._latex_name + '_*' + tensor._latex_name fmodule1 = dom1.vector_field_module() ring1 = fmodule1._ring si1 = fmodule1._sindex @@ -945,7 +944,7 @@ def _pullback_chart(diff_map, tensor): chart2 = frame2._chart for chart1 in dom1._atlas: if (chart1._domain is dom1 and (chart1, chart2) in - diff_map._coord_expression): + self._coord_expression): # Computation at the component level: frame1 = chart1._frame tcomp = tensor._components[frame2] @@ -967,7 +966,7 @@ def _pullback_chart(diff_map, tensor): ptcomp = Components(ring1, frame1, ncov, start_index=si1, output_formatter=of1) - phi = diff_map._coord_expression[(chart1, chart2)] + phi = self._coord_expression[(chart1, chart2)] jacob = phi.jacobian() # X2 coordinates expressed in terms of X1 ones via the # mapping: From 9bd903b23c6f30274ecaa14bb45a8725a90fe762 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Sat, 11 Mar 2017 22:35:11 +0100 Subject: [PATCH 101/185] Special cases for iterating t_VECSMALL and t_STR --- src/sage/libs/cypari2/gen.pyx | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/sage/libs/cypari2/gen.pyx b/src/sage/libs/cypari2/gen.pyx index 1cd83f9b92e..d330c23a5b7 100644 --- a/src/sage/libs/cypari2/gen.pyx +++ b/src/sage/libs/cypari2/gen.pyx @@ -197,6 +197,13 @@ cdef class Gen(Gen_auto): """ Iterate over the components of ``self``. + The items in the iteration are of type :class:`Gen` with the + following exceptions: + + - items of a ``t_VECSMALL`` are of type ``int`` + + - items of a ``t_STR`` are of type ``str`` + EXAMPLES: We can iterate over PARI vectors or columns:: @@ -251,6 +258,20 @@ cdef class Gen(Gen_auto): ... PariError: incorrect type in gtovec (t_CLOSURE) + For ``t_VECSMALL``, the items are Python integers:: + + sage: v = pari("Vecsmall([1,2,3,4,5,6])") + sage: list(v) + [1, 2, 3, 4, 5, 6] + sage: type(list(v)[0]).__name__ + 'int' + + For ``t_STR``, the items are Python strings:: + + sage: v = pari('"hello"') + sage: list(v) + ['h', 'e', 'l', 'l', 'o'] + TESTS: The following are deprecated:: @@ -262,7 +283,9 @@ cdef class Gen(Gen_auto): doctest:...: DeprecationWarning: iterating a PARI 't_COMPLEX' is deprecated (1, 5) """ + cdef long i cdef long t = typ(self.g) + cdef GEN x # First convert self to a vector type cdef Gen v @@ -279,12 +302,19 @@ cdef class Gen(Gen_auto): v = self elif is_scalar_t(t): raise TypeError(f"PARI object of type {self.type()!r} is not iterable") + elif t == t_VECSMALL: + # Special case: items of type int + x = self.g + return (x[i] for i in range(1, lg(x))) + elif t == t_STR: + # Special case: convert to str + return iter(GSTR(self.g)) else: v = self.Vec() # Now iterate over the vector v - cdef long i - return (v.new_ref(gel(v.g, i)) for i in range(1, lg(v.g))) + x = v.g + return (v.new_ref(gel(x, i)) for i in range(1, lg(x))) def list(self): """ From 02add83718a340f778b47aacb73a8a61dba2aa18 Mon Sep 17 00:00:00 2001 From: Eric Gourgoulhon Date: Sun, 12 Mar 2017 12:26:27 +0100 Subject: [PATCH 102/185] Revert to previous version of nested function _pullback_chart in DiffMap.pullback --- src/sage/manifolds/differentiable/diff_map.py | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/sage/manifolds/differentiable/diff_map.py b/src/sage/manifolds/differentiable/diff_map.py index 40db29e939f..6740d021cdc 100644 --- a/src/sage/manifolds/differentiable/diff_map.py +++ b/src/sage/manifolds/differentiable/diff_map.py @@ -908,29 +908,33 @@ def pullback(self, tensor): from sage.tensor.modules.comp import (Components, CompWithSym, CompFullySym, CompFullyAntiSym) - def _pullback_chart(self, tensor): + def _pullback_chart(diff_map, tensor): r""" Helper function performing the pullback on chart domains only. INPUT: + - ``diff_map`` -- a restriction of ``self``, whose both + domain and codomain are chart domains - ``tensor`` -- a covariant tensor field, whose domain is - the codomain of ``self`` + the codomain of ``diff_map`` OUTPUT: - - the pull back of ``tensor`` by ``self`` + - the pull back of ``tensor`` by ``diff_map`` """ - dom1 = self._domain - dom2 = self._codomain + dom1 = diff_map._domain + dom2 = diff_map._codomain ncov = tensor._tensor_type[1] resu_name = None ; resu_latex_name = None - if self._name is not None and tensor._name is not None: - resu_name = self._name + '_*(' + tensor._name + ')' - if self._latex_name is not None and tensor._latex_name is not None: - resu_latex_name = self._latex_name + '_*' + tensor._latex_name + if diff_map._name is not None and tensor._name is not None: + resu_name = diff_map._name + '_*(' + tensor._name + ')' + if (diff_map._latex_name is not None and + tensor._latex_name is not None): + resu_latex_name = '{' + diff_map._latex_name + '}_*' + \ + tensor._latex_name fmodule1 = dom1.vector_field_module() ring1 = fmodule1._ring si1 = fmodule1._sindex @@ -944,7 +948,7 @@ def _pullback_chart(self, tensor): chart2 = frame2._chart for chart1 in dom1._atlas: if (chart1._domain is dom1 and (chart1, chart2) in - self._coord_expression): + diff_map._coord_expression): # Computation at the component level: frame1 = chart1._frame tcomp = tensor._components[frame2] @@ -966,10 +970,10 @@ def _pullback_chart(self, tensor): ptcomp = Components(ring1, frame1, ncov, start_index=si1, output_formatter=of1) - phi = self._coord_expression[(chart1, chart2)] + phi = diff_map._coord_expression[(chart1, chart2)] jacob = phi.jacobian() - # X2 coordinates expressed in terms of X1 ones via the - # mapping: + # X2 coordinates expressed in terms of + # X1 ones via the diff. map: coord2_1 = phi(*(chart1._xx)) for ind_new in ptcomp.non_redundant_index_generator(): res = 0 @@ -977,12 +981,12 @@ def _pullback_chart(self, tensor): ff = tcomp[[ind_old]].coord_function(chart2) t = chart1.function(ff(*coord2_1)) for i in range(ncov): - t *= jacob[ind_old[i]-si2][ind_new[i]-si1] + t *= jacob[ind_old[i]-si2, ind_new[i]-si1] res += t ptcomp[ind_new] = res resu._components[frame1] = ptcomp return resu - # End of function _pullback_paral + # End of function _pullback_chart # Special case of the identity map: if self._is_identity: @@ -1001,7 +1005,8 @@ def _pullback_chart(self, tensor): if self._name is not None and tensor._name is not None: resu_name = self._name + '_*(' + tensor._name + ')' if self._latex_name is not None and tensor._latex_name is not None: - resu_latex_name = self._latex_name + '_*' + tensor._latex_name + resu_latex_name = "{" + self._latex_name + '}_*' + \ + tensor._latex_name if ncov == 0: # Case of a scalar field resu_fc = [] @@ -1205,7 +1210,7 @@ def pushforward(self, tensor): for ind_old in dom1.index_generator(ncon): t = tcomp[[ind_old]].coord_function(chart1) for i in range(ncon): - t *= jacob[ind_new[i]-si2][ind_old[i]-si1] + t *= jacob[ind_new[i]-si2, ind_old[i]-si1] res += t ptcomp[ind_new] = res # Name of the result: From 1a6171fe2ba6b5d42cffa45d124dd931cf8cdb1f Mon Sep 17 00:00:00 2001 From: David Coudert Date: Sun, 12 Mar 2017 15:40:56 +0100 Subject: [PATCH 103/185] trac #22586: add method add_clique to (di)graph --- src/sage/graphs/generic_graph.py | 43 ++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 490bf1c9562..64a97d8a466 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -83,6 +83,7 @@ :meth:`~GenericGraph.degree_iterator` | Return an iterator over the degrees of the (di)graph. :meth:`~GenericGraph.degree_sequence` | Return the degree sequence of this (di)graph. :meth:`~GenericGraph.random_subgraph` | Return a random subgraph that contains each vertex with prob. p. + :meth:`~GenericGraph.add_clique` | Add a clique to the graph with the given vertices. :meth:`~GenericGraph.add_cycle` | Add a cycle to the graph with the given vertices. :meth:`~GenericGraph.add_path` | Add a cycle to the graph with the given vertices. :meth:`~GenericGraph.complement` | Return the complement of the (di)graph. @@ -16702,6 +16703,48 @@ def lex_BFS(self,reverse=False,tree=False, initial_vertex = None): ### Constructors + def add_clique(self, vertices, loops=False): + """ + Add a clique to the graph with the given vertices. + + If the vertices are already present, only the edges are added. + + INPUT: + + - ``vertices`` -- a list of vertices for the clique to be added. + + - ``loops`` -- (boolean) whether to add loops or not, i.e., edges from a + vertex to itself. Possible only if the (di)graph allows loops. + + EXAMPLES:: + + sage: G = Graph() + sage: G.add_clique(list(range(4))) + sage: G.is_isomorphic(graphs.CompleteGraph(4)) + True + sage: D = DiGraph() + sage: D.add_clique(list(range(4))) + sage: D.is_isomorphic(digraphs.Complete(4)) + True + sage: D = DiGraph(loops=True) + sage: D.add_clique(list(range(4)), loops=True) + sage: D.is_isomorphic(digraphs.Complete(4, loops=True)) + True + sage: D = DiGraph(loops=False) + sage: D.add_clique(list(range(4)), loops=True) + sage: D.is_isomorphic(digraphs.Complete(4, loops=True)) + False + sage: D.is_isomorphic(digraphs.Complete(4, loops=False)) + True + """ + if vertices: + n = len(vertices) + self.add_edges((vertices[i],vertices[j]) for i in range(n-1) for j in range(i+1,n)) + if self.is_directed(): + self.add_edges((vertices[j],vertices[i]) for i in range(n-1) for j in range(i+1,n)) + if loops and self.allows_loops(): + self.add_edges((vertices[i],vertices[i]) for i in range(n)) + def add_cycle(self, vertices): """ Adds a cycle to the graph with the given vertices. If the vertices From e9ebab2e0fe8202c35a2f6070bf1ebd876136e05 Mon Sep 17 00:00:00 2001 From: Ximin Luo Date: Sun, 12 Mar 2017 16:40:34 +0100 Subject: [PATCH 104/185] Fix Sage's use of scipy rtol parameter --- src/sage/numerical/optimize.py | 7 +++++-- src/sage/symbolic/expression.pyx | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/sage/numerical/optimize.py b/src/sage/numerical/optimize.py index 76eed12be21..22efd5290ce 100644 --- a/src/sage/numerical/optimize.py +++ b/src/sage/numerical/optimize.py @@ -16,7 +16,7 @@ from sage.rings.real_double import RDF -def find_root(f, a, b, xtol=10e-13, rtol=4.5e-16, maxiter=100, full_output=False): +def find_root(f, a, b, xtol=10e-13, rtol=2.0**-50, maxiter=100, full_output=False): """ Numerically find a root of ``f`` on the closed interval `[a,b]` (or `[b,a]`) if possible, where ``f`` is a function in the one variable. @@ -32,7 +32,10 @@ def find_root(f, a, b, xtol=10e-13, rtol=4.5e-16, maxiter=100, full_output=False - ``xtol``, ``rtol`` -- the routine converges when a root is known to lie within ``xtol`` of the value return. Should be `\geq 0`. The routine modifies this to take into account the relative precision - of doubles. + of doubles. By default, rtol is ``4*numpy.finfo(float).eps``, the + minimum allowed value for ``scipy.optimize.brentq``, which is what + this method uses underneath. This value is equal to ``2.0**-50`` for + IEEE-754 double precision floats as used by Python. - ``maxiter`` -- integer; if convergence is not achieved in ``maxiter`` iterations, an error is raised. Must be `\geq 0`. diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index f725816efff..f929e29d089 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -11092,7 +11092,7 @@ cdef class Expression(CommutativeRingElement): ret = ret[0] return ret - def find_root(self, a, b, var=None, xtol=10e-13, rtol=4.5e-16, maxiter=100, full_output=False): + def find_root(self, a, b, var=None, xtol=10e-13, rtol=2.0**-50, maxiter=100, full_output=False): """ Numerically find a root of self on the closed interval [a,b] (or [b,a]) if possible, where self is a function in the one variable. From 4e1c272447821bcefbc0cbd73d746249a9ebdc5c Mon Sep 17 00:00:00 2001 From: paulmasson Date: Sun, 12 Mar 2017 20:16:22 -0700 Subject: [PATCH 105/185] Update examples --- .../plot3d/threejs_examples/helix.html | 105 +++++++++++------- .../plot3d/threejs_examples/spheres.html | 105 +++++++++++------- .../plot3d/threejs_examples/template.html | 5 +- 3 files changed, 130 insertions(+), 85 deletions(-) diff --git a/src/doc/en/reference/plot3d/threejs_examples/helix.html b/src/doc/en/reference/plot3d/threejs_examples/helix.html index c00e4ed0081..4bfa45da48e 100644 --- a/src/doc/en/reference/plot3d/threejs_examples/helix.html +++ b/src/doc/en/reference/plot3d/threejs_examples/helix.html @@ -1,11 +1,11 @@ - \ No newline at end of file From 21045e404002bdad08ee64b18ea87fd76fd8ddc1 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Mon, 13 Mar 2017 15:05:18 +0100 Subject: [PATCH 106/185] Use error_msg for a lot more error messages in sage-spkg --- build/bin/sage-spkg | 75 +++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/build/bin/sage-spkg b/build/bin/sage-spkg index cbed2653574..5086e5e1fa4 100755 --- a/build/bin/sage-spkg +++ b/build/bin/sage-spkg @@ -85,8 +85,9 @@ EOF # error_msg(header, command) # This is for printing an error message if something went wrong. -# The first argument is the header to print, the second argument should -# be some proposed command to run in the subshell, e.g. "make". +# The first argument is the header to print. If given, the second +# argument should be some proposed command to run in the subshell +# such as "make". error_msg() { cat >&2 <&2 <&2 <&2 <&2 "Error setting environment variables by sourcing sage-env." - echo >&2 "possibly contact sage-devel (see http://groups.google.com/group/sage-devel)." + error_msg "Error setting environment variables by sourcing sage-env" exit 1 fi @@ -156,7 +164,7 @@ fi mkdir -p "$SAGE_SPKG_INST" if [ $? -ne 0 ]; then - echo >&2 "Error creating directory $SAGE_SPKG_INST." + error_msg "Error creating directory $SAGE_SPKG_INST" exit 1 fi @@ -348,7 +356,10 @@ fi if [ ! -f "$PKG_SRC" ]; then if [ -n "$PKG_NAME_UPSTREAM" ]; then # This is the new-style package way of downloading the tarball - sage-download-file $PKG_NAME_UPSTREAM || exit $? + if ! sage-download-file "$PKG_NAME_UPSTREAM"; then + error_msg "Error downloading $PKG_NAME_UPSTREAM" + exit 1 + fi PKG_SRC="$SAGE_DISTFILES/$PKG_NAME_UPSTREAM" else # Handle all the legacy cruft. This branch can be deleted once @@ -372,6 +383,7 @@ if [ ! -f "$PKG_SRC" ]; then # like "foo" or "foo-1.2.3". MIRROR=$(sage-download-file --print-fastest-mirror)/spkg if [ $? -ne 0 ]; then + error_msg "Error downloading list of packages" exit 1 fi for repo in optional experimental huge; do @@ -382,6 +394,7 @@ if [ ! -f "$PKG_SRC" ]; then sage-download-file --quiet "$MIRROR/$repo/list" $repolist if [ $? -ne 0 ]; then rm -f $repolist + error_msg "Error downloading $MIRROR/$repo/list" exit 1 fi @@ -478,7 +491,7 @@ EOF # Trac #5852: check write permissions mkdir -p "$SAGE_DISTFILES" if [ ! -w "$SAGE_DISTFILES" ]; then - echo >&2 "Error: no write access to packages directory $SAGE_PACKAGES." + error_msg "Error: no write access to packages directory $SAGE_PACKAGES" exit 1 fi cd "$SAGE_DISTFILES" || exit $? @@ -491,6 +504,7 @@ EOF if [ $? -ne 0 ]; then # Delete failed download rm -f "$PKG_TMP" + error_msg "Error downloading $PKG_URL" exit 1 fi @@ -516,7 +530,7 @@ cd "$SAGE_ROOT" || exit $? if [ -n "$SAGE_SPKG_COPY_UPSTREAM" ]; then mkdir -p "$SAGE_SPKG_COPY_UPSTREAM" && cp -p "$PKG_SRC" "$SAGE_SPKG_COPY_UPSTREAM" if [ $? -ne 0 ]; then - echo >&2 "Failed to copy upstream tarball to directory '$SAGE_SPKG_COPY_UPSTREAM'" + error_msg "Error copying upstream tarball to directory '$SAGE_SPKG_COPY_UPSTREAM'" exit 1 fi fi @@ -532,7 +546,7 @@ if [ $INFO -ne 0 -a -z "$USE_LOCAL_SCRIPTS" ]; then cat "$PKG_SCRIPTS/SPKG.txt" sage-uncompress-spkg "$PKG_SRC" "$PKG_NAME/SPKG.txt" if [ $? -ne 0 ]; then - echo >&2 "No file SPKG.txt in $PKG_NAME" + error_msg "Error: no file SPKG.txt in $PKG_NAME" exit 1 fi exit 0 @@ -544,13 +558,13 @@ fi mkdir -p "$SAGE_BUILD_DIR" if [ $? -ne 0 ]; then - echo >&2 "Error creating directory $SAGE_BUILD_DIR." + error_msg "Error creating directory $SAGE_BUILD_DIR" exit 1 fi # Trac #5852: check write permissions if [ ! -w "$SAGE_BUILD_DIR" ]; then - echo >&2 "Error: no write access to build directory $SAGE_BUILD_DIR." + error_msg "Error: no write access to build directory $SAGE_BUILD_DIR" exit 1 fi if [ ! -d "$SAGE_LOCAL" ]; then @@ -558,7 +572,7 @@ if [ ! -d "$SAGE_LOCAL" ]; then mkdir "$SAGE_LOCAL" fi if [ ! -w "$SAGE_LOCAL" ]; then - echo >&2 "Error: no write access to installation directory $SAGE_LOCAL." + error_msg "Error: no write access to installation directory $SAGE_LOCAL" exit 1 fi @@ -577,7 +591,7 @@ else echo "Moving old directory $PKG_NAME to $SAGE_BUILD_DIR/old..." mkdir -p old if [ $? -ne 0 ]; then - echo >&2 "Error creating directory $SAGE_BUILD_DIR/old." + error_msg "Error creating directory $SAGE_BUILD_DIR/old" exit 1 fi rm -rf old/"$PKG_NAME" @@ -586,7 +600,7 @@ else fi if [ -e "$PKG_NAME" ]; then - echo >&2 "Error (re)moving $PKG_NAME" + error_msg "Error (re)moving $PKG_NAME" exit 1 fi @@ -602,7 +616,7 @@ if [ "$USE_LOCAL_SCRIPTS" = yes ]; then sage-uncompress-spkg -d src "$PKG_SRC" if [ $? -ne 0 ]; then - echo >&2 "Error: failed to extract $PKG_SRC" + error_msg "Error: failed to extract $PKG_SRC" exit 1 fi else @@ -612,13 +626,13 @@ else sage-uncompress-spkg "$PKG_SRC" if [ $? -ne 0 ]; then - echo >&2 "Error: failed to extract $PKG_SRC" + error_msg "Error: failed to extract $PKG_SRC" exit 1 fi cd "$PKG_NAME" if [ $? -ne 0 ]; then - echo >&2 "Error: after extracting, the directory '$PKG_NAME' does not exist" + error_msg "Error: after extracting, the directory '$PKG_NAME' does not exist" exit 1 fi fi @@ -626,7 +640,10 @@ fi echo "Finished extraction" cd src -sage-apply-patches || exit 1 +if ! sage-apply-patches; then + error_msg "Error applying patches" + exit 1 +fi cd .. ################################################################## @@ -706,14 +723,6 @@ export rsync_proxy=$http_proxy ################################################################## # Actually install ################################################################## -if [ -r spkg-build ]; then - # Package has both spkg-build and spkg-install - if [ ! -x spkg-build ]; then - echo >&2 "WARNING: spkg-build is not executable, making it executable" - chmod +x spkg-build - fi -fi - if [ ! -x spkg-install ]; then echo >&2 "WARNING: spkg-install is not executable, making it executable" chmod +x spkg-install @@ -723,20 +732,20 @@ if [ -x spkg-build ]; then # Package has both spkg-build and spkg-install; execute the latter with SAGE_SUDO time ./spkg-build if [ $? -ne 0 ]; then - error_msg "Error building package $PKG_NAME" "make" - exit 1 + error_msg "Error building package $PKG_NAME" "make" + exit 1 fi time $SAGE_SUDO ./spkg-install if [ $? -ne 0 ]; then - error_msg "Error installing package $PKG_NAME" "make" - exit 1 + error_msg "Error installing package $PKG_NAME" "make" + exit 1 fi else # Package only has spkg-install time ./spkg-install if [ $? -ne 0 ]; then - error_msg "Error installing package $PKG_NAME" "make" - exit 1 + error_msg "Error installing package $PKG_NAME" "make" + exit 1 fi fi From 879c401a54a4c4cb9e0d77fadd1f010c44d9b2a8 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 25 Jan 2017 12:16:23 +0100 Subject: [PATCH 107/185] Upgrade to Sphinx 1.5.3 --- build/pkgs/requests/SPKG.txt | 6 ++++++ build/pkgs/requests/checksums.ini | 4 ++++ build/pkgs/requests/dependencies | 5 +++++ build/pkgs/requests/package-version.txt | 1 + build/pkgs/requests/spkg-install | 3 +++ build/pkgs/requests/type | 1 + build/pkgs/sphinx/checksums.ini | 6 +++--- build/pkgs/sphinx/dependencies | 2 +- build/pkgs/sphinx/package-version.txt | 2 +- build/pkgs/sphinx/patches/Makefile.patch | 21 --------------------- build/pkgs/sphinx/patches/environment.patch | 18 ------------------ 11 files changed, 25 insertions(+), 44 deletions(-) create mode 100644 build/pkgs/requests/SPKG.txt create mode 100644 build/pkgs/requests/checksums.ini create mode 100644 build/pkgs/requests/dependencies create mode 100644 build/pkgs/requests/package-version.txt create mode 100755 build/pkgs/requests/spkg-install create mode 100644 build/pkgs/requests/type delete mode 100644 build/pkgs/sphinx/patches/Makefile.patch delete mode 100644 build/pkgs/sphinx/patches/environment.patch diff --git a/build/pkgs/requests/SPKG.txt b/build/pkgs/requests/SPKG.txt new file mode 100644 index 00000000000..5f5a73a5fc2 --- /dev/null +++ b/build/pkgs/requests/SPKG.txt @@ -0,0 +1,6 @@ += requests = + +== Description == + +Requests is the only Non-GMO HTTP library for Python, safe for human +consumption. diff --git a/build/pkgs/requests/checksums.ini b/build/pkgs/requests/checksums.ini new file mode 100644 index 00000000000..2eb73f76df9 --- /dev/null +++ b/build/pkgs/requests/checksums.ini @@ -0,0 +1,4 @@ +tarball=requests-VERSION.tar.gz +sha1=827f7c8abb5a57d980d9870908724613b8b120c1 +md5=921ec6b48f2ddafc8bb6160957baf444 +cksum=3618433743 diff --git a/build/pkgs/requests/dependencies b/build/pkgs/requests/dependencies new file mode 100644 index 00000000000..d5dab729e18 --- /dev/null +++ b/build/pkgs/requests/dependencies @@ -0,0 +1,5 @@ +$(PYTHON) | pip + +---------- +All lines of this file are ignored except the first. +It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/requests/package-version.txt b/build/pkgs/requests/package-version.txt new file mode 100644 index 00000000000..fb2c0766b7c --- /dev/null +++ b/build/pkgs/requests/package-version.txt @@ -0,0 +1 @@ +2.13.0 diff --git a/build/pkgs/requests/spkg-install b/build/pkgs/requests/spkg-install new file mode 100755 index 00000000000..c1a2289ade0 --- /dev/null +++ b/build/pkgs/requests/spkg-install @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +cd src && $PIP_INSTALL . diff --git a/build/pkgs/requests/type b/build/pkgs/requests/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/requests/type @@ -0,0 +1 @@ +standard diff --git a/build/pkgs/sphinx/checksums.ini b/build/pkgs/sphinx/checksums.ini index 6b5bf7ccd4c..a353d48c696 100644 --- a/build/pkgs/sphinx/checksums.ini +++ b/build/pkgs/sphinx/checksums.ini @@ -1,4 +1,4 @@ tarball=Sphinx-VERSION.tar.gz -sha1=87ef31c2ce8c556a1644c53d21526eac7ad45f38 -md5=64ce2ec08d37ed56313a98232cbe2aee -cksum=759415183 +sha1=e296be1f697ba5eda7941570d718544df8182648 +md5=6a9522761bde569a3d50cc4509e313d9 +cksum=549728909 diff --git a/build/pkgs/sphinx/dependencies b/build/pkgs/sphinx/dependencies index cc85f403234..02e5fd48e2a 100644 --- a/build/pkgs/sphinx/dependencies +++ b/build/pkgs/sphinx/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | setuptools pip docutils jinja2 pygments six snowballstemmer imagesize babel alabaster +$(PYTHON) | setuptools pip docutils jinja2 pygments six snowballstemmer imagesize babel alabaster requests ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/sphinx/package-version.txt b/build/pkgs/sphinx/package-version.txt index 6bcecfc82d3..5c7efb1863a 100644 --- a/build/pkgs/sphinx/package-version.txt +++ b/build/pkgs/sphinx/package-version.txt @@ -1 +1 @@ -1.4.4.p0 +1.5.3.p0 diff --git a/build/pkgs/sphinx/patches/Makefile.patch b/build/pkgs/sphinx/patches/Makefile.patch deleted file mode 100644 index 8b695e32a57..00000000000 --- a/build/pkgs/sphinx/patches/Makefile.patch +++ /dev/null @@ -1,21 +0,0 @@ -Increase the memory sizes for LaTeX - -These increased stack sizes should be sufficient for LaTeX to handle the -huge index of the Sage PDF reference manual. - -diff -ru a/sphinx/texinputs/Makefile b/sphinx/texinputs/Makefile ---- a/sphinx/texinputs/Makefile 2016-03-06 06:25:30.000000000 +0100 -+++ b/sphinx/texinputs/Makefile 2016-04-06 19:33:07.248103397 +0200 -@@ -11,8 +11,10 @@ - # format: pdf or dvi - FMT = pdf - --LATEX = latex --PDFLATEX = pdflatex -+LATEXENV = env pool_size=4000000 save_size=50000 extra_mem_top=2000000 -+ -+LATEX = $(LATEXENV) latex -+PDFLATEX = $(LATEXENV) pdflatex - MAKEINDEX = makeindex - - all: $(ALLPDF) diff --git a/build/pkgs/sphinx/patches/environment.patch b/build/pkgs/sphinx/patches/environment.patch deleted file mode 100644 index d14ae5d7920..00000000000 --- a/build/pkgs/sphinx/patches/environment.patch +++ /dev/null @@ -1,18 +0,0 @@ -Prevent Sphinx from rebuilding documentation that is already built - ---- Sphinx-1.2.2/sphinx/environment.py.orig 2014-03-02 20:38:09.000000000 +1300 -+++ Sphinx-1.2.2/sphinx/environment.py 2014-10-19 23:31:15.000000000 +1300 -@@ -540,10 +540,13 @@ - else: - # check if a config value was changed that affects how - # doctrees are read -+ import inspect - for key, descr in iteritems(config.values): - if descr[1] != 'env': - continue - if self.config[key] != config[key]: -+ if inspect.isfunction(config[key]): -+ continue - msg = '[config changed] ' - config_changed = True - break From 78e671810360d3e02ec1e0fa6643a0e63f727f39 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 25 Jan 2017 16:42:34 +0100 Subject: [PATCH 108/185] Docbuild fixes for Sphinx 1.5.x --- src/sage/homology/simplicial_complex.py | 6 ++--- src/sage_setup/docbuild/__init__.py | 28 ------------------------ src/sage_setup/docbuild/ext/multidocs.py | 18 ++++++++------- 3 files changed, 13 insertions(+), 39 deletions(-) diff --git a/src/sage/homology/simplicial_complex.py b/src/sage/homology/simplicial_complex.py index c1106483024..462d0bf7091 100644 --- a/src/sage/homology/simplicial_complex.py +++ b/src/sage/homology/simplicial_complex.py @@ -195,8 +195,8 @@ def lattice_paths(t1, t2, length=None): :param length: if not ``None``, then an integer, the length of the desired path. :type length: integer or ``None``; optional, default ``None`` - :type t1: tuple, list, other iterable - :type t2: tuple, list, other iterable + :type t1: list, other iterable + :type t2: list, other iterable :return: list of lists of vertices making up the paths as described above :rtype: list of lists @@ -333,7 +333,7 @@ class Simplex(SageObject): tuple of the vertices. :param X: set of vertices - :type X: integer or list, tuple, or other iterable + :type X: integer, list, other iterable :return: simplex with those vertices ``X`` may be a non-negative integer `n`, in which case the diff --git a/src/sage_setup/docbuild/__init__.py b/src/sage_setup/docbuild/__init__.py index c155b4e629b..b93e74386d5 100644 --- a/src/sage_setup/docbuild/__init__.py +++ b/src/sage_setup/docbuild/__init__.py @@ -1578,32 +1578,6 @@ def fetch_inventory(self, app, uri, inv): return i -def patch_domain_init(): - """ - Applies a monkey-patch to the __init__ method of the Domain class in - Sphinx, in order to work around a bug. - - See https://trac.sagemath.org/ticket/21044 as well as - https://github.com/sphinx-doc/sphinx/pull/2816 for details about that - bug. - """ - - from sphinx.domains import Domain - import copy - - orig_init = Domain.__init__ - - def __init__(self, *args, **kwargs): - orig_init(self, *args, **kwargs) - - # Replace the original initial_data class attribute with a new - # deep-copy of itself, since the bug will cause the original - # initial_data to be modified in-place - self.__class__.initial_data = copy.deepcopy(self.initial_data) - - Domain.__init__ = __init__ - - def main(): # Parse the command-line. parser = setup_parser() @@ -1653,8 +1627,6 @@ def main(): ABORT_ON_ERROR = not options.keep_going - patch_domain_init() - # Delete empty directories. This is needed in particular for empty # directories due to "git checkout" which never deletes empty # directories it leaves behind. See Trac #20010. diff --git a/src/sage_setup/docbuild/ext/multidocs.py b/src/sage_setup/docbuild/ext/multidocs.py index 63dbb712616..47b232124ce 100644 --- a/src/sage_setup/docbuild/ext/multidocs.py +++ b/src/sage_setup/docbuild/ext/multidocs.py @@ -3,8 +3,6 @@ multi documentation in Sphinx ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - This is a slightly hacked-up version of the Sphinx-multidoc plugin - The goal of this extension is to manage a multi documentation in Sphinx. To be able to compile Sage's huge documentation in parallel, the documentation is cut into a bunch of independent documentations called @@ -57,7 +55,7 @@ def merge_environment(app, env): app.info(" %s todos, %s index, %s citations"%( len(docenv.todo_all_todos), len(docenv.indexentries), - len(docenv.citations) + len(docenv.domaindata["std"]["citations"]) ), nonl=1) # merge titles @@ -88,10 +86,10 @@ def merge_environment(app, env): env.metadata[ind] = md # merge the citations newcite = {} - for ind, (path, tag) in six.iteritems(docenv.citations): + for ind, (path, tag) in six.iteritems(docenv.domaindata["std"]["citations"]): # TODO: Warn on conflicts newcite[ind] = (fixpath(path), tag) - env.citations.update(newcite) + env.domaindata["std"]["citations"].update(newcite) # merge the py:module indexes newmodules = {} for ind,(modpath,v1,v2,v3) in ( @@ -102,9 +100,9 @@ def merge_environment(app, env): app.info('... done (%s todos, %s index, %s citations, %s modules)'%( len(env.todo_all_todos), len(env.indexentries), - len(env.citations), + len(env.domaindata["std"]["citations"]), len(env.domaindata['py']['modules']))) - write_citations(app, env.citations) + write_citations(app, env.domaindata["std"]["citations"]) def get_env(app, curdoc): """ @@ -146,6 +144,10 @@ def merge_js_index(app): titles = app.builder.indexer._titles for (res, title) in six.iteritems(index._titles): titles[fixpath(res)] = title + # merge the filenames + filenames = app.builder.indexer._filenames + for (res, filename) in six.iteritems(index._filenames): + filenames[fixpath(res)] = filename # TODO: merge indexer._objtypes, indexer._objnames as well # Setup source symbolic links @@ -244,7 +246,7 @@ def fetch_citation(app, env): with open(filename, 'rb') as f: cache = cPickle.load(f) app.builder.info("done (%s citations)."%len(cache)) - cite = env.citations + cite = env.domaindata["std"]["citations"] for ind, (path, tag) in six.iteritems(cache): if ind not in cite: # don't override local citation cite[ind]=(os.path.join("..", path), tag) From c8f968a0ee377a83c63d296b3bee58aad48116bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 13 Mar 2017 16:32:33 +0100 Subject: [PATCH 109/185] py: more care for range --- src/sage/graphs/generators/families.py | 2 +- src/sage/homology/matrix_utils.py | 4 ++-- src/sage/schemes/toric/variety.py | 9 +++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/sage/graphs/generators/families.py b/src/sage/graphs/generators/families.py index d6aebc26f2d..c05b2b22e73 100644 --- a/src/sage/graphs/generators/families.py +++ b/src/sage/graphs/generators/families.py @@ -2879,7 +2879,7 @@ def MuzychukS6Graph(n, d, Phi='fixed', Sigma='fixed', verbose=False): if Phi == 'random': Phi = {} for x in range(m): - temp = range(len(ParClasses)) + temp = list(range(len(ParClasses))) for line in L_i[x]: rand = randrange(0, len(temp)) Phi[(x, line)] = temp.pop(rand) diff --git a/src/sage/homology/matrix_utils.py b/src/sage/homology/matrix_utils.py index 415f9ebd2d3..222634e64c8 100644 --- a/src/sage/homology/matrix_utils.py +++ b/src/sage/homology/matrix_utils.py @@ -16,7 +16,7 @@ # http://www.gnu.org/licenses/ ######################################################################## from __future__ import print_function - +from six.moves import range # TODO: this module is a clear candidate for cythonizing. Need to # evaluate speed benefits. @@ -130,7 +130,7 @@ def dhsw_snf(mat, verbose=False): new_mat = new_mat.matrix_from_columns(range(cols)) if verbose: print("starting pass 2") - keep_columns = range(cols) + keep_columns = list(range(cols)) check_leading = True while check_leading: check_leading = False diff --git a/src/sage/schemes/toric/variety.py b/src/sage/schemes/toric/variety.py index 7d3a9cb4daa..933e4ce29ab 100644 --- a/src/sage/schemes/toric/variety.py +++ b/src/sage/schemes/toric/variety.py @@ -323,6 +323,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import print_function +from six.moves import range import sys @@ -642,7 +643,7 @@ def _an_element_(self): sage: P1xP1._an_element_() [1 : 2 : 3 : 4] """ - return self(range(1, self.ngens() + 1)) + return self(list(range(1, self.ngens() + 1))) def _check_satisfies_equations(self, coordinates): r""" @@ -1757,7 +1758,7 @@ def resolve(self, **kwds): if coordinate_names is None: coordinate_names = list(self.variable_names()) if coordinate_indices is None: - coordinate_indices = range(fan.nrays(), rfan.nrays()) + coordinate_indices = list(range(fan.nrays(), rfan.nrays())) else: coordinate_indices = coordinate_indices[fan.nrays():] coordinate_names.extend(normalize_names( @@ -3037,7 +3038,7 @@ def normalize_names(names=None, ngens=None, prefix=None, indices=None, raise IndexError("need %d names but only %d are given!" % (ngens, len(names))) if indices is None: - indices = range(ngens) + indices = list(range(ngens)) elif len(indices) != ngens: raise ValueError("need exactly %d indices, but got %d!" % (ngens, len(indices))) @@ -3516,6 +3517,6 @@ def exp(self): if not self.part_of_degree(0).is_zero(): raise ValueError('Must not have a constant part.') exp_x = self.parent().one() - for d in range(1,self.parent()._variety.dimension()+1): + for d in range(1, self.parent()._variety.dimension()+1): exp_x += self**d / factorial(d) return exp_x From a2f2ad5fcca366bb529f1ad7a95d49193db973ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jori=20M=C3=A4ntysalo?= Date: Mon, 13 Mar 2017 22:33:52 +0200 Subject: [PATCH 110/185] Typos. --- src/sage/combinat/posets/hasse_diagram.py | 2 +- src/sage/combinat/posets/lattices.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/posets/hasse_diagram.py b/src/sage/combinat/posets/hasse_diagram.py index 03a07df7c09..0d48a8c0858 100644 --- a/src/sage/combinat/posets/hasse_diagram.py +++ b/src/sage/combinat/posets/hasse_diagram.py @@ -1819,7 +1819,7 @@ def antichains_iterator(self): sage: list(H.antichains_iterator()) [[]] """ - # NOTE: Ordering of antichains as a prefix tree is crusial for + # NOTE: Ordering of antichains as a prefix tree is crucial for # congruences_iterator() to work. Change it, if you change this. # Complexity note: diff --git a/src/sage/combinat/posets/lattices.py b/src/sage/combinat/posets/lattices.py index c61fb24fc07..2e2a6d00766 100644 --- a/src/sage/combinat/posets/lattices.py +++ b/src/sage/combinat/posets/lattices.py @@ -63,7 +63,7 @@ :meth:`~FiniteLatticePoset.is_simple` | Return ``True`` if the lattice has no nontrivial congruences. :meth:`~FiniteLatticePoset.is_isoform` | Return ``True`` if all congruences of the lattice consists of isoform blocks. :meth:`~FiniteLatticePoset.is_uniform` | Return ``True`` if all congruences of the lattice consists of equal-sized blocks. - :meth:`~FiniteLatticePoset.is_regular` | Return ``True`` if all congruences of lattice are determined by any of the congruence block. + :meth:`~FiniteLatticePoset.is_regular` | Return ``True`` if all congruences of lattice are determined by any of the congruence blocks. :meth:`~FiniteLatticePoset.is_subdirectly_reducible` | Return ``True`` if the lattice is a sublattice of the product of smaller lattices. :meth:`~FiniteLatticePoset.breadth` | Return the breadth of the lattice. From 3184bc255e1d2f06b21e2455ac70ef333bfced4b Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Mon, 13 Mar 2017 19:11:57 +0100 Subject: [PATCH 111/185] Set() should take arbitrary iterables as input --- src/sage/categories/finite_posets.py | 2 +- src/sage/combinat/perfect_matching.py | 2 +- src/sage/combinat/set_partition.py | 2 +- src/sage/sets/set.py | 132 +++++++++++++++++--------- 4 files changed, 91 insertions(+), 47 deletions(-) diff --git a/src/sage/categories/finite_posets.py b/src/sage/categories/finite_posets.py index 27355b8de2b..8613a8457aa 100644 --- a/src/sage/categories/finite_posets.py +++ b/src/sage/categories/finite_posets.py @@ -426,7 +426,7 @@ def rowmotion(self, order_ideal): sage: P = Poset( {} ) sage: I = Set({}) sage: P.rowmotion(I) - Set of elements of {} + {} """ result = order_ideal for i in reversed(self.linear_extension()): diff --git a/src/sage/combinat/perfect_matching.py b/src/sage/combinat/perfect_matching.py index 540fca191bc..aa99a8f93c9 100644 --- a/src/sage/combinat/perfect_matching.py +++ b/src/sage/combinat/perfect_matching.py @@ -194,7 +194,7 @@ def __classcall_private__(cls, p): if not(p.cycle_type() == [2 for i in range(n//2)]): raise ValueError("The permutation p (= %s) is not a " "fixed point free involution" % p) - objects = Set(list(range(1, n + 1))) + objects = Set(range(1, n + 1)) data = p.to_cycles() # Third case: p is already a perfect matching, we return p directly elif isinstance(p, PerfectMatching): diff --git a/src/sage/combinat/set_partition.py b/src/sage/combinat/set_partition.py index 8741cdcc1bf..3bce7c67613 100644 --- a/src/sage/combinat/set_partition.py +++ b/src/sage/combinat/set_partition.py @@ -1627,7 +1627,7 @@ def _listbloc(n, nbrepets, listint=None): True """ if isinstance(listint, (int, Integer)) or listint is None: - listint = Set(list(range(1,n+1))) + listint = Set(range(1,n+1)) if nbrepets == 1: yield Set([listint]) diff --git a/src/sage/sets/set.py b/src/sage/sets/set.py index 15afced7f2a..39e1add0c91 100644 --- a/src/sage/sets/set.py +++ b/src/sage/sets/set.py @@ -41,6 +41,7 @@ from sage.misc.prandom import choice from sage.misc.misc import is_iterator +from sage.structure.category_object import CategoryObject from sage.structure.element import Element from sage.structure.parent import Parent, Set_generic @@ -49,7 +50,41 @@ import sage.rings.infinity -def Set(X=frozenset()): + +def has_finite_length(obj): + """ + Return ``True`` if ``obj`` is known to have finite length. + + This is mainly meant for pure Python types, so we do not call any + Sage-specific methods. + + EXAMPLES:: + + sage: from sage.sets.set import has_finite_length + sage: has_finite_length(tuple(range(10))) + True + sage: has_finite_length(list(range(10))) + True + sage: has_finite_length(set(range(10))) + True + sage: has_finite_length(iter(range(10))) + False + sage: has_finite_length(GF(17^127)) + True + sage: has_finite_length(ZZ) + False + """ + try: + len(obj) + except OverflowError: + return True + except Exception: + return False + else: + return True + + +def Set(X=[]): r""" Create the underlying set of ``X``. @@ -100,11 +135,15 @@ def Set(X=frozenset()): sage: 5 in X False - Set also accepts iterators, but be careful to only give *finite* sets. + Set also accepts iterators, but be careful to only give *finite* + sets:: - :: - - sage: list(Set(iter([1, 2, 3, 4, 5]))) + sage: from six.moves import range + sage: sorted(Set(range(1,6))) + [1, 2, 3, 4, 5] + sage: sorted(Set(list(range(1,6)))) + [1, 2, 3, 4, 5] + sage: sorted(Set(iter(range(1,6)))) [1, 2, 3, 4, 5] We can also create sets from different types:: @@ -112,12 +151,20 @@ def Set(X=frozenset()): sage: sorted(Set([Sequence([3,1], immutable=True), 5, QQ, Partition([3,1,1])]), key=str) [5, Rational Field, [3, 1, 1], [3, 1]] - However each of the objects must be hashable:: + Sets with unhashable objects work, but with less functionality:: - sage: Set([QQ, [3, 1], 5]) + sage: A = Set([QQ, (3, 1), 5]) # hashable + sage: sorted(A.list(), key=repr) + [(3, 1), 5, Rational Field] + sage: type(A) + + sage: B = Set([QQ, [3, 1], 5]) # unhashable + sage: sorted(B.list(), key=repr) Traceback (most recent call last): ... - TypeError: unhashable type: 'list' + AttributeError: 'Set_object_with_category' object has no attribute 'list' + sage: type(B) + TESTS:: @@ -137,24 +184,24 @@ def Set(X=frozenset()): sage: Set() {} """ - if is_Set(X): - return X + if isinstance(X, CategoryObject): + if is_Set(X): + return X + elif X in Sets().Finite(): + return Set_object_enumerated(X) + else: + return Set_object(X) if isinstance(X, Element): raise TypeError("Element has no defined underlying set") - elif isinstance(X, (list, tuple, set, frozenset)): - return Set_object_enumerated(frozenset(X)) + try: - if X.is_finite(): - return Set_object_enumerated(X) - except AttributeError: - pass - if is_iterator(X): - # Note we are risking an infinite loop here, - # but this is the way Python behaves too: try - # sage: set(an iterator which does not terminate) - return Set_object_enumerated(list(X)) - return Set_object(X) + X = frozenset(X) + except TypeError: + return Set_object(X) + else: + return Set_object_enumerated(X) + def is_Set(x): """ @@ -204,7 +251,7 @@ class Set_object(Set_generic): sage: 1 == Set([0]), Set([0]) == 1 (False, False) """ - def __init__(self, X): + def __init__(self, X, category=None): """ Create a Set_object @@ -215,6 +262,8 @@ def __init__(self, X): sage: type(Set(QQ)) + sage: Set(QQ).category() + Category of sets TESTS:: @@ -225,21 +274,13 @@ def __init__(self, X): '' and 'Integer Ring' """ - from six.moves import range from sage.rings.integer import is_Integer if isinstance(X, (int, long)) or is_Integer(X): # The coercion model will try to call Set_object(0) raise ValueError('underlying object cannot be an integer') - category = Sets() - if X in Sets().Finite() or isinstance(X, (tuple, list, - set, frozenset)): - category = Sets().Finite() - - elif isinstance(X, range): - category = Sets().Finite() - X = tuple(X) - + if category is None: + category = Sets() Parent.__init__(self, category=category) self.__object = X @@ -291,7 +332,7 @@ def _repr_(self): sage: X { integers } """ - return "Set of elements of %s"%self.__object + return "Set of elements of " + repr(self.__object) def __iter__(self): """ @@ -576,11 +617,8 @@ def cardinality(self): sage: Set(GF(5^2,'a')).cardinality() 25 """ - try: - if not self.is_finite(): - return sage.rings.infinity.infinity - except (AttributeError, NotImplementedError): - pass + if not self.is_finite(): + return sage.rings.infinity.infinity if self is not self.__object: try: @@ -646,10 +684,13 @@ def is_finite(self): sage: Set([1,'a',ZZ]).is_finite() True """ - if isinstance(self.__object, (set, frozenset, tuple, list)): - return True + obj = self.__object + try: + is_finite = obj.is_finite + except AttributeError: + return has_finite_length(obj) else: - return self.__object.is_finite() + return is_finite() def object(self): """ @@ -683,6 +724,7 @@ def subsets(self,size=None): from sage.combinat.subset import Subsets return Subsets(self,size) + class Set_object_enumerated(Set_object): """ A finite enumerated set. @@ -695,11 +737,13 @@ def __init__(self, X): sage: S = Set(GF(19)); S {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18} + sage: S.category() + Category of finite sets sage: print(latex(S)) \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() """ - Set_object.__init__(self, X) + Set_object.__init__(self, X, category=Sets().Finite()) def random_element(self): r""" @@ -1475,7 +1519,7 @@ def __cmp__(self, right): return -1 if not isinstance(right, Set_object_difference): return -1 - if self._X == right._X and self._Y == right._Y: + if self._X == right._X and self._Y == right._Y: return 0 return -1 From 01d06c7790e1ef11e961fa3015d70a9856d952a4 Mon Sep 17 00:00:00 2001 From: paulmasson Date: Mon, 13 Mar 2017 17:36:00 -0700 Subject: [PATCH 112/185] Edit and add links --- src/doc/en/developer/git_trac.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/doc/en/developer/git_trac.rst b/src/doc/en/developer/git_trac.rst index 8fe86130741..bd30c04870d 100644 --- a/src/doc/en/developer/git_trac.rst +++ b/src/doc/en/developer/git_trac.rst @@ -357,12 +357,13 @@ This creates a new "merge" commit, joining your current branch and * Or you definitely need a feature that has been developed as part of another branch. -A special case of merging is merging in the ``master`` branch. This +A special case of merging is merging in the ``develop`` branch. This brings your local branch up to date with the newest Sage version. The above warning against unnecessary merges still applies, though. Try to do all of your development with the Sage version that you originally -started with. The only reason for merging in the master branch is if -you need a new feature or if your branch conflicts. +started with. The only reason for merging in the ``develop`` branch is if +you need a new feature or if your branch conflicts. See +:ref:`section-git-update-latest` for details. .. _section-git_trac-collaborate: @@ -555,7 +556,7 @@ To review tickets with minimal recompiling, start by building the "develop" branch, that is, the latest beta. Just checking out an older ticket would most likely reset the Sage tree to an older version, so you would have to compile older versions of packages to make it work. Instead, you can create an anonymous -("detached HEAD") merge of the ticket and the develop branch:: +("detached HEAD") merge of the ticket and the develop branch using :: $ git trac try 12345 @@ -563,10 +564,10 @@ This will only touch files that are really modified by the ticket. In particular if only Python files are changed by the ticket (which is true for most tickets) then you just have to run ``sage -b`` to rebuild the Sage library. If files other than Python have been changed, you must run ``make``. When you are finished -reviewing, just checkout a named branch, for example :: +reviewing, just check out a named branch, for example :: $ git checkout develop If you want to edit the ticket branch (that is, add additional commits) you cannot -use ``git trac try``. You must use ``git trac checkout`` to get the actual ticket +use ``git trac try``. You must :ref:`section-git_trac-checkout` to get the actual ticket branch as a starting point. From d3b70e5253ecaa9507930b75266d5dc86e259d5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jori=20M=C3=A4ntysalo?= Date: Tue, 14 Mar 2017 07:02:30 +0200 Subject: [PATCH 113/185] Docstring formatting. --- src/sage/combinat/posets/lattices.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/posets/lattices.py b/src/sage/combinat/posets/lattices.py index 2e2a6d00766..c557dfa4bad 100644 --- a/src/sage/combinat/posets/lattices.py +++ b/src/sage/combinat/posets/lattices.py @@ -3886,7 +3886,7 @@ def congruences_lattice(self, labels='congruence'): INPUT: - - ``labels``, a string -- type of elements of resulting lattice + - ``labels`` -- a string; the type of elements in the resulting lattice OUTPUT: From e18c726d30af85869e56778c1192277858499180 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Tue, 14 Mar 2017 13:11:24 +0100 Subject: [PATCH 114/185] Only invert an action if it is invertible --- src/sage/categories/action.pxd | 6 ++--- src/sage/categories/action.pyx | 42 ++++++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/sage/categories/action.pxd b/src/sage/categories/action.pxd index 4db2c62fc6a..e660316e397 100644 --- a/src/sage/categories/action.pxd +++ b/src/sage/categories/action.pxd @@ -4,10 +4,10 @@ from .map cimport Map from .functor cimport Functor cdef class Action(Functor): - cdef G + cdef readonly G + cdef readonly op + cdef readonly bint _is_left cdef US - cdef bint _is_left - cdef op cdef underlying_set(self) cpdef _call_(self, a, b) diff --git a/src/sage/categories/action.pyx b/src/sage/categories/action.pyx index 2712fe79964..0dadfd70567 100644 --- a/src/sage/categories/action.pyx +++ b/src/sage/categories/action.pyx @@ -212,10 +212,37 @@ cdef class InverseAction(Action): """ An action that acts as the inverse of the given action. - TESTS: + EXAMPLES:: - This illustrates a shortcoming in the current coercion model. - See the comments in _call_ below:: + 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: 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) + (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) + (3, 6, 9) + + sage: c = cm.get_action(ZZ, list, operator.mul) + sage: c + Left action by Integer Ring on + sage: ~c + Traceback (most recent call last): + ... + TypeError: no inverse defined for Left action by Integer Ring on + + TESTS: sage: x = polygen(QQ,'x') sage: a = 2*x^2+2; a @@ -231,19 +258,14 @@ cdef class InverseAction(Action): try: from sage.groups.group import is_Group # We must be in the case that parent(~a) == parent(a) - # so we can invert in call_c code below. + # so we can invert in _call_ code below. if (is_Group(G) and G.is_multiplicative()) or G.is_field(): Action.__init__(self, G, action.underlying_set(), action._is_left) self._action = action return - else: - K = G._pseudo_fraction_field() - Action.__init__(self, K, action.underlying_set(), action._is_left) - self._action = action - return except (AttributeError, NotImplementedError): pass - raise TypeError("No inverse defined for %r." % action) + raise TypeError(f"no inverse defined for {action!r}") cpdef _call_(self, a, b): if self._action._is_left: From fed37d779356f22bb1c9f53b3c1016aca11ab692 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Tue, 14 Mar 2017 13:00:43 +0000 Subject: [PATCH 115/185] Fix dynatomic polynomial test. Only the scaling factor changed. --- src/sage/schemes/affine/affine_morphism.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/schemes/affine/affine_morphism.py b/src/sage/schemes/affine/affine_morphism.py index d061b40834b..611b274b729 100644 --- a/src/sage/schemes/affine/affine_morphism.py +++ b/src/sage/schemes/affine/affine_morphism.py @@ -670,7 +670,7 @@ def dynatomic_polynomial(self, period): sage: H = Hom(A,A) sage: F = H([1/2*x^2 + sqrt(3)]) sage: F.dynatomic_polynomial([1,1]) - (2.00000000000000*x^4 + 5.85640646055102*x^2 + 24.0000000000000)/(x^2 + (-2.00000000000000)*x + 3.46410161513775) + (0.125000000000000*x^4 + 0.366025403784439*x^2 + 1.50000000000000)/(0.500000000000000*x^2 - x + 1.73205080756888) """ if self.domain() != self.codomain(): raise TypeError("must have same domain and codomain to iterate") From 516f0291f093af9415003b6b99c7d0ecb1ee8ac8 Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Tue, 14 Mar 2017 15:02:10 +0100 Subject: [PATCH 116/185] Upgraded to R 3.3.3 --- build/pkgs/r/SPKG.txt | 5 +++++ build/pkgs/r/checksums.ini | 6 +++--- build/pkgs/r/package-version.txt | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/build/pkgs/r/SPKG.txt b/build/pkgs/r/SPKG.txt index f455817542c..a6b1e72ab2c 100644 --- a/build/pkgs/r/SPKG.txt +++ b/build/pkgs/r/SPKG.txt @@ -22,3 +22,8 @@ much code written for S runs unaltered under R. * iconv * Readline * BLAS/LAPACK + * xz + * pcre + * curl + * https-capable SSL + diff --git a/build/pkgs/r/checksums.ini b/build/pkgs/r/checksums.ini index 4c348a19482..f8426dd9e83 100644 --- a/build/pkgs/r/checksums.ini +++ b/build/pkgs/r/checksums.ini @@ -1,4 +1,4 @@ tarball=R-VERSION.tar.gz -sha1=0e39e9c2d28fe6bab9c55ca23e08ba8727fd2fca -md5=2437014ef40641cdc9673e89c040b7a8 -cksum=1781035256 +sha1=9e205a817970578ecd80384f397bae35b46f13b9 +md5=0ac211ec15e813a24f8f4a5a634029a4 +cksum=3798762927 diff --git a/build/pkgs/r/package-version.txt b/build/pkgs/r/package-version.txt index e5691ee639c..82a836a7c0c 100644 --- a/build/pkgs/r/package-version.txt +++ b/build/pkgs/r/package-version.txt @@ -1 +1 @@ -3.3.2.p0 +3.3.3.p0 From e25848924e7dc74d4a5cc41470997bccb20b3013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Tue, 14 Mar 2017 16:30:19 +0100 Subject: [PATCH 117/185] Fix indentation --- src/sage/tests/py3_syntax.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/tests/py3_syntax.py b/src/sage/tests/py3_syntax.py index 2732064538c..b31bfddcb28 100644 --- a/src/sage/tests/py3_syntax.py +++ b/src/sage/tests/py3_syntax.py @@ -53,7 +53,7 @@ def __iter__(self): sage: test = Python3SyntaxTest('sage/tests/french_book') sage: next(iter(test)) ('src/sage/tests/french_book', 'README', '') - """ + """ tree_walk = itertools.chain(*map(os.walk, self._directories)) for path, _, files in tree_walk: path = os.path.relpath(path) From d9ce045dbbd4edbc452d3830536a532c9c7ea8f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20R=C3=BCth?= Date: Tue, 14 Mar 2017 17:06:43 +0100 Subject: [PATCH 118/185] Make py3_syntax.py compliant with our style guide --- src/sage/tests/py3_syntax.py | 87 +++++++++++++++++++++++++----------- 1 file changed, 61 insertions(+), 26 deletions(-) diff --git a/src/sage/tests/py3_syntax.py b/src/sage/tests/py3_syntax.py index b31bfddcb28..b8ed8c23924 100644 --- a/src/sage/tests/py3_syntax.py +++ b/src/sage/tests/py3_syntax.py @@ -1,12 +1,31 @@ -""" +r""" Test that the Sage library uses Python 3 syntax +AUTHORS: + +- Volker Braun (2017-02-11): initial version + +- Frédéric Chapoton (2017-02-28): fixes + +- Julian Rüth (2017-03-14): documentation changes + EXAMPLES:: sage: from sage.tests.py3_syntax import Python3SyntaxTest sage: py3_syntax = Python3SyntaxTest('sage', 'sage_setup') sage: py3_syntax.run_tests('.py') # long time """ +#***************************************************************************** +# Copyright (C) 2017 Volker Braun +# 2017 Frédéric Chapoton +# 2017 Julian Rüth +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** from __future__ import print_function @@ -16,30 +35,35 @@ from sage.env import SAGE_SRC - class SortedDirectoryWalkerABC(object): + r""" + Walks the directory tree in a reproducible manner. - def __init__(self, *directories): - """ - Walk directory tree in a reproducible manner + INPUT: - INPUT: + - ``*directories`` -- roots of the directory trees to walk - -- ``*directories`` - Roots of the directory trees to walk. + EXAMPLES:: - EXAMPLES:: + sage: from sage.tests.py3_syntax import SortedDirectoryWalkerABC + sage: walker = SortedDirectoryWalkerABC('sage/tests') - sage: from sage.tests.py3_syntax import Python3SyntaxTest - sage: Python3SyntaxTest('sage/tests') - + """ + def __init__(self, *directories): + r""" + TESTS:: + + sage: from sage.tests.py3_syntax import Python3SyntaxTest, SortedDirectoryWalkerABC + sage: isinstance(Python3SyntaxTest('sage/tests'), SortedDirectoryWalkerABC) + True """ self._directories = tuple( os.path.join(SAGE_SRC, d) for d in directories ) def __iter__(self): - """ - Iterate over files + r""" + Return an iterator over the files in the directories. OUTPUT: @@ -65,16 +89,13 @@ def __iter__(self): yield (path, filename, ext) def run_tests(self, *extensions): - """ - Run tests - - The abstract :meth:`test` is called on each file with a - matching extension. + r""" + Run :meth:`test` on each file with a matching extension. INPUT: - -- ``*extensions`` - the file extensions (including the leading dot) - to check. + - ``*extensions`` -- the file extensions (including the leading dot) to + check EXAMPLES:: @@ -96,14 +117,14 @@ def run_tests(self, *extensions): self.test(*buf) def test(self, *filenames): - """ - Test the given filenames + r""" + Test the given filenames. To be implemented in derived classes. INPUT: - -- ``*filename`` -- string. The full qualified filenames to check. + - ``*filenames`` -- the fully qualified filenames to check EXAMPLES:: @@ -122,16 +143,30 @@ def test(self, *filenames): PYTHON3_ENV = dict(os.environ) PYTHON3_ENV.pop('PYTHONPATH', None) - class Python3SyntaxTest(SortedDirectoryWalkerABC): + r""" + Walks the directory tree and tests that all Python files are valid Python 3 + syntax. + + INPUT: + + - ``*directories`` -- roots of the directory trees to walk + + EXAMPLES:: + + sage: from sage.tests.py3_syntax import Python3SyntaxTest + sage: walker = Python3SyntaxTest('sage/tests') + sage: walker.run_tests('.py') # long time + """ def test(self, *filenames): r""" - Test that the given filenames are valid Python 3 syntax + Print an error message if the given files are not using valid Python 3 + syntax. INPUT: - -- ``filename`` -- string. The full qualified filename to check. + - ``*filenames`` -- the fully qualified filenames to check EXAMPLES:: From 91d86a43fd5096df085e1a7321ee907c20fb7b47 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Tue, 14 Mar 2017 07:52:56 -0500 Subject: [PATCH 119/185] Native implementation of Weyl groups as permutations and refactoring. --- src/sage/categories/affine_weyl_groups.py | 2 +- .../finite_complex_reflection_groups.py | 310 +++++ src/sage/categories/finite_coxeter_groups.py | 13 + .../combinat/root_system/dynkin_diagram.py | 12 +- .../root_system/reflection_group_c.pyx | 17 +- .../root_system/reflection_group_complex.py | 978 +-------------- .../root_system/reflection_group_element.pxd | 8 + .../root_system/reflection_group_element.pyx | 1099 +++++++++++++++++ .../root_system/reflection_group_real.py | 433 +------ src/sage/combinat/root_system/weyl_group.py | 380 +++++- 10 files changed, 1845 insertions(+), 1407 deletions(-) create mode 100644 src/sage/combinat/root_system/reflection_group_element.pxd create mode 100644 src/sage/combinat/root_system/reflection_group_element.pyx diff --git a/src/sage/categories/affine_weyl_groups.py b/src/sage/categories/affine_weyl_groups.py index e24b98181fd..b7cb2047e4e 100644 --- a/src/sage/categories/affine_weyl_groups.py +++ b/src/sage/categories/affine_weyl_groups.py @@ -35,7 +35,7 @@ class AffineWeylGroups(Category_singleton): sage: W = WeylGroup(["A",4,1]); W Weyl Group of type ['A', 4, 1] (as a matrix group acting on the root space) sage: W.category() - Category of affine weyl groups + Category of irreducible affine weyl groups TESTS:: diff --git a/src/sage/categories/finite_complex_reflection_groups.py b/src/sage/categories/finite_complex_reflection_groups.py index 7209298e024..28a6a6a2edb 100644 --- a/src/sage/categories/finite_complex_reflection_groups.py +++ b/src/sage/categories/finite_complex_reflection_groups.py @@ -486,6 +486,44 @@ def is_real(self): """ return self.degrees().count(2) == self.number_of_irreducible_components() + @cached_method + def base_change_matrix(self): + r""" + Return the base change from the standard basis of the vector + space of ``self`` to the basis given by the independent roots of + ``self``. + + .. TODO:: + + For non-well-generated groups there is a conflict with + construction of the matrix for an element. + + EXAMPLES:: + + 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 + [1 0 0] + [0 1 0] + [0 0 1] + + 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 + [ 1 0] + [E(4) 1] + """ + from sage.matrix.all import Matrix + return Matrix( list(self.independent_roots()) ).inverse() + class ElementMethods: @abstract_method(optional=True) @@ -567,6 +605,46 @@ def character_value(self): """ return self.to_matrix().trace() + #@cached_in_parent_method + def reflection_length(self, in_unitary_group=False): + r""" + Return the reflection length of ``self``. + + This is the minimal numbers of reflections needed to + obtain ``self``. + + INPUT: + + - ``in_unitary_group`` -- (default: ``False``) if ``True``, + the reflection length is computed in the unitary group + which is the dimension of the move space of ``self`` + + EXAMPLES:: + + 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 + [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 + [0, 1, 1, 2] + + 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() + if in_unitary_group or W.is_real(): + from sage.matrix.special import identity_matrix + I = identity_matrix(self.parent().rank()) + return W.rank() - (self.to_matrix() - I).right_nullity() + else: + return len(self.reduced_word_in_reflections()) + class Irreducible(CategoryWithAxiom): def example(self): @@ -602,6 +680,238 @@ def coxeter_number(self): return (self.number_of_reflection_hyperplanes() + self.number_of_reflections()) // self.rank() + def elements_below_coxeter_element(self, c=None): + r""" + Return all elements in ``self`` in the interval `[1,c]` in the + absolute order of ``self``. + + This order is defined by + + .. MATH:: + + \omega \leq_R \tau \Leftrightarrow \ell_R(\omega) + + \ell_R(\omega^{-1} \tau) = \ell_R(\tau), + + where `\ell_R` denotes the reflection length. + + .. NOTE:: + + ``self`` is assumed to be well-generated. + + INPUT: + + - ``c`` -- (default: ``None``) if an element ``c`` is given, it + is used as the maximal element in the interval; if a list is + given, the union of the various maximal elements is computed + + EXAMPLES:: + + sage: W = ReflectionGroup((1,1,3)) # optional - gap3 + + sage: sorted( w.reduced_word() for w in W.elements_below_coxeter_element() ) # optional - gap3 + [[], [1], [1, 2], [1, 2, 1], [2]] + + sage: sorted( w.reduced_word() for w in W.elements_below_coxeter_element(W.from_reduced_word([2,1])) ) # optional - gap3 + [[], [1], [1, 2, 1], [2], [2, 1]] + + sage: sorted( w.reduced_word() for w in W.elements_below_coxeter_element(W.from_reduced_word([2])) ) # optional - gap3 + [[], [2]] + """ + if c in self: + cs = [c] + elif c is None: + cs = [self.coxeter_element()] + else: + cs = list(c) + l = cs[0].reflection_length(in_unitary_group=True) + f = lambda pi: any(pi.reflection_length(in_unitary_group=True) + + (c*pi**-1).reflection_length(in_unitary_group=True) == l + for c in cs) + # first computing the conjugacy classes only needed if the + # interaction with gap3 is slow due to a bug + #self.conjugacy_classes() + return filter(f, self) + + # TODO: have a cached and an uncached version + @cached_method + def noncrossing_partition_lattice(self, c=None, L=None, in_unitary_group=False): + r""" + Return the interval `[1,c]` in the absolute order of + ``self`` as a finite lattice. + + .. SEEALSO:: :meth:`elements_below_coxeter_element` + + INPUT: + + - ``c`` -- (default: ``None``) if an element ``c`` in ``self`` is + given, it is used as the maximal element in the interval + + - ``L`` -- (default: ``None``) if a subset ``L`` (must be hashable!) + of ``self`` is given, it is used as the underlying set (only + cover relations are checked) + + - ``in_unitary_group`` -- (default: ``False``) if ``False``, the + relation is given by `\sigma \leq \tau` if + `l_R(\sigma) + l_R(\sigma^{-1}\tau) = l_R(\tau)`; + if ``True``, the relation is given by `\sigma \leq \tau` if + `\dim(\mathrm{Fix}(\sigma)) + \dim(\mathrm{Fix}(\sigma^{-1}\tau)) + = \dim(\mathrm{Fix}(\tau))` + + EXAMPLES:: + + sage: W = ReflectionGroup((1,1,3)) # optional - gap3 + + sage: sorted( w.reduced_word() for w in W.noncrossing_partition_lattice() ) # optional - gap3 + [[], [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 + [[], [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 + [[], [2]] + """ + from sage.combinat.posets.all import Poset, LatticePoset + if c is None: + c = self.coxeter_element() + + smart_covers = not in_unitary_group + + if self.is_real(): + smart_covers = in_unitary_group = True + + R = self.reflections() + if L is None: + L = self.elements_below_coxeter_element(c=c) + if c.is_coxeter_element(): + smart_covers = in_unitary_group = True + rels = [] + ref_lens = {w: w.reflection_length(in_unitary_group=in_unitary_group) + for w in L} + if smart_covers: + for pi in L: + for t in R: + tau = pi*t + if tau in L and ref_lens[pi] + 1 == ref_lens[tau]: + rels.append((pi,tau)) + else: + rels = [(pi,tau) for pi in L for tau in L + if ref_lens[pi] + ref_lens[pi.inverse()*tau] == ref_lens[tau]] + P = Poset((L,rels), cover_relations=smart_covers, facade=True) + if P.is_lattice(): + return LatticePoset(P) + else: + return P + + def generalized_noncrossing_partitions(self, m, c=None, positive=False): + r""" + Return the set of all chains of length ``m`` in the + noncrossing partition lattice of ``self``, see + :meth:`noncrossing_partition_lattice`. + + .. NOTE:: + + ``self`` is assumed to be well-generated. + + INPUT: + + - ``c`` -- (default: ``None``) if an element ``c`` in ``self`` + is given, it is used as the maximal element in the interval + + - ``positive`` -- (default: ``False``) if ``True``, only those + generalized noncrossing partitions of full support are returned + + EXAMPLES:: + + sage: W = ReflectionGroup((1,1,3)) # optional - gap3 + + sage: sorted([w.reduced_word() for w in chain] # optional - gap3 + ....: for chain in W.generalized_noncrossing_partitions(2)) # optional - gap3 + [[[], [], [1, 2]], + [[], [1], [2]], + [[], [1, 2], []], + [[], [1, 2, 1], [1]], + [[], [2], [1, 2, 1]], + [[1], [], [2]], + [[1], [2], []], + [[1, 2], [], []], + [[1, 2, 1], [], [1]], + [[1, 2, 1], [1], []], + [[2], [], [1, 2, 1]], + [[2], [1, 2, 1], []]] + + sage: sorted([w.reduced_word() for w in chain] # optional - gap3 + ....: for chain in W.generalized_noncrossing_partitions(2, positive=True)) # optional - gap3 + [[[], [1, 2], []], + [[], [1, 2, 1], [1]], + [[1], [2], []], + [[1, 2], [], []], + [[1, 2, 1], [], [1]], + [[1, 2, 1], [1], []], + [[2], [1, 2, 1], []]] + """ + from sage.combinat.combination import Combinations + NC = self.noncrossing_partition_lattice(c=c) + one = self.one() + if c is None: + c = self.coxeter_element() + chains = NC.chains() + NCm = set() + iter = chains.breadth_first_search_iterator() + chain = next(iter) + chain = next(iter) + while len(chain) <= m: + chain.append(c) + for i in range(len(chain)-1, 0, -1): + chain[i] = chain[i-1]**-1 * chain[i] + k = m + 1 - len(chain) + for positions in Combinations(range(m+1),k): + ncm = [] + for l in range(m+1): + if l in positions: + ncm.append(one) + else: + l_prime = l - len([i for i in positions if i <= l]) + ncm.append(chain[l_prime]) + if not positive or prod(ncm[:-1]).has_full_support(): + NCm.add(tuple(ncm)) + try: + chain = next(iter) + except StopIteration: + chain = list(range(m + 1)) + return NCm + + # TODO: have a cached and an uncached version + def absolute_poset(self, in_unitary_group=False): + r""" + Return the poset induced by the absolute order of ``self`` + as a finite lattice. + + INPUT: + + - ``in_unitary_group`` -- (default: ``False``) if ``False``, + the relation is given by ``\sigma \leq \tau`` if + `l_R(\sigma) + l_R(\sigma^{-1}\tau) = l_R(\tau)` + If ``True``, the relation is given by `\sigma \leq \tau` if + `\dim(\mathrm{Fix}(\sigma)) + \dim(\mathrm{Fix}(\sigma^{-1}\tau)) + = \dim(\mathrm{Fix}(\tau))` + + .. SEEALSO:: :meth:`noncrossing_partition_lattice` + + EXAMPLES:: + + sage: P = ReflectionGroup((1,1,3)).absolute_poset(); P # optional - gap3 + Finite poset containing 6 elements + + sage: sorted(w.reduced_word() for w in P) # optional - gap3 + [[], [1], [1, 2], [1, 2, 1], [2], [2, 1]] + + sage: W = ReflectionGroup(4); W # optional - gap3 + Irreducible complex reflection group of rank 2 and type ST4 + sage: W.absolute_poset() # optional - gap3 + Finite poset containing 24 elements + """ + return self.noncrossing_partition_lattice(L=self, in_unitary_group=in_unitary_group) + class WellGenerated(CategoryWithAxiom): def example(self): diff --git a/src/sage/categories/finite_coxeter_groups.py b/src/sage/categories/finite_coxeter_groups.py index 003ca335fcf..31aad3907ed 100644 --- a/src/sage/categories/finite_coxeter_groups.py +++ b/src/sage/categories/finite_coxeter_groups.py @@ -670,6 +670,19 @@ def cambrian_lattice(self, c, on_roots=False): """ return self.m_cambrian_lattice(c=c, m=1, on_roots=on_roots) + def is_real(self): + """ + Return ``True`` since ``self`` is a real reflection group. + + EXMAPLES:: + + sage: CoxeterGroup(['F',4]).is_real() + True + sage: CoxeterGroup(['H',4]).is_real() + True + """ + return True + class ElementMethods: @cached_in_parent_method diff --git a/src/sage/combinat/root_system/dynkin_diagram.py b/src/sage/combinat/root_system/dynkin_diagram.py index bebe22fabbf..a8abd57a160 100644 --- a/src/sage/combinat/root_system/dynkin_diagram.py +++ b/src/sage/combinat/root_system/dynkin_diagram.py @@ -607,8 +607,18 @@ def is_irreducible(self): sage: CartanType(['F',4]).dynkin_diagram().is_irreducible() True + sage: CM = CartanMatrix([[2,-6],[-4,2]]) + sage: CM.dynkin_diagram().is_irreducible() + True + sage: CartanType("A2xB3").dynkin_diagram().is_irreducible() + False + sage: CM = CartanMatrix([[2,-6,0],[-4,2,0],[0,0,2]]) + sage: CM.dynkin_diagram().is_irreducible() + False """ - return self._cartan_type.is_irreducible() + if self._cartan_type is not None: + return self._cartan_type.is_irreducible() + return self.connected_components_number() == 1 def is_crystallographic(self): """ diff --git a/src/sage/combinat/root_system/reflection_group_c.pyx b/src/sage/combinat/root_system/reflection_group_c.pyx index 56e5f7e7e39..d2d6b45cbb1 100644 --- a/src/sage/combinat/root_system/reflection_group_c.pyx +++ b/src/sage/combinat/root_system/reflection_group_c.pyx @@ -1,3 +1,4 @@ +#cython: wraparound=False, boundscheck=False r""" This contains a few time-critical auxillary cython functions for finite complex or real reflection groups. @@ -127,15 +128,14 @@ cdef class Iterator(object): successors.append((u1, word_new, i)) return successors - cdef bint test(self, PermutationGroupElement u, PermutationGroupElement si, int i): - cdef int j, sij + cdef inline bint test(self, PermutationGroupElement u, PermutationGroupElement si, int i): + cdef int j cdef int N = self.N cdef int* siperm = si.perm cdef int* uperm = u.perm for j in range(i): - sij = siperm[j] - if uperm[sij] >= N: + if uperm[siperm[j]] >= N: return False return True @@ -374,7 +374,7 @@ def iterator_tracking_words(W): level_set_new.append((y, word+[i])) level_set_cur = level_set_new -cdef bint has_descent(PermutationGroupElement w, int i, int N): +cdef inline bint has_descent(PermutationGroupElement w, int i, int N): return w.perm[i] >= N cdef int first_descent(PermutationGroupElement w, int n, int N): @@ -402,9 +402,12 @@ cpdef list reduced_word_c(W,w): cdef int fdes = 0 cdef list word = [] - while fdes != -1: + while True: fdes = first_descent(w,n,N) + if fdes == -1: + break si = S[fdes] w = si._mul_(w) word.append(fdes) - return word[:-1] + return word + diff --git a/src/sage/combinat/root_system/reflection_group_complex.py b/src/sage/combinat/root_system/reflection_group_complex.py index fa5217165e8..acb7e1a6df3 100644 --- a/src/sage/combinat/root_system/reflection_group_complex.py +++ b/src/sage/combinat/root_system/reflection_group_complex.py @@ -196,15 +196,15 @@ #***************************************************************************** from __future__ import print_function -from sage.misc.cachefunc import cached_method, cached_in_parent_method -from sage.misc.lazy_attribute import lazy_attribute -from sage.misc.flatten import flatten +#from six.moves import range + +from sage.misc.cachefunc import cached_method from sage.misc.misc_c import prod from sage.categories.category import Category from sage.categories.permutation_groups import PermutationGroups from sage.categories.complex_reflection_groups import ComplexReflectionGroups from sage.categories.coxeter_groups import CoxeterGroups -from sage.groups.perm_gps.permgroup_element import PermutationGroupElement +from sage.combinat.root_system.reflection_group_element import ComplexReflectionGroupElement, _gap_return from sage.sets.family import Family from sage.structure.unique_representation import UniqueRepresentation from sage.groups.perm_gps.permgroup import PermutationGroup_generic @@ -213,7 +213,6 @@ from sage.matrix.matrix import is_Matrix from sage.interfaces.gap3 import gap3 from sage.rings.universal_cyclotomic_field import E -from sage.arith.misc import lcm from sage.modules.free_module_element import vector from sage.combinat.root_system.cartan_matrix import CartanMatrix @@ -259,7 +258,7 @@ def __init__(self, W_types, index_set=None, hyperplane_index_set=None, reflectio if len(X) > 1: raise ValueError("input data %s is invalid"%W_type) X = X[0] - type_dict = dict() + type_dict = {} type_dict["series"] = X.series.sage() type_dict["rank"] = X.rank.sage() type_dict["indices"] = X.indices.sage() @@ -854,6 +853,7 @@ def conjugacy_classes_representatives(self): [1, 2, 1, 2, 3, 2, 1, 2, 3], [1, 2, 1, 2, 1, 3, 2, 1, 2, 1, 3, 2, 1, 2, 3]] """ + # This can be converted to usual GAP S = str(gap3('List(ConjugacyClasses(%s),Representative)'%self._gap_group._name)) exec('_conjugacy_classes_representatives=' + _gap_return(S)) return _conjugacy_classes_representatives @@ -1201,50 +1201,13 @@ def independent_roots(self): return Delta from sage.sets.family import Family - basis = dict() - for i,ind in enumerate(self._index_set): + basis = {} + for ind in self._index_set: vec = Delta[ind] if Matrix(basis.values()+[vec]).rank() == len(basis) + 1: basis[ind] = vec return Family(basis) - @cached_method - def base_change_matrix(self): - r""" - Return the base change from the standard basis of the vector - space of ``self`` to the basis given by the independent roots of - ``self``. - - .. TODO:: - - For non-well-generated groups there is a conflict with - construction of the matrix for an element. - - EXAMPLES:: - - 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 - [1 0 0] - [0 1 0] - [0 0 1] - - 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 - [ 1 0] - [E(4) 1] - """ - return Matrix( list(self.independent_roots()) ).inverse() - @cached_method def roots(self): r""" @@ -1539,8 +1502,6 @@ def _invariant_form_brute_force(self): """ from sage.misc.cachefunc import cached_function - Phi = self.roots() - base_change = self.base_change_matrix() Delta = tuple(self.independent_roots()) basis_is_Delta = base_change.is_one() @@ -1573,7 +1534,8 @@ def invariant_value(i,j): coeff = QQ(coeff) coeffs.append(coeff) - return Matrix([ [ invariant_value(i,j)/self.cardinality() for j in range(n) ] for i in range(n) ]) + return Matrix([[invariant_value(i,j) / self.cardinality() for j in range(n)] + for i in range(n)]) def set_reflection_representation(self,refl_repr=None): r""" @@ -1641,8 +1603,7 @@ def set_reflection_representation(self,refl_repr=None): else: raise ValueError("the reflection representation must be defined for the complete index set") - class Element(PermutationGroupElement): - + class Element(ComplexReflectionGroupElement): #@cached_in_parent_method def conjugacy_class_representative(self): r""" @@ -1702,97 +1663,6 @@ def conjugacy_class(self): W._conjugacy_classes[self] = orbit_set return orbit_set - def reduced_word(self): - r""" - Return a word in the simple reflections to obtain ``self``. - - EXAMPLES:: - - sage: W = ReflectionGroup((5,1,1), index_set=['a'], hyperplane_index_set=['x'], reflection_index_set=['A','B','C','D']) # optional - gap3 - sage: [w.reduced_word() for w in W] # optional - gap3 - [[], ['a'], ['a', 'a'], ['a', 'a', 'a'], ['a', 'a', 'a', 'a']] - - .. SEEALSO:: :meth:`reduced_word_in_reflections` - """ - I = self.parent()._index_set - return [I[i] for i in self._reduced_word] - - @lazy_attribute - def _reduced_word(self): - r""" - Computes a reduced word and stores it into ``self._reduced_word``. - - TESTS:: - - sage: W = ReflectionGroup((5,1,1)) # optional - gap3 - sage: w = W.an_element() # optional - gap3 - sage: w._reduced_word # optional - gap3 - [0] - """ - W = self.parent() - gens = [W.simple_reflection(j) for j in W._index_set] - return _gap_factorization(self, gens) - - #@cached_in_parent_method - def reduced_word_in_reflections(self): - r""" - Return a word in the reflections to obtain ``self``. - - EXAMPLES:: - - sage: W = ReflectionGroup((5,1,1), index_set=['a'], reflection_index_set=['A','B','C','D']) # optional - gap3 - sage: [w.reduced_word_in_reflections() for w in W] # optional - gap3 - [[], ['A'], ['B'], ['C'], ['D']] - - .. SEEALSO:: :meth:`reduced_word` - """ - if self.is_one(): - return [] - - W = self.parent() - gens = [W.reflection(j) for j in W._reflection_index_set] - word = _gap_factorization(self, gens) - return [self.parent()._reflection_index_set[i] for i in word] - - def length(self): - r""" - Return the length of ``self`` in generating reflections. - - This is the minimal numbers of generating reflections needed - to obtain ``self``. - - EXAMPLES:: - - sage: W = ReflectionGroup(4) # optional - gap3 - sage: for w in W: # optional - gap3 - ....: print("{} {}".format(w.reduced_word(), w.length())) - [] 0 - [1] 1 - [2] 1 - [1, 1] 2 - [1, 2] 2 - [2, 1] 2 - [2, 2] 2 - [1, 1, 2] 3 - [1, 2, 1] 3 - [1, 2, 2] 3 - [2, 1, 1] 3 - [2, 2, 1] 3 - [1, 1, 2, 1] 4 - [1, 1, 2, 2] 4 - [1, 2, 1, 1] 4 - [1, 2, 2, 1] 4 - [2, 1, 1, 2] 4 - [2, 2, 1, 1] 4 - [1, 1, 2, 1, 1] 5 - [1, 1, 2, 2, 1] 5 - [1, 2, 1, 1, 2] 5 - [1, 2, 2, 1, 1] 5 - [1, 1, 2, 1, 1, 2] 6 - [1, 1, 2, 2, 1, 1] 6 - """ - return len(self.reduced_word()) - #@cached_in_parent_method def reflection_length(self, in_unitary_group=False): r""" @@ -1838,496 +1708,6 @@ def reflection_length(self, in_unitary_group=False): assert w in self.parent().conjugacy_classes_representatives() return w.reflection_length(in_unitary_group=in_unitary_group) - #@cached_in_parent_method - def to_matrix(self, on_space="primal"): - r""" - Return ``self`` as a matrix acting on the underlying vector - space. - - - ``on_space`` -- optional (default: ``"primal"``) whether - to act as the reflection representation on the given - basis, or to act on the dual reflection representation - on the dual basis - - EXAMPLES:: - - sage: W = ReflectionGroup((3,1,2)) # optional - gap3 - sage: for w in W: # optional - gap3 - ....: w.reduced_word() # optional - gap3 - ....: [w.to_matrix(), w.to_matrix(on_space="dual")] # optional - gap3 - [] - [ - [1 0] [1 0] - [0 1], [0 1] - ] - [1] - [ - [E(3) 0] [E(3)^2 0] - [ 0 1], [ 0 1] - ] - [2] - [ - [0 1] [0 1] - [1 0], [1 0] - ] - [1, 1] - [ - [E(3)^2 0] [E(3) 0] - [ 0 1], [ 0 1] - ] - [1, 2] - [ - [ 0 E(3)] [ 0 E(3)^2] - [ 1 0], [ 1 0] - ] - [2, 1] - [ - [ 0 1] [ 0 1] - [E(3) 0], [E(3)^2 0] - ] - [1, 1, 2] - [ - [ 0 E(3)^2] [ 0 E(3)] - [ 1 0], [ 1 0] - ] - [1, 2, 1] - [ - [ 0 E(3)] [ 0 E(3)^2] - [E(3) 0], [E(3)^2 0] - ] - [2, 1, 1] - [ - [ 0 1] [ 0 1] - [E(3)^2 0], [E(3) 0] - ] - [2, 1, 2] - [ - [ 1 0] [ 1 0] - [ 0 E(3)], [ 0 E(3)^2] - ] - [1, 1, 2, 1] - [ - [ 0 E(3)^2] [ 0 E(3)] - [ E(3) 0], [E(3)^2 0] - ] - [1, 2, 1, 1] - [ - [ 0 E(3)] [ 0 E(3)^2] - [E(3)^2 0], [ E(3) 0] - ] - [1, 2, 1, 2] - [ - [E(3) 0] [E(3)^2 0] - [ 0 E(3)], [ 0 E(3)^2] - ] - [2, 1, 1, 2] - [ - [ 1 0] [ 1 0] - [ 0 E(3)^2], [ 0 E(3)] - ] - [1, 1, 2, 1, 1] - [ - [ 0 E(3)^2] [ 0 E(3)] - [E(3)^2 0], [E(3) 0] - ] - [1, 1, 2, 1, 2] - [ - [E(3)^2 0] [ E(3) 0] - [ 0 E(3)], [ 0 E(3)^2] - ] - [1, 2, 1, 1, 2] - [ - [ E(3) 0] [E(3)^2 0] - [ 0 E(3)^2], [ 0 E(3)] - ] - [1, 1, 2, 1, 1, 2] - [ - [E(3)^2 0] [E(3) 0] - [ 0 E(3)^2], [ 0 E(3)] - ] - """ - W = self.parent() - if W._reflection_representation is None: - Phi = W.roots() - inds = [W._index_set_inverse[i] for i in W.independent_roots().keys()] - M = Matrix([Phi[self(i+1)-1] for i in inds]) - mat = W.base_change_matrix() * M - else: - refl_repr = W._reflection_representation - id_mat = identity_matrix(QQ, refl_repr[W.index_set()[0]].nrows()) - mat = prod([refl_repr[i] for i in self.reduced_word()], id_mat) - - if on_space == "primal": - pass - elif on_space == "dual": - mat = mat.inverse().transpose() - else: - raise ValueError('on_space must be "primal" or "dual"') - - mat.set_immutable() - return mat - - matrix = to_matrix - - def action(self, vec, on_space="primal"): - r""" - Return the image of ``vec`` under the action of ``self``. - - INPUT: - - - ``vec`` -- vector in the basis given by the simple root - - - ``on_space`` -- optional (default: ``"primal"``) whether - to act as the reflection representation on the given - basis, or to act on the dual reflection representation - on the dual basis - - EXAMPLES:: - - sage: W = ReflectionGroup((3,1,2)) # optional - gap3 - sage: w = W.from_reduced_word([1, 2, 1, 1, 2]) # optional - gap3 - sage: for alpha in W.independent_roots(): # optional - gap3 - ....: print("%s -> %s"%(alpha,w.action(alpha))) # optional - gap3 - (1, 0) -> (E(3), 0) - (-1, 1) -> (-E(3), E(3)^2) - """ - mat = self.matrix(on_space=on_space) - return vec * mat - - def _act_on_(self, vec, self_on_left): - r""" - Defines the action of ``self`` as a linear transformation - on the vector space, in the basis given by the simple - roots. - - - ``vec`` -- the vector (an iterable) to act on - - - ``self_on_left`` -- whether the action of ``self`` is on - the left or on the right - - .. WARNING:: - - This coercion is currently only defined for - ``self_on_left`` being ``False``. - - EXAMPLES:: - - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: w = W.from_reduced_word([1,2]) # optional - gap3 - sage: for root in W.positive_roots(): # optional - gap3 - ....: print("%s -> %s"%(root, w*root)) # optional - gap3 - (1, 0) -> (0, 1) - (0, 1) -> (-1, -1) - (1, 1) -> (-1, 0) - - sage: for root in W.positive_roots(): # optional - gap3 - ....: print("%s -> %s"%(root, root*w)) # optional - gap3 - (1, 0) -> (-1, -1) - (0, 1) -> (1, 0) - (1, 1) -> (0, -1) - """ - if not self_on_left: - return self.action(vec, side="right") - - def action_on_root_indices(self, i): - """ - Return the right action on the set of roots. - - INPUT: - - - ``i`` -- index of the root to act on - - EXAMPLES:: - - sage: W = ReflectionGroup(['A',3]) # optional - gap3 - sage: w = W.w0 # optional - gap3 - sage: N = len(W.roots()) # optional - gap3 - sage: [w.action_on_root_indices(i) for i in range(N)] # optional - gap3 - [8, 7, 6, 10, 9, 11, 2, 1, 0, 4, 3, 5] - - sage: W = ReflectionGroup(['A',2], reflection_index_set=['A','B','C']) # optional - gap3 - sage: w = W.w0 # optional - gap3 - sage: N = len(W.roots()) # optional - gap3 - sage: [w.action_on_root_indices(i) for i in range(N)] # optional - gap3 - [4, 3, 5, 1, 0, 2] - - TESTS:: - - sage: W = ReflectionGroup(4) # optional - gap3 - sage: N = len(W.roots()) # optional - gap3 - sage: all(sorted([w.action_on_root_indices(i) for i in range(N)]) == list(range(N)) for w in W) # optional - gap3 - True - """ - return self(i + 1) - 1 - - def action_on_root(self, root): - r""" - Return the root obtained by applying ``self`` to ``root`` - on the right. - - INPUT: - - - ``root`` -- the root to act on - - EXAMPLES:: - - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: for w in W: # optional - gap3 - ....: print("%s %s"%(w.reduced_word(), # optional - gap3 - ....: [w.action_on_root(beta,side="left") for beta in W.positive_roots()])) # optional - gap3 - [] [(1, 0), (0, 1), (1, 1)] - [2] [(1, 1), (0, -1), (1, 0)] - [1] [(-1, 0), (1, 1), (0, 1)] - [1, 2] [(0, 1), (-1, -1), (-1, 0)] - [2, 1] [(-1, -1), (1, 0), (0, -1)] - [1, 2, 1] [(0, -1), (-1, 0), (-1, -1)] - - TESTS:: - - sage: W = ReflectionGroup(4); Phi = sorted(W.roots()) # optional - gap3 - sage: all(sorted([w.action_on_root(beta) for beta in Phi]) == Phi for w in W) # optional - gap3 - True - """ - Phi = self.parent().roots() - return Phi[self.action_on_root_indices(Phi.index(root))] - - def to_permutation_of_roots(self): - r""" - Return ``self`` as a permutation of the roots with indexing - starting at `1`. - - EXAMPLES:: - - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: for w in W: # optional - gap3 - ....: perm = w.to_permutation_of_roots() - ....: print("{} {}".format(perm, perm == w)) - () True - (1,3)(2,5)(4,6) True - (1,4)(2,3)(5,6) True - (1,6,2)(3,5,4) True - (1,2,6)(3,4,5) True - (1,5)(2,4)(3,6) True - """ - return PermutationGroupElement(self) - - #@cached_in_parent_method - def fix_space(self): - r""" - Return the fix space of ``self``. - - This is the sub vector space of the underlying vector space - on which ``self`` acts trivially. - - EXAMPLES:: - - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: for w in W: # optional - gap3 - ....: w.reduced_word() # optional - gap3 - ....: w.fix_space() # optional - gap3 - [] - Vector space of degree 2 and dimension 2 over Rational Field - Basis matrix: - [1 0] - [0 1] - [2] - Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [1 0] - [1] - Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [0 1] - [1, 2] - Vector space of degree 2 and dimension 0 over Rational Field - Basis matrix: - [] - [2, 1] - Vector space of degree 2 and dimension 0 over Rational Field - Basis matrix: - [] - [1, 2, 1] - Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [ 1 -1] - - sage: W = ReflectionGroup(23) # optional - gap3 - sage: W.an_element().fix_space() # optional - gap3 - Vector space of degree 3 and dimension 2 over Universal Cyclotomic Field - Basis matrix: - [0 1 0] - [0 0 1] - """ - I = identity_matrix(QQ, self.parent().rank()) - return (self.to_matrix() - I).right_kernel() - - #@cached_in_parent_method - def reflection_eigenvalues(self, is_class_representative=False): - r""" - Return the reflection eigenvalues of ``self``. - - INPUT: - - - ``is_class_representative`` -- (default: ``False``) whether - to first replace ``self`` by the representative of its - conjugacy class - - EXAMPLES:: - - sage: W = ReflectionGroup(4) # optional - gap3 - sage: for w in W: w.reflection_eigenvalues() # optional - gap3 - [0, 0] - [1/3, 0] - [1/3, 0] - [2/3, 0] - [1/6, 1/2] - [1/6, 1/2] - [2/3, 0] - [1/4, 3/4] - [1/4, 3/4] - [1/4, 3/4] - [1/4, 3/4] - [1/4, 3/4] - [1/3, 0] - [1/2, 5/6] - [1/3, 0] - [1/2, 5/6] - [1/2, 5/6] - [1/2, 5/6] - [1/6, 1/2] - [2/3, 0] - [1/6, 1/2] - [2/3, 0] - [1/2, 1/2] - [1/4, 3/4] - """ - return self.parent().reflection_eigenvalues(self, is_class_representative=is_class_representative) - - #@cached_in_parent_method - def galois_conjugates(self): - r""" - Return all Galois conjugates of ``self``. - - EXAMPLES:: - - sage: W = ReflectionGroup(4) # optional - gap3 - sage: for w in W: print(w.galois_conjugates()) # optional - gap3 - [[1 0] - [0 1]] - [[ 1 0] - [ 0 E(3)], [ 1 0] - [ 0 E(3)^2]] - [[ 1/3*E(3) - 1/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2] - [ 4/3*E(3) + 2/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2], - [-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2] - [ 2/3*E(3) + 4/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2]] - [[ 1 0] - [ 0 E(3)^2], [ 1 0] - [ 0 E(3)]] - [[ 1/3*E(3) - 1/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2] - [-2/3*E(3) + 2/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2], - [-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2] - [ 2/3*E(3) - 2/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2]] - [[ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2] - [ 4/3*E(3) + 2/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2], - [-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2] - [ 2/3*E(3) + 4/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2]] - [[-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2] - [ 2/3*E(3) + 4/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2], - [ 1/3*E(3) - 1/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2] - [ 4/3*E(3) + 2/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2]] - [[ 1/3*E(3) - 1/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2] - [-2/3*E(3) - 4/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2], - [-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2] - [-4/3*E(3) - 2/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2]] - [[ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2] - [-2/3*E(3) + 2/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2], - [-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2] - [ 2/3*E(3) - 2/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2]] - [[-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2] - [-4/3*E(3) - 2/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2], - [ 1/3*E(3) - 1/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2] - [-2/3*E(3) - 4/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2]] - [[ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2] - [ 4/3*E(3) + 2/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2], - [-1/3*E(3) + 1/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2] - [ 2/3*E(3) + 4/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2]] - [[-1/3*E(3) + 1/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2] - [ 2/3*E(3) + 4/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2], - [ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2] - [ 4/3*E(3) + 2/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2]] - [[ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2] - [-2/3*E(3) - 4/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2], - [-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2] - [-4/3*E(3) - 2/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2]] - [[-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2] - [ 2/3*E(3) - 2/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2], - [ 1/3*E(3) - 1/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2] - [-2/3*E(3) + 2/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2]] - [[ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2] - [-2/3*E(3) + 2/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2], - [-1/3*E(3) + 1/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2] - [ 2/3*E(3) - 2/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2]] - [[-1/3*E(3) + 1/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2] - [-4/3*E(3) - 2/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2], - [ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2] - [-2/3*E(3) - 4/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2]] - [[ -1 0] - [ 0 -E(3)], [ -1 0] - [ 0 -E(3)^2]] - [[-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2] - [ 2/3*E(3) + 4/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2], - [ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2] - [ 4/3*E(3) + 2/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2]] - [[ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2] - [-2/3*E(3) - 4/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2], - [-1/3*E(3) + 1/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2] - [-4/3*E(3) - 2/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2]] - [[-1/3*E(3) + 1/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2] - [ 2/3*E(3) - 2/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2], - [ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2] - [-2/3*E(3) + 2/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2]] - [[ -1 0] - [ 0 -E(3)^2], [ -1 0] - [ 0 -E(3)]] - [[-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2] - [-4/3*E(3) - 2/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2], - [ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2] - [-2/3*E(3) - 4/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2]] - [[-1 0] - [ 0 -1]] - [[-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2] - [ 2/3*E(3) - 2/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2], - [ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2] - [-2/3*E(3) + 2/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2]] - """ - rk = self.parent().rank() - M = self.to_matrix().list() - m = lcm([x.conductor() if hasattr(x,"conductor") else 1 for x in M]) - M_gals = [x.galois_conjugates(m) if hasattr(x,"galois_conjugates") else [x] for x in M] - conjugates = [] - for i in range(len(M_gals[0])): - conjugates.append(Matrix(rk, [X[i] for X in M_gals])) - return conjugates - - def __cmp__(self, other): - r""" - Compare ``self`` with ``other``. - - Without this comparison method, the initialization of this - permutation group fails :-(. - - TESTS:: - - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: a,b = W.gens() # optional - gap3 - sage: a.__cmp__(b) # optional - gap3 - 1 - sage: b.__cmp__(a) # optional - gap3 - -1 - """ - return super(ComplexReflectionGroup.Element, self).__cmp__(other) - class IrreducibleComplexReflectionGroup(ComplexReflectionGroup): def _repr_(self): @@ -2344,249 +1724,6 @@ def _repr_(self): type_str = self._irrcomp_repr_(self._type[0]) return 'Irreducible complex reflection group of rank %s and type %s'%(self._rank,type_str) - def elements_below_coxeter_element(self, c=None): - r""" - Return all elements in ``self`` in the interval `[1,c]` in the - absolute order of ``self``. - - This order is defined by - - .. MATH:: - - \omega \leq_R \tau \Leftrightarrow \ell_R(\omega) + - \ell_R(\omega^{-1} \tau) = \ell_R(\tau), - - where `\ell_R` denotes the reflection length. - - .. NOTE:: - - ``self`` is assumed to be well-generated. - - INPUT: - - - ``c`` -- (default: ``None``) if an element ``c`` is given, it - is used as the maximal element in the interval; if a list is - given, the union of the various maximal elements is computed - - EXAMPLES:: - - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - - sage: sorted( w.reduced_word() for w in W.elements_below_coxeter_element() ) # optional - gap3 - [[], [1], [1, 2], [1, 2, 1], [2]] - - sage: sorted( w.reduced_word() for w in W.elements_below_coxeter_element(W.from_reduced_word([2,1])) ) # optional - gap3 - [[], [1], [1, 2, 1], [2], [2, 1]] - - sage: sorted( w.reduced_word() for w in W.elements_below_coxeter_element(W.from_reduced_word([2])) ) # optional - gap3 - [[], [2]] - """ - if c in self: - cs = [c] - elif c is None: - cs = [self.coxeter_element()] - else: - cs = list(c) - l = cs[0].reflection_length(in_unitary_group=True) - f = lambda pi: any(pi.reflection_length(in_unitary_group=True) - + (c*pi**-1).reflection_length(in_unitary_group=True) == l - for c in cs) - # first computing the conjugacy classes only needed if the interaction with gap3 is slow due to a bug - #self.conjugacy_classes() - return filter(f, self) - - # TODO: lift to ComplexReflectionGroups.Finite - # this method can be defined for well-generated, finite, - # irreducible complex reflection group. The current - # implementation uses this particular connection to chevie. - # TODO: have a cached and an uncached version - @cached_method - def noncrossing_partition_lattice(self, c=None, L=None, in_unitary_group=False): - r""" - Return the interval `[1,c]` in the absolute order of - ``self`` as a finite lattice. - - .. SEEALSO:: :meth:`elements_below_coxeter_element` - - INPUT: - - - ``c`` -- (default: ``None``) if an element ``c`` in ``self`` is - given, it is used as the maximal element in the interval - - - ``L`` -- (default: ``None``) if a subset ``L`` (must be hashable!) - of ``self`` is given, it is used as the underlying set (only - cover relations are checked) - - - ``in_unitary_group`` -- (default: ``False``) if ``False``, the - relation is given by `\sigma \leq \tau` if - `l_R(\sigma) + l_R(\sigma^{-1}\tau) = l_R(\tau)`; - if ``True``, the relation is given by `\sigma \leq \tau` if - `\dim(\mathrm{Fix}(\sigma)) + \dim(\mathrm{Fix}(\sigma^{-1}\tau)) - = \dim(\mathrm{Fix}(\tau))` - - EXAMPLES:: - - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - - sage: sorted( w.reduced_word() for w in W.noncrossing_partition_lattice() ) # optional - gap3 - [[], [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 - [[], [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 - [[], [2]] - """ - from sage.combinat.posets.all import Poset, LatticePoset - if c is None: - c = self.coxeter_element() - - smart_covers = not in_unitary_group - - if self.is_real(): - smart_covers = in_unitary_group = True - - R = self.reflections() - if L is None: - L = self.elements_below_coxeter_element(c=c) - if c.is_coxeter_element(): - smart_covers = in_unitary_group = True - rels = [] - ref_lens = {w: w.reflection_length(in_unitary_group=in_unitary_group) - for w in L} - if smart_covers: - for pi in L: - for t in R: - tau = pi*t - if tau in L and ref_lens[pi] + 1 == ref_lens[tau]: - rels.append((pi,tau)) - else: - rels = [(pi,tau) for pi in L for tau in L - if ref_lens[pi] + ref_lens[pi.inverse()*tau] == ref_lens[tau]] - P = Poset((L,rels), cover_relations=smart_covers, facade=True) - if P.is_lattice(): - return LatticePoset(P) - else: - return P - - # TODO: lift to ComplexReflectionGroups.Finite - # this method can be defined for well-generated, finite, - # irreducible complex reflection group. The current - # implementation uses this particular connection to chevie. - def generalized_noncrossing_partitions(self, m, c=None, positive=False): - r""" - Return the set of all chains of length ``m`` in the noncrossing - partition lattice of ``self``, see - :meth:`noncrossing_partition_lattice`. - - .. NOTE:: - - ``self`` is assumed to be well-generated - - INPUT: - - - ``c`` -- (default: ``None``) if an element ``c`` in ``self`` - is given, it is used as the maximal element in the interval - - - ``positive`` -- (default: ``False``) if ``True``, only those - generalized noncrossing partitions of full support are returned - - EXAMPLES:: - - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - - sage: sorted([w.reduced_word() for w in chain] # optional - gap3 - ....: for chain in W.generalized_noncrossing_partitions(2)) # optional - gap3 - [[[], [], [1, 2]], - [[], [1], [2]], - [[], [1, 2], []], - [[], [1, 2, 1], [1]], - [[], [2], [1, 2, 1]], - [[1], [], [2]], - [[1], [2], []], - [[1, 2], [], []], - [[1, 2, 1], [], [1]], - [[1, 2, 1], [1], []], - [[2], [], [1, 2, 1]], - [[2], [1, 2, 1], []]] - - sage: sorted([w.reduced_word() for w in chain] # optional - gap3 - ....: for chain in W.generalized_noncrossing_partitions(2, positive=True)) # optional - gap3 - [[[], [1, 2], []], - [[], [1, 2, 1], [1]], - [[1], [2], []], - [[1, 2], [], []], - [[1, 2, 1], [], [1]], - [[1, 2, 1], [1], []], - [[2], [1, 2, 1], []]] - """ - from sage.combinat.combination import Combinations - NC = self.noncrossing_partition_lattice(c=c) - one = self.one() - if c is None: - c = self.coxeter_element() - chains = NC.chains() - NCm = set() - iter = chains.breadth_first_search_iterator() - chain = next(iter) - chain = next(iter) - while len(chain) <= m: - chain.append( c ) - for i in range(len(chain)-1, 0, -1): - chain[i] = chain[i-1]**-1 * chain[i] - k = m + 1 - len(chain) - for positions in Combinations(range(m+1),k): - ncm = [] - for l in range(m+1): - if l in positions: - ncm.append(one) - else: - l_prime = l - len([i for i in positions if i <= l]) - ncm.append(chain[l_prime]) - if not positive or prod(ncm[:-1]).has_full_support(): - NCm.add(tuple(ncm)) - try: - chain = next(iter) - except StopIteration: - chain = list(range(m + 1)) - return NCm - - # TODO: lift to ComplexReflectionGroups.Finite - # this method can be defined for well-generated, finite, - # irreducible complex reflection group. The current - # implementation uses this particular connection to chevie. - # TODO: have a cached and an uncached version - def absolute_poset(self, in_unitary_group=False): - r""" - Return the poset induced by the absolute order of ``self`` as a - finite lattice. - - INPUT: - - - ``in_unitary_group`` -- (default: ``False``) if ``False``, the - relation is given by ``\sigma \leq \tau`` if - `l_R(\sigma) + l_R(\sigma^{-1}\tau) = l_R(\tau)` - If ``True``, the relation is given by `\sigma \leq \tau` if - `\dim(\mathrm{Fix}(\sigma)) + \dim(\mathrm{Fix}(\sigma^{-1}\tau)) - = \dim(\mathrm{Fix}(\tau))`. - - .. SEEALSO:: :meth:`noncrossing_partition_lattice` - - EXAMPLES:: - - sage: P = ReflectionGroup((1,1,3)).absolute_poset(); P # optional - gap3 - Finite poset containing 6 elements - - sage: sorted(w.reduced_word() for w in P) # optional - gap3 - [[], [1], [1, 2], [1, 2, 1], [2], [2, 1]] - - sage: W = ReflectionGroup(4); W # optional - gap3 - Irreducible complex reflection group of rank 2 and type ST4 - sage: W.absolute_poset() # optional - gap3 - Finite poset containing 24 elements - """ - return self.noncrossing_partition_lattice(L=self) - class Element(ComplexReflectionGroup.Element): # TODO: lift to ComplexReflectionGroups.Finite @@ -2721,96 +1858,3 @@ def is_regular(self, h, is_class_representative=False): return True return False -def _gap_factorization(w, gens): - r""" - Return a factorization of ``w`` using the generators ``gens``. - - .. WARNING:: - - This is only available through GAP3 and Chevie. - - EXAMPLES:: - - sage: from sage.combinat.root_system.reflection_group_complex import _gap_factorization - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: gens = [ W.simple_reflection(i) for i in W.index_set() ] # optional - gap3 - sage: for w in W: _gap_factorization(w,gens) # optional - gap3 - [] - [1] - [0] - [0, 1] - [1, 0] - [0, 1, 0] - """ - gap3.execute('W := GroupWithGenerators(%s)'%str(gens)) - gap3.execute(_gap_factorization_code) - fac = gap3('MinimalWord(W,%s)'%str(w)).sage() - return [i-1 for i in fac] - -_gap_factorization_code = """ -# MinimalWord(G,w) -# given a permutation group G find some expression of minimal length in the -# generators of G and their inverses of the element w (an inverse is -# representated by a negative index). -# To speed up later calls to the same function the fields G.base, G.words, -# G.nbwordslength are kept. -MinimalWord:=function(G,w) - local decode,i,p,g,h,n,bag,nbe,nbf,new,gens,inds; - # to save space elements of G are represented as image of the base, and - # words are represented as: index of previous elt, last generator applied; - if not IsBound(G.base) then - StabChain(G);g:=G; G.base:=[]; - while IsBound(g.orbit) do Add(G.base,g.orbit[1]); g:=g.stabilizer; od; - fi; - w:=OnTuples(G.base,w); - if not IsBound(G.words) then - G.words:=[G.base]; G.lastmult:=[[0,0]]; - G.nbwordslength:=[1]; - fi; - gens:=ShallowCopy(G.generators);inds:=[1..Length(gens)]; - # for g in G.generators do - # if g<>g^-1 then Add(gens,g^-1);Add(inds,-Position(gens,g));fi; - # od; - bag:=Set(G.words); - nbe:=0;nbf:=0; - decode:=function(i)local w;w:=[]; - while i<>1 do Add(w,G.lastmult[i][2]); i:=G.lastmult[i][1];od; - return Reversed(w); - end; - while true do - if w in bag then return decode(Position(G.words,w));fi; - new:=Length(G.words); - for g in [1..Length(gens)] do - for h in [1+Sum(G.nbwordslength{[1..Length(G.nbwordslength)-1]})..new] do - n:=OnTuples(G.words[h],gens[g]); - if n in bag then - nbe:=nbe+1;# if nbe mod 500=1 then Print(".\c");fi; - else - nbf:=nbf+1;# if nbf mod 500=1 then Print("*\c");fi; - Add(G.words,n);Add(G.lastmult,[h,inds[g]]);AddSet(bag,n); - fi; - od; - od; - Add(G.nbwordslength,Length(G.words)-new); - Print("\n",G.nbwordslength[Length(G.nbwordslength)]," elements of length ", - Length(G.nbwordslength)-1); - od; -end;""" - -def _gap_return(S, coerce_obj='self'): - r""" - Return the string ``S`` after a few modifications are done. - - This is a stupid internal function to take GAP output as a string, - replace a few things, to then turn it into a Sage object. - - TESTS:: - - sage: from sage.combinat.root_system.reflection_group_complex import _gap_return - sage: _gap_return("[ (), (1,4)(2,3)(5,6), (1,6,2)(3,5,4) ]") # optional - gap3 - "[self('()',check=False),self('(1,4)(2,3)(5,6)',check=False),self('(1,6,2)(3,5,4)',check=False)]" - """ - S = S.replace(' ','').replace('\n','') - S = S.replace(',(','\',check=False),%s(\'('%coerce_obj).replace('[','[%s(\''%coerce_obj).replace(']','\',check=False)]') - return S - diff --git a/src/sage/combinat/root_system/reflection_group_element.pxd b/src/sage/combinat/root_system/reflection_group_element.pxd new file mode 100644 index 00000000000..7e6f4a8d4ed --- /dev/null +++ b/src/sage/combinat/root_system/reflection_group_element.pxd @@ -0,0 +1,8 @@ +from sage.groups.perm_gps.permgroup_element cimport PermutationGroupElement + +cdef class ComplexReflectionGroupElement(PermutationGroupElement): + pass + +cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): + cpdef bint has_left_descent(self, i) + cpdef bint has_descent(self, i, side=*, positive=*) diff --git a/src/sage/combinat/root_system/reflection_group_element.pyx b/src/sage/combinat/root_system/reflection_group_element.pyx new file mode 100644 index 00000000000..94462d288d2 --- /dev/null +++ b/src/sage/combinat/root_system/reflection_group_element.pyx @@ -0,0 +1,1099 @@ +r""" +Reflection group elements + +.. SEEALSO:: + + :mod:`sage.combinat.root_system.reflection_group_complex`, + :mod:`sage.combinat.root_system.reflection_group_real` + +AUTHORS: + +- Christian Stump (initial version 2011--2015) +- Travis Scrimshaw (14-03-2017): moved element code +""" +#***************************************************************************** +# Copyright (C) 2011-2016 Christian Stump +# Copyright (C) 2017 Travis Scrimshaw +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** +from __future__ import print_function + +from six.moves import range + +from sage.misc.cachefunc import cached_method#, cached_in_parent_method +from sage.misc.lazy_attribute import lazy_attribute +from sage.misc.misc_c import prod +from sage.arith.misc import lcm +from sage.combinat.root_system.cartan_type import CartanType, CartanType_abstract +from sage.rings.all import ZZ, QQ +from sage.interfaces.gap3 import gap3 +from sage.combinat.root_system.cartan_matrix import CartanMatrix +from sage.misc.sage_eval import sage_eval +from sage.combinat.root_system.reflection_group_c import reduced_word_c +from sage.matrix.all import Matrix, identity_matrix + +cdef class ComplexReflectionGroupElement(PermutationGroupElement): + """ + An element in a complex reflection group. + """ + def reduced_word(self): + r""" + Return a word in the simple reflections to obtain ``self``. + + EXAMPLES:: + + sage: W = ReflectionGroup((5,1,1), index_set=['a'], hyperplane_index_set=['x'], reflection_index_set=['A','B','C','D']) # optional - gap3 + sage: [w.reduced_word() for w in W] # optional - gap3 + [[], ['a'], ['a', 'a'], ['a', 'a', 'a'], ['a', 'a', 'a', 'a']] + + .. SEEALSO:: :meth:`reduced_word_in_reflections` + """ + I = self.parent()._index_set + return [I[i] for i in self._reduced_word] + + @lazy_attribute + def _reduced_word(self): + r""" + Computes a reduced word and stores it into ``self._reduced_word``. + + TESTS:: + + sage: W = ReflectionGroup((5,1,1)) # optional - gap3 + sage: w = W.an_element() # optional - gap3 + sage: w._reduced_word # optional - gap3 + [0] + """ + W = self.parent() + gens = [W.simple_reflection(j) for j in W._index_set] + return _gap_factorization(self, gens) + + #@cached_in_parent_method + def reduced_word_in_reflections(self): + r""" + Return a word in the reflections to obtain ``self``. + + EXAMPLES:: + + sage: W = ReflectionGroup((5,1,1), index_set=['a'], reflection_index_set=['A','B','C','D']) # optional - gap3 + sage: [w.reduced_word_in_reflections() for w in W] # optional - gap3 + [[], ['A'], ['B'], ['C'], ['D']] + + .. SEEALSO:: :meth:`reduced_word` + """ + if self.is_one(): + return [] + + W = self.parent() + gens = [W.reflection(j) for j in W._reflection_index_set] + word = _gap_factorization(self, gens) + return [self.parent()._reflection_index_set[i] for i in word] + + def length(self): + r""" + Return the length of ``self`` in generating reflections. + + This is the minimal numbers of generating reflections needed + to obtain ``self``. + + EXAMPLES:: + + sage: W = ReflectionGroup(4) # optional - gap3 + sage: for w in W: # optional - gap3 + ....: print("{} {}".format(w.reduced_word(), w.length())) + [] 0 + [1] 1 + [2] 1 + [1, 1] 2 + [1, 2] 2 + [2, 1] 2 + [2, 2] 2 + [1, 1, 2] 3 + [1, 2, 1] 3 + [1, 2, 2] 3 + [2, 1, 1] 3 + [2, 2, 1] 3 + [1, 1, 2, 1] 4 + [1, 1, 2, 2] 4 + [1, 2, 1, 1] 4 + [1, 2, 2, 1] 4 + [2, 1, 1, 2] 4 + [2, 2, 1, 1] 4 + [1, 1, 2, 1, 1] 5 + [1, 1, 2, 2, 1] 5 + [1, 2, 1, 1, 2] 5 + [1, 2, 2, 1, 1] 5 + [1, 1, 2, 1, 1, 2] 6 + [1, 1, 2, 2, 1, 1] 6 + """ + return len(self.reduced_word()) + + #@cached_in_parent_method + def to_matrix(self, on_space="primal"): + r""" + Return ``self`` as a matrix acting on the underlying vector + space. + + - ``on_space`` -- optional (default: ``"primal"``) whether + to act as the reflection representation on the given + basis, or to act on the dual reflection representation + on the dual basis + + EXAMPLES:: + + sage: W = ReflectionGroup((3,1,2)) # optional - gap3 + sage: for w in W: # optional - gap3 + ....: w.reduced_word() # optional - gap3 + ....: [w.to_matrix(), w.to_matrix(on_space="dual")] # optional - gap3 + [] + [ + [1 0] [1 0] + [0 1], [0 1] + ] + [1] + [ + [E(3) 0] [E(3)^2 0] + [ 0 1], [ 0 1] + ] + [2] + [ + [0 1] [0 1] + [1 0], [1 0] + ] + [1, 1] + [ + [E(3)^2 0] [E(3) 0] + [ 0 1], [ 0 1] + ] + [1, 2] + [ + [ 0 E(3)] [ 0 E(3)^2] + [ 1 0], [ 1 0] + ] + [2, 1] + [ + [ 0 1] [ 0 1] + [E(3) 0], [E(3)^2 0] + ] + [1, 1, 2] + [ + [ 0 E(3)^2] [ 0 E(3)] + [ 1 0], [ 1 0] + ] + [1, 2, 1] + [ + [ 0 E(3)] [ 0 E(3)^2] + [E(3) 0], [E(3)^2 0] + ] + [2, 1, 1] + [ + [ 0 1] [ 0 1] + [E(3)^2 0], [E(3) 0] + ] + [2, 1, 2] + [ + [ 1 0] [ 1 0] + [ 0 E(3)], [ 0 E(3)^2] + ] + [1, 1, 2, 1] + [ + [ 0 E(3)^2] [ 0 E(3)] + [ E(3) 0], [E(3)^2 0] + ] + [1, 2, 1, 1] + [ + [ 0 E(3)] [ 0 E(3)^2] + [E(3)^2 0], [ E(3) 0] + ] + [1, 2, 1, 2] + [ + [E(3) 0] [E(3)^2 0] + [ 0 E(3)], [ 0 E(3)^2] + ] + [2, 1, 1, 2] + [ + [ 1 0] [ 1 0] + [ 0 E(3)^2], [ 0 E(3)] + ] + [1, 1, 2, 1, 1] + [ + [ 0 E(3)^2] [ 0 E(3)] + [E(3)^2 0], [E(3) 0] + ] + [1, 1, 2, 1, 2] + [ + [E(3)^2 0] [ E(3) 0] + [ 0 E(3)], [ 0 E(3)^2] + ] + [1, 2, 1, 1, 2] + [ + [ E(3) 0] [E(3)^2 0] + [ 0 E(3)^2], [ 0 E(3)] + ] + [1, 1, 2, 1, 1, 2] + [ + [E(3)^2 0] [E(3) 0] + [ 0 E(3)^2], [ 0 E(3)] + ] + """ + W = self.parent() + if W._reflection_representation is None: + Phi = W.roots() + inds = [W._index_set_inverse[i] for i in W.independent_roots().keys()] + M = Matrix([Phi[self(i+1)-1] for i in inds]) + mat = W.base_change_matrix() * M + else: + refl_repr = W._reflection_representation + id_mat = identity_matrix(QQ, refl_repr[W.index_set()[0]].nrows()) + mat = prod([refl_repr[i] for i in self.reduced_word()], id_mat) + + if on_space == "primal": + pass + elif on_space == "dual": + mat = mat.inverse().transpose() + else: + raise ValueError('on_space must be "primal" or "dual"') + + mat.set_immutable() + return mat + + matrix = to_matrix + + def action(self, vec, on_space="primal"): + r""" + Return the image of ``vec`` under the action of ``self``. + + INPUT: + + - ``vec`` -- vector in the basis given by the simple root + + - ``on_space`` -- optional (default: ``"primal"``) whether + to act as the reflection representation on the given + basis, or to act on the dual reflection representation + on the dual basis + + EXAMPLES:: + + sage: W = ReflectionGroup((3,1,2)) # optional - gap3 + sage: w = W.from_reduced_word([1, 2, 1, 1, 2]) # optional - gap3 + sage: for alpha in W.independent_roots(): # optional - gap3 + ....: print("%s -> %s"%(alpha,w.action(alpha))) # optional - gap3 + (1, 0) -> (E(3), 0) + (-1, 1) -> (-E(3), E(3)^2) + """ + mat = self.matrix(on_space=on_space) + return vec * mat + + cpdef _act_on_(self, vec, bint self_on_left): + r""" + Defines the action of ``self`` as a linear transformation + on the vector space, in the basis given by the simple + roots. + + - ``vec`` -- the vector (an iterable) to act on + + - ``self_on_left`` -- whether the action of ``self`` is on + the left or on the right + + .. WARNING:: + + This coercion is currently only defined for + ``self_on_left`` being ``False``. + + EXAMPLES:: + + sage: W = ReflectionGroup(['A',2]) # optional - gap3 + sage: w = W.from_reduced_word([1,2]) # optional - gap3 + sage: for root in W.positive_roots(): # optional - gap3 + ....: print("%s -> %s"%(root, w*root)) # optional - gap3 + (1, 0) -> (0, 1) + (0, 1) -> (-1, -1) + (1, 1) -> (-1, 0) + + sage: for root in W.positive_roots(): # optional - gap3 + ....: print("%s -> %s"%(root, root*w)) # optional - gap3 + (1, 0) -> (-1, -1) + (0, 1) -> (1, 0) + (1, 1) -> (0, -1) + """ + if not self_on_left: + return self.action(vec, side="right") + + def action_on_root_indices(self, i): + """ + Return the right action on the set of roots. + + INPUT: + + - ``i`` -- index of the root to act on + + EXAMPLES:: + + sage: W = ReflectionGroup(['A',3]) # optional - gap3 + sage: w = W.w0 # optional - gap3 + sage: N = len(W.roots()) # optional - gap3 + sage: [w.action_on_root_indices(i) for i in range(N)] # optional - gap3 + [8, 7, 6, 10, 9, 11, 2, 1, 0, 4, 3, 5] + + sage: W = ReflectionGroup(['A',2], reflection_index_set=['A','B','C']) # optional - gap3 + sage: w = W.w0 # optional - gap3 + sage: N = len(W.roots()) # optional - gap3 + sage: [w.action_on_root_indices(i) for i in range(N)] # optional - gap3 + [4, 3, 5, 1, 0, 2] + + TESTS:: + + sage: W = ReflectionGroup(4) # optional - gap3 + sage: N = len(W.roots()) # optional - gap3 + sage: all(sorted([w.action_on_root_indices(i) for i in range(N)]) == list(range(N)) for w in W) # optional - gap3 + True + """ + return self(i + 1) - 1 + + def action_on_root(self, root): + r""" + Return the root obtained by applying ``self`` to ``root`` + on the right. + + INPUT: + + - ``root`` -- the root to act on + + EXAMPLES:: + + sage: W = ReflectionGroup(['A',2]) # optional - gap3 + sage: for w in W: # optional - gap3 + ....: print("%s %s"%(w.reduced_word(), # optional - gap3 + ....: [w.action_on_root(beta,side="left") for beta in W.positive_roots()])) # optional - gap3 + [] [(1, 0), (0, 1), (1, 1)] + [2] [(1, 1), (0, -1), (1, 0)] + [1] [(-1, 0), (1, 1), (0, 1)] + [1, 2] [(0, 1), (-1, -1), (-1, 0)] + [2, 1] [(-1, -1), (1, 0), (0, -1)] + [1, 2, 1] [(0, -1), (-1, 0), (-1, -1)] + + TESTS:: + + sage: W = ReflectionGroup(4); Phi = sorted(W.roots()) # optional - gap3 + sage: all(sorted([w.action_on_root(beta) for beta in Phi]) == Phi for w in W) # optional - gap3 + True + """ + Phi = self.parent().roots() + return Phi[self.action_on_root_indices(Phi.index(root))] + + def to_permutation_of_roots(self): + r""" + Return ``self`` as a permutation of the roots with indexing + starting at `1`. + + EXAMPLES:: + + sage: W = ReflectionGroup((1,1,3)) # optional - gap3 + sage: for w in W: # optional - gap3 + ....: perm = w.to_permutation_of_roots() + ....: print("{} {}".format(perm, perm == w)) + () True + (1,3)(2,5)(4,6) True + (1,4)(2,3)(5,6) True + (1,6,2)(3,5,4) True + (1,2,6)(3,4,5) True + (1,5)(2,4)(3,6) True + """ + return PermutationGroupElement(self) + + #@cached_in_parent_method + def fix_space(self): + r""" + Return the fix space of ``self``. + + This is the sub vector space of the underlying vector space + on which ``self`` acts trivially. + + EXAMPLES:: + + sage: W = ReflectionGroup((1,1,3)) # optional - gap3 + sage: for w in W: # optional - gap3 + ....: w.reduced_word() # optional - gap3 + ....: w.fix_space() # optional - gap3 + [] + Vector space of degree 2 and dimension 2 over Rational Field + Basis matrix: + [1 0] + [0 1] + [2] + Vector space of degree 2 and dimension 1 over Rational Field + Basis matrix: + [1 0] + [1] + Vector space of degree 2 and dimension 1 over Rational Field + Basis matrix: + [0 1] + [1, 2] + Vector space of degree 2 and dimension 0 over Rational Field + Basis matrix: + [] + [2, 1] + Vector space of degree 2 and dimension 0 over Rational Field + Basis matrix: + [] + [1, 2, 1] + Vector space of degree 2 and dimension 1 over Rational Field + Basis matrix: + [ 1 -1] + + sage: W = ReflectionGroup(23) # optional - gap3 + sage: W.an_element().fix_space() # optional - gap3 + Vector space of degree 3 and dimension 2 over Universal Cyclotomic Field + Basis matrix: + [0 1 0] + [0 0 1] + """ + I = identity_matrix(QQ, self.parent().rank()) + return (self.to_matrix() - I).right_kernel() + + #@cached_in_parent_method + def reflection_eigenvalues(self, is_class_representative=False): + r""" + Return the reflection eigenvalues of ``self``. + + INPUT: + + - ``is_class_representative`` -- (default: ``False``) whether + to first replace ``self`` by the representative of its + conjugacy class + + EXAMPLES:: + + sage: W = ReflectionGroup(4) # optional - gap3 + sage: for w in W: w.reflection_eigenvalues() # optional - gap3 + [0, 0] + [1/3, 0] + [1/3, 0] + [2/3, 0] + [1/6, 1/2] + [1/6, 1/2] + [2/3, 0] + [1/4, 3/4] + [1/4, 3/4] + [1/4, 3/4] + [1/4, 3/4] + [1/4, 3/4] + [1/3, 0] + [1/2, 5/6] + [1/3, 0] + [1/2, 5/6] + [1/2, 5/6] + [1/2, 5/6] + [1/6, 1/2] + [2/3, 0] + [1/6, 1/2] + [2/3, 0] + [1/2, 1/2] + [1/4, 3/4] + """ + return self.parent().reflection_eigenvalues(self, is_class_representative=is_class_representative) + + #@cached_in_parent_method + def galois_conjugates(self): + r""" + Return all Galois conjugates of ``self``. + + EXAMPLES:: + + sage: W = ReflectionGroup(4) # optional - gap3 + sage: for w in W: print(w.galois_conjugates()) # optional - gap3 + [[1 0] + [0 1]] + [[ 1 0] + [ 0 E(3)], [ 1 0] + [ 0 E(3)^2]] + [[ 1/3*E(3) - 1/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2] + [ 4/3*E(3) + 2/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2], + [-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2] + [ 2/3*E(3) + 4/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2]] + [[ 1 0] + [ 0 E(3)^2], [ 1 0] + [ 0 E(3)]] + [[ 1/3*E(3) - 1/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2] + [-2/3*E(3) + 2/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2], + [-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2] + [ 2/3*E(3) - 2/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2]] + [[ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2] + [ 4/3*E(3) + 2/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2], + [-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2] + [ 2/3*E(3) + 4/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2]] + [[-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2] + [ 2/3*E(3) + 4/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2], + [ 1/3*E(3) - 1/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2] + [ 4/3*E(3) + 2/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2]] + [[ 1/3*E(3) - 1/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2] + [-2/3*E(3) - 4/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2], + [-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2] + [-4/3*E(3) - 2/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2]] + [[ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2] + [-2/3*E(3) + 2/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2], + [-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2] + [ 2/3*E(3) - 2/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2]] + [[-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2] + [-4/3*E(3) - 2/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2], + [ 1/3*E(3) - 1/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2] + [-2/3*E(3) - 4/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2]] + [[ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2] + [ 4/3*E(3) + 2/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2], + [-1/3*E(3) + 1/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2] + [ 2/3*E(3) + 4/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2]] + [[-1/3*E(3) + 1/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2] + [ 2/3*E(3) + 4/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2], + [ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2] + [ 4/3*E(3) + 2/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2]] + [[ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2] + [-2/3*E(3) - 4/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2], + [-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2] + [-4/3*E(3) - 2/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2]] + [[-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2] + [ 2/3*E(3) - 2/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2], + [ 1/3*E(3) - 1/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2] + [-2/3*E(3) + 2/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2]] + [[ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2] + [-2/3*E(3) + 2/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2], + [-1/3*E(3) + 1/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2] + [ 2/3*E(3) - 2/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2]] + [[-1/3*E(3) + 1/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2] + [-4/3*E(3) - 2/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2], + [ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2] + [-2/3*E(3) - 4/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2]] + [[ -1 0] + [ 0 -E(3)], [ -1 0] + [ 0 -E(3)^2]] + [[-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2] + [ 2/3*E(3) + 4/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2], + [ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2] + [ 4/3*E(3) + 2/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2]] + [[ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2] + [-2/3*E(3) - 4/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2], + [-1/3*E(3) + 1/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2] + [-4/3*E(3) - 2/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2]] + [[-1/3*E(3) + 1/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2] + [ 2/3*E(3) - 2/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2], + [ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2] + [-2/3*E(3) + 2/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2]] + [[ -1 0] + [ 0 -E(3)^2], [ -1 0] + [ 0 -E(3)]] + [[-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2] + [-4/3*E(3) - 2/3*E(3)^2 -2/3*E(3) - 1/3*E(3)^2], + [ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2] + [-2/3*E(3) - 4/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2]] + [[-1 0] + [ 0 -1]] + [[-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2] + [ 2/3*E(3) - 2/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2], + [ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2] + [-2/3*E(3) + 2/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2]] + """ + rk = self.parent().rank() + M = self.to_matrix().list() + m = lcm([x.conductor() if hasattr(x,"conductor") else 1 for x in M]) + M_gals = [x.galois_conjugates(m) if hasattr(x,"galois_conjugates") else [x] for x in M] + conjugates = [] + for i in range(len(M_gals[0])): + conjugates.append(Matrix(rk, [X[i] for X in M_gals])) + return conjugates + +cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): + @lazy_attribute + def _reduced_word(self): + r""" + Computes a reduced word and stores it into ``self._reduced_word``. + The words are in ``range(n)`` and not in the index set. + + TESTS:: + + sage: W = ReflectionGroup(['A',2]) # optional - gap3 + sage: [w._reduced_word for w in W] # optional - gap3 + [[], [1], [0], [0, 1], [1, 0], [0, 1, 0]] + """ + return reduced_word_c(self.parent(),self) + + def reduced_word_in_reflections(self): + r""" + Return a word in the reflections to obtain ``self``. + + EXAMPLES:: + + sage: W = ReflectionGroup(['A',2], index_set=['a','b'], reflection_index_set=['A','B','C']) # optional - gap3 + sage: [(w.reduced_word(), w.reduced_word_in_reflections()) for w in W] # optional - gap3 + [([], []), + (['b'], ['B']), + (['a'], ['A']), + (['a', 'b'], ['A', 'B']), + (['b', 'a'], ['A', 'C']), + (['a', 'b', 'a'], ['C'])] + + .. SEEALSO:: :meth:`reduced_word` + """ + if self.is_one(): + return [] + + W = self.parent() + r = self.reflection_length() + R = W.reflections() + I = W.reflection_index_set() + word = [] + while r > 0: + for i in I: + w = R[i]._mul_(self) + if w.reflection_length() < r: + word += [i] + r -= 1 + self = w + break + return word + + def length(self): + r""" + Return the length of ``self`` in generating reflections. + + This is the minimal numbers of generating reflections needed + to obtain ``self``. + + EXAMPLES:: + + sage: W = ReflectionGroup(['A',2]) # optional - gap3 + sage: for w in W: # optional - gap3 + ....: print("%s %s"%(w.reduced_word(), w.length())) # optional - gap3 + [] 0 + [2] 1 + [1] 1 + [1, 2] 2 + [2, 1] 2 + [1, 2, 1] 3 + """ + return len(self._reduced_word) + + cpdef bint has_left_descent(self, i): + r""" + Return whether ``i`` is a left descent of ``self``. + + This is done by testing whether ``i`` is mapped by ``self`` + to a negative root. + + EXAMPLES:: + + sage: W = ReflectionGroup(["A",3]) # optional - gap3 + sage: s = W.simple_reflections() # optional - gap3 + sage: (s[1]*s[2]).has_left_descent(1) # optional - gap3 + True + sage: (s[1]*s[2]).has_left_descent(2) # optional - gap3 + False + """ + W = self.parent() + return self(W._index_set_inverse[i]+1) > W.number_of_reflections() + + cpdef bint has_descent(self, i, side="left", positive=False): + r""" + Return whether ``i`` is a descent (or ascent) of ``self``. + + This is done by testing whether ``i`` is mapped by ``self`` + to a negative root. + + INPUT: + + - ``i`` -- an index of a simple reflection + - ``side`` (default: ``'right'``) -- ``'left'`` or ``'right'`` + - ``positive`` (default: ``False``) -- a boolean + + EXAMPLES:: + + sage: W = ReflectionGroup(["A",3]) # optional - gap3 + sage: s = W.simple_reflections() # optional - gap3 + sage: (s[1]*s[2]).has_descent(1) # optional - gap3 + True + sage: (s[1]*s[2]).has_descent(2) # optional - gap3 + False + """ + if not isinstance(positive, bool): + raise TypeError("%s is not a boolean"%(bool)) + + if i not in self.parent().index_set(): + raise ValueError("the given index %s is not in the index set"%i) + + negative = not positive + + if side == 'left': + return self.has_left_descent(i) is negative + elif side == 'right': + return self.has_right_descent(i) is negative + else: + raise ValueError('side must be "left" or "right"') + + def to_matrix(self, side="right", on_space="primal"): + r""" + Return ``self`` as a matrix acting on the underlying vector + space. + + - ``side`` -- optional (default: ``"right"``) whether the + action of ``self`` is on the ``"left"`` or on the ``"right"`` + + - ``on_space`` -- optional (default: ``"primal"``) whether + to act as the reflection representation on the given + basis, or to act on the dual reflection representation + on the dual basis + + EXAMPLES:: + + sage: W = ReflectionGroup(['A',2]) # optional - gap3 + sage: for w in W: # optional - gap3 + ....: w.reduced_word() # optional - gap3 + ....: [w.to_matrix(), w.to_matrix(on_space="dual")] # optional - gap3 + [] + [ + [1 0] [1 0] + [0 1], [0 1] + ] + [2] + [ + [ 1 1] [ 1 0] + [ 0 -1], [ 1 -1] + ] + [1] + [ + [-1 0] [-1 1] + [ 1 1], [ 0 1] + ] + [1, 2] + [ + [-1 -1] [ 0 -1] + [ 1 0], [ 1 -1] + ] + [2, 1] + [ + [ 0 1] [-1 1] + [-1 -1], [-1 0] + ] + [1, 2, 1] + [ + [ 0 -1] [ 0 -1] + [-1 0], [-1 0] + ] + + TESTS:: + + sage: W = ReflectionGroup(['F',4]) # optional - gap3 + sage: all(w.to_matrix(side="left") == W.from_reduced_word(reversed(w.reduced_word())).to_matrix(side="right").transpose() for w in W) # optional - gap3 + True + sage: all(w.to_matrix(side="right") == W.from_reduced_word(reversed(w.reduced_word())).to_matrix(side="left").transpose() for w in W) # optional - gap3 + True + """ + W = self.parent() + if W._reflection_representation is None: + if side == "left": + w = ~self + elif side == "right": + w = self + else: + raise ValueError('side must be "left" or "right"') + + Delta = W.independent_roots() + Phi = W.roots() + M = Matrix([Phi[w(Phi.index(alpha)+1)-1] for alpha in Delta]) + mat = W.base_change_matrix() * M + else: + refl_repr = W._reflection_representation + id_mat = identity_matrix(QQ, refl_repr[W.index_set()[0]].nrows()) + mat = prod([refl_repr[i] for i in self.reduced_word()], id_mat) + + if on_space == "primal": + if side == "left": + mat = mat.transpose() + elif on_space == "dual": + if side == "left": + mat = mat.inverse() + else: + mat = mat.inverse().transpose() + else: + raise ValueError('on_space must be "primal" or "dual"') + + mat.set_immutable() + return mat + + matrix = to_matrix + + def action(self, vec, side="right", on_space="primal"): + r""" + Return the image of ``vec`` under the action of ``self``. + + INPUT: + + - ``vec`` -- vector in the basis given by the simple root + + - ``side`` -- optional (default: ``"right"``) whether the + action of ``self`` is on the ``"left"`` or on the ``"right"`` + + - ``on_space`` -- optional (default: ``"primal"``) whether + to act as the reflection representation on the given + basis, or to act on the dual reflection representation + on the dual basis + + EXAMPLES:: + + sage: W = ReflectionGroup(['A',2]) # optional - gap3 + sage: for w in W: # optional - gap3 + ....: print("%s %s"%(w.reduced_word(), # optional - gap3 + ....: [w.action(weight,side="left") for weight in W.fundamental_weights()])) # optional - gap3 + [] [(2/3, 1/3), (1/3, 2/3)] + [2] [(2/3, 1/3), (1/3, -1/3)] + [1] [(-1/3, 1/3), (1/3, 2/3)] + [1, 2] [(-1/3, 1/3), (-2/3, -1/3)] + [2, 1] [(-1/3, -2/3), (1/3, -1/3)] + [1, 2, 1] [(-1/3, -2/3), (-2/3, -1/3)] + + TESTS:: + + sage: W = ReflectionGroup(['B',3]) # optional - gap3 + sage: all(w.action(alpha,side="right") == w.action_on_root(alpha,side="right") # optional - gap3 + ....: for w in W for alpha in W.simple_roots()) # optional - gap3 + True + sage: all(w.action(alpha,side="left") == w.action_on_root(alpha,side="left") #optional - gap3 + ....: for w in W for alpha in W.simple_roots()) # optional - gap3 + True + """ + W = self.parent() + n = W.rank() + Phi = W.roots() + if side == "right": + w = self + elif side == "left": + w = ~self + else: + raise ValueError('side must be "left" or "right"') + if on_space == "primal": + return sum(vec[j] * Phi[w(j+1) - 1] for j in range(n)) + elif on_space == "dual": + w = ~w + return sum(Phi[w(j+1) - 1]*vec[j] for j in range(n)) + else: + raise ValueError('on_space must be "primal" or "dual"') + + cpdef _act_on_(self, vec, bint self_on_left): + r""" + Give the action of ``self`` as a linear transformation on + the vector space, in the basis given by the simple roots. + + INPUT: + + - ``vec`` -- the vector (an iterable) to act on + + - ``self_on_left`` -- whether the action of ``self`` is on + the left or on the right + + EXAMPLES:: + + sage: W = ReflectionGroup(['A',2]) # optional - gap3 + sage: w = W.from_reduced_word([1,2]) # optional - gap3 + sage: for root in W.positive_roots(): # optional - gap3 + ....: print("%s -> %s"%(root, w*root)) # optional - gap3 + (1, 0) -> (0, 1) + (0, 1) -> (-1, -1) + (1, 1) -> (-1, 0) + + sage: for root in W.positive_roots(): # optional - gap3 + ....: print("%s -> %s"%(root, root*w)) # optional - gap3 + (1, 0) -> (-1, -1) + (0, 1) -> (1, 0) + (1, 1) -> (0, -1) + """ + if self_on_left: + return self.action(vec,side="left") + else: + return self.action(vec,side="right") + + def action_on_root_indices(self, i, side="right"): + """ + Return the action on the set of roots. + + INPUT: + + - ``i`` -- index of the root to act on + + - ``side`` -- optional (default: ``"right"``) whether the + action is on the left or on the right + + EXAMPLES:: + + sage: W = ReflectionGroup(['A',3]) # optional - gap3 + sage: w = W.w0 # optional - gap3 + sage: N = len(W.roots()) # optional - gap3 + sage: [w.action_on_root_indices(i,side="left") for i in range(N)] # optional - gap3 + [8, 7, 6, 10, 9, 11, 2, 1, 0, 4, 3, 5] + + sage: W = ReflectionGroup(['A',2], reflection_index_set=['A','B','C']) # optional - gap3 + sage: w = W.w0 # optional - gap3 + sage: N = len(W.roots()) # optional - gap3 + sage: [w.action_on_root_indices(i,side="left") for i in range(N)] # optional - gap3 + [4, 3, 5, 1, 0, 2] + """ + if side == "right": + w = self + elif side == "left": + w = ~self + else: + raise ValueError('side must be "left" or "right"') + return w(i + 1) - 1 + + def action_on_root(self, root, side="right"): + r""" + Return the root obtained by applying ``self`` to ``root``. + + INPUT: + + - ``root`` -- the root to act on + + - ``side`` -- optional (default: ``"right"``) whether the + action is on the left or on the right + + EXAMPLES:: + + sage: W = ReflectionGroup(['A',2]) # optional - gap3 + sage: for w in W: # optional - gap3 + ....: print("%s %s"%(w.reduced_word(), # optional - gap3 + ....: [w.action_on_root(beta,side="left") for beta in W.positive_roots()])) # optional - gap3 + [] [(1, 0), (0, 1), (1, 1)] + [2] [(1, 1), (0, -1), (1, 0)] + [1] [(-1, 0), (1, 1), (0, 1)] + [1, 2] [(0, 1), (-1, -1), (-1, 0)] + [2, 1] [(-1, -1), (1, 0), (0, -1)] + [1, 2, 1] [(0, -1), (-1, 0), (-1, -1)] + + sage: W = ReflectionGroup(['A',2]) # optional - gap3 + sage: for w in W: # optional - gap3 + ....: print("%s %s"%(w.reduced_word(), # optional - gap3 + ....: [w.action_on_root(beta,side="right") for beta in W.positive_roots()])) # optional - gap3 + [] [(1, 0), (0, 1), (1, 1)] + [2] [(1, 1), (0, -1), (1, 0)] + [1] [(-1, 0), (1, 1), (0, 1)] + [1, 2] [(-1, -1), (1, 0), (0, -1)] + [2, 1] [(0, 1), (-1, -1), (-1, 0)] + [1, 2, 1] [(0, -1), (-1, 0), (-1, -1)] + """ + Phi = self.parent().roots() + return Phi[self.action_on_root_indices(Phi.index(root), side=side)] + + def inversion_set(self, side="right"): + r""" + Return the inversion set of ``self``. + + This is the set `\{\beta \in \Phi^+ : s(\beta) \in \Phi^-\}`, + where `s` is ``self``. + + EXAMPLES:: + + sage: W = ReflectionGroup(['A',2]) # optional - gap3 + sage: for w in W: # optional - gap3 + ....: print("%s %s"%(w.reduced_word(), w.inversion_set())) # optional - gap3 + [] [] + [2] [(0, 1)] + [1] [(1, 0)] + [1, 2] [(1, 0), (1, 1)] + [2, 1] [(0, 1), (1, 1)] + [1, 2, 1] [(0, 1), (1, 0), (1, 1)] + + sage: W.from_reduced_word([1,2]).inversion_set(side="left") # optional - gap3 + [(0, 1), (1, 1)] + """ + Phi_plus = set(self.parent().positive_roots()) + return [root for root in Phi_plus + if self.action_on_root(root,side=side) not in Phi_plus] + +def _gap_factorization(w, gens): + r""" + Return a factorization of ``w`` using the generators ``gens``. + + .. WARNING:: + + This is only available through GAP3 and Chevie. + + EXAMPLES:: + + sage: from sage.combinat.root_system.reflection_group_element import _gap_factorization + sage: W = ReflectionGroup((1,1,3)) # optional - gap3 + sage: gens = [W.simple_reflection(i) for i in W.index_set()] # optional - gap3 + sage: [_gap_factorization(w,gens) for w in W] # optional - gap3 + [[], [1], [0], [0, 1], [1, 0], [0, 1, 0]] + """ + gap3.execute('W := GroupWithGenerators(%s)'%str(gens)) + gap3.execute(_gap_factorization_code) + fac = gap3('MinimalWord(W,%s)'%str(w)).sage() + return [i-1 for i in fac] + +_gap_factorization_code = """ +# MinimalWord(G,w) +# given a permutation group G find some expression of minimal length in the +# generators of G and their inverses of the element w (an inverse is +# representated by a negative index). +# To speed up later calls to the same function the fields G.base, G.words, +# G.nbwordslength are kept. +MinimalWord:=function(G,w) + local decode,i,p,g,h,n,bag,nbe,nbf,new,gens,inds; + # to save space elements of G are represented as image of the base, and + # words are represented as: index of previous elt, last generator applied; + if not IsBound(G.base) then + StabChain(G);g:=G; G.base:=[]; + while IsBound(g.orbit) do Add(G.base,g.orbit[1]); g:=g.stabilizer; od; + fi; + w:=OnTuples(G.base,w); + if not IsBound(G.words) then + G.words:=[G.base]; G.lastmult:=[[0,0]]; + G.nbwordslength:=[1]; + fi; + gens:=ShallowCopy(G.generators);inds:=[1..Length(gens)]; + # for g in G.generators do + # if g<>g^-1 then Add(gens,g^-1);Add(inds,-Position(gens,g));fi; + # od; + bag:=Set(G.words); + nbe:=0;nbf:=0; + decode:=function(i)local w;w:=[]; + while i<>1 do Add(w,G.lastmult[i][2]); i:=G.lastmult[i][1];od; + return Reversed(w); + end; + while true do + if w in bag then return decode(Position(G.words,w));fi; + new:=Length(G.words); + for g in [1..Length(gens)] do + for h in [1+Sum(G.nbwordslength{[1..Length(G.nbwordslength)-1]})..new] do + n:=OnTuples(G.words[h],gens[g]); + if n in bag then + nbe:=nbe+1;# if nbe mod 500=1 then Print(".\c");fi; + else + nbf:=nbf+1;# if nbf mod 500=1 then Print("*\c");fi; + Add(G.words,n);Add(G.lastmult,[h,inds[g]]);AddSet(bag,n); + fi; + od; + od; + Add(G.nbwordslength,Length(G.words)-new); + Print("\n",G.nbwordslength[Length(G.nbwordslength)]," elements of length ", + Length(G.nbwordslength)-1); + od; +end;""" + +def _gap_return(S, coerce_obj='self'): + r""" + Return the string ``S`` after a few modifications are done. + + This is a stupid internal function to take GAP output as a string, + replace a few things, to then turn it into a Sage object. + + TESTS:: + + sage: from sage.combinat.root_system.reflection_group_complex import _gap_return + sage: _gap_return("[ (), (1,4)(2,3)(5,6), (1,6,2)(3,5,4) ]") # optional - gap3 + "[self('()',check=False),self('(1,4)(2,3)(5,6)',check=False),self('(1,6,2)(3,5,4)',check=False)]" + """ + S = S.replace(' ','').replace('\n','') + S = S.replace(',(','\',check=False),%s(\'('%coerce_obj).replace('[','[%s(\''%coerce_obj).replace(']','\',check=False)]') + return S + diff --git a/src/sage/combinat/root_system/reflection_group_real.py b/src/sage/combinat/root_system/reflection_group_real.py index be106f0ed9a..2e997c1d897 100644 --- a/src/sage/combinat/root_system/reflection_group_real.py +++ b/src/sage/combinat/root_system/reflection_group_real.py @@ -54,20 +54,13 @@ from six.moves import range from sage.misc.cachefunc import cached_method, cached_in_parent_method -from sage.misc.lazy_attribute import lazy_attribute -from sage.misc.misc_c import prod from sage.combinat.root_system.cartan_type import CartanType, CartanType_abstract -from sage.rings.all import ZZ, QQ -from sage.matrix.matrix import is_Matrix +from sage.rings.all import ZZ from sage.interfaces.gap3 import gap3 from sage.combinat.root_system.reflection_group_complex import ComplexReflectionGroup, IrreducibleComplexReflectionGroup -from sage.categories.coxeter_groups import CoxeterGroups -from sage.combinat.root_system.cartan_matrix import CartanMatrix from sage.combinat.root_system.coxeter_group import is_chevie_available from sage.misc.sage_eval import sage_eval -from sage.rings.universal_cyclotomic_field import UniversalCyclotomicField -from sage.combinat.root_system.reflection_group_c import reduced_word_c -from sage.matrix.all import Matrix, identity_matrix +from sage.combinat.root_system.reflection_group_element import RealReflectionGroupElement def ReflectionGroup(*args,**kwds): r""" @@ -394,18 +387,6 @@ def cartan_type(self): else: return CartanType([W.cartan_type() for W in self.irreducible_components()]) - def simple_root(self, i): - r""" - Return the simple root with index ``i``. - - EXAMPLES:: - - sage: W = ReflectionGroup(['A',3]) # optional - gap3 - sage: W.simple_root(1) # optional - gap3 - (1, 0, 0) - """ - return self.simple_roots()[i] - def positive_roots(self): r""" Return the positive roots of ``self``. @@ -682,7 +663,7 @@ def right_coset_representatives(self, J): (1,12,3,2)(4,11,10,5)(6,9,8,7)] [()] """ - from sage.combinat.root_system.reflection_group_complex import _gap_return + from sage.combinat.root_system.reflection_group_element import _gap_return J_inv = [self._index_set_inverse[j] + 1 for j in J] S = str(gap3('ReducedRightCosetRepresentatives(%s,ReflectionSubgroup(%s,%s))' % (self._gap_group._name, self._gap_group._name, J_inv))) return sage_eval(_gap_return(S), locals={'self': self}) @@ -701,411 +682,7 @@ def simple_root_index(self, i): """ return self._index_set_inverse[i] - class Element(ComplexReflectionGroup.Element): - - @lazy_attribute - def _reduced_word(self): - r""" - Computes a reduced word and stores it into ``self._reduced_word``. - The words are in ``range(n)`` and not in the index set. - - TESTS:: - - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: [w._reduced_word for w in W] # optional - gap3 - [[], [1], [0], [0, 1], [1, 0], [0, 1, 0]] - """ - return reduced_word_c(self.parent(),self) - - def reduced_word_in_reflections(self): - r""" - Return a word in the reflections to obtain ``self``. - - EXAMPLES:: - - sage: W = ReflectionGroup(['A',2], index_set=['a','b'], reflection_index_set=['A','B','C']) # optional - gap3 - sage: [(w.reduced_word(), w.reduced_word_in_reflections()) for w in W] # optional - gap3 - [([], []), - (['b'], ['B']), - (['a'], ['A']), - (['a', 'b'], ['A', 'B']), - (['b', 'a'], ['A', 'C']), - (['a', 'b', 'a'], ['C'])] - - .. SEEALSO:: :meth:`reduced_word` - """ - if self.is_one(): - return [] - - W = self.parent() - r = self.reflection_length() - R = W.reflections() - I = W.reflection_index_set() - word = [] - while r > 0: - for i in I: - w = R[i]._mul_(self) - if w.reflection_length() < r: - word += [i] - r -= 1 - self = w - break - return word - - def length(self): - r""" - Return the length of ``self`` in generating reflections. - - This is the minimal numbers of generating reflections needed - to obtain ``self``. - - EXAMPLES:: - - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: for w in W: # optional - gap3 - ....: print("%s %s"%(w.reduced_word(), w.length())) # optional - gap3 - [] 0 - [2] 1 - [1] 1 - [1, 2] 2 - [2, 1] 2 - [1, 2, 1] 3 - """ - return len(self._reduced_word) - - def has_left_descent(self, i): - r""" - Return whether ``i`` is a left descent of ``self``. - - This is done by testing whether ``i`` is mapped by ``self`` - to a negative root. - - EXAMPLES:: - - sage: W = ReflectionGroup(["A",3]) # optional - gap3 - sage: s = W.simple_reflections() # optional - gap3 - sage: (s[1]*s[2]).has_left_descent(1) # optional - gap3 - True - sage: (s[1]*s[2]).has_left_descent(2) # optional - gap3 - False - """ - W = self.parent() - return self(W._index_set_inverse[i]+1) > W.number_of_reflections() - - def has_descent(self, i, side="left", positive=False): - r""" - Return whether ``i`` is a descent (or ascent) of ``self``. - - This is done by testing whether ``i`` is mapped by ``self`` - to a negative root. - - INPUT: - - - ``i`` -- an index of a simple reflection - - ``side`` (default: ``'right'``) -- ``'left'`` or ``'right'`` - - ``positive`` (default: ``False``) -- a boolean - - EXAMPLES:: - - sage: W = ReflectionGroup(["A",3]) # optional - gap3 - sage: s = W.simple_reflections() # optional - gap3 - sage: (s[1]*s[2]).has_descent(1) # optional - gap3 - True - sage: (s[1]*s[2]).has_descent(2) # optional - gap3 - False - """ - if not isinstance(positive, bool): - raise TypeError("%s is not a boolean"%(bool)) - - if i not in self.parent().index_set(): - raise ValueError("the given index %s is not in the index set"%i) - - negative = not positive - - if side == 'left': - return self.has_left_descent(i) is negative - elif side == 'right': - return self.has_right_descent(i) is negative - else: - raise ValueError('side must be "left" or "right"') - - def to_matrix(self, side="right", on_space="primal"): - r""" - Return ``self`` as a matrix acting on the underlying vector - space. - - - ``side`` -- optional (default: ``"right"``) whether the - action of ``self`` is on the ``"left"`` or on the ``"right"`` - - - ``on_space`` -- optional (default: ``"primal"``) whether - to act as the reflection representation on the given - basis, or to act on the dual reflection representation - on the dual basis - - EXAMPLES:: - - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: for w in W: # optional - gap3 - ....: w.reduced_word() # optional - gap3 - ....: [w.to_matrix(), w.to_matrix(on_space="dual")] # optional - gap3 - [] - [ - [1 0] [1 0] - [0 1], [0 1] - ] - [2] - [ - [ 1 1] [ 1 0] - [ 0 -1], [ 1 -1] - ] - [1] - [ - [-1 0] [-1 1] - [ 1 1], [ 0 1] - ] - [1, 2] - [ - [-1 -1] [ 0 -1] - [ 1 0], [ 1 -1] - ] - [2, 1] - [ - [ 0 1] [-1 1] - [-1 -1], [-1 0] - ] - [1, 2, 1] - [ - [ 0 -1] [ 0 -1] - [-1 0], [-1 0] - ] - - TESTS:: - - sage: W = ReflectionGroup(['F',4]) # optional - gap3 - sage: all(w.to_matrix(side="left") == W.from_reduced_word(reversed(w.reduced_word())).to_matrix(side="right").transpose() for w in W) # optional - gap3 - True - sage: all(w.to_matrix(side="right") == W.from_reduced_word(reversed(w.reduced_word())).to_matrix(side="left").transpose() for w in W) # optional - gap3 - True - """ - W = self.parent() - if W._reflection_representation is None: - if side == "left": - w = ~self - elif side == "right": - w = self - else: - raise ValueError('side must be "left" or "right"') - - Delta = W.independent_roots() - Phi = W.roots() - M = Matrix([Phi[w(Phi.index(alpha)+1)-1] for alpha in Delta]) - mat = W.base_change_matrix() * M - else: - refl_repr = W._reflection_representation - id_mat = identity_matrix(QQ, refl_repr[W.index_set()[0]].nrows()) - mat = prod([refl_repr[i] for i in self.reduced_word()], id_mat) - - if on_space == "primal": - if side == "left": - mat = mat.transpose() - elif on_space == "dual": - if side == "left": - mat = mat.inverse() - else: - mat = mat.inverse().transpose() - else: - raise ValueError('on_space must be "primal" or "dual"') - - mat.set_immutable() - return mat - - matrix = to_matrix - - def action(self, vec, side="right", on_space="primal"): - r""" - Return the image of ``vec`` under the action of ``self``. - - INPUT: - - - ``vec`` -- vector in the basis given by the simple root - - - ``side`` -- optional (default: ``"right"``) whether the - action of ``self`` is on the ``"left"`` or on the ``"right"`` - - - ``on_space`` -- optional (default: ``"primal"``) whether - to act as the reflection representation on the given - basis, or to act on the dual reflection representation - on the dual basis - - EXAMPLES:: - - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: for w in W: # optional - gap3 - ....: print("%s %s"%(w.reduced_word(), # optional - gap3 - ....: [w.action(weight,side="left") for weight in W.fundamental_weights()])) # optional - gap3 - [] [(2/3, 1/3), (1/3, 2/3)] - [2] [(2/3, 1/3), (1/3, -1/3)] - [1] [(-1/3, 1/3), (1/3, 2/3)] - [1, 2] [(-1/3, 1/3), (-2/3, -1/3)] - [2, 1] [(-1/3, -2/3), (1/3, -1/3)] - [1, 2, 1] [(-1/3, -2/3), (-2/3, -1/3)] - - TESTS:: - - sage: W = ReflectionGroup(['B',3]) # optional - gap3 - sage: all(w.action(alpha,side="right") == w.action_on_root(alpha,side="right") # optional - gap3 - ....: for w in W for alpha in W.simple_roots()) # optional - gap3 - True - sage: all(w.action(alpha,side="left") == w.action_on_root(alpha,side="left") #optional - gap3 - ....: for w in W for alpha in W.simple_roots()) # optional - gap3 - True - """ - W = self.parent() - n = W.rank() - Phi = W.roots() - if side == "right": - w = self - elif side == "left": - w = ~self - else: - raise ValueError('side must be "left" or "right"') - if on_space == "primal": - return sum(vec[j] * Phi[w(j+1) - 1] for j in range(n)) - elif on_space == "dual": - w = ~w - return sum(Phi[w(j+1) - 1]*vec[j] for j in range(n)) - else: - raise ValueError('on_space must be "primal" or "dual"') - - def _act_on_(self, vec, self_on_left): - r""" - Give the action of ``self`` as a linear transformation on - the vector space, in the basis given by the simple roots. - - INPUT: - - - ``vec`` -- the vector (an iterable) to act on - - - ``self_on_left`` -- whether the action of ``self`` is on - the left or on the right - - EXAMPLES:: - - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: w = W.from_reduced_word([1,2]) # optional - gap3 - sage: for root in W.positive_roots(): # optional - gap3 - ....: print("%s -> %s"%(root, w*root)) # optional - gap3 - (1, 0) -> (0, 1) - (0, 1) -> (-1, -1) - (1, 1) -> (-1, 0) - - sage: for root in W.positive_roots(): # optional - gap3 - ....: print("%s -> %s"%(root, root*w)) # optional - gap3 - (1, 0) -> (-1, -1) - (0, 1) -> (1, 0) - (1, 1) -> (0, -1) - """ - if self_on_left: - return self.action(vec,side="left") - else: - return self.action(vec,side="right") - - def action_on_root_indices(self, i, side="right"): - """ - Return the action on the set of roots. - - INPUT: - - - ``i`` -- index of the root to act on - - - ``side`` -- optional (default: ``"right"``) whether the - action is on the left or on the right - - EXAMPLES:: - - sage: W = ReflectionGroup(['A',3]) # optional - gap3 - sage: w = W.w0 # optional - gap3 - sage: N = len(W.roots()) # optional - gap3 - sage: [w.action_on_root_indices(i,side="left") for i in range(N)] # optional - gap3 - [8, 7, 6, 10, 9, 11, 2, 1, 0, 4, 3, 5] - - sage: W = ReflectionGroup(['A',2], reflection_index_set=['A','B','C']) # optional - gap3 - sage: w = W.w0 # optional - gap3 - sage: N = len(W.roots()) # optional - gap3 - sage: [w.action_on_root_indices(i,side="left") for i in range(N)] # optional - gap3 - [4, 3, 5, 1, 0, 2] - """ - if side == "right": - w = self - elif side == "left": - w = ~self - else: - raise ValueError('side must be "left" or "right"') - W = w.parent() - return w(i + 1) - 1 - - def action_on_root(self, root, side="right"): - r""" - Return the root obtained by applying ``self`` to ``root``. - - INPUT: - - - ``root`` -- the root to act on - - - ``side`` -- optional (default: ``"right"``) whether the - action is on the left or on the right - - EXAMPLES:: - - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: for w in W: # optional - gap3 - ....: print("%s %s"%(w.reduced_word(), # optional - gap3 - ....: [w.action_on_root(beta,side="left") for beta in W.positive_roots()])) # optional - gap3 - [] [(1, 0), (0, 1), (1, 1)] - [2] [(1, 1), (0, -1), (1, 0)] - [1] [(-1, 0), (1, 1), (0, 1)] - [1, 2] [(0, 1), (-1, -1), (-1, 0)] - [2, 1] [(-1, -1), (1, 0), (0, -1)] - [1, 2, 1] [(0, -1), (-1, 0), (-1, -1)] - - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: for w in W: # optional - gap3 - ....: print("%s %s"%(w.reduced_word(), # optional - gap3 - ....: [w.action_on_root(beta,side="right") for beta in W.positive_roots()])) # optional - gap3 - [] [(1, 0), (0, 1), (1, 1)] - [2] [(1, 1), (0, -1), (1, 0)] - [1] [(-1, 0), (1, 1), (0, 1)] - [1, 2] [(-1, -1), (1, 0), (0, -1)] - [2, 1] [(0, 1), (-1, -1), (-1, 0)] - [1, 2, 1] [(0, -1), (-1, 0), (-1, -1)] - """ - Phi = self.parent().roots() - return Phi[self.action_on_root_indices(Phi.index(root), side=side)] - - def inversion_set(self, side="right"): - r""" - Return the inversion set of ``self``. - - This is the set `\{\beta \in \Phi^+ : s(\beta) \in \Phi^-\}`, - where `s` is ``self``. - - EXAMPLES:: - - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: for w in W: # optional - gap3 - ....: print("%s %s"%(w.reduced_word(), w.inversion_set())) # optional - gap3 - [] [] - [2] [(0, 1)] - [1] [(1, 0)] - [1, 2] [(1, 0), (1, 1)] - [2, 1] [(0, 1), (1, 1)] - [1, 2, 1] [(0, 1), (1, 0), (1, 1)] - - sage: W.from_reduced_word([1,2]).inversion_set(side="left") # optional - gap3 - [(0, 1), (1, 1)] - """ - Phi_plus = set(self.parent().positive_roots()) - return [root for root in Phi_plus if self.action_on_root(root,side=side) not in Phi_plus] + class Element(RealReflectionGroupElement, ComplexReflectionGroup.Element): @cached_in_parent_method def right_coset_representatives(self): @@ -1126,12 +703,12 @@ def right_coset_representatives(self): [2, 1] [[]] [1, 2, 1] [[], [2], [2, 1]] """ - from sage.combinat.root_system.reflection_group_complex import _gap_return W = self.parent() T = W.reflections() T_fix = [i + 1 for i in T.keys() if self.fix_space().is_subspace(T[i].fix_space())] S = str(gap3('ReducedRightCosetRepresentatives(%s,ReflectionSubgroup(%s,%s))' % (W._gap_group._name, W._gap_group._name, T_fix))) + from sage.combinat.root_system.reflection_group_element import _gap_return return sage_eval(_gap_return(S, coerce_obj='W'), locals={'self': self, 'W': W}) diff --git a/src/sage/combinat/root_system/weyl_group.py b/src/sage/combinat/root_system/weyl_group.py index 33c2d77006f..a9cfec27f9c 100644 --- a/src/sage/combinat/root_system/weyl_group.py +++ b/src/sage/combinat/root_system/weyl_group.py @@ -39,21 +39,24 @@ #***************************************************************************** from sage.groups.matrix_gps.finitely_generated import FinitelyGeneratedMatrixGroup_gap from sage.groups.matrix_gps.group_element import MatrixGroupElement_gap +from sage.groups.perm_gps.permgroup import PermutationGroup_generic from sage.rings.all import ZZ, QQ from sage.interfaces.gap import gap from sage.misc.cachefunc import cached_method from sage.combinat.root_system.cartan_type import CartanType from sage.combinat.root_system.cartan_matrix import CartanMatrix +from sage.combinat.root_system.reflection_group_element import RealReflectionGroupElement from sage.matrix.constructor import matrix, diagonal_matrix from sage.combinat.root_system.root_lattice_realizations import RootLatticeRealizations from sage.structure.unique_representation import UniqueRepresentation from sage.structure.sage_object import richcmp, richcmp_not_equal from sage.categories.all import WeylGroups, FiniteWeylGroups, AffineWeylGroups +from sage.categories.permutation_groups import PermutationGroups from sage.sets.family import Family from sage.matrix.constructor import Matrix from sage.graphs.graph import DiGraph -def WeylGroup(x, prefix=None): +def WeylGroup(x, prefix=None, implementation='matrix'): """ Returns the Weyl group of the root system defined by the Cartan type (or matrix) ``ct``. @@ -67,6 +70,10 @@ def WeylGroup(x, prefix=None): - ``prefix`` -- changes the representation of elements from matrices to products of simple reflections + - ``implementation`` -- one of the following: + * ``'matrix'`` - as matrices acting on a root system + * ``"permutation"`` - as a permutation group acting on the roots + EXAMPLES: The following constructions yield the same result, namely @@ -185,6 +192,11 @@ def WeylGroup(x, prefix=None): [2, 0] sage: W = groups.misc.WeylGroup(['A',3,1]) """ + if implementation == "permutation": + return WeylGroup_permutation(x, prefix) + elif implementation != "matrix": + raise ValueError("invalid implementation") + if x in RootLatticeRealizations: return WeylGroup_gens(x, prefix=prefix) @@ -221,6 +233,8 @@ def __init__(self, domain, prefix): category = FiniteWeylGroups() else: category = WeylGroups() + if self.cartan_type().is_irreducible(): + category = category.Irreducible() self.n = domain.dimension() # Really needed? self._prefix = prefix @@ -607,7 +621,7 @@ class ClassicalWeylSubgroup(WeylGroup_gens): sage: G Parabolic Subgroup of the Weyl Group of type ['A', 3, 1] (as a matrix group acting on the root space) sage: G.category() - Category of finite weyl groups + Category of finite irreducible weyl groups sage: G.cardinality() 24 sage: G.index_set() @@ -659,7 +673,8 @@ def simple_reflections(self): Note: won't be needed, once the lattice will be a parabolic sub root system """ - return Family(dict((i, self.from_morphism(self.domain().simple_reflection(i))) for i in self.index_set())) + return Family({i: self.from_morphism(self.domain().simple_reflection(i)) + for i in self.index_set()}) def __repr__(self): """ @@ -678,6 +693,7 @@ def __repr__(self): self._domain._name_string(capitalize=False, base_ring=False, type=False)) + def weyl_group(self, prefix="hereditary"): """ Return the Weyl group associated to the parabolic subgroup. @@ -1016,3 +1032,361 @@ def to_permutation_string(self): return "".join(str(i) for i in self.to_permutation()) WeylGroup_gens.Element = WeylGroupElement + + +class WeylGroup_permutation(UniqueRepresentation, PermutationGroup_generic): + """ + A Weyl group given as a permutation group. + """ + @staticmethod + def __classcall__(cls, cartan_type, prefix=None): + """ + Normalize input to ensure a unique representation. + + EXAMPLES:: + + sage: W1 = WeylGroup(['B',2], implementation="permutation") + sage: W2 = WeylGroup(CartanType(['B',2]), implementation="permutation") + sage: W1 is W2 + True + """ + return super(WeylGroup_permutation, cls).__classcall__(cls, CartanType(cartan_type), prefix) + + def __init__(self, cartan_type, prefix): + """ + Initialize ``self``. + + EXAMPLES:: + + sage: W = WeylGroup(['F',4], implementation="permutation") + sage: TestSuite(W).run() + """ + self._cartan_type = cartan_type + self._index_set = cartan_type.index_set() + self._index_set_inverse = {ii: i for i,ii in enumerate(cartan_type.index_set())} + self._reflection_representation = None + self._prefix = prefix + #from sage.libs.all import libgap + Q = cartan_type.root_system().root_lattice() + Phi = list(Q.positive_roots()) + [-x for x in Q.positive_roots()] + p = [[Phi.index(x.weyl_action([i]))+1 for x in Phi] + for i in self._cartan_type.index_set()] + cat = FiniteWeylGroups() + if self._cartan_type.is_irreducible(): + cat = cat.Irreducible() + cat = (cat, PermutationGroups().Finite()) + PermutationGroup_generic.__init__(self, gens=p, canonicalize=False, category=cat) + + def iteration(self, algorithm="breadth", tracking_words=True): + r""" + Return an iterator going through all elements in ``self``. + + INPUT: + + - ``algorithm`` (default: ``'breadth'``) -- must be one of + the following: + + * ``'breadth'`` - iterate over in a linear extension of the + weak order + * ``'depth'`` - iterate by a depth-first-search + + - ``tracking_words`` (default: ``True``) -- whether or not to keep + track of the reduced words and store them in ``_reduced_word`` + + .. NOTE:: + + The fastest iteration is the depth first algorithm without + tracking words. In particular, ``'depth'`` is ~1.5x faster. + + EXAMPLES:: + + sage: W = WeylGroup(["B",2], implementation="permutation") + + sage: for w in W.iteration("breadth",True): + ....: print("%s %s"%(w, w._reduced_word)) + () [] + (1,3)(2,6)(5,7) [1] + (1,5)(2,4)(6,8) [0] + (1,7,5,3)(2,4,6,8) [0, 1] + (1,3,5,7)(2,8,6,4) [1, 0] + (2,8)(3,7)(4,6) [1, 0, 1] + (1,7)(3,5)(4,8) [0, 1, 0] + (1,5)(2,6)(3,7)(4,8) [0, 1, 0, 1] + + sage: for w in W.iteration("depth", False): w + () + (1,3)(2,6)(5,7) + (1,5)(2,4)(6,8) + (1,3,5,7)(2,8,6,4) + (1,7)(3,5)(4,8) + (1,7,5,3)(2,4,6,8) + (2,8)(3,7)(4,6) + (1,5)(2,6)(3,7)(4,8) + """ + from sage.combinat.root_system.reflection_group_c import Iterator + return iter(Iterator(self, N=self.number_of_reflections(), + algorithm=algorithm, tracking_words=tracking_words)) + + def __iter__(self): + r""" + Return an iterator going through all elements in ``self``. + + For options and faster iteration see :meth:`iteration`. + + EXAMPLES:: + + sage: W = WeylGroup(["B",2], implementation="permutation") + sage: for w in W: print("%s %s"%(w, w._reduced_word)) + () [] + (1,3)(2,6)(5,7) [1] + (1,5)(2,4)(6,8) [0] + (1,7,5,3)(2,4,6,8) [0, 1] + (1,3,5,7)(2,8,6,4) [1, 0] + (2,8)(3,7)(4,6) [1, 0, 1] + (1,7)(3,5)(4,8) [0, 1, 0] + (1,5)(2,6)(3,7)(4,8) [0, 1, 0, 1] + """ + return self.iteration(algorithm="breadth", tracking_words=True) + + @cached_method + def rank(self): + """ + Return the rank of ``self``. + + EXAMPLES:: + + sage: W = WeylGroup(['A',4], implementation="permutation") + sage: W.rank() + 4 + """ + return self._cartan_type.rank() + + def simple_reflection(self, i): + r""" + Return the ``i``-th simple reflection of ``self``. + + EXAMPLES:: + + sage: W = WeylGroup(['A',4], implementation="permutation") + sage: W.simple_reflection(1) + (1,11)(2,6)(7,9)(8,10)(12,16)(17,19)(18,20) + sage: W.simple_reflections() + Finite family {1: (1,11)(2,6)(7,9)(8,10)(12,16)(17,19)(18,20), + 2: (1,6)(2,12)(3,7)(5,8)(11,16)(13,17)(15,18), + 3: (2,7)(3,13)(4,5)(6,9)(12,17)(14,15)(16,19), + 4: (3,5)(4,14)(7,8)(9,10)(13,15)(17,18)(19,20)} + """ + return self.gens()[self._index_set_inverse[i]] + + @cached_method + def simple_roots(self): + """ + Return the simple roots of ``self``. + + EXAMPLES:: + + sage: W = WeylGroup(['A',4], implementation="permutation") + sage: W.simple_roots() + ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)) + """ + Q = self._cartan_type.root_system().root_lattice() + roots = [al.to_vector() for al in Q.simple_roots()] + for v in roots: + v.set_immutable() + return tuple(roots) + + independent_roots = simple_roots + + @cached_method + def index_set(self): + """ + Return the index set of ``self``. + + EXAMPLES:: + + sage: W = WeylGroup(['A',4], implementation="permutation") + sage: W.index_set() + (1, 2, 3, 4) + """ + return self._index_set + + @cached_method + def reflection_index_set(self): + """ + Return the index set of reflections of ``self``. + + EXAMPLES:: + + sage: W = WeylGroup(['A',3], implementation="permutation") + sage: W.reflection_index_set() + (1, 2, 3, 4, 5, 6) + """ + return tuple(range(1, self.number_of_reflections()+1)) + + def cartan_type(self): + """ + Return the Cartan type of ``self``. + + EXAMPLES:: + + sage: W = WeylGroup(['A',4], implementation="permutation") + sage: W.cartan_type() + ['A', 4] + """ + return self._cartan_type + + @cached_method + def roots(self): + """ + Return the roots of ``self``. + + EXAMPLES:: + + sage: W = WeylGroup(['G',2], implementation="permutation") + sage: W.roots() + ((1, 0), + (0, 1), + (1, 1), + (3, 1), + (2, 1), + (3, 2), + (-1, 0), + (0, -1), + (-1, -1), + (-3, -1), + (-2, -1), + (-3, -2)) + """ + Q = self._cartan_type.root_system().root_lattice() + roots = ([x.to_vector() for x in Q.positive_roots()] + + [-x.to_vector() for x in Q.positive_roots()]) + for v in roots: + v.set_immutable() + return tuple(roots) + + def positive_roots(self): + """ + Return the positive roots of ``self``. + + EXAMPLES:: + + sage: W = WeylGroup(['C',3], implementation="permutation") + sage: W.positive_roots() + ((1, 0, 0), + (0, 1, 0), + (0, 0, 1), + (1, 1, 0), + (0, 2, 1), + (0, 1, 1), + (2, 2, 1), + (1, 1, 1), + (1, 2, 1)) + """ + return self.roots()[:self.number_of_reflections()] + + @cached_method + def number_of_reflections(self): + """ + Return the number of reflections in ``self``. + + EXAMPLES:: + + sage: W = WeylGroup(['D',4], implementation="permutation") + sage: W.number_of_reflections() + 12 + """ + return len(list(self._cartan_type.root_system().root_lattice().positive_roots())) + + @cached_method + def distinguished_reflections(self): + """ + Return the reflections of ``self``. + + EXAMPLES:: + + sage: W = WeylGroup(['B',2], implementation="permutation") + sage: W.distinguished_reflections() + Finite family {1: (1,5)(2,4)(6,8), 2: (1,3)(2,6)(5,7), + 3: (2,8)(3,7)(4,6), 4: (1,7)(3,5)(4,8)} + """ + Q = self._cartan_type.root_system().root_lattice() + pos_roots = list(Q.positive_roots()) + Phi = pos_roots + [-x for x in pos_roots] + def build_elt(index): + r = pos_roots[index] + perm = [Phi.index(x.reflection(r))+1 for x in Phi] + return self.element_class(perm, self, check=False) + return Family(self.reflection_index_set(), lambda i: build_elt(i-1)) + + reflections = distinguished_reflections + + def simple_root_index(self, i): + r""" + Return the index of the simple root `\alpha_i`. + + This is the position of `\alpha_i` in the list of simple roots. + + EXAMPLES:: + + sage: W = WeylGroup(['A',3], implementation="permutation") + sage: [W.simple_root_index(i) for i in W.index_set()] + [0, 1, 2] + """ + return self._index_set_inverse[i] + + def _element_class(self): + r""" + A temporary workaround for compatibility with Sage's + permutation groups. + + TESTS:: + + sage: W = WeylGroup(['B',3], implementation="permutation") + sage: W._element_class() is W.element_class + True + """ + return self.element_class + + class Element(RealReflectionGroupElement): + def _repr_(self): + """ + EXAMPLES:: + + sage: W = WeylGroup(['A',3], prefix="s", implementation="permutation") + sage: [s1,s2,s3] = W.simple_reflections() + sage: s1*s2 + s1*s2 + sage: W = WeylGroup(['A',3], implementation="permutation") + sage: [s1,s2,s3] = W.simple_reflections() + sage: s1*s2 + (1,10,2)(3,5,6)(4,8,7)(9,11,12) + """ + if self.parent()._prefix is None: + return RealReflectionGroupElement._repr_(self) + redword = self.reduced_word() + if not redword: + return "1" + else: + return "*".join("%s%d"%(self.parent()._prefix, i) for i in redword) + + def _latex_(self): + """ + EXAMPLES:: + + sage: W = WeylGroup(['A',3], prefix="s", implementation="permutation") + sage: [s1,s2,s3] = W.simple_reflections() + sage: s1*s2 + s1*s2 + sage: W = WeylGroup(['A',3], implementation="permutation") + sage: [s1,s2,s3] = W.simple_reflections() + sage: s1*s2 + (1,10,2)(3,5,6)(4,8,7)(9,11,12) + """ + if self.parent()._prefix is None: + return RealReflectionGroupElement._repr_(self) + redword = self.reduced_word() + if not redword: + return "1" + else: + return "".join("%s_{%d}"%(self.parent()._prefix, i) for i in redword) + From 0ef73628c50f4c5ce45ac7cc2221fbbdcaf70dd9 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Tue, 14 Mar 2017 11:39:12 -0500 Subject: [PATCH 120/185] More standardization and removing CoxeterGroupAsPermutationGroup class. --- .../finite_complex_reflection_groups.py | 2 +- src/sage/categories/weyl_groups.py | 13 + .../combinat/root_system/coxeter_group.py | 240 ++---------------- .../root_system/reflection_group_element.pyx | 37 +++ .../root_system/reflection_group_real.py | 28 +- src/sage/combinat/root_system/weyl_group.py | 32 +-- 6 files changed, 108 insertions(+), 244 deletions(-) diff --git a/src/sage/categories/finite_complex_reflection_groups.py b/src/sage/categories/finite_complex_reflection_groups.py index 28a6a6a2edb..3afab6929a0 100644 --- a/src/sage/categories/finite_complex_reflection_groups.py +++ b/src/sage/categories/finite_complex_reflection_groups.py @@ -641,7 +641,7 @@ def reflection_length(self, in_unitary_group=False): if in_unitary_group or W.is_real(): from sage.matrix.special import identity_matrix I = identity_matrix(self.parent().rank()) - return W.rank() - (self.to_matrix() - I).right_nullity() + return W.rank() - (self.canonical_matrix() - I).right_nullity() else: return len(self.reduced_word_in_reflections()) diff --git a/src/sage/categories/weyl_groups.py b/src/sage/categories/weyl_groups.py index 1dac30c34f6..8617b9b2f47 100644 --- a/src/sage/categories/weyl_groups.py +++ b/src/sage/categories/weyl_groups.py @@ -78,6 +78,19 @@ def additional_structure(self): Finite = LazyImport('sage.categories.finite_weyl_groups', 'FiniteWeylGroups') class ParentMethods: + def coxeter_matrix(self): + """ + Return the Coxeter matrix associated to ``self``. + + EXAMPLES:: + + sage: G = WeylGroup(['A',3]) + sage: G.coxeter_matrix() + [1 3 2] + [3 1 3] + [2 3 1] + """ + return self.cartan_type().coxeter_matrix() def pieri_factors(self, *args, **keywords): r""" diff --git a/src/sage/combinat/root_system/coxeter_group.py b/src/sage/combinat/root_system/coxeter_group.py index ab659832ff0..0882eca14ab 100644 --- a/src/sage/combinat/root_system/coxeter_group.py +++ b/src/sage/combinat/root_system/coxeter_group.py @@ -10,15 +10,9 @@ #***************************************************************************** from six.moves import range -from sage.misc.cachefunc import cached_function, cached_method -from sage.groups.perm_gps.permgroup_element import PermutationGroupElement from sage.combinat.root_system.weyl_group import WeylGroup -from sage.structure.unique_representation import UniqueRepresentation +from sage.combinat.root_system.reflection_group_real import ReflectionGroup from sage.combinat.root_system.cartan_type import CartanType -from sage.groups.perm_gps.permgroup import PermutationGroup_generic - -from sage.misc.lazy_import import lazy_import -lazy_import('sage.groups.matrix_gps.coxeter_group', 'CoxeterMatrixGroup') def CoxeterGroup(data, implementation="reflection", base_ring=None, index_set=None): """ @@ -76,10 +70,10 @@ def CoxeterGroup(data, implementation="reflection", base_ring=None, index_set=No sage: W = CoxeterGroup(["A",2], implementation = "permutation") # optional - gap3 sage: W # optional - gap3 - Permutation Group with generators [(1,3)(2,5)(4,6), (1,4)(2,3)(5,6)] + Permutation Group with generators [(1,4)(2,3)(5,6), (1,3)(2,5)(4,6)] sage: W.category() # optional - gap3 - Join of Category of finite permutation groups - and Category of finite coxeter 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: W = CoxeterGroup(["A",2], implementation="matrix") @@ -105,7 +99,7 @@ def CoxeterGroup(data, implementation="reflection", base_ring=None, index_set=No sage: W = CoxeterGroup(["A",4,1], implementation="permutation") Traceback (most recent call last): ... - NotImplementedError: Coxeter group of type ['A', 4, 1] as permutation group not implemented + ValueError: the type must be finite sage: W = CoxeterGroup(["A",4], implementation="chevie"); W # optional - gap3 Irreducible real reflection group of rank 4 and type A4 @@ -131,6 +125,8 @@ def CoxeterGroup(data, implementation="reflection", base_ring=None, index_set=No if implementation not in ["permutation", "matrix", "coxeter3", "reflection", "chevie", None]: raise ValueError("invalid type implementation") + from sage.groups.matrix_gps.coxeter_group import CoxeterMatrixGroup + try: cartan_type = CartanType(data) except (TypeError, ValueError): # If it is not a Cartan type, try to see if we can represent it as a matrix group @@ -148,225 +144,21 @@ def CoxeterGroup(data, implementation="reflection", base_ring=None, index_set=No raise RuntimeError("coxeter3 must be installed") else: return CoxeterGroup(cartan_type) - if implementation == "permutation" and is_chevie_available() and \ - cartan_type.is_finite() and cartan_type.is_irreducible(): - return CoxeterGroupAsPermutationGroup(cartan_type) + if implementation == "permutation": + if not cartan_type.is_finite(): + raise ValueError("the type must be finite") + if cartan_type.is_crystallographic(): + return WeylGroup(cartan_type, implementation="permutation") + return ReflectionGroup(cartan_type, index_set=index_set) elif implementation == "matrix": if cartan_type.is_crystallographic(): return WeylGroup(cartan_type) return CoxeterMatrixGroup(cartan_type, base_ring, index_set) elif implementation == "chevie": - from sage.combinat.root_system.reflection_group_real import ReflectionGroup - return ReflectionGroup(data, index_set=index_set) + return ReflectionGroup(cartan_type, index_set=index_set) raise NotImplementedError("Coxeter group of type {} as {} group not implemented".format(cartan_type, implementation)) -@cached_function -def is_chevie_available(): - r""" - Tests whether the GAP3 Chevie package is available - - EXAMPLES:: - - sage: from sage.combinat.root_system.coxeter_group import is_chevie_available - sage: is_chevie_available() # random - False - sage: is_chevie_available() in [True, False] - True - """ - try: - from sage.interfaces.gap3 import gap3 - gap3._start() - gap3.load_package("chevie") - return True - except Exception: - return False - -class CoxeterGroupAsPermutationGroup(UniqueRepresentation, PermutationGroup_generic): - - @staticmethod - def __classcall__(cls, cartan_type): - """ - TESTS:: - - sage: from sage.combinat.root_system.coxeter_group import CoxeterGroupAsPermutationGroup - sage: W1 = CoxeterGroupAsPermutationGroup(CartanType(["H",3])) # optional - gap3 - sage: W2 = CoxeterGroupAsPermutationGroup(["H",3]) # optional - gap3 - sage: W1 is W2 # optional - gap3 - True - """ - cartan_type = CartanType(cartan_type) - return super(CoxeterGroupAsPermutationGroup, cls).__classcall__(cls, cartan_type) - - def __init__(self, cartan_type): - """ - Construct this Coxeter group as a Sage permutation group, by - fetching the permutation representation of the generators from - Chevie's database. - - TESTS:: - - sage: from sage.combinat.root_system.coxeter_group import CoxeterGroupAsPermutationGroup - sage: W = CoxeterGroupAsPermutationGroup(CartanType(["H",3])) # optional - gap3 - sage: TestSuite(W).run() # optional - gap3 - """ - if not (cartan_type.is_finite() and cartan_type.is_irreducible()): - raise ValueError("must be a finite irreducible type") - self._semi_simple_rank = cartan_type.n - from sage.interfaces.gap3 import gap3 - gap3._start() - gap3.load_package("chevie") - self._gap_group = gap3('CoxeterGroup("%s",%s)'%(cartan_type.letter,cartan_type.n)) - # Following #9032, x.N is an alias for x.numerical_approx in every Sage object ... - N = self._gap_group.__getattr__("N").sage() - generators = [str(x) for x in self._gap_group.generators] - self._is_positive_root = [None] + [ True ] * N + [False]*N - from sage.categories.finite_permutation_groups import FinitePermutationGroups - from sage.categories.finite_coxeter_groups import FiniteCoxeterGroups - PermutationGroup_generic.__init__(self, gens=generators, - category=(FinitePermutationGroups(), - FiniteCoxeterGroups().Irreducible())) - - def _element_class(self): - """ - A temporary workaround for compatibility with Sage's - permutation groups - - TESTS:: - - sage: from sage.combinat.root_system.coxeter_group import CoxeterGroupAsPermutationGroup - sage: W = CoxeterGroupAsPermutationGroup("H3") # optional - gap3 - sage: W._element_class() is W.element_class # optional - gap3 - True - """ - return self.element_class - - def index_set(self): - """ - Return the index set of this Coxeter group. - - EXAMPLES:: - - sage: W = CoxeterGroup(["H",3], implementation = "permutation") # optional - gap3 - sage: W.index_set() # optional - gap3 - [1, 2, 3] - """ - return list(range(1, self._semi_simple_rank + 1)) - - @cached_method - def reflection(self, i): - """ - Returns the `i`-th reflection of ``self``. - - For `i` in `1, \ldots, n`, this gives the `i`-th simple - reflection of ``self``. - - EXAMPLES:: - - sage: W = CoxeterGroup(["H",3], implementation="permutation") # optional - gap3 - sage: W.simple_reflection(1) # optional - gap3 - (1,16)(2,5)(4,7)(6,9)(8,10)(11,13)(12,14)(17,20)(19,22)(21,24)(23,25)(26,28)(27,29) - sage: W.simple_reflection(2) # optional - gap3 - (1,4)(2,17)(3,6)(5,7)(9,11)(10,12)(14,15)(16,19)(18,21)(20,22)(24,26)(25,27)(29,30) - sage: W.simple_reflection(3) # optional - gap3 - (2,6)(3,18)(4,8)(5,9)(7,10)(11,12)(13,14)(17,21)(19,23)(20,24)(22,25)(26,27)(28,29) - sage: W.reflection(4) # optional - gap3 - (1,5)(2,22)(3,11)(4,19)(7,17)(8,12)(9,13)(10,15)(16,20)(18,26)(23,27)(24,28)(25,30) - sage: W.reflection(5) # optional - gap3 - (1,22)(2,4)(3,9)(5,20)(6,13)(7,16)(8,14)(12,15)(17,19)(18,24)(21,28)(23,29)(27,30) - sage: W.reflection(6) # optional - gap3 - (1,8)(2,18)(3,17)(5,12)(6,21)(7,11)(9,10)(13,15)(16,23)(20,27)(22,26)(24,25)(28,30) - """ - return self(str(self._gap_group.Reflection(i))) - - simple_reflection = reflection - - @cached_method - def degrees(self): - r""" - Return the degrees of ``self`` ordered within each irreducible - component of ``self``. - - EXAMPLES:: - - sage: from sage.combinat.root_system.coxeter_group import CoxeterGroupAsPermutationGroup - sage: W = CoxeterGroupAsPermutationGroup("A3") # optional - gap3 - sage: W.degrees() # optional - gap3 - (2, 3, 4) - sage: W = CoxeterGroupAsPermutationGroup("H3") # optional - gap3 - sage: W.degrees() # optional - gap3 - (2, 6, 10) - """ - if self.is_irreducible(): - try: - return tuple(sorted(self._gap_group.degrees.sage())) - except AttributeError: - return tuple(sorted(self._gap_group.ReflectionDegrees().sage())) - else: - return sum([comp.degrees() for comp in self.irreducible_components()],tuple()) - - class Element(PermutationGroupElement): - - def has_descent(self, i, side = 'right', positive=False): - """ - Returns whether `i` is a (left/right) descent of ``self``. - - See :meth:`sage.categories.coxeter_groups.CoxeterGroups.ElementMethods.descents` for a - description of the options. - - EXAMPLES:: - - sage: W = CoxeterGroup(["A",3]) - sage: s = W.simple_reflections() - sage: w = s[1] * s[2] * s[3] - sage: w.has_descent(3) - True - sage: [ w.has_descent(i) for i in [1,2,3] ] - [False, False, True] - sage: [ w.has_descent(i, side = 'left') for i in [1,2,3] ] - [True, False, False] - sage: [ w.has_descent(i, positive = True) for i in [1,2,3] ] - [True, True, False] - - This implementation is a plain copy of that of - ``CoxeterGroups``. It is there as a workaround since - `PermutationGroupElement` currently redefines abusively - :meth:`has_descent` as if the group was the full symmetric - group. - """ - assert isinstance(positive, bool) - if side == 'right': - return self.has_right_descent(i) != positive - else: - assert side == 'left' - return self.has_left_descent(i) != positive - - def has_left_descent(self, i): - r""" - Returns whether ``i`` is a descent of ``self`` by testing - whether ``i`` is mapped to a negative root. - - EXAMPLES:: - - sage: W = CoxeterGroup(["A",3], implementation = "permutation") # optional - gap3 - sage: s = W.simple_reflections() # optional - gap3 - sage: (s[1]*s[2]).has_left_descent(1) # optional - gap3 - True - sage: (s[1]*s[2]).has_left_descent(2) # optional - gap3 - False - """ - return not self.parent()._is_positive_root[self(i)] - - def __cmp__(self, other): - r""" - Without this comparison method, the initialization of this - permutation group fails ... - - EXAMPLES:: - - sage: W = CoxeterGroup(["B",3], implementation = "permutation") # optional - gap3 - sage: cmp(W.an_element(), W.one()) # optional - gap3 - 1 - """ - return super(CoxeterGroupAsPermutationGroup.Element, self).__cmp__(other) +from sage.structure.sage_object import register_unpickle_override +register_unpickle_override('sage.combinat.root_system.coxeter_group', 'CoxeterGroupAsPermutationGroup', ReflectionGroup) diff --git a/src/sage/combinat/root_system/reflection_group_element.pyx b/src/sage/combinat/root_system/reflection_group_element.pyx index 94462d288d2..5dc9021b635 100644 --- a/src/sage/combinat/root_system/reflection_group_element.pyx +++ b/src/sage/combinat/root_system/reflection_group_element.pyx @@ -263,6 +263,43 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): matrix = to_matrix + def canonical_matrix(self): + r""" + Return the matrix of ``self`` in the canonical faithful representation. + + EXAMPLES:: + + sage: W = WeylGroup(['A',2], prefix='s', implementation="permutation") + sage: for w in W: + ....: w.reduced_word() + ....: w.canonical_matrix() + [] + [1 0] + [0 1] + [2] + [ 1 1] + [ 0 -1] + [1] + [-1 0] + [ 1 1] + [1, 2] + [-1 -1] + [ 1 0] + [2, 1] + [ 0 1] + [-1 -1] + [1, 2, 1] + [ 0 -1] + [-1 0] + """ + W = self.parent() + Phi = W.roots() + inds = [W._index_set_inverse[i] for i in W.independent_roots().keys()] + M = Matrix([Phi[self(i+1)-1] for i in inds]) + mat = W.base_change_matrix() * M + mat.set_immutable() + return mat + def action(self, vec, on_space="primal"): r""" Return the image of ``vec`` under the action of ``self``. diff --git a/src/sage/combinat/root_system/reflection_group_real.py b/src/sage/combinat/root_system/reflection_group_real.py index 2e997c1d897..82751d0f570 100644 --- a/src/sage/combinat/root_system/reflection_group_real.py +++ b/src/sage/combinat/root_system/reflection_group_real.py @@ -53,12 +53,11 @@ from six.moves import range -from sage.misc.cachefunc import cached_method, cached_in_parent_method +from sage.misc.cachefunc import cached_function, cached_method, cached_in_parent_method from sage.combinat.root_system.cartan_type import CartanType, CartanType_abstract from sage.rings.all import ZZ from sage.interfaces.gap3 import gap3 from sage.combinat.root_system.reflection_group_complex import ComplexReflectionGroup, IrreducibleComplexReflectionGroup -from sage.combinat.root_system.coxeter_group import is_chevie_available from sage.misc.sage_eval import sage_eval from sage.combinat.root_system.reflection_group_element import RealReflectionGroupElement @@ -224,6 +223,30 @@ def ReflectionGroup(*args,**kwds): hyperplane_index_set=kwds.get('hyperplane_index_set', None), reflection_index_set=kwds.get('reflection_index_set', None)) +@cached_function +def is_chevie_available(): + r""" + Test whether the GAP3 Chevie package is available. + + EXAMPLES:: + + sage: from sage.combinat.root_system.reflection_group_real import is_chevie_available + sage: is_chevie_available() # random + False + sage: is_chevie_available() in [True, False] + True + """ + try: + from sage.interfaces.gap3 import gap3 + gap3._start() + gap3.load_package("chevie") + return True + except Exception: + return False + +##################################################################### +## Classes + class RealReflectionGroup(ComplexReflectionGroup): """ A real reflection group given as a permutation group. @@ -735,7 +758,6 @@ def left_coset_representatives(self): return [ (~w) for w in self.right_coset_representatives() ] class IrreducibleRealReflectionGroup(RealReflectionGroup, IrreducibleComplexReflectionGroup): - def _repr_(self): r""" Return the string representation of ``self``. diff --git a/src/sage/combinat/root_system/weyl_group.py b/src/sage/combinat/root_system/weyl_group.py index a9cfec27f9c..d00fb12dc27 100644 --- a/src/sage/combinat/root_system/weyl_group.py +++ b/src/sage/combinat/root_system/weyl_group.py @@ -261,20 +261,6 @@ def cartan_type(self): """ return self.domain().cartan_type() - def coxeter_matrix(self): - """ - Return the Coxeter matrix associated to ``self``. - - EXAMPLES:: - - sage: G = WeylGroup(['A',3]) - sage: G.coxeter_matrix() - [1 3 2] - [3 1 3] - [2 3 1] - """ - return self.cartan_type().coxeter_matrix() - @cached_method def index_set(self): """ @@ -742,6 +728,19 @@ def __init__(self, parent, g, check=False): def __hash__(self): return hash(self.matrix()) + def to_matrix(self): + """ + Return ``self`` as a matrix. + + EXAMPLES:: + + sage: G = WeylGroup(['A',2]) + sage: s1 = G.simple_reflection(1) + sage: s1.to_matrix() == s1.matrix() + True + """ + return self.matrix() + def domain(self): """ Returns the ambient lattice associated with self. @@ -1187,13 +1186,14 @@ def simple_roots(self): sage: W = WeylGroup(['A',4], implementation="permutation") sage: W.simple_roots() - ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)) + Finite family {1: (1, 0, 0, 0), 2: (0, 1, 0, 0), + 3: (0, 0, 1, 0), 4: (0, 0, 0, 1)} """ Q = self._cartan_type.root_system().root_lattice() roots = [al.to_vector() for al in Q.simple_roots()] for v in roots: v.set_immutable() - return tuple(roots) + return Family(self._index_set, lambda i: roots[self._index_set_inverse[i]]) independent_roots = simple_roots From ced49200aefa25b91ff96bb2cbc03fe418ec425b Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Tue, 14 Mar 2017 18:58:19 +0100 Subject: [PATCH 121/185] Allow running Sphinx without SSL --- build/pkgs/sphinx/patches/ssl.patch | 62 +++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 build/pkgs/sphinx/patches/ssl.patch diff --git a/build/pkgs/sphinx/patches/ssl.patch b/build/pkgs/sphinx/patches/ssl.patch new file mode 100644 index 00000000000..df2074ab2f7 --- /dev/null +++ b/build/pkgs/sphinx/patches/ssl.patch @@ -0,0 +1,62 @@ +commit b1fbd4cd3118a5f8b4c0790ac843ac4da7d09864 +Author: Jeroen Demeyer +Date: Tue Mar 14 18:56:18 2017 +0100 + + Allow running Sphinx without ssl + +diff --git a/sphinx/util/requests.py b/sphinx/util/requests.py +index ec5aa23..fcce42f 100644 +--- a/sphinx/util/requests.py ++++ b/sphinx/util/requests.py +@@ -36,30 +36,34 @@ except ImportError: + # for requests < 2.4.0 + InsecureRequestWarning = None + +-# try to load requests[security] ++# try to load requests[security] (but only if SSL is available) + try: +- pkg_resources.require(['requests[security]']) +-except (pkg_resources.DistributionNotFound, +- pkg_resources.VersionConflict): + import ssl +- if not getattr(ssl, 'HAS_SNI', False): +- # don't complain on each url processed about the SSL issue +- requests.packages.urllib3.disable_warnings( +- requests.packages.urllib3.exceptions.InsecurePlatformWarning) ++except ImportError: ++ pass ++else: ++ try: ++ pkg_resources.require(['requests[security]']) ++ except (pkg_resources.DistributionNotFound, ++ pkg_resources.VersionConflict): ++ if not getattr(ssl, 'HAS_SNI', False): ++ # don't complain on each url processed about the SSL issue ++ requests.packages.urllib3.disable_warnings( ++ requests.packages.urllib3.exceptions.InsecurePlatformWarning) ++ warnings.warn( ++ 'Some links may return broken results due to being unable to ' ++ 'check the Server Name Indication (SNI) in the returned SSL cert ' ++ 'against the hostname in the url requested. Recommended to ' ++ 'install "requests[security]" as a dependency or upgrade to ' ++ 'a python version with SNI support (Python 3 and Python 2.7.9+).' ++ ) ++ except pkg_resources.UnknownExtra: + warnings.warn( + 'Some links may return broken results due to being unable to ' + 'check the Server Name Indication (SNI) in the returned SSL cert ' + 'against the hostname in the url requested. Recommended to ' +- 'install "requests[security]" as a dependency or upgrade to ' +- 'a python version with SNI support (Python 3 and Python 2.7.9+).' ++ 'install requests-2.4.1+.' + ) +-except pkg_resources.UnknownExtra: +- warnings.warn( +- 'Some links may return broken results due to being unable to ' +- 'check the Server Name Indication (SNI) in the returned SSL cert ' +- 'against the hostname in the url requested. Recommended to ' +- 'install requests-2.4.1+.' +- ) + + if False: + # For type annotation From 3a4e3a13f8dd4a7c683459806f1a4f35c2a228fb Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Tue, 14 Mar 2017 19:35:17 +0100 Subject: [PATCH 122/185] Upgrade docutils --- build/pkgs/docutils/checksums.ini | 6 +++--- build/pkgs/docutils/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/docutils/checksums.ini b/build/pkgs/docutils/checksums.ini index ae3378e23c3..fa0bd928197 100644 --- a/build/pkgs/docutils/checksums.ini +++ b/build/pkgs/docutils/checksums.ini @@ -1,4 +1,4 @@ tarball=docutils-VERSION.tar.gz -sha1=002450621b33c5690060345b0aac25bc2426d675 -md5=4622263b62c5c771c03502afa3157768 -cksum=4175926448 +sha1=c16e14ef18142fa248400cd174edb4fa40e51d5b +md5=ea4a893c633c788be9b8078b6b305d53 +cksum=137667414 diff --git a/build/pkgs/docutils/package-version.txt b/build/pkgs/docutils/package-version.txt index 5a2f0506560..c317a91891f 100644 --- a/build/pkgs/docutils/package-version.txt +++ b/build/pkgs/docutils/package-version.txt @@ -1 +1 @@ -0.12.p0 +0.13.1 From d08356c2d40c486ada7099df864f965775f03778 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 10 Mar 2017 17:53:09 +0100 Subject: [PATCH 123/185] 22578: Polyhedron.bounding_box: New keyword argument integral_hull, use it it .integral_points --- .../geometry/polyhedron/backend_normaliz.py | 2 +- src/sage/geometry/polyhedron/base.py | 27 ++++++++++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/sage/geometry/polyhedron/backend_normaliz.py b/src/sage/geometry/polyhedron/backend_normaliz.py index 58ead439e6c..b4b6c0c37ec 100644 --- a/src/sage/geometry/polyhedron/backend_normaliz.py +++ b/src/sage/geometry/polyhedron/backend_normaliz.py @@ -566,7 +566,7 @@ def integral_points(self, threshold=10000): return () # for small bounding boxes, it is faster to naively iterate over the points of the box if threshold > 1: - box_min, box_max = self.bounding_box(integral=True) + box_min, box_max = self.bounding_box(integral_hull=True) box_points = prod(max_coord-min_coord+1 for min_coord, max_coord in zip(box_min, box_max)) if box_points b: + return None, None + box_max.append(b) + box_min.append(a) + elif integral: box_max.append(ceil(max_coord)) box_min.append(floor(min_coord)) else: @@ -4708,6 +4723,12 @@ def integral_points(self, threshold=100000): sage: len(simplex.integral_points()) 49 + A case where rounding in the right direction goes a long way:: + + sage: P = 1/10*polytopes.hypercube(14) + sage: P.integral_points() + ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),) + 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), @@ -4759,7 +4780,7 @@ def integral_points(self, threshold=100000): return () # for small bounding boxes, it is faster to naively iterate over the points of the box - box_min, box_max = self.bounding_box(integral=True) + box_min, box_max = self.bounding_box(integral_hull=True) box_points = prod(max_coord-min_coord+1 for min_coord, max_coord in zip(box_min, box_max)) if not self.is_lattice_polytope() or \ (self.is_simplex() and box_points < 1000) or \ From 40684b9c5beb99f5073eacc1d1cc323b007c623c Mon Sep 17 00:00:00 2001 From: John Cremona Date: Tue, 14 Mar 2017 19:55:17 +0000 Subject: [PATCH 124/185] #22164 added missing # long time tags --- src/sage/libs/eclib/newforms.pyx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/libs/eclib/newforms.pyx b/src/sage/libs/eclib/newforms.pyx index 1f7667a15fd..6ad4f362fed 100644 --- a/src/sage/libs/eclib/newforms.pyx +++ b/src/sage/libs/eclib/newforms.pyx @@ -129,12 +129,12 @@ cdef class ECModularSymbol: may use up some memory, further calls use no more:: sage: from sage.libs.eclib.newforms import ECModularSymbol - sage: E = EllipticCurve([1,1,0,-108,-432]) # conductor 930 - sage: for _ in range(2): M = ECModularSymbol(E) # long time - sage: mem = get_memory_usage() + sage: E = EllipticCurve([1,1,0,-108,-432]) # conductor 930 # long time + sage: for _ in range(2): M = ECModularSymbol(E) # long time + sage: mem = get_memory_usage() # long time sage: for _ in range(10): M = ECModularSymbol(E) # long time - sage: mem2 = get_memory_usage() - sage: (mem2==mem) or (mem2 - mem) + sage: mem2 = get_memory_usage() # long time + sage: (mem2==mem) or (mem2 - mem) # long time True sage: ECModularSymbol.__new__(ECModularSymbol) From 486204f7e7a5ac5f14573e006f3d6464584ef6bd Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 14 Mar 2017 16:02:23 -0700 Subject: [PATCH 125/185] Polyhedron.bounding_box: Handle empty bounding box --- src/sage/geometry/polyhedron/base.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index c581eda4d43..9abde6ba200 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -4781,6 +4781,8 @@ def integral_points(self, threshold=100000): # for small bounding boxes, it is faster to naively iterate over the points of the box box_min, box_max = self.bounding_box(integral_hull=True) + if box_min is None: + return () box_points = prod(max_coord-min_coord+1 for min_coord, max_coord in zip(box_min, box_max)) if not self.is_lattice_polytope() or \ (self.is_simplex() and box_points < 1000) or \ From 640fe83501fd6c8837456405ffe2410848365463 Mon Sep 17 00:00:00 2001 From: John Cremona Date: Wed, 15 Mar 2017 10:38:47 +0000 Subject: [PATCH 126/185] #22164 deleted machine-dependent doctest --- src/sage/libs/eclib/newforms.pyx | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/sage/libs/eclib/newforms.pyx b/src/sage/libs/eclib/newforms.pyx index 6ad4f362fed..87bc4abc366 100644 --- a/src/sage/libs/eclib/newforms.pyx +++ b/src/sage/libs/eclib/newforms.pyx @@ -122,20 +122,7 @@ cdef class ECModularSymbol: sage: all((M3(r,-1)==M1(r,-1)) for r in QQ.range_by_height(10)) True - TESTS: - - Until :trac:`22164`, eclib had a memory leak. Here we test that - it has gone. After one call to create an ECModularSymbol, which - may use up some memory, further calls use no more:: - - sage: from sage.libs.eclib.newforms import ECModularSymbol - sage: E = EllipticCurve([1,1,0,-108,-432]) # conductor 930 # long time - sage: for _ in range(2): M = ECModularSymbol(E) # long time - sage: mem = get_memory_usage() # long time - sage: for _ in range(10): M = ECModularSymbol(E) # long time - sage: mem2 = get_memory_usage() # long time - sage: (mem2==mem) or (mem2 - mem) # long time - True + TESTS:: sage: ECModularSymbol.__new__(ECModularSymbol) Modular symbol with sign 0 over Rational Field attached to None From 3aa014ba4c7b002a17e50eb121aa611186dc0b3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 15 Mar 2017 11:45:26 +0100 Subject: [PATCH 127/185] trac 22602 relabel poset in increasing way --- src/sage/combinat/posets/posets.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index dc39754282e..f845b5ec8c0 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -4752,7 +4752,7 @@ def with_bounds(self, labels=('bottom', 'top')): return constructor(D) - def relabel(self, relabeling): + def relabel(self, relabeling=None): r""" Return a copy of this poset with its elements relabelled. @@ -4763,6 +4763,9 @@ def relabel(self, relabeling): This function must map each (non-wrapped) element of ``self`` to some distinct object. + If no relabeling is given, the poset is relabeled by integers + according to one of its linear extensions. + EXAMPLES:: sage: P = Poset((divisors(12), attrcall("divides")), linear_extension=True) @@ -4802,6 +4805,14 @@ def relabel(self, relabeling): sage: Q.cover_relations() [[12, 6], [12, 4], [6, 3], [6, 2], [4, 2], [3, 1], [2, 1]] + An example of the default behaviour (increasing relabeling):: + + sage: a2 = posets.ChainPoset(2) + sage: P = a2 * a2 + sage: Q = P.relabel() + sage: Q.cover_relations() + [[0, 1], [0, 2], [1, 3], [2, 3]] + Relabeling a (semi)lattice gives a (semi)lattice:: sage: P = JoinSemilattice({0: [1]}) @@ -4846,12 +4857,18 @@ def relabel(self, relabeling): from sage.combinat.posets.lattices import LatticePoset, \ JoinSemilattice, MeetSemilattice, FiniteLatticePoset, \ FiniteMeetSemilattice, FiniteJoinSemilattice - if isinstance(relabeling, (list, tuple)): - relabeling = {i:relabeling[i] for i in range(len(self._elements))} + + if relabeling is None: + relabeling = {i: i for i in range(len(self._elements))} + elif isinstance(relabeling, (list, tuple)): + relabeling = {i: relabeling[i] + for i in range(len(self._elements))} else: if isinstance(relabeling, dict): relabeling = relabeling.__getitem__ - relabeling = {i: relabeling(x) for i,x in enumerate(self._elements)} + relabeling = {i: relabeling(x) + for i, x in enumerate(self._elements)} + if not self._with_linear_extension: elements = None else: From 141ffc0cc8bac6532f48d79a959b995d5563d5e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 15 Mar 2017 12:05:58 +0100 Subject: [PATCH 128/185] py3: handle last change for zip --- src/sage/graphs/generic_graph.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 8cbdb8a47fb..da2c30195c8 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -311,7 +311,7 @@ ------- """ from __future__ import print_function, absolute_import, division -from six.moves import range +from six.moves import range, zip from six import itervalues, iteritems from copy import copy @@ -714,7 +714,7 @@ def _bit_vector(self): bit = lambda x,y : n_ch_2(max([x,y])) + min([x,y]) bit_vector = set() - v_to_int = {v:i for i,v in enumerate(self.vertices())} + v_to_int = {v: i for i, v in enumerate(self.vertices())} for u,v,_ in self.edge_iterator(): bit_vector.add(bit(v_to_int[u], v_to_int[v])) bit_vector = sorted(bit_vector) @@ -1485,7 +1485,7 @@ def igraph_graph(self, vertex_attrs={}, edge_attrs={}): raise ImportError("The package igraph is not available. To " + "install it, run 'sage -i python_igraph'") - v_to_int = {v:i for i,v in enumerate(self.vertices())} + v_to_int = {v: i for i, v in enumerate(self.vertices())} edges = [(v_to_int[v], v_to_int[w]) for v,w in self.edge_iterator(labels=False)] return igraph.Graph(n = self.num_verts(), @@ -1884,7 +1884,7 @@ def incidence_matrix(self, oriented=None, sparse=True): from sage.matrix.constructor import matrix from sage.rings.integer_ring import ZZ m = matrix(ZZ, self.num_verts(), self.num_edges(), sparse=sparse) - verts = {v:i for i,v in enumerate(self.vertices())} + verts = {v: i for i, v in enumerate(self.vertices())} if oriented: for e, (i, j) in enumerate(self.edge_iterator(labels=False)): @@ -3301,13 +3301,12 @@ def eulerian_orientation(self): # list of vertices of odd degree - from builtins import zip odd = [x for (x, deg) in zip(g.vertex_iterator(), g.degree_iterator()) if deg % 2 == 1] # Picks the first vertex, which is preferably an odd one - if len(odd)>0: - v=odd.pop() + if odd: + v = odd.pop() else: v = next(g.edge_iterator(labels=None))[0] odd.append(v) @@ -4328,9 +4327,9 @@ def is_circular_planar(self, on_embedding=None, kuratowski=False, # We add edges between consecutive vertices of the boundary (only # len(boundary)-1 are actually sufficient) - for u,v in zip(boundary[:-1],boundary[1:]): - if not graph.has_edge(u,v): - extra_edges.append((u,v)) + for u, v in zip(boundary[:-1], boundary[1:]): + if not graph.has_edge(u, v): + extra_edges.append((u, v)) graph.add_edges(extra_edges) @@ -6713,7 +6712,7 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP", if algorithm == "backtrack": from sage.graphs.generic_graph_pyx import find_hamiltonian as fh x = fh(self, find_path=True)[1] - return self.subgraph(vertices=x, edges=zip(x[:-1], x[1:])) + return self.subgraph(vertices=x, edges=list(zip(x[:-1], x[1:]))) ################## # LP Formulation # @@ -8259,7 +8258,7 @@ def _ford_fulkerson(self, s, t, use_edge_labels = False, integer = False, value_ # Reqrites a path as a list of edges : # ex : [0,1,2,3,4,5] becomes [(0,1), (1,2), (2,3), (3,4), (4,5)] - path_to_edges = lambda P : zip(P[:-1],P[1:]) + path_to_edges = lambda P : zip(P[:-1], P[1:]) # Rewrites a path as a list of edges labeled with their # available capacity @@ -16657,7 +16656,7 @@ def lex_BFS(self,reverse=False,tree=False, initial_vertex = None): ([0], Digraph on 1 vertex) """ - id_inv = dict([(i,v) for (v,i) in zip(self.vertices(),range(self.order()))]) + id_inv = {i: v for i, v in enumerate(self.vertices())} code = [[] for i in range(self.order())] m = self.am() @@ -20168,7 +20167,7 @@ def relabel(self, perm=None, inplace=True, return_map=False, check_input = True, # vertices() returns a sorted list: # this guarantees consistent relabeling - perm = dict({v:i for i,v in enumerate(self.vertices())}) + perm = {v: i for i, v in enumerate(self.vertices())} complete_partial_function = False check_input = False From bf54f54e895a416a21457e48067cb198ebae28cc Mon Sep 17 00:00:00 2001 From: Dmitrii Pasechnik Date: Wed, 15 Mar 2017 12:45:18 +0000 Subject: [PATCH 129/185] bumped up the version --- build/pkgs/curl/checksums.ini | 6 +++--- build/pkgs/curl/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/curl/checksums.ini b/build/pkgs/curl/checksums.ini index 02da2005459..cb4c4a39905 100644 --- a/build/pkgs/curl/checksums.ini +++ b/build/pkgs/curl/checksums.ini @@ -1,4 +1,4 @@ tarball=curl-VERSION.tar.bz2 -sha1=aa9f2300096d806c68c7ba8c50771853d1b43eb4 -md5=dd014df06ff1d12e173de86873f9f77a -cksum=2873185834 +sha1=ae4a14778ef9ac3aaeaa022243d6e26c0bf1362b +md5=fb1f03a142236840c1a77c035fa4c542 +cksum=2520895893 diff --git a/build/pkgs/curl/package-version.txt b/build/pkgs/curl/package-version.txt index adeee46ddd0..40f94c2dcfc 100644 --- a/build/pkgs/curl/package-version.txt +++ b/build/pkgs/curl/package-version.txt @@ -1 +1 @@ -7.52.1 +7.53.1 From 63aa1783c48552cc9c1285c63a3ba7470686f07d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 15 Mar 2017 14:31:47 +0100 Subject: [PATCH 130/185] trac 22602 reviewer's suggestions --- src/sage/combinat/posets/posets.py | 75 ++++++++++++++++++------------ 1 file changed, 44 insertions(+), 31 deletions(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index f845b5ec8c0..24484a53f04 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -4754,19 +4754,27 @@ def with_bounds(self, labels=('bottom', 'top')): def relabel(self, relabeling=None): r""" - Return a copy of this poset with its elements relabelled. + Return a copy of this poset with its elements relabeled. INPUT: - - ``relabeling`` -- a function or dictionary + - ``relabeling`` -- a function, dictionary, list or tuple - This function must map each (non-wrapped) element of - ``self`` to some distinct object. + The given function or dictionary must map each (non-wrapped) + element of ``self`` to some distinct object. The given list or tuple + must be made of distinct objects. + + When the input is a list or a tuple, the relabeling uses + the total ordering of the elements of the poset given by + ``list(self)``. If no relabeling is given, the poset is relabeled by integers - according to one of its linear extensions. + from `0` to `n` according to one of its linear extensions. This means + that `i Date: Wed, 15 Mar 2017 14:45:14 +0100 Subject: [PATCH 131/185] trac 22602 detail --- src/sage/combinat/posets/posets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 24484a53f04..e7ee274fafd 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -4769,7 +4769,7 @@ def relabel(self, relabeling=None): ``list(self)``. If no relabeling is given, the poset is relabeled by integers - from `0` to `n` according to one of its linear extensions. This means + from `0` to `n-1` according to one of its linear extensions. This means that `i Date: Wed, 15 Mar 2017 14:52:43 +0100 Subject: [PATCH 132/185] disable polymake in singular build --- build/pkgs/singular/spkg-install | 1 + 1 file changed, 1 insertion(+) diff --git a/build/pkgs/singular/spkg-install b/build/pkgs/singular/spkg-install index 373bd0852b2..8daa218849d 100755 --- a/build/pkgs/singular/spkg-install +++ b/build/pkgs/singular/spkg-install @@ -96,6 +96,7 @@ config() --enable-Singular \ --enable-factory \ --disable-doc \ + --disable-polymake \ $SINGULAR_CONFIGURE if [ $? -ne 0 ]; then From ef48f715189d6629f776b7a87334fc4da2e6219f Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Wed, 15 Mar 2017 16:04:35 +0100 Subject: [PATCH 133/185] Upgraded to pcre 8.40 --- build/pkgs/pcre/checksums.ini | 8 ++++---- build/pkgs/pcre/package-version.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/pkgs/pcre/checksums.ini b/build/pkgs/pcre/checksums.ini index f367739cd98..31e13a23cbc 100644 --- a/build/pkgs/pcre/checksums.ini +++ b/build/pkgs/pcre/checksums.ini @@ -1,4 +1,4 @@ -tarball=pcre-8.39.tar.gz -sha1=b3aec1f643d9701841e2f9d57ac121a7ff448fc8 -md5=26a76d97e04c89fe9ce22ecc1cd0b315 -cksum=157808039 +tarball=pcre-8.40.tar.gz +sha1=10384eb3d411794cc15f55b9d837d3f69e35391e +md5=890c808122bd90f398e6bc40ec862102 +cksum=451624496 diff --git a/build/pkgs/pcre/package-version.txt b/build/pkgs/pcre/package-version.txt index 803ed032518..34194f8d9af 100644 --- a/build/pkgs/pcre/package-version.txt +++ b/build/pkgs/pcre/package-version.txt @@ -1 +1 @@ -8.39 +8.40 From 1176203f95f7b30be2f332665f5d607b1ec87798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 15 Mar 2017 17:35:21 +0100 Subject: [PATCH 134/185] trac 22357 fixing regression + add utf8 encoding --- src/sage/coding/bch.py | 2 +- src/sage/tests/py3_syntax.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/coding/bch.py b/src/sage/coding/bch.py index 037adc622b1..c17b2d8ef89 100644 --- a/src/sage/coding/bch.py +++ b/src/sage/coding/bch.py @@ -481,7 +481,7 @@ def decode_to_code(self, y): c_bch = self.grs_word_to_bch(c) if c_bch in self.code(): l.append(c_bch) - except ValueError, e: + except ValueError: pass return l return self.grs_word_to_bch(cgrs) diff --git a/src/sage/tests/py3_syntax.py b/src/sage/tests/py3_syntax.py index b8ed8c23924..36a78b40a6a 100644 --- a/src/sage/tests/py3_syntax.py +++ b/src/sage/tests/py3_syntax.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- r""" Test that the Sage library uses Python 3 syntax From 7608202b228c7d6ff5388d19632f415a575f13b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 15 Mar 2017 17:59:34 +0100 Subject: [PATCH 135/185] trac 22373 adding a doctest --- src/sage/combinat/posets/posets.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 665d20f6e3d..fbd009ee901 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -254,9 +254,8 @@ # python3 from __future__ import division, print_function, absolute_import -import six from six.moves import range -from six import itervalues +from six import itervalues, iteritems import copy from sage.misc.cachefunc import cached_method @@ -3011,7 +3010,7 @@ def init_LP(k,cycles,inc_P): # We create the digraphs of all color classes linear_extensions = [hasse_diagram.copy() for i in range(k)] - for ((u,v),i),x in six.iteritems(p.get_values(b)): + for ((u,v),i),x in iteritems(p.get_values(b)): if x == 1: linear_extensions[i].add_edge(u,v) @@ -4933,7 +4932,7 @@ def canonical_label(self, algorithm=None): """ canonical_label = self._hasse_diagram.canonical_label(certificate=True, algorithm=algorithm)[1] - canonical_label = {self._elements[v]:i for v,i in six.iteritems(canonical_label)} + canonical_label = {self._elements[v]:i for v,i in iteritems(canonical_label)} return self.relabel(canonical_label) def with_linear_extension(self, linear_extension): @@ -6373,13 +6372,19 @@ def is_slender(self, certificate=False): sage: Poset().is_slender() # Test empty poset True + + Correct certificate (:trac:`22373`):: + + sage: P = Poset({0:[1,2,3],1:[4],2:[4],3:[4,5]}) + sage: P.is_slender(True) + (False, (0, 4)) """ for x in self: d = {} for y in self.upper_covers(x): for c in self.upper_covers(y): d[c] = d.get(c, 0) + 1 - for c, y in six.iteritems(d): + for c, y in iteritems(d): if y >= 3: if certificate: return (False, (x, c)) From 611559dc7440dcb93938983418e13604473099f1 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 15 Mar 2017 23:12:35 +0100 Subject: [PATCH 136/185] Use coercion model for comparisons in Weyl algebras --- src/sage/algebras/weyl_algebra.py | 34 +++++++++---------------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/src/sage/algebras/weyl_algebra.py b/src/sage/algebras/weyl_algebra.py index 4104760a13a..075b8e375c1 100644 --- a/src/sage/algebras/weyl_algebra.py +++ b/src/sage/algebras/weyl_algebra.py @@ -7,19 +7,21 @@ """ #***************************************************************************** -# Copyright (C) 2013 Travis Scrimshaw +# Copyright (C) 2013 Travis Scrimshaw # -# Distributed under the terms of the GNU General Public License (GPL) +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** from sage.misc.cachefunc import cached_method from sage.misc.latex import latex -from sage.structure.element import AlgebraElement, get_coercion_model +from sage.structure.sage_object import richcmp +from sage.structure.element import AlgebraElement from sage.structure.unique_representation import UniqueRepresentation -from sage.structure.element import have_same_parent from copy import copy -import operator from sage.categories.rings import Rings from sage.categories.algebras_with_basis import AlgebrasWithBasis from sage.sets.family import Family @@ -243,10 +245,9 @@ def half_term(mon, polynomial): return p + ' ' + d return repr_from_monomials(self.list(), term, True) - # Copied from CombinatorialFreeModuleElement - def __eq__(self, other): + def _richcmp_(self, other, op): """ - Check equality. + Rich comparison for equal parents. TESTS:: @@ -265,20 +266,6 @@ def __eq__(self, other): False sage: W(x^3 - y*z) == x^3 - y*z True - """ - if have_same_parent(self, other): - return self.__monomials == other.__monomials - try: - return get_coercion_model().bin_op(self, other, operator.eq) - except TypeError: - return False - - def __ne__(self, rhs): - """ - Check inequality. - - TESTS:: - sage: W. = DifferentialWeylAlgebra(QQ) sage: dx,dy,dz = W.differentials() sage: dx != dy @@ -286,7 +273,7 @@ def __ne__(self, rhs): sage: W.one() != 1 False """ - return not self == rhs + return richcmp(self.__monomials, other.__monomials, op) def __neg__(self): """ @@ -783,7 +770,6 @@ def basis(self): """ n = self._n from sage.combinat.integer_lists.nn import IntegerListsNN - from sage.categories.cartesian_product import cartesian_product elt_map = lambda u : (tuple(u[:n]), tuple(u[n:])) I = IntegerListsNN(length=2*n, element_constructor=elt_map) one = self.base_ring().one() From 3e800a3d98c6490addc8585cf3771a9847397ae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bissey?= Date: Thu, 16 Mar 2017 21:43:44 +1300 Subject: [PATCH 137/185] Make the cython example using singular more robust by using Singular.pc --- src/sage/misc/cython.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sage/misc/cython.py b/src/sage/misc/cython.py index 72e56634bfb..f0b61dd103b 100644 --- a/src/sage/misc/cython.py +++ b/src/sage/misc/cython.py @@ -307,9 +307,12 @@ def cython(filename, verbose=False, compile_message=False, Before :trac:`12975`, it would have been needed to write ``#clang c++``, but upper case ``C++`` has resulted in an error:: + sage: import pkgconfig + sage: singular_pc = pkgconfig.parse('Singular') sage: code = [ ....: "#clang C++", - ....: "#clib m readline Singular givaro ntl gmpxx gmp", + ....: "#clib " + " ".join(singular_pc['libraries']), + ....: "#cargs " + pkgconfig.cflags('Singular'), ....: "from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular", ....: "from sage.libs.singular.polynomial cimport singular_polynomial_pow", ....: "def test(MPolynomial_libsingular p):", From 3017fa97330850d81b666d9d312d68590894fc7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bissey?= Date: Thu, 16 Mar 2017 23:44:54 +1300 Subject: [PATCH 138/185] Adding comment about upcoming ticket #22461 --- src/sage/misc/cython.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sage/misc/cython.py b/src/sage/misc/cython.py index f0b61dd103b..c740c81d8d1 100644 --- a/src/sage/misc/cython.py +++ b/src/sage/misc/cython.py @@ -305,7 +305,10 @@ def cython(filename, verbose=False, compile_message=False, TESTS: Before :trac:`12975`, it would have been needed to write ``#clang c++``, - but upper case ``C++`` has resulted in an error:: + but upper case ``C++`` has resulted in an error. + Using pkgconfig to find the libraries, headers and macros. This is a + work around while waiting for :trac:`22461` which will offer a better + solution:: sage: import pkgconfig sage: singular_pc = pkgconfig.parse('Singular') From 4c7d5eb846d40287f9fb69ddff18d2e00ae9f6d9 Mon Sep 17 00:00:00 2001 From: Dmitrii Pasechnik Date: Thu, 16 Mar 2017 10:47:44 +0000 Subject: [PATCH 139/185] use clang with --with-darwinssl for newer OSX --- build/pkgs/curl/spkg-install | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build/pkgs/curl/spkg-install b/build/pkgs/curl/spkg-install index 2528aee8183..2b7912bc88a 100755 --- a/build/pkgs/curl/spkg-install +++ b/build/pkgs/curl/spkg-install @@ -14,6 +14,14 @@ if [ "$SAGE_FAT_BINARY" = yes ]; then CURL_CONFIGURE="--disable-ldap --disable-ldaps --disable-rtsp --disable-ares --disable-crypto-auth --without-libpsl --without-libmetalink --without-libssh2 --without-librtmp --without-libidn --without-nghttp2 --without-gssapi $CURL_CONFIGURE" fi +if [ "$UNAME" = "Darwin" ]; then + if [ $MACOSX_VERSION -ge 16 ]; then + echo "OS X 10.$[$MACOSX_VERSION-4] Building with clang and --with-darwinssl." + CC=clang + CURL_CONFIGURE="--with-darwinssl $CURL_CONFIGURE" + fi +fi + ./configure --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" \ $CURL_CONFIGURE if [ $? -ne 0 ]; then From f029f66bbf131eb7cdd4f8bfbe42d5c560baea1c Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Thu, 16 Mar 2017 12:04:49 +0000 Subject: [PATCH 140/185] This simple patch removes an overkill check in R's configure. --- .../r/patches/libcurl_https_support.patch | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 build/pkgs/r/patches/libcurl_https_support.patch diff --git a/build/pkgs/r/patches/libcurl_https_support.patch b/build/pkgs/r/patches/libcurl_https_support.patch new file mode 100644 index 00000000000..4cc18273979 --- /dev/null +++ b/build/pkgs/r/patches/libcurl_https_support.patch @@ -0,0 +1,99 @@ +diff -druN R-3.3.1/configure R-3.3.1.patched/configure +--- R-3.3.1/configure 2016-06-13 22:16:32.000000000 +0000 ++++ R-3.3.1.patched/configure 2016-10-27 13:53:26.347387983 +0000 +@@ -36227,47 +36227,6 @@ + have_libcurl=no + fi + +-if test "x${have_libcurl}" = "xyes"; then +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if libcurl supports https" >&5 +-$as_echo_n "checking if libcurl supports https... " >&6; } +-if ${r_cv_have_curl_https+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test "$cross_compiling" = yes; then : +- r_cv_have_curl_https=no +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#include +-#include +-int main() +-{ +- curl_version_info_data *data = curl_version_info(CURLVERSION_NOW); +- const char * const *p = data->protocols; +- int found = 0; +- for (; *p; p++) +- if(strcmp(*p, "https") == 0) {found = 1; break;} +- exit(found ? 0 : 1); +-} +- +-_ACEOF +-if ac_fn_c_try_run "$LINENO"; then : +- r_cv_have_curl_https=yes +-else +- r_cv_have_curl_https=no +-fi +-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext +-fi +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $r_cv_have_curl_https" >&5 +-$as_echo "$r_cv_have_curl_https" >&6; } +-fi +-if test "x${r_cv_have_curl_https}" = xno; then +- have_libcurl=no +-fi + if test "x${have_libcurl}" = xyes; then + + $as_echo "#define HAVE_LIBCURL 1" >>confdefs.h +@@ -36277,7 +36236,7 @@ + + + else +- as_fn_error $? "libcurl >= 7.28.0 library and headers are required with support for https" "$LINENO" 5 ++ as_fn_error $? "libcurl >= 7.28.0 library and headers are required" "$LINENO" 5 + fi + + +diff -druN R-3.3.1/m4/R.m4 R-3.3.1.patched/m4/R.m4 +--- R-3.3.1/m4/R.m4 2016-03-16 23:02:06.000000000 +0000 ++++ R-3.3.1.patched/m4/R.m4 2016-10-27 13:52:20.247269003 +0000 +@@ -4196,33 +4196,14 @@ + have_libcurl=no + fi + +-if test "x${have_libcurl}" = "xyes"; then +-AC_CACHE_CHECK([if libcurl supports https], [r_cv_have_curl_https], +-[AC_RUN_IFELSE([AC_LANG_SOURCE([[ +-#include +-#include +-int main() +-{ +- curl_version_info_data *data = curl_version_info(CURLVERSION_NOW); +- const char * const *p = data->protocols; +- int found = 0; +- for (; *p; p++) +- if(strcmp(*p, "https") == 0) {found = 1; break;} +- exit(found ? 0 : 1); +-} +-]])], [r_cv_have_curl_https=yes], [r_cv_have_curl_https=no], [r_cv_have_curl_https=no])]) +-fi +-if test "x${r_cv_have_curl_https}" = xno; then +- have_libcurl=no +-fi + if test "x${have_libcurl}" = xyes; then +- AC_DEFINE(HAVE_LIBCURL, 1, [Define if your system has libcurl >= 7.28.0 with support for https.]) ++ AC_DEFINE(HAVE_LIBCURL, 1, [Define if your system has libcurl >= 7.28.0.]) + CPPFLAGS="${r_save_CPPFLAGS}" + LIBS="${r_save_LIBS}" + AC_SUBST(CURL_CPPFLAGS) + AC_SUBST(CURL_LIBS) + else +- AC_MSG_ERROR([libcurl >= 7.28.0 library and headers are required with support for https]) ++ AC_MSG_ERROR([libcurl >= 7.28.0 library and headers are required]) + fi + ])# R_LIBCURL + From 4fb7bf48fc7beb87c3055acbe28dc96358edfe13 Mon Sep 17 00:00:00 2001 From: Ximin Luo Date: Sat, 25 Feb 2017 00:18:26 +0530 Subject: [PATCH 141/185] planarity patch --- src/sage/graphs/planarity.pyx | 53 ++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/src/sage/graphs/planarity.pyx b/src/sage/graphs/planarity.pyx index b4665595c71..7c6cd34a0a3 100644 --- a/src/sage/graphs/planarity.pyx +++ b/src/sage/graphs/planarity.pyx @@ -3,13 +3,19 @@ Wrapper for Boyer's (C) planarity algorithm. """ cdef extern from "planarity/graph.h": - ctypedef struct graphNode: - int v + ctypedef struct vertexRec: int link[2] - ctypedef graphNode * graphNodeP + int index + ctypedef vertexRec * vertexRecP + + ctypedef struct edgeRec: + int link[2] + int neighbor + ctypedef edgeRec * edgeRecP ctypedef struct BM_graph: - graphNodeP G + vertexRecP V + edgeRecP E int N ctypedef BM_graph * graphP @@ -93,15 +99,16 @@ def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False, circular= g._pos = { u: [0,0], v: [0,1] } return (True, None) if kuratowski else True - # create to and from mappings to relabel vertices to the set {0,...,n-1} + # create to and from mappings to relabel vertices to the set {1,...,n} + # (planarity 3 uses 1-based array indexing, with 0 representing NIL) cdef int i listto = g.vertices() ffrom = {} for vvv in listto: - ffrom[vvv] = listto.index(vvv) + ffrom[vvv] = listto.index(vvv) + 1 to = {} for i from 0 <= i < len(listto): - to[i] = listto[i] + to[i + 1] = listto[i] g.relabel(ffrom) cdef graphP theGraph @@ -125,7 +132,7 @@ def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False, circular= status = gp_Embed(theGraph, EMBEDFLAGS_PLANAR) gp_SortVertices(theGraph) - # use to and from mappings to relabel vertices back from the set {0,...,n-1} + # use to and from mappings to relabel vertices back from the set {1,...,n} g.relabel(to) if status == NOTOK: @@ -134,12 +141,12 @@ def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False, circular= # Kuratowski subgraph isolator g_dict = {} from sage.graphs.graph import Graph - for i from 0 <= i < theGraph.N: + for i from 0 < i <= theGraph.N: linked_list = [] - j = theGraph.G[i].link[1] - while j >= theGraph.N: - linked_list.append(to[theGraph.G[j].v]) - j = theGraph.G[j].link[1] + j = theGraph.V[i].link[1] + while j: + linked_list.append(to[theGraph.E[j].neighbor]) + j = theGraph.E[j].link[1] if len(linked_list) > 0: g_dict[to[i]] = linked_list G = Graph(g_dict) @@ -153,12 +160,12 @@ def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False, circular= if set_embedding: emb_dict = {} #for i in range(theGraph.N): - for i from 0 <= i < theGraph.N: + for i from 0 < i <= theGraph.N: linked_list = [] - j = theGraph.G[i].link[1] - while j >= theGraph.N: - linked_list.append(to[theGraph.G[j].v]) - j = theGraph.G[j].link[1] + j = theGraph.V[i].link[1] + while j: + linked_list.append(to[theGraph.E[j].neighbor]) + j = theGraph.E[j].link[1] emb_dict[to[i]] = linked_list g._embedding = emb_dict if set_pos: @@ -174,12 +181,12 @@ def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False, circular= emb_dict = {} #for i in range(theGraph.N): - for i from 0 <= i < theGraph.N: + for i from 0 < i <= theGraph.N: linked_list = [] - j = theGraph.G[i].link[0] - while j >= theGraph.N: - linked_list.append(to[theGraph.G[j].v]) - j = theGraph.G[j].link[0] + j = theGraph.V[i].link[0] + while j: + linked_list.append(to[theGraph.E[j].neighbor]) + j = theGraph.E[j].link[0] emb_dict[to[i]] = linked_list g._embedding = emb_dict gp_Free(&theGraph) From 3a60460e5aad031e1f6c312ecdf86cd85535afc2 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 4 Mar 2017 11:30:17 +0530 Subject: [PATCH 142/185] Update planarity to 3.0.0.5 --- build/pkgs/planarity/SPKG.txt | 16 +++++------ build/pkgs/planarity/checksums.ini | 8 +++--- build/pkgs/planarity/package-version.txt | 2 +- build/pkgs/planarity/patches/malloc.patch | 26 ------------------ .../planarity/patches/without_nauty.patch | 27 ------------------- 5 files changed, 12 insertions(+), 67 deletions(-) delete mode 100644 build/pkgs/planarity/patches/malloc.patch delete mode 100644 build/pkgs/planarity/patches/without_nauty.patch diff --git a/build/pkgs/planarity/SPKG.txt b/build/pkgs/planarity/SPKG.txt index e8991ac294f..6f5a75eafd5 100644 --- a/build/pkgs/planarity/SPKG.txt +++ b/build/pkgs/planarity/SPKG.txt @@ -27,12 +27,10 @@ None == Special Update/Build Instructions == -The tarball was created from upstream's SVN repository by checking out -the version tag 2.2.0, see -http://trac.sagemath.org/ticket/18187#comment:48 - -Two changes were made to the upstream code: -- the non-free Nauty code in c/nauty was removed. Note that this - requires adding a patch without_nauty.patch to remove planarity's - bindings to Nauty. -- an autotools-based build system was added. +The tarballs can be found at, +https://github.com/graph-algorithms/edge-addition-planarity-suite/releases +sage tarball is repackaged after running autogen.sh + +One change was made to the upstream code: +- extern.patch - declare variables declared in headers as extern. + https://github.com/graph-algorithms/edge-addition-planarity-suite/pull/3 diff --git a/build/pkgs/planarity/checksums.ini b/build/pkgs/planarity/checksums.ini index 2bc73e510f3..15dcbe50642 100644 --- a/build/pkgs/planarity/checksums.ini +++ b/build/pkgs/planarity/checksums.ini @@ -1,4 +1,4 @@ -tarball=planarity-VERSION.tar.bz2 -sha1=3ef0985a2b8476123969cef5c1273d11286605f2 -md5=3e05f05ad8bf777e6a7ad48958a18c06 -cksum=679137721 +tarball=planarity-VERSION.tar.gz +sha1=622da7eaf6d689aebeffccbfca55e164f774a8e4 +md5=71ee7822b967e9df1f0015b8d384cbf1 +cksum=3992798763 diff --git a/build/pkgs/planarity/package-version.txt b/build/pkgs/planarity/package-version.txt index ccbccc3dc62..4c1e4c7cb15 100644 --- a/build/pkgs/planarity/package-version.txt +++ b/build/pkgs/planarity/package-version.txt @@ -1 +1 @@ -2.2.0 +3.0.0.5 diff --git a/build/pkgs/planarity/patches/malloc.patch b/build/pkgs/planarity/patches/malloc.patch deleted file mode 100644 index 07020156047..00000000000 --- a/build/pkgs/planarity/patches/malloc.patch +++ /dev/null @@ -1,26 +0,0 @@ -Change to - -diff -ru src/c/graphColorVertices.c b/c/graphColorVertices.c ---- src/c/graphColorVertices.c 2015-05-05 14:20:57.000000000 +0200 -+++ b/c/graphColorVertices.c 2015-05-07 11:18:43.927221207 +0200 -@@ -50,7 +50,7 @@ - #include "graph.h" - - #include --#include -+#include - #include - - extern void _FillVisitedFlags(graphP theGraph, int FillValue); -diff -ru src/c/graphDrawPlanar.c b/c/graphDrawPlanar.c ---- src/c/graphDrawPlanar.c 2015-05-05 14:20:57.000000000 +0200 -+++ b/c/graphDrawPlanar.c 2015-05-07 11:18:30.608065652 +0200 -@@ -50,7 +50,7 @@ - #include "graph.h" - - #include --#include -+#include - #include - - extern void _FillVisitedFlags(graphP theGraph, int FillValue); diff --git a/build/pkgs/planarity/patches/without_nauty.patch b/build/pkgs/planarity/patches/without_nauty.patch deleted file mode 100644 index 3db8fe3f17d..00000000000 --- a/build/pkgs/planarity/patches/without_nauty.patch +++ /dev/null @@ -1,27 +0,0 @@ -Minimal patch to compile planarity without Nauty - ---- a/c/planarityCommandLine.c 2015-05-05 14:20:57.000000000 +0200 -+++ b/c/planarityCommandLine.c 2015-05-07 11:05:24.053668256 +0200 -@@ -157,6 +157,7 @@ - extern unsigned long numErrors; - extern unsigned long numOKs; - -+#ifdef HAVE_NAUTY - int callNauty(int argc, char *argv[]) - { - char command; -@@ -294,6 +295,14 @@ - return 0; - } - } -+#else -+unsigned long numGraphs, numErrors, numOKs; -+int callNauty(int argc, char *argv[]) -+{ -+ fprintf(stderr, "Nauty is not installed, aborting\n"); -+ exit(1); -+} -+#endif - - /**************************************************************************** - Quick regression test From bfcdfe5cddc243af2679ef1497f84edafcb2fb2d Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Thu, 16 Mar 2017 11:54:36 -0500 Subject: [PATCH 143/185] Some little bits of cleanup. --- .../combinat/ncsf_qsym/generic_basis_code.py | 18 +++++++++++++ src/sage/modules/with_basis/morphism.py | 26 +++++++++---------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/sage/combinat/ncsf_qsym/generic_basis_code.py b/src/sage/combinat/ncsf_qsym/generic_basis_code.py index 0ce70febe0c..64bd73c8780 100644 --- a/src/sage/combinat/ncsf_qsym/generic_basis_code.py +++ b/src/sage/combinat/ncsf_qsym/generic_basis_code.py @@ -1104,6 +1104,24 @@ def __eq__(self, other): and self._is_module_with_basis_over_same_base_ring == other._is_module_with_basis_over_same_base_ring) + def __ne__(self, other): + """ + Check equality. + + EXAMPLES:: + + sage: Psi = NonCommutativeSymmetricFunctions(QQ).Psi() + sage: Phi = NonCommutativeSymmetricFunctions(QQ).Phi() + sage: f = Psi.algebra_morphism(Phi.antipode_on_generators, codomain=Phi) + sage: g = Psi.algebra_morphism(Phi.antipode_on_generators, codomain=Phi) + sage: f != g + False + sage: h = Phi.algebra_morphism(Psi.antipode_on_generators, codomain=Psi) + sage: f != h + True + """ + return not (self == other) + def _on_basis(self, c): r""" Computes the image of this morphism on the basis element indexed by diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index fd9be8e2841..c28faabb5e6 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -337,14 +337,14 @@ def _richcmp_(self, other, op): """ if op == op_EQ: return (self.__class__ is other.__class__ - and parent(self) == parent(other) + and self.parent() == other.parent() and self._zero == other._zero and self._on_basis == other._on_basis and self._position == other._position and self._is_module_with_basis_over_same_base_ring == other._is_module_with_basis_over_same_base_ring) if op == op_NE: return not (self == other) - raise NotImplementedError("Operator not implemented") + return NotImplemented def on_basis(self): """ @@ -739,7 +739,7 @@ def _richcmp_(self, other, op): and self._dominant_item == other._dominant_item) if op == op_NE: return not (self == other) - raise NotImplementedError("Operator not implemented") + return NotImplemented def _test_triangular(self, **options): """ @@ -1215,14 +1215,13 @@ def _richcmp_(self, other, op): ....: X, on_basis=on_basis, codomain=X) sage: phi == phi True - """ if op == op_EQ: return (ModuleMorphismByLinearity._richcmp_(self, other, op) and TriangularModuleMorphism._richcmp_(self, other, op)) if op == op_NE: return not (self == other) - raise NotImplementedError("Operator not implemented") + return NotImplemented class TriangularModuleMorphismFromFunction(ModuleMorphismFromFunction, TriangularModuleMorphism): r""" @@ -1400,19 +1399,18 @@ def _richcmp_(self, other, op): sage: phi2 = ModuleMorphismFromMatrix(matrix=m2, domain=X, codomain=Y, side="right") sage: phi == phi2 False - """ if op == op_EQ: # We skip the on_basis check since the matrix defines the morphism return (self.__class__ is other.__class__ - and parent(self) == parent(other) + and self.parent() == other.parent() and self._zero == other._zero and self._position == other._position and self._is_module_with_basis_over_same_base_ring == other._is_module_with_basis_over_same_base_ring and self._matrix == other._matrix) if op == op_NE: return not (self == other) - raise NotImplementedError("Operator not implemented") + return NotImplemented class DiagonalModuleMorphism(ModuleMorphismByLinearity): r""" @@ -1496,11 +1494,11 @@ def _richcmp_(self, other, op): """ if op == op_EQ: return (self.__class__ is other.__class__ - and parent(self) == parent(other) + and self.parent() == other.parent() and self._diagonal == other._diagonal) if op == op_NE: return not (self == other) - raise NotImplementedError("Operator not implemented") + return NotImplemented def _on_basis(self, i): """ @@ -1612,9 +1610,9 @@ def __eq__(self, other): False sage: f == g True - """ - return self.__class__ is other.__class__ and self._pointwise_inverse == other._pointwise_inverse + return (self.__class__ is other.__class__ + and self._pointwise_inverse == other._pointwise_inverse) def __ne__(self, other): r""" @@ -1627,9 +1625,8 @@ def __ne__(self, other): sage: g = PointwiseInverseFunction(factorial) sage: f != g False - """ - return not self == other + return not (self == other) def __call__(self, *args): """ @@ -1652,3 +1649,4 @@ def pointwise_inverse(self): True """ return self._pointwise_inverse + From 25d54714ad22586f98741160d9c82b440a7f73d1 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 15 Mar 2017 22:31:28 +0100 Subject: [PATCH 144/185] Remove set_coercion_model; add coercion_model global --- src/sage/categories/pushout.py | 4 ++-- src/sage/functions/other.py | 10 +++++----- src/sage/homology/chains.py | 8 +++----- src/sage/matrix/matrix2.pyx | 7 +++---- src/sage/modular/abvar/finite_subgroup.py | 10 ++++------ src/sage/modular/modform/element.py | 4 +--- .../rings/polynomial/polynomial_element_generic.py | 3 +-- src/sage/rings/universal_cyclotomic_field.py | 3 +-- src/sage/schemes/generic/morphism.py | 4 +--- src/sage/schemes/toric/fano_variety.py | 6 +++--- src/sage/structure/all.py | 1 + src/sage/structure/element.pyx | 8 +++++--- 12 files changed, 30 insertions(+), 38 deletions(-) diff --git a/src/sage/categories/pushout.py b/src/sage/categories/pushout.py index cd8b9db2fc4..d9c8d49a388 100644 --- a/src/sage/categories/pushout.py +++ b/src/sage/categories/pushout.py @@ -711,8 +711,8 @@ def common_base(self, other_functor, self_bases, other_bases): self._raise_common_base_exception_( other_functor, self_bases, other_bases, 'Functors need the same number of arguments') - from sage.structure.element import get_coercion_model - Z_bases = tuple(get_coercion_model().common_parent(S, O) + from sage.structure.element import coercion_model + Z_bases = tuple(coercion_model.common_parent(S, O) for S, O in zip(self_bases, other_bases)) return self(Z_bases) diff --git a/src/sage/functions/other.py b/src/sage/functions/other.py index 87abbfc0466..a1704120fcb 100644 --- a/src/sage/functions/other.py +++ b/src/sage/functions/other.py @@ -9,13 +9,12 @@ from sage.libs.pynac.pynac import (register_symbol, symbol_table, py_factorial_py, I) from sage.symbolic.all import SR -from sage.rings.all import Integer, Rational, RealField, RR, ZZ, ComplexField +from sage.rings.all import Integer, Rational, RealField, ZZ, ComplexField from sage.rings.complex_number import is_ComplexNumber from sage.misc.latex import latex import math -import sage.structure.element -coercion_model = sage.structure.element.get_coercion_model() +from sage.structure.element import coercion_model # avoid name conflicts with `parent` as a function parameter from sage.structure.all import parent as s_parent @@ -25,6 +24,7 @@ from sage.functions.trig import arctan2 from sage.functions.exp_integral import Ei from sage.libs.mpmath import utils as mpmath_utils +from sage.arith.all import binomial as arith_binomial one_half = ~SR(2) @@ -756,7 +756,7 @@ def _eval_(self, x): return Integer(0) elif isinstance(x, (float, complex)): return x - Integer(int(math.floor(x))) - elif isinstance(x, sage.symbolic.expression.Expression): + elif isinstance(x, Expression): ret = floor(x) if not hasattr(ret, "operator") or not ret.operator() == floor: return x - ret @@ -1953,7 +1953,7 @@ def _evalf_(self, n, k, parent=None, algorithm=None): sage: binomial._evalf_(3/2,SR(1/1)) 3/2 """ - return sage.arith.all.binomial(n, k) + return arith_binomial(n, k) binomial = Function_binomial() diff --git a/src/sage/homology/chains.py b/src/sage/homology/chains.py index 4d8241df647..b1ab2a071ac 100644 --- a/src/sage/homology/chains.py +++ b/src/sage/homology/chains.py @@ -24,8 +24,7 @@ from sage.combinat.free_module import CombinatorialFreeModule, \ CombinatorialFreeModuleElement from sage.rings.integer_ring import ZZ -from sage.structure.element import get_coercion_model - +from sage.structure.element import coercion_model class CellComplexReference(object): @@ -605,8 +604,7 @@ def eval(self, other): for cell, coeff in self) R = self.base_ring() if R != other.base_ring(): - cm = get_coercion_model() - R = cm.common_parent(R, other.base_ring()) + R = coercion_model.common_parent(R, other.base_ring()) return R(result) def cup_product(self, cochain): @@ -652,7 +650,7 @@ def cup_product(self, cochain): right_deg = cochain.parent().degree() left_chains = self.parent().dual() right_chains = cochain.parent().dual() - base_ring = get_coercion_model().common_parent( + base_ring = coercion_model.common_parent( left_chains.base_ring(), right_chains.base_ring()) cx = self.parent().cell_complex() codomain = cx.n_chains( diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index bec11f4c750..e0a2b498154 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -47,8 +47,8 @@ include "cysignals/signals.pxi" from sage.misc.randstate cimport randstate, current_randstate from sage.structure.coerce cimport py_scalar_parent from sage.structure.sequence import Sequence -from sage.structure.element import (is_Vector, get_coercion_model) -from sage.structure.element cimport have_same_parent +from sage.structure.element import is_Vector +from sage.structure.element cimport have_same_parent, coercion_model from sage.misc.misc import verbose, get_verbose from sage.rings.ring import is_Ring from sage.rings.number_field.number_field_base import is_NumberField @@ -10663,8 +10663,7 @@ cdef class Matrix(matrix1.Matrix): mesg += "maybe the ring is not an integral domain" raise ValueError(mesg) if not have_same_parent(A, B): - cm = get_coercion_model() - A, B = cm.canonical_coercion(A, B) + A, B = coercion_model.canonical_coercion(A, B) # base rings are equal now, via above check similar = (A.rational_form() == B.rational_form()) diff --git a/src/sage/modular/abvar/finite_subgroup.py b/src/sage/modular/abvar/finite_subgroup.py index b144f153803..24dd87ecd6e 100644 --- a/src/sage/modular/abvar/finite_subgroup.py +++ b/src/sage/modular/abvar/finite_subgroup.py @@ -108,9 +108,7 @@ from sage.rings.all import QQ, ZZ, QQbar, Integer from sage.arith.all import gcd, lcm from sage.misc.all import prod -from sage.structure.element import get_coercion_model - - +from sage.structure.element import coercion_model class FiniteSubgroup(Module): @@ -302,7 +300,7 @@ def __add__(self, other): B = other.abelian_variety() if not A.in_same_ambient_variety(B): raise ValueError("self and other must be in the same ambient Jacobian") - K = get_coercion_model().common_parent(self.field_of_definition(), other.field_of_definition()) + K = coercion_model.common_parent(self.field_of_definition(), other.field_of_definition()) lattice = self.lattice() + other.lattice() if A != B: lattice += C.lattice() @@ -389,7 +387,7 @@ def intersection(self, other): amb = other B = other M = B.lattice().scale(Integer(1)/self.exponent()) - K = get_coercion_model().common_parent(self.field_of_definition(), other.base_field()) + K = coercion_model.common_parent(self.field_of_definition(), other.base_field()) else: amb = A if not isinstance(other, FiniteSubgroup): @@ -398,7 +396,7 @@ def intersection(self, other): if A.ambient_variety() != B.ambient_variety(): raise TypeError("finite subgroups must be in the same ambient product Jacobian") M = other.lattice() - K = get_coercion_model().common_parent(self.field_of_definition(), other.field_of_definition()) + K = coercion_model.common_parent(self.field_of_definition(), other.field_of_definition()) L = self.lattice() if A != B: diff --git a/src/sage/modular/modform/element.py b/src/sage/modular/modform/element.py index 0ce9a062938..8b51d0bf2c5 100644 --- a/src/sage/modular/modform/element.py +++ b/src/sage/modular/modform/element.py @@ -28,7 +28,7 @@ from sage.modular.dirichlet import DirichletGroup from sage.misc.superseded import deprecated_function_alias from sage.arith.all import lcm, divisors, moebius, sigma, factor -from sage.structure.element import get_coercion_model, ModuleElement +from sage.structure.element import coercion_model, ModuleElement def is_ModularFormElement(x): @@ -1460,7 +1460,6 @@ def twist(self, chi, level=None, check=True): """ from sage.modular.all import CuspForms - coercion_model = get_coercion_model() R = coercion_model.common_parent(self.base_ring(), chi.base_ring()) N = self.level() epsilon = self.character() @@ -1772,7 +1771,6 @@ def twist(self, chi, level=None): """ from sage.modular.all import CuspForms, ModularForms from sage.rings.all import PowerSeriesRing - coercion_model = get_coercion_model() R = coercion_model.common_parent(self.base_ring(), chi.base_ring()) N = self.level() Q = chi.modulus() diff --git a/src/sage/rings/polynomial/polynomial_element_generic.py b/src/sage/rings/polynomial/polynomial_element_generic.py index 8370a4ca2ac..d2aa6c3cb43 100644 --- a/src/sage/rings/polynomial/polynomial_element_generic.py +++ b/src/sage/rings/polynomial/polynomial_element_generic.py @@ -291,8 +291,7 @@ def integral(self, var=None): # calling the coercion model bin_op is much more accurate than using the # true division (which is bypassed by polynomials). But it does not work # in all cases!! - from sage.structure.element import get_coercion_model - cm = get_coercion_model() + from sage.structure.element import coercion_model as cm import operator try: Q = cm.bin_op(R.one(), ZZ.one(), operator.div).parent() diff --git a/src/sage/rings/universal_cyclotomic_field.py b/src/sage/rings/universal_cyclotomic_field.py index 5a811f1147c..a94f2c00603 100644 --- a/src/sage/rings/universal_cyclotomic_field.py +++ b/src/sage/rings/universal_cyclotomic_field.py @@ -346,8 +346,7 @@ def __eq__(self, other): False """ if parent(self) is not parent(other): - from sage.structure.element import get_coercion_model - cm = get_coercion_model() + from sage.structure.element import coercion_model as cm try: self, other = cm.canonical_coercion(self, other) except TypeError: diff --git a/src/sage/schemes/generic/morphism.py b/src/sage/schemes/generic/morphism.py index 21f29a2c91f..0ca8991c497 100644 --- a/src/sage/schemes/generic/morphism.py +++ b/src/sage/schemes/generic/morphism.py @@ -82,7 +82,7 @@ import operator from sage.structure.element import (AdditiveGroupElement, RingElement, - Element, generic_power, parent, get_coercion_model) + Element, generic_power, parent, coercion_model) from sage.structure.sequence import Sequence from sage.categories.homset import Homset, Hom, End from sage.categories.number_fields import NumberFields @@ -105,8 +105,6 @@ from sage.categories.morphism import Morphism from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme -coercion_model = get_coercion_model() - def is_SchemeMorphism(f): """ diff --git a/src/sage/schemes/toric/fano_variety.py b/src/sage/schemes/toric/fano_variety.py index f521b8d61a4..cc109bc3214 100644 --- a/src/sage/schemes/toric/fano_variety.py +++ b/src/sage/schemes/toric/fano_variety.py @@ -168,7 +168,7 @@ from sage.schemes.toric.variety import ( ToricVariety_field, normalize_names) -from sage.structure.all import get_coercion_model +from sage.structure.all import coercion_model from sage.categories.fields import Fields _Fields = Fields() @@ -1451,7 +1451,7 @@ def __init__(self, P_Delta, monomial_points=None, coefficient_names=None, else: nonstr.append(c) F = add_variables(P_Delta.base_ring(), sorted(variables)) - F = get_coercion_model().common_parent(F, *nonstr) + F = coercion_model.common_parent(F, *nonstr) coefficients = [F(_) for _ in coefficients] P_Delta = P_Delta.base_extend(F) if len(monomial_points) != len(coefficients): @@ -1581,7 +1581,7 @@ def __init__(self, P_Delta, nef_partition, else: nonstr.append(c) F = add_variables(P_Delta.base_ring(), sorted(variables)) - F = get_coercion_model().common_parent(F, *nonstr) + F = coercion_model.common_parent(F, *nonstr) coefficients[i] = [F(_) for _ in coefficients[i]] P_Delta = P_Delta.base_extend(F) if len(monomial_points[i]) != len(coefficients[i]): diff --git a/src/sage/structure/all.py b/src/sage/structure/all.py index 5be67ba9d08..297b7efe12d 100644 --- a/src/sage/structure/all.py +++ b/src/sage/structure/all.py @@ -10,6 +10,7 @@ from .element import ( canonical_coercion, + coercion_model, get_coercion_model, coercion_traceback, parent diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index b8119ed279c..9355df10e45 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -3911,6 +3911,9 @@ cdef class CoercionModel: from . import coerce cdef CoercionModel coercion_model = coerce.CoercionModel_cache_maps() +# Make this accessible as Python object +globals()["coercion_model"] = coercion_model + def get_coercion_model(): """ @@ -3922,12 +3925,11 @@ def get_coercion_model(): sage: cm = e.get_coercion_model() sage: cm + sage: cm is coercion_model + True """ return coercion_model -def set_coercion_model(cm): - global coercion_model - coercion_model = cm def coercion_traceback(dump=True): r""" From 67f3b42a18bb98b54da28b5b323d2f45af6c7374 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 16 Mar 2017 19:53:49 +0100 Subject: [PATCH 145/185] Add missing patches back --- build/pkgs/sphinx/patches/environment.patch | 18 ++++++++++++++++ build/pkgs/sphinx/patches/latex_memory.patch | 22 ++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 build/pkgs/sphinx/patches/environment.patch create mode 100644 build/pkgs/sphinx/patches/latex_memory.patch diff --git a/build/pkgs/sphinx/patches/environment.patch b/build/pkgs/sphinx/patches/environment.patch new file mode 100644 index 00000000000..d0b7a050e0e --- /dev/null +++ b/build/pkgs/sphinx/patches/environment.patch @@ -0,0 +1,18 @@ +Prevent Sphinx from rebuilding documentation that is already built + +--- a/sphinx/environment/__init__.py 2014-03-02 20:38:09.000000000 +1300 ++++ b/sphinx/environment/__init__.py 2014-10-19 23:31:15.000000000 +1300 +@@ -540,10 +540,13 @@ + else: + # check if a config value was changed that affects how + # doctrees are read ++ import inspect + for key, descr in iteritems(config.values): + if descr[1] != 'env': + continue + if self.config[key] != config[key]: ++ if inspect.isfunction(config[key]): ++ continue + msg = '[config changed] ' + config_changed = True + break diff --git a/build/pkgs/sphinx/patches/latex_memory.patch b/build/pkgs/sphinx/patches/latex_memory.patch new file mode 100644 index 00000000000..62c3facb8c3 --- /dev/null +++ b/build/pkgs/sphinx/patches/latex_memory.patch @@ -0,0 +1,22 @@ +Increase the memory sizes for LaTeX + +These increased stack sizes should be sufficient for LaTeX to handle the +huge index of the Sage PDF reference manual. + +diff -ru a/sphinx/texinputs/Makefile_t b/sphinx/texinputs/Makefile_t +--- a/sphinx/texinputs/Makefile_t 2017-02-20 03:06:00.000000000 +0100 ++++ b/sphinx/texinputs/Makefile_t 2017-03-16 20:04:52.393946075 +0100 +@@ -12,8 +12,10 @@ + # format: pdf or dvi + FMT = pdf + +-LATEX = latex +-PDFLATEX = {{ latex_engine }} ++LATEXENV = env pool_size=4000000 save_size=50000 extra_mem_top=2000000 ++ ++LATEX = $(LATEXENV) latex ++PDFLATEX = $(LATEXENV) {{ latex_engine }} + MAKEINDEX = makeindex + + {% if latex_engine == 'platex' %} +Only in b/sphinx/texinputs: Makefile_t.orig From c15ac75bbf2c983baf104d69114223995a30d4bf Mon Sep 17 00:00:00 2001 From: "Erik M. Bray" Date: Thu, 18 Aug 2016 12:40:20 +0200 Subject: [PATCH 146/185] Prevent fork() from crashing after calls into InlineFortran When a Python module is loaded from a DLL, it never gets unloaded during the lifetime of that Python process. This means that when the process is forked (on Cygwin), in the process of setting up the child process all DLLs that were loaded in the parent need to be loaded in the child. If the DLL itself was deleted it can't be loaded, and fork() fails. By far the easiest solution is to not immediately delete temporary DLLs. Instead they will be deleted when the process exits, by the atexit handler. This is fine, just as long the DLLs stick around for the rest of the process's lifetime. --- src/sage/misc/inline_fortran.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/sage/misc/inline_fortran.py b/src/sage/misc/inline_fortran.py index 2fff6177201..39c82baa6da 100644 --- a/src/sage/misc/inline_fortran.py +++ b/src/sage/misc/inline_fortran.py @@ -5,6 +5,7 @@ import os import imp import shutil +import sys from sage.misc.temporary_file import tmp_dir @@ -128,11 +129,16 @@ def eval(self, x, globals=None, locals=None): print(log_string) finally: os.chdir(old_cwd) - try: - shutil.rmtree(mytmpdir) - except OSError: - # This can fail for example over NFS - pass + + if sys.platform != 'cygwin': + # Do not delete temporary DLLs on Cygwin; this will cause + # future forks of this process to fail. Instead temporary DLLs + # will be cleaned up upon process exit + try: + shutil.rmtree(mytmpdir) + except OSError: + # This can fail for example over NFS + pass for k, x in iteritems(m.__dict__): if k[0] != '_': From 5b1b761250b8c384d0cbd53695b73ad5f15f2aa4 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Thu, 16 Mar 2017 16:36:19 -0500 Subject: [PATCH 147/185] Fixing some tidbits of ModuleMorphism. --- src/sage/modules/with_basis/morphism.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index c28faabb5e6..26ceb436524 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -108,7 +108,6 @@ from sage.categories.fields import Fields from sage.categories.modules import Modules from sage.misc.misc import attrcall -#from sage.misc.cachefunc import cached_method, cached_function # The identity function would deserve a more canonical location from sage.misc.c3_controlled import identity from sage.misc.superseded import deprecated_function_alias, deprecation @@ -337,7 +336,6 @@ def _richcmp_(self, other, op): """ if op == op_EQ: return (self.__class__ is other.__class__ - and self.parent() == other.parent() and self._zero == other._zero and self._on_basis == other._on_basis and self._position == other._position @@ -731,7 +729,7 @@ def _richcmp_(self, other, op): """ if op == op_EQ: - return (self.__class__ is other.__class__ and self.parent() == other.parent() + return (self.__class__ is other.__class__ and self._triangular == other._triangular and self._unitriangular == other._unitriangular and self._inverse_on_support == other._inverse_on_support @@ -1403,7 +1401,6 @@ def _richcmp_(self, other, op): if op == op_EQ: # We skip the on_basis check since the matrix defines the morphism return (self.__class__ is other.__class__ - and self.parent() == other.parent() and self._zero == other._zero and self._position == other._position and self._is_module_with_basis_over_same_base_ring == other._is_module_with_basis_over_same_base_ring @@ -1494,7 +1491,6 @@ def _richcmp_(self, other, op): """ if op == op_EQ: return (self.__class__ is other.__class__ - and self.parent() == other.parent() and self._diagonal == other._diagonal) if op == op_NE: return not (self == other) From d2ee262c9a58bc2a9f50aabc2b86299ecf741c63 Mon Sep 17 00:00:00 2001 From: "Erik M. Bray" Date: Thu, 16 Mar 2017 22:29:34 +0100 Subject: [PATCH 148/185] Upgrade psutil to 5.2.0 --- build/pkgs/psutil/package-version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/psutil/package-version.txt b/build/pkgs/psutil/package-version.txt index 4b708b2649e..91ff57278e3 100644 --- a/build/pkgs/psutil/package-version.txt +++ b/build/pkgs/psutil/package-version.txt @@ -1 +1 @@ -4.3.1.p0 +5.2.0 From 3da41f400d1f19054380b081a5c01ec3e858194c Mon Sep 17 00:00:00 2001 From: "Erik M. Bray" Date: Thu, 16 Mar 2017 21:54:55 +0000 Subject: [PATCH 149/185] Update the checksums --- build/pkgs/psutil/checksums.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/pkgs/psutil/checksums.ini b/build/pkgs/psutil/checksums.ini index e75916613f7..8154abe0921 100644 --- a/build/pkgs/psutil/checksums.ini +++ b/build/pkgs/psutil/checksums.ini @@ -1,4 +1,4 @@ tarball=psutil-VERSION.tar.gz -sha1=14fd78406eed9b0cd794cfad19f8d49eb76d1c44 -md5=199a366dba829c88bddaf5b41d19ddc0 -cksum=190866472 +sha1=94bfd957caf439c504858dfbfea4c43581698d9c +md5=c9aa2599dcd9e5b59d71b6660d396062 +cksum=1440797320 From 18e7a748198e1c3abc175b703a24d1010b8ee8cf Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Thu, 16 Mar 2017 17:08:16 -0500 Subject: [PATCH 150/185] Fixing doctests and doing it so the order doesn't change in the future. --- src/doc/en/thematic_tutorials/sandpile.rst | 32 ++++++++--------- src/sage/sandpiles/sandpile.py | 40 +++++++++++----------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/doc/en/thematic_tutorials/sandpile.rst b/src/doc/en/thematic_tutorials/sandpile.rst index 5d45ad778c6..ae3d4345743 100644 --- a/src/doc/en/thematic_tutorials/sandpile.rst +++ b/src/doc/en/thematic_tutorials/sandpile.rst @@ -3987,36 +3987,36 @@ EXAMPLES:: sage: s = sandpiles.Complete(4) sage: D = SandpileDivisor(s,[4,2,0,0]) - sage: D.effective_div() - [{0: 0, 1: 6, 2: 0, 3: 0}, + sage: sorted(D.effective_div(), key=str) + [{0: 0, 1: 2, 2: 0, 3: 4}, {0: 0, 1: 2, 2: 4, 3: 0}, - {0: 0, 1: 2, 2: 0, 3: 4}, + {0: 0, 1: 6, 2: 0, 3: 0}, {0: 1, 1: 3, 2: 1, 3: 1}, {0: 2, 1: 0, 2: 2, 3: 2}, {0: 4, 1: 2, 2: 0, 3: 0}] - sage: D.effective_div(False) - [[0, 6, 0, 0], + sage: sorted(D.effective_div(False)) + [[0, 2, 0, 4], [0, 2, 4, 0], - [0, 2, 0, 4], + [0, 6, 0, 0], [1, 3, 1, 1], [2, 0, 2, 2], [4, 2, 0, 0]] - sage: D.effective_div(with_firing_vectors=True) - [({0: 0, 1: 6, 2: 0, 3: 0}, (0, -2, -1, -1)), + sage: sorted(D.effective_div(with_firing_vectors=True), key=str) + [({0: 0, 1: 2, 2: 0, 3: 4}, (0, -1, -1, -2)), ({0: 0, 1: 2, 2: 4, 3: 0}, (0, -1, -2, -1)), - ({0: 0, 1: 2, 2: 0, 3: 4}, (0, -1, -1, -2)), + ({0: 0, 1: 6, 2: 0, 3: 0}, (0, -2, -1, -1)), ({0: 1, 1: 3, 2: 1, 3: 1}, (0, -1, -1, -1)), ({0: 2, 1: 0, 2: 2, 3: 2}, (0, 0, -1, -1)), ({0: 4, 1: 2, 2: 0, 3: 0}, (0, 0, 0, 0))] - sage: a = _[0] + sage: a = _[2] sage: a[0].values() [0, 6, 0, 0] sage: vector(D.values()) - s.laplacian()*a[1] (0, 6, 0, 0) - sage: D.effective_div(False, True) - [([0, 6, 0, 0], (0, -2, -1, -1)), + sage: sorted(D.effective_div(False, True)) + [([0, 2, 0, 4], (0, -1, -1, -2)), ([0, 2, 4, 0], (0, -1, -2, -1)), - ([0, 2, 0, 4], (0, -1, -1, -2)), + ([0, 6, 0, 0], (0, -2, -1, -1)), ([1, 3, 1, 1], (0, -1, -1, -1)), ([2, 0, 2, 2], (0, 0, -1, -1)), ([4, 2, 0, 0], (0, 0, 0, 0))] @@ -4377,13 +4377,13 @@ EXAMPLES:: sage: s = sandpiles.Complete(4) sage: D = SandpileDivisor(s,[4,2,0,0]) - sage: D.polytope_integer_pts() - ((-2, -1, -1), + sage: sorted(D.polytope_integer_pts()) + [(-2, -1, -1), (-1, -2, -1), (-1, -1, -2), (-1, -1, -1), (0, -1, -1), - (0, 0, 0)) + (0, 0, 0)] sage: D = SandpileDivisor(s,[-1,0,0,0]) sage: D.polytope_integer_pts() () diff --git a/src/sage/sandpiles/sandpile.py b/src/sage/sandpiles/sandpile.py index be6b9e9b1f7..ea1762268a2 100644 --- a/src/sage/sandpiles/sandpile.py +++ b/src/sage/sandpiles/sandpile.py @@ -280,14 +280,14 @@ {0: 4, 1: 0, 2: 0, 3: 1} sage: D.rank() 2 - sage: D.effective_div() + sage: sorted(D.effective_div(), key=str) [{0: 0, 1: 0, 2: 0, 3: 5}, - {0: 0, 1: 4, 2: 0, 3: 1}, {0: 0, 1: 0, 2: 4, 3: 1}, + {0: 0, 1: 4, 2: 0, 3: 1}, {0: 1, 1: 1, 2: 1, 3: 2}, {0: 4, 1: 0, 2: 0, 3: 1}] - sage: D.effective_div(False) - [[0, 0, 0, 5], [0, 4, 0, 1], [0, 0, 4, 1], [1, 1, 1, 2], [4, 0, 0, 1]] + sage: sorted(D.effective_div(False)) + [[0, 0, 0, 5], [0, 0, 4, 1], [0, 4, 0, 1], [1, 1, 1, 2], [4, 0, 0, 1]] sage: D.rank() 2 sage: D.rank(True) @@ -5345,13 +5345,13 @@ def polytope_integer_pts(self): sage: s = sandpiles.Complete(4) sage: D = SandpileDivisor(s,[4,2,0,0]) - sage: D.polytope_integer_pts() - ((-2, -1, -1), + sage: sorted(D.polytope_integer_pts()) + [(-2, -1, -1), (-1, -2, -1), (-1, -1, -2), (-1, -1, -1), (0, -1, -1), - (0, 0, 0)) + (0, 0, 0)] sage: D = SandpileDivisor(s,[-1,0,0,0]) sage: D.polytope_integer_pts() () @@ -5398,36 +5398,36 @@ def effective_div(self, verbose=True, with_firing_vectors=False): sage: s = sandpiles.Complete(4) sage: D = SandpileDivisor(s,[4,2,0,0]) - sage: D.effective_div() - [{0: 0, 1: 6, 2: 0, 3: 0}, + sage: sorted(D.effective_div(), key=str) + [{0: 0, 1: 2, 2: 0, 3: 4}, {0: 0, 1: 2, 2: 4, 3: 0}, - {0: 0, 1: 2, 2: 0, 3: 4}, + {0: 0, 1: 6, 2: 0, 3: 0}, {0: 1, 1: 3, 2: 1, 3: 1}, {0: 2, 1: 0, 2: 2, 3: 2}, {0: 4, 1: 2, 2: 0, 3: 0}] - sage: D.effective_div(False) - [[0, 6, 0, 0], + sage: sorted(D.effective_div(False)) + [[0, 2, 0, 4], [0, 2, 4, 0], - [0, 2, 0, 4], + [0, 6, 0, 0], [1, 3, 1, 1], [2, 0, 2, 2], [4, 2, 0, 0]] - sage: D.effective_div(with_firing_vectors=True) - [({0: 0, 1: 6, 2: 0, 3: 0}, (0, -2, -1, -1)), + sage: sorted(D.effective_div(with_firing_vectors=True), key=str) + [({0: 0, 1: 2, 2: 0, 3: 4}, (0, -1, -1, -2)), ({0: 0, 1: 2, 2: 4, 3: 0}, (0, -1, -2, -1)), - ({0: 0, 1: 2, 2: 0, 3: 4}, (0, -1, -1, -2)), + ({0: 0, 1: 6, 2: 0, 3: 0}, (0, -2, -1, -1)), ({0: 1, 1: 3, 2: 1, 3: 1}, (0, -1, -1, -1)), ({0: 2, 1: 0, 2: 2, 3: 2}, (0, 0, -1, -1)), ({0: 4, 1: 2, 2: 0, 3: 0}, (0, 0, 0, 0))] - sage: a = _[0] + sage: a = _[2] sage: a[0].values() [0, 6, 0, 0] sage: vector(D.values()) - s.laplacian()*a[1] (0, 6, 0, 0) - sage: D.effective_div(False, True) - [([0, 6, 0, 0], (0, -2, -1, -1)), + sage: sorted(D.effective_div(False, True)) + [([0, 2, 0, 4], (0, -1, -1, -2)), ([0, 2, 4, 0], (0, -1, -2, -1)), - ([0, 2, 0, 4], (0, -1, -1, -2)), + ([0, 6, 0, 0], (0, -2, -1, -1)), ([1, 3, 1, 1], (0, -1, -1, -1)), ([2, 0, 2, 2], (0, 0, -1, -1)), ([4, 2, 0, 0], (0, 0, 0, 0))] From 12534165611faba27546cdcfb135e7d6d0f70181 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 23 Feb 2017 21:19:38 +0100 Subject: [PATCH 151/185] Run sagenb_export as default notebook --- src/bin/sage-notebook | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/sage-notebook b/src/bin/sage-notebook index 74192da240b..06fb3aef280 100755 --- a/src/bin/sage-notebook +++ b/src/bin/sage-notebook @@ -162,7 +162,7 @@ EXAMPLES: notebook_launcher = { - 'default': NotebookSageNB, # change this to change the default + 'default': SageNBExport, # change this to change the default 'sagenb': NotebookSageNB, 'ipython': NotebookJupyter, 'jupyter': NotebookJupyter, From 4d838d042236b62c9e997ecbc04e4606e0500fd1 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 23 Feb 2017 21:16:49 +0100 Subject: [PATCH 152/185] Update to sagenb_export 3.1 --- build/pkgs/sagenb_export/checksums.ini | 6 +++--- build/pkgs/sagenb_export/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/sagenb_export/checksums.ini b/build/pkgs/sagenb_export/checksums.ini index 8d4e420af54..7ccedb06dc4 100644 --- a/build/pkgs/sagenb_export/checksums.ini +++ b/build/pkgs/sagenb_export/checksums.ini @@ -1,4 +1,4 @@ tarball=sagenb_export-VERSION.tar.gz -sha1=0ecc7eaf28f7603185d1784773375ada483d2820 -md5=cf277861925e3bb6e4fcb38f2de9a0ec -cksum=3933869953 +sha1=b5441150dc47e80a2436a8402e84defc9a79fee5 +md5=bdfd92e3187e3b0f4debea6dc0f1b3d4 +cksum=1703654922 diff --git a/build/pkgs/sagenb_export/package-version.txt b/build/pkgs/sagenb_export/package-version.txt index c9eae59d88c..8c50098d8ae 100644 --- a/build/pkgs/sagenb_export/package-version.txt +++ b/build/pkgs/sagenb_export/package-version.txt @@ -1 +1 @@ -2.0.p0 +3.1 From eda7dbdc749adfcbb80f8e4ee26868ec122814fc Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Fri, 17 Mar 2017 05:14:45 -0500 Subject: [PATCH 153/185] Using xrange in the new Cython file. --- .../combinat/root_system/reflection_group_element.pyx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/sage/combinat/root_system/reflection_group_element.pyx b/src/sage/combinat/root_system/reflection_group_element.pyx index 5dc9021b635..4434f3e106b 100644 --- a/src/sage/combinat/root_system/reflection_group_element.pyx +++ b/src/sage/combinat/root_system/reflection_group_element.pyx @@ -23,8 +23,6 @@ AUTHORS: #***************************************************************************** from __future__ import print_function -from six.moves import range - from sage.misc.cachefunc import cached_method#, cached_in_parent_method from sage.misc.lazy_attribute import lazy_attribute from sage.misc.misc_c import prod @@ -637,7 +635,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): m = lcm([x.conductor() if hasattr(x,"conductor") else 1 for x in M]) M_gals = [x.galois_conjugates(m) if hasattr(x,"galois_conjugates") else [x] for x in M] conjugates = [] - for i in range(len(M_gals[0])): + for i in xrange(len(M_gals[0])): conjugates.append(Matrix(rk, [X[i] for X in M_gals])) return conjugates @@ -909,10 +907,10 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): else: raise ValueError('side must be "left" or "right"') if on_space == "primal": - return sum(vec[j] * Phi[w(j+1) - 1] for j in range(n)) + return sum(vec[j] * Phi[w(j+1) - 1] for j in xrange(n)) elif on_space == "dual": w = ~w - return sum(Phi[w(j+1) - 1]*vec[j] for j in range(n)) + return sum(Phi[w(j+1) - 1]*vec[j] for j in xrange(n)) else: raise ValueError('on_space must be "primal" or "dual"') From 98fc2b0e39f04b160eb0663fe1ad5101daded40a Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Fri, 17 Mar 2017 07:06:05 -0500 Subject: [PATCH 154/185] Getting some more speedup by taking advantage of Cython. --- .../root_system/reflection_group_element.pxd | 4 +- .../root_system/reflection_group_element.pyx | 55 +++++++++++-------- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/sage/combinat/root_system/reflection_group_element.pxd b/src/sage/combinat/root_system/reflection_group_element.pxd index 7e6f4a8d4ed..c6d8f868332 100644 --- a/src/sage/combinat/root_system/reflection_group_element.pxd +++ b/src/sage/combinat/root_system/reflection_group_element.pxd @@ -1,8 +1,10 @@ from sage.groups.perm_gps.permgroup_element cimport PermutationGroupElement cdef class ComplexReflectionGroupElement(PermutationGroupElement): - pass + cpdef action_on_root_indices(self, i) cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): cpdef bint has_left_descent(self, i) cpdef bint has_descent(self, i, side=*, positive=*) + cpdef action(self, vec, side=*, on_space=*) + cpdef action_on_root_indices(self, i, side=*) diff --git a/src/sage/combinat/root_system/reflection_group_element.pyx b/src/sage/combinat/root_system/reflection_group_element.pyx index 4434f3e106b..7ec1711ce1b 100644 --- a/src/sage/combinat/root_system/reflection_group_element.pyx +++ b/src/sage/combinat/root_system/reflection_group_element.pyx @@ -242,7 +242,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): if W._reflection_representation is None: Phi = W.roots() inds = [W._index_set_inverse[i] for i in W.independent_roots().keys()] - M = Matrix([Phi[self(i+1)-1] for i in inds]) + M = Matrix([Phi[self.perm[i]] for i in inds]) mat = W.base_change_matrix() * M else: refl_repr = W._reflection_representation @@ -293,7 +293,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): W = self.parent() Phi = W.roots() inds = [W._index_set_inverse[i] for i in W.independent_roots().keys()] - M = Matrix([Phi[self(i+1)-1] for i in inds]) + M = Matrix([Phi[self.perm[i]] for i in inds]) mat = W.base_change_matrix() * M mat.set_immutable() return mat @@ -358,7 +358,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): if not self_on_left: return self.action(vec, side="right") - def action_on_root_indices(self, i): + cpdef action_on_root_indices(self, i): """ Return the right action on the set of roots. @@ -387,7 +387,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): sage: all(sorted([w.action_on_root_indices(i) for i in range(N)]) == list(range(N)) for w in W) # optional - gap3 True """ - return self(i + 1) - 1 + return self.perm[i] def action_on_root(self, root): r""" @@ -678,12 +678,12 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): r = self.reflection_length() R = W.reflections() I = W.reflection_index_set() - word = [] + cdef list word = [] while r > 0: for i in I: w = R[i]._mul_(self) if w.reflection_length() < r: - word += [i] + word.append(i) r -= 1 self = w break @@ -708,7 +708,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): [2, 1] 2 [1, 2, 1] 3 """ - return len(self._reduced_word) + return ZZ(len(self._reduced_word)) cpdef bint has_left_descent(self, i): r""" @@ -727,7 +727,8 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): False """ W = self.parent() - return self(W._index_set_inverse[i]+1) > W.number_of_reflections() + # we also check == because 0-based indexing + return self.perm[W._index_set_inverse[i]] >= W.number_of_reflections() cpdef bint has_descent(self, i, side="left", positive=False): r""" @@ -825,17 +826,18 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): True """ W = self.parent() + cdef RealReflectionGroupElement w if W._reflection_representation is None: if side == "left": - w = ~self + w = (~self) elif side == "right": - w = self + w = (self) else: raise ValueError('side must be "left" or "right"') Delta = W.independent_roots() Phi = W.roots() - M = Matrix([Phi[w(Phi.index(alpha)+1)-1] for alpha in Delta]) + M = Matrix([Phi[w.perm[Phi.index(alpha)]] for alpha in Delta]) mat = W.base_change_matrix() * M else: refl_repr = W._reflection_representation @@ -858,7 +860,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): matrix = to_matrix - def action(self, vec, side="right", on_space="primal"): + cpdef action(self, vec, side="right", on_space="primal"): r""" Return the image of ``vec`` under the action of ``self``. @@ -900,17 +902,23 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): W = self.parent() n = W.rank() Phi = W.roots() + cdef RealReflectionGroupElement w if side == "right": - w = self + w = self elif side == "left": - w = ~self + w = (~self) else: raise ValueError('side must be "left" or "right"') + ret = Phi[0].parent().zero() if on_space == "primal": - return sum(vec[j] * Phi[w(j+1) - 1] for j in xrange(n)) + for j in xrange(n): + ret += vec[j] * Phi[w.perm[j]] + return ret elif on_space == "dual": - w = ~w - return sum(Phi[w(j+1) - 1]*vec[j] for j in xrange(n)) + w = (~w) + for j in xrange(n): + ret += Phi[w.perm[j]] * vec[j] + return ret else: raise ValueError('on_space must be "primal" or "dual"') @@ -947,7 +955,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): else: return self.action(vec,side="right") - def action_on_root_indices(self, i, side="right"): + cpdef action_on_root_indices(self, i, side="right"): """ Return the action on the set of roots. @@ -978,7 +986,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): w = ~self else: raise ValueError('side must be "left" or "right"') - return w(i + 1) - 1 + return (w).perm[i] def action_on_root(self, root, side="right"): r""" @@ -1035,14 +1043,15 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): [1] [(1, 0)] [1, 2] [(1, 0), (1, 1)] [2, 1] [(0, 1), (1, 1)] - [1, 2, 1] [(0, 1), (1, 0), (1, 1)] + [1, 2, 1] [(1, 0), (0, 1), (1, 1)] sage: W.from_reduced_word([1,2]).inversion_set(side="left") # optional - gap3 [(0, 1), (1, 1)] """ - Phi_plus = set(self.parent().positive_roots()) - return [root for root in Phi_plus - if self.action_on_root(root,side=side) not in Phi_plus] + N = self.parent().number_of_reflections() + Phi = self.parent().roots() + return [Phi[i] for i in range(N) + if self.action_on_root_indices(i, side=side) >= N] def _gap_factorization(w, gens): r""" From d2b38fa0700a7a48dcde1286aa4f7b1e69b8b9ca Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Fri, 17 Mar 2017 07:23:41 -0500 Subject: [PATCH 155/185] Fixing action of ComplexReflectionGroupElement. --- .../root_system/reflection_group_element.pxd | 1 + .../root_system/reflection_group_element.pyx | 29 ++++++------------- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/sage/combinat/root_system/reflection_group_element.pxd b/src/sage/combinat/root_system/reflection_group_element.pxd index c6d8f868332..04e98fc3fb2 100644 --- a/src/sage/combinat/root_system/reflection_group_element.pxd +++ b/src/sage/combinat/root_system/reflection_group_element.pxd @@ -1,6 +1,7 @@ from sage.groups.perm_gps.permgroup_element cimport PermutationGroupElement cdef class ComplexReflectionGroupElement(PermutationGroupElement): + cpdef action(self, vec, on_space=*) cpdef action_on_root_indices(self, i) cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): diff --git a/src/sage/combinat/root_system/reflection_group_element.pyx b/src/sage/combinat/root_system/reflection_group_element.pyx index 7ec1711ce1b..f160e37b09a 100644 --- a/src/sage/combinat/root_system/reflection_group_element.pyx +++ b/src/sage/combinat/root_system/reflection_group_element.pyx @@ -298,7 +298,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): mat.set_immutable() return mat - def action(self, vec, on_space="primal"): + cpdef action(self, vec, on_space="primal"): r""" Return the image of ``vec`` under the action of ``self``. @@ -334,29 +334,18 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): - ``self_on_left`` -- whether the action of ``self`` is on the left or on the right - .. WARNING:: - - This coercion is currently only defined for - ``self_on_left`` being ``False``. - EXAMPLES:: - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: w = W.from_reduced_word([1,2]) # optional - gap3 - sage: for root in W.positive_roots(): # optional - gap3 - ....: print("%s -> %s"%(root, w*root)) # optional - gap3 - (1, 0) -> (0, 1) - (0, 1) -> (-1, -1) - (1, 1) -> (-1, 0) - - sage: for root in W.positive_roots(): # optional - gap3 - ....: print("%s -> %s"%(root, root*w)) # optional - gap3 - (1, 0) -> (-1, -1) - (0, 1) -> (1, 0) - (1, 1) -> (0, -1) + sage: W = ReflectionGroup((3,1,2)) # optional - gap3 + sage: w = W.from_reduced_word([1, 2, 1, 1, 2]) # optional - gap3 + sage: for alpha in W.independent_roots(): # optional - gap3 + ....: print("%s -> %s"%(alpha, w * alpha)) # optional - gap3 + (1, 0) -> (E(3), 0) + (-1, 1) -> (-E(3), E(3)^2) """ if not self_on_left: - return self.action(vec, side="right") + return (~self).action(vec) + return self.action(vec) cpdef action_on_root_indices(self, i): """ From 221cea55785980280cd1fe6d487d52139b221e8b Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Fri, 17 Mar 2017 07:26:57 -0500 Subject: [PATCH 156/185] Making length() return a Sage integer. --- .../combinat/root_system/reflection_group_element.pyx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/sage/combinat/root_system/reflection_group_element.pyx b/src/sage/combinat/root_system/reflection_group_element.pyx index f160e37b09a..1feaf9e326c 100644 --- a/src/sage/combinat/root_system/reflection_group_element.pyx +++ b/src/sage/combinat/root_system/reflection_group_element.pyx @@ -101,7 +101,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): EXAMPLES:: sage: W = ReflectionGroup(4) # optional - gap3 - sage: for w in W: # optional - gap3 + sage: for w in W: # optional - gap3 ....: print("{} {}".format(w.reduced_word(), w.length())) [] 0 [1] 1 @@ -128,7 +128,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): [1, 1, 2, 1, 1, 2] 6 [1, 1, 2, 2, 1, 1] 6 """ - return len(self.reduced_word()) + return ZZ(len(self.reduced_word())) #@cached_in_parent_method def to_matrix(self, on_space="primal"): @@ -240,10 +240,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): """ W = self.parent() if W._reflection_representation is None: - Phi = W.roots() - inds = [W._index_set_inverse[i] for i in W.independent_roots().keys()] - M = Matrix([Phi[self.perm[i]] for i in inds]) - mat = W.base_change_matrix() * M + mat = self.canonical_matrix() else: refl_repr = W._reflection_representation id_mat = identity_matrix(QQ, refl_repr[W.index_set()[0]].nrows()) From f20f00a5ce6168f34f51845c0698e4419506ea12 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Fri, 17 Mar 2017 18:19:58 +0100 Subject: [PATCH 157/185] Use TeX package iftex --- src/doc/common/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/common/conf.py b/src/doc/common/conf.py index 564407bd5f9..7ec52df4794 100644 --- a/src/doc/common/conf.py +++ b/src/doc/common/conf.py @@ -308,6 +308,7 @@ def set_intersphinx_mappings(app): \usepackage{amssymb} \usepackage{textcomp} \usepackage{mathrsfs} +\usepackage{iftex} % Only declare unicode characters when compiling with pdftex; E.g. japanese % tutorial does not use pdftex From fa42d8eb1966a7e1ade67bb40b42a80bb04059b1 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Fri, 17 Mar 2017 18:19:10 +0100 Subject: [PATCH 158/185] Replace _sage_doc_ by a __doc__ descriptor --- src/doc/en/reference/misc/index.rst | 1 + src/module_list.py | 9 + src/sage/docs/__init__.py | 0 src/sage/docs/instancedoc.pyx | 174 ++++++++++++++++++ .../groups/perm_gps/permgroup_element.pyx | 1 - src/sage/interfaces/axiom.py | 28 +-- src/sage/interfaces/expect.py | 6 +- src/sage/interfaces/fricas.py | 8 +- src/sage/interfaces/gap.py | 14 +- src/sage/interfaces/giac.py | 16 +- src/sage/interfaces/gp.py | 23 +-- src/sage/interfaces/interface.py | 19 +- src/sage/interfaces/kash.py | 4 + src/sage/interfaces/lie.py | 12 +- src/sage/interfaces/lisp.py | 14 +- src/sage/interfaces/macaulay2.py | 7 +- src/sage/interfaces/magma.py | 18 +- src/sage/interfaces/maple.py | 13 +- src/sage/interfaces/mathematica.py | 10 +- src/sage/interfaces/matlab.py | 4 +- src/sage/interfaces/maxima.py | 34 +--- src/sage/interfaces/maxima_abstract.py | 17 +- src/sage/interfaces/maxima_lib.py | 22 +-- src/sage/interfaces/mupad.py | 17 +- src/sage/interfaces/octave.py | 4 + src/sage/interfaces/qepcad.py | 8 +- src/sage/interfaces/r.py | 15 +- src/sage/interfaces/sage0.py | 3 + src/sage/interfaces/scilab.py | 2 + src/sage/interfaces/singular.py | 14 +- src/sage/libs/gap/element.pyx | 10 +- src/sage/libs/singular/function.pyx | 11 +- src/sage/misc/cachefunc.pyx | 14 +- src/sage/misc/lazy_import.pyx | 11 +- src/sage/misc/sagedoc.py | 8 +- src/sage/misc/sageinspect.py | 15 +- src/sage/parallel/decorate.py | 8 +- src/sage/sets/set_from_iterator.py | 16 +- src/sage/symbolic/maxima_wrapper.py | 3 + src/sage/symbolic/units.py | 9 +- 40 files changed, 445 insertions(+), 177 deletions(-) create mode 100644 src/sage/docs/__init__.py create mode 100644 src/sage/docs/instancedoc.pyx diff --git a/src/doc/en/reference/misc/index.rst b/src/doc/en/reference/misc/index.rst index 3644e83d852..12681fe26bd 100644 --- a/src/doc/en/reference/misc/index.rst +++ b/src/doc/en/reference/misc/index.rst @@ -277,6 +277,7 @@ Miscellaneous Inspection and Development Tools .. toctree:: :maxdepth: 1 + sage/docs/instancedoc sage/misc/sageinspect sage/misc/edit_module sage/misc/getusage diff --git a/src/module_list.py b/src/module_list.py index f5fcd79fe3a..ee5d19d34b3 100644 --- a/src/module_list.py +++ b/src/module_list.py @@ -257,6 +257,15 @@ def uname_specific(name, value, alternative): Extension('*', ['sage/data_structures/*.pyx']), + ################################ + ## + ## sage.docs + ## + ################################ + + Extension('*', ['sage/docs/*.pyx']), + + ################################ ## ## sage.ext diff --git a/src/sage/docs/__init__.py b/src/sage/docs/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/sage/docs/instancedoc.pyx b/src/sage/docs/instancedoc.pyx new file mode 100644 index 00000000000..f9d7e035563 --- /dev/null +++ b/src/sage/docs/instancedoc.pyx @@ -0,0 +1,174 @@ +r""" +Dynamic documentation for instances of classes + +The functionality in this module allows to define specific docstrings +of *instances* of a class, which are different from the class docstring. +A typical use case is given by cached methods: the documentation of a +cached method should not be the documentation of the class +:class:`CachedMethod`; it should be the documentation of the underlying +method. + +In order to use this, define a class docstring as usual. Also define a +method ``def _instancedoc_(self)`` which should return the docstring of +the instance ``self``. Finally, add the decorator ``@InstanceDoc`` to +the class. + +.. WARNING:: + + Since the ``__doc__`` attribute is never inherited, the decorator + ``@InstanceDoc`` must be added to all subclasses of the class + defining ``_instancedoc_``. Doing it on the base class is not + sufficient. + +EXAMPLES:: + + sage: from sage.docs.instancedoc import InstanceDoc + sage: @InstanceDoc + ....: class X(object): + ....: "Class docstring" + ....: def _instancedoc_(self): + ....: return "Instance docstring" + sage: X.__doc__ + 'Class docstring' + sage: X().__doc__ + 'Instance docstring' + +For a Cython ``cdef class``, a decorator cannot be used. Instead, call +:func:`InstanceDoc` as a function after defining the class:: + + sage: cython(''' + ....: from sage.docs.instancedoc import InstanceDoc + ....: cdef class Y: + ....: "Class docstring" + ....: def _instancedoc_(self): + ....: return "Instance docstring" + ....: InstanceDoc(Y) + ....: ''') + sage: Y.__doc__ + 'File:...\nClass docstring' + sage: Y().__doc__ + 'Instance docstring' + +TESTS: + +Check that inheritance works (after passing the subclass to +:func:`InstanceDoc`):: + + sage: @InstanceDoc + ....: class A(object): + ....: "Class A docstring" + ....: def _instancedoc_(self): + ....: return "Instance docstring" + sage: class B(A): + ....: "Class B docstring" + sage: B.__doc__ + 'Class B docstring' + sage: B().__doc__ # Ideally, this would return the instance docstring + 'Class B docstring' + sage: B = InstanceDoc(B) + sage: B.__doc__ + 'Class B docstring' + sage: B().__doc__ + 'Instance docstring' +""" + +#***************************************************************************** +# Copyright (C) 2017 Jeroen Demeyer +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +from cpython.object cimport PyObject, PyTypeObject + +cdef extern from *: + cdef int PyDict_SetItemString(PyObject*, const char*, object) except -1 + cdef void PyType_Modified(PyTypeObject*) + +cdef inline PyTypeObject* TypeObject(cls) except NULL: + if not isinstance(cls, type): + raise TypeError(f"expected type, got {cls!r}") + return cls + + +cdef class InstanceDocDescriptor: + """ + Descriptor for dynamic documentation, to be installed as the + ``__doc__`` attribute. + + INPUT: + + - ``classdoc`` -- (string) class documentation + + - ``instancedoc`` -- (method) documentation for an instance + + EXAMPLES:: + + sage: from sage.docs.instancedoc import InstanceDocDescriptor + sage: def instancedoc(self): + ....: return "Instance doc" + sage: docattr = InstanceDocDescriptor("Class doc", instancedoc) + sage: class Z(object): + ....: __doc__ = InstanceDocDescriptor("Class doc", instancedoc) + sage: Z.__doc__ + 'Class doc' + sage: Z().__doc__ + 'Instance doc' + """ + cdef classdoc + cdef instancedoc + + def __init__(self, classdoc, instancedoc): + self.classdoc = classdoc + self.instancedoc = instancedoc + + def __get__(self, obj, typ): + if obj is None: + return self.classdoc + else: + return self.instancedoc(obj) + + +def InstanceDoc(cls): + """ + Add support for ``_instancedoc_`` to the class ``cls``. + + Typically, this will be used as decorator. + + INPUT: + + - ``cls`` -- a new-style class + + OUTPUT: ``cls`` + + .. WARNING:: + + ``InstanceDoc`` mutates the given class. So you are *not* supposed + to use it as ``newcls = InstanceDoc(cls)`` because that would + mutate ``cls`` (and ``newcls`` would be the same object as ``cls``) + + TESTS: + + This does not work on old-style classes or things which are not a + class at all:: + + sage: from sage.docs.instancedoc import InstanceDoc + sage: InstanceDoc(7) + Traceback (most recent call last): + ... + TypeError: expected type, got 7 + sage: class OldStyle: pass + sage: InstanceDoc(OldStyle) + Traceback (most recent call last): + ... + TypeError: expected type, got + """ + cdef PyTypeObject* tp = TypeObject(cls) + docattr = InstanceDocDescriptor(cls.__doc__, cls._instancedoc_) + PyDict_SetItemString(tp.tp_dict, "__doc__", docattr) + tp.tp_doc = NULL + PyType_Modified(tp) + return cls diff --git a/src/sage/groups/perm_gps/permgroup_element.pyx b/src/sage/groups/perm_gps/permgroup_element.pyx index 37a84b2707a..b5aa9e20f80 100644 --- a/src/sage/groups/perm_gps/permgroup_element.pyx +++ b/src/sage/groups/perm_gps/permgroup_element.pyx @@ -68,7 +68,6 @@ from sage.matrix.matrix import is_Matrix from sage.matrix.all import MatrixSpace from sage.interfaces.all import gap from sage.interfaces.gap import is_GapElement -from sage.interfaces.expect import is_ExpectElement from sage.sets.finite_enumerated_set import FiniteEnumeratedSet import sage.structure.coerce as coerce from sage.structure.sage_object cimport richcmp_not_equal, rich_to_bool diff --git a/src/sage/interfaces/axiom.py b/src/sage/interfaces/axiom.py index fda7d6cba66..f5403d5a998 100644 --- a/src/sage/interfaces/axiom.py +++ b/src/sage/interfaces/axiom.py @@ -187,6 +187,7 @@ from pexpect import EOF from sage.misc.multireplace import multiple_replace from sage.interfaces.tab_completion import ExtraTabCompletion +from sage.docs.instancedoc import InstanceDoc # The Axiom commands ")what thing det" ")show Matrix" and ")display # op det" commands, gives a list of all identifiers that begin in @@ -505,9 +506,9 @@ def _function_class(self): EXAMPLES:: sage: axiom._function_class() - + sage: type(axiom.gcd) - + """ return AxiomExpectFunction @@ -516,9 +517,9 @@ def _object_class(self): EXAMPLES:: sage: axiom._object_class() - + sage: type(axiom(2)) #optional - axiom - + """ return AxiomElement @@ -529,9 +530,9 @@ def _function_element_class(self): EXAMPLES:: sage: axiom._function_element_class() - + sage: type(axiom(2).gcd) #optional - axiom - + """ return AxiomFunctionElement @@ -553,6 +554,8 @@ def console(self): """ axiom_console() + +@InstanceDoc class PanAxiomElement(ExpectElement): def __call__(self, x): """ @@ -900,10 +903,10 @@ def _sage_domain(self): raise NotImplementedError +AxiomElement = PanAxiomElement -class AxiomElement(PanAxiomElement): - pass +@InstanceDoc class PanAxiomFunctionElement(FunctionElement): def __init__(self, object, name): """ @@ -923,9 +926,10 @@ def __init__(self, object, name): name = name[:-2] + "!" FunctionElement.__init__(self, object, name) -class AxiomFunctionElement(PanAxiomFunctionElement): - pass +AxiomFunctionElement = PanAxiomFunctionElement + +@InstanceDoc class PanAxiomExpectFunction(ExpectFunction): def __init__(self, parent, name): """ @@ -942,8 +946,8 @@ def __init__(self, parent, name): name = name[:-2] + "!" ExpectFunction.__init__(self, parent, name) -class AxiomExpectFunction(PanAxiomExpectFunction): - pass +AxiomExpectFunction = PanAxiomExpectFunction + def is_AxiomElement(x): """ diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index 6a44b292fdd..2fb71b000e6 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -63,6 +63,7 @@ from sage.misc.misc import SAGE_TMP_INTERFACE from sage.env import SAGE_EXTCODE, LOCAL_IDENTIFIER from sage.misc.object_multiplexer import Multiplex +from sage.docs.instancedoc import InstanceDoc from six import reraise as raise_ @@ -1344,13 +1345,14 @@ def _function_element_class(self): return FunctionElement +@InstanceDoc class ExpectFunction(InterfaceFunction): """ Expect function. """ pass - +@InstanceDoc class FunctionElement(InterfaceFunctionElement): """ Expect function element. @@ -1361,6 +1363,8 @@ class FunctionElement(InterfaceFunctionElement): def is_ExpectElement(x): return isinstance(x, ExpectElement) + +@InstanceDoc class ExpectElement(InterfaceElement): """ Expect element. diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index 4d5b266ac16..e536b004de5 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -191,6 +191,7 @@ from sage.interfaces.expect import Expect, ExpectElement, FunctionElement, ExpectFunction from sage.misc.misc import SAGE_TMP_INTERFACE from sage.env import DOT_SAGE +from sage.docs.instancedoc import InstanceDoc import re import six @@ -813,6 +814,8 @@ def console(self): """ fricas_console() + +@InstanceDoc class FriCASElement(ExpectElement): """ Instances of this class represent objects in FriCAS. @@ -1319,6 +1322,8 @@ def _sage_(self): raise NotImplementedError("The translation of the FriCAS object %s to sage is not yet implemented." %(unparsed_InputForm)) + +@InstanceDoc class FriCASFunctionElement(FunctionElement): def __init__(self, object, name): """ @@ -1341,8 +1346,8 @@ def __init__(self, object, name): name = name[:-2] + "!" FunctionElement.__init__(self, object, name) - pass +@InstanceDoc class FriCASExpectFunction(ExpectFunction): def __init__(self, parent, name): """ @@ -1363,7 +1368,6 @@ def __init__(self, parent, name): name = name[:-2] + "!" ExpectFunction.__init__(self, parent, name) - pass def is_FriCASElement(x): """ diff --git a/src/sage/interfaces/gap.py b/src/sage/interfaces/gap.py index 42bc72d566d..ec9bb9fce8c 100644 --- a/src/sage/interfaces/gap.py +++ b/src/sage/interfaces/gap.py @@ -183,6 +183,7 @@ from sage.misc.misc import is_in_string from sage.misc.superseded import deprecation from sage.misc.cachefunc import cached_method +from sage.docs.instancedoc import InstanceDoc from sage.interfaces.tab_completion import ExtraTabCompletion import re import os @@ -962,6 +963,7 @@ def get_record_element(self, record, name): return self('%s.%s' % (record.name(), name)) +@InstanceDoc class GapElement_generic(ExtraTabCompletion, ExpectElement): r""" Generic interface to the GAP3/GAP4 interpreters. @@ -1544,6 +1546,7 @@ def gap_reset_workspace(max_workspace_size=None, verbose=False): g.quit() +@InstanceDoc class GapElement(GapElement_generic): def __getitem__(self, n): """ @@ -1615,13 +1618,13 @@ def _tab_completion(self): return v - +@InstanceDoc class GapFunctionElement(FunctionElement): - def _sage_doc_(self): + def _instancedoc_(self): """ EXAMPLES:: - sage: print(gap(4).SymmetricGroup._sage_doc_()) + sage: print(gap(4).SymmetricGroup.__doc__) 50 Group Libraries @@ -1634,12 +1637,13 @@ def _sage_doc_(self): return help +@InstanceDoc class GapFunction(ExpectFunction): - def _sage_doc_(self): + def _instancedoc(self): """ EXAMPLES:: - sage: print(gap.SymmetricGroup._sage_doc_()) + sage: print(gap.SymmetricGroup.__doc__) 50 Group Libraries diff --git a/src/sage/interfaces/giac.py b/src/sage/interfaces/giac.py index 33129869219..7c1ba2c6272 100644 --- a/src/sage/interfaces/giac.py +++ b/src/sage/interfaces/giac.py @@ -193,6 +193,8 @@ from sage.env import DOT_SAGE from sage.misc.pager import pager +from sage.docs.instancedoc import InstanceDoc + COMMANDS_CACHE = '%s/giac_commandlist_cache.sobj'%DOT_SAGE @@ -750,22 +752,26 @@ def version(self): """ return giac('version()') + +@InstanceDoc class GiacFunction(ExpectFunction): - def _sage_doc_(self): + def _instancedoc_(self): """ Returns the Giac help for this function. This gets called when doing "?" on self. EXAMPLES:: - sage: giac.gcd._sage_doc_() # not tested ; output may vary LANG + sage: giac.gcd.__doc__ # random "gcd - greatest common divisor of polynomials... """ M = self._parent return M._help(self._name) + +@InstanceDoc class GiacFunctionElement(FunctionElement): - def _sage_doc_(self): + def _instancedoc_(self): """ Returns the Giac help for this function. This gets called when doing "?" on self. @@ -773,11 +779,13 @@ def _sage_doc_(self): EXAMPLES:: sage: two = giac(2) - sage: two.gcd._sage_doc_() # not tested; output may vary LANG + sage: two.gcd.__doc__ # random "...gcd - greatest common divisor of polynomials... """ return self._obj.parent()._help(self._name) + +@InstanceDoc class GiacElement(ExpectElement): def __float__(self): """ diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index 6c30182a840..63fb923d987 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -146,7 +146,8 @@ from sage.interfaces.tab_completion import ExtraTabCompletion from sage.libs.pari.all import pari import sage.rings.complex_field -## import sage.rings.all +from sage.docs.instancedoc import InstanceDoc + class Gp(ExtraTabCompletion, Expect): """ @@ -287,9 +288,9 @@ def _function_class(self): EXAMPLES:: sage: gp._function_class() - + sage: type(gp.gcd) - + """ return GpFunction @@ -709,12 +710,9 @@ def _function_element_class(self): EXAMPLES:: sage: gp._function_element_class() - - - :: - + sage: type(gp(2).gcd) - + """ return GpFunctionElement @@ -837,6 +835,7 @@ def new_with_bits_prec(self, s, precision = 0): return x +@InstanceDoc class GpElement(ExpectElement): """ EXAMPLES: This example illustrates dumping and loading GP elements @@ -1049,12 +1048,8 @@ def _tab_completion(self): return self.parent()._tab_completion() -class GpFunctionElement(FunctionElement): - pass - -class GpFunction(ExpectFunction): - pass - +GpFunctionElement = FunctionElement +GpFunction = ExpectFunction def is_GpElement(x): diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index e4cfe518239..53727253d18 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -48,6 +48,7 @@ from sage.structure.element import Element, parent import sage.misc.sage_eval +from sage.docs.instancedoc import InstanceDoc class AsciiArtString(str): @@ -594,6 +595,7 @@ def help(self, s): return AsciiArtString('No help on %s available'%s) +@InstanceDoc class InterfaceFunction(SageObject): """ Interface function. @@ -608,17 +610,18 @@ def __repr__(self): def __call__(self, *args, **kwds): return self._parent.function_call(self._name, list(args), kwds) - def _sage_doc_(self): + def _instancedoc_(self): """ EXAMPLES:: - sage: gp.gcd._sage_doc_() + sage: gp.gcd.__doc__ 'gcd(x,{y}): greatest common divisor of x and y.' """ M = self._parent return M.help(self._name) +@InstanceDoc class InterfaceFunctionElement(SageObject): """ Interface function element. @@ -634,13 +637,13 @@ def __call__(self, *args, **kwds): return self._obj.parent().function_call(self._name, [self._obj] + list(args), kwds) def help(self): - print(self._sage_doc_()) + print(self.__doc__) - def _sage_doc_(self): + def _instancedoc_(self): """ EXAMPLES:: - sage: gp(2).gcd._sage_doc_() + sage: gp(2).gcd.__doc__ 'gcd(x,{y}): greatest common divisor of x and y.' """ M = self._obj.parent() @@ -652,6 +655,7 @@ def is_InterfaceElement(x): return isinstance(x, InterfaceElement) +@InstanceDoc class InterfaceElement(Element): """ Interface element. @@ -814,12 +818,11 @@ def __contains__(self, x): x = P.new(x) return P._contains(x.name(), self.name()) - - def _sage_doc_(self): + def _instancedoc_(self): """ EXAMPLES:: - sage: gp(2)._sage_doc_() + sage: gp(2).__doc__ '2' """ return str(self) diff --git a/src/sage/interfaces/kash.py b/src/sage/interfaces/kash.py index 80efd6a6516..850e53982e6 100644 --- a/src/sage/interfaces/kash.py +++ b/src/sage/interfaces/kash.py @@ -433,8 +433,10 @@ from __future__ import absolute_import from .expect import Expect, ExpectElement +from sage.docs.instancedoc import InstanceDoc import os + class Kash(Expect): r""" Interface to the Kash interpreter. @@ -665,6 +667,8 @@ def console(self): def version(self): return kash_version() + +@InstanceDoc class KashElement(ExpectElement): def __mod__(self, other): self._check_valid() diff --git a/src/sage/interfaces/lie.py b/src/sage/interfaces/lie.py index 71200714971..e65634d024b 100644 --- a/src/sage/interfaces/lie.py +++ b/src/sage/interfaces/lie.py @@ -292,6 +292,7 @@ from sage.misc.all import prod from sage.env import DOT_SAGE, SAGE_LOCAL from sage.interfaces.tab_completion import ExtraTabCompletion +from sage.docs.instancedoc import InstanceDoc import os @@ -747,6 +748,7 @@ def _function_element_class(self): return LiEFunctionElement +@InstanceDoc class LiEElement(ExtraTabCompletion, ExpectElement): def _tab_completion(self): """ @@ -866,27 +868,29 @@ def _sage_(self): return ExpectElement._sage_(self) +@InstanceDoc class LiEFunctionElement(FunctionElement): - def _sage_doc_(self): + def _instancedoc_(self): """ EXAMPLES:: sage: a4 = lie('A4') # optional - lie - sage: a4.diagram._sage_doc_() # optional - lie + sage: a4.diagram.__doc__ # optional - lie 'diagram(g)...' """ M = self._obj.parent() return M.help(self._name) +@InstanceDoc class LiEFunction(ExpectFunction): - def _sage_doc_(self): + def _instancedoc_(self): """ Returns the help for self. EXAMPLES:: - sage: lie.diagram._sage_doc_() # optional - lie + sage: lie.diagram.__doc__ # optional - lie 'diagram(g)...' """ M = self._parent diff --git a/src/sage/interfaces/lisp.py b/src/sage/interfaces/lisp.py index e6ef1e5738b..058114e3c7b 100644 --- a/src/sage/interfaces/lisp.py +++ b/src/sage/interfaces/lisp.py @@ -56,6 +56,8 @@ from .expect import Expect, ExpectElement, ExpectFunction, FunctionElement, gc_disabled from sage.structure.element import RingElement, parent +from sage.docs.instancedoc import InstanceDoc + class Lisp(Expect): def __init__(self, @@ -383,6 +385,7 @@ def function_call(self, function, args=None, kwds=None): # Inherit from RingElement to make __pow__ work +@InstanceDoc class LispElement(RingElement, ExpectElement): def __cmp__(self, other): """ @@ -481,13 +484,15 @@ def __pow__(self, n): """ return RingElement.__pow__(self, n) + +@InstanceDoc class LispFunctionElement(FunctionElement): - def _sage_doc_(self): + def _instancedoc_(self): """ EXAMPLES:: sage: two = lisp(2) - sage: two.sin._sage_doc_() + sage: two.sin.__doc__ Traceback (most recent call last): ... NotImplementedError @@ -496,12 +501,13 @@ def _sage_doc_(self): return M.help(self._name) +@InstanceDoc class LispFunction(ExpectFunction): - def _sage_doc_(self): + def _instancedoc_(self): """ EXAMPLES:: - sage: lisp.sin._sage_doc_() + sage: lisp.sin.__doc__ Traceback (most recent call last): ... NotImplementedError diff --git a/src/sage/interfaces/macaulay2.py b/src/sage/interfaces/macaulay2.py index 9eca0e66436..aaa50d5d0f1 100644 --- a/src/sage/interfaces/macaulay2.py +++ b/src/sage/interfaces/macaulay2.py @@ -104,6 +104,7 @@ from sage.misc.multireplace import multiple_replace from sage.interfaces.tab_completion import ExtraTabCompletion +from sage.docs.instancedoc import InstanceDoc import re @@ -603,6 +604,7 @@ def new_from(self, type, value): return self.new("new %s from %s"%(type.name(), value.name())) +@InstanceDoc class Macaulay2Element(ExtraTabCompletion, ExpectElement): def _latex_(self): """ @@ -1165,12 +1167,13 @@ def to_sage(self): raise NotImplementedError("cannot convert %s to a Sage object"%repr_str) +@InstanceDoc class Macaulay2Function(ExpectFunction): - def _sage_doc_(self): + def _instancedoc_(self): """ EXAMPLES:: - sage: print(macaulay2.load._sage_doc_()) # optional - macaulay2 + sage: print(macaulay2.load.__doc__) # optional - macaulay2 load -- read Macaulay2 commands ******************************* ... diff --git a/src/sage/interfaces/magma.py b/src/sage/interfaces/magma.py index de49c9926ea..ea4afae07fc 100644 --- a/src/sage/interfaces/magma.py +++ b/src/sage/interfaces/magma.py @@ -228,6 +228,7 @@ import sage.misc.misc import sage.misc.sage_eval from sage.interfaces.tab_completion import ExtraTabCompletion +from sage.docs.instancedoc import InstanceDoc INTRINSIC_CACHE = '%s/magma_intrinsic_cache.sobj' % DOT_SAGE EXTCODE_DIR = None @@ -1648,6 +1649,7 @@ def GetVerbose(self, type): return int(self.eval('GetVerbose("%s")' % type)) +@InstanceDoc class MagmaFunctionElement(FunctionElement): def __call__(self, *args, **kwds): """ @@ -1692,7 +1694,7 @@ def __call__(self, *args, **kwds): params=kwds, nvals=nvals) - def _sage_doc_(self): + def _instancedoc_(self): """ Return the docstring for this function of an element. @@ -1702,10 +1704,10 @@ def _sage_doc_(self): sage: n = magma(-15) # optional - magma sage: f = n.Factorisation # optional - magma - sage: print(f._sage_doc_()) # optional - magma + sage: print(f.__doc__) # optional - magma ( n) -> RngIntEltFact, RngIntElt, SeqEnum ... - sage: print(n.Factorisation._sage_doc_()) # optional - magma + sage: print(n.Factorisation.__doc__) # optional - magma ( n) -> RngIntEltFact, RngIntElt, SeqEnum ... """ @@ -1727,7 +1729,7 @@ def __repr__(self): """ Return string representation of this partially evaluated function. - This is basically the docstring (as returned by _sage_doc_) + This is basically the docstring (as returned by ``_instancedoc_``) unless self._name is the name of an attribute of the object, in which case this returns the value of that attribute. @@ -1763,9 +1765,10 @@ def __repr__(self): try: return M.eval('%s`%s' % (self._obj.name(), self._name)) except RuntimeError: - return "Partially evaluated Magma function or intrinsic '%s'\n\nSignature:\n\n%s" % (self._name, self._sage_doc_()) + return "Partially evaluated Magma function or intrinsic '%s'\n\nSignature:\n\n%s" % (self._name, self._instancedoc_()) +@InstanceDoc class MagmaFunction(ExpectFunction): def __call__(self, *args, **kwds): """ @@ -1802,7 +1805,7 @@ def __call__(self, *args, **kwds): params=kwds, nvals=nvals) - def _sage_doc_(self): + def _instancedoc_(self): """ Return docstring about this function. @@ -1813,7 +1816,7 @@ def _sage_doc_(self): sage: f = magma.Factorisation sage: type(f) - sage: print(f._sage_doc_()) # optional - magma + sage: print(f.__doc__) # optional - magma Intrinsic 'Factorisation' ... """ @@ -1846,6 +1849,7 @@ def is_MagmaElement(x): return isinstance(x, MagmaElement) +@InstanceDoc class MagmaElement(ExtraTabCompletion, ExpectElement): def _ref(self): """ diff --git a/src/sage/interfaces/maple.py b/src/sage/interfaces/maple.py index 2ea89a8992a..b6876e94de7 100644 --- a/src/sage/interfaces/maple.py +++ b/src/sage/interfaces/maple.py @@ -246,6 +246,7 @@ from sage.env import DOT_SAGE from sage.misc.pager import pager from sage.interfaces.tab_completion import ExtraTabCompletion +from sage.docs.instancedoc import InstanceDoc COMMANDS_CACHE = '%s/maple_commandlist_cache.sobj'%DOT_SAGE @@ -838,15 +839,17 @@ def clear(self, var): """ self.set(var, "'{}'".format(var)) + +@InstanceDoc class MapleFunction(ExpectFunction): - def _sage_doc_(self): + def _instancedoc(self): """ Returns the Maple help for this function. This gets called when doing "?" on self. EXAMPLES:: - sage: txt = maple.gcd._sage_doc_() # optional - maple + sage: txt = maple.gcd.__doc__ # optional - maple sage: txt.find('gcd - greatest common divisor') > 0 # optional - maple True """ @@ -873,8 +876,9 @@ def _sage_src_(self): return M._source(self._name) +@InstanceDoc class MapleFunctionElement(FunctionElement): - def _sage_doc_(self): + def _instancedoc_(self): """ Returns the Maple help for this function. @@ -883,7 +887,7 @@ def _sage_doc_(self): EXAMPLES:: sage: two = maple(2) # optional - maple - sage: txt = two.gcd._sage_doc_() # optional - maple + sage: txt = two.gcd.__doc__ # optional - maple sage: txt.find('gcd - greatest common divisor') > 0 # optional - maple True """ @@ -907,6 +911,7 @@ def _sage_src_(self): return self._obj.parent()._source(self._name) +@InstanceDoc class MapleElement(ExtraTabCompletion, ExpectElement): def __float__(self): diff --git a/src/sage/interfaces/mathematica.py b/src/sage/interfaces/mathematica.py index 165ad7f2cfc..ee8dc8aa36e 100644 --- a/src/sage/interfaces/mathematica.py +++ b/src/sage/interfaces/mathematica.py @@ -364,6 +364,7 @@ from sage.interfaces.expect import (Expect, ExpectElement, ExpectFunction, FunctionElement, AsciiArtString) from sage.interfaces.tab_completion import ExtraTabCompletion +from sage.docs.instancedoc import InstanceDoc def clean_output(s): @@ -624,6 +625,8 @@ def __getattr__(self, attrname): raise AttributeError return MathematicaFunction(self, attrname) + +@InstanceDoc class MathematicaElement(ExpectElement): def __getitem__(self, n): return self.parent().new('%s[[%s]]'%(self._name, n)) @@ -986,14 +989,17 @@ def n(self, *args, **kwargs): """ return self._sage_().n(*args, **kwargs) + +@InstanceDoc class MathematicaFunction(ExpectFunction): - def _sage_doc_(self): + def _instancedoc_(self): M = self._parent return M.help(self._name) +@InstanceDoc class MathematicaFunctionElement(FunctionElement): - def _sage_doc_(self): + def _instancedoc_(self): M = self._obj.parent() return M.help(self._name) diff --git a/src/sage/interfaces/matlab.py b/src/sage/interfaces/matlab.py index 39d6219989d..aefe0d339f1 100644 --- a/src/sage/interfaces/matlab.py +++ b/src/sage/interfaces/matlab.py @@ -152,10 +152,9 @@ import os from .expect import Expect, ExpectElement +from sage.docs.instancedoc import InstanceDoc -#import sage.matrix.matrix_space - class Matlab(Expect): """ Interface to the Matlab interpreter. @@ -321,6 +320,7 @@ def _object_class(self): return MatlabElement +@InstanceDoc class MatlabElement(ExpectElement): def __getitem__(self, n): raise RuntimeError("Use parenthesis for MATLAB matrices instead.") diff --git a/src/sage/interfaces/maxima.py b/src/sage/interfaces/maxima.py index 1fb0481b4ef..4b7799d35c7 100644 --- a/src/sage/interfaces/maxima.py +++ b/src/sage/interfaces/maxima.py @@ -469,14 +469,11 @@ import os import re import pexpect -#cygwin = os.uname()[0][:6]=="CYGWIN" from random import randrange from sage.env import DOT_SAGE, SAGE_LOCAL -##import sage.rings.all - from .expect import (Expect, ExpectElement, FunctionElement, ExpectFunction, gc_disabled) @@ -484,6 +481,8 @@ MaximaAbstractElement, MaximaAbstractFunctionElement, MaximaAbstractElementFunction) +from sage.docs.instancedoc import InstanceDoc + # Thanks to the MRO for multiple inheritance used by the Sage's Python, # this should work as expected @@ -1046,7 +1045,7 @@ def _function_class(self): EXAMPLES:: sage: maxima._function_class() - + """ return MaximaFunction @@ -1068,7 +1067,7 @@ def _function_element_class(self): EXAMPLES:: sage: maxima._function_element_class() - + """ return MaximaFunctionElement @@ -1119,8 +1118,8 @@ def is_MaximaElement(x): """ return isinstance(x, MaximaElement) -# Thanks to the MRO for multiple inheritance used by the Sage's Python, -# this should work as expected + +@InstanceDoc class MaximaElement(MaximaAbstractElement, ExpectElement): """ Element of Maxima through Pexpect interface. @@ -1186,26 +1185,11 @@ def display2d(self, onscreen=True): return s -# Thanks to the MRO for multiple inheritance used by the Sage's Python, -# this should work as expected -class MaximaFunctionElement(MaximaAbstractFunctionElement, FunctionElement): - pass -# def __init__(self, obj, name): -# MaximaAbstractFunctionElement.__init__(self, obj, name) -# FunctionElement.__init__(self, obj, name) +MaximaFunctionElement = MaximaAbstractFunctionElement +MaximaFunction = MaximaAbstractFunction -# Thanks to the MRO for multiple inheritance used by the Sage's Python, -# this should work as expected -class MaximaFunction(MaximaAbstractFunction, ExpectFunction): - pass -# def __init__(self, parent, name): -# MaximaAbstractFunction.__init__(self, parent, name) -# ExpectFunction.__init__(self, parent, name) - - -# Thanks to the MRO for multiple inheritance used by the Sage's Python, -# this should work as expected +@InstanceDoc class MaximaElementFunction(MaximaElement, MaximaAbstractElementFunction): """ Maxima user-defined functions. diff --git a/src/sage/interfaces/maxima_abstract.py b/src/sage/interfaces/maxima_abstract.py index 96675748d0a..dfafe12c1a9 100644 --- a/src/sage/interfaces/maxima_abstract.py +++ b/src/sage/interfaces/maxima_abstract.py @@ -60,14 +60,12 @@ COMMANDS_CACHE = '%s/maxima_commandlist_cache.sobj'%DOT_SAGE from sage.misc.multireplace import multiple_replace - import sage.server.support -##import sage.rings.all - from .interface import (Interface, InterfaceElement, InterfaceFunctionElement, InterfaceFunction, AsciiArtString) from sage.interfaces.tab_completion import ExtraTabCompletion +from sage.docs.instancedoc import InstanceDoc # The Maxima "apropos" command, e.g., apropos(det) gives a list # of all identifiers that begin in a certain way. This could @@ -534,7 +532,7 @@ def _function_class(self): EXAMPLES:: sage: maxima._function_class() - + """ return MaximaAbstractFunction @@ -564,7 +562,7 @@ def _function_element_class(self): EXAMPLES:: sage: maxima._function_element_class() - + """ return MaximaAbstractFunctionElement @@ -1072,6 +1070,7 @@ def plot_multilist(self, pts_list, options=None): self('plot2d('+cmd+','+options+')') +@InstanceDoc class MaximaAbstractElement(ExtraTabCompletion, InterfaceElement): r""" Element of Maxima through an abstract interface. @@ -1930,12 +1929,8 @@ def _operation(self, operation, other=None): raise TypeError(msg) -class MaximaAbstractFunctionElement(InterfaceFunctionElement): - pass - - -class MaximaAbstractFunction(InterfaceFunction): - pass +MaximaAbstractFunctionElement = InterfaceFunctionElement +MaximaAbstractFunction = InterfaceFunction class MaximaAbstractElementFunction(MaximaAbstractElement): diff --git a/src/sage/interfaces/maxima_lib.py b/src/sage/interfaces/maxima_lib.py index 5e95ae5b71c..8fa880ce0a0 100644 --- a/src/sage/interfaces/maxima_lib.py +++ b/src/sage/interfaces/maxima_lib.py @@ -92,8 +92,10 @@ from sage.libs.ecl import EclObject, ecl_eval from .maxima_abstract import (MaximaAbstract, MaximaAbstractFunction, - MaximaAbstractElement, MaximaAbstractFunctionElement, - MaximaAbstractElementFunction) + MaximaAbstractElement, MaximaAbstractFunctionElement, + MaximaAbstractElementFunction) +from sage.docs.instancedoc import InstanceDoc + ## We begin here by initializing Maxima in library mode ## i.e. loading it into ECL @@ -615,7 +617,7 @@ def _function_class(self): sage: from sage.interfaces.maxima_lib import maxima_lib sage: maxima_lib._function_class() - + """ return MaximaLibFunction @@ -647,7 +649,7 @@ def _function_element_class(self): sage: from sage.interfaces.maxima_lib import maxima_lib sage: maxima_lib._function_element_class() - + """ return MaximaLibFunctionElement @@ -1032,6 +1034,8 @@ def is_MaximaLibElement(x): """ return isinstance(x, MaximaLibElement) + +@InstanceDoc class MaximaLibElement(MaximaAbstractElement): r""" Element of Maxima through library interface. @@ -1134,14 +1138,10 @@ def display2d(self, onscreen=True): return s -class MaximaLibFunctionElement(MaximaAbstractFunctionElement): - pass - - -class MaximaLibFunction(MaximaAbstractFunction): - pass - +MaximaLibFunctionElement = MaximaAbstractFunctionElement +MaximaLibFunction = MaximaAbstractFunction +@InstanceDoc class MaximaLibElementFunction(MaximaLibElement, MaximaAbstractElementFunction): pass diff --git a/src/sage/interfaces/mupad.py b/src/sage/interfaces/mupad.py index 8e9bebed8ba..be9aa3c0c15 100644 --- a/src/sage/interfaces/mupad.py +++ b/src/sage/interfaces/mupad.py @@ -97,9 +97,8 @@ from .expect import (Expect, ExpectElement, ExpectFunction, FunctionElement, AsciiArtString) from sage.interfaces.tab_completion import ExtraTabCompletion - - from sage.env import DOT_SAGE +from sage.docs.instancedoc import InstanceDoc COMMANDS_CACHE = '%s/mupad_commandlist_cache.sobj'%DOT_SAGE PROMPT = ">>" @@ -443,13 +442,13 @@ def completions(self, string, strip=False): return res if res != [''] else [] +@InstanceDoc class MupadFunction(ExtraTabCompletion, ExpectFunction): - - def _sage_doc_(self): + def _instancedoc_(self): """ EXAMPLES:: - sage: mupad.diff._sage_doc_() + sage: mupad.diff.__doc__ No help on diff available """ M = self._parent @@ -481,13 +480,14 @@ def _tab_completion(self): return res if res != [] else self._parent._tab_completion() +@InstanceDoc class MupadFunctionElement(ExtraTabCompletion, FunctionElement): - def _sage_doc_(self): + def _instancedoc_(self): """ EXAMPLES:: - sage: x = mupad('x') # optional - mupad - sage: x.diff._sage_doc_() # optional - mupad + sage: x = mupad('x') # optional - mupad + sage: x.diff.__doc__ # optional - mupad No help on diff available """ @@ -551,6 +551,7 @@ def __call__(self, *args): return P.function_call(self._name, [self._obj] + list(args)) +@InstanceDoc class MupadElement(ExtraTabCompletion, ExpectElement): def __getattr__(self, attrname): diff --git a/src/sage/interfaces/octave.py b/src/sage/interfaces/octave.py index b4eac6c89fa..a948defe261 100644 --- a/src/sage/interfaces/octave.py +++ b/src/sage/interfaces/octave.py @@ -156,6 +156,8 @@ import os from .expect import Expect, ExpectElement from sage.misc.misc import verbose +from sage.docs.instancedoc import InstanceDoc + class Octave(Expect): r""" @@ -611,6 +613,8 @@ def to_complex(octave_string, R): real, imag = octave_string.strip('() ').split(',') return R(float(real), float(imag)) + +@InstanceDoc class OctaveElement(ExpectElement): def _get_sage_ring(self): r""" diff --git a/src/sage/interfaces/qepcad.py b/src/sage/interfaces/qepcad.py index b6252c2781c..0973c6f55d3 100644 --- a/src/sage/interfaces/qepcad.py +++ b/src/sage/interfaces/qepcad.py @@ -615,9 +615,10 @@ from sage.misc.sage_eval import sage_eval from sage.repl.preparse import implicit_mul from sage.interfaces.tab_completion import ExtraTabCompletion - +from sage.docs.instancedoc import InstanceDoc from .expect import Expect, ExpectFunction, AsciiArtString + def _qepcad_atoms(formula): r""" Return the atoms of a qepcad quantifier-free formula, as a set of strings. @@ -1359,11 +1360,12 @@ def _format_cell_index(a): return str(tuple(a)) +@InstanceDoc class QepcadFunction(ExpectFunction): r""" A wrapper for a QEPCAD command. """ - def _sage_doc_(self): + def _instancedoc_(self): r""" Return the documentation for a QEPCAD command, from ``qepcad.help``. @@ -1372,7 +1374,7 @@ def _sage_doc_(self): sage: qe = qepcad(x == 17, interact=True) # optional - qepcad sage: cmd = qe.approx_precision # optional - qepcad - sage: cmd._sage_doc_() # optional - qepcad + sage: cmd.__doc__ # optional - qepcad 'approx-precision N\n\nApproximate algeraic numbers to N decimal places.\n' """ _update_command_info() diff --git a/src/sage/interfaces/r.py b/src/sage/interfaces/r.py index a759ce4ce97..3e343116da8 100644 --- a/src/sage/interfaces/r.py +++ b/src/sage/interfaces/r.py @@ -274,7 +274,7 @@ from sage.structure.element import parent from sage.misc.cachefunc import cached_method from sage.interfaces.tab_completion import ExtraTabCompletion - +from sage.docs.instancedoc import InstanceDoc COMMANDS_CACHE = '%s/r_commandlist.sobj'%DOT_SAGE PROMPT = '__SAGE__R__PROMPT__> ' @@ -1255,6 +1255,8 @@ def chdir(self, dir): rel_re_terms = re.compile('terms\s*=\s*(.*?),') rel_re_call = re.compile('call\s*=\s*(.*?)\),') + +@InstanceDoc class RElement(ExtraTabCompletion, ExpectElement): def _tab_completion(self): @@ -1921,7 +1923,7 @@ def _latex_(self): return LatexExpr(P.eval('latex(%s, file="");'%self.name())) - +@InstanceDoc class RFunctionElement(FunctionElement): def __reduce__(self): """ @@ -1937,7 +1939,7 @@ def __reduce__(self): """ raise NotImplementedError("pickling of R element methods is not yet supported") - def _sage_doc_(self): + def _instancedoc_(self): """ Returns the help for self as a string. @@ -1945,7 +1947,7 @@ def _sage_doc_(self): sage: a = r([1,2,3]) sage: length = a.length - sage: print(length._sage_doc_()) + sage: print(length.__doc__) length package:base R Documentation ... @@ -1979,6 +1981,7 @@ def __call__(self, *args, **kwds): return self._obj.parent().function_call(self._name, args=[self._obj] + list(args), kwds=kwds) +@InstanceDoc class RFunction(ExpectFunction): def __init__(self, parent, name, r_name=None): """ @@ -2027,14 +2030,14 @@ def __ne__(self, other): """ return not (self == other) - def _sage_doc_(self): + def _instancedoc_(self): """ Returns the help for self. EXAMPLES:: sage: length = r.length - sage: print(length._sage_doc_()) + sage: print(length.__doc__) length package:base R Documentation ... diff --git a/src/sage/interfaces/sage0.py b/src/sage/interfaces/sage0.py index 56e6eba6c54..68e55232219 100644 --- a/src/sage/interfaces/sage0.py +++ b/src/sage/interfaces/sage0.py @@ -26,6 +26,7 @@ from sage.interfaces.tab_completion import ExtraTabCompletion from sage.structure.sage_object import dumps, load +from sage.docs.instancedoc import InstanceDoc class Sage(ExtraTabCompletion, Expect): @@ -397,6 +398,7 @@ def new(self, x): return SageElement(self, x) +@InstanceDoc class SageElement(ExpectElement): def _rich_repr_(self, display_manager, **kwds): @@ -464,6 +466,7 @@ def _sage_(self): return load(P._local_tmpfile()) +@InstanceDoc class SageFunction(FunctionElement): def __call__(self, *args, **kwds): """ diff --git a/src/sage/interfaces/scilab.py b/src/sage/interfaces/scilab.py index f746132cbac..16c3d769d60 100644 --- a/src/sage/interfaces/scilab.py +++ b/src/sage/interfaces/scilab.py @@ -192,6 +192,7 @@ import os from .expect import Expect, ExpectElement +from sage.docs.instancedoc import InstanceDoc class Scilab(Expect): @@ -425,6 +426,7 @@ def _object_class(self): return ScilabElement +@InstanceDoc class ScilabElement(ExpectElement): def __getitem__(self, n): """ diff --git a/src/sage/interfaces/singular.py b/src/sage/interfaces/singular.py index 2af7bc10781..fb914dd2468 100644 --- a/src/sage/interfaces/singular.py +++ b/src/sage/interfaces/singular.py @@ -337,6 +337,7 @@ from sage.misc.misc import get_verbose from sage.misc.superseded import deprecation +from sage.docs.instancedoc import InstanceDoc from six import reraise as raise_ @@ -1260,6 +1261,7 @@ def _keyboard_interrupt(self): raise KeyboardInterrupt("Restarting %s (WARNING: all variables defined in previous session are now invalid)" % self) +@InstanceDoc class SingularElement(ExtraTabCompletion, ExpectElement): def __init__(self, parent, type, value, is_name=False): @@ -2172,12 +2174,14 @@ def attrib(self, name, value=None): else: self.parent().eval('attrib(%s,"%s",%d)'%(self.name(),name,value)) + +@InstanceDoc class SingularFunction(ExpectFunction): - def _sage_doc_(self): + def _instancedoc_(self): """ EXAMPLES:: - sage: 'groebner' in singular.groebner._sage_doc_() + sage: 'groebner' in singular.groebner.__doc__ True """ if not nodes: @@ -2208,14 +2212,16 @@ def _sage_doc_(self): except KeyError: return prefix + +@InstanceDoc class SingularFunctionElement(FunctionElement): - def _sage_doc_(self): + def _instancedoc_(self): r""" EXAMPLES:: sage: R = singular.ring(0, '(x,y,z)', 'dp') sage: A = singular.matrix(2,2) - sage: 'matrix_expression' in A.nrows._sage_doc_() + sage: 'matrix_expression' in A.nrows.__doc__ True """ if not nodes: diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index ee5bcde8b2f..8bec94f8205 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -2060,14 +2060,14 @@ cdef class GapElement_Function(GapElement): return make_any_gap_element(self.parent(), result) - def _sage_doc_(self): + def _instancedoc_(self): r""" Return the help string EXAMPLES:: sage: f = libgap.CyclicGroup - sage: 'constructs the cyclic group' in f._sage_doc_() + sage: 'constructs the cyclic group' in f.__doc__ True You would get the full help by typing ``f?`` in the command line. @@ -2673,3 +2673,9 @@ cdef class GapElement_RecordIterator(object): val = make_any_gap_element(self.rec.parent(), result) self.i += 1 return (key, val) + + +# Add support for _instancedoc_ +from sage.docs.instancedoc import InstanceDoc +InstanceDoc(GapElement_Function) +InstanceDoc(GapElement_MethodProxy) diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index 2813a6f6df9..599fda4cee0 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -1322,13 +1322,13 @@ cdef class SingularFunction(SageObject): raise TypeError("Cannot call Singular function '%s' with ring parameter of type '%s'"%(self._name,type(ring))) return call_function(self, args, ring, interruptible, attributes) - def _sage_doc_(self): + def _instancedoc_(self): """ EXAMPLES:: sage: from sage.libs.singular.function import singular_function sage: groebner = singular_function('groebner') - sage: 'groebner' in groebner._sage_doc_() + sage: 'groebner' in groebner.__doc__ True """ @@ -1876,3 +1876,10 @@ cdef inline RingWrap new_RingWrap(ring* r): ring_wrap_result._ring.ref += 1 return ring_wrap_result + + +# Add support for _instancedoc_ +from sage.docs.instancedoc import InstanceDoc +InstanceDoc(SingularFunction) +InstanceDoc(SingularLibraryFunction) +InstanceDoc(SingularKernelFunction) diff --git a/src/sage/misc/cachefunc.pyx b/src/sage/misc/cachefunc.pyx index 5ce4098f9ed..99ac71bb354 100644 --- a/src/sage/misc/cachefunc.pyx +++ b/src/sage/misc/cachefunc.pyx @@ -892,7 +892,7 @@ cdef class CachedFunction(object): ## We provide some methods explicitly, and ## forward other questions to the cached function. - def _sage_doc_(self): + def _instancedoc_(self): """ Provide documentation for the cached function. @@ -924,7 +924,7 @@ cdef class CachedFunction(object): sage: @cached_function ....: def f(): ....: return 3 - sage: f._sage_doc_() + sage: f.__doc__ 'File: ... (starting at line 1)\n' """ from sage.misc.sageinspect import _extract_embedded_position @@ -3785,3 +3785,13 @@ class disk_cached_function: Modular Symbols space of dimension 65 for Gamma_0(389) of weight 2 with sign 0 over Rational Field """ return DiskCachedFunction(f, self._dir, memory_cache=self._memory_cache, key=self._key) + + +# Add support for _instancedoc_ +from sage.docs.instancedoc import InstanceDoc +InstanceDoc(CachedFunction) +InstanceDoc(WeakCachedFunction) +InstanceDoc(CachedMethodCaller) +InstanceDoc(CachedMethodCallerNoArgs) +InstanceDoc(GloballyCachedMethodCaller) +InstanceDoc(DiskCachedFunction) diff --git a/src/sage/misc/lazy_import.pyx b/src/sage/misc/lazy_import.pyx index 5f288870d75..204fe4b6bdf 100644 --- a/src/sage/misc/lazy_import.pyx +++ b/src/sage/misc/lazy_import.pyx @@ -296,7 +296,7 @@ cdef class LazyImport(object): except TypeError: return self._deprecation - def _sage_doc_(self): + def _instancedoc_(self): """ Return the docstring of the wrapped object for introspection. @@ -304,14 +304,14 @@ cdef class LazyImport(object): sage: from sage.misc.lazy_import import LazyImport sage: my_isprime = LazyImport('sage.all', 'is_prime') - sage: my_isprime._sage_doc_() is is_prime.__doc__ + sage: my_isprime.__doc__ is is_prime.__doc__ True TESTS: Check that :trac:`19475` is fixed:: - sage: 'A subset of the real line' in RealSet._sage_doc_() + sage: 'A subset of the real line' in RealSet.__doc__ True """ return sageinspect.sage_getdoc_original(self._get_object()) @@ -1150,3 +1150,8 @@ def get_star_imports(module_name): all = [key for key in dir(module) if key[0] != "_"] star_imports[module_name] = all return all + + +# Add support for _instancedoc_ +from sage.docs.instancedoc import InstanceDoc +InstanceDoc(LazyImport) diff --git a/src/sage/misc/sagedoc.py b/src/sage/misc/sagedoc.py index 3d77c988d86..787e11e2592 100644 --- a/src/sage/misc/sagedoc.py +++ b/src/sage/misc/sagedoc.py @@ -1576,13 +1576,7 @@ def help(module=None): Welcome to Sage ... """ if not module is None: - if hasattr(module, '_sage_doc_'): - from sage.misc.sageinspect import sage_getdef, _sage_getdoc_unformatted - docstr = 'Help on ' + str(module) + '\n' - docstr += 'Definition: ' + module.__name__ + sage_getdef(module) + '\n' - pydoc.pager(docstr + _sage_getdoc_unformatted(module)) - else: - python_help(module) + python_help(module) else: print("""Welcome to Sage {}! diff --git a/src/sage/misc/sageinspect.py b/src/sage/misc/sageinspect.py index 747a69de41b..bb448a0abb9 100644 --- a/src/sage/misc/sageinspect.py +++ b/src/sage/misc/sageinspect.py @@ -1609,15 +1609,15 @@ def _sage_getdoc_unformatted(obj): '' Construct an object raising an exception when accessing the - ``_sage_doc_`` attribute. This should not give an error in + ``__doc__`` attribute. This should not give an error in ``_sage_getdoc_unformatted``, see :trac:`19671`:: sage: class NoSageDoc(object): ....: @property - ....: def _sage_doc_(self): + ....: def __doc__(self): ....: raise Exception("no doc here") sage: obj = NoSageDoc() - sage: obj._sage_doc_ + sage: obj.__doc__ Traceback (most recent call last): ... Exception: no doc here @@ -1632,14 +1632,9 @@ def _sage_getdoc_unformatted(obj): if obj is None: return '' try: - getdoc = obj._sage_doc_ - except Exception: r = obj.__doc__ - else: - try: - r = getdoc() - except TypeError: # This can occur if obj is a class - r = obj.__doc__ + except Exception: + return '' # Check if the __doc__ attribute was actually a string, and # not a 'getset_descriptor' or similar. diff --git a/src/sage/parallel/decorate.py b/src/sage/parallel/decorate.py index ebc06e283e5..33057247cb9 100644 --- a/src/sage/parallel/decorate.py +++ b/src/sage/parallel/decorate.py @@ -10,6 +10,7 @@ from .reference import parallel_iter as p_iter_reference from .use_fork import p_iter_fork from . import multiprocessing_sage +from sage.docs.instancedoc import InstanceDoc def normalize_input(a): @@ -119,6 +120,8 @@ def __call__(self, f): """ return ParallelFunction(self, f) + +@InstanceDoc class ParallelFunction(object): """ Class which parallelizes a function or class method. @@ -266,7 +269,7 @@ def _sage_src_(self): from sage.misc.sageinspect import sage_getsource return sage_getsource(self.func) - def _sage_doc_(self): + def _instancedoc_(self): """ Returns the docstring for this object, which is just the docstring for the underlying function. See @@ -284,8 +287,7 @@ def _sage_doc_(self): sage: sage_getdoc(p(f)) 'Test docstring\n' """ - from sage.misc.sageinspect import sage_getdoc - return sage_getdoc(self.func) + return self.func.__doc__ def parallel(p_iter='fork', ncpus=None, **kwds): diff --git a/src/sage/sets/set_from_iterator.py b/src/sage/sets/set_from_iterator.py index 7acf885eca6..2e954fa5c94 100644 --- a/src/sage/sets/set_from_iterator.py +++ b/src/sage/sets/set_from_iterator.py @@ -72,6 +72,7 @@ import os from sage.misc.function_mangling import ArgumentFixer from sage.misc.lazy_list import lazy_list +from sage.docs.instancedoc import InstanceDoc class EnumeratedSetFromIterator(Parent): @@ -446,13 +447,14 @@ def clear_cache(self): # #TODO: move it in sage.misc ? -class Decorator: +@InstanceDoc +class Decorator(object): r""" Abstract class that manage documentation and sources of the wrapped object. The method needs to be stored in the attribute ``self.f`` """ - def _sage_doc_(self): + def _instancedoc_(self): """ Provide documentation for the wrapped function. @@ -559,6 +561,8 @@ def __call__(self, *args, **kwds): """ raise NotImplementedError + +@InstanceDoc class EnumeratedSetFromIterator_function_decorator(Decorator): r""" Decorator for :class:`EnumeratedSetFromIterator`. @@ -717,6 +721,8 @@ def __call__(self, *args, **kwds): set_from_function = EnumeratedSetFromIterator_function_decorator + +@InstanceDoc class EnumeratedSetFromIterator_method_caller(Decorator): r""" Caller for decorated method in class. @@ -863,7 +869,7 @@ class EnumeratedSetFromIterator_method_decorator(object): ....: def f(self): return xsrange(self.n()) sage: a = A() sage: print(a.f.__class__) - sage.sets.set_from_iterator.EnumeratedSetFromIterator_method_caller + sage: a.f() {0, 1, 2, 3, 4, ...} sage: A.f(a) @@ -978,9 +984,9 @@ def __get__(self, inst, cls): ....: def f(self): return xsrange(self.n()) sage: a = A() sage: print(A.f.__class__) - sage.sets.set_from_iterator.EnumeratedSetFromIterator_method_caller + sage: print(a.f.__class__) - sage.sets.set_from_iterator.EnumeratedSetFromIterator_method_caller + """ # You would hardly ever see an instance of this class alive. return EnumeratedSetFromIterator_method_caller(inst, self.f, **self.options) diff --git a/src/sage/symbolic/maxima_wrapper.py b/src/sage/symbolic/maxima_wrapper.py index 84ac4bae71d..da10d10cbbe 100644 --- a/src/sage/symbolic/maxima_wrapper.py +++ b/src/sage/symbolic/maxima_wrapper.py @@ -10,7 +10,10 @@ from sage.structure.sage_object import SageObject from sage.interfaces.maxima import MaximaFunctionElement +from sage.docs.instancedoc import InstanceDoc + +@InstanceDoc class MaximaFunctionElementWrapper(MaximaFunctionElement): def __call__(self, *args, **kwds): """ diff --git a/src/sage/symbolic/units.py b/src/sage/symbolic/units.py index da42e852696..b75c1453330 100644 --- a/src/sage/symbolic/units.py +++ b/src/sage/symbolic/units.py @@ -22,7 +22,7 @@ Units have additional information in their docstring:: sage: # You would type: units.force.dyne? - sage: print(units.force.dyne._sage_doc_()) + sage: print(units.force.dyne.__doc__) CGS unit for force defined to be gram*centimeter/second^2. Equal to 10^-5 newtons. @@ -97,6 +97,7 @@ from .ring import SR from .expression import Expression from sage.interfaces.tab_completion import ExtraTabCompletion +from sage.docs.instancedoc import InstanceDoc ############################################################################### # Unit conversions dictionary. @@ -984,6 +985,8 @@ def unit_derivations_expr(v): unit_derivations[v] = Z return Z + +@InstanceDoc class UnitExpression(Expression): """ A symbolic unit. @@ -1001,13 +1004,13 @@ class UnitExpression(Expression): sage: type(loads(dumps(acre))) """ - def _sage_doc_(self): + def _instancedoc_(self): """ Return docstring for this unit. EXAMPLES:: - sage: print(units.area.acre._sage_doc_()) + sage: print(units.area.acre.__doc__) Defined to be 10 square chains or 4840 square yards. Approximately equal to 4046.856 square meters. """ From eceafc72fb4dbaf0df046f4b2ae52e11422028cd Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Sat, 18 Mar 2017 10:32:17 +0100 Subject: [PATCH 159/185] Add a "sageruntime" build target --- build/make/deps | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/make/deps b/build/make/deps index 11650097ea4..cc14493b767 100644 --- a/build/make/deps +++ b/build/make/deps @@ -80,6 +80,9 @@ toolchain-deps: # every part of Sage will work. It does not include Maxima for example. SAGERUNTIME = sagelib $(SCRIPTS) $(inst_ipython) $(inst_pexpect) $(inst_psutil) +sageruntime: all-toolchain + $(MAKE) $(SAGERUNTIME) + # Start Sage at least once to check that it works # (i.e. when we just installed Sage for the first time). From 680628695b486702af7f8136c14bc6f7ab7b600e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jori=20M=C3=A4ntysalo?= Date: Sun, 19 Mar 2017 10:19:51 +0200 Subject: [PATCH 160/185] Minor code change. --- src/sage/combinat/posets/lattices.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/posets/lattices.py b/src/sage/combinat/posets/lattices.py index 88065be29ba..1e4e211e519 100644 --- a/src/sage/combinat/posets/lattices.py +++ b/src/sage/combinat/posets/lattices.py @@ -3768,8 +3768,8 @@ def subdirect_decomposition(self): for e in L: low = L.lower_covers(e) if len(low) == 1: # a join-irreducible element - C[e] = congs[max(e, key=lambda x: cong_ji._element_to_vertex(x))] - if len(low) > 1: # "extending" congruence to avoid re-computation + C[e] = congs[max(e, key=cong_ji._element_to_vertexx)] + elif low: # "extending" congruence to avoid re-computation low_0 = min(low, key=lambda x: C[x].number_of_subsets()) for new_pair in e: if new_pair not in low_0: From 3c8d86af00bd5ec2345059be0c1b7a29dafc3cc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jori=20M=C3=A4ntysalo?= Date: Sun, 19 Mar 2017 19:08:44 +0200 Subject: [PATCH 161/185] A typo in code. --- src/sage/combinat/posets/lattices.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/posets/lattices.py b/src/sage/combinat/posets/lattices.py index 1e4e211e519..c6e458b64ed 100644 --- a/src/sage/combinat/posets/lattices.py +++ b/src/sage/combinat/posets/lattices.py @@ -3768,7 +3768,7 @@ def subdirect_decomposition(self): for e in L: low = L.lower_covers(e) if len(low) == 1: # a join-irreducible element - C[e] = congs[max(e, key=cong_ji._element_to_vertexx)] + C[e] = congs[max(e, key=cong_ji._element_to_vertex)] elif low: # "extending" congruence to avoid re-computation low_0 = min(low, key=lambda x: C[x].number_of_subsets()) for new_pair in e: From ccf5e37b0ccf0e2b48c1c4f8d914dc5169df86fc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 12 Mar 2017 19:16:35 +0100 Subject: [PATCH 162/185] Update patches and script for 4.0.0 --- build/pkgs/scipoptsuite/checksums.ini | 6 +-- build/pkgs/scipoptsuite/package-version.txt | 2 +- ...-Add-dependency-of-libscip-on-liblpi.patch | 28 +++++------ .../scip/0002-Library-dependencies.patch | 48 ++++++++----------- .../scip/0003-Link-SCIP-against-libscip.patch | 27 ++++------- ...missing-header-files-to-make-install.patch | 32 ------------- ...ew-variables-SCIP_LIBBUILDFLAGS-etc.patch} | 47 ++++++++++-------- ...-Add-TPI-to-the-library-dependencies.patch | 25 ++++++++++ build/pkgs/scipoptsuite/spkg-install | 16 ++++--- 9 files changed, 109 insertions(+), 122 deletions(-) delete mode 100644 build/pkgs/scipoptsuite/patches/scip/0004-Add-missing-header-files-to-make-install.patch rename build/pkgs/scipoptsuite/patches/scip/{0005-Use-new-variables-SCIP_LIBBUILDFLAGS-etc.patch => 0004-Use-new-variables-SCIP_LIBBUILDFLAGS-etc.patch} (55%) create mode 100644 build/pkgs/scipoptsuite/patches/scip/0005-Add-TPI-to-the-library-dependencies.patch diff --git a/build/pkgs/scipoptsuite/checksums.ini b/build/pkgs/scipoptsuite/checksums.ini index 7e5e46012ab..7a726ddfdfe 100644 --- a/build/pkgs/scipoptsuite/checksums.ini +++ b/build/pkgs/scipoptsuite/checksums.ini @@ -1,4 +1,4 @@ tarball=scipoptsuite-VERSION.tgz -sha1=68fcd1eb43efbe33ee062097bc6c04e53ad8a64a -md5=c8e4d39a447ef651e3d49a3955c24450 -cksum=2550094083 +sha1=72023e6cb2238f45da76cd2d7ee73880272158e9 +md5=cdd56b4f39bfbe9ed49ca50c57f406c4 +cksum=4143641727 diff --git a/build/pkgs/scipoptsuite/package-version.txt b/build/pkgs/scipoptsuite/package-version.txt index e4604e3afd0..fcdb2e109f6 100644 --- a/build/pkgs/scipoptsuite/package-version.txt +++ b/build/pkgs/scipoptsuite/package-version.txt @@ -1 +1 @@ -3.2.1 +4.0.0 diff --git a/build/pkgs/scipoptsuite/patches/scip/0001-Add-dependency-of-libscip-on-liblpi.patch b/build/pkgs/scipoptsuite/patches/scip/0001-Add-dependency-of-libscip-on-liblpi.patch index 635239534be..9ee5eda71ca 100644 --- a/build/pkgs/scipoptsuite/patches/scip/0001-Add-dependency-of-libscip-on-liblpi.patch +++ b/build/pkgs/scipoptsuite/patches/scip/0001-Add-dependency-of-libscip-on-liblpi.patch @@ -1,29 +1,25 @@ -From 702bcd9003dbb90fb2ff33ddbe4e01229207bd63 Mon Sep 17 00:00:00 2001 +From c56ab3fbeea95c232372ba1bafb8f09bedd4c010 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 26 Jul 2016 11:32:35 -0700 Subject: [PATCH 1/5] Add dependency of libscip on liblpi* --- - Makefile | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile -index 6181eb4..27fb1ec 100644 +index d9835fc..b276aa7 100644 --- a/Makefile +++ b/Makefile -@@ -945,10 +945,10 @@ endif - makesciplibfile: preprocess - @$(MAKE) $(SCIPLIBFILE) - --$(SCIPLIBFILE): $(SCIPLIBOBJFILES) | $(LIBDIR) $(LIBOBJSUBDIRS) -+$(SCIPLIBFILE): $(SCIPLIBOBJFILES) $(LPILIBFILE) | $(LIBDIR) $(LIBOBJSUBDIRS) - @echo "-> generating library $@" - -rm -f $@ -- $(LIBBUILD) $(LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(SCIPLIBOBJFILES) -+ $(LIBBUILD) $(LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(SCIPLIBOBJFILES) $(LPILIBFILE) - ifneq ($(RANLIB),) - $(RANLIB) $@ +@@ -422,7 +422,7 @@ SCIPLIBEXTLIBS += $(READLINE_LDFLAGS) + endif + SCIPLIBEXTLIBS += $(ZIMPLLIB) $(LINKRPATH)$(realpath $(LIBDIR)/$(LIBTYPE)) endif +- ++SCIPLIBEXTLIBS += $(LPILIBFILE) + + #----------------------------------------------------------------------------- + # SCIP Library -- 2.7.4 (Apple Git-66) diff --git a/build/pkgs/scipoptsuite/patches/scip/0002-Library-dependencies.patch b/build/pkgs/scipoptsuite/patches/scip/0002-Library-dependencies.patch index b66dee6c5fa..4db7f02fd08 100644 --- a/build/pkgs/scipoptsuite/patches/scip/0002-Library-dependencies.patch +++ b/build/pkgs/scipoptsuite/patches/scip/0002-Library-dependencies.patch @@ -1,43 +1,35 @@ -From 9e0f53cdeaebfd22721a52078af22fb9456156c6 Mon Sep 17 00:00:00 2001 +From 99b9db6b9e1db1a048e4bade34e1c5d86d3055c8 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 26 Jul 2016 12:55:23 -0700 Subject: [PATCH 2/5] Library dependencies --- - Makefile | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) + Makefile | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile -index 27fb1ec..abf324a 100644 +index b276aa7..90a0eb1 100644 --- a/Makefile +++ b/Makefile -@@ -122,6 +122,7 @@ endif - LPILIBOBJ = lpi/lpi_spx.o scip/bitencode.o blockmemshell/memory.o scip/message.o - LPILIBSRC = $(SRCDIR)/lpi/lpi_spx.cpp $(SRCDIR)/scip/bitencode.c $(SRCDIR)/blockmemshell/memory.c $(SRCDIR)/scip/message.c - SOFTLINKS += $(LIBDIR)/spxinc -+LPILIBS = $(LIBDIR)/libsoplex.$(OSTYPE).$(ARCH).$(COMP).$(LPSOPT).$(LIBEXT) - SOFTLINKS += $(LIBDIR)/libsoplex.$(OSTYPE).$(ARCH).$(COMP).$(LPSOPT).$(STATICLIBEXT) - SOFTLINKS += $(LIBDIR)/libsoplex.$(OSTYPE).$(ARCH).$(COMP).$(LPSOPT).$(SHAREDLIBEXT) - LPIINSTMSG = " -> \"spxinc\" is the path to the SoPlex \"src\" directory, e.g., \"../../soplex/src\".\n" -@@ -945,10 +946,10 @@ endif - makesciplibfile: preprocess - @$(MAKE) $(SCIPLIBFILE) - --$(SCIPLIBFILE): $(SCIPLIBOBJFILES) $(LPILIBFILE) | $(LIBDIR) $(LIBOBJSUBDIRS) -+$(SCIPLIBFILE): $(SCIPLIBOBJFILES) $(LPILIBFILE) $(NLPILIBFILE) | $(LIBDIR) $(LIBOBJSUBDIRS) - @echo "-> generating library $@" - -rm -f $@ -- $(LIBBUILD) $(LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(SCIPLIBOBJFILES) $(LPILIBFILE) -+ $(LIBBUILD) $(LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(SCIPLIBOBJFILES) $(LPILIBFILE) $(NLPILIBFILE) - ifneq ($(RANLIB),) - $(RANLIB) $@ +@@ -422,7 +422,7 @@ SCIPLIBEXTLIBS += $(READLINE_LDFLAGS) + endif + SCIPLIBEXTLIBS += $(ZIMPLLIB) $(LINKRPATH)$(realpath $(LIBDIR)/$(LIBTYPE)) endif -@@ -964,7 +965,7 @@ endif - $(LPILIBFILE): $(LPILIBOBJFILES) | $(LIBOBJSUBDIRS) $(LIBDIR) +-SCIPLIBEXTLIBS += $(LPILIBFILE) ++SCIPLIBEXTLIBS += $(LPILIBFILE) $(NLPILIBFILE) + + #----------------------------------------------------------------------------- + # SCIP Library +@@ -1104,10 +1104,11 @@ endif + libscip: preprocess + @$(MAKE) $(SCIPLIBFILE) $(SCIPLIBLINK) $(SCIPLIBSHORTLINK) + +-$(SCIPLIBFILE): $(SCIPLIBOBJFILES) | $(LIBDIR)/$(LIBTYPE) $(LIBOBJSUBDIRS) ++$(SCIPLIBFILE): $(SCIPLIBOBJFILES) $(LPILIBFILE) $(NLPILIBFILE) | $(LIBDIR)/$(LIBTYPE) $(LIBOBJSUBDIRS) @echo "-> generating library $@" -rm -f $@ -- $(LIBBUILD) $(LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(LPILIBOBJFILES) -+ $(LIBBUILD) $(LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(LPILIBOBJFILES) $(LPILIBS) + $(LIBBUILD) $(LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(SCIPLIBOBJFILES) $(SCIPLIBEXTLIBS) ++ ifneq ($(RANLIB),) $(RANLIB) $@ endif diff --git a/build/pkgs/scipoptsuite/patches/scip/0003-Link-SCIP-against-libscip.patch b/build/pkgs/scipoptsuite/patches/scip/0003-Link-SCIP-against-libscip.patch index 311743c1e50..cd5cba96f2f 100644 --- a/build/pkgs/scipoptsuite/patches/scip/0003-Link-SCIP-against-libscip.patch +++ b/build/pkgs/scipoptsuite/patches/scip/0003-Link-SCIP-against-libscip.patch @@ -1,34 +1,27 @@ -From 89d51635a590233215f1f08a73407a38f3c1a2f1 Mon Sep 17 00:00:00 2001 +From 0b208a25652550b3afd49ddd35e3879e82652a5b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 29 Jul 2016 14:18:12 -0700 Subject: [PATCH 3/5] Link SCIP against libscip --- - Makefile | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) + Makefile | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile -index abf324a..7ee691a 100644 +index 90a0eb1..d551556 100644 --- a/Makefile +++ b/Makefile -@@ -927,7 +927,7 @@ depend: scipdepend lpidepend nlpidepend maindepend - -include $(LPILIBDEP) - -include $(NLPILIBDEP) - --$(MAINFILE): $(SCIPLIBOBJFILES) $(LPILIBOBJFILES) $(NLPILIBOBJFILES) $(MAINOBJFILES) | $(BINDIR) $(BINOBJDIR) $(LIBOBJSUBDIRS) -+$(MAINFILE): $(SCIPLIBFILE) $(MAINOBJFILES) | $(BINDIR) $(BINOBJDIR) $(LIBOBJSUBDIRS) - @echo "-> linking $@" - ifeq ($(LINKER),C) - -$(LINKCC) $(MAINOBJFILES) \ -@@ -937,7 +937,7 @@ ifeq ($(LINKER),C) +@@ -1096,7 +1096,9 @@ ifeq ($(LINKER),C) + || ($(MAKE) errorhints && false) endif ifeq ($(LINKER),CPP) - -$(LINKCXX) $(MAINOBJFILES) \ -- $(LINKCXX_L)$(LIBDIR) $(SCIPLIBOBJFILES) $(LPILIBOBJFILES) $(NLPILIBOBJFILES) \ +- -$(LINKCXX) $(MAINOBJFILES) $(LINKCCSCIPALL) $(LINKCXX_o)$@ \ ++ -$(LINKCXX) $(MAINOBJFILES) \ + $(LINKCXX_L)$(LIBDIR) $(SCIPLIBFILE) $(LPILIBFILE) $(NLPILIBFILE) \ - $(OFLAGS) $(LPSLDFLAGS) $(LDFLAGS) $(LINKCXX_o)$@ \ ++ $(OFLAGS) $(LPSLDFLAGS) $(LDFLAGS) $(LINKCXX_o)$@ \ || ($(MAKE) errorhints && false) endif + -- 2.7.4 (Apple Git-66) diff --git a/build/pkgs/scipoptsuite/patches/scip/0004-Add-missing-header-files-to-make-install.patch b/build/pkgs/scipoptsuite/patches/scip/0004-Add-missing-header-files-to-make-install.patch deleted file mode 100644 index 6aa1f18a873..00000000000 --- a/build/pkgs/scipoptsuite/patches/scip/0004-Add-missing-header-files-to-make-install.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 9de9714845a02c6dcf40548f820c2970aa561eb3 Mon Sep 17 00:00:00 2001 -From: Matthias Koeppe -Date: Fri, 29 Jul 2016 14:18:32 -0700 -Subject: [PATCH 4/5] Add missing header files to 'make install' - ---- - make/make.install | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/make/make.install b/make/make.install -index 07e409d..c60a4a3 100644 ---- a/make/make.install -+++ b/make/make.install -@@ -37,6 +37,15 @@ ifneq ($(INSTALLDIR),) - @-install -m 644 -p $(SRCDIR)/scip/type_*.h $(INSTALLDIR)/$(INCLUDEDIR)/scip/ - @-install -m 644 -p $(SRCDIR)/scip/scip.h $(INSTALLDIR)/$(INCLUDEDIR)/scip/ - @-install -m 644 -p $(SRCDIR)/scip/def.h $(INSTALLDIR)/$(INCLUDEDIR)/scip/ -+ @-install -m 644 -p $(SRCDIR)/scip/implics.h $(INSTALLDIR)/$(INCLUDEDIR)/scip/ -+ @-install -m 644 -p $(SRCDIR)/scip/history.h $(INSTALLDIR)/$(INCLUDEDIR)/scip/ -+ @-install -m 644 -p $(SRCDIR)/scip/message.h $(INSTALLDIR)/$(INCLUDEDIR)/scip/ -+ @-install -m 644 -p $(SRCDIR)/scip/set.h $(INSTALLDIR)/$(INCLUDEDIR)/scip/ -+ @-install -m 644 -p $(SRCDIR)/scip/debug.h $(INSTALLDIR)/$(INCLUDEDIR)/scip/ -+ @-install -m 644 -p $(SRCDIR)/scip/tree.h $(INSTALLDIR)/$(INCLUDEDIR)/scip/ -+ @-install -m 644 -p $(SRCDIR)/scip/misc.h $(INSTALLDIR)/$(INCLUDEDIR)/scip/ -+ @-install -m 644 -p $(SRCDIR)/scip/var.h $(INSTALLDIR)/$(INCLUDEDIR)/scip/ -+ @-install -m 644 -p $(SRCDIR)/scip/event.h $(INSTALLDIR)/$(INCLUDEDIR)/scip/ - @-install -m 644 -p $(SRCDIR)/scip/visual.h $(INSTALLDIR)/$(INCLUDEDIR)/scip/ - @-install -m 644 -p $(SRCDIR)/scip/scipshell.h $(INSTALLDIR)/$(INCLUDEDIR)/scip/ - @-install -m 644 -p $(SRCDIR)/scip/scipdefplugins.h $(INSTALLDIR)/$(INCLUDEDIR)/scip/ --- -2.7.4 (Apple Git-66) - diff --git a/build/pkgs/scipoptsuite/patches/scip/0005-Use-new-variables-SCIP_LIBBUILDFLAGS-etc.patch b/build/pkgs/scipoptsuite/patches/scip/0004-Use-new-variables-SCIP_LIBBUILDFLAGS-etc.patch similarity index 55% rename from build/pkgs/scipoptsuite/patches/scip/0005-Use-new-variables-SCIP_LIBBUILDFLAGS-etc.patch rename to build/pkgs/scipoptsuite/patches/scip/0004-Use-new-variables-SCIP_LIBBUILDFLAGS-etc.patch index e4ed161bedb..e4cc9438a88 100644 --- a/build/pkgs/scipoptsuite/patches/scip/0005-Use-new-variables-SCIP_LIBBUILDFLAGS-etc.patch +++ b/build/pkgs/scipoptsuite/patches/scip/0004-Use-new-variables-SCIP_LIBBUILDFLAGS-etc.patch @@ -1,27 +1,27 @@ -From 274f5d7ebbda7080d45f4193c57dedb9e38e0bb6 Mon Sep 17 00:00:00 2001 +From 3fee3c4219a116c3f962848fcf2b12b81e833579 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Jul 2016 12:58:52 -0700 -Subject: [PATCH 5/5] Use new variables SCIP_LIBBUILDFLAGS etc. +Subject: [PATCH 4/5] Use new variables SCIP_LIBBUILDFLAGS etc. --- - Makefile | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) + Makefile | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile -index 7ee691a..ecf7eff 100644 +index d551556..103d89b 100644 --- a/Makefile +++ b/Makefile -@@ -949,7 +949,7 @@ makesciplibfile: preprocess - $(SCIPLIBFILE): $(SCIPLIBOBJFILES) $(LPILIBFILE) $(NLPILIBFILE) | $(LIBDIR) $(LIBOBJSUBDIRS) +@@ -1109,7 +1109,7 @@ libscip: preprocess + $(SCIPLIBFILE): $(SCIPLIBOBJFILES) $(LPILIBFILE) $(NLPILIBFILE) | $(LIBDIR)/$(LIBTYPE) $(LIBOBJSUBDIRS) @echo "-> generating library $@" -rm -f $@ -- $(LIBBUILD) $(LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(SCIPLIBOBJFILES) $(LPILIBFILE) $(NLPILIBFILE) -+ $(LIBBUILD) $(LIBBUILDFLAGS) $(SCIP_LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(SCIPLIBOBJFILES) $(LPILIBFILE) $(NLPILIBFILE) +- $(LIBBUILD) $(LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(SCIPLIBOBJFILES) $(SCIPLIBEXTLIBS) ++ $(LIBBUILD) $(LIBBUILDFLAGS) $(SCIP_LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(SCIPLIBOBJFILES) $(SCIPLIBEXTLIBS) + ifneq ($(RANLIB),) $(RANLIB) $@ - endif -@@ -957,7 +957,7 @@ endif - $(OBJSCIPLIBFILE): $(OBJSCIPLIBOBJFILES) | $(LIBOBJSUBDIRS) $(LIBDIR) +@@ -1122,7 +1122,7 @@ libobjscip: preprocess + $(OBJSCIPLIBFILE): $(OBJSCIPLIBOBJFILES) | $(LIBOBJSUBDIRS) $(LIBDIR)/$(LIBTYPE) @echo "-> generating library $@" -rm -f $@ - $(LIBBUILD) $(LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(OBJSCIPLIBOBJFILES) @@ -29,24 +29,33 @@ index 7ee691a..ecf7eff 100644 ifneq ($(RANLIB),) $(RANLIB) $@ endif -@@ -965,7 +965,7 @@ endif - $(LPILIBFILE): $(LPILIBOBJFILES) | $(LIBOBJSUBDIRS) $(LIBDIR) +@@ -1134,7 +1134,7 @@ liblpi: preprocess + $(LPILIBFILE): $(LPILIBOBJFILES) | $(LIBOBJSUBDIRS) $(LIBDIR)/$(LIBTYPE) @echo "-> generating library $@" -rm -f $@ -- $(LIBBUILD) $(LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(LPILIBOBJFILES) $(LPILIBS) -+ $(LIBBUILD) $(LIBBUILDFLAGS) $(LPI_LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(LPILIBOBJFILES) $(LPILIBS) +- $(LIBBUILD) $(LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(LPILIBOBJFILES) $(LPILIBEXTLIBS) ++ $(LIBBUILD) $(LIBBUILDFLAGS) $(LPI_LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(LPILIBOBJFILES) $(LPILIBEXTLIBS) ifneq ($(RANLIB),) $(RANLIB) $@ endif -@@ -973,7 +973,7 @@ endif - $(NLPILIBFILE): $(NLPILIBOBJFILES) $(NLPILIBSCIPOBJFILES) | $(LIBOBJSUBDIRS) $(LIBDIR) +@@ -1146,7 +1146,7 @@ libnlpi: preprocess + $(NLPILIBFILE): $(NLPILIBOBJFILES) $(NLPILIBSCIPOBJFILES) | $(LIBOBJSUBDIRS) $(LIBDIR)/$(LIBTYPE) @echo "-> generating library $@" -rm -f $@ -- $(LIBBUILD) $(LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(NLPILIBOBJFILES) $(NLPILIBSCIPOBJFILES) +- $(LIBBUILD) $(LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(NLPILIBOBJFILES) $(NLPILIBSCIPOBJFILES) $(NLPILIBEXTLIBS) + $(LIBBUILD) $(LIBBUILDFLAGS) $(NLPI_LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(NLPILIBOBJFILES) $(NLPILIBSCIPOBJFILES) ifneq ($(RANLIB),) $(RANLIB) $@ endif +@@ -1158,7 +1158,7 @@ libtpi: preprocess + $(TPILIBFILE): $(TPILIBOBJFILES) | $(LIBOBJSUBDIRS) $(LIBDIR)/$(LIBTYPE) + @echo "-> generating library $@" + -rm -f $@ +- $(LIBBUILD) $(LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(TPILIBOBJFILES) ++ $(LIBBUILD) $(LIBBUILDFLAGS) $(TPI_LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(TPILIBOBJFILES) + ifneq ($(RANLIB),) + $(RANLIB) $@ + endif -- 2.7.4 (Apple Git-66) diff --git a/build/pkgs/scipoptsuite/patches/scip/0005-Add-TPI-to-the-library-dependencies.patch b/build/pkgs/scipoptsuite/patches/scip/0005-Add-TPI-to-the-library-dependencies.patch new file mode 100644 index 00000000000..32d7d1b3d78 --- /dev/null +++ b/build/pkgs/scipoptsuite/patches/scip/0005-Add-TPI-to-the-library-dependencies.patch @@ -0,0 +1,25 @@ +From 77a5582c685616437b7982d1be4203c4d0fb8758 Mon Sep 17 00:00:00 2001 +From: Matthias Koeppe +Date: Thu, 16 Mar 2017 18:37:43 -0700 +Subject: [PATCH 5/5] Add TPI to the library dependencies + +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 103d89b..6a310e9 100644 +--- a/Makefile ++++ b/Makefile +@@ -422,7 +422,7 @@ SCIPLIBEXTLIBS += $(READLINE_LDFLAGS) + endif + SCIPLIBEXTLIBS += $(ZIMPLLIB) $(LINKRPATH)$(realpath $(LIBDIR)/$(LIBTYPE)) + endif +-SCIPLIBEXTLIBS += $(LPILIBFILE) $(NLPILIBFILE) ++SCIPLIBEXTLIBS += $(LPILIBFILE) $(NLPILIBFILE) $(TPILIBFILE) + + #----------------------------------------------------------------------------- + # SCIP Library +-- +2.7.4 (Apple Git-66) + diff --git a/build/pkgs/scipoptsuite/spkg-install b/build/pkgs/scipoptsuite/spkg-install index f9ebe9677d8..4d3e222bb6d 100755 --- a/build/pkgs/scipoptsuite/spkg-install +++ b/build/pkgs/scipoptsuite/spkg-install @@ -114,9 +114,10 @@ cd $SRC/$SCIP_DIR mkdir lib cd lib -ln -sv $SRC/$SOPLEX_DIR/lib/libsoplex-$SOPLEX_VERSION.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT libsoplex.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT -ln -sv $SRC/$SOPLEX_DIR/src/ spxinc -touch libsoplex.$OS.$ARCH.gnu.$OPT.a +mkdir -p shared static include +ln -sv $SRC/$SOPLEX_DIR/lib/libsoplex-$SOPLEX_VERSION.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT shared/libsoplex.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT +ln -sv $SRC/$SOPLEX_DIR/src/ include/spxinc +touch static/libsoplex.$OS.$ARCH.gnu.$OPT.a echo "Compiling SCIP" @@ -125,13 +126,15 @@ if [ `uname` = 'Darwin' ] ; then arg_LIBBUILDFLAGS=LIBBUILDFLAGS="$LDFLAGS -dynamiclib -undefined dynamic_lookup -flat_namespace" SCIP_LIBBUILDFLAGS="-Wl,-install_name,$SAGE_LOCAL/lib/libscip-$SCIP_VERSION.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT" OBJSCIP_LIBBUILDFLAGS="-Wl,-install_name,$SAGE_LOCAL/lib/libobjscip-$SCIP_VERSION.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT" - LPI_LIBBUILDFLAGS="-Wl,-install_name,$SAGE_LOCAL/lib/liblpispx-$SCIP_VERSION.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT" + LPI_LIBBUILDFLAGS="-Wl,-install_name,$SAGE_LOCAL/lib/liblpispx2-$SCIP_VERSION.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT" NLPI_LIBBUILDFLAGS="-Wl,-install_name,$SAGE_LOCAL/lib/libnlpi.cppad-$SCIP_VERSION.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT" + TPI_LIBBUILDFLAGS="-Wl,-install_name,$SAGE_LOCAL/lib/libtpinone-$SCIP_VERSION.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT" else SCIP_LIBBUILDFLAGS="-Wl,-soname=$SAGE_LOCAL/lib/libscip-$SCIP_VERSION.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT" OBJSCIP_LIBBUILDFLAGS="-Wl,-soname=$SAGE_LOCAL/lib/libobjscip-$SCIP_VERSION.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT" - LPI_LIBBUILDFLAGS="-Wl,-soname=$SAGE_LOCAL/lib/liblpispx-$SCIP_VERSION.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT" + LPI_LIBBUILDFLAGS="-Wl,-soname=$SAGE_LOCAL/lib/liblpispx2-$SCIP_VERSION.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT" NLPI_LIBBUILDFLAGS="-Wl,-soname=$SAGE_LOCAL/lib/libnlpi.cppad-$SCIP_VERSION.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT" + TPI_LIBBUILDFLAGS="-Wl,-soname=$SAGE_LOCAL/lib/libtpinone-$SCIP_VERSION.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT" fi cd $SRC/$SCIP_DIR @@ -145,7 +148,8 @@ $MAKE OPT=$OPT LPSOPT=$OPT VERBOSE=true SHARED=true ZIMPL=false GMP=true ZLIB=tr OBJSCIP_LIBBUILDFLAGS=$OBJSCIP_LIBBUILDFLAGS \ LPI_LIBBUILDFLAGS=$LPI_LIBBUILDFLAGS \ NLPI_LIBBUILDFLAGS=$NLPI_LIBBUILDFLAGS \ - SHAREDLIBEXT="$SHAREDLIBEXT" INSTALLDIR="$SAGE_LOCAL" LINKRPATH="" install + TPI_LIBBUILDFLAGS=$TPI_LIBBUILDFLAGS \ + SHAREDLIBEXT="$SHAREDLIBEXT" INSTALLDIR="$SAGE_LOCAL" install if [ $? -ne 0 ]; then echo "Error building/installing SCIP." exit 1 From 75fb34c33e866a1d1acba3bb1beaa1cb796588be Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 18 Mar 2017 08:48:43 -0700 Subject: [PATCH 163/185] Use OPT=opt on Linux. Check results of test suite --- build/pkgs/scipoptsuite/spkg-check | 13 +++++++++++-- build/pkgs/scipoptsuite/spkg-install | 12 ++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/build/pkgs/scipoptsuite/spkg-check b/build/pkgs/scipoptsuite/spkg-check index 1893c213317..36ada5fced6 100755 --- a/build/pkgs/scipoptsuite/spkg-check +++ b/build/pkgs/scipoptsuite/spkg-check @@ -8,12 +8,21 @@ fi cd src +# Choice of OPT should be consistent with spkg-install +OPT=opt +if [ `uname` = 'Darwin' ] ; then + OPT=dbg +fi + echo "Now running the SCIP test suite..." # Do the tests with the installed version of SCIP. # (The uninstalled ones do not work because we did not adjust their library dependencies.) -$MAKE check OPT=dbg MAINFILE=$SAGE_LOCAL/bin/scip +$MAKE check OPT=$OPT MAINFILE="$SAGE_LOCAL"/bin/scip | tee testsuite.log if [ $? -ne 0 ]; then + echo >&2 "Error: The SCIP test suite failed with an error status." + exit 1 +fi +if grep -q fail testsuite.log ; then echo >&2 "Error: The SCIP test suite failed." exit 1 fi -echo "Review the above table regarding the outcome of the SCIP test suite." diff --git a/build/pkgs/scipoptsuite/spkg-install b/build/pkgs/scipoptsuite/spkg-install index 4d3e222bb6d..8ea8aebfb83 100755 --- a/build/pkgs/scipoptsuite/spkg-install +++ b/build/pkgs/scipoptsuite/spkg-install @@ -74,16 +74,16 @@ sage-apply-patches $SPKGDIR/patches/scip || exit $? echo "Compiling SoPlex" -#OPT=opt -# The compiler flags that come with "OPT=opt" on Mac OS X lead to a segfault in SCIP during a call to Soplex. ("stack_not_16_byte_aligned_error") -OPT=dbg -# instead supply some of our own optimization flags -CFLAGS="$CFLAGS -O3" -CXXFLAGS="$CXXFLAGS -O3" +OPT=opt arg_LIBBUILDFLAGS=UNUSED= if [ `uname` = 'Darwin' ] ; then + # The compiler flags that come with "OPT=opt" on Mac OS X lead to a segfault in SCIP during a call to Soplex. ("stack_not_16_byte_aligned_error") + OPT=dbg + # instead supply some of our own optimization flags + CFLAGS="$CFLAGS -O3" + CXXFLAGS="$CXXFLAGS -O3" SHAREDLIBEXT="dylib" # regarding "-undefined dynamic_lookup" see https://trac.macports.org/ticket/44596 arg_LIBBUILDFLAGS=LIBBUILDFLAGS="$LDFLAGS -dynamiclib -undefined dynamic_lookup -flat_namespace -install_name $SAGE_LOCAL/lib/libsoplex-$SOPLEX_VERSION.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT -lgmp -lz" From 74f1d792480b7f792292aa05705daa4a56d143f4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 18 Mar 2017 19:42:26 -0700 Subject: [PATCH 164/185] scip: Working configuration for clang on Mac --- build/pkgs/scipoptsuite/spkg-install | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/build/pkgs/scipoptsuite/spkg-install b/build/pkgs/scipoptsuite/spkg-install index 8ea8aebfb83..9f50becff6a 100755 --- a/build/pkgs/scipoptsuite/spkg-install +++ b/build/pkgs/scipoptsuite/spkg-install @@ -79,11 +79,8 @@ OPT=opt arg_LIBBUILDFLAGS=UNUSED= if [ `uname` = 'Darwin' ] ; then - # The compiler flags that come with "OPT=opt" on Mac OS X lead to a segfault in SCIP during a call to Soplex. ("stack_not_16_byte_aligned_error") - OPT=dbg - # instead supply some of our own optimization flags - CFLAGS="$CFLAGS -O3" - CXXFLAGS="$CXXFLAGS -O3" + CFLAGS="$CFLAGS -O3 -DTHREADLOCAL=" + CXXFLAGS="$CXXFLAGS -O3 -DTHREADLOCAL=" SHAREDLIBEXT="dylib" # regarding "-undefined dynamic_lookup" see https://trac.macports.org/ticket/44596 arg_LIBBUILDFLAGS=LIBBUILDFLAGS="$LDFLAGS -dynamiclib -undefined dynamic_lookup -flat_namespace -install_name $SAGE_LOCAL/lib/libsoplex-$SOPLEX_VERSION.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT -lgmp -lz" From 0f376581d42e4b299e8d6acdf6ec45fce5fbfb96 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 19 Mar 2017 13:41:44 -0700 Subject: [PATCH 165/185] scipoptsuite: Use clang on Mac OS --- build/pkgs/scipoptsuite/spkg-install | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/build/pkgs/scipoptsuite/spkg-install b/build/pkgs/scipoptsuite/spkg-install index 9f50becff6a..789534bde89 100755 --- a/build/pkgs/scipoptsuite/spkg-install +++ b/build/pkgs/scipoptsuite/spkg-install @@ -79,8 +79,15 @@ OPT=opt arg_LIBBUILDFLAGS=UNUSED= if [ `uname` = 'Darwin' ] ; then - CFLAGS="$CFLAGS -O3 -DTHREADLOCAL=" - CXXFLAGS="$CXXFLAGS -O3 -DTHREADLOCAL=" + # Using the GCC 5.4.0 shipped with Sage leads to segmentation fault. + # Override. + CXX=g++ + PATH=/usr/bin:$PATH + if [ -d "$SAGE_LOCAL/libexec/ccache" ]; then + PATH="$SAGE_LOCAL/libexec/ccache:$PATH" + fi + CFLAGS="-DTHREADLOCAL=" + CXXFLAGS="-DTHREADLOCAL=" SHAREDLIBEXT="dylib" # regarding "-undefined dynamic_lookup" see https://trac.macports.org/ticket/44596 arg_LIBBUILDFLAGS=LIBBUILDFLAGS="$LDFLAGS -dynamiclib -undefined dynamic_lookup -flat_namespace -install_name $SAGE_LOCAL/lib/libsoplex-$SOPLEX_VERSION.$OS.$ARCH.gnu.$OPT.$SHAREDLIBEXT -lgmp -lz" @@ -93,7 +100,8 @@ cd $SRC/$SOPLEX_DIR ## The Makefile in soplex 2.2.1 forgets to add the library dependencies ## "-lgmp -lz", causing the link to fail on Mac OS X. LIBBUILDFLAGS="-lgmp -lz -lreadline" -$MAKE VERBOSE=true OPT=$OPT ZLIB=true READLINE=true SHARED=true USRCFLAGS="$CFLAGS" USRCXXFLAGS="$CXXFLAGS" USRLDFLAGS="$LDFLAGS" "$arg_LIBBUILDFLAGS" SHAREDLIBEXT="$SHAREDLIBEXT" INSTALLDIR="$SAGE_LOCAL" install +# Put -Llib first, or otherwise the build will try link the soplex binary against an installed libsoplex from $SAGE_LOCAL/lib. +$MAKE VERBOSE=true OPT=$OPT ZLIB=true READLINE=true SHARED=true CXX="$CXX" USRCFLAGS="$CFLAGS" USRCXXFLAGS="$CXXFLAGS" USRLDFLAGS="-Llib $LDFLAGS" "$arg_LIBBUILDFLAGS" SHAREDLIBEXT="$SHAREDLIBEXT" INSTALLDIR="$SAGE_LOCAL" install if [ $? -ne 0 ]; then echo "Error building SOPLEX." From d64bcd5e4c123eda9c2bc2f60fce1c1624262e4c Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Mon, 20 Mar 2017 14:39:50 +0100 Subject: [PATCH 166/185] Make inherit_comparison.pyx compatible with Python 3 --- src/sage/misc/inherit_comparison.pyx | 8 +++++--- src/sage/misc/inherit_comparison_impl.c | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 src/sage/misc/inherit_comparison_impl.c diff --git a/src/sage/misc/inherit_comparison.pyx b/src/sage/misc/inherit_comparison.pyx index 5e14e08f85a..67d05404416 100644 --- a/src/sage/misc/inherit_comparison.pyx +++ b/src/sage/misc/inherit_comparison.pyx @@ -38,6 +38,10 @@ AUTHOR: from cpython.object cimport PyTypeObject from sage.misc.classcall_metaclass cimport ClasscallMetaclass +cdef extern from "inherit_comparison_impl.c": + void inherit_comparison(PyTypeObject* dst, PyTypeObject* src) + + cdef class InheritComparisonMetaclass(type): """ If the type does not define ``__richcmp__`` nor ``__cmp__``, @@ -78,9 +82,7 @@ cdef class InheritComparisonMetaclass(type): cdef PyTypeObject* t = self cdef PyTypeObject* b = t.tp_base if b: - if not t.tp_richcompare and not t.tp_compare: - t.tp_richcompare = b.tp_richcompare - t.tp_compare = b.tp_compare + inherit_comparison(t, b) super(InheritComparisonMetaclass, self).__init__(*args) class InheritComparisonClasscallMetaclass(InheritComparisonMetaclass, ClasscallMetaclass): diff --git a/src/sage/misc/inherit_comparison_impl.c b/src/sage/misc/inherit_comparison_impl.c new file mode 100644 index 00000000000..f12dc2a6976 --- /dev/null +++ b/src/sage/misc/inherit_comparison_impl.c @@ -0,0 +1,21 @@ +/* + * Copy comparison methods from type "src" to type "dst" if "dst" has + * no comparison defined. + * + * This is implemented in pure C instead of Cython because it needs to + * be different in Python 2 and Python 3. + */ +static CYTHON_INLINE void inherit_comparison(PyTypeObject* dst, const PyTypeObject* src) +{ + /* Do nothing if "dst" already has comparison defined */ +#if (PY_MAJOR_VERSION < 3) + if (dst->tp_compare) return; +#endif + if (dst->tp_richcompare) return; + + /* Copy comparison method(s) */ +#if (PY_MAJOR_VERSION < 3) + dst->tp_compare = src->tp_compare; +#endif + dst->tp_richcompare = src->tp_richcompare; +} From a8b5ccf3856915631b8f391ad315347dcd60aec2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 20 Mar 2017 14:56:54 -0700 Subject: [PATCH 167/185] Update patch to get libtpinone makefile dependency right --- ...05-Add-TPI-to-the-library-dependencies.patch | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/build/pkgs/scipoptsuite/patches/scip/0005-Add-TPI-to-the-library-dependencies.patch b/build/pkgs/scipoptsuite/patches/scip/0005-Add-TPI-to-the-library-dependencies.patch index 32d7d1b3d78..47feb23e6ae 100644 --- a/build/pkgs/scipoptsuite/patches/scip/0005-Add-TPI-to-the-library-dependencies.patch +++ b/build/pkgs/scipoptsuite/patches/scip/0005-Add-TPI-to-the-library-dependencies.patch @@ -1,14 +1,14 @@ -From 77a5582c685616437b7982d1be4203c4d0fb8758 Mon Sep 17 00:00:00 2001 +From 1ca7c0504ea4caa678e13eb238d6bae7a705d26e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 16 Mar 2017 18:37:43 -0700 Subject: [PATCH 5/5] Add TPI to the library dependencies --- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile -index 103d89b..6a310e9 100644 +index 103d89b..35a0224 100644 --- a/Makefile +++ b/Makefile @@ -422,7 +422,7 @@ SCIPLIBEXTLIBS += $(READLINE_LDFLAGS) @@ -20,6 +20,15 @@ index 103d89b..6a310e9 100644 #----------------------------------------------------------------------------- # SCIP Library +@@ -1106,7 +1106,7 @@ endif + libscip: preprocess + @$(MAKE) $(SCIPLIBFILE) $(SCIPLIBLINK) $(SCIPLIBSHORTLINK) + +-$(SCIPLIBFILE): $(SCIPLIBOBJFILES) $(LPILIBFILE) $(NLPILIBFILE) | $(LIBDIR)/$(LIBTYPE) $(LIBOBJSUBDIRS) ++$(SCIPLIBFILE): $(SCIPLIBOBJFILES) $(LPILIBFILE) $(NLPILIBFILE) $(TPILIBFILE) | $(LIBDIR)/$(LIBTYPE) $(LIBOBJSUBDIRS) + @echo "-> generating library $@" + -rm -f $@ + $(LIBBUILD) $(LIBBUILDFLAGS) $(SCIP_LIBBUILDFLAGS) $(LIBBUILD_o)$@ $(SCIPLIBOBJFILES) $(SCIPLIBEXTLIBS) -- 2.7.4 (Apple Git-66) From cbe9bf269788ebda128a37a076a4a488cf03efd7 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Tue, 21 Mar 2017 02:33:40 -0500 Subject: [PATCH 168/185] Last little bit of Cython optimization. --- .../root_system/reflection_group_element.pyx | 75 ++++++++++--------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/src/sage/combinat/root_system/reflection_group_element.pyx b/src/sage/combinat/root_system/reflection_group_element.pyx index 1feaf9e326c..3edbc31d8b3 100644 --- a/src/sage/combinat/root_system/reflection_group_element.pyx +++ b/src/sage/combinat/root_system/reflection_group_element.pyx @@ -51,7 +51,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): .. SEEALSO:: :meth:`reduced_word_in_reflections` """ - I = self.parent()._index_set + I = self._parent._index_set return [I[i] for i in self._reduced_word] @lazy_attribute @@ -66,7 +66,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): sage: w._reduced_word # optional - gap3 [0] """ - W = self.parent() + W = self._parent gens = [W.simple_reflection(j) for j in W._index_set] return _gap_factorization(self, gens) @@ -86,10 +86,10 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): if self.is_one(): return [] - W = self.parent() + W = self._parent gens = [W.reflection(j) for j in W._reflection_index_set] word = _gap_factorization(self, gens) - return [self.parent()._reflection_index_set[i] for i in word] + return [self._parent._reflection_index_set[i] for i in word] def length(self): r""" @@ -238,13 +238,13 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): [ 0 E(3)^2], [ 0 E(3)] ] """ - W = self.parent() + W = self._parent if W._reflection_representation is None: mat = self.canonical_matrix() else: refl_repr = W._reflection_representation id_mat = identity_matrix(QQ, refl_repr[W.index_set()[0]].nrows()) - mat = prod([refl_repr[i] for i in self.reduced_word()], id_mat) + mat = prod((refl_repr[i] for i in self.reduced_word()), id_mat) if on_space == "primal": pass @@ -287,11 +287,10 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): [ 0 -1] [-1 0] """ - W = self.parent() + W = self._parent Phi = W.roots() - inds = [W._index_set_inverse[i] for i in W.independent_roots().keys()] - M = Matrix([Phi[self.perm[i]] for i in inds]) - mat = W.base_change_matrix() * M + cdef list inds = [W._index_set_inverse[i] for i in W.independent_roots().keys()] + mat = W.base_change_matrix() * Matrix([Phi[self.perm[i]] for i in inds]) mat.set_immutable() return mat @@ -403,7 +402,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): sage: all(sorted([w.action_on_root(beta) for beta in Phi]) == Phi for w in W) # optional - gap3 True """ - Phi = self.parent().roots() + Phi = self._parent.roots() return Phi[self.action_on_root_indices(Phi.index(root))] def to_permutation_of_roots(self): @@ -473,7 +472,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): [0 1 0] [0 0 1] """ - I = identity_matrix(QQ, self.parent().rank()) + I = identity_matrix(QQ, self._parent.rank()) return (self.to_matrix() - I).right_kernel() #@cached_in_parent_method @@ -516,7 +515,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): [1/2, 1/2] [1/4, 3/4] """ - return self.parent().reflection_eigenvalues(self, is_class_representative=is_class_representative) + return self._parent.reflection_eigenvalues(self, is_class_representative=is_class_representative) #@cached_in_parent_method def galois_conjugates(self): @@ -616,11 +615,12 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): [ 1/3*E(3) - 1/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2] [-2/3*E(3) + 2/3*E(3)^2 -1/3*E(3) + 1/3*E(3)^2]] """ - rk = self.parent().rank() + rk = self._parent.rank() M = self.to_matrix().list() m = lcm([x.conductor() if hasattr(x,"conductor") else 1 for x in M]) - M_gals = [x.galois_conjugates(m) if hasattr(x,"galois_conjugates") else [x] for x in M] - conjugates = [] + cdef list M_gals = [x.galois_conjugates(m) if hasattr(x,"galois_conjugates") else [x] for x in M] + cdef list conjugates = [] + cdef int i for i in xrange(len(M_gals[0])): conjugates.append(Matrix(rk, [X[i] for X in M_gals])) return conjugates @@ -638,7 +638,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): sage: [w._reduced_word for w in W] # optional - gap3 [[], [1], [0], [0, 1], [1, 0], [0, 1, 0]] """ - return reduced_word_c(self.parent(),self) + return reduced_word_c(self._parent, self) def reduced_word_in_reflections(self): r""" @@ -660,14 +660,15 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): if self.is_one(): return [] - W = self.parent() + W = self._parent r = self.reflection_length() R = W.reflections() I = W.reflection_index_set() cdef list word = [] + cdef RealReflectionGroupElement w while r > 0: for i in I: - w = R[i]._mul_(self) + w = (R[i]._mul_(self)) if w.reflection_length() < r: word.append(i) r -= 1 @@ -712,7 +713,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): sage: (s[1]*s[2]).has_left_descent(2) # optional - gap3 False """ - W = self.parent() + W = self._parent # we also check == because 0-based indexing return self.perm[W._index_set_inverse[i]] >= W.number_of_reflections() @@ -741,7 +742,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): if not isinstance(positive, bool): raise TypeError("%s is not a boolean"%(bool)) - if i not in self.parent().index_set(): + if i not in self._parent.index_set(): raise ValueError("the given index %s is not in the index set"%i) negative = not positive @@ -811,7 +812,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): sage: all(w.to_matrix(side="right") == W.from_reduced_word(reversed(w.reduced_word())).to_matrix(side="left").transpose() for w in W) # optional - gap3 True """ - W = self.parent() + W = self._parent cdef RealReflectionGroupElement w if W._reflection_representation is None: if side == "left": @@ -820,15 +821,11 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): w = (self) else: raise ValueError('side must be "left" or "right"') - - Delta = W.independent_roots() - Phi = W.roots() - M = Matrix([Phi[w.perm[Phi.index(alpha)]] for alpha in Delta]) - mat = W.base_change_matrix() * M + mat = w.canonical_matrix() else: refl_repr = W._reflection_representation id_mat = identity_matrix(QQ, refl_repr[W.index_set()[0]].nrows()) - mat = prod([refl_repr[i] for i in self.reduced_word()], id_mat) + mat = prod((refl_repr[i] for i in self.reduced_word()), id_mat) if on_space == "primal": if side == "left": @@ -885,7 +882,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): ....: for w in W for alpha in W.simple_roots()) # optional - gap3 True """ - W = self.parent() + W = self._parent n = W.rank() Phi = W.roots() cdef RealReflectionGroupElement w @@ -895,6 +892,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): w = (~self) else: raise ValueError('side must be "left" or "right"') + cdef int j ret = Phi[0].parent().zero() if on_space == "primal": for j in xrange(n): @@ -966,13 +964,14 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): sage: [w.action_on_root_indices(i,side="left") for i in range(N)] # optional - gap3 [4, 3, 5, 1, 0, 2] """ + cdef RealReflectionGroupElement w if side == "right": w = self elif side == "left": - w = ~self + w = (~self) else: raise ValueError('side must be "left" or "right"') - return (w).perm[i] + return w.perm[i] def action_on_root(self, root, side="right"): r""" @@ -1009,7 +1008,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): [2, 1] [(0, 1), (-1, -1), (-1, 0)] [1, 2, 1] [(0, -1), (-1, 0), (-1, -1)] """ - Phi = self.parent().roots() + Phi = self._parent.roots() return Phi[self.action_on_root_indices(Phi.index(root), side=side)] def inversion_set(self, side="right"): @@ -1034,10 +1033,14 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): sage: W.from_reduced_word([1,2]).inversion_set(side="left") # optional - gap3 [(0, 1), (1, 1)] """ - N = self.parent().number_of_reflections() - Phi = self.parent().roots() - return [Phi[i] for i in range(N) - if self.action_on_root_indices(i, side=side) >= N] + N = self._parent.number_of_reflections() + Phi = self._parent.roots() + cdef int i + if side == "left": + self = (~self) + elif side != "right": + raise ValueError('side must be "left" or "right"') + return [Phi[i] for i in xrange(N) if self.perm[i] >= N] def _gap_factorization(w, gens): r""" From f83541403e90cfc895fc3781f9f5a0780e1acf93 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 5 Jan 2017 15:54:18 +0100 Subject: [PATCH 169/185] Update SAGERUNTIME dependencies --- build/make/deps | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/make/deps b/build/make/deps index cc14493b767..ee353fc151b 100644 --- a/build/make/deps +++ b/build/make/deps @@ -78,7 +78,8 @@ toolchain-deps: # Everything needed to start up Sage using "./sage". Of course, not # every part of Sage will work. It does not include Maxima for example. -SAGERUNTIME = sagelib $(SCRIPTS) $(inst_ipython) $(inst_pexpect) $(inst_psutil) +SAGERUNTIME = sagelib $(SCRIPTS) $(inst_ipython) $(inst_pexpect) \ + $(inst_psutil) $(inst_future) sageruntime: all-toolchain $(MAKE) $(SAGERUNTIME) From 769d635266ab2cd061ce877c58cbc7ea6465ce48 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Tue, 21 Mar 2017 10:05:46 +0100 Subject: [PATCH 170/185] Lazy import catalogs in homology --- src/sage/homology/all.py | 7 +++---- src/sage/tests/startup.py | 2 ++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sage/homology/all.py b/src/sage/homology/all.py index 511ad4d122b..fb08ed85730 100644 --- a/src/sage/homology/all.py +++ b/src/sage/homology/all.py @@ -1,4 +1,5 @@ from __future__ import absolute_import + from .chain_complex import ChainComplex from .chain_complex_morphism import ChainComplexMorphism @@ -7,13 +8,11 @@ from .simplicial_complex_morphism import SimplicialComplexMorphism -from . import simplicial_complexes_catalog as simplicial_complexes - from .delta_complex import DeltaComplex, delta_complexes from .cubical_complex import CubicalComplex, cubical_complexes from sage.misc.lazy_import import lazy_import lazy_import('sage.homology.koszul_complex', 'KoszulComplex') - -from . import simplicial_set_catalog as simplicial_sets +lazy_import('sage.homology', 'simplicial_complexes_catalog', 'simplicial_complexes') +lazy_import('sage.homology', 'simplicial_set_catalog', 'simplicial_sets') diff --git a/src/sage/tests/startup.py b/src/sage/tests/startup.py index 2fe80e03f56..0d0ddd87321 100644 --- a/src/sage/tests/startup.py +++ b/src/sage/tests/startup.py @@ -5,6 +5,8 @@ sage: 'numpy' in sys.modules False + sage: 'pyparsing' in sys.modules + False sage: 'sage.libs.gap.libgap' in sys.modules False From 5eabe46ca0f929e8e09f0b90e295a0300afe3750 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Tue, 21 Mar 2017 10:51:56 +0100 Subject: [PATCH 171/185] Make coverage script happy --- src/sage/docs/instancedoc.pyx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/sage/docs/instancedoc.pyx b/src/sage/docs/instancedoc.pyx index f9d7e035563..9e50e9abea5 100644 --- a/src/sage/docs/instancedoc.pyx +++ b/src/sage/docs/instancedoc.pyx @@ -122,10 +122,29 @@ cdef class InstanceDocDescriptor: cdef instancedoc def __init__(self, classdoc, instancedoc): + """ + TESTS:: + + sage: from sage.docs.instancedoc import InstanceDocDescriptor + sage: InstanceDocDescriptor(None, None) + + """ self.classdoc = classdoc self.instancedoc = instancedoc def __get__(self, obj, typ): + """ + TESTS:: + + sage: from sage.docs.instancedoc import InstanceDocDescriptor + sage: def instancedoc(self): + ....: return "Doc for {!r}".format(self) + sage: descr = InstanceDocDescriptor("Class doc", instancedoc) + sage: descr.__get__(None, object) + 'Class doc' + sage: descr.__get__(42, type(42)) + 'Doc for 42' + """ if obj is None: return self.classdoc else: From 98358f719ef9d712b2515f81389548a669242dd6 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Tue, 21 Mar 2017 17:02:43 +0100 Subject: [PATCH 172/185] Move unpickle override to all.py --- src/sage/homology/all.py | 5 +++++ src/sage/homology/examples.py | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/homology/all.py b/src/sage/homology/all.py index fb08ed85730..991bec41fce 100644 --- a/src/sage/homology/all.py +++ b/src/sage/homology/all.py @@ -16,3 +16,8 @@ lazy_import('sage.homology.koszul_complex', 'KoszulComplex') lazy_import('sage.homology', 'simplicial_complexes_catalog', 'simplicial_complexes') lazy_import('sage.homology', 'simplicial_set_catalog', 'simplicial_sets') + + +# For taking care of old pickles +from sage.structure.sage_object import register_unpickle_override +register_unpickle_override('sage.homology.examples', 'SimplicialSurface', SimplicialComplex) diff --git a/src/sage/homology/examples.py b/src/sage/homology/examples.py index a7c1821c7ba..057e9f47804 100644 --- a/src/sage/homology/examples.py +++ b/src/sage/homology/examples.py @@ -1544,8 +1544,3 @@ def DunceHat(): [1,5,6], [4,5,6], [4,6,8], [6,7,8], [2,3,8]], name="Minimal triangulation of the dunce hat" ) - - -# For taking care of old pickles -from sage.structure.sage_object import register_unpickle_override -register_unpickle_override('sage.homology.examples', 'SimplicialSurface', SimplicialComplex) From f92c25856bd33edfe0b157f9504c2d5a73d4caac Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 22 Mar 2017 16:58:27 +0100 Subject: [PATCH 173/185] Doctest an example where _instancedoc_ is not defined --- src/sage/docs/instancedoc.pyx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sage/docs/instancedoc.pyx b/src/sage/docs/instancedoc.pyx index 9e50e9abea5..d83f86438ad 100644 --- a/src/sage/docs/instancedoc.pyx +++ b/src/sage/docs/instancedoc.pyx @@ -171,10 +171,18 @@ def InstanceDoc(cls): TESTS: + We get a useful error message if ``_instancedoc_`` is not defined:: + + sage: from sage.docs.instancedoc import InstanceDoc + sage: class X(object): pass + sage: InstanceDoc(X) + Traceback (most recent call last): + ... + AttributeError: type object 'X' has no attribute '_instancedoc_' + This does not work on old-style classes or things which are not a class at all:: - sage: from sage.docs.instancedoc import InstanceDoc sage: InstanceDoc(7) Traceback (most recent call last): ... From 676a80428a980b326a936a42759ff3ba88398f27 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 22 Mar 2017 17:02:50 +0100 Subject: [PATCH 174/185] Rename InstanceDoc -> instancedoc --- src/sage/docs/instancedoc.pyx | 34 +++++++++++++------------- src/sage/interfaces/axiom.py | 8 +++--- src/sage/interfaces/expect.py | 8 +++--- src/sage/interfaces/fricas.py | 8 +++--- src/sage/interfaces/gap.py | 10 ++++---- src/sage/interfaces/giac.py | 8 +++--- src/sage/interfaces/gp.py | 4 +-- src/sage/interfaces/interface.py | 8 +++--- src/sage/interfaces/kash.py | 4 +-- src/sage/interfaces/lie.py | 8 +++--- src/sage/interfaces/lisp.py | 8 +++--- src/sage/interfaces/macaulay2.py | 6 ++--- src/sage/interfaces/magma.py | 8 +++--- src/sage/interfaces/maple.py | 8 +++--- src/sage/interfaces/mathematica.py | 8 +++--- src/sage/interfaces/matlab.py | 4 +-- src/sage/interfaces/maxima.py | 6 ++--- src/sage/interfaces/maxima_abstract.py | 4 +-- src/sage/interfaces/maxima_lib.py | 6 ++--- src/sage/interfaces/mupad.py | 8 +++--- src/sage/interfaces/octave.py | 4 +-- src/sage/interfaces/qepcad.py | 4 +-- src/sage/interfaces/r.py | 8 +++--- src/sage/interfaces/sage0.py | 6 ++--- src/sage/interfaces/scilab.py | 4 +-- src/sage/interfaces/singular.py | 8 +++--- src/sage/libs/gap/element.pyx | 6 ++--- src/sage/libs/singular/function.pyx | 8 +++--- src/sage/misc/cachefunc.pyx | 14 +++++------ src/sage/misc/lazy_import.pyx | 4 +-- src/sage/parallel/decorate.py | 4 +-- src/sage/sets/set_from_iterator.py | 8 +++--- src/sage/symbolic/maxima_wrapper.py | 4 +-- src/sage/symbolic/units.py | 4 +-- 34 files changed, 126 insertions(+), 126 deletions(-) diff --git a/src/sage/docs/instancedoc.pyx b/src/sage/docs/instancedoc.pyx index d83f86438ad..d209d14737b 100644 --- a/src/sage/docs/instancedoc.pyx +++ b/src/sage/docs/instancedoc.pyx @@ -10,20 +10,20 @@ method. In order to use this, define a class docstring as usual. Also define a method ``def _instancedoc_(self)`` which should return the docstring of -the instance ``self``. Finally, add the decorator ``@InstanceDoc`` to +the instance ``self``. Finally, add the decorator ``@instancedoc`` to the class. .. WARNING:: Since the ``__doc__`` attribute is never inherited, the decorator - ``@InstanceDoc`` must be added to all subclasses of the class + ``@instancedoc`` must be added to all subclasses of the class defining ``_instancedoc_``. Doing it on the base class is not sufficient. EXAMPLES:: - sage: from sage.docs.instancedoc import InstanceDoc - sage: @InstanceDoc + sage: from sage.docs.instancedoc import instancedoc + sage: @instancedoc ....: class X(object): ....: "Class docstring" ....: def _instancedoc_(self): @@ -34,15 +34,15 @@ EXAMPLES:: 'Instance docstring' For a Cython ``cdef class``, a decorator cannot be used. Instead, call -:func:`InstanceDoc` as a function after defining the class:: +:func:`instancedoc` as a function after defining the class:: sage: cython(''' - ....: from sage.docs.instancedoc import InstanceDoc + ....: from sage.docs.instancedoc import instancedoc ....: cdef class Y: ....: "Class docstring" ....: def _instancedoc_(self): ....: return "Instance docstring" - ....: InstanceDoc(Y) + ....: instancedoc(Y) ....: ''') sage: Y.__doc__ 'File:...\nClass docstring' @@ -52,9 +52,9 @@ For a Cython ``cdef class``, a decorator cannot be used. Instead, call TESTS: Check that inheritance works (after passing the subclass to -:func:`InstanceDoc`):: +:func:`instancedoc`):: - sage: @InstanceDoc + sage: @instancedoc ....: class A(object): ....: "Class A docstring" ....: def _instancedoc_(self): @@ -65,7 +65,7 @@ Check that inheritance works (after passing the subclass to 'Class B docstring' sage: B().__doc__ # Ideally, this would return the instance docstring 'Class B docstring' - sage: B = InstanceDoc(B) + sage: B = instancedoc(B) sage: B.__doc__ 'Class B docstring' sage: B().__doc__ @@ -151,7 +151,7 @@ cdef class InstanceDocDescriptor: return self.instancedoc(obj) -def InstanceDoc(cls): +def instancedoc(cls): """ Add support for ``_instancedoc_`` to the class ``cls``. @@ -165,17 +165,17 @@ def InstanceDoc(cls): .. WARNING:: - ``InstanceDoc`` mutates the given class. So you are *not* supposed - to use it as ``newcls = InstanceDoc(cls)`` because that would + ``instancedoc`` mutates the given class. So you are *not* supposed + to use it as ``newcls = instancedoc(cls)`` because that would mutate ``cls`` (and ``newcls`` would be the same object as ``cls``) TESTS: We get a useful error message if ``_instancedoc_`` is not defined:: - sage: from sage.docs.instancedoc import InstanceDoc + sage: from sage.docs.instancedoc import instancedoc sage: class X(object): pass - sage: InstanceDoc(X) + sage: instancedoc(X) Traceback (most recent call last): ... AttributeError: type object 'X' has no attribute '_instancedoc_' @@ -183,12 +183,12 @@ def InstanceDoc(cls): This does not work on old-style classes or things which are not a class at all:: - sage: InstanceDoc(7) + sage: instancedoc(7) Traceback (most recent call last): ... TypeError: expected type, got 7 sage: class OldStyle: pass - sage: InstanceDoc(OldStyle) + sage: instancedoc(OldStyle) Traceback (most recent call last): ... TypeError: expected type, got diff --git a/src/sage/interfaces/axiom.py b/src/sage/interfaces/axiom.py index f5403d5a998..be769d2aa55 100644 --- a/src/sage/interfaces/axiom.py +++ b/src/sage/interfaces/axiom.py @@ -187,7 +187,7 @@ from pexpect import EOF from sage.misc.multireplace import multiple_replace from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc # The Axiom commands ")what thing det" ")show Matrix" and ")display # op det" commands, gives a list of all identifiers that begin in @@ -555,7 +555,7 @@ def console(self): axiom_console() -@InstanceDoc +@instancedoc class PanAxiomElement(ExpectElement): def __call__(self, x): """ @@ -906,7 +906,7 @@ def _sage_domain(self): AxiomElement = PanAxiomElement -@InstanceDoc +@instancedoc class PanAxiomFunctionElement(FunctionElement): def __init__(self, object, name): """ @@ -929,7 +929,7 @@ def __init__(self, object, name): AxiomFunctionElement = PanAxiomFunctionElement -@InstanceDoc +@instancedoc class PanAxiomExpectFunction(ExpectFunction): def __init__(self, parent, name): """ diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index 2fb71b000e6..530505af7b6 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -63,7 +63,7 @@ from sage.misc.misc import SAGE_TMP_INTERFACE from sage.env import SAGE_EXTCODE, LOCAL_IDENTIFIER from sage.misc.object_multiplexer import Multiplex -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc from six import reraise as raise_ @@ -1345,14 +1345,14 @@ def _function_element_class(self): return FunctionElement -@InstanceDoc +@instancedoc class ExpectFunction(InterfaceFunction): """ Expect function. """ pass -@InstanceDoc +@instancedoc class FunctionElement(InterfaceFunctionElement): """ Expect function element. @@ -1364,7 +1364,7 @@ def is_ExpectElement(x): return isinstance(x, ExpectElement) -@InstanceDoc +@instancedoc class ExpectElement(InterfaceElement): """ Expect element. diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index e536b004de5..ff69fcb1eb9 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -191,7 +191,7 @@ from sage.interfaces.expect import Expect, ExpectElement, FunctionElement, ExpectFunction from sage.misc.misc import SAGE_TMP_INTERFACE from sage.env import DOT_SAGE -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc import re import six @@ -815,7 +815,7 @@ def console(self): fricas_console() -@InstanceDoc +@instancedoc class FriCASElement(ExpectElement): """ Instances of this class represent objects in FriCAS. @@ -1323,7 +1323,7 @@ def _sage_(self): raise NotImplementedError("The translation of the FriCAS object %s to sage is not yet implemented." %(unparsed_InputForm)) -@InstanceDoc +@instancedoc class FriCASFunctionElement(FunctionElement): def __init__(self, object, name): """ @@ -1347,7 +1347,7 @@ def __init__(self, object, name): FunctionElement.__init__(self, object, name) -@InstanceDoc +@instancedoc class FriCASExpectFunction(ExpectFunction): def __init__(self, parent, name): """ diff --git a/src/sage/interfaces/gap.py b/src/sage/interfaces/gap.py index ec9bb9fce8c..3e07bfc9dd5 100644 --- a/src/sage/interfaces/gap.py +++ b/src/sage/interfaces/gap.py @@ -183,7 +183,7 @@ from sage.misc.misc import is_in_string from sage.misc.superseded import deprecation from sage.misc.cachefunc import cached_method -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc from sage.interfaces.tab_completion import ExtraTabCompletion import re import os @@ -963,7 +963,7 @@ def get_record_element(self, record, name): return self('%s.%s' % (record.name(), name)) -@InstanceDoc +@instancedoc class GapElement_generic(ExtraTabCompletion, ExpectElement): r""" Generic interface to the GAP3/GAP4 interpreters. @@ -1546,7 +1546,7 @@ def gap_reset_workspace(max_workspace_size=None, verbose=False): g.quit() -@InstanceDoc +@instancedoc class GapElement(GapElement_generic): def __getitem__(self, n): """ @@ -1618,7 +1618,7 @@ def _tab_completion(self): return v -@InstanceDoc +@instancedoc class GapFunctionElement(FunctionElement): def _instancedoc_(self): """ @@ -1637,7 +1637,7 @@ def _instancedoc_(self): return help -@InstanceDoc +@instancedoc class GapFunction(ExpectFunction): def _instancedoc(self): """ diff --git a/src/sage/interfaces/giac.py b/src/sage/interfaces/giac.py index 7c1ba2c6272..82efb1970e9 100644 --- a/src/sage/interfaces/giac.py +++ b/src/sage/interfaces/giac.py @@ -193,7 +193,7 @@ from sage.env import DOT_SAGE from sage.misc.pager import pager -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc COMMANDS_CACHE = '%s/giac_commandlist_cache.sobj'%DOT_SAGE @@ -753,7 +753,7 @@ def version(self): return giac('version()') -@InstanceDoc +@instancedoc class GiacFunction(ExpectFunction): def _instancedoc_(self): """ @@ -769,7 +769,7 @@ def _instancedoc_(self): return M._help(self._name) -@InstanceDoc +@instancedoc class GiacFunctionElement(FunctionElement): def _instancedoc_(self): """ @@ -785,7 +785,7 @@ def _instancedoc_(self): return self._obj.parent()._help(self._name) -@InstanceDoc +@instancedoc class GiacElement(ExpectElement): def __float__(self): """ diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index 63fb923d987..c77fa35c98f 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -146,7 +146,7 @@ from sage.interfaces.tab_completion import ExtraTabCompletion from sage.libs.pari.all import pari import sage.rings.complex_field -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc class Gp(ExtraTabCompletion, Expect): @@ -835,7 +835,7 @@ def new_with_bits_prec(self, s, precision = 0): return x -@InstanceDoc +@instancedoc class GpElement(ExpectElement): """ EXAMPLES: This example illustrates dumping and loading GP elements diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index 53727253d18..3257da626d7 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -48,7 +48,7 @@ from sage.structure.element import Element, parent import sage.misc.sage_eval -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc class AsciiArtString(str): @@ -595,7 +595,7 @@ def help(self, s): return AsciiArtString('No help on %s available'%s) -@InstanceDoc +@instancedoc class InterfaceFunction(SageObject): """ Interface function. @@ -621,7 +621,7 @@ def _instancedoc_(self): return M.help(self._name) -@InstanceDoc +@instancedoc class InterfaceFunctionElement(SageObject): """ Interface function element. @@ -655,7 +655,7 @@ def is_InterfaceElement(x): return isinstance(x, InterfaceElement) -@InstanceDoc +@instancedoc class InterfaceElement(Element): """ Interface element. diff --git a/src/sage/interfaces/kash.py b/src/sage/interfaces/kash.py index 850e53982e6..1630451f72e 100644 --- a/src/sage/interfaces/kash.py +++ b/src/sage/interfaces/kash.py @@ -433,7 +433,7 @@ from __future__ import absolute_import from .expect import Expect, ExpectElement -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc import os @@ -668,7 +668,7 @@ def version(self): return kash_version() -@InstanceDoc +@instancedoc class KashElement(ExpectElement): def __mod__(self, other): self._check_valid() diff --git a/src/sage/interfaces/lie.py b/src/sage/interfaces/lie.py index e65634d024b..c51ece13ad9 100644 --- a/src/sage/interfaces/lie.py +++ b/src/sage/interfaces/lie.py @@ -292,7 +292,7 @@ from sage.misc.all import prod from sage.env import DOT_SAGE, SAGE_LOCAL from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc import os @@ -748,7 +748,7 @@ def _function_element_class(self): return LiEFunctionElement -@InstanceDoc +@instancedoc class LiEElement(ExtraTabCompletion, ExpectElement): def _tab_completion(self): """ @@ -868,7 +868,7 @@ def _sage_(self): return ExpectElement._sage_(self) -@InstanceDoc +@instancedoc class LiEFunctionElement(FunctionElement): def _instancedoc_(self): """ @@ -882,7 +882,7 @@ def _instancedoc_(self): return M.help(self._name) -@InstanceDoc +@instancedoc class LiEFunction(ExpectFunction): def _instancedoc_(self): """ diff --git a/src/sage/interfaces/lisp.py b/src/sage/interfaces/lisp.py index 058114e3c7b..3abec1cf7ea 100644 --- a/src/sage/interfaces/lisp.py +++ b/src/sage/interfaces/lisp.py @@ -56,7 +56,7 @@ from .expect import Expect, ExpectElement, ExpectFunction, FunctionElement, gc_disabled from sage.structure.element import RingElement, parent -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc class Lisp(Expect): @@ -385,7 +385,7 @@ def function_call(self, function, args=None, kwds=None): # Inherit from RingElement to make __pow__ work -@InstanceDoc +@instancedoc class LispElement(RingElement, ExpectElement): def __cmp__(self, other): """ @@ -485,7 +485,7 @@ def __pow__(self, n): return RingElement.__pow__(self, n) -@InstanceDoc +@instancedoc class LispFunctionElement(FunctionElement): def _instancedoc_(self): """ @@ -501,7 +501,7 @@ def _instancedoc_(self): return M.help(self._name) -@InstanceDoc +@instancedoc class LispFunction(ExpectFunction): def _instancedoc_(self): """ diff --git a/src/sage/interfaces/macaulay2.py b/src/sage/interfaces/macaulay2.py index aaa50d5d0f1..720e3ee3c5c 100644 --- a/src/sage/interfaces/macaulay2.py +++ b/src/sage/interfaces/macaulay2.py @@ -104,7 +104,7 @@ from sage.misc.multireplace import multiple_replace from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc import re @@ -604,7 +604,7 @@ def new_from(self, type, value): return self.new("new %s from %s"%(type.name(), value.name())) -@InstanceDoc +@instancedoc class Macaulay2Element(ExtraTabCompletion, ExpectElement): def _latex_(self): """ @@ -1167,7 +1167,7 @@ def to_sage(self): raise NotImplementedError("cannot convert %s to a Sage object"%repr_str) -@InstanceDoc +@instancedoc class Macaulay2Function(ExpectFunction): def _instancedoc_(self): """ diff --git a/src/sage/interfaces/magma.py b/src/sage/interfaces/magma.py index ea4afae07fc..5decd251baf 100644 --- a/src/sage/interfaces/magma.py +++ b/src/sage/interfaces/magma.py @@ -228,7 +228,7 @@ import sage.misc.misc import sage.misc.sage_eval from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc INTRINSIC_CACHE = '%s/magma_intrinsic_cache.sobj' % DOT_SAGE EXTCODE_DIR = None @@ -1649,7 +1649,7 @@ def GetVerbose(self, type): return int(self.eval('GetVerbose("%s")' % type)) -@InstanceDoc +@instancedoc class MagmaFunctionElement(FunctionElement): def __call__(self, *args, **kwds): """ @@ -1768,7 +1768,7 @@ def __repr__(self): return "Partially evaluated Magma function or intrinsic '%s'\n\nSignature:\n\n%s" % (self._name, self._instancedoc_()) -@InstanceDoc +@instancedoc class MagmaFunction(ExpectFunction): def __call__(self, *args, **kwds): """ @@ -1849,7 +1849,7 @@ def is_MagmaElement(x): return isinstance(x, MagmaElement) -@InstanceDoc +@instancedoc class MagmaElement(ExtraTabCompletion, ExpectElement): def _ref(self): """ diff --git a/src/sage/interfaces/maple.py b/src/sage/interfaces/maple.py index b6876e94de7..22c51c00001 100644 --- a/src/sage/interfaces/maple.py +++ b/src/sage/interfaces/maple.py @@ -246,7 +246,7 @@ from sage.env import DOT_SAGE from sage.misc.pager import pager from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc COMMANDS_CACHE = '%s/maple_commandlist_cache.sobj'%DOT_SAGE @@ -840,7 +840,7 @@ def clear(self, var): self.set(var, "'{}'".format(var)) -@InstanceDoc +@instancedoc class MapleFunction(ExpectFunction): def _instancedoc(self): """ @@ -876,7 +876,7 @@ def _sage_src_(self): return M._source(self._name) -@InstanceDoc +@instancedoc class MapleFunctionElement(FunctionElement): def _instancedoc_(self): """ @@ -911,7 +911,7 @@ def _sage_src_(self): return self._obj.parent()._source(self._name) -@InstanceDoc +@instancedoc class MapleElement(ExtraTabCompletion, ExpectElement): def __float__(self): diff --git a/src/sage/interfaces/mathematica.py b/src/sage/interfaces/mathematica.py index ee8dc8aa36e..31ff6d55f35 100644 --- a/src/sage/interfaces/mathematica.py +++ b/src/sage/interfaces/mathematica.py @@ -364,7 +364,7 @@ from sage.interfaces.expect import (Expect, ExpectElement, ExpectFunction, FunctionElement, AsciiArtString) from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc def clean_output(s): @@ -626,7 +626,7 @@ def __getattr__(self, attrname): return MathematicaFunction(self, attrname) -@InstanceDoc +@instancedoc class MathematicaElement(ExpectElement): def __getitem__(self, n): return self.parent().new('%s[[%s]]'%(self._name, n)) @@ -990,14 +990,14 @@ def n(self, *args, **kwargs): return self._sage_().n(*args, **kwargs) -@InstanceDoc +@instancedoc class MathematicaFunction(ExpectFunction): def _instancedoc_(self): M = self._parent return M.help(self._name) -@InstanceDoc +@instancedoc class MathematicaFunctionElement(FunctionElement): def _instancedoc_(self): M = self._obj.parent() diff --git a/src/sage/interfaces/matlab.py b/src/sage/interfaces/matlab.py index aefe0d339f1..5cf7e695754 100644 --- a/src/sage/interfaces/matlab.py +++ b/src/sage/interfaces/matlab.py @@ -152,7 +152,7 @@ import os from .expect import Expect, ExpectElement -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc class Matlab(Expect): @@ -320,7 +320,7 @@ def _object_class(self): return MatlabElement -@InstanceDoc +@instancedoc class MatlabElement(ExpectElement): def __getitem__(self, n): raise RuntimeError("Use parenthesis for MATLAB matrices instead.") diff --git a/src/sage/interfaces/maxima.py b/src/sage/interfaces/maxima.py index 4b7799d35c7..0da14f8786c 100644 --- a/src/sage/interfaces/maxima.py +++ b/src/sage/interfaces/maxima.py @@ -481,7 +481,7 @@ MaximaAbstractElement, MaximaAbstractFunctionElement, MaximaAbstractElementFunction) -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc # Thanks to the MRO for multiple inheritance used by the Sage's Python, @@ -1119,7 +1119,7 @@ def is_MaximaElement(x): return isinstance(x, MaximaElement) -@InstanceDoc +@instancedoc class MaximaElement(MaximaAbstractElement, ExpectElement): """ Element of Maxima through Pexpect interface. @@ -1189,7 +1189,7 @@ def display2d(self, onscreen=True): MaximaFunction = MaximaAbstractFunction -@InstanceDoc +@instancedoc class MaximaElementFunction(MaximaElement, MaximaAbstractElementFunction): """ Maxima user-defined functions. diff --git a/src/sage/interfaces/maxima_abstract.py b/src/sage/interfaces/maxima_abstract.py index dfafe12c1a9..d3713e30c5a 100644 --- a/src/sage/interfaces/maxima_abstract.py +++ b/src/sage/interfaces/maxima_abstract.py @@ -65,7 +65,7 @@ from .interface import (Interface, InterfaceElement, InterfaceFunctionElement, InterfaceFunction, AsciiArtString) from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc # The Maxima "apropos" command, e.g., apropos(det) gives a list # of all identifiers that begin in a certain way. This could @@ -1070,7 +1070,7 @@ def plot_multilist(self, pts_list, options=None): self('plot2d('+cmd+','+options+')') -@InstanceDoc +@instancedoc class MaximaAbstractElement(ExtraTabCompletion, InterfaceElement): r""" Element of Maxima through an abstract interface. diff --git a/src/sage/interfaces/maxima_lib.py b/src/sage/interfaces/maxima_lib.py index 8fa880ce0a0..552c96a0b91 100644 --- a/src/sage/interfaces/maxima_lib.py +++ b/src/sage/interfaces/maxima_lib.py @@ -94,7 +94,7 @@ from .maxima_abstract import (MaximaAbstract, MaximaAbstractFunction, MaximaAbstractElement, MaximaAbstractFunctionElement, MaximaAbstractElementFunction) -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc ## We begin here by initializing Maxima in library mode @@ -1035,7 +1035,7 @@ def is_MaximaLibElement(x): return isinstance(x, MaximaLibElement) -@InstanceDoc +@instancedoc class MaximaLibElement(MaximaAbstractElement): r""" Element of Maxima through library interface. @@ -1141,7 +1141,7 @@ def display2d(self, onscreen=True): MaximaLibFunctionElement = MaximaAbstractFunctionElement MaximaLibFunction = MaximaAbstractFunction -@InstanceDoc +@instancedoc class MaximaLibElementFunction(MaximaLibElement, MaximaAbstractElementFunction): pass diff --git a/src/sage/interfaces/mupad.py b/src/sage/interfaces/mupad.py index be9aa3c0c15..ec2cc26e625 100644 --- a/src/sage/interfaces/mupad.py +++ b/src/sage/interfaces/mupad.py @@ -98,7 +98,7 @@ FunctionElement, AsciiArtString) from sage.interfaces.tab_completion import ExtraTabCompletion from sage.env import DOT_SAGE -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc COMMANDS_CACHE = '%s/mupad_commandlist_cache.sobj'%DOT_SAGE PROMPT = ">>" @@ -442,7 +442,7 @@ def completions(self, string, strip=False): return res if res != [''] else [] -@InstanceDoc +@instancedoc class MupadFunction(ExtraTabCompletion, ExpectFunction): def _instancedoc_(self): """ @@ -480,7 +480,7 @@ def _tab_completion(self): return res if res != [] else self._parent._tab_completion() -@InstanceDoc +@instancedoc class MupadFunctionElement(ExtraTabCompletion, FunctionElement): def _instancedoc_(self): """ @@ -551,7 +551,7 @@ def __call__(self, *args): return P.function_call(self._name, [self._obj] + list(args)) -@InstanceDoc +@instancedoc class MupadElement(ExtraTabCompletion, ExpectElement): def __getattr__(self, attrname): diff --git a/src/sage/interfaces/octave.py b/src/sage/interfaces/octave.py index a948defe261..0141a3bf5ad 100644 --- a/src/sage/interfaces/octave.py +++ b/src/sage/interfaces/octave.py @@ -156,7 +156,7 @@ import os from .expect import Expect, ExpectElement from sage.misc.misc import verbose -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc class Octave(Expect): @@ -614,7 +614,7 @@ def to_complex(octave_string, R): return R(float(real), float(imag)) -@InstanceDoc +@instancedoc class OctaveElement(ExpectElement): def _get_sage_ring(self): r""" diff --git a/src/sage/interfaces/qepcad.py b/src/sage/interfaces/qepcad.py index 0973c6f55d3..00488e99398 100644 --- a/src/sage/interfaces/qepcad.py +++ b/src/sage/interfaces/qepcad.py @@ -615,7 +615,7 @@ from sage.misc.sage_eval import sage_eval from sage.repl.preparse import implicit_mul from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc from .expect import Expect, ExpectFunction, AsciiArtString @@ -1360,7 +1360,7 @@ def _format_cell_index(a): return str(tuple(a)) -@InstanceDoc +@instancedoc class QepcadFunction(ExpectFunction): r""" A wrapper for a QEPCAD command. diff --git a/src/sage/interfaces/r.py b/src/sage/interfaces/r.py index 3e343116da8..a84aa5eb7c9 100644 --- a/src/sage/interfaces/r.py +++ b/src/sage/interfaces/r.py @@ -274,7 +274,7 @@ from sage.structure.element import parent from sage.misc.cachefunc import cached_method from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc COMMANDS_CACHE = '%s/r_commandlist.sobj'%DOT_SAGE PROMPT = '__SAGE__R__PROMPT__> ' @@ -1256,7 +1256,7 @@ def chdir(self, dir): rel_re_call = re.compile('call\s*=\s*(.*?)\),') -@InstanceDoc +@instancedoc class RElement(ExtraTabCompletion, ExpectElement): def _tab_completion(self): @@ -1923,7 +1923,7 @@ def _latex_(self): return LatexExpr(P.eval('latex(%s, file="");'%self.name())) -@InstanceDoc +@instancedoc class RFunctionElement(FunctionElement): def __reduce__(self): """ @@ -1981,7 +1981,7 @@ def __call__(self, *args, **kwds): return self._obj.parent().function_call(self._name, args=[self._obj] + list(args), kwds=kwds) -@InstanceDoc +@instancedoc class RFunction(ExpectFunction): def __init__(self, parent, name, r_name=None): """ diff --git a/src/sage/interfaces/sage0.py b/src/sage/interfaces/sage0.py index 68e55232219..b0487da9c29 100644 --- a/src/sage/interfaces/sage0.py +++ b/src/sage/interfaces/sage0.py @@ -26,7 +26,7 @@ from sage.interfaces.tab_completion import ExtraTabCompletion from sage.structure.sage_object import dumps, load -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc class Sage(ExtraTabCompletion, Expect): @@ -398,7 +398,7 @@ def new(self, x): return SageElement(self, x) -@InstanceDoc +@instancedoc class SageElement(ExpectElement): def _rich_repr_(self, display_manager, **kwds): @@ -466,7 +466,7 @@ def _sage_(self): return load(P._local_tmpfile()) -@InstanceDoc +@instancedoc class SageFunction(FunctionElement): def __call__(self, *args, **kwds): """ diff --git a/src/sage/interfaces/scilab.py b/src/sage/interfaces/scilab.py index 16c3d769d60..8d9e9605cf4 100644 --- a/src/sage/interfaces/scilab.py +++ b/src/sage/interfaces/scilab.py @@ -192,7 +192,7 @@ import os from .expect import Expect, ExpectElement -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc class Scilab(Expect): @@ -426,7 +426,7 @@ def _object_class(self): return ScilabElement -@InstanceDoc +@instancedoc class ScilabElement(ExpectElement): def __getitem__(self, n): """ diff --git a/src/sage/interfaces/singular.py b/src/sage/interfaces/singular.py index fb914dd2468..7b979da0a5d 100644 --- a/src/sage/interfaces/singular.py +++ b/src/sage/interfaces/singular.py @@ -337,7 +337,7 @@ from sage.misc.misc import get_verbose from sage.misc.superseded import deprecation -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc from six import reraise as raise_ @@ -1261,7 +1261,7 @@ def _keyboard_interrupt(self): raise KeyboardInterrupt("Restarting %s (WARNING: all variables defined in previous session are now invalid)" % self) -@InstanceDoc +@instancedoc class SingularElement(ExtraTabCompletion, ExpectElement): def __init__(self, parent, type, value, is_name=False): @@ -2175,7 +2175,7 @@ def attrib(self, name, value=None): self.parent().eval('attrib(%s,"%s",%d)'%(self.name(),name,value)) -@InstanceDoc +@instancedoc class SingularFunction(ExpectFunction): def _instancedoc_(self): """ @@ -2213,7 +2213,7 @@ def _instancedoc_(self): return prefix -@InstanceDoc +@instancedoc class SingularFunctionElement(FunctionElement): def _instancedoc_(self): r""" diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index 8bec94f8205..3aebbc50375 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -2676,6 +2676,6 @@ cdef class GapElement_RecordIterator(object): # Add support for _instancedoc_ -from sage.docs.instancedoc import InstanceDoc -InstanceDoc(GapElement_Function) -InstanceDoc(GapElement_MethodProxy) +from sage.docs.instancedoc import instancedoc +instancedoc(GapElement_Function) +instancedoc(GapElement_MethodProxy) diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index 599fda4cee0..17f28e11a95 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -1879,7 +1879,7 @@ cdef inline RingWrap new_RingWrap(ring* r): # Add support for _instancedoc_ -from sage.docs.instancedoc import InstanceDoc -InstanceDoc(SingularFunction) -InstanceDoc(SingularLibraryFunction) -InstanceDoc(SingularKernelFunction) +from sage.docs.instancedoc import instancedoc +instancedoc(SingularFunction) +instancedoc(SingularLibraryFunction) +instancedoc(SingularKernelFunction) diff --git a/src/sage/misc/cachefunc.pyx b/src/sage/misc/cachefunc.pyx index 99ac71bb354..eb2d16102df 100644 --- a/src/sage/misc/cachefunc.pyx +++ b/src/sage/misc/cachefunc.pyx @@ -3788,10 +3788,10 @@ class disk_cached_function: # Add support for _instancedoc_ -from sage.docs.instancedoc import InstanceDoc -InstanceDoc(CachedFunction) -InstanceDoc(WeakCachedFunction) -InstanceDoc(CachedMethodCaller) -InstanceDoc(CachedMethodCallerNoArgs) -InstanceDoc(GloballyCachedMethodCaller) -InstanceDoc(DiskCachedFunction) +from sage.docs.instancedoc import instancedoc +instancedoc(CachedFunction) +instancedoc(WeakCachedFunction) +instancedoc(CachedMethodCaller) +instancedoc(CachedMethodCallerNoArgs) +instancedoc(GloballyCachedMethodCaller) +instancedoc(DiskCachedFunction) diff --git a/src/sage/misc/lazy_import.pyx b/src/sage/misc/lazy_import.pyx index 204fe4b6bdf..80dff585b4c 100644 --- a/src/sage/misc/lazy_import.pyx +++ b/src/sage/misc/lazy_import.pyx @@ -1153,5 +1153,5 @@ def get_star_imports(module_name): # Add support for _instancedoc_ -from sage.docs.instancedoc import InstanceDoc -InstanceDoc(LazyImport) +from sage.docs.instancedoc import instancedoc +instancedoc(LazyImport) diff --git a/src/sage/parallel/decorate.py b/src/sage/parallel/decorate.py index 33057247cb9..17f43d793c3 100644 --- a/src/sage/parallel/decorate.py +++ b/src/sage/parallel/decorate.py @@ -10,7 +10,7 @@ from .reference import parallel_iter as p_iter_reference from .use_fork import p_iter_fork from . import multiprocessing_sage -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc def normalize_input(a): @@ -121,7 +121,7 @@ def __call__(self, f): return ParallelFunction(self, f) -@InstanceDoc +@instancedoc class ParallelFunction(object): """ Class which parallelizes a function or class method. diff --git a/src/sage/sets/set_from_iterator.py b/src/sage/sets/set_from_iterator.py index 2e954fa5c94..00cd4eb20e0 100644 --- a/src/sage/sets/set_from_iterator.py +++ b/src/sage/sets/set_from_iterator.py @@ -72,7 +72,7 @@ import os from sage.misc.function_mangling import ArgumentFixer from sage.misc.lazy_list import lazy_list -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc class EnumeratedSetFromIterator(Parent): @@ -447,7 +447,7 @@ def clear_cache(self): # #TODO: move it in sage.misc ? -@InstanceDoc +@instancedoc class Decorator(object): r""" Abstract class that manage documentation and sources of the wrapped object. @@ -562,7 +562,7 @@ def __call__(self, *args, **kwds): raise NotImplementedError -@InstanceDoc +@instancedoc class EnumeratedSetFromIterator_function_decorator(Decorator): r""" Decorator for :class:`EnumeratedSetFromIterator`. @@ -722,7 +722,7 @@ def __call__(self, *args, **kwds): set_from_function = EnumeratedSetFromIterator_function_decorator -@InstanceDoc +@instancedoc class EnumeratedSetFromIterator_method_caller(Decorator): r""" Caller for decorated method in class. diff --git a/src/sage/symbolic/maxima_wrapper.py b/src/sage/symbolic/maxima_wrapper.py index da10d10cbbe..d5bdb0d28a4 100644 --- a/src/sage/symbolic/maxima_wrapper.py +++ b/src/sage/symbolic/maxima_wrapper.py @@ -10,10 +10,10 @@ from sage.structure.sage_object import SageObject from sage.interfaces.maxima import MaximaFunctionElement -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc -@InstanceDoc +@instancedoc class MaximaFunctionElementWrapper(MaximaFunctionElement): def __call__(self, *args, **kwds): """ diff --git a/src/sage/symbolic/units.py b/src/sage/symbolic/units.py index b75c1453330..f1d862023e7 100644 --- a/src/sage/symbolic/units.py +++ b/src/sage/symbolic/units.py @@ -97,7 +97,7 @@ from .ring import SR from .expression import Expression from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import InstanceDoc +from sage.docs.instancedoc import instancedoc ############################################################################### # Unit conversions dictionary. @@ -986,7 +986,7 @@ def unit_derivations_expr(v): return Z -@InstanceDoc +@instancedoc class UnitExpression(Expression): """ A symbolic unit. From 5fe7cb01a8cd117ac6754c8301fb5ddf94d82813 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 23 Mar 2017 11:17:10 +0100 Subject: [PATCH 175/185] Change exception message for missing _instancedoc_ --- src/sage/docs/instancedoc.pyx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/sage/docs/instancedoc.pyx b/src/sage/docs/instancedoc.pyx index d209d14737b..e23ed8348a2 100644 --- a/src/sage/docs/instancedoc.pyx +++ b/src/sage/docs/instancedoc.pyx @@ -178,7 +178,7 @@ def instancedoc(cls): sage: instancedoc(X) Traceback (most recent call last): ... - AttributeError: type object 'X' has no attribute '_instancedoc_' + TypeError: instancedoc requires to have an '_instancedoc_' attribute This does not work on old-style classes or things which are not a class at all:: @@ -194,7 +194,11 @@ def instancedoc(cls): TypeError: expected type, got """ cdef PyTypeObject* tp = TypeObject(cls) - docattr = InstanceDocDescriptor(cls.__doc__, cls._instancedoc_) + try: + instdoc = cls._instancedoc_ + except AttributeError: + raise TypeError(f"instancedoc requires {cls!r} to have an '_instancedoc_' attribute") + docattr = InstanceDocDescriptor(cls.__doc__, instdoc) PyDict_SetItemString(tp.tp_dict, "__doc__", docattr) tp.tp_doc = NULL PyType_Modified(tp) From 9ba1bb25f49532832701a343e101282e743f00da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konrad=20K=2E=20D=C4=85browski?= Date: Mon, 27 Mar 2017 00:05:45 +0000 Subject: [PATCH 176/185] Fix compiling Tachyon on Arm (#21171) --- build/pkgs/tachyon/patches/Make-arch.patch | 113 +++++++++++---------- build/pkgs/tachyon/spkg-install | 3 +- 2 files changed, 62 insertions(+), 54 deletions(-) diff --git a/build/pkgs/tachyon/patches/Make-arch.patch b/build/pkgs/tachyon/patches/Make-arch.patch index 8dc65b68329..0fcce9a58f0 100644 --- a/build/pkgs/tachyon/patches/Make-arch.patch +++ b/build/pkgs/tachyon/patches/Make-arch.patch @@ -1,5 +1,5 @@ ---- a/unix/Make-arch 2011-03-13 11:01:07.000000000 +0000 -+++ b/unix/Make-arch 2016-07-04 15:29:30.502923000 +0000 +--- a/unix/Make-arch ++++ b/unix/Make-arch @@ -7,7 +7,8 @@ # Some machines don't have/need ranlib, in their case, use 'touch' @@ -10,7 +10,7 @@ # MPI path setup, probably shouldn't need to be changed. MPIINC=$(MPIDIR)/include -@@ -23,7 +24,8 @@ +@@ -23,7 +24,8 @@ default: @echo "--------------------------------------------------------------" @echo " Parallel Versions " @echo "" @@ -20,7 +20,7 @@ @echo " aix-64-thr - IBM AIX 5.x POSIX Threads, 64-bit " @echo " aix-mpi - IBM AIX 5.x (SP) MPI " @echo " asci-red-mpi - Intel ASCI Red MPI " -@@ -32,11 +34,12 @@ +@@ -32,11 +34,12 @@ default: @echo " cray-t3e-mpi - Cray T3E MPI " @echo " cray-xt3-mpi - Cray XT3 MPI " @echo " compaq-alphasc-mpi - Lemieux at PSC MPI " @@ -34,7 +34,7 @@ @echo " linux-alpha-ccc-qsw - Linux Alpha, Compaq C, MPI, QSWnet " @echo " linux-lam - Linux MPI (OSC LAM) " @echo " linux-lam-64 - Linux AMD64/EM64T, MPI, 64-bit " -@@ -48,13 +51,14 @@ +@@ -48,13 +51,14 @@ default: @echo "linux-ia64-thr-sgicc - Linux IA-64, SGI Pro64 Compilers " @echo " macosx-thr - MacOS X PowerPC, POSIX Threads " @echo " macosx-x86-thr - MacOS X Intel x86, POSIX Threads " @@ -56,7 +56,7 @@ @echo "--------------------------------------------------------------" @echo " Hybrid Parallel Versions " @echo "" -@@ -63,9 +67,11 @@ +@@ -63,9 +67,11 @@ default: @echo "--------------------------------------------------------------" @echo " Sequential Versions " @echo "" @@ -70,7 +70,7 @@ @echo " irix6 - SGI Irix 6.x " @echo " linux - Linux " @echo " linux-64 - Linux, AMD64/EM64T, GCC 3.x, 64-bit " -@@ -102,7 +108,7 @@ +@@ -102,7 +108,7 @@ default: @echo "Consult the README file in this directory for further info. " ## @@ -79,7 +79,7 @@ ## No pthreads on ASCI Red yet. I didn't bother with the cop() stuff ## asci-red-mpi: -@@ -118,7 +124,7 @@ +@@ -118,7 +124,7 @@ asci-red-mpi: ## ## IBM Blue Gene/L Parallel Supercomputer @@ -88,7 +88,7 @@ ## NOTE: strip breaks bluegene executables, they are dynamically re-linked ## at runtime, so we must use /bin/true rather than strip ## -@@ -137,7 +143,7 @@ +@@ -137,7 +143,7 @@ bluegene-mpi: ## Cray Parallel Vector Processor Machines Using Threads ## ## Tested on J90s, but should work on almost any of the Cray PVP systems. @@ -97,7 +97,7 @@ ## off running on a fast workstation, or even better, on a T3E!!! ## cray-thr: -@@ -228,7 +234,7 @@ +@@ -228,7 +234,7 @@ cray-xt3-mpi: ## ## Architecture flags for the Intel Paragon XP/S Supercomputer using MPI ## for message passing. NX is no longer supported by this software. @@ -106,7 +106,7 @@ ## Concurrent I/O is used by default. ## -@@ -264,8 +270,8 @@ +@@ -264,8 +270,8 @@ paragon-mpi: ## @@ -117,7 +117,7 @@ ## Tested with the mpich distribution from Argonne National Labs ## -@@ -277,7 +283,7 @@ +@@ -277,7 +283,7 @@ ipsc860-mpi: "AR = ar860" \ "ARFLAGS = r" \ "STRIP = strip860" \ @@ -126,7 +126,7 @@ ipsc860-mpi-debug: $(MAKE) all \ -@@ -287,7 +293,7 @@ +@@ -287,7 +293,7 @@ ipsc860-mpi-debug: "AR = ar860" \ "ARFLAGS = r" \ "STRIP = touch " \ @@ -135,7 +135,7 @@ ## -@@ -296,22 +302,18 @@ +@@ -296,22 +302,18 @@ ipsc860-mpi-debug: tru64-alpha: $(MAKE) all \ "ARCH = tru64-alpha" \ @@ -159,7 +159,7 @@ "ARFLAGS = r" \ "STRIP = strip" \ "LIBS = -L. -ltachyon $(MISCLIB) -lm" -@@ -319,9 +321,7 @@ +@@ -319,9 +321,7 @@ tru64-alpha-thr: tru64-alpha-thr-ogl: $(MAKE) all \ "ARCH = tru64-alpha-thr-ogl" \ @@ -169,7 +169,7 @@ "ARFLAGS = r" \ "STRIP = strip" \ "LIBS = -L. -ltachyon $(TRU64_GLX_LIBS) $(MISCLIB) -lm" -@@ -448,7 +448,7 @@ +@@ -448,7 +448,7 @@ solaris-ultra-hpc: "AR = ar" \ "ARFLAGS = r" \ "STRIP = strip" \ @@ -178,7 +178,7 @@ solaris-mpi: $(MAKE) all \ -@@ -458,7 +458,7 @@ +@@ -458,7 +458,7 @@ solaris-mpi: "AR = ar" \ "ARFLAGS = r" \ "STRIP = strip" \ @@ -187,7 +187,7 @@ solaris-thr: $(MAKE) all \ -@@ -473,9 +473,15 @@ +@@ -473,9 +473,15 @@ solaris-thr: solaris-pthreads-gcc: $(MAKE) all \ "ARCH = solaris-pthreads-gcc" \ @@ -205,7 +205,7 @@ "ARFLAGS = r" \ "STRIP = strip" \ "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" -@@ -618,7 +624,7 @@ +@@ -618,7 +624,7 @@ solaris-ultra-hpc-ogl: "AR = ar" \ "ARFLAGS = r" \ "STRIP = strip" \ @@ -214,7 +214,7 @@ solaris-ultra-pthreads-ogl: $(MAKE) all \ -@@ -643,9 +649,7 @@ +@@ -643,9 +649,7 @@ solaris-apcc-ultra-thr: solaris-gcc-thr: $(MAKE) all \ "ARCH = solaris-gcc-thr" \ @@ -224,7 +224,7 @@ "ARFLAGS = r" \ "STRIP = touch" \ "LIBS = -L. -ltachyon $(MISCLIB) -lm -lsocket -lthread" -@@ -653,9 +657,7 @@ +@@ -653,9 +657,7 @@ solaris-gcc-thr: solaris-gcc-thr-x11: $(MAKE) all \ "ARCH = solaris-gcc-thr-x11" \ @@ -234,7 +234,7 @@ "ARFLAGS = r" \ "STRIP = touch" \ "LIBS = -L. -ltachyon $(MISCLIB) -lm -lsocket $(X11LIB) -lthread" -@@ -701,7 +703,7 @@ +@@ -701,7 +703,7 @@ irix5-mpi: "AR = ar" \ "ARFLAGS = r" \ "STRIP = strip" \ @@ -243,7 +243,7 @@ irix5: $(MAKE) all \ -@@ -710,7 +712,7 @@ +@@ -710,7 +712,7 @@ irix5: "AR = ar" \ "ARFLAGS = r" \ "STRIP = strip" \ @@ -252,7 +252,7 @@ irix6: $(MAKE) all \ -@@ -719,7 +721,7 @@ +@@ -719,7 +721,7 @@ irix6: "AR = ar" \ "ARFLAGS = r" \ "STRIP = strip" \ @@ -261,7 +261,7 @@ irix6-purify: $(MAKE) all \ -@@ -738,7 +740,7 @@ +@@ -738,7 +740,7 @@ irix6-64-thr: "AR = ar" \ "ARFLAGS = r" \ "STRIP = strip" \ @@ -270,7 +270,7 @@ irix6-thr: $(MAKE) all \ -@@ -747,7 +749,7 @@ +@@ -747,7 +749,7 @@ irix6-thr: "AR = ar" \ "ARFLAGS = r" \ "STRIP = strip" \ @@ -279,7 +279,7 @@ irix6-thr-purify: $(MAKE) all \ -@@ -766,7 +768,7 @@ +@@ -766,7 +768,7 @@ irix6-thr-ogl: "AR = ar" \ "ARFLAGS = r" \ "STRIP = strip" \ @@ -288,7 +288,7 @@ ## -@@ -776,6 +778,8 @@ +@@ -776,6 +778,8 @@ irix6-thr-ogl: ## available yet, since access to a thread capable test machine is needed ## for implementation. These configurations require xlc. ## @@ -297,7 +297,7 @@ aix: -@@ -788,6 +792,19 @@ +@@ -788,6 +792,19 @@ aix: "STRIP = strip" \ "LIBS = -L. -ltachyon $(MISCLIB) -lm" @@ -317,7 +317,7 @@ aix-mpi: $(MAKE) all \ "ARCH = aix-mpi" \ -@@ -808,6 +825,19 @@ +@@ -808,6 +825,19 @@ aix-thr: "STRIP = strip" \ "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" @@ -337,7 +337,7 @@ aix-64-thr: $(MAKE) all \ "ARCH = aix-64-thr" \ -@@ -836,6 +866,32 @@ +@@ -836,6 +866,32 @@ hpux: "STRIP = strip" \ "LIBS = -L. -ltachyon $(MISCLIB) -lm" @@ -370,7 +370,7 @@ hpux-thr: $(MAKE) all \ "ARCH = hpux-thr" \ -@@ -867,67 +923,57 @@ +@@ -867,67 +923,57 @@ hpux-ia64-thr: next: $(MAKE) all \ "ARCH = next" \ @@ -446,7 +446,7 @@ "LIBS = -L. -ltachyon $(MISCLIB) -lpthread -L/usr/X11R6/lib -lGLU -lGL -lX11 -framework Carbon" -@@ -938,12 +984,9 @@ +@@ -938,12 +984,9 @@ macosx-x86-thr-ogl: beos: $(MAKE) all \ "ARCH = beos" \ @@ -459,7 +459,7 @@ "LIBS = -L. -ltachyon $(MISCLIB)" ## -@@ -954,23 +997,17 @@ +@@ -954,23 +997,17 @@ beos: bsd: $(MAKE) all \ "ARCH = bsd" \ @@ -483,7 +483,7 @@ "LIBS = -L. -ltachyon $(MISCLIB) -lm" ## -@@ -980,23 +1017,17 @@ +@@ -980,23 +1017,17 @@ bsd-sparc: win32: $(MAKE) all \ "ARCH = win32" \ @@ -509,7 +509,7 @@ "LIBS = -L. -L'/Program files/MPIPro/LIB' -ltachyon -lmpi $(MISCLIB) -lm" ## -@@ -1007,60 +1038,45 @@ +@@ -1007,60 +1038,45 @@ win32-mpi: linux: $(MAKE) all \ "ARCH = linux" \ @@ -570,7 +570,7 @@ "LIBS = -L. -ltachyon $(MISCLIB) -lm" -@@ -1068,12 +1084,9 @@ +@@ -1068,12 +1084,9 @@ linux-64-debug: linux-64-thr: $(MAKE) all \ "ARCH = linux-64-thr" \ @@ -583,7 +583,7 @@ "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" -@@ -1081,17 +1094,14 @@ +@@ -1081,17 +1094,14 @@ linux-64-thr: linux-p4: $(MAKE) all \ "ARCH = linux-p4" \ @@ -603,7 +603,7 @@ linux-p4-icc: $(MAKE) all \ "ARCH = linux-p4-icc" \ -@@ -1119,23 +1129,17 @@ +@@ -1119,23 +1129,17 @@ linux-p4-icc-thr: linux-athlon: $(MAKE) all \ "ARCH = linux-athlon" \ @@ -627,7 +627,7 @@ "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" -@@ -1167,21 +1171,16 @@ +@@ -1167,21 +1171,25 @@ linux-athlon-pgcc: linux-thr: $(MAKE) all \ "ARCH = linux-thr" \ @@ -637,6 +637,15 @@ "ARFLAGS = r" \ "STRIP = strip" \ - "RANLIB = ranlib" \ ++ "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" ++ ++# Linux Arm using gcc, with threads ++linux-arm-thr: ++ $(MAKE) all \ ++ "ARCH = linux-arm-thr" \ ++ "CFLAGS = -Wall -O3 -fomit-frame-pointer -ffast-math -DLinux -DTHR -D_REENTRANT $(MISCFLAGS)" \ ++ "ARFLAGS = r" \ ++ "STRIP = strip" \ "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" # Linux x86 using gcc, threads, and OpenGL @@ -649,7 +658,7 @@ "ARFLAGS = r" \ "STRIP = touch" \ "LIBS = -L. -ltachyon $(MISCLIB) $(LINUX_GLX_LIBS) $(MISCLIB) -lm -lpthread" -@@ -1190,24 +1189,18 @@ +@@ -1190,24 +1198,18 @@ linux-thr-ogl: linux-beowulf-mpi-ogl: $(MAKE) all \ "ARCH = linux-beowulf-mpi" \ @@ -674,7 +683,7 @@ "LIBS = -L. -ltachyon -lmpi $(MISCLIB) -lm" # Linux x86 using LAM MPI -@@ -1239,10 +1232,8 @@ +@@ -1239,10 +1241,8 @@ linux-mpi: "ARCH = linux-mpi" \ "CC = mpicc" \ "CFLAGS = -DLinux -DMPI $(MISCFLAGS)" \ @@ -685,7 +694,7 @@ "LIBS = -L. -ltachyon $(MISCLIB) -lm" linux-mpi-thr: -@@ -1250,10 +1241,8 @@ +@@ -1250,10 +1250,8 @@ linux-mpi-thr: "ARCH = linux-mpi-thr" \ "CC = mpicc" \ "CFLAGS = -DLinux -DMPI -DTHR $(MISCFLAGS)" \ @@ -696,7 +705,7 @@ "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" linux-mpi-64: -@@ -1261,10 +1250,8 @@ +@@ -1261,10 +1259,8 @@ linux-mpi-64: "ARCH = linux-mpi-64" \ "CC = mpicc" \ "CFLAGS = -Wall -O3 -fomit-frame-pointer -ffast-math -I$(LAMHOME)/h -DLinux -DMPI -DLP64 $(MISCFLAGS)" \ @@ -707,7 +716,7 @@ "LIBS = -L. -L$(LAMHOME)/lib -ltachyon $(MISCLIB) -lm" -@@ -1297,48 +1284,36 @@ +@@ -1297,48 +1293,36 @@ linux-lam-thr: linux-ipaq: $(MAKE) all \ "ARCH = linux-ipaq" \ @@ -759,7 +768,7 @@ "LIBS = -L. -ltachyon $(MISCLIB) -lm" # Linux Alpha using Compaq's compilers -@@ -1369,12 +1344,9 @@ +@@ -1369,12 +1353,9 @@ linux-alpha-ccc-qsw: linux-ia64: $(MAKE) all \ "ARCH = linux-ia64" \ @@ -773,7 +782,7 @@ "LIBS = -L. -ltachyon $(MISCLIB) -lm" # Linux IA-64 using SGI compilers (Merced, Itanium, McKinley, etc) -@@ -1393,12 +1365,9 @@ +@@ -1393,12 +1374,9 @@ linux-ia64-sgicc: linux-ia64-thr: $(MAKE) all \ "ARCH = linux-ia64-thr" \ @@ -787,7 +796,7 @@ "LIBS = -L. -ltachyon $(MISCLIB) -lm -lpthread" # Linux IA-64 using SGI compilers and threads (Merced, Itanium, McKinley, etc) -@@ -1421,9 +1390,7 @@ +@@ -1421,9 +1399,7 @@ linux-ia64-thr-sgicc: sgi-altix-mpi: $(MAKE) all \ "ARCH = sgi-altix-mpi" \ @@ -797,7 +806,7 @@ "ARFLAGS = r" \ "STRIP = strip" \ "LIBS = -ltachyon -lmpi $(MISCLIB) -lm " -@@ -1432,7 +1399,7 @@ +@@ -1432,7 +1408,7 @@ sgi-altix-mpi: ## CSPI PowerPC Based Multicomputers Running VXWORKS ## This configuration works for the machine at MPI Software Technologies ## Uses MSTI MPI/Pro for message passing. @@ -806,7 +815,7 @@ cspi-ppc-mpi: $(MAKE) all \ "ARCH = cspi-ppc-mpi" \ -@@ -1448,7 +1415,7 @@ +@@ -1448,7 +1424,7 @@ cspi-ppc-mpi: ## Mercury PowerPC Based Multicomputers Running MCOS ## This configuration works for the machine at MPI Software Technologies ## Uses MSTI MPI/Pro for message passing. @@ -815,7 +824,7 @@ mercury-ppc-mpi: $(MAKE) all \ "ARCH = mercury-ppc-mpi" \ -@@ -1469,7 +1436,7 @@ +@@ -1469,7 +1445,7 @@ mercury-ppc-mpi-rtvi: "ARFLAGS = -r" \ "STRIP = /bin/touch" \ "LIBS = -L. -L/opt/MPIPro/lib ../compile/mercury-ppc-mpi-rtvi/libmgf.a ../compile/mercury-ppc-mpi-rtvi/libray.a $(RTVILIB) -lmpi.appc" @@ -824,7 +833,7 @@ @echo " Also, copy your machines file into your CWD." ## -@@ -1490,7 +1457,7 @@ +@@ -1490,7 +1466,7 @@ mercury-i860-rtvi: ## Mercury i860 Based Multicomputers Running MCOS ## This configuration works for the machine at MPI Software Technologies ## Uses MSTI MPI/Pro for message passing. diff --git a/build/pkgs/tachyon/spkg-install b/build/pkgs/tachyon/spkg-install index 1e83b92ad40..7365487f552 100755 --- a/build/pkgs/tachyon/spkg-install +++ b/build/pkgs/tachyon/spkg-install @@ -72,8 +72,7 @@ if [ "$UNAME" = "Linux" ]; then ppc*|powerpc*) $MAKE linux-ppc;; armv6l|armv7l) - sed "s/-m32//g" ../../patches/Make-arch > Make-arch - $MAKE linux-thr;; + $MAKE linux-arm-thr;; *) # e.g. SPARC echo "Error: Sorry, your platform isn't supported by Tachyon and/or Sage. Exiting..." exit 1 From abf86ee926f7ced530f6f7e8bdf78b76de1bd7d9 Mon Sep 17 00:00:00 2001 From: "Erik M. Bray" Date: Thu, 29 Dec 2016 12:19:07 +0000 Subject: [PATCH 177/185] Generate auto-generated sources as the earliest step in the 'build' command. Make sure that entire sub-packages that are auto-generated (namely, sage.ext.interpreters) is added to the distribution's list of packages. --- src/sage_setup/autogen/__init__.py | 7 +++++++ src/setup.py | 26 +++++++++++++++++--------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/sage_setup/autogen/__init__.py b/src/sage_setup/autogen/__init__.py index 52675fcefc8..4d4b22af2ac 100644 --- a/src/sage_setup/autogen/__init__.py +++ b/src/sage_setup/autogen/__init__.py @@ -10,3 +10,10 @@ def autogen_all(): from sage_setup.autogen import interpreters interpreters.rebuild(os.path.join("sage", "ext", "interpreters")) + + # Return list of sub-packages that should be appended to the list of + # packages built/installed by setup.py + # + # In the case of Pari it just adds new files to an existing package (rather + # than autogenerating the entire sub-package) so it's omitted here. + return ['sage.ext.interpreters'] diff --git a/src/setup.py b/src/setup.py index 4d20a0f0274..a4a41b75d86 100755 --- a/src/setup.py +++ b/src/setup.py @@ -4,6 +4,7 @@ import os, sys, time, errno, platform, subprocess from distutils import log from distutils.core import setup, DistutilsSetupError +from distutils.command.build import build from distutils.command.build_ext import build_ext from distutils.command.install import install from distutils.dep_util import newer_group @@ -664,16 +665,22 @@ def copy_extra_files(self): for src in src_files: self.copy_file(src, dst, preserve_mode=False) -######################################################### -### Generating auto-generated Sources -### This must be done before discovering and building -### the python modules. See #22094. -######################################################### -log.info("Generating auto-generated sources") -from sage_setup.autogen import autogen_all +class sage_build(build): + def run_autogen(self): + """ + Generating auto-generated Sources This must be done before discovering + and building the python modules. See #22106. + """ + + from sage_setup.autogen import autogen_all + log.info("Generating auto-generated sources") + self.distribution.packages += autogen_all() + + def run(self): + self.run_autogen() + build.run(self) -autogen_all() ######################################################### ### Discovering Sources @@ -764,5 +771,6 @@ def clean_stale_files(self): author_email= 'http://groups.google.com/group/sage-support', url = 'http://www.sagemath.org', packages = python_packages, - cmdclass = dict(build_ext=sage_build_ext, install=sage_install), + cmdclass = dict(build=sage_build, build_ext=sage_build_ext, + install=sage_install), ext_modules = ext_modules) From d311e0e0a32419a5bb6110f8bb828181b1e52b31 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Mon, 2 Jan 2017 10:28:20 +0100 Subject: [PATCH 178/185] Cosmetic changes --- src/sage_setup/autogen/__init__.py | 11 ++++++----- src/setup.py | 7 ++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/sage_setup/autogen/__init__.py b/src/sage_setup/autogen/__init__.py index 4d4b22af2ac..2fa39b94f4b 100644 --- a/src/sage_setup/autogen/__init__.py +++ b/src/sage_setup/autogen/__init__.py @@ -4,6 +4,9 @@ def autogen_all(): """ Regenerate the automatically generated files of the Sage library. + + Return a list of sub-packages that should be appended to the list + of packages built/installed by setup.py. """ from sage_setup.autogen import pari pari.rebuild() @@ -11,9 +14,7 @@ def autogen_all(): from sage_setup.autogen import interpreters interpreters.rebuild(os.path.join("sage", "ext", "interpreters")) - # Return list of sub-packages that should be appended to the list of - # packages built/installed by setup.py - # - # In the case of Pari it just adds new files to an existing package (rather - # than autogenerating the entire sub-package) so it's omitted here. + # In the case of Pari it just adds new files to an existing package + # (rather than autogenerating the entire sub-package) so it is + # omitted here. return ['sage.ext.interpreters'] diff --git a/src/setup.py b/src/setup.py index a4a41b75d86..ddd151a106d 100755 --- a/src/setup.py +++ b/src/setup.py @@ -669,10 +669,11 @@ def copy_extra_files(self): class sage_build(build): def run_autogen(self): """ - Generating auto-generated Sources This must be done before discovering - and building the python modules. See #22106. - """ + Generate auto-generated sources. + This must be done before building the python modules, + see :trac:`22106`. + """ from sage_setup.autogen import autogen_all log.info("Generating auto-generated sources") self.distribution.packages += autogen_all() From d9d6e54c6785097cbf6f6720bd46ff042bc2ca64 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Tue, 28 Mar 2017 14:41:49 +0200 Subject: [PATCH 179/185] Only add packages which did not exist already --- src/setup.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/setup.py b/src/setup.py index ddd151a106d..68ee9ea0064 100755 --- a/src/setup.py +++ b/src/setup.py @@ -676,7 +676,9 @@ def run_autogen(self): """ from sage_setup.autogen import autogen_all log.info("Generating auto-generated sources") - self.distribution.packages += autogen_all() + for pkg in autogen_all(): + if pkg not in self.distribution.packages: + self.distribution.packages.append(pkg) def run(self): self.run_autogen() From 4394a22ef16c6e7934c2c6b318c0ad594fec7d29 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Tue, 28 Mar 2017 15:29:35 +0200 Subject: [PATCH 180/185] Only wrap pari_err2str() in sig_block() --- src/sage/libs/cypari2/handle_error.pyx | 33 +++++++++++++------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/sage/libs/cypari2/handle_error.pyx b/src/sage/libs/cypari2/handle_error.pyx index d99dc60d803..0abd5da8da2 100644 --- a/src/sage/libs/cypari2/handle_error.pyx +++ b/src/sage/libs/cypari2/handle_error.pyx @@ -143,8 +143,7 @@ cdef void _pari_init_error_handling(): cdef int _pari_err_handle(GEN E) except 0: """ - Convert a PARI error into a Sage exception, unless the error was - a stack overflow, in which case we enlarge the stack. + Convert a PARI error into a Sage exception. This function is a callback from the PARI error handler. @@ -161,28 +160,28 @@ cdef int _pari_err_handle(GEN E) except 0: """ cdef long errnum = E[1] - - sig_block() cdef char* errstr cdef const char* s - try: - if errnum == e_STACK: - # Custom error message for PARI stack overflow - pari_error_string = "the PARI stack overflows (current size: {}; maximum size: {})\n" - pari_error_string += "You can use pari.allocatemem() to change the stack size and try again" - pari_error_string = pari_error_string.format(pari_mainstack.size, pari_mainstack.vsize) - else: + + if errnum == e_STACK: + # Custom error message for PARI stack overflow + pari_error_string = "the PARI stack overflows (current size: {}; maximum size: {})\n" + pari_error_string += "You can use pari.allocatemem() to change the stack size and try again" + pari_error_string = pari_error_string.format(pari_mainstack.size, pari_mainstack.vsize) + else: + sig_block() + try: errstr = pari_err2str(E) pari_error_string = errstr.decode('ascii') pari_free(errstr) + finally: + sig_unblock() - s = closure_func_err() - if s is not NULL: - pari_error_string = s.decode('ascii') + ": " + pari_error_string + s = closure_func_err() + if s is not NULL: + pari_error_string = s.decode('ascii') + ": " + pari_error_string - raise PariError(errnum, pari_error_string, new_gen_noclear(E)) - finally: - sig_unblock() + raise PariError(errnum, pari_error_string, new_gen_noclear(E)) cdef void _pari_err_recover(long errnum): From 12e7d1cd8ec4e28a2f10e4d79492d0cf1ff3d2fe Mon Sep 17 00:00:00 2001 From: Moritz Firsching Date: Sun, 5 Mar 2017 10:28:54 +0100 Subject: [PATCH 181/185] install of beta 3.1-beta2 now works --- build/pkgs/polymake/checksums.ini | 8 ++++---- build/pkgs/polymake/package-version.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/pkgs/polymake/checksums.ini b/build/pkgs/polymake/checksums.ini index 8c029dabb1c..622259de226 100644 --- a/build/pkgs/polymake/checksums.ini +++ b/build/pkgs/polymake/checksums.ini @@ -1,4 +1,4 @@ -tarball=polymake-VERSION-minimal.tar.bz2 -sha1=0c96b4f2c9e56d72131166d2c9a7f25fffa99107 -md5=c1f5d71cdd86d0339c3e642494d6ac67 -cksum=3739642796 +tarball=polymake-VERSION.tar.bz2 +sha1=b4cf46d5476e16fef9c664d82a8890dbf2c1bc4b +md5=30a1a9f25ba01e5181fe3fa84743c273 +cksum=2568837152 diff --git a/build/pkgs/polymake/package-version.txt b/build/pkgs/polymake/package-version.txt index 8c44f27dd73..8dbbb63f2cc 100644 --- a/build/pkgs/polymake/package-version.txt +++ b/build/pkgs/polymake/package-version.txt @@ -1 +1 @@ -3.0r2 +3.1-beta2 From 9f0c6d50420346c3c5564a0d6354774520bedac6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 Mar 2017 12:01:15 -0700 Subject: [PATCH 182/185] Upgrade polymake to version 3.1 --- build/pkgs/polymake/checksums.ini | 8 ++++---- build/pkgs/polymake/package-version.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/pkgs/polymake/checksums.ini b/build/pkgs/polymake/checksums.ini index 622259de226..b121a75bbfc 100644 --- a/build/pkgs/polymake/checksums.ini +++ b/build/pkgs/polymake/checksums.ini @@ -1,4 +1,4 @@ -tarball=polymake-VERSION.tar.bz2 -sha1=b4cf46d5476e16fef9c664d82a8890dbf2c1bc4b -md5=30a1a9f25ba01e5181fe3fa84743c273 -cksum=2568837152 +tarball=polymake-VERSION-minimal.tar.bz2 +sha1=4e08e82789733cb790891a828836e218e8483b3b +md5=4ae61ddf1da139700ec4611eaeefd7a9 +cksum=591217498 diff --git a/build/pkgs/polymake/package-version.txt b/build/pkgs/polymake/package-version.txt index 8dbbb63f2cc..8c50098d8ae 100644 --- a/build/pkgs/polymake/package-version.txt +++ b/build/pkgs/polymake/package-version.txt @@ -1 +1 @@ -3.1-beta2 +3.1 From d48516b28859f434c84ad5d41471a58b49704c84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konrad=20K=2E=20D=C4=85browski?= Date: Tue, 28 Mar 2017 22:47:49 +0000 Subject: [PATCH 183/185] Fix cython testsuite on 32-bit --- build/pkgs/cython/patches/cpdef_enums.pyx.patch | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 build/pkgs/cython/patches/cpdef_enums.pyx.patch diff --git a/build/pkgs/cython/patches/cpdef_enums.pyx.patch b/build/pkgs/cython/patches/cpdef_enums.pyx.patch new file mode 100644 index 00000000000..b81cb68efba --- /dev/null +++ b/build/pkgs/cython/patches/cpdef_enums.pyx.patch @@ -0,0 +1,12 @@ +Fix Cython testsuite failure on 32-bit +From upstream commit: d92a718a26c9354fbf35f31a17de5c069865a447 +See also: https://github.com/cython/cython/issues/1548 + +--- a/tests/run/cpdef_enums.pyx ++++ b/tests/run/cpdef_enums.pyx +@@ -93,4 +93,4 @@ def verify_resolution_GH1533(): + 3 + """ + THREE = 100 +- return PyxEnum.THREE ++ return int(PyxEnum.THREE) From 52a77ee1b1fd70e0d6371f2789c4b6bfffe511ec Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 Mar 2017 19:20:32 -0700 Subject: [PATCH 184/185] PolymakeElement._member_list: Fix for python 3 syntax --- src/sage/interfaces/polymake.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/interfaces/polymake.py b/src/sage/interfaces/polymake.py index a703928cd5e..83593ba967b 100644 --- a/src/sage/interfaces/polymake.py +++ b/src/sage/interfaces/polymake.py @@ -1500,7 +1500,7 @@ def _member_list(self): cmd = 'print join(", ", sorted_uniq(sort { $a cmp $b } map { keys %{$_->properties} }$SAGETMP, @{$SAGETMP->super}));' try: out = P.eval(cmd).split(', ') - except PolymakeError, msg: + except PolymakeError as msg: return [] return sorted(out) From 8725c635c3e1df92d76f7d31cd168f47c0b48a9b Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Thu, 30 Mar 2017 23:37:55 +0200 Subject: [PATCH 185/185] Updated SageMath version to 8.0.beta0 --- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 6 +++--- build/pkgs/configure/package-version.txt | 2 +- src/bin/sage-banner | 5 ++++- src/bin/sage-version.sh | 4 ++-- src/sage/version.py | 4 ++-- 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index 03b43a5c15a..9cea1398c5a 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 7.6, Release Date: 2017-03-25 +SageMath version 8.0.beta0, Release Date: 2017-03-30 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 80ea8d9ca72..4d356f2f416 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=7a84c43745334f9940826319b4799e3e7883ee17 -md5=e897b888529be545e40ddb697c778a89 -cksum=3005224762 +sha1=b7df014e2f3dc762a43a96a2e49553a301b6eb75 +md5=c8c2f7b67bc0a9784b30239c7b65ba17 +cksum=3421961180 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 0d389107a34..964480f63e4 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -212 +213 diff --git a/src/bin/sage-banner b/src/bin/sage-banner index 713519bfc9e..3b9be49822f 100644 --- a/src/bin/sage-banner +++ b/src/bin/sage-banner @@ -1,5 +1,8 @@ ┌────────────────────────────────────────────────────────────────────┐ -│ SageMath version 7.6, Release Date: 2017-03-25 │ +│ SageMath version 8.0.beta0, Release Date: 2017-03-30 │ │ Type "notebook()" for the browser-based notebook interface. │ │ Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Warning: this is a prerelease version, and it may be unstable. ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index b168f200bc6..2ff893d85b2 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -1,4 +1,4 @@ # Sage version information for shell scripts # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='7.6' -SAGE_RELEASE_DATE='2017-03-25' +SAGE_VERSION='8.0.beta0' +SAGE_RELEASE_DATE='2017-03-30' diff --git a/src/sage/version.py b/src/sage/version.py index 17f9cdfb98f..00ba3f71632 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,4 +1,4 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '7.6' -date = '2017-03-25' +version = '8.0.beta0' +date = '2017-03-30'