From 482dfc486aca79386b12da206170776869255aef Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 11 Jan 2020 00:32:39 -0500 Subject: [PATCH 01/77] Add src/tox.ini --- src/tox.ini | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/tox.ini diff --git a/src/tox.ini b/src/tox.ini new file mode 100644 index 00000000000..742e089b6a3 --- /dev/null +++ b/src/tox.ini @@ -0,0 +1,10 @@ +[tox] +envlist = doctest +skipsdist = true + +[testenv:doctest] +whitelist_externals = {toxinidir}/../sage +passenv = + HOME +commands = + {toxinidir}/../sage -t -p 0 {posargs:--all} From e15f33da976e8b99bd29d9aa0bcb4d3403ae96a1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 2 Feb 2020 10:41:14 -0500 Subject: [PATCH 02/77] src/tox.ini: Add commentss on usage --- src/tox.ini | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/tox.ini b/src/tox.ini index 742e089b6a3..4d3eef48a37 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -1,8 +1,23 @@ +## If the system python has tox installed, you can use it to run +## the sage doctests. From the SAGE_ROOT/src directory: +## +## $ tox +## +## Arguments are passed on to "sage -t": +## +## $ tox src/sage/geometry +## +## To pass on options to "sage -t", use -- to separate it from tox options: +## +## $ tox -- --verbose --optional=sage,pynormaliz --long sage/geometry +## [tox] envlist = doctest skipsdist = true [testenv:doctest] +## This toxenv bypasses the virtual environment set up by tox. +## It calls sage directly and invokes the doctester. whitelist_externals = {toxinidir}/../sage passenv = HOME From 0860f1acf5db02eba028f18f4873bea471ef484a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 2 Feb 2020 10:49:07 -0500 Subject: [PATCH 03/77] fixup --- src/tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tox.ini b/src/tox.ini index 4d3eef48a37..798c2f8cceb 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -5,7 +5,7 @@ ## ## Arguments are passed on to "sage -t": ## -## $ tox src/sage/geometry +## $ tox sage/geometry ## ## To pass on options to "sage -t", use -- to separate it from tox options: ## From ea5eb69ceedf16452ae5a2673a05089f6e0d41d5 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Sat, 15 Feb 2020 17:05:24 +0100 Subject: [PATCH 04/77] use both Vrep and Hrep to obtain dilation --- .../en/thematic_tutorials/geometry/tips.rst | 50 +++++++++---------- src/sage/geometry/polyhedron/base.py | 35 ++++++++++++- .../geometry/polyhedron/representation.py | 4 +- 3 files changed, 60 insertions(+), 29 deletions(-) diff --git a/src/doc/en/thematic_tutorials/geometry/tips.rst b/src/doc/en/thematic_tutorials/geometry/tips.rst index a484b5d2f72..9e2de1b16b6 100644 --- a/src/doc/en/thematic_tutorials/geometry/tips.rst +++ b/src/doc/en/thematic_tutorials/geometry/tips.rst @@ -43,13 +43,13 @@ object, you can! sage: Cube = polytopes.cube() sage: TCube = Cube.truncation().dilation(1/2) sage: sage_input(TCube) - Polyhedron(backend='ppl', base_ring=QQ, vertices=[(-1/2, -1/2, -1/6), - (-1/2, -1/2, 1/6), (-1/2, -1/6, -1/2), (-1/2, -1/6, 1/2), (-1/2, 1/6, - -1/2), (-1/2, 1/6, 1/2), (-1/2, 1/2, -1/6), (-1/2, 1/2, 1/6), (-1/6, -1/2, - -1/2), (-1/6, -1/2, 1/2), (-1/6, 1/2, -1/2), (-1/6, 1/2, 1/2), (1/6, -1/2, - -1/2), (1/6, -1/2, 1/2), (1/6, 1/2, -1/2), (1/6, 1/2, 1/2), (1/2, -1/2, - -1/6), (1/2, -1/2, 1/6), (1/2, -1/6, -1/2), (1/2, -1/6, 1/2), (1/2, 1/6, - -1/2), (1/2, 1/6, 1/2), (1/2, 1/2, -1/6), (1/2, 1/2, 1/6)]) + Polyhedron(backend='ppl', base_ring=QQ, vertices=[(1/6, -1/2, -1/2), + (1/2, -1/6, -1/2), (1/2, 1/6, -1/2), (1/2, 1/2, -1/6), (1/2, 1/2, 1/6), + (1/2, 1/6, 1/2), (1/6, 1/2, 1/2), (1/2, -1/6, 1/2), (1/6, 1/2, -1/2), + (1/6, -1/2, 1/2), (1/2, -1/2, 1/6), (1/2, -1/2, -1/6), (-1/2, 1/6, -1/2), + (-1/2, -1/2, 1/6), (-1/2, 1/6, 1/2), (-1/2, 1/2, 1/6), (-1/6, 1/2, 1/2), + (-1/2, 1/2, -1/6), (-1/6, 1/2, -1/2), (-1/2, -1/6, 1/2), (-1/6, -1/2, 1/2), + (-1/2, -1/2, -1/6), (-1/6, -1/2, -1/2), (-1/2, -1/6, -1/2)]) .. end of output @@ -64,37 +64,37 @@ the latex presentation, there is a method for that! sage: Nice_repr = TCube.Hrepresentation_str() sage: print(Nice_repr) + -6*x0 - 6*x1 - 6*x2 >= -7 + -6*x0 - 6*x1 + 6*x2 >= -7 + -6*x0 + 6*x1 - 6*x2 >= -7 + -6*x0 + 6*x1 + 6*x2 >= -7 -2*x0 >= -1 -2*x1 >= -1 - -6*x0 + 6*x1 - 6*x2 >= -7 - 2*x0 >= -1 + -2*x2 >= -1 + 6*x0 + 6*x1 + 6*x2 >= -7 + 2*x2 >= -1 2*x1 >= -1 + 2*x0 >= -1 6*x0 - 6*x1 - 6*x2 >= -7 - 6*x0 + 6*x1 - 6*x2 >= -7 6*x0 - 6*x1 + 6*x2 >= -7 - 6*x0 + 6*x1 + 6*x2 >= -7 - 2*x2 >= -1 - -2*x2 >= -1 - -6*x0 + 6*x1 + 6*x2 >= -7 - -6*x0 - 6*x1 + 6*x2 >= -7 - -6*x0 - 6*x1 - 6*x2 >= -7 + 6*x0 + 6*x1 - 6*x2 >= -7 sage: print(TCube.Hrepresentation_str(latex=True)) \begin{array}{rcl} + -6 \, x_{0} - 6 \, x_{1} - 6 \, x_{2} & \geq & -7 \\ + -6 \, x_{0} - 6 \, x_{1} + 6 \, x_{2} & \geq & -7 \\ + -6 \, x_{0} + 6 \, x_{1} - 6 \, x_{2} & \geq & -7 \\ + -6 \, x_{0} + 6 \, x_{1} + 6 \, x_{2} & \geq & -7 \\ -2 \, x_{0} & \geq & -1 \\ -2 \, x_{1} & \geq & -1 \\ - -6 \, x_{0} + 6 \, x_{1} - 6 \, x_{2} & \geq & -7 \\ - 2 \, x_{0} & \geq & -1 \\ + -2 \, x_{2} & \geq & -1 \\ + 6 \, x_{0} + 6 \, x_{1} + 6 \, x_{2} & \geq & -7 \\ + 2 \, x_{2} & \geq & -1 \\ 2 \, x_{1} & \geq & -1 \\ + 2 \, x_{0} & \geq & -1 \\ 6 \, x_{0} - 6 \, x_{1} - 6 \, x_{2} & \geq & -7 \\ - 6 \, x_{0} + 6 \, x_{1} - 6 \, x_{2} & \geq & -7 \\ 6 \, x_{0} - 6 \, x_{1} + 6 \, x_{2} & \geq & -7 \\ - 6 \, x_{0} + 6 \, x_{1} + 6 \, x_{2} & \geq & -7 \\ - 2 \, x_{2} & \geq & -1 \\ - -2 \, x_{2} & \geq & -1 \\ - -6 \, x_{0} + 6 \, x_{1} + 6 \, x_{2} & \geq & -7 \\ - -6 \, x_{0} - 6 \, x_{1} + 6 \, x_{2} & \geq & -7 \\ - -6 \, x_{0} - 6 \, x_{1} - 6 \, x_{2} & \geq & -7 + 6 \, x_{0} + 6 \, x_{1} - 6 \, x_{2} & \geq & -7 \end{array} sage: Latex_repr = LatexExpr(TCube.Hrepresentation_str(latex=True)) diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index 614a49ee1d8..f4443b8fb65 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -4297,22 +4297,53 @@ def dilation(self, scalar): sage: P = polytopes.simplex(backend='field') sage: P.dilation(3).backend() 'field' + + Dilation with both Vrep and Hrep works correctly:: + + sage: def test_dilation(P): + ....: Q = P.change_ring(P.base_ring(), backend='field') + ....: assert 2*Q == 2*P + ....: assert 1/2*Q == 1/2*P + ....: assert (-3)*Q == (-3)*P + ....: assert (-1/2)*Q == (-1/2)*P + sage: test_dilation(polytopes.cube()) + sage: test_dilation(polytopes.cross_polytope(3)) + sage: test_dilation(polytopes.simplex(4)) + sage: test_dilation(polytopes.permutahedron(3)) + sage: test_dilation(polytopes.permutahedron(3)*Polyhedron(rays=[[0,0,1],[0,1,1],[1,2,3]])) + sage: test_dilation(polytopes.permutahedron(3)*Polyhedron(rays=[[0,0,1],[0,1,1]], lines=[[1,0,0]])) """ + parent = self.parent().base_extend(scalar) + one = parent.base_ring().one() if scalar > 0: new_vertices = [ list(scalar*v.vector()) for v in self.vertex_generator() ] new_rays = self.rays() new_lines = self.lines() + new_inequalities = [f.vector()*one for f in self.inequality_generator()] + for f in new_inequalities: + f[0] *= scalar + new_equations = [e.vector()*one for e in self.equation_generator()] + for e in new_equations: + e[0] *= scalar elif scalar < 0: new_vertices = [ list(scalar*v.vector()) for v in self.vertex_generator() ] new_rays = [ list(-r.vector()) for r in self.ray_generator()] new_lines = self.lines() + new_inequalities = [-f.vector()*one for f in self.inequality_generator()] + for f in new_inequalities: + f[0] *= scalar + new_equations = [-e.vector()*one for e in self.equation_generator()] + for e in new_equations: + e[0] *= scalar else: new_vertices = [ self.ambient_space().zero() for v in self.vertex_generator() ] new_rays = [] new_lines = [] + return parent.element_class(parent, [new_vertices, new_rays, new_lines], None) - parent = self.parent().base_extend(scalar) - return parent.element_class(parent, [new_vertices, new_rays, new_lines], None) + return parent.element_class(parent, [new_vertices, new_rays, new_lines], + [new_inequalities, new_equations], + Vrep_minimal=True, Hrep_minimal=True) def linear_transformation(self, linear_transf): """ diff --git a/src/sage/geometry/polyhedron/representation.py b/src/sage/geometry/polyhedron/representation.py index 8d29c4fac62..6b55521c093 100644 --- a/src/sage/geometry/polyhedron/representation.py +++ b/src/sage/geometry/polyhedron/representation.py @@ -751,7 +751,7 @@ def contains(self, Vobj): [True, True, True, True, True, True] sage: p2 = 3*polytopes.hypercube(3) sage: [i1.contains(q) for q in p2.vertex_generator()] - [True, False, False, False, True, True, True, False] + [True, True, False, True, False, True, False, False] """ try: if Vobj.is_vector(): # assume we were passed a point @@ -778,7 +778,7 @@ def interior_contains(self, Vobj): [False, True, True, False, False, True] sage: p2 = 3*polytopes.hypercube(3) sage: [i1.interior_contains(q) for q in p2.vertex_generator()] - [True, False, False, False, True, True, True, False] + [True, True, False, True, False, True, False, False] If you pass a vector, it is assumed to be the coordinate vector of a point:: From a1d8b0b40344c69a60902d6d3ccfb3752776e51a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 22 Aug 2019 23:23:07 -0400 Subject: [PATCH 05/77] qepcad: Fix ARFLAGS for macOS --- build/pkgs/qepcad/spkg-install | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build/pkgs/qepcad/spkg-install b/build/pkgs/qepcad/spkg-install index 5db42370b73..937760c0790 100644 --- a/build/pkgs/qepcad/spkg-install +++ b/build/pkgs/qepcad/spkg-install @@ -15,7 +15,9 @@ export qe=$(pwd -P) # https://trac.sagemath.org/ticket/10224 # * Add rpath to compiler flags, see # https://trac.sagemath.org/ticket/22653 -$MAKE -j1 opt SHELL=/bin/sh FLAGSo="-O3 -g -Wl,-rpath,$SAGE_LOCAL/lib" +# * User ARFLAGS that also work on macOS, avoiding the U option, see +# https://trac.sagemath.org/ticket/28388 +$MAKE -j1 opt SHELL=/bin/sh FLAGSo="-O3 -g -Wl,-rpath,$SAGE_LOCAL/lib" ARFLAGS="crv" if [ $? -ne 0 ]; then echo >&2 "Error building qepcad." exit 1 From a2652fc2e6e3817030f6a6aa97d9c8c7567dda43 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 22 Aug 2019 23:23:48 -0400 Subject: [PATCH 06/77] qepcad: Add patche s for macOS --- .../0001-Don-t-use-timer_t-on-macOS.patch | 34 +++++++++++++ .../patches/0002-WIP-Don-t-add-lrt.patch | 49 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 build/pkgs/qepcad/patches/0001-Don-t-use-timer_t-on-macOS.patch create mode 100644 build/pkgs/qepcad/patches/0002-WIP-Don-t-add-lrt.patch diff --git a/build/pkgs/qepcad/patches/0001-Don-t-use-timer_t-on-macOS.patch b/build/pkgs/qepcad/patches/0001-Don-t-use-timer_t-on-macOS.patch new file mode 100644 index 00000000000..a2b81959142 --- /dev/null +++ b/build/pkgs/qepcad/patches/0001-Don-t-use-timer_t-on-macOS.patch @@ -0,0 +1,34 @@ +From cc535b88a2ac93fdd390a7ef8ab6005d7a3cd8a0 Mon Sep 17 00:00:00 2001 +From: Matthias Koeppe +Date: Thu, 22 Aug 2019 22:18:17 -0400 +Subject: [PATCH 1/2] Don't use timer_t on macOS + +--- + source/main/MAIN.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/source/main/MAIN.c b/source/main/MAIN.c +index 723306d..73f8cef 100644 +--- a/source/main/MAIN.c ++++ b/source/main/MAIN.c +@@ -81,6 +81,9 @@ static void init_SIGINT_handler() + + static int sendSignalAfterInterval(int seconds, int signum) + { ++#ifdef __APPLE__ ++ return 1; ++#else + /* Create timer */ + timer_t timerid; + struct sigevent sev; +@@ -100,6 +103,7 @@ static int sendSignalAfterInterval(int seconds, int signum) + return 2; + + return 0; ++#endif + } + + int main(int argc, char **argv) +-- +2.19.0 + diff --git a/build/pkgs/qepcad/patches/0002-WIP-Don-t-add-lrt.patch b/build/pkgs/qepcad/patches/0002-WIP-Don-t-add-lrt.patch new file mode 100644 index 00000000000..54282fbf8f0 --- /dev/null +++ b/build/pkgs/qepcad/patches/0002-WIP-Don-t-add-lrt.patch @@ -0,0 +1,49 @@ +From 9fa8ce43a1ebbc1807528acf7d109abc19ba3ba4 Mon Sep 17 00:00:00 2001 +From: Matthias Koeppe +Date: Thu, 22 Aug 2019 22:39:21 -0400 +Subject: [PATCH 2/2] WIP: Don't add -lrt + +--- + source/Makefile | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/source/Makefile b/source/Makefile +index d184650..f13113b 100644 +--- a/source/Makefile ++++ b/source/Makefile +@@ -30,6 +30,14 @@ SPECIFLAGS = -I/opt/sfw/include + SPECLFLAGS = -lcurses # on solaris you have to link curses to get readline! + endif + ++LIBS = -lreadline ++ ++# On macOS, librt is not available, ++# see https://trac.sagemath.org/ticket/28388 ++#ifeq ($(findstring darwin,${OSTYPE}),) ++#LIBS += -lrt ++#endif ++ + # ============================================================ + # Do not touch below unless you know what you are doing + # ============================================================ +@@ -44,7 +52,7 @@ EXTLIBS = ${qe}/extensions/sfext/sfexto.a \ + ${qe}/extensions/adj2d/adj2do.a \ + ${qe}/extensions/rend/rendo.a \ + ${saclib}/lib/saclibo.a \ +- -lreadline -lrt \ ++ $(LIBS) \ + ${SPECLFLAGS} + + +@@ -54,7 +62,7 @@ EXTLIBSD = ${qe}/extensions/sfext/sfextd.a \ + ${qe}/extensions/adj2d/adj2dd.a \ + ${qe}/extensions/rend/rendd.a \ + ${saclib}/lib/saclibd.a \ +- -lreadline -lrt \ ++ $(LIBS) \ + ${SPECLFLAGS} + + NAME = qepcad +-- +2.19.0 + From 86f338aff1ea68bee6c970d29cf398f84747c2c9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 23 Aug 2019 15:54:58 -0400 Subject: [PATCH 07/77] qepcad: Add patches from Fedora, omitting qepcad-B-attr.patch (adds gccisms) --- .../qepcad/patches/qepcad-B-destructor.patch | 125 ++ build/pkgs/qepcad/patches/qepcad-B-env.patch | 12 + build/pkgs/qepcad/patches/qepcad-B-gcc6.patch | 59 + .../pkgs/qepcad/patches/qepcad-B-parens.patch | 132 ++ .../pkgs/qepcad/patches/qepcad-B-return.patch | 56 + .../pkgs/qepcad/patches/qepcad-B-signed.patch | 78 + .../pkgs/qepcad/patches/qepcad-B-syntax.patch | 22 + build/pkgs/qepcad/patches/qepcad-B-tty.patch | 45 + .../pkgs/qepcad/patches/qepcad-B-uninit.patch | 314 +++ .../pkgs/qepcad/patches/qepcad-B-unused.patch | 1739 +++++++++++++++++ 10 files changed, 2582 insertions(+) create mode 100644 build/pkgs/qepcad/patches/qepcad-B-destructor.patch create mode 100644 build/pkgs/qepcad/patches/qepcad-B-env.patch create mode 100644 build/pkgs/qepcad/patches/qepcad-B-gcc6.patch create mode 100644 build/pkgs/qepcad/patches/qepcad-B-parens.patch create mode 100644 build/pkgs/qepcad/patches/qepcad-B-return.patch create mode 100644 build/pkgs/qepcad/patches/qepcad-B-signed.patch create mode 100644 build/pkgs/qepcad/patches/qepcad-B-syntax.patch create mode 100644 build/pkgs/qepcad/patches/qepcad-B-tty.patch create mode 100644 build/pkgs/qepcad/patches/qepcad-B-uninit.patch create mode 100644 build/pkgs/qepcad/patches/qepcad-B-unused.patch diff --git a/build/pkgs/qepcad/patches/qepcad-B-destructor.patch b/build/pkgs/qepcad/patches/qepcad-B-destructor.patch new file mode 100644 index 00000000000..2809a0af004 --- /dev/null +++ b/build/pkgs/qepcad/patches/qepcad-B-destructor.patch @@ -0,0 +1,125 @@ +--- a/extensions/rend/Rend_Sample.cc.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/rend/Rend_Sample.cc 2018-08-29 20:07:27.087257552 -0600 +@@ -40,11 +40,6 @@ Rend_Sample_1DS::Rend_Sample_1DS(Word C, + } + + +-Rend_Sample_1DS::~Rend_Sample_1DS() +-{ +- +-} +- + /************************************************************* + ** Refines I to 2^k or less, and returns binary rational + ** middle of interval. +@@ -112,13 +107,6 @@ Rend_Sample_1DO::Rend_Sample_1DO(Rend_Ce + L.W = NIL; + } + +- +-Rend_Sample_1DO::~Rend_Sample_1DO() +-{ +- +-} +- +- + Word Rend_Sample_1DO::coordinate(int k) + { + Word e,j1,j2,J,kp = k; +@@ -178,11 +166,6 @@ Rend_Sample_2DS::Rend_Sample_2DS(Word C) + } + + +-Rend_Sample_2DS::~Rend_Sample_2DS() +-{ +- +-} +- + /************************************************************* + ** Refines I to 2^k or less, and returns binary rational + ** lower endpoint. +@@ -237,11 +220,6 @@ Rend_Sample_2DC::Rend_Sample_2DC(Word C, + + } + +-Rend_Sample_2DC::~Rend_Sample_2DC() +-{ +- +-} +- + Word Rend_Sample_2DC::coordinate(int k) + { + return L.W; +@@ -265,11 +243,6 @@ Rend_Sample_BR::Rend_Sample_BR(Word a) + N.W = a; + } + +-Rend_Sample_BR::~Rend_Sample_BR() +-{ +- +-} +- + Word Rend_Sample_BR::coordinate(int k) + { + return N.W; +--- a/extensions/rend/Rend_Sample.h.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/rend/Rend_Sample.h 2018-08-29 20:07:27.087257552 -0600 +@@ -32,7 +32,7 @@ class Rend_Sample + virtual Word coordinate(int k) = 0; + virtual Word round(int k,int roundup) + { return this -> coordinate(k); } +- // virtual ~Rend_Sample() = 0; ++ virtual ~Rend_Sample() {} + }; + + class Rend_Sample_1DS : public Rend_Sample +@@ -49,7 +49,6 @@ private: + gcmemloc A,I; + public: + Rend_Sample_1DS(Word C, Word P); +- virtual ~Rend_Sample_1DS(); + virtual Word coordinate(int k); + virtual Word round(int k, int roundup); + Word weakcompare(Word R); +@@ -66,7 +65,6 @@ public: + gcmemloc L; + public: + Rend_Sample_1DO(Rend_Cell *dad); +- virtual ~Rend_Sample_1DO(); + virtual Word coordinate(int k); + + }; +@@ -86,7 +84,6 @@ private: + gcmemloc A,I; + public: + Rend_Sample_2DS(Word C); +- virtual ~Rend_Sample_2DS(); + virtual Word coordinate(int k); + + }; +@@ -101,7 +98,6 @@ public: + gcmemloc L; + public: + Rend_Sample_2DC(Word C,Word P); +- virtual ~Rend_Sample_2DC(); + virtual Word coordinate(int k); + void add_point(Word p); + void clear_points(); +@@ -116,7 +112,6 @@ private: + gcmemloc N; + public: + Rend_Sample_BR(Word a); +- virtual ~Rend_Sample_BR(); + virtual Word coordinate(int k); + }; + +--- a/plot2d/plot.cc.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/plot2d/plot.cc 2018-08-29 20:07:27.086257553 -0600 +@@ -37,6 +37,7 @@ class CADELT + public: + virtual bool read(istream &in) = 0; + virtual void glRend(const CADColors &C) = 0; ++ virtual ~CADELT() {} + }; + + class SNoverSR : public CADELT diff --git a/build/pkgs/qepcad/patches/qepcad-B-env.patch b/build/pkgs/qepcad/patches/qepcad-B-env.patch new file mode 100644 index 00000000000..ce32a5e8a87 --- /dev/null +++ b/build/pkgs/qepcad/patches/qepcad-B-env.patch @@ -0,0 +1,12 @@ +--- a/source/main/BEGINQEPCAD.c.orig 2018-01-30 14:04:58.000000000 -0700 ++++ b/source/main/BEGINQEPCAD.c 2018-08-29 20:03:05.718540333 -0600 +@@ -127,7 +127,8 @@ void BEGINQEPCAD(int &argc, char**& argv + void QEPCAD_ProcessRC(int argc, char **argv) + { + char *qepath = getenv("qe"); +- if (qepath == NULL) { FAIL("QEPCAD_ProcessRC","Environment variable qe not defined!"); } ++ if (qepath == NULL) { setenv("qe", "/usr/share/qepcad", 1); qepath = getenv("qe"); } ++ if (getenv("SINGULARPATH") == NULL) { setenv("SINGULARPATH", "@LIBDIR@/Singular", 1); } + string rcFileName = qepath + string("/default.qepcadrc"); + ifstream rcin(rcFileName.c_str()); + if (!rcin) { return; } diff --git a/build/pkgs/qepcad/patches/qepcad-B-gcc6.patch b/build/pkgs/qepcad/patches/qepcad-B-gcc6.patch new file mode 100644 index 00000000000..2caed816ca7 --- /dev/null +++ b/build/pkgs/qepcad/patches/qepcad-B-gcc6.patch @@ -0,0 +1,59 @@ +--- a/plot2d/plot.cc.orig 2018-08-29 20:10:06.396075816 -0600 ++++ b/plot2d/plot.cc 2018-08-29 20:11:48.982924732 -0600 +@@ -276,7 +276,7 @@ bool SNoverSR::read(istream &in) + V.resize(N); + for(int i = 0; i < N; i++) + in >> V[i]; +- return in; ++ return in.good(); + } + + void SNoverSR::glRend(const CADColors &C) +@@ -333,7 +333,7 @@ bool SRoverSR::read(istream &in) + } + } + +- return in; ++ return in.good(); + } + + void SRoverSR::glRend(const CADColors &C) +@@ -351,7 +351,7 @@ bool SRoverSN::read(istream &in) + { + in >> colorType >> a >> b.y; + b.x = a.x; +- return in; ++ return in.good(); + } + + void SRoverSN::glRend(const CADColors &C) +@@ -365,7 +365,8 @@ void SRoverSN::glRend(const CADColors &C + + bool SNoverSN::read(istream &in) + { +- return in >> colorType >> a; ++ in >> colorType >> a; ++ return in.good(); + } + + void SNoverSN::glRend(const CADColors &C) +@@ -380,7 +381,8 @@ void SNoverSN::glRend(const CADColors &C + + bool SN::read(istream &in) + { +- return in >> colorType >> x; ++ in >> colorType >> x; ++ return in.good(); + } + + void SN::glRend(const CADColors &C) +@@ -394,7 +396,8 @@ void SN::glRend(const CADColors &C) + + bool SR::read(istream &in) + { +- return in >> colorType >> x1 >> x2; ++ in >> colorType >> x1 >> x2; ++ return in.good(); + } + + void SR::glRend(const CADColors &C) diff --git a/build/pkgs/qepcad/patches/qepcad-B-parens.patch b/build/pkgs/qepcad/patches/qepcad-B-parens.patch new file mode 100644 index 00000000000..1d881f7467b --- /dev/null +++ b/build/pkgs/qepcad/patches/qepcad-B-parens.patch @@ -0,0 +1,132 @@ +--- a/extensions/adj2d/truthbytop/BOUNDARY2D.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/adj2d/truthbytop/BOUNDARY2D.c 2018-08-29 20:07:50.511232206 -0600 +@@ -106,7 +106,7 @@ Step6: /* Split cell list by dimension. + tc++; + else + fc++; } +- if (tc > 0 && fc > 0 || GVERTEXLABEL(v,G) == TRUE && tc == 0) ++ if ((tc > 0 && fc > 0) || (GVERTEXLABEL(v,G) == TRUE && tc == 0)) + GNEWLABEL(v,TRUE,G); + else + GNEWLABEL(v,FALSE,G); } +--- a/extensions/lift2D/IBPRRIOAP.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/lift2D/IBPRRIOAP.c 2018-08-29 20:07:50.510232207 -0600 +@@ -95,7 +95,7 @@ Step3: /* Isolate the roots of B(alpha,y + goto Return; } + + /* get trend of first root */ +- if (PDEG(B) % 2 == 0 && s == 1 || PDEG(B) % 2 == 1 && s == -1) ++ if ((PDEG(B) % 2 == 0 && s == 1) || (PDEG(B) % 2 == 1 && s == -1)) + t1 = -1; + else + t1 = 1; +--- a/extensions/lift2D/modIBPRRIOAP.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/lift2D/modIBPRRIOAP.c 2018-08-29 20:07:50.510232207 -0600 +@@ -97,7 +97,7 @@ Step3: /* Isolate the roots of B(alpha,y + goto Return; } + + /* get trend of first root */ +- if (PDEG(B) % 2 == 0 && s == 1 || PDEG(B) % 2 == 1 && s == -1) ++ if ((PDEG(B) % 2 == 0 && s == 1) || (PDEG(B) % 2 == 1 && s == -1)) + t1 = -1; + else + t1 = 1; +--- a/source/db/convenientstreams.h.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/db/convenientstreams.h 2018-08-29 20:07:50.511232206 -0600 +@@ -31,7 +31,7 @@ public: + string s = ""; + char c = in.get(); + if (opt == skipleadingws) +- while(c != EOF && (isspace(c) || c == '\\' && isspace(in.peek()))) c = in.get(); ++ while(c != EOF && (isspace(c) || (c == '\\' && isspace(in.peek())))) c = in.get(); + // States : 0 = normal, 1 = in comment, 2 = just read a backslash + int state = 0; + do { +--- a/source/db/SINGULAR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/db/SINGULAR.c 2018-08-29 20:07:50.511232206 -0600 +@@ -58,7 +58,7 @@ void SingularServer::reportStats(ostream + + char peekNonWS(istream &in) + { +- char c; while((c = in.peek()) && c == ' ' || c == '\t' || c == '\n') in.get(); return c; ++ char c; while(c = in.peek() && (c == ' ' || c == '\t' || c == '\n')) in.get(); return c; + } + + +--- a/source/proj/GROUPSAMEPJ.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/proj/GROUPSAMEPJ.c 2018-08-29 20:07:50.511232206 -0600 +@@ -46,7 +46,7 @@ BDigit PRJPNTEQUAL(Word A, Word B) + Word KR = LIST2(SECOND(aK),LIST2(1,1)); + Word sL = AFSIGN(aM,aI,AFPEMV(1,aM,G,KL)); + Word sR = AFSIGN(aM,aI,AFPEMV(1,aM,G,KR)); +- return EQUAL(KL,KR) && sL == 0 || sL == 1 && sR == -1 || sL == -1 && sR == 1; ++ return (EQUAL(KL,KR) && sL == 0) || (sL == 1 && sR == -1) || (sL == -1 && sR == 1); + } + + /* One primitive, the other not */ +@@ -75,10 +75,10 @@ Step1: /* Group. */ + { + ADV(Jt,&J2,&Jt); + Jt2 = LELTI(J2,PO_POLY); +- if (LELTI(J1,PO_TYPE) == PO_POINT && LELTI(J2,PO_TYPE) == PO_POINT +- && PRJPNTEQUAL(Js1,Jt2) || +- LELTI(J1,PO_TYPE) != PO_POINT && LELTI(J2,PO_TYPE) != PO_POINT +- && EQUAL(Js1,Jt2)) ++ if ((LELTI(J1,PO_TYPE) == PO_POINT && LELTI(J2,PO_TYPE) == PO_POINT ++ && PRJPNTEQUAL(Js1,Jt2)) || ++ (LELTI(J1,PO_TYPE) != PO_POINT && LELTI(J2,PO_TYPE) != PO_POINT ++ && EQUAL(Js1,Jt2))) + { + SLELTI(J2,PO_PARENT,CONC(LELTI(J2,PO_PARENT),LELTI(J1,PO_PARENT))); + t = 1; +--- a/source/proj/PROJMCECmod.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/proj/PROJMCECmod.c 2018-08-29 20:07:50.511232206 -0600 +@@ -67,7 +67,7 @@ Step1: /* Obtain coefficients. */ + t = 1; } + + /* If r = 2 OR r-1 is in free variable space, the leading coefficient is always enough! */ +- if (t && (r == 2 || (PCMZERROR && r-1 <= GVNFV)) ++ if ((t && (r == 2 || (PCMZERROR && r-1 <= GVNFV))) + || (experimentalExtensionFlag && qfrCheckNonNullified(r,Ap1,GVNA.W,GVNQFF.W,GVVL.W)) + ) + t = 0; +@@ -101,7 +101,7 @@ Step1: /* Obtain coefficients. */ + tf = tf || (Q == FULLDE || Q == FULLDA); + + /* Test 3: in free variable space when the PCMZERROR option is used */ +- tf = tf || PCMZERROR && rp <= GVNFV; ++ tf = tf || (PCMZERROR && rp <= GVNFV); + + /* Test 4: has no common zero with the system of all other coefficients */ + if (!tf) +--- a/source/proj/PROJMCmod.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/proj/PROJMCmod.c 2018-08-29 20:07:50.511232206 -0600 +@@ -57,7 +57,7 @@ Step1: /* Obtain coefficients. */ + t = 1; } + + /* If r = 2 OR r-1 is in free variable space, the leading coefficient is always enough! */ +- if (t && (r == 2 || (PCMZERROR && r-1 <= GVNFV)) ++ if ((t && (r == 2 || (PCMZERROR && r-1 <= GVNFV))) + || (experimentalExtensionFlag && qfrCheckNonNullified(r,Ap1,GVNA.W,GVNQFF.W,GVVL.W)) + ) + t = 0; +@@ -91,7 +91,7 @@ Step1: /* Obtain coefficients. */ + tf = tf || (Q == FULLDE || Q == FULLDA); + + /* Test 3: in free variable space when the PCMZERROR option is used */ +- tf = tf || PCMZERROR && rp <= GVNFV; ++ tf = tf || (PCMZERROR && rp <= GVNFV); + + /* Test 4: has no common zero with the system of all other coefficients */ + if (!tf) +--- a/source/ticad/INITPCAD.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/ticad/INITPCAD.c 2018-08-29 20:07:50.511232206 -0600 +@@ -14,7 +14,7 @@ Word QepcadCls::INITPCAD() + Word D, tv; + + Step0: /* Determine truth value! */ +- if (GVNA == FALSE || GVNA != NIL && LELTI(GVNA,1) == NEOP && LELTI(GVNA,2) == 0) tv = NA; ++ if (GVNA == FALSE || (GVNA != NIL && LELTI(GVNA,1) == NEOP && LELTI(GVNA,2) == 0)) tv = NA; + else if (LELTI(GVNQFF,1) == NEOP && LELTI(GVNQFF,2) == 0) tv = FALSE; + else if (LELTI(GVNQFF,1) == EQOP && LELTI(GVNQFF,2) == 0) tv = TRUE; + else tv = UNDET; diff --git a/build/pkgs/qepcad/patches/qepcad-B-return.patch b/build/pkgs/qepcad/patches/qepcad-B-return.patch new file mode 100644 index 00000000000..04a243a9b72 --- /dev/null +++ b/build/pkgs/qepcad/patches/qepcad-B-return.patch @@ -0,0 +1,56 @@ +--- a/extensions/sfext/formula/FTYPEINFO.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/formula/FTYPEINFO.c 2018-08-29 20:06:48.870298902 -0600 +@@ -23,6 +23,6 @@ Word FTYPEINFO(Word A) + return TRUE; + if (FIRST(A) == FALSE) + return FALSE; +- ++ FAIL("FTYPEINFO","Unknown formula type!"); + } + +--- a/source/db/AFUPSFNDB.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/db/AFUPSFNDB.c 2018-08-29 20:06:48.871298901 -0600 +@@ -5,7 +5,7 @@ AFUPSFN with Database. + ======================================================================*/ + #include "qepcad.h" + +-Word AFUPSFNDB(Word M, Word B, Word *t_, Word *Bt_, Word *F_) ++void AFUPSFNDB(Word M, Word B, Word *t_, Word *Bt_, Word *F_) + { + Word t,Bt,F; + +--- a/source/db/SingSacPolicy.h.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/db/SingSacPolicy.h 2018-08-29 20:06:48.872298900 -0600 +@@ -28,17 +28,17 @@ public: + Word IPRES(Word r, Word A, Word B) + { + if (r > 2) +- sing->IPRES(r,A,B); ++ return sing->IPRES(r,A,B); + else +- sac ->IPRES(r,A,B); ++ return sac ->IPRES(r,A,B); + } + + Word IPDSCR(Word r, Word A) + { + if (r > 2) +- sing->IPDSCR(r,A); ++ return sing->IPDSCR(r,A); + else +- sac ->IPDSCR(r,A); ++ return sac ->IPDSCR(r,A); + } + + Word IPFACTGB(Word r, Word I, Word N) +--- a/source/qepcad.h.orig 2018-08-29 20:04:27.596451754 -0600 ++++ b/source/qepcad.h 2018-08-29 20:06:48.871298901 -0600 +@@ -34,7 +34,7 @@ Word AFPNIPDB(Word Mb, Word B); + void AFUPGCDB(Word M, Word A, Word B, Word *C_, Word *Ab_, Word *Bb_); + void AFUPLM(Word M, Word A, Word *L_, Word *P_); + void AFUPRWR(Word a, Word v, Word A, Word I); +-Word AFUPSFNDB(Word M, Word B, Word *t_, Word *Bt_, Word *F_); ++void AFUPSFNDB(Word M, Word B, Word *t_, Word *Bt_, Word *F_); + Word APPEND(Word P, Word k, Word R); + void APPENDEC(Word P, Word k, Word R, Word *Ps_, Word *F_); + void ATOMFLWR(Word N, Word V, Word A); diff --git a/build/pkgs/qepcad/patches/qepcad-B-signed.patch b/build/pkgs/qepcad/patches/qepcad-B-signed.patch new file mode 100644 index 00000000000..4a424aec3aa --- /dev/null +++ b/build/pkgs/qepcad/patches/qepcad-B-signed.patch @@ -0,0 +1,78 @@ +--- a/plot2d/plot.cc.orig 2018-08-29 20:07:27.086257553 -0600 ++++ b/plot2d/plot.cc 2018-08-29 20:08:10.014211101 -0600 +@@ -134,7 +134,7 @@ void* readdata(void *x) + pthread_mutex_lock(&M); + swap(CE,E); + pthread_mutex_unlock(&M); +- for(int i = 0; i < E.size(); i++) delete E[i]; ++ for(size_t i = 0; i < E.size(); i++) delete E[i]; + E.clear(); } + else if (c == 'E') { /******* Exit! *******************/ + return 0; +@@ -155,7 +155,7 @@ void display() + { + pthread_mutex_lock(&M); + glClear(GL_COLOR_BUFFER_BIT); +- for(int i = 0; i < CE.size(); i++) ++ for(size_t i = 0; i < CE.size(); i++) + CE[i]->glRend(Colors); + pthread_mutex_unlock(&M); + glutSwapBuffers(); +@@ -286,7 +286,7 @@ void SNoverSR::glRend(const CADColors &C + // 128 or so points that can appear. + C.glSetColor(colorType,'D'); + glBegin(GL_LINE_STRIP); +- for(int i = 0; i < V.size(); i++) ++ for(size_t i = 0; i < V.size(); i++) + glVertex2(V[i]); + glEnd(); + } +@@ -328,7 +328,7 @@ bool SRoverSR::read(istream &in) + else + { + cerr << "Sector over sector in unknown format!" << endl; +- for(int i = 0; i < V.size(); i++) ++ for(size_t i = 0; i < V.size(); i++) + cerr << V[i] << endl; + exit(1); + } +--- a/source/db/SINGULAR.c.orig 2018-08-29 20:07:50.511232206 -0600 ++++ b/source/db/SINGULAR.c 2018-08-29 20:08:10.015211100 -0600 +@@ -67,7 +67,7 @@ Word readSingularPoly(Word r, Word V, is + Word A, t; + string s; + in >> s; +- for(int i = 0; i < s.length(); ++i) ++ for(size_t i = 0; i < s.length(); ++i) + if (s[i] == '*') s[i] = ' '; + s += ".\n"; + istringstream si(s); +@@ -108,7 +108,7 @@ string WritePolyForSingular(Word r, Word + out = sout.str(); + } + // Put in * symbols +- for(int i = 1; i < out.length() - 1; ++i) ++ for(size_t i = 1; i < out.length() - 1U; ++i) + if (out[i] == ' ' && out[i+1] != '+' && out[i+1] != '-' + && out[i-1] != '+' && out[i-1] != '-' + ) +--- a/source/saclib/gcword.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/saclib/gcword.c 2018-08-29 20:08:10.015211100 -0600 +@@ -30,7 +30,7 @@ void gcw_MARK(); + } + + static vector G; +-static int lim = 10; ++static size_t lim = 10; + + void clean() + { +@@ -62,7 +62,7 @@ void gcw_MARK() + { + // SWRITE("gcw size is: ");IWRITE(G.size()); SWRITE("\n"); + clean(); +- for(int i = 0; i < G.size(); i++) ++ for(size_t i = 0; i < G.size(); i++) + if (*G[i] > BETA && *G[i] < BETAp && (*G[i] & 1)) + MARK(*G[i]); + diff --git a/build/pkgs/qepcad/patches/qepcad-B-syntax.patch b/build/pkgs/qepcad/patches/qepcad-B-syntax.patch new file mode 100644 index 00000000000..832cdbee4e3 --- /dev/null +++ b/build/pkgs/qepcad/patches/qepcad-B-syntax.patch @@ -0,0 +1,22 @@ +--- a/source/main/BEGINQEPCAD.c.orig 2018-08-29 20:03:05.718540333 -0600 ++++ b/source/main/BEGINQEPCAD.c 2018-08-29 20:09:45.542106837 -0600 +@@ -53,7 +53,7 @@ void BEGINQEPCAD(int &argc, char**& argv + { + int tmp = system("bash -c 'exit $(stty size | cut -d\" \" -f2)'"); + tmp = WEXITSTATUS(tmp); +- if (10 <= tmp <= 512) ++ if (10 <= tmp && tmp <= 512) + cols = tmp; + } + +--- a/source/userint/USERINT.c.orig 2018-03-16 14:22:00.000000000 -0600 ++++ b/source/userint/USERINT.c 2018-08-29 20:09:45.543106835 -0600 +@@ -492,7 +492,7 @@ void VERTFILL2D(Word D) + Word L, S, T, CB; + + /* GET 1D CAD STACK */ +- L = L = LELTI(D,CHILD); ++ L = LELTI(D,CHILD); + if (L == NIL) + { + SWRITE("Must by a 2D CAD!\n"); diff --git a/build/pkgs/qepcad/patches/qepcad-B-tty.patch b/build/pkgs/qepcad/patches/qepcad-B-tty.patch new file mode 100644 index 00000000000..0bda2e973b8 --- /dev/null +++ b/build/pkgs/qepcad/patches/qepcad-B-tty.patch @@ -0,0 +1,45 @@ +--- a/source/db/SINGULAR.c.orig 2018-08-29 20:10:06.406075801 -0600 ++++ b/source/db/SINGULAR.c 2018-08-29 20:11:02.229992773 -0600 +@@ -1,6 +1,7 @@ + #include "SINGULAR.h" + #include + #include ++#include + using namespace std; + + +@@ -15,6 +16,12 @@ SingularServer::SingularServer(string Si + if (childpid == 0) { + intoSingular.setStdinToPipe(); + outofSingular.setStdoutToPipe(); ++ outofSingular.setStderrToPipe(); ++ intoSingular.closeIn(); ++ intoSingular.closeOut(); ++ outofSingular.closeIn(); ++ outofSingular.closeOut(); ++ setsid(); + + // Begin: Just for debug!! + //system("/home/wcbrown/bin/Singular -q --no-warn --min-time=0.001 --ticks-per-sec=1000 | tee /tmp/SingOutLog"); +@@ -30,9 +37,10 @@ SingularServer::SingularServer(string Si + "--ticks-per-sec=1000", + NULL); + perror("SingularServer Constructor: Singular startup failed! (Set SINGULAR environment variable)"); +- outofSingular.closeOut(); + exit(0); + } ++ intoSingular.closeIn(); ++ outofSingular.closeOut(); + } + + SingularServer::~SingularServer() +--- a/source/db/unnamedpipe.h.orig 2018-08-29 20:10:06.406075801 -0600 ++++ b/source/db/unnamedpipe.h 2018-08-29 20:11:02.229992773 -0600 +@@ -113,6 +113,7 @@ public: + int fdout() { return fd[1]; } + int setStdinToPipe() { return dup2(fdin(),fileno(stdin)); } + int setStdoutToPipe() { return dup2(fdout(),fileno(stdout)); } ++ int setStderrToPipe() { return dup2(fdout(),fileno(stderr)); } + void closeIn() { + if (_in) { delete _in; _in = 0; } + if (openmask[0]) { close(fd[0]); openmask[0] = false; } diff --git a/build/pkgs/qepcad/patches/qepcad-B-uninit.patch b/build/pkgs/qepcad/patches/qepcad-B-uninit.patch new file mode 100644 index 00000000000..f78e4c2239a --- /dev/null +++ b/build/pkgs/qepcad/patches/qepcad-B-uninit.patch @@ -0,0 +1,314 @@ +--- a/cad2d/src/TICAD.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/cad2d/src/TICAD.c 2018-08-29 20:05:52.862359504 -0600 +@@ -43,6 +43,8 @@ Step2: /* Choose. */ + if (L == 0) { /* Init for 1D Sectors */ + L = LELTI(D,CHILD); + d = 1; } ++ else ++ d = 0; + + if (d == 1 && L != NIL) { /* Choose next 1D sectors */ + c = FIRST(L); +@@ -51,6 +53,7 @@ Step2: /* Choose. */ + else + L = RED2(L); } + else if (d == 1 && L == NIL) { /* Init for 1D sections */ ++ c = NIL; + d = 0; + L = RED(LELTI(D,CHILD)); + } +--- a/extensions/adj2d/oldadj/ACMADJ2D.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/adj2d/oldadj/ACMADJ2D.c 2018-08-29 20:05:52.864359502 -0600 +@@ -29,6 +29,7 @@ Step1: /* Get (A,I) defining c. */ + FIRST2(Ip,&ip1,&ip2); + i1 = RNLBRN(ip1); + i2 = RNLBRN(ip2); ++ t = 0; + + Step2: /* Get sample points for c_l and c_r. */ + i_l = RNLBRN(SPRLC(c_l)); +--- a/extensions/lift2D/modHIPRRID.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/lift2D/modHIPRRID.c 2018-08-29 20:05:52.864359502 -0600 +@@ -28,6 +28,7 @@ Step1: /* Compute a bound for the positi + k = HIPPRB(n,A); + + Step2: /* Isolate the positive roots. */ ++ L = NIL; + if (k == NIL) { + L1 = NIL; + goto Step3; } +--- a/extensions/lift2D/modIBPRRIOAPSF.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/lift2D/modIBPRRIOAPSF.c 2018-08-29 20:05:52.863359503 -0600 +@@ -77,6 +77,7 @@ Step4: /* Isolate the real roots of eac + Step5: /* Refine roots? */ + if (k == NIL) + goto Return; ++ Js = NIL; + Ls = NIL; + for(Lp = L; Lp != NIL; Lp = RED(Lp)) + { +--- a/extensions/rend/WRITE_PS_INTERACTIVE.cc.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/rend/WRITE_PS_INTERACTIVE.cc 2018-08-29 20:05:52.863359503 -0600 +@@ -262,6 +262,8 @@ void WRITE_PS_INTERACTIVE(Rend_Cell &M, + if (t == 'p') { + SWRITE("Enter projetion factor by (level,index): "); + p = LREAD(); } ++ else ++ p = NIL; + + switch(c) { + case 'x': // 1D Sectors +--- a/extensions/sfext/addpol/MINPFSETNSC.c.orig 2018-08-29 20:03:25.110519357 -0600 ++++ b/extensions/sfext/addpol/MINPFSETNSC.c 2018-08-29 20:05:52.865359501 -0600 +@@ -42,7 +42,7 @@ Word MINPFSETNSC(Word P,Word S,Word D,Wo + Word x_s,js,Ls,O,Q,Q_i,Sp,Pp,i,Cp,*V,*Vp,**A,a,N,k,S_r,I,j,p; + + Step1: /* Initialization. */ +- C = NIL; Sltr = NIL; Pltr = NIL; N = LENGTH(K); ++ C = NIL; Sltr = NIL; S_r = NIL; Pltr = NIL; N = LENGTH(K); + + Step2: /* Loop over each level in D. */ + for(r = 1; r <= N; r++) { +--- a/extensions/sfext/espcad/PCAD2ESPCAD.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/espcad/PCAD2ESPCAD.c 2018-08-29 20:05:52.866359500 -0600 +@@ -44,6 +44,8 @@ Step2: /* Generate correct i-level signi + P_i = RED(P_i); + s = RED(s); } + s = INV(ss); } ++ else ++ s = NIL; + + Step3: /* Construct extended Sub-CAD cell structure. */ + EDs = LIST8(C,A,LELTI(Ds,SC_INX),NIL,s,NIL,UNDET,UNDET); +--- a/extensions/sfext/extlang/SCAD2ESCAD.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/extlang/SCAD2ESCAD.c 2018-08-29 20:05:52.864359502 -0600 +@@ -27,6 +27,8 @@ Step2: /* Generate correct i-level signi + P_i = RED(P_i); + s = RED(s); } + s = INV(ss); } ++ else ++ s = NIL; + + Step3: /* Construct extended Sub-CAD cell structure. */ + EDs = LIST7(C,A,LELTI(Ds,SC_INX),NIL,s,NIL,UNDET); +--- a/extensions/sfext/formula/FMAATOMREAD.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/formula/FMAATOMREAD.c 2018-08-29 20:05:52.865359501 -0600 +@@ -18,7 +18,7 @@ void FMAATOMREAD(Word Q, Word V, Word *F + /* hide r,s,t; */ + + Step1: /* Read the left polynomial. */ +- t = 1; r = LENGTH(V); ++ t = 1; r = LENGTH(V); F = NIL; + IPEXPREAD(r,V,&P1,&t); if (t == 0) goto Return; + + Step2: /* Read the relational operator. */ +@@ -71,6 +71,7 @@ Word POLYINDEX(Word P, Word p, Word r, W + p = SECOND(p); + + /* Is p already in P? */ ++ pp = NIL; + P_r = LELTI(P,r); *t = 0; + for(Pp = P_r; Pp != NIL; Pp = RED(Pp)) { + pp = FIRST(Pp); +--- a/extensions/sfext/formula/FMASMOOTH.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/formula/FMASMOOTH.c 2018-08-29 20:05:52.865359501 -0600 +@@ -16,6 +16,7 @@ Step1: /* Atoms and Constants. */ + if (ISLIST(F1) || F1 == TRUE || F1 == FALSE) { + G = F; + goto Return; } ++ G = NIL; + + Step2: /* AND's */ + if (F1 == ANDOP) { +--- a/extensions/sfext/sfcons/SFC3.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/sfcons/SFC3.c 2018-08-29 20:05:52.865359501 -0600 +@@ -90,7 +90,7 @@ Step3: /* The normal language. */ + switch(m) { + case (0) : SF = NECCONDS(Lt,Lf,LA,Pp); break; + case (1) : SF = NAIVESF(Lt,Lf,LA,Pp); break; +- case (2) : SWRITE("GEOTEST requires the extended language!\n"); goto Return; } } ++ case (2) : SF = NIL; SWRITE("GEOTEST requires the extended language!\n"); goto Return; } } + + Step4: /* Massage the formula. */ + pflag = 1; +--- a/extensions/sfext/sfcons/SFC3f.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/sfcons/SFC3f.c 2018-08-29 20:05:52.865359501 -0600 +@@ -88,7 +88,7 @@ Step3: /* The normal language. */ + switch(m) { + case (0) : SF = NECCONDS(Lt,Lf,LA,Pp); break; + case (1) : SF = NAIVESF(Lt,Lf,LA,Pp); break; +- case (2) : SWRITE("GEOTEST requires the extended language!\n"); goto Return; } } ++ case (2) : SF = NIL; SWRITE("GEOTEST requires the extended language!\n"); goto Return; } } + + Step4: /* Massage the formula. */ + pflag = 1; +--- a/extensions/sfext/sfcons/SFC4.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/sfcons/SFC4.c 2018-08-29 20:05:52.865359501 -0600 +@@ -31,6 +31,7 @@ void QepcadCls::SFC4(Word D, Word P, Wor + { + Word t,SF,Dp,Pp,Lt,Lf,LA,Q,D1,P1,D0,P0,J0,i,Lp,pflag; + char e,s,m,c; ++ e = s = m = c = '\0'; + T1 = T2 = T3 = T4 = 0; + F1 = 0; + +--- a/extensions/sfext/sfcons/SFCFULLDf.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/sfcons/SFCFULLDf.c 2018-08-29 20:05:52.865359501 -0600 +@@ -52,6 +52,7 @@ Step2: /* Extended language. */ + + if (Lt == NIL && Lf == NIL) { + SWRITE("No cells have truth values!\n"); ++ SF = NIL; + goto Return; } + t = ESPCADDOPFSUFF(Pp,LIST1(Dp)); + LA = LISTOETAmod(Pp,n,t==NIL); +--- a/source/io/ATOMFRDR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/io/ATOMFRDR.c 2018-08-29 20:05:52.866359500 -0600 +@@ -76,7 +76,7 @@ void ETFATOMRDR(Word V, Word P1, BDigit + Word t, F, r, j, P2, P2p, r1, r2, a, P, s; + + Step1: /* Prepare */ +- t = 1; r = LENGTH(V); ++ t = 1; r = LENGTH(V); F = NIL; + + + Step2: /* Read "_root_" */ +--- a/source/io/CATTRNRDR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/io/CATTRNRDR.c 2018-08-29 20:05:52.866359500 -0600 +@@ -39,7 +39,7 @@ Step2: /* Get the internal representatio + goto Return; + + Step3: /* Error exit. */ +- DIELOC(); t = 0; ++ DIELOC(); V = 0; t = 0; + + Return: /* Prepare for return. */ + *V_ = V; +--- a/source/io/DESIREDRDR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/io/DESIREDRDR.c 2018-08-29 20:05:52.867359499 -0600 +@@ -15,6 +15,7 @@ void DESIREDRDR(Word *F_, Word *t_) + /* hide C,C1,R,V1,V2,t; */ + + Step1: /* Atomic condition. */ ++ F = NIL; + t = 1; + C = CREADB(); if (C == '[') goto Step2; + BKSP(); +--- a/source/io/FREADR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/io/FREADR.c 2018-08-29 20:05:52.866359500 -0600 +@@ -23,7 +23,7 @@ void FREADR(Word V, Word f, Word *Fs_, W + /* hide C,i,q,r,t; */ + + Step1: /* Read quantifier list. */ +- t = 1; Q = NIL; r = LENGTH(V); ++ Fs = NIL; t = 1; Q = NIL; r = LENGTH(V); + for (i = f + 1; i <= r; i++) + { + C = CREADB(); +--- a/source/io/GREADR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/io/GREADR.c 2018-08-29 20:05:52.867359499 -0600 +@@ -33,7 +33,7 @@ Step2: /* Read digits and convert. */ + BKSP(); a = S * a; goto Return; + + Step3: /* Error. */ +- DIELOC(); t = 0; goto Return; ++ DIELOC(); a = 0; t = 0; goto Return; + + Return: /* Prepare for return. */ + *a_ = a; +--- a/source/io/LGOPRDR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/io/LGOPRDR.c 2018-08-29 20:05:52.866359500 -0600 +@@ -50,7 +50,7 @@ Step1: /* Read in. */ + { SWRITE("Error LGOPRDR: Logic operator was expected.\n"); goto Step2; } + + Step2: /* Error exit. */ +- DIELOC(); t = 0; goto Return; ++ DIELOC(); p = 0; t = 0; goto Return; + + Return: /* Prepare for return. */ + *p_ = p; +--- a/source/io/QFRDR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/io/QFRDR.c 2018-08-29 20:05:52.867359499 -0600 +@@ -39,7 +39,7 @@ Step1: /* Read in. */ + goto Return; + + Step2: /* Error exit. */ +- DIELOC(); t = 0; goto Return; ++ DIELOC(); q = 0; t = 0; goto Return; + + Return: /* Prepare for return. */ + *q_ = q; +--- a/source/io/RLOPRDR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/io/RLOPRDR.c 2018-08-29 20:05:52.866359500 -0600 +@@ -31,7 +31,7 @@ Step1: /* Read in. */ + goto Return; + + Step2: /* Error exit. */ +- DIELOC(); t = 0; goto Return; ++ DIELOC(); p = 0; t = 0; goto Return; + + Return: /* Prepare for return. */ + *p_ = p; +--- a/source/main/QEPCADauto.c.orig 2018-03-16 14:22:00.000000000 -0600 ++++ b/source/main/QEPCADauto.c 2018-08-29 20:05:52.867359499 -0600 +@@ -27,6 +27,8 @@ void QepcadCls::QEPCADauto(Word Fs, Word + char c1,c2; /* Chris variables. */ + + Step1: /* Normalize. */ ++ t = 0; ++ F_e = F_n = F_s = NIL; + FIRST4(Fs,&r,&f,&Q,&Fh); + F = NORMQFF(Fh); + if (GVUA != NIL) GVNA = NORMQFF(GVUA); +--- a/source/main/QEPCAD.c.orig 2018-03-16 14:22:00.000000000 -0600 ++++ b/source/main/QEPCAD.c 2018-08-29 20:05:52.867359499 -0600 +@@ -26,6 +26,8 @@ void QepcadCls::QEPCAD(Word Fs, Word *t_ + Word Cs,Ps,Qs,Pps,Cps,Qps,SF; /* Chris variables. */ + char c1,c2; /* Chris variables. */ + Step1: /* Normalize. */ ++ t = 0; ++ F_e = F_n = F_s = NIL; + FIRST4(Fs,&r,&f,&Q,&Fh); + /*Int*/ PCNSTEP = 1; + /*Int*/ if (INTERACT()) USERINT(LFS("Before Normalization"),'a'); +--- a/source/ticad/AFUPMPR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/ticad/AFUPMPR.c 2018-08-29 20:05:52.867359499 -0600 +@@ -27,6 +27,7 @@ void AFUPMPR(Word M, Word I, Word B, Wor + /* hide L1,Lp,j,jp,s,t,v,vp; */ + + Step1: /* Initialize. */ ++ j = 0; + FIRST2(J,&a,&b); + t = AFUPSR(M,I,B,b); + if (t == 0) +--- a/source/ticad/SUBST.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/ticad/SUBST.c 2018-08-29 20:05:52.867359499 -0600 +@@ -24,6 +24,7 @@ Word QepcadCls::SUBST(Word c, Word k, Wo + Word P,L,Sp,T1,T2,G,Q,f,i; + + Step1: /* Substitute. */ ++ f = UNDET; + L = NIL; + S = NIL; + Bp = B; +--- a/source/ticad/SUBSTR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/ticad/SUBSTR.c 2018-08-29 20:05:52.868359497 -0600 +@@ -24,6 +24,7 @@ Word QepcadCls::SUBSTR(Word c, Word k, W + Word P,L,Q,T1,T2,Sp,G,f,i; + + Step1: /* Do it. */ ++ f = UNDET; + L = NIL; + S = NIL; + Bp = B; +--- a/source/userint/PREQNCONSTL.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/userint/PREQNCONSTL.c 2018-08-29 20:05:52.868359497 -0600 +@@ -73,7 +73,7 @@ Return: /* Prepare for return. */ + + Word POLYLABEL(Word P, Word p, Word r, Word *t) + { +- Word P_r, Pp, pp; ++ Word P_r, Pp, pp = NIL; + + for(; PDEG(p) == 0; r--) + p = SECOND(p); diff --git a/build/pkgs/qepcad/patches/qepcad-B-unused.patch b/build/pkgs/qepcad/patches/qepcad-B-unused.patch new file mode 100644 index 00000000000..b14ade83ae3 --- /dev/null +++ b/build/pkgs/qepcad/patches/qepcad-B-unused.patch @@ -0,0 +1,1739 @@ +--- a/cad2d/src/CAD2D.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/cad2d/src/CAD2D.c 2018-08-29 20:10:06.394075819 -0600 +@@ -20,8 +20,8 @@ + + void QepcadCls2D::CAD2D(Word Fs, Word *t_, Word *F_e_, Word *F_n_, Word *F_s_) + { +- Word A,D,F,F_e,F_n,F_s,Fh,J,P,Q,Ths,f,i,r,t; +- Word L; ++ Word A,D,F,F_e,F_n,F_s,Fh,J,P,Q,f,i,r,t; ++ + Step1: /* Normalize. */ + FIRST4(Fs,&r,&f,&Q,&Fh); + F = NORMQFF(Fh); +@@ -70,9 +70,7 @@ Word AllAdjs(QepcadCls2D &Q, Word D,Word + + Word printgraph(Word D, Word L) + { +- Word A,R,c,Q,a,b; +- FILE* fp; +- fp = fopen("temp","w"); ++ Word R,c,Q,a,b; + + SWRITE("graph: {\n"); + +--- a/cad2d/src/CONSTRUCT.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/cad2d/src/CONSTRUCT.c 2018-08-29 20:10:06.395075818 -0600 +@@ -19,31 +19,10 @@ Construct a stack. + ======================================================================*/ + #include "cad2d.h" + +-static Word Chrisolate(Word M, BDigit p) +-{ +- Word n,q1,q2,S,L; +- BDigit *Mp; +- +-Step1: /* Convert the minimal polynomial to a software interval +- polynomial. */ +- n = PDEG(M); +- q1 = p + 3; +- q2 = q1 + q1; +- S = (n + 1) * q2 + 1; +- Mp = GETARRAY(S); +- IPSIP(M,p,Mp); +- +-Step2: /* Isolate roots! */ +- L = SIPRRID(Mp); +- FREEARRAY(Mp); +- return L; +-} +- + void QepcadCls2D::CONSTRUCT(Word c,Word k,Word f,Word Ps_,Word As) + { + BDigit p,t,Ths; +- Word A1,As1,At,B,b,E,I,Ip,I1,J,Jp,L,M,P1,Ps1,Pt,Pt1,S,s,T,Q; +- Word junk,a1,b1,t1,p1,j1; ++ Word A1,As1,At,B,b,E,I,Ip,I1,J,Jp,L,M,P1,Ps1,Pt,S,s,T,Q; + + Step1: /* Extract the projection factors from their attribute lists. */ + Word Ps = Ps_; +--- a/cad2d/src/PROJECT.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/cad2d/src/PROJECT.c 2018-08-29 20:10:06.395075818 -0600 +@@ -17,7 +17,7 @@ Projection Phase. + + void QepcadCls2D::PROJECT(Word r, Word A,Word *P_, Word *J_) + { +- Word D,F,J,P,Ps,J_k1,P_k,R,Ths,Thss,k,i; ++ Word D,F,J,P,J_k1,P_k,R,Ths,Thss,k,i; + + Step1: /* Initialize. */ + P = LLCOPY(A); +--- a/cad2d/src/TICAD.c.orig 2018-08-29 20:05:52.862359504 -0600 ++++ b/cad2d/src/TICAD.c 2018-08-29 20:10:06.394075819 -0600 +@@ -24,7 +24,7 @@ Output + + Word QepcadCls2D::TICAD(Word Q,Word F,Word f,Word P,Word A) + { +- Word As,D,Ps,Ths,Thss,c,cp,k,s,sh,sp,t,R,S; ++ Word As,D,Ps,c,k,s,sh; + Word L,d; + + Step1: /* Initialize. */ +--- a/extensions/adj2d/ADJ_2D1.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/adj2d/ADJ_2D1.c 2018-08-29 20:10:06.400075810 -0600 +@@ -16,6 +16,7 @@ Outputs + #include "adj2D.h" + #include "adj2D.h" + /**************************************/ ++/* + static FILE *OUTPUT; + + static void init() +@@ -30,6 +31,7 @@ static void uninit() + { + fclose(OUTPUT); + } ++*/ + /**************************************/ + + +--- a/extensions/adj2d/ADJ_2D1P2.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/adj2d/ADJ_2D1P2.c 2018-08-29 20:10:06.401075809 -0600 +@@ -9,7 +9,7 @@ void sa_send(const char* S); + + Word ADJ_2D1P2(Word U, Word V, Word w_l, Word B) + { +- Word Sol,S,v,J,w_v,u,w_u,I,Solp,t,f; ++ Word Sol,S,v,J,w_v,u,w_u,I,Solp,f; + + /*sa_send("[");*/ + +--- a/extensions/adj2d/ADJ_2D.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/adj2d/ADJ_2D.c 2018-08-29 20:10:06.400075810 -0600 +@@ -17,12 +17,6 @@ Outputs + ======================================================================*/ + #include "adj2D.h" + #include "adj2D.h" +-static void start(); +-static void stop(); +-static int k; +-static void zero() { k = 0; } +-void bump() { k++; } +-static void print() { SWRITE("\n\nk = "); IWRITE(k); SWRITE("\n\n"); } + + Word ADJ_2D(Word c, Word c_l, Word c_r, Word P, Word J) + { +@@ -37,18 +31,3 @@ Word ADJ_2D(Word c, Word c_l, Word c_r, + + return Sol; + } +- +-static Word ADJ_D_Time; +- +-void start() +-{ +- ADJ_D_Time = ACLOCK(); +-} +- +-void stop() +-{ +- ADJ_D_Time = ACLOCK() - ADJ_D_Time; +- SWRITE("\nADJ_2D took "); +- IWRITE(ADJ_D_Time); +- SWRITE(" millseconds.\n"); +-} +--- a/extensions/adj2d/ADJ_2D_PART.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/adj2d/ADJ_2D_PART.c 2018-08-29 20:10:06.401075809 -0600 +@@ -80,8 +80,3 @@ Step5: /* Clean up evidence of "shadow s + Return: /* Prepare to return. */ + return Sol; + } +- +-static void dummy() +-{ +- +-} +--- a/extensions/adj2d/oldadj/ACMADJ2D.c.orig 2018-08-29 20:05:52.864359502 -0600 ++++ b/extensions/adj2d/oldadj/ACMADJ2D.c 2018-08-29 20:10:06.400075810 -0600 +@@ -239,7 +239,7 @@ Step3: /* Make assignments. */ + + Word ASYS2(Word M, Word H, Word I, Word P2) + { +- Word P,p,tH,tI,h1,h2,i1,i2,L1p,L2p,L1n,L2n,n1p,n1n,n2p,n2n,p1,p2,L1,L2,t; ++ Word P,p,tH,tI,h1,h2,i1,i2; + + tH = -LBRNSIGN(IUPLBREVAL(M,FIRST(H))); + tI = LBRNSIGN(IUPLBREVAL(M,SECOND(I))); +--- a/extensions/adj2d/P1.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/adj2d/P1.c 2018-08-29 20:10:06.401075809 -0600 +@@ -25,7 +25,7 @@ Notes: P1 has three main cases to deal w + + Word P1(Word U, Word V, Word W, Word v_l, Word B) + { +- Word Sol,As,S,u,I,J,a,w,v,n,x,x_u,x_w,N,m_v,m_2v; ++ Word Sol,As,S,u,I,J,a,w,v,n,x,x_u,x_w,m_v,m_2v; + + Sol = NIL; As = NIL; + +--- a/extensions/adj2d/P3.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/adj2d/P3.c 2018-08-29 20:10:06.401075809 -0600 +@@ -29,7 +29,7 @@ Note: Program 3 is the first called, an + + Word P3(Word U, Word V, Word W, Word v_l, Word B) + { +- Word I,J,Sol,S,u,As; ++ Word J,Sol,S,u,As; + + Step1: /* Special Case: No adjacencies to determine. */ + if (U == NIL && W == NIL) +--- a/extensions/adj2d/P4.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/adj2d/P4.c 2018-08-29 20:10:06.400075810 -0600 +@@ -25,7 +25,7 @@ Notes: Program 4 tries to find solutions + + Word P4(Word U, Word V, Word W, Word v_l, Word B) + { +- Word I,Sol,S,w,As,J; ++ Word Sol,S,w,As,J; + + Step1: /* Loop. */ + J = LIST2(B,AD2D_N_In); Sol = NIL; As = NIL; +--- a/extensions/adj2d/sac_ext/IUPTSII.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/adj2d/sac_ext/IUPTSII.c 2018-08-29 20:10:06.401075809 -0600 +@@ -14,7 +14,7 @@ Outputs + + Word IUPTSII(Word A, Word I) + { +- Word i1,i2,Ap,t,a; ++ Word i1,i2,Ap,t; + + Step1: /* One-point interval. */ + FIRST2(I,&i1,&i2); +--- a/extensions/adj2d/truthbytop/ADJ2DITOEL.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/adj2d/truthbytop/ADJ2DITOEL.c 2018-08-29 20:10:06.400075810 -0600 +@@ -27,7 +27,7 @@ int bc(int a, int b) + + Word ADJ2DITOEL(Word L, Word c1, Word c0) + { +- Word *A, E,n,l,s,a,b,k1,k0,i,itop,ibot,S; ++ Word *A, E,n,l,a,b,k1,k0,i,itop,ibot,S; + + Step1: /* Initialize & Special Case. */ + E = NIL; +--- a/extensions/adj2d/truthbytop/GRAPHMODULE.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/adj2d/truthbytop/GRAPHMODULE.c 2018-08-29 20:10:06.400075810 -0600 +@@ -61,9 +61,9 @@ Return: /* Prepare to return. */ + + Word GSTACKHANDLE(Word i, Word G_) + { +- Word G,Gp,h; +- G = G_; +- for(Gp = NIL; G != NIL && (i > FIRST(FIRST(G))); G = RED(G)); ++ Word G,h; ++ ++ for(G = G_; G != NIL && (i > FIRST(FIRST(G))); G = RED(G)); + if (G == NIL || FIRST(FIRST(G)) != i) + h = NIL; + else +@@ -74,7 +74,7 @@ Word GSTACKHANDLE(Word i, Word G_) + + Word GVERTEXHANDLE(Word v, Word G_) + { +- Word G,i,j,Gp,T,h; ++ Word i,j,T,h; + + FIRST2(v,&i,&j); + h = GSTACKHANDLE(i,G_); +--- a/extensions/lift2D/IBPRRIOAPSF.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/lift2D/IBPRRIOAPSF.c 2018-08-29 20:10:06.399075811 -0600 +@@ -30,8 +30,8 @@ Outputs + + void IBPRRIOAPSF(Word M, Word I, Word B, BDigit p,BDigit k, Word *J_, Word *L_) + { +- BDigit *Mp,*bp,*c,i,m,n,q1,q2,S,s,t; +- Word b,Bp,I1,I2,J,K,L,Ls,Lp,T,Jp; ++ BDigit *Mp,*bp,*c,m,n,q1,q2,S,s,t; ++ Word b,J,L,Ls,Lp,Jp; + + Step1: /* Convert the minimal polynomial to a software interval + polynomial. */ +--- a/extensions/lift2D/LIFTSRD2D.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/lift2D/LIFTSRD2D.c 2018-08-29 20:10:06.399075811 -0600 +@@ -14,7 +14,7 @@ + + Word LIFTSRD2D(Word c, Word D, Word P, Word L) + { +- Word S_L,S_R,s_L,s_R,S,i,c_L,c_R,cp,flag,m_L,m_R,so,mo,m,s,j; ++ Word S_L,S_R,s_R,S,i,c_R,cp,so,m,s,j; + Word M,I,P2,Rp,t,R,Rs,Rt,SP,r,k,c1,c2,prev,Sp,sor,next,s2,nextc,X; + Word DL,Rps,pf,a,b,e,temp,count,J; + Word R_L; +@@ -113,7 +113,6 @@ if (PCVERBOSE) { SWRITE("Tried up to pre + /* Go through the neighboring stacks! */ + /**************************************/ + i = 0; +- flag = FALSE; + + /* LIMITATION OF CURRENT IMPLEMENTATION + make sure the larger stack is to the right */ +@@ -127,7 +126,6 @@ if (PCVERBOSE) { SWRITE("Tried up to pre + + for(S = NIL; S_R != NIL; ) { /******* BIG LOOP!!!! **********/ + +- c_L = FIRST(S_L); + c_R = FIRST(S_R); + + if (LELTI(c_R,MULSUB) != NIL && FIRST(FIRST(LELTI(c_R,MULSUB))) == J) +@@ -153,7 +151,6 @@ if (PCVERBOSE) { SWRITE("Tried up to pre + NOTDET, + LELTI(c_R,DEGSUB),LELTI(c_R,MULSUB)); + S = COMP(cp,S); +- flag = FALSE; + if (RED(S_L) == NIL && RED(S_R) != NIL) + S_R = RED(S_R); + else { +--- a/extensions/lift2D/LIFTSRR2D.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/lift2D/LIFTSRR2D.c 2018-08-29 20:10:06.400075810 -0600 +@@ -38,7 +38,7 @@ void debWRITEINTERVAL(Word I) { + + Word LIFTSRR2D(Word c, Word D, Word P) + { +- Word S_L,S_R,s_L,s_R,S,i,c_L,c_R,cp,flag,m_L,m_R,so,mo,m,s,j; ++ Word S_L,S_R,s_L,s_R,S,i,c_L,c_R,cp,so,m,s; + Word M,I,P2,Rp,t,R,Rs,Rt,SP,r,k,c1,c2,prev,Sp,sor,next,s2,nextc,X; + Word OC, OT,count; + +@@ -108,7 +108,6 @@ Word LIFTSRR2D(Word c, Word D, Word P) + /* Go through the neighboring stacks! */ + /**************************************/ + i = 0; +- flag = FALSE; + for(S = NIL; S_L != NIL; S_L = RED(S_L), S_R = RED(S_R)) { + + c_L = FIRST(S_L); +@@ -133,8 +132,7 @@ Word LIFTSRR2D(Word c, Word D, Word P) + CCONC(LELTI(c,INDX),LIST1(i)),COMP(FIRST(LELTI(c_L,SIGNPF)),LELTI(c,SIGNPF)), + NOTDET, + LELTI(c_L,DEGSUB),LELTI(c_L,MULSUB)); +- S = COMP(cp,S); +- flag = FALSE; } ++ S = COMP(cp,S); } + + else { + /************************************************************ +--- a/extensions/lift2D/modHIPRRID.c.orig 2018-08-29 20:05:52.864359502 -0600 ++++ b/extensions/lift2D/modHIPRRID.c 2018-08-29 20:10:06.400075810 -0600 +@@ -22,7 +22,7 @@ void modHIPRRID(BDigit n, interval *A, W + { + BDigit k,s,t; + interval *B,*C; +- Word b,I,J,L,L1,L2; ++ Word I,L,L1,L2; + + Step1: /* Compute a bound for the positive roots. */ + k = HIPPRB(n,A); +--- a/extensions/lift2D/modHIPRRISD.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/lift2D/modHIPRRISD.c 2018-08-29 20:10:06.399075811 -0600 +@@ -23,7 +23,7 @@ Outputs + + Word modHIPRRISD(BDigit n, interval *A, Word a, Word b) + { +- BDigit s,s2,t,u,v,Th,T0,sh; ++ BDigit s,s2,t,v,Th,T0,sh; + Word c,L,L1,L2; + interval *B,*C,J; + +--- a/extensions/lift2D/modIBPRRIOAPSF.c.orig 2018-08-29 20:05:52.863359503 -0600 ++++ b/extensions/lift2D/modIBPRRIOAPSF.c 2018-08-29 20:10:06.399075811 -0600 +@@ -31,8 +31,8 @@ Outputs + + void modIBPRRIOAPSF(Word M, Word I, Word B, Word p, Word k, BDigit *J_, BDigit *L_) + { +- BDigit *Mp,*bp,*c,i,m,n,q1,q2,S,s,t; +- Word a,b,Bp,I1,I2,J,K,L,Ls,Lp,T,Jp,Js,Ld; ++ BDigit *Mp,*bp,*c,m,n,q1,q2,S,s,t; ++ Word a,b,J,L,Ls,Lp,Jp,Js,Ld; + + Step1: /* Convert the minimal polynomial to a software interval + polynomial. */ +--- a/extensions/newadj/HAP2.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/newadj/HAP2.c 2018-08-29 20:10:06.406075801 -0600 +@@ -18,7 +18,7 @@ Outputs + + Word HAP2(Word U, Word V, Word w_l, Word B) + { +- Word Sol,S,v,J,w_v,u,w_u,I,Solp,t,f; ++ Word Sol,S,v,J,w_v,u,w_u,I,Solp,f; + + Sol = NIL; + S = NIL; +--- a/extensions/newadj/HATEST.c.orig 2018-08-29 20:03:25.111519356 -0600 ++++ b/extensions/newadj/HATEST.c 2018-08-29 20:10:06.406075801 -0600 +@@ -111,13 +111,11 @@ Sample point coordinate write. + + void SAMPLECWR(Word c) + { +- Word I,Ip,M,Mp,b,bp,k,s,F,j,Ms,Is; ++ Word I,Ip,M,Mp,b,bp,s,F,j,Ms,Is; + Word M1; +- /* hide k; */ + + Step1: /* Setup. */ + s = LELTI(c,SAMPLE); +- k = LELTI(c,LEVEL); + + Step2: /* Extended representation. */ + if (ISPRIMIT(s)) goto Step3; +@@ -160,7 +158,7 @@ Algebraic number field elements list wri + + void strippedAFLWR(Word M,Word I,Word N,Word a,Word A) + { +- Word A1,Ap,i,l,L,j; ++ Word A1,Ap,i; + /* hide i; */ + + Step1: /* Write. */ +@@ -196,7 +194,7 @@ Side effects + + void ANDWRITExx(Word M, Word I, Word n) + { +- Word J,R,Mp,K; ++ Word J,R,K; + Word a,a1,a2,b,b1,b2,d,d1,d2,e,f,m; + Word N; + +--- a/extensions/rend/CH_VIEW_WIN.cc.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/rend/CH_VIEW_WIN.cc 2018-08-29 20:10:06.397075815 -0600 +@@ -4,7 +4,7 @@ + Word CH_VIEW_WIN(Rend_Cell &M, Rend_Win &W, Word Xs, Word Xt, + Word Ys,Word Yt, Word e, Word P) + { +- Word mx,dx,dxp,dxp2,my,dy,d2x,d2y,L,i; ++ Word mx,my,d2x,d2y,L,i; + + mx = LBRNP2PROD( LBRNSUM(W.x.W,W.X.W) , -1 ); + my = LBRNP2PROD( LBRNSUM(W.y.W,W.Y.W) , -1 ); +--- a/extensions/rend/PLOT_2D_CAD.cc.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/rend/PLOT_2D_CAD.cc 2018-08-29 20:10:06.397075815 -0600 +@@ -42,9 +42,8 @@ void PLOT_2D_CAD(Word D, Word P, Word J, + { + char c; + Word N; +- Word i,j,I,ap,bp,a,b,L,p_n,n,A,Q,x,yl,Xs,Ys,Xt,Yt; +- char FIFO_NAME[20] = "/tmp/_plot_pipe_", +- RM_FIFO[25] = "rm "; ++ Word L,Xs,Ys,Xt,Yt; ++ char FIFO_NAME[20] = "/tmp/_plot_pipe_"; + longtostring(getpid(),FIFO_NAME+11); + int t = 1, first = 1; + int wcount = 0; +--- a/extensions/rend/Rend_Cell.cc.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/rend/Rend_Cell.cc 2018-08-29 20:10:06.398075813 -0600 +@@ -183,7 +183,7 @@ Word Rend_Cell::description(Rend_Win &W) + *************************************************************/ + void Rend_Cell::out_descrip(Rend_Win &W,ostream &out,Mapper &M) + { +- Word p,x,y,L,Lp,l,l1,l2,l3,x1,x2,y1,y2; ++ Word x,y,L,l,x1,x2,y1,y2; + + int px = 8; + int py = 8; +@@ -310,7 +310,7 @@ void Rend_Cell::out_descrip(Rend_Win &W, + *************************************************************/ + void Rend_Cell::out_descrip_ps(Rend_Win &W,ostream &out, Mapper &M) + { +- Word p,x,y,L,l,x1,x2,y1,y2; ++ Word p,L; + p = 12; + switch (level) { + case 0 : +@@ -382,7 +382,7 @@ void Rend_Cell::out_descrip_ps(Rend_Win + *************************************************************/ + void Rend_Cell::out_descrip_ps_color(Rend_Win &W,ostream &out, Mapper &M) + { +- Word p,x,y,L,l,x1,x2,y1,y2; ++ Word p,L; + p = 12; + switch (level) { + case 0 : +@@ -475,7 +475,7 @@ void Rend_Cell::out_descrip_ps_color(Ren + *************************************************************/ + void Rend_Cell::out_descrip_ps_raji(Rend_Win &W,ostream &out, Mapper &M) + { +- Word p,x,y,L,l,x1,x2,y1,y2; ++ Word p,L; + p = 12; + switch (level) { + case 0 : +@@ -511,7 +511,7 @@ void Rend_Cell::out_descrip_ps_raji(Rend + *************************************************************/ + void Rend_Cell::out_descrip_ps_standard(Rend_Win &W,ostream &out, Mapper &M) + { +- Word p,x,y,L,l,x1,x2,y1,y2; ++ Word p,L; + p = 12; + switch (level) { + case 0 : +--- a/extensions/rend/Rend_Sample.cc.orig 2018-08-29 20:07:27.087257552 -0600 ++++ b/extensions/rend/Rend_Sample.cc 2018-08-29 20:10:06.396075816 -0600 +@@ -46,7 +46,7 @@ Rend_Sample_1DS::Rend_Sample_1DS(Word C, + *************************************************************/ + Word Rend_Sample_1DS::coordinate(int k) + { +- Word P,J,j1,j2,js1,js2,s1,s2; ++ Word P,J,j1,j2; + + P = A.W; J = I.W; + +@@ -64,7 +64,7 @@ Step2: /* Save interval refinement and r + + Word Rend_Sample_1DS::round(int k, int roundup) + { +- Word P,J,j1,j2,js1,js2,s1,s2; ++ Word P,J,j1,j2; + + P = A.W; J = I.W; + +@@ -109,7 +109,7 @@ Rend_Sample_1DO::Rend_Sample_1DO(Rend_Ce + + Word Rend_Sample_1DO::coordinate(int k) + { +- Word e,j1,j2,J,kp = k; ++ Word /* e, */ j1,j2,J,kp = k; + do { + j1 = l -> sample -> round(kp,1); + j2 = r -> sample -> round(kp,0); +@@ -132,8 +132,8 @@ Word Rend_Sample_1DO::coordinate(int k) + *************************************************************/ + Rend_Sample_2DS::Rend_Sample_2DS(Word C) + { +- Word T,i,t1,t2,t3,j1,j2,s1,s2,s; +- Word tB,tJ,tA,tI,d1,d2,d3,d4,d5; ++ Word T,t1,t2,t3,j1,j2,s1,s2; ++ Word tB,tJ,tA,tI,d1; + + //-- Set A to the minpol of sample point, and I to isolating int --/ + T = LELTI( C , SAMPLE ); +@@ -172,7 +172,7 @@ Rend_Sample_2DS::Rend_Sample_2DS(Word C) + *************************************************************/ + Word Rend_Sample_2DS::coordinate(int k) + { +- Word J,j1,j2,JL,S,tB,tJ,tA,tI,d1,i; ++ Word J,S,tB,tJ,tA,tI,d1,i; + + + Step1: /* Initialize and decide if refinement is even necessary. */ +--- a/extensions/rend/WRITE_PS_INTERACTIVE.cc.orig 2018-08-29 20:05:52.863359503 -0600 ++++ b/extensions/rend/WRITE_PS_INTERACTIVE.cc 2018-08-29 20:10:06.399075811 -0600 +@@ -190,8 +190,8 @@ void WRITE_PS_INTERACTIVE(Rend_Cell &M, + **********************************************************/ + case 'a': + { +- Word OX, OY,xoff,yoff; +- double dum,Ox = 0, Oy = 0; ++ Word OX, OY; ++ double Ox = 0, Oy = 0; + SWRITE("Provide an origin: "); + qein() >> Ox >> Oy; + OX = IEEELBRN(Ox); +--- a/extensions/sfext/addpol/BPOLSETS.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/addpol/BPOLSETS.c 2018-08-29 20:10:06.405075803 -0600 +@@ -24,7 +24,7 @@ Outputs + + void BPOLSETS(Word L_, Word D, Word P, Word *T_, Word *N_) + { +- Word L,T,Q,q,a,b,I_a,I_b,i_a,i_b,n,P_N,S_a,S_b,s_a,s_b,t,N,p, ++ Word L,T,Q,q,a,b,I_a,I_b,i_a,i_b,n,P_N,t,N, + S_T,S_L,s_c,c,i,Tb,Tp; + + Step1: /* Initialization. */ +--- a/extensions/sfext/addpol/CFLCELLLIST.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/addpol/CFLCELLLIST.c 2018-08-29 20:10:06.405075803 -0600 +@@ -21,8 +21,7 @@ static Word comp(Word A, Word B); + + Word CFLCELLLIST(Word L_D) + { +- Word C,r,C_r,L,Lp,T,F,U,c,t,f,u,Fp,Up,h,Cb,Cp,Q; +- /* Time */ Word tm; ++ Word C,C_r,L,Lp,T,F,U,c,t,f,u,Fp,Up,h,Cb,Cp,Q; + + Step1: /* Initialize. */ + C = NIL; +--- a/extensions/sfext/addpol/CLEAN_BIGLOOP.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/addpol/CLEAN_BIGLOOP.c 2018-08-29 20:10:06.405075803 -0600 +@@ -15,8 +15,8 @@ Inputs + + void QepcadCls::CLEAN_BIGLOOP(Word Jb, Word Pb, Word P0, Word D0, Word N, Word *P_, Word *D_) + { +- Word P,D,G,C,T,N_T,Tb,Gb,Gbp,S_N_T,Tp,Gp,K,KT,p,i,S; +- Word Q,Q_i,Ps,Ds,Qb,Qb_i,Dsp,t,Ph; ++ Word P,D,G,C,T,N_T,Gb,K,KT,p,i,S; ++ Word Q,Ps,Ds,Dsp,t,Ph; + Word inum,tm,temp; + + Step1: /* Initialize. */ +--- a/extensions/sfext/addpol/KCONST.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/addpol/KCONST.c 2018-08-29 20:10:06.405075803 -0600 +@@ -53,8 +53,7 @@ static Word S1_EMPTY(Word S1) + + static Word S2_IN(Word o, Word S2) + { +- Word S; +- for(S = S2; S2 != NIL; S2 = RED(S2)) { ++ for( ; S2 != NIL; S2 = RED(S2)) { + if ( EQUAL(FIRST(FIRST(S2)),o) ) + return (1); } + return (0); +@@ -79,30 +78,6 @@ static Word S2_EMPTY(Word S2) + return ( (S2 == NIL) ); + } + +-/*--------- Is p a factor of q? ----------------*/ +-static Word ISPFACQ(Word p, Word q) +-{ +- Word l_p,R,r; +- l_p = LELTI(p,PO_LABEL); +- for(R = LELTI(q,PO_PARENT); R != NIL; R = RED(R)) { +- r = FIRST(R); +- if ( (FIRST(r) == PO_FAC) && +- EQUAL(LELTI(THIRD(r),PO_LABEL),l_p) ) +- return (1); } +- return (0); +-} +-/*--------- Is p the derivative of q? ----------------*/ +-static Word ISPDERQ(Word p, Word q) +-{ +- Word l_p,R,r; +- l_p = LELTI(p,PO_LABEL); +- for(R = LELTI(q,PO_PARENT); R != NIL; R = RED(R)) { +- r = FIRST(R); +- if ( (FIRST(r) == PO_DER) && +- EQUAL(LELTI(THIRD(r),PO_LABEL),l_p) ) +- return (1); } +- return (0); +-} + /*--------- List of derivative factor indices. --------*/ + + static Word LIST_OF_DI(Word o, Word J, Word P) +@@ -132,7 +107,7 @@ return (L); + + void KCONST(Word J, Word P, Word G, Word *K_, Word *KT_) + { +- Word S1,S2,Gp,o,L,l,KT,K,i,j; ++ Word S1,S2,Gp,o,L,l,KT,K; + + /* Initialization. */ + S1 = NIL; S2 = NIL; +--- a/extensions/sfext/addpol/MINPFSETNSC.c.orig 2018-08-29 20:05:52.865359501 -0600 ++++ b/extensions/sfext/addpol/MINPFSETNSC.c 2018-08-29 20:10:06.405075803 -0600 +@@ -38,8 +38,8 @@ static Word comp1(Word a,Word b) { + + Word MINPFSETNSC(Word P,Word S,Word D,Word K) + { +- Word C,Sltr,Pltr,r,L_r,Ls_r,L,l,l_t,l_s,ls,Kp,Js,x,Jsp,s_k,sk; +- Word x_s,js,Ls,O,Q,Q_i,Sp,Pp,i,Cp,*V,*Vp,**A,a,N,k,S_r,I,j,p; ++ Word C,Sltr,Pltr,r,L_r,Ls_r,l,l_t,l_s,ls,Kp,Js,Jsp,s_k,sk; ++ Word Ls,O,Q,Q_i,Sp,i,Cp,*V,*Vp,**A,a,N,k,S_r,j,p; + + Step1: /* Initialization. */ + C = NIL; Sltr = NIL; S_r = NIL; Pltr = NIL; N = LENGTH(K); +--- a/extensions/sfext/addpol/STRIPPED_BIGLOOP.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/addpol/STRIPPED_BIGLOOP.c 2018-08-29 20:10:06.405075803 -0600 +@@ -15,8 +15,8 @@ Inputs + + void QepcadCls::STRIPPED_BIGLOOP(Word Jb, Word Pb, Word P0, Word D0, Word N, Word *P_, Word *D_) + { +- Word P,D,G,C,T,N_T,Tb,Gb,Gbp,S_N_T,Tp,Gp,K,KT,p,i,S; +- Word Q,Q_i,Ps,Ds,Qb,Qb_i,Dsp,t,Ph; ++ Word P,D,G,C,T,N_T,Gb,K,KT,p,i; ++ Word Ps,t; + Word inum,tm,tt; + + Step1: /* Initialize. */ +--- a/extensions/sfext/crcads/CSORCELL.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/crcads/CSORCELL.c 2018-08-29 20:10:06.405075803 -0600 +@@ -19,7 +19,7 @@ Side Effects + + void QepcadCls::CSORCELLTR(Word c, Word Pp, Word PpO, Word PpN) + { +- Word f,s,sh,M,K,C,Pps,L,T,B,E,I,A,a,b,k; ++ Word s,sh,M,K,C,Pps,L,T,B,E,I,A,a,b,k; + + k = LELTI(c,LEVEL); + +--- a/extensions/sfext/crcads/CSORCELL_MOD.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/crcads/CSORCELL_MOD.c 2018-08-29 20:10:06.406075801 -0600 +@@ -25,8 +25,8 @@ static Word LLPFZC(Word c,Word P); + + void QepcadCls::CSORCELLTR_MOD(Word c, Word Pp, Word PpO, Word PpN, Word P) + { +- Word f,s,sh,M,K,C,Pps,L,T,B,E,I,A,a,b,k; +- Word PP,NP,L_P,TP,i,ta,t; ++ Word s,sh,T,B,A,a,b,k; ++ Word PP,NP,L_P,TP,i,ta; + + Step0: + k = LELTI(c,LEVEL); +--- a/extensions/sfext/crcads/LISTOFCWTV.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/crcads/LISTOFCWTV.c 2018-08-29 20:10:06.406075801 -0600 +@@ -14,7 +14,7 @@ Outputs + + void LISTOFCWTV(Word C, Word *Lt_, Word *Lf_) + { +- Word L,Cp,Lt,Lf,t,Ltp,Lfp; ++ Word Cp,Lt,Lf,t,Ltp,Lfp; + + Step1: /* If C is undetermined recurse on the children. */ + t = LELTI(C,TRUTH); +--- a/extensions/sfext/espcad/ESPCADLSNC.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/espcad/ESPCADLSNC.c 2018-08-29 20:10:06.406075801 -0600 +@@ -97,7 +97,7 @@ Output + + Word ESPCADCTLSNC(Word c1,Word c2,Word c3,Word i,Word P) + { +- Word S1,S2,S3,n,Sp1,Sp2,s1,s2,T,L,j,k; ++ Word S1,S2,n,Sp1,Sp2,s1,s2,T,L,j,k; + + Step1: /* Initialize. */ + if (LELTI(c1,SC_TMPM) == LELTI(c2,SC_TMPM) && +@@ -106,7 +106,6 @@ Step1: /* Initialize. */ + goto Return; } + S1 = LELTI(c1,SC_SIGN); + S2 = LELTI(c2,SC_SIGN); +- S3 = LELTI(c3,SC_SIGN); + + Step2: /* Figure out which polynomials are zero in c2. */ + for(n = 0, Sp1 = S1, Sp2 = S2, T = NIL; n < LENGTH(S1); n++) { +--- a/extensions/sfext/formula/FMAATOMREAD.c.orig 2018-08-29 20:05:52.865359501 -0600 ++++ b/extensions/sfext/formula/FMAATOMREAD.c 2018-08-29 20:10:06.403075806 -0600 +@@ -13,9 +13,9 @@ Word POLYINDEX(Word P, Word p, Word r, W + + void FMAATOMREAD(Word Q, Word V, Word *F_, Word *t_) + { +- Word F,P,P1,P2,R,a,r,s,t,k,pi; ++ Word F,P1,P2,R,r,t,k,pi; + char c; +- /* hide r,s,t; */ ++ /* hide r,t; */ + + Step1: /* Read the left polynomial. */ + t = 1; r = LENGTH(V); F = NIL; +--- a/extensions/sfext/formula/FMACELLEVAL.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/formula/FMACELLEVAL.c 2018-08-29 20:10:06.404075804 -0600 +@@ -15,7 +15,7 @@ Outputs + + Word FMACELLEVAL(Word F, Word C, Word P) + { +- Word t,L,i,j,k,op,s,S,ip,c,v,cp,n,t1,A1,A2,U_FLAG; ++ Word t,L,i,j,k,op,s,S,ip,c,cp,n,t1,A1,A2,U_FLAG; + + switch(FIRST(F)) { + +--- a/extensions/sfext/formula/FMAPOLLIST.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/formula/FMAPOLLIST.c 2018-08-29 20:10:06.404075804 -0600 +@@ -19,7 +19,7 @@ static Word subprog(Word F); + + Word FMAPOLLIST(Word F, Word P) + { +- Word Q,L,i,j,n,np,P_i,G; ++ Word Q,L,i,j,P_i; + + Q = NIL; + L = subprog(F); +--- a/extensions/sfext/formula/FMATRYDISTRIBUTE.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/formula/FMATRYDISTRIBUTE.c 2018-08-29 20:10:06.404075804 -0600 +@@ -45,7 +45,7 @@ Fp: the conjunction of C and F. The fun + Word FMADISTRIBUTE(Word F, Word C) + { + +- Word Fp, f, L, flag, fp,gp,I,X,X_C, I_C, op, A, Ap; ++ Word Fp, f, L, flag, gp,I,X,X_C, I_C, op, A, Ap; + f = FIRST(F); + + switch(f) +@@ -59,7 +59,6 @@ Word FMADISTRIBUTE(Word F, Word C) + L = NIL; + for(Fp = CINV(RED(F)); Fp != NIL; Fp = RED(Fp)) + { +- fp = FIRST(Fp); + gp = FMADISTRIBUTE(FIRST(Fp),C); + L = COMP(gp,L); + } +--- a/extensions/sfext/formula/FMAWRITE.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/formula/FMAWRITE.c 2018-08-29 20:10:06.404075804 -0600 +@@ -8,7 +8,7 @@ ForMulA write. + + void FMAWRITE(Word F, Word P, Word V) + { +- Word L,E,i,j,k,op,t,Fp,O,A; ++ Word i,j,k,op,t,Fp,O,A; + + switch(FTYPEINFO(F)) { + +--- a/extensions/sfext/formula/FMAWRITELATEX.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/formula/FMAWRITELATEX.c 2018-08-29 20:10:06.404075804 -0600 +@@ -8,7 +8,7 @@ ForMulA write. + + void FMAWRITELATEX(Word F, Word P, Word V) + { +- Word L,E,i,j,k,op,t,Fp,O,A; ++ Word i,j,k,op,t,Fp,O,A; + + switch(FTYPEINFO(F)) { + +@@ -62,7 +62,7 @@ void FMAWRITELATEX(Word F, Word P, Word + + void FMAWRITELATEXp(Word F, Word P, Word V, Word flag) + { +- Word L,E,i,j,k,op,t,Fp,O,A; ++ Word i,j,k,op,t,Fp,O,A; + + switch(FTYPEINFO(F)) { + +--- a/extensions/sfext/formula/FMAWRITENEWLINE.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/formula/FMAWRITENEWLINE.c 2018-08-29 20:10:06.404075804 -0600 +@@ -10,7 +10,7 @@ ForMulA write. + + void FMAWRITENEWLINE(Word F, Word P, Word V, Word n) + { +- Word L,E,i,j,k,op,t,Fp,O,A; ++ Word i,j,k,op,t,Fp,O,A; + + switch(FTYPEINFO(F)) { + +@@ -65,7 +65,7 @@ void FMAWRITENEWLINE(Word F, Word P, Wor + + void FMAWRITENEWLINEp(Word F, Word P, Word V, Word flag) + { +- Word L,E,i,j,k,op,t,Fp,O,A; ++ Word i,j,k,op,t,Fp,O,A; + + switch(FTYPEINFO(F)) { + +--- a/extensions/sfext/formula/FMAWRITEp.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/formula/FMAWRITEp.c 2018-08-29 20:10:06.404075804 -0600 +@@ -9,7 +9,7 @@ ForMulA write. + + void FMAWRITEp(Word F, Word P, Word V, Word flag) + { +- Word L,E,i,j,k,op,t,Fp,O,A; ++ Word i,j,k,op,t,Fp,O,A; + + switch(FTYPEINFO(F)) { + +--- a/extensions/sfext/formula/FMAWRITEQEIN.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/formula/FMAWRITEQEIN.c 2018-08-29 20:10:06.404075804 -0600 +@@ -7,7 +7,7 @@ ForMulA write. + + void FMAWRITEQEIN(Word F, Word P, Word V) + { +- Word Q,L,i,j,n,np,P_i,G; ++ Word Q,i,n,np,G; + + Step1: /* Get list of polynomials. */ + Q = FMAPOLLIST(F,P); +--- a/extensions/sfext/minhit/MINHITSETSRDR.c.orig 2018-08-29 20:03:25.109519358 -0600 ++++ b/extensions/sfext/minhit/MINHITSETSRDR.c 2018-08-29 20:10:06.402075807 -0600 +@@ -27,7 +27,7 @@ Note: The point is that not only sortin + static Word comp(Word a, Word b) __pure; + + static Word comp(Word a, Word b) { +- Word ap,bp,t,q; ++ Word ap,bp,t; + ap = a; bp = b; + t = BDCOMP(LENGTH(ap),LENGTH(bp)); + while ((t == 0) && (bp != NIL) && (ap != NIL)) { +--- a/extensions/sfext/pcadst/CADFPCAD.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/pcadst/CADFPCAD.c 2018-08-29 20:10:06.402075807 -0600 +@@ -21,7 +21,7 @@ Outputs + + Word CADFPCAD(Word D, Word P, Word S, Word I, Word Pb) + { +- Word Db,Is,N,Sb,Pb_N,Ts,L,p,i,is,Q,Ms,C,Cs,Ds,Ss; ++ Word Db,Is,N,Sb,Pb_N,Ts,L,p,i,is,Ms,C,Cs,Ds,Ss; + Word Mb,mb; + + Step1: /* Is D the root cell? */ +--- a/extensions/sfext/pcadst/CADFPCADWI.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/pcadst/CADFPCADWI.c 2018-08-29 20:10:06.401075809 -0600 +@@ -22,7 +22,7 @@ Outputs + + Word CADFPCADWI(Word D, Word P, Word S, Word I, Word Pb) + { +- Word Db,Is,N,Sb,Pb_N,Ts,L,p,i,is,Q,Ms,C,Cs,Ds,Ss; ++ Word Db,Is,N,Sb,Pb_N,Ts,L,p,i,is,Ms,C,Cs,Ds,Ss; + Word Mb,mb; + + Step1: /* Is D the root cell? */ +--- a/extensions/sfext/pcadst/CCADCONEXT.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/pcadst/CCADCONEXT.c 2018-08-29 20:10:06.402075807 -0600 +@@ -21,7 +21,7 @@ Outputs + + void CCADCONEXT(Word n, Word P, Word C, Word *Ps_, Word *Cs_, Word *N_) + { +- Word Ps,i,Cs,Q,S,c,L,Lp,b,d,bs,ds,cs,T1,T2,N,Np; ++ Word Ps,i,Cs,Q,S,L,Lp,bs,ds,cs,T1,T2,N; + + Word t; + +--- a/extensions/sfext/pcadst/CCADCONmod.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/pcadst/CCADCONmod.c 2018-08-29 20:10:06.402075807 -0600 +@@ -22,7 +22,7 @@ Outputs + + void CCADCONmod(Word n, Word P, Word C, Word *Ps_, Word *Cs_) + { +- Word Ps,i,Cs,Q,S,c,L,Lp,b,d,bs,ds,cs,T1,T2; ++ Word Ps,i,Cs,Q,S,c,L,Lp,b,d,bs,ds,T1,T2; + + Step1: /* Set Ps to the empty projection list, and Cs to the full + original CAD C. */ +--- a/extensions/sfext/pcadst/LTFOCALWTV.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/pcadst/LTFOCALWTV.c 2018-08-29 20:10:06.402075807 -0600 +@@ -16,7 +16,7 @@ Outputs + + void LTFOCALWTV(Word C, Word n, Word *Lt_, Word *Lf_) + { +- Word L,Cp,Lt,Lf,t,Ltp,Lfp; ++ Word Cp,Lt,Lf,t,Ltp,Lfp; + + Step1: /* If C is undetermined recurse on the children. */ + t = LELTI(C,SC_CDTV); +--- a/extensions/sfext/pcadst/LTFOCWTV.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/pcadst/LTFOCWTV.c 2018-08-29 20:10:06.402075807 -0600 +@@ -15,7 +15,7 @@ Outputs + + void LTFOCWTV(Word C, Word *Lt_, Word *Lf_) + { +- Word L,Cp,Lt,Lf,t,Ltp,Lfp; ++ Word Cp,Lt,Lf,t,Ltp,Lfp; + + Step1: /* If C is undetermined recurse on the children. */ + t = LELTI(C,SC_CDTV); +--- a/extensions/sfext/pcadst/PCADSCANL.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/pcadst/PCADSCANL.c 2018-08-29 20:10:06.402075807 -0600 +@@ -18,7 +18,7 @@ Outputs + + Word PCADSCANL(Word Cs, Word i) + { +- Word CC,CC1,CC2,L,c; ++ Word CC,CC1,L,c; + + Step1: /* Get list of children. */ + CC = LELTI(Cs,SC_CDTV); +--- a/extensions/sfext/pcadst/PCADWRITE.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/pcadst/PCADWRITE.c 2018-08-29 20:10:06.402075807 -0600 +@@ -7,7 +7,7 @@ + + void PCADWRITE(Word Cs, Word Ps) + { +- Word C,l,i,L,k,I; ++ Word l,L,k,I; + + Step1: /* */ + I = PCADCINDEX(Cs); +--- a/extensions/sfext/pcadst/SCADDSCON.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/pcadst/SCADDSCON.c 2018-08-29 20:10:06.401075809 -0600 +@@ -30,7 +30,7 @@ example, would be bad. + + Word SCADDSCON(Word C, Word A, Word n) + { +- Word c,a,i,Cs,X,L,t; ++ Word c,a,i,Cs,X,L; + + Step1: /* Construct a preliminary version of Cs, with all but the child + list filled in. */ +--- a/extensions/sfext/pcadst/SIMPLE_CAD_INFO.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/pcadst/SIMPLE_CAD_INFO.c 2018-08-29 20:10:06.401075809 -0600 +@@ -6,7 +6,7 @@ n : the level + + void SIMPLE_CAD_INFO(Word D, Word P, Word n, Word flag) + { +- Word Ps,Cs,t,Db; ++ Word Ps,Cs,t; + + Step1: /* Check for the trivial cases. */ + switch( DOPFSUFF(P,LIST1(D)) ) { +--- a/extensions/sfext/projpf/PPFLPROJ.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/projpf/PPFLPROJ.c 2018-08-29 20:10:06.403075806 -0600 +@@ -17,11 +17,10 @@ Side Effects + + void PPFLPROJ(Word L, Word i, Word P) + { +- Word A,T,p,B,b,t,tp,C; ++ Word A,p,B,b,t,tp,C; + + Step1: /* Loop over each proj. fac. p in level i of P. */ + A = LELTI(P,i); +- T = NIL; + while(A != NIL) { + ADV(A,&p,&A); + +--- a/extensions/sfext/sfcons/CYLIMPFORM.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/sfcons/CYLIMPFORM.c 2018-08-29 20:10:06.403075806 -0600 +@@ -9,7 +9,7 @@ A : a list of atoms from which to constr + + Word CYLIMPFORM(Word C, Word P, Word k, Word A) + { +- Word SF,L,Lp,c,S,t,Q,As,Ap,Fp,F,Lt,Lf,s,Si,Fi,Qp,SF2; ++ Word SF,L,Lp,c,S,t,F,Lt,Lf,s,Si,Fi,Qp,SF2; + + Step1: /* Set L to a list of all (k-1)-level cells over which there are + k-level cells with SC_TMPM of TRUE. */ +--- a/extensions/sfext/sfcons/GEOTEST.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/sfcons/GEOTEST.c 2018-08-29 20:10:06.403075806 -0600 +@@ -101,7 +101,7 @@ Word GEOMERGE(Word c,Word G,Word P) + + Word GEOFIT(Word c,Word G,Word P) + { +- Word Q,Qp,C_Q,C_Qp,Ap,App,R,Rp,T,Tp,t,Rpp,A,m,L,x,a; ++ Word Q,Qp,C_Q,C_Qp,Ap,App,R,Rp,T,Tp,t,Rpp,m,L,x,a; + FIRST5(G,&Q,&C_Q,&Ap,&R,&T); + FIRST5(c,&Qp,&C_Qp,&App,&Rp,&Tp); + Tp = SINTER(Tp,T); +@@ -128,8 +128,8 @@ Word GEOFIT(Word c,Word G,Word P) + + Word GEOTEST(Word C,Word P,Word k,Word A) + { +- Word L,Lp,c,S,t,G,Q,Ap,Qp,App,C_Q,C_Qp,SF,SF1, +- SF2,Lt,Lf,Si,Fi,T,R,Tp,Rp,Rpp,Bs,Bi,i,s,t1,t2,SFp,Ap1,Ap2,a; ++ Word L,Lp,c,S,t,G,Q,Ap,Qp,App,C_Q,SF,SF1, ++ SF2,Lt,Lf,T,Bs,Bi,i,s,t1,t2,Ap1,Ap2,a; + + Step1: /* Set L to a list of all (k-1)-level cells over which there are + k-level cells with SC_TMPM of TRUE. */ +--- a/extensions/sfext/sfcons/SFC2.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/sfcons/SFC2.c 2018-08-29 20:10:06.402075807 -0600 +@@ -5,7 +5,7 @@ Solution formula construction version 2 + + void QepcadCls::SFC2(Word D, Word P, Word J, Word n, Word sfm) + { +- Word t,SF,D0,P0,J0,D1,P1,Pp,Dp,Q,L,Lt,Lf; ++ Word t,SF,D1,P1,Pp,Dp,Q,L,Lt,Lf; + + Step1: /* Space is either empty or R^n. */ + t = DOPFSUFF(P,LIST1(D)); +--- a/extensions/sfext/sfcons/SFC4.c.orig 2018-08-29 20:05:52.865359501 -0600 ++++ b/extensions/sfext/sfcons/SFC4.c 2018-08-29 20:10:06.403075806 -0600 +@@ -29,7 +29,7 @@ static Word F1; /* Flag indicating that + + void QepcadCls::SFC4(Word D, Word P, Word J, Word n, Word L) + { +- Word t,SF,Dp,Pp,Lt,Lf,LA,Q,D1,P1,D0,P0,J0,i,Lp,pflag; ++ Word t,SF,Dp,Pp,Lt,Lf,LA,Q,D1,P1,D0,P0,J0,i; + char e,s,m,c; + e = s = m = c = '\0'; + T1 = T2 = T3 = T4 = 0; +--- a/extensions/sfext/sfcons/SFCFULLD.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/sfcons/SFCFULLD.c 2018-08-29 20:10:06.403075806 -0600 +@@ -19,8 +19,7 @@ static Word PLISTOETAmod(Word p,Word B,W + + void QepcadCls::SFCFULLD(Word D, Word P, Word J, Word n) + { +- Word t,SF,Dp,Pp,Lt,Lf,LA,Q,D1,P1,D0,P0,J0,i,Lp,pflag, L; +- char e,s,m,c; ++ Word t,SF,Dp,Pp,Lt,Lf,LA,L; + + Step1: /* Space is either empty or R^n. */ + t = DOPFSUFF_FULLD(P,LIST1(D)); +--- a/extensions/sfext/sfcons/SFCFULLDf.c.orig 2018-08-29 20:05:52.865359501 -0600 ++++ b/extensions/sfext/sfcons/SFCFULLDf.c 2018-08-29 20:10:06.403075806 -0600 +@@ -19,8 +19,7 @@ static Word PLISTOETAmod(Word p,Word B,W + + Word QepcadCls::SFCFULLDf(Word D, Word P, Word J, Word n) + { +- Word t,SF,Dp,Pp,Lt,Lf,LA,Q,D1,P1,D0,P0,J0,i,Lp,pflag, L; +- char e,s,m,c; ++ Word t,SF,Dp,Pp,Lt,Lf,LA,L; + + Step1: /* Space is either empty or R^n. */ + t = DOPFSUFF_FULLD(P,LIST1(D)); +--- a/extensions/sfext/sfcons/SOLEXTINT.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/sfcons/SOLEXTINT.c 2018-08-29 20:10:06.403075806 -0600 +@@ -10,7 +10,7 @@ method to call and, of course, calls it. + + void QepcadCls::SOLEXTINT() + { +- Word t,F_e,F_n,F_s, T, f, c; ++ Word T, f, c; + + Step1: /* Initialization */ + T = ACLOCK(); +--- a/extensions/sfext/sort/GMSDS.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/extensions/sfext/sort/GMSDS.c 2018-08-29 20:10:06.404075804 -0600 +@@ -19,7 +19,7 @@ static Word G23VSDS(Word *v,Word m,Word + + Word GMSDS(Word *A, Word m, Word (*C)(Word,Word)) + { +- Word *T,*T1,*T2,*A1,*A2,m1,m1p,m2,m2p,mp,k,l; ++ Word *T,*T1,*T2,*A1,*A2,m1,m1p,m2,m2p,mp,k; + + Step1: /* Split. */ + m1 = m >> 1; +--- a/plot2d/plot.cc.orig 2018-08-29 20:08:10.014211101 -0600 ++++ b/plot2d/plot.cc 2018-08-29 20:10:06.396075816 -0600 +@@ -112,7 +112,6 @@ void* readdata(void *x) + { + vector E; + istream &in = *inp; +- int flag; + char c; + do { + while( in >> c ) +--- a/source/db/SINGULAR.c.orig 2018-08-29 20:08:10.015211100 -0600 ++++ b/source/db/SINGULAR.c 2018-08-29 20:10:06.406075801 -0600 +@@ -162,8 +162,6 @@ Return: /* Prepare for return. */ + + void SingularServer::IPFAC(Word r, Word P, Word *s_, Word *c_, Word *L_) + { +- int T1 = serverTime(); +- + Word V = CreateVariableList(r); + string out = WritePolyForSingular(r,P,V); + +@@ -212,9 +210,6 @@ void SingularServer::IPFAC(Word r, Word + Word ct = IABSF(lcf); + sn *= ISIGNF(lcf); + +- // Figure out how long that took! +- int T2 = serverTime(); +- + // RETURN + *s_ = sn; + *c_ = ct; +--- a/source/db/unnamedpipe.h.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/db/unnamedpipe.h 2018-08-29 20:10:06.406075801 -0600 +@@ -118,7 +118,7 @@ public: + if (openmask[0]) { close(fd[0]); openmask[0] = false; } + } + void closeOut() { +- const char ts[2] = {EOF,'\n'}; ++ // const char ts[2] = {EOF,'\n'}; + if (_out) { delete _out; _out = 0; } + if (openmask[1]) { + // write(fd[1],ts,2); +--- a/source/io/DNFLWR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/io/DNFLWR.c 2018-08-29 20:10:06.407075800 -0600 +@@ -13,7 +13,7 @@ Disjuctive Normal Form Label Write. + + void DNFLWR(Word N, Word V, Word F) + { +- Word F1,F2,Fp,T; ++ Word F1,Fp,T; + + Step1: /* Classify the formula F. */ + T = FIRST(F); +--- a/source/io/DNFWR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/io/DNFWR.c 2018-08-29 20:10:06.408075798 -0600 +@@ -12,7 +12,7 @@ Disjunctive Normal Form Write. + + void DNFWR(Word V, Word F) + { +- Word F1,F2,Fp,T; ++ Word F1,Fp,T; + + Step1: /* Classify the formula F. */ + T = FIRST(F); +--- a/source/io/IPLLDWR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/io/IPLLDWR.c 2018-08-29 20:10:06.407075800 -0600 +@@ -12,7 +12,7 @@ Integral Polynomial, List of Lists, Dist + + void IPLLDWR(Word V, Word A) + { +- Word A1,A11,i,P,L,H; ++ Word A1,A11,i,P,H; + /* hide i,j,n,r; */ + + Step1: /* Write. */ +--- a/source/io/IPLLDWRMOD.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/io/IPLLDWRMOD.c 2018-08-29 20:10:06.407075800 -0600 +@@ -12,7 +12,7 @@ Integral Polynomial, List of Lists, Dist + + void IPLLDWRMOD(Word V, Word A) + { +- Word A1,A11,i,P,L,H; ++ Word A1,A11,i,P,H; + /* hide i,j,n,r; */ + + Step1: /* Write. */ +--- a/source/io/PCADSWR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/io/PCADSWR.c 2018-08-29 20:10:06.407075800 -0600 +@@ -11,7 +11,7 @@ Partial CAD signature write. + + void PCADSWR(Word c) + { +- Word M,cb,cp,p,s,S; ++ Word cb,cp,p,s,S; + /* hide p; */ + + Step1: /* common. */ +--- a/source/io/PCADWR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/io/PCADWR.c 2018-08-29 20:10:06.407075800 -0600 +@@ -11,7 +11,7 @@ Partial CAD write. + + void PCADWR(Word c) + { +- Word M,cb,cp,p,s; ++ Word cb,cp,p,s; + /* hide p; */ + + Step1: /* common. */ +--- a/source/io/PRODWR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/io/PRODWR.c 2018-08-29 20:10:06.407075800 -0600 +@@ -10,7 +10,8 @@ Product Write. + + void PRODWR(Word v) + { +- Word I,I1,P1,P11,Pp,R1,W,W1,i,j,n1,v1,vp; ++ /* Word P1,P11,Pp,i,j,n1; */ ++ Word I,I1,R1,W,W1,v1,vp; + /* hide i,j,n1; */ + + SWRITE("In \"PRODWR\"! This is dead code!\n"); exit(1); +--- a/source/io/SAMPLEWR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/io/SAMPLEWR.c 2018-08-29 20:10:06.408075798 -0600 +@@ -55,8 +55,7 @@ Return: /* Prepare for return. */ + + void QepcadCls::SAMPLEWR(Word c) + { +- Word I,Ip,M,Mp,b,bp,k,s,F,j,Ms,Is; +- Word M1; ++ Word k,s; + + s = LELTI(c,SAMPLE); + k = LELTI(c,LEVEL); +--- a/source/main/CADautoConst.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/main/CADautoConst.c 2018-08-29 20:10:06.409075797 -0600 +@@ -16,11 +16,7 @@ been set to something other than NIL, th + + void QepcadCls::CADautoConst() + { +- Word A,D,F,F_e,F_n,F_s,Fh,J,P,Q,Ths,f,i,r,t, T; +- /* hide Ths,i,t; */ +- Word cL,**cC,cr,ce,ci,*cT,cj,cs,cl,ct; /* Chris variables. */ +- Word Cs,Ps,Qs,Pps,Cps,Qps,SF; /* Chris variables. */ +- char c1,c2; /* Chris variables. */ ++ Word A,D,F,Fh,J,P,Q,f,r; + + Step1: /* Normalize. */ + FIRST4(GVF,&r,&f,&Q,&Fh); +--- a/source/main/INITCTRL.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/main/INITCTRL.c 2018-08-29 20:10:06.409075797 -0600 +@@ -7,12 +7,9 @@ Initialize Program/Trace Control. + + void INITCTRL() + { +- Word k; +- /* hide k; */ +- + Step1: /* Initialize program control */ +- Word PCDBUSE = 'y'; +- Word PCDBLIMIT = 10; ++ PCDBUSE = 'y'; ++ PCDBLIMIT = 10; + + Step2: /* Initialize Algorithm Trace Control Variables. */ + TCPROJ = NIL; +--- a/source/main/INITIO.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/main/INITIO.c 2018-08-29 20:10:06.409075797 -0600 +@@ -14,8 +14,6 @@ void OutputContextInit(ostream&); + + void INITIO() + { +- Word i; +- + Step1: /* Initialize Input. */ + if (isatty(0)) + InputContextInit(*(new readlineIstream())); +--- a/source/main/INITSTAT.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/main/INITSTAT.c 2018-08-29 20:10:06.409075797 -0600 +@@ -7,10 +7,6 @@ Initialize Statistics. + + void INITSTAT() + { +- Word i; +- /* hide i; */ +- +- + Step5: /* Statistics on Databases. */ + TMDBMNG = 0; + TMDBSAV = 0; +--- a/source/main/QEPCADauto.c.orig 2018-08-29 20:05:52.867359499 -0600 ++++ b/source/main/QEPCADauto.c 2018-08-29 20:10:06.409075797 -0600 +@@ -20,11 +20,8 @@ Quantifier Elimination by Partial Cylind + + void QepcadCls::QEPCADauto(Word Fs, Word *t_, Word *F_e_, Word *F_n_, Word *F_s_) + { +- Word A,D,F,F_e,F_n,F_s,Fh,J,P,Q,Ths,f,i,r,t, T; +- /* hide Ths,i,t; */ +- Word cL,**cC,cr,ce,ci,*cT,cj,cs,cl,ct; /* Chris variables. */ +- Word Cs,Ps,Qs,Pps,Cps,Qps,SF; /* Chris variables. */ +- char c1,c2; /* Chris variables. */ ++ Word A,D,F,F_e,F_n,F_s,Fh,J,P,Q,f,r,t; ++ /* hide t; */ + + Step1: /* Normalize. */ + t = 0; +--- a/source/main/QEPCAD.c.orig 2018-08-29 20:05:52.867359499 -0600 ++++ b/source/main/QEPCAD.c 2018-08-29 20:10:06.409075797 -0600 +@@ -22,9 +22,6 @@ void QepcadCls::QEPCAD(Word Fs, Word *t_ + { + Word A,D,F,F_e,F_n,F_s,Fh,J,P,Q,Ths,f,i,r,t, T; + /* hide Ths,i,t; */ +- Word cL,**cC,cr,ce,ci,*cT,cj,cs,cl,ct; /* Chris variables. */ +- Word Cs,Ps,Qs,Pps,Cps,Qps,SF; /* Chris variables. */ +- char c1,c2; /* Chris variables. */ + Step1: /* Normalize. */ + t = 0; + F_e = F_n = F_s = NIL; +--- a/source/proj/ECLEVEL.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/proj/ECLEVEL.c 2018-08-29 20:10:06.408075798 -0600 +@@ -14,10 +14,9 @@ Output + + Word ECLEVEL(Word L) + { +- Word k,Lp,L1; ++ Word k,L1; + + Step1: /* Initialize. */ +- Lp = L; + k = 0; + + Step2: /* Loop. */ +--- a/source/proj/PROJCO.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/proj/PROJCO.c 2018-08-29 20:10:06.408075798 -0600 +@@ -15,7 +15,7 @@ Collins' projection. + + Word QepcadCls::PROJCO(Word r, Word A) + { +- Word A1,A2,Ap,Ap1,Ap2,App,D,L,L1,P,P1,R,R1,R11,R2,R21,Rp,Rp1,Rp11,Rp2, ++ Word A1,A2,Ap,Ap1,Ap2,App,D,L,L1,P,R,R1,R11,R2,R21,Rp,Rp1,Rp11,Rp2, + Rpp,Rs2,S1,Sp1,T,W,ap1,b,d,i,i1,i2,k,t; + + Step1: /* $r = 2$. */ +--- a/source/proj/PROJECTauto.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/proj/PROJECTauto.c 2018-08-29 20:10:06.408075798 -0600 +@@ -17,7 +17,7 @@ Projection Phase. + + void QepcadCls::PROJECTauto(Word r, Word A, Word *P_, Word *J_) + { +- Word D,F,J,P,Ps,J_k1,P_k,R,Ths,Thss,k,i; ++ Word D,F,J,P,J_k1,P_k,R,k,i; + + Step1: /* Initialize. */ + P = LLCOPY(A); +--- a/source/proj/PROJECT.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/proj/PROJECT.c 2018-08-29 20:10:06.408075798 -0600 +@@ -19,7 +19,7 @@ Projection Phase. + + void QepcadCls::PROJECT(Word r, Word A, Word *P_, Word *J_) + { +- Word D,F,J,P,Ps,J_k1,P_k,R,Ths,Thss,k,i; ++ Word D,F,J,P,J_k1,P_k,R,Ths,Thss,k,i; + + Step1: /* Initialize. */ + P = LLCOPY(A); +--- a/source/proj/PROJMCECmod.c.orig 2018-08-29 20:07:50.511232206 -0600 ++++ b/source/proj/PROJMCECmod.c 2018-08-29 20:10:06.408075798 -0600 +@@ -18,8 +18,8 @@ not propogate! + + Word QepcadCls::PROJMCECmod(Word r, Word A) + { +- Word A1,A2,Ap,Ap1,Ap2,App,D,L,Lh,P,R,W,i,t,Q,j,S,Sp,C; +- Word Ls, Lc,LL,f,rp,fp,tf,T1,fef,esu,AssTmp,Sf,k; ++ Word A1,A2,Ap,Ap1,Ap2,App,D,L,Lh,P,R,W,i,t,Q,j,S,C; ++ Word Ls, Lc,LL,f,rp,fp,T1,fef,esu,AssTmp,Sf; + + Step0: /* Obtain pivot constraint: If pivot is not all of level k, we can't use it! */ + C = LELTI(GVPIVOT,r); +--- a/source/proj/PROJMCmod.c.orig 2018-08-29 20:07:50.511232206 -0600 ++++ b/source/proj/PROJMCmod.c 2018-08-29 20:10:06.409075797 -0600 +@@ -20,8 +20,8 @@ using namespace std; + + Word QepcadCls::PROJMCmod(Word r, Word A) + { +- Word A1,A2,Ap,Ap1,Ap2,App,D,L,Lh,P,R,W,i,t,Q,j,S,Sp; +- Word Ls, Lc,LL,f,rp,fp,tf,T1,fef,esu,AssTmp,Sf; ++ Word A1,A2,Ap,Ap1,Ap2,App,D,L,Lh,P,R,W,i,t,Q,j,S; ++ Word Ls, Lc,LL,f,rp,fp,T1,fef,esu,AssTmp,Sf; + + Step1: /* Obtain coefficients. */ + P = NIL; +--- a/source/proj/PROJMCx.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/proj/PROJMCx.c 2018-08-29 20:10:06.408075798 -0600 +@@ -15,7 +15,7 @@ McCallum's projection excluding leading + + Word QepcadCls::PROJMCx(Word r, Word A) + { +- Word A1,A2,Ap,Ap1,Ap2,App,D,L,Lh,P,R,W,i,t; ++ Word A1,A2,Ap,Ap1,Ap2,App,D,P,R,W; + + Step1: /* Obtain coefficients. */ + P = NIL; +--- a/source/saclib/GCSI.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/saclib/GCSI.c 2018-08-29 20:10:06.408075798 -0600 +@@ -23,10 +23,9 @@ extern void gcw_MARK(); + + void GCSI(Word s, char *EACSTACK) + { +- Word I,L,N,N1,Np,Np1,T,T1,c,**i,j,inc; ++ Word I,L,N,N1,Np,Np1,T,T1,c,inc; + char *a; +- GCArray *v; +- /* hide I,L,N,N1,Np,Np1,T,T1,c,i,j,inc,a,v; */ ++ /* hide I,L,N,N1,Np,Np1,T,T1,c,inc,a; */ + + Step1: /* Setup. */ + if (GCM == 1) { +--- a/source/sysolve/EVALSYS.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/sysolve/EVALSYS.c 2018-08-29 20:10:06.407075800 -0600 +@@ -20,7 +20,7 @@ Outputs: + + Word EVALSYS(Word S, BDigit t, Word R) + { +- Word r, L, i, S_i, Ap, a, A, is, As, F, f, ip, fp, s, c; ++ Word r, L, i, S_i, Ap, a, A, is, As; + + Step1: /* Construct the skelaton of L, the answer. */ + r = LENGTH(S); +--- a/source/sysolve/SYSSOLVE.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/sysolve/SYSSOLVE.c 2018-08-29 20:10:06.407075800 -0600 +@@ -21,7 +21,7 @@ Output + + Word SYSSOLVECAD(BDigit r, Word L, Word A, Word Vp, QepcadCls &Q) + { +- Word F, Fp, d, t, Lt, Lf, V, S; ++ Word F, Lt, Lf, V, S; + + /* Set variable list */ + if (LENGTH(Vp) < r) { +--- a/source/sysolve/VERIFYCONSTSIGN.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/sysolve/VERIFYCONSTSIGN.c 2018-08-29 20:10:06.406075801 -0600 +@@ -78,7 +78,7 @@ BDigit VERIFYPOSITIVITY(Word A, BDigit r + else if (FIRST(A) != IROOT) + { + /* atomic formula is "P_A T_A 0", where P_A is of level k_A. */ +- Word T_A,P_A,k_A,s,rp,Pp,P,a,T; ++ Word T_A,P_A,k_A; + FIRST3(A,&T_A,&P_A,&k_A); + if (r != k_A) { goto Return; } + +--- a/source/ticad/ACCCVBC.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/ticad/ACCCVBC.c 2018-08-29 20:10:06.411075794 -0600 +@@ -28,7 +28,7 @@ static Word SECTIONPOLS(Word k, Word c, + + Word QepcadCls::ACCCVBC(Word k, Word c, Word M, Word B1, Word b, Word* B1h) + { +- Word d, nnf, dV, IV, cp, i, I_i, d_i, c_i, L, Q, Qb, Qbs, F, Fp, a; ++ Word d, nnf, dV, IV, i, I_i, c_i, L, Q, Qb, Qbs, F, Fp, a; + + Step1: /* Initialization **********************************************/ + a = NIL; /* this is the pseudo-sample point we're building up *******/ +@@ -44,7 +44,6 @@ Step1: /* Initialization *************** + Step2: /* Loop over each level from 1 to k ****************************/ + for(i = 1; i <= k; i++) { + I_i = LELTI(IV,i); +- d_i = LELTI(dV,i); + c_i = LELTI(LELTI(c_i,CHILD),I_i); + + Step3: /* c_i is a section over a 0-dimensional cell ******************/ +@@ -108,11 +107,10 @@ L : the list of all k-level polynomials + ======================================================================*/ + static Word SECTIONPOLS(Word k, Word c, Word P) + { +- Word L,P_k,M,i,Mp; ++ Word L,P_k,M,i; + L = NIL; + P_k = LELTI(P,k); +- M = LELTI(c,MULSUB); +- for(Mp = M; M != NIL; M = RED(M)) { ++ for(M = LELTI(c,MULSUB); M != NIL; M = RED(M)) { + i = FIRST(FIRST(M)); + L = COMP(LELTI(P_k,i),L); } + return L; +--- a/source/ticad/ACCCVBCR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/ticad/ACCCVBCR.c 2018-08-29 20:10:06.409075797 -0600 +@@ -25,7 +25,7 @@ static Word SECTIONPOLS(Word k, Word c, + + Word QepcadCls::ACCCVBCR(Word k, Word c, Word B1, Word b, Word* B1h) + { +- Word d, nnf, dV, IV, cp, i, I_i, d_i, c_i, L, Q, Qb, Qbs, F, Fp, a; ++ Word d, nnf, dV, IV, i, I_i, c_i, L, Q, Qb, Qbs, F, Fp, a; + + Step1: /* Initialization **********************************************/ + a = NIL; /* this is the pseudo-sample point we're building up *******/ +@@ -41,7 +41,6 @@ Step2: /* Loop over each level from 1 to + c_i = GVPC; + for(i = 1; i <= k; i++) { + I_i = LELTI(IV,i); +- d_i = LELTI(dV,i); + c_i = LELTI(LELTI(c_i,CHILD),I_i); + + Step3: /* c_i is a section over a 0-dimensional cell ******************/ +@@ -99,11 +98,10 @@ L : the list of all k-level polynomials + ======================================================================*/ + static Word SECTIONPOLS(Word k, Word c, Word P) + { +- Word L,P_k,M,i,Mp; ++ Word L,P_k,M,i; + L = NIL; + P_k = LELTI(P,k); +- M = LELTI(c,MULSUB); +- for(Mp = M; M != NIL; M = RED(M)) { ++ for(M = LELTI(c,MULSUB); M != NIL; M = RED(M)) { + i = FIRST(FIRST(M)); + L = COMP(LELTI(P_k,i),L); } + return L; +--- a/source/ticad/APEQC.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/ticad/APEQC.c 2018-08-29 20:10:06.410075795 -0600 +@@ -21,7 +21,7 @@ Effect + + void QepcadCls::APEQC(Word c, Word k, Word P) + { +- Word c1,E,E1,E11,Ep,Ep1,h,i,j,m,M,Mp,S,t,tp,Ps,p; ++ Word c1,E,E1,E11,Ep,Ep1,i,j,m,M,Mp,S,t,Ps,p; + + Step1: /* Get (k+1)-level equational constraints, if none, return. */ + E = LELTI(GVEQNCONST,k+1); +--- a/source/ticad/CONSTRUCT.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/ticad/CONSTRUCT.c 2018-08-29 20:10:06.411075794 -0600 +@@ -24,8 +24,7 @@ Word IUPSBRRI(Word B, BDigit k); + void QepcadCls::CONSTRUCT(Word c, Word k, Word f, Word Ps_, Word As) + { + BDigit p,t,Ths; +- Word B,b,E,I,Ip,I1,J,Jp,L,M,Ps,P1,Ps1,S,s,T,Q; +- Word junk,a1,b1,t1,p1,j1; ++ Word B,b,E,I,Ip,I1,J,Jp,L,M,Ps,S,s,T; + + Step0: /* Root cell. */ + if (k == 0) { CONSTRUCT1(c,k,f,Ps_,As); goto Return; } +@@ -36,9 +35,7 @@ Step1: /* Extract the projection factors + for(Word Pt = CINV(Ps_); Pt != NIL; Pt = RED(Pt)) + { + Word Pt1 = FIRST(Pt); +- if (LELTI(Pt1,PO_TYPE) == PO_POINT) +- junk = 1; +- else ++ if (LELTI(Pt1,PO_TYPE) != PO_POINT) + Ps = COMP(LELTI(Pt1,PO_POLY),Ps); + } + +@@ -242,9 +239,8 @@ BDigit C1COMP(Word A, Word B) + /* Root cell. */ + void QepcadCls::CONSTRUCT1(Word c, Word k, Word f, Word Ps_, Word As) + { +- BDigit p,t,Ths; +- Word B,b,E,I,Ip,I1,J,Jp,L,M,Ps,P1,Ps1,S,s,T,Q,Pp; +- Word junk,a1,b1,t1,p1,j1; ++ BDigit Ths; ++ Word I,Ps,Pp; + + Step1: /* Extract the projection factors from their attribute lists. */ + Ps = NIL; /* Basis for real-root isolation - i.e. the polynomials */ +@@ -390,7 +386,7 @@ Word IUPSBRRIIR(Word t_B, BDigit p, BDig + if (Li == 0) { fail = true; goto Return; } + + for(BDigit t = (n%2==1 ? 1 : -1); Li != NIL; t *= -1, Li = RED(Li)) { +- Word I = FIRST(Li), i1, i2; ++ Word I = FIRST(Li); + Word J = SIPIR(C[i],I,t,k); + L = COMP(LIST3(i,J,t),L); + } +--- a/source/ticad/EC1.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/ticad/EC1.c 2018-08-29 20:10:06.411075794 -0600 +@@ -15,7 +15,7 @@ Establish Children of the root. + + void EC1(Word c, Word L, Word Bs) + { +- Word B,I,J,Lp,M,N,S,Sp,P,a,b,kp,l,r,rp,s,xb,xp,Lp1,OL; ++ Word B,I,J,Lp,M,N,S,Sp,P,a,b,kp,l,r,s,xb,xp,Lp1,OL; + /* hide kp,xp; */ + Word T; + +@@ -58,7 +58,6 @@ Step4: /* First section. */ + + Step5: /* Check if there are more roots. */ + if (Lp == NIL) goto Step9; +- rp = r; + + Step6: /* Next sector. */ + ADV(Lp,&Lp1,&Lp); +--- a/source/ticad/EC.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/ticad/EC.c 2018-08-29 20:10:06.410075795 -0600 +@@ -16,7 +16,7 @@ Establish Children. + + void EC(Word c, Word L, Word E, Word Bs) + { +- Word B,I,J,Lp,M,N,S,Sp,Pp,P,a,b,bp,kp,l,r,rp,s,sp,x,xb,xp; ++ Word B,I,J,Lp,M,N,S,Sp,Pp,P,a,b,bp,kp,l,r,s,sp,x,xb,xp; + /* hide kp,xp; */ + Word T; + +@@ -52,7 +52,6 @@ Step4: /* First section. */ + + Step5: /* Check if there are more roots. */ + if (Lp == NIL) goto Step9; +- rp = r; + + Step6: /* Next sector. */ + ADV2(Lp,&I,&B,&Lp); FIRST2(I,&l,&r); +--- a/source/ticad/ECR.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/ticad/ECR.c 2018-08-29 20:10:06.410075795 -0600 +@@ -16,7 +16,7 @@ Establish Children on a rational sample + + void ECR(Word c, Word L, Word E, Word Bs) + { +- Word B,I,J,Lp,M,N,S,Sp,Pp,P,a,b,bp,kp,l,r,rp,s,sp,x,xb,xp; ++ Word B,I,J,Lp,M,N,S,Sp,Pp,P,a,b,bp,kp,l,r,s,sp,x,xb,xp; + /* hide kp,xp; */ + Word T; + +@@ -55,7 +55,6 @@ Step4: /* First section. */ + + Step5: /* Check if there are more roots. */ + if (Lp == NIL) goto Step9; +- rp = r; + + Step6: /* Next sector. */ + ADV2(Lp,&I,&B,&Lp); FIRST2(I,&l,&r); +--- a/source/ticad/MAFUPGCD.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/ticad/MAFUPGCD.c 2018-08-29 20:10:06.409075797 -0600 +@@ -17,7 +17,7 @@ Output + + Word MAFUPGCD(Word p, Word M, Word A, Word B) + { +- Word C,A1,A2,A3,a,ap,r; ++ Word C,A1,A2,A3; + + Step1: /* A = 0 \/ B = 0 */ + if (A == 0) { +--- a/source/ticad/MAFUPMON.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/ticad/MAFUPMON.c 2018-08-29 20:10:06.410075795 -0600 +@@ -17,7 +17,7 @@ Output + + Word MAFUPMON(Word p, Word M, Word A) + { +- Word B,d,Ap,a,ap,r; ++ Word B,d,Ap,a,ap; + + Step1: /* A = 0 */ + if (A == 0) { +--- a/source/ticad/QFFTEV.c.orig 2018-08-29 20:03:25.112519355 -0600 ++++ b/source/ticad/QFFTEV.c 2018-08-29 20:10:06.411075794 -0600 +@@ -17,8 +17,8 @@ static Word ATOMETFEVAL(Word Q, Word D, + + Word QepcadCls::QFFTEV(Word F, Word c, Word k) + { +- Word F1,Fp,I,Pt,T,i,j,m,s,t,tp,z; +- /* hide m,t,tp,z; */ ++ Word F1,Fp,I,Pt,T,i,j,s,t,tp,z; ++ /* hide t,tp,z; */ + + Step1: /* Classify the formula $F$. */ + T = FIRST(F); +--- a/source/ticad/SIGNP1.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/ticad/SIGNP1.c 2018-08-29 20:10:06.410075795 -0600 +@@ -19,7 +19,7 @@ using namespace std; + + void SIGNP1(Word c, Word P1, Word I) + { +- Word S1,c1,cb,I1; ++ Word c1,cb,I1; + + Step1: /* Compute the signatures of $P_1$. */ + vector S; +--- a/source/ticad/SUBST.c.orig 2018-08-29 20:05:52.867359499 -0600 ++++ b/source/ticad/SUBST.c 2018-08-29 20:10:06.410075795 -0600 +@@ -20,7 +20,6 @@ Substitute the sample point into the pro + Word QepcadCls::SUBST(Word c, Word k, Word M, Word b, Word B) + { + Word B1,Bp,S,S1; +- Word dV,IV; + Word P,L,Sp,T1,T2,G,Q,f,i; + + Step1: /* Substitute. */ +--- a/source/ticad/SUBSTR.c.orig 2018-08-29 20:05:52.868359497 -0600 ++++ b/source/ticad/SUBSTR.c 2018-08-29 20:10:06.411075794 -0600 +@@ -20,7 +20,6 @@ Substitute the rational sample point int + Word QepcadCls::SUBSTR(Word c, Word k, Word b, Word B) + { + Word B1,Bp,S,S1; +- Word dV,IV; + Word P,L,Q,T1,T2,Sp,G,f,i; + + Step1: /* Do it. */ +--- a/source/ticad/TICADauto.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/ticad/TICADauto.c 2018-08-29 20:10:06.410075795 -0600 +@@ -24,7 +24,7 @@ Output + + Word QepcadCls::TICADauto(Word Q, Word F, Word f, Word P, Word A) + { +- Word As,D,Ps,Ths,Thss,c,cp,k,s,sh,sp,t,R,S; ++ Word As,D,Ps,c,k,s,sh,t; + + Step1: /* Initialize. */ + D = INITPCAD(); +--- a/source/ticad/TICAD.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/ticad/TICAD.c 2018-08-29 20:10:06.410075795 -0600 +@@ -24,7 +24,7 @@ Output + + Word QepcadCls::TICAD(Word Q, Word F, Word f, Word P, Word A) + { +- Word As,D,Ps,Ths,Thss,c,cp,k,s,sh,sp,t,R,S; ++ Word As,D,Ps,Ths,Thss,c,k,s,sh,t; + + Step1: /* Initialize. */ + D = INITPCAD(); +--- a/source/userint/PRDLFI.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/userint/PRDLFI.c 2018-08-29 20:10:06.411075794 -0600 +@@ -7,7 +7,7 @@ Process "display-level-factors i" comman + + void QepcadCls::PRDLFI() + { +- Word i,j,L; ++ Word i; + + Step1: /* Get level. */ + i = IREAD(); +--- a/source/userint/PREQNCONSTL.c.orig 2018-08-29 20:05:52.868359497 -0600 ++++ b/source/userint/PREQNCONSTL.c 2018-08-29 20:10:06.412075792 -0600 +@@ -90,7 +90,7 @@ Word POLYLABEL(Word P, Word p, Word r, W + + void QepcadCls::PREQNCONSTPOLY() + { +- Word t1,t2,t3,r,P1,E,k,pi; ++ Word t1,t2,t3,r,P1,E,pi; + + // Check if propagation of equational constraints was specified. + if (PCPROPEC == FALSE) { +--- a/source/userint/PRMCC.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/userint/PRMCC.c 2018-08-29 20:10:06.411075794 -0600 +@@ -10,7 +10,7 @@ Process "manually choose a cell" command + + void QepcadCls::PRMCC(Word *t_) + { +- Word C,c,cp,t; ++ Word c,t; + /* hide t; */ + + Step1: /* Read in an argument. */ +--- a/source/userint/PRPROPEC.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/userint/PRPROPEC.c 2018-08-29 20:10:06.412075792 -0600 +@@ -7,7 +7,7 @@ Process prop-eqn-const command. + + void QepcadCls::PRPROPEC() + { +- Word C,i,r; ++ Word i,r; + + Step1: /* Toggle the PCPROPEC global variable and initialize globals. */ + GVEQNCONST = GVPIVOT = NIL; +--- a/source/userint/PRRMPF.c.orig 2018-01-25 14:25:22.000000000 -0700 ++++ b/source/userint/PRRMPF.c 2018-08-29 20:10:06.411075794 -0600 +@@ -7,7 +7,7 @@ Process "Remove Projection Factor" comma + + void QepcadCls::PRRMPF() + { +- Word A_i,C,P_i,P_ij,i,j,t; ++ Word C,P_i,P_ij,i,j,t; + /* hide C,t; */ + + Step1: /* Read in arguments. */ From f589b9b70d83555d8f4e3759c099db634ed7e1ed Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 23 Aug 2019 15:55:40 -0400 Subject: [PATCH 08/77] Fix typo in comment --- build/pkgs/qepcad/spkg-install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/qepcad/spkg-install b/build/pkgs/qepcad/spkg-install index 937760c0790..5e40b7848ff 100644 --- a/build/pkgs/qepcad/spkg-install +++ b/build/pkgs/qepcad/spkg-install @@ -15,7 +15,7 @@ export qe=$(pwd -P) # https://trac.sagemath.org/ticket/10224 # * Add rpath to compiler flags, see # https://trac.sagemath.org/ticket/22653 -# * User ARFLAGS that also work on macOS, avoiding the U option, see +# * Use ARFLAGS that also work on macOS, avoiding the U option, see # https://trac.sagemath.org/ticket/28388 $MAKE -j1 opt SHELL=/bin/sh FLAGSo="-O3 -g -Wl,-rpath,$SAGE_LOCAL/lib" ARFLAGS="crv" if [ $? -ne 0 ]; then From 9f35106290cf9e2d5d408f7efae4dbb08117d7ee Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 23 Aug 2019 15:56:21 -0400 Subject: [PATCH 09/77] Upgrade qepcad to B.1.72 --- build/pkgs/qepcad/checksums.ini | 6 +++--- build/pkgs/qepcad/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/qepcad/checksums.ini b/build/pkgs/qepcad/checksums.ini index 080531dee83..400dd800ac0 100644 --- a/build/pkgs/qepcad/checksums.ini +++ b/build/pkgs/qepcad/checksums.ini @@ -1,4 +1,4 @@ tarball=qepcad-VERSION.tar.gz -sha1=085f7063811d160b427d6cd92a3e92aaa580030f -md5=b426b8698ac2e012e2534af9634d743f -cksum=207677138 +sha1=7de9ff3a7ce61e751d91fe5e74079a706174e4fa +md5=61ebb23f407a72cee6142a3b144dea06 +cksum=2428332890 diff --git a/build/pkgs/qepcad/package-version.txt b/build/pkgs/qepcad/package-version.txt index 1406597b159..b477f38083e 100644 --- a/build/pkgs/qepcad/package-version.txt +++ b/build/pkgs/qepcad/package-version.txt @@ -1 +1 @@ -B.1.71 +B.1.72 From 791b41f41dd26e5c20d9537109069e57760f64c9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 11 Feb 2020 15:51:53 -0500 Subject: [PATCH 10/77] build/pkgs/qepcad/spkg-install: set LIBS correctly on linux and macos --- build/pkgs/qepcad/spkg-install | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build/pkgs/qepcad/spkg-install b/build/pkgs/qepcad/spkg-install index 5e40b7848ff..cc182e30729 100644 --- a/build/pkgs/qepcad/spkg-install +++ b/build/pkgs/qepcad/spkg-install @@ -17,7 +17,11 @@ export qe=$(pwd -P) # https://trac.sagemath.org/ticket/22653 # * Use ARFLAGS that also work on macOS, avoiding the U option, see # https://trac.sagemath.org/ticket/28388 -$MAKE -j1 opt SHELL=/bin/sh FLAGSo="-O3 -g -Wl,-rpath,$SAGE_LOCAL/lib" ARFLAGS="crv" +LIBS=-lreadline +if [ "$UNAME" = "Linux" ]; then + LIBS="$LIBS -lrt" +fi +$MAKE -j1 opt SHELL=/bin/sh FLAGSo="-O3 -g -Wl,-rpath,$SAGE_LOCAL/lib" ARFLAGS="crv" LIBS="$LIBS" if [ $? -ne 0 ]; then echo >&2 "Error building qepcad." exit 1 From 56d30c22bd8f73d3e8ecf56a680fba000c670a24 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 10 Feb 2020 22:03:10 -0500 Subject: [PATCH 11/77] build/pkgs/qepcad/checksums.ini: Add upstream_url --- build/pkgs/qepcad/checksums.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/build/pkgs/qepcad/checksums.ini b/build/pkgs/qepcad/checksums.ini index 400dd800ac0..5ab616658b0 100644 --- a/build/pkgs/qepcad/checksums.ini +++ b/build/pkgs/qepcad/checksums.ini @@ -2,3 +2,4 @@ tarball=qepcad-VERSION.tar.gz sha1=7de9ff3a7ce61e751d91fe5e74079a706174e4fa md5=61ebb23f407a72cee6142a3b144dea06 cksum=2428332890 +upstream_url=http://www.usna.edu/Users/cs/wcbrown/qepcad/INSTALL/qepcad-VERSION.tar.gz From 833ab0e56542413009d4fac4108b421cdace404c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 23 Feb 2020 16:40:08 -0800 Subject: [PATCH 12/77] Build gcc/gfortran without passing -std=gnu++11 to the system g++ --- build/bin/sage-build-env-config.in | 3 +++ build/pkgs/gcc/build-gcc | 4 +++- build/pkgs/gcc/spkg-configure.m4 | 4 ++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/build/bin/sage-build-env-config.in b/build/bin/sage-build-env-config.in index de4de3183e1..2b409d53fc1 100644 --- a/build/bin/sage-build-env-config.in +++ b/build/bin/sage-build-env-config.in @@ -19,6 +19,9 @@ # ########################################################################## +# The configured CXX without special flags added that enable C++11 support +export SAGE_CXX_WITHOUT_STD="@SAGE_CXX_WITHOUT_STD@" + # This is usually blank if the system GMP is used, or $SAGE_LOCAL otherwise export SAGE_GMP_PREFIX="@SAGE_GMP_PREFIX@" export SAGE_GMP_INCLUDE="@SAGE_GMP_INCLUDE@" diff --git a/build/pkgs/gcc/build-gcc b/build/pkgs/gcc/build-gcc index e6bdd7fbfd4..fa7a1cae4ee 100755 --- a/build/pkgs/gcc/build-gcc +++ b/build/pkgs/gcc/build-gcc @@ -58,6 +58,8 @@ if [ -n "$LD" -a "$LD" != "ld" ]; then CONFIGURE_LD="--with-ld=$LD" fi +# Use SAGE_CXX_WITHOUT_STD instead of CXX. +# This fixes #29162 (gfortran 9.2.0 compile error on debian-jessie with gcc 4.9.2) ../src/configure \ --prefix="$SAGE_LOCAL" \ --with-local-prefix="$SAGE_LOCAL" \ @@ -67,6 +69,6 @@ fi --disable-multilib \ --disable-nls \ --disable-libitm \ - $GCC_CONFIGURE "$CONFIGURE_AS" "$CONFIGURE_LD" + $GCC_CONFIGURE "$CONFIGURE_AS" "$CONFIGURE_LD" CXX="$SAGE_CXX_WITHOUT_STD" sdh_make BOOT_LDFLAGS="-Wl,-rpath,$SAGE_LOCAL/lib" diff --git a/build/pkgs/gcc/spkg-configure.m4 b/build/pkgs/gcc/spkg-configure.m4 index 19c55b08aad..49eca3b7599 100644 --- a/build/pkgs/gcc/spkg-configure.m4 +++ b/build/pkgs/gcc/spkg-configure.m4 @@ -94,6 +94,10 @@ SAGE_SPKG_CONFIGURE_BASE([gcc], [ IS_REALLY_GCC=yes fi + # Save the value of CXX without special flags to enable C++11 support + AS_VAR_SET([SAGE_CXX_WITHOUT_STD], [$CXX]) + AC_SUBST(SAGE_CXX_WITHOUT_STD) + # Modify CXX to include an option that enables C++11 support if necessary AX_CXX_COMPILE_STDCXX_11([], optional) if test $HAVE_CXX11 != 1; then SAGE_MUST_INSTALL_GCC([your C++ compiler does not support C++11]) From 34d1c62c3496c6c78238d8a350f7e58bcf127b7c Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Mon, 24 Feb 2020 12:40:53 -0500 Subject: [PATCH 13/77] Trac #29245: new spkg-configure.m4 for fplll. The fplll package is slow to build, easy to detect, and has already been packaged for a number of distributions. This commit adds an spkg-configure.m4 file for it, so that we can detect and use the system copy should one exist. --- build/pkgs/fplll/spkg-configure.m4 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 build/pkgs/fplll/spkg-configure.m4 diff --git a/build/pkgs/fplll/spkg-configure.m4 b/build/pkgs/fplll/spkg-configure.m4 new file mode 100644 index 00000000000..f79e1632a47 --- /dev/null +++ b/build/pkgs/fplll/spkg-configure.m4 @@ -0,0 +1,16 @@ +SAGE_SPKG_CONFIGURE([fplll], [ + SAGE_SPKG_DEPCHECK([mpfr], [ + dnl If we're using the system mpfr, use pkgconfig to determine + dnl if there's a usable system copy of fplll. Unless there's + dnl a system that ships fplll without fplll.pc file, falling + dnl back to a manual header/library search is pointless. + PKG_CHECK_MODULES([FPLLL], + [fplll >= 5.0], + [], + [sage_spkg_install_fplll=yes]) + ], + [ dnl If we're installing sage's mpfr, then we have to install + dnl its fplll, too. + sage_spkg_install_fplll=yes + ]) +]) From e478f113368a16d45c1c10f71d5dd49f47047724 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Mon, 24 Feb 2020 13:10:16 -0500 Subject: [PATCH 14/77] Trac #29245: add "distros" directory with an entry for Gentoo. Since Gentoo ships this package as sci-libs/fplll, we add a file named gentoo.txt containing "sci-libs/fplll" to the new distros directory. This information is useful to users who wish to install the system package, but who may not know what the package is called on the various distributions. --- build/pkgs/fplll/distros/gentoo.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 build/pkgs/fplll/distros/gentoo.txt diff --git a/build/pkgs/fplll/distros/gentoo.txt b/build/pkgs/fplll/distros/gentoo.txt new file mode 100644 index 00000000000..bff0d457997 --- /dev/null +++ b/build/pkgs/fplll/distros/gentoo.txt @@ -0,0 +1 @@ +sci-libs/fplll From e8c386758094cb74e8c3c498a220dbccb0892a48 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 25 Feb 2020 10:06:15 -0500 Subject: [PATCH 15/77] Trac #29245: add Debian package information for fplll. On Debian, one needs the libfplll-dev package to link programs (like SageMath) against fplll. This commit adds a new file debian.txt to the build/pkgs/fplll/distros directory that mentions that package along with the fplll-tools package that Debian provides. The latter is small and can't hurt, even though it may not strictly be necessary. --- build/pkgs/fplll/debian.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 build/pkgs/fplll/debian.txt diff --git a/build/pkgs/fplll/debian.txt b/build/pkgs/fplll/debian.txt new file mode 100644 index 00000000000..7def04a6329 --- /dev/null +++ b/build/pkgs/fplll/debian.txt @@ -0,0 +1,2 @@ +libfplll-dev +fplll-tools From 7fc917b6cdeac783ad8dd05aed19fd783772d53d Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Thu, 27 Feb 2020 07:57:44 -0500 Subject: [PATCH 16/77] Trac #29245: increase minimum version of fplll to 5.3. We need the fplll/pruner headers that are present only in newer versions, so the original check for >= 5.0 was incorrect. This commit bumps the minimum version to 5.3 in spkg-configure.m4. --- build/pkgs/fplll/spkg-configure.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/fplll/spkg-configure.m4 b/build/pkgs/fplll/spkg-configure.m4 index f79e1632a47..602169f8327 100644 --- a/build/pkgs/fplll/spkg-configure.m4 +++ b/build/pkgs/fplll/spkg-configure.m4 @@ -5,7 +5,7 @@ SAGE_SPKG_CONFIGURE([fplll], [ dnl a system that ships fplll without fplll.pc file, falling dnl back to a manual header/library search is pointless. PKG_CHECK_MODULES([FPLLL], - [fplll >= 5.0], + [fplll >= 5.3], [], [sage_spkg_install_fplll=yes]) ], From bd97ff9f189490d9e04ce8d22d6f564b9884ea16 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Fri, 21 Feb 2020 15:47:58 +0100 Subject: [PATCH 17/77] Trac 29247: remove no_generic_basering_coercion --- .../coercion_and_categories.rst | 2 +- src/sage/algebras/free_algebra.py | 2 +- src/sage/algebras/jordan_algebra.py | 5 -- src/sage/categories/homset.py | 3 +- src/sage/categories/modules_with_basis.py | 1 - src/sage/categories/unital_algebras.py | 26 +++++---- src/sage/libs/singular/ring.pyx | 2 +- src/sage/matrix/matrix_space.py | 40 ++++++++----- .../multi_polynomial_libsingular.pyx | 29 +++++----- .../rings/polynomial/multi_polynomial_ring.py | 17 ++---- .../polynomial/multi_polynomial_ring_base.pxd | 1 - .../polynomial/multi_polynomial_ring_base.pyx | 48 +++++++++++++-- src/sage/rings/polynomial/polynomial_ring.py | 58 +++++++++---------- .../rings/polynomial/skew_polynomial_ring.py | 1 - src/sage/structure/coerce.pyx | 1 + 15 files changed, 139 insertions(+), 97 deletions(-) diff --git a/src/doc/en/thematic_tutorials/coercion_and_categories.rst b/src/doc/en/thematic_tutorials/coercion_and_categories.rst index bd76813e9c8..9e5fdb47f71 100644 --- a/src/doc/en/thematic_tutorials/coercion_and_categories.rst +++ b/src/doc/en/thematic_tutorials/coercion_and_categories.rst @@ -448,7 +448,7 @@ And indeed, ``MS2`` has *more* methods than ``MS1``:: sage: import inspect sage: len([s for s in dir(MS1) if inspect.ismethod(getattr(MS1,s,None))]) - 81 + 82 sage: len([s for s in dir(MS2) if inspect.ismethod(getattr(MS2,s,None))]) 121 diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index c24add03fd7..2ba6b721c6f 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -116,7 +116,7 @@ sage: FreeAlgebra(FreeAlgebra(ZZ,2,'ab'), 2, 'x', implementation='letterplace') Traceback (most recent call last): ... - TypeError: The base ring Free Algebra on 2 generators (a, b) over Integer Ring is not a commutative ring + NotImplementedError: polynomials over Free Algebra on 2 generators (a, b) over Integer Ring are not supported in Singular """ #***************************************************************************** diff --git a/src/sage/algebras/jordan_algebra.py b/src/sage/algebras/jordan_algebra.py index dd271a35ec5..aaf712959f6 100644 --- a/src/sage/algebras/jordan_algebra.py +++ b/src/sage/algebras/jordan_algebra.py @@ -234,10 +234,6 @@ def __init__(self, A, names=None): cat = C.Commutative() if A in C.Unital(): cat = cat.Unital() - self._no_generic_basering_coercion = True - # Remove the preceding line once trac #16492 is fixed - # Removing this line will also break some of the input formats, - # see trac #16054 if A in C.WithBasis(): cat = cat.WithBasis() if A in C.FiniteDimensional(): @@ -595,7 +591,6 @@ def __init__(self, R, form, names=None): self._form = form self._M = FreeModule(R, form.ncols()) cat = MagmaticAlgebras(R).Commutative().Unital().FiniteDimensional().WithBasis() - self._no_generic_basering_coercion = True # Remove once 16492 is fixed Parent.__init__(self, base=R, names=names, category=cat) def _repr_(self): diff --git a/src/sage/categories/homset.py b/src/sage/categories/homset.py index fe2b8e466a8..d3d2896a638 100644 --- a/src/sage/categories/homset.py +++ b/src/sage/categories/homset.py @@ -364,7 +364,8 @@ def Hom(X, Y, category=None, check=True): ....: raise TypeError sage: from sage.structure.element import Element sage: class Foo(Parent): - ....: _no_generic_basering_coercion = True + ....: def _coerce_map_from_base_ring(self): + ....: return self._generic_coerce_map(self.base_ring()) ....: class Element(Element): ....: pass sage: X = Foo(base=QQ, category=AlgebrasWithHom(QQ)) diff --git a/src/sage/categories/modules_with_basis.py b/src/sage/categories/modules_with_basis.py index 7b43e95ad7d..1c0fd5a61db 100644 --- a/src/sage/categories/modules_with_basis.py +++ b/src/sage/categories/modules_with_basis.py @@ -1223,7 +1223,6 @@ def random_element(self, n=2): we can find a random element in a trivial module:: sage: class Foo(CombinatorialFreeModule): - ....: _no_generic_basering_coercion = True ....: def _element_constructor_(self,x): ....: if x in self: ....: return x diff --git a/src/sage/categories/unital_algebras.py b/src/sage/categories/unital_algebras.py index 58fea9fca17..48bcc795849 100644 --- a/src/sage/categories/unital_algebras.py +++ b/src/sage/categories/unital_algebras.py @@ -79,9 +79,11 @@ def __init_extra__(self): An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field sage: coercion_model = sage.structure.element.get_coercion_model() sage: coercion_model.discover_coercion(QQ, A) - (Generic morphism: - From: Rational Field - To: An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field, None) + ((map internal to coercion system -- copy before use) + Generic morphism: + From: Rational Field + To: An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field, + None) sage: A(1) # indirect doctest B[word: ] @@ -102,16 +104,17 @@ def __init_extra__(self): sage: F(3) 3*B[0] + sage: class Bar(Parent): + ....: _no_generic_basering_coercion = True + sage: Bar(category=Algebras(QQ)) + doctest:warning...: + DeprecationWarning: the attribute _no_generic_basering_coercion is deprecated, implement _coerce_map_from_base_ring() instead + See http://trac.sagemath.org/19225 for details. + <__main__.Bar_with_category object at 0x...> """ - # If self has an attribute _no_generic_basering_coercion - # set to True, then this declaration is skipped. - # This trick, introduced in #11900, is used in - # sage.matrix.matrix_space.py and - # sage.rings.polynomial.polynomial_ring. - # It will hopefully be refactored into something more - # conceptual later on. if getattr(self, '_no_generic_basering_coercion', False): - return + from sage.misc.superseded import deprecation + deprecation(19225, "the attribute _no_generic_basering_coercion is deprecated, implement _coerce_map_from_base_ring() instead") base_ring = self.base_ring() if base_ring is self: @@ -127,6 +130,7 @@ def __init_extra__(self): mor = self._coerce_map_from_base_ring() if mor is not None: + mor._make_weak_references() try: self.register_coercion(mor) except AssertionError: diff --git a/src/sage/libs/singular/ring.pyx b/src/sage/libs/singular/ring.pyx index 5d4fa74e804..f331ed549c1 100644 --- a/src/sage/libs/singular/ring.pyx +++ b/src/sage/libs/singular/ring.pyx @@ -559,7 +559,7 @@ cdef ring *singular_ring_reference(ring *existing_ring) except NULL: sage: ring_ptr # random output The ring pointer 0x7f78a646b8d0 sage: ring_refcount_dict[ring_ptr] - 4 + 3 sage: strat = GroebnerStrategy(Ideal([P.gen(0) + P.gen(1)])) sage: ring_refcount_dict[ring_ptr] diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 9202c6a6c9b..5bfd6a86439 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -425,7 +425,6 @@ class MatrixSpace(UniqueRepresentation, Parent): sage: M1(m * m) == M1(m) * M1(m) True """ - _no_generic_basering_coercion = True @staticmethod def __classcall__(cls, base_ring, nrows, ncols=None, sparse=False, implementation=None): @@ -951,19 +950,17 @@ def _get_action_(self, S, op, self_on_left): except TypeError: return None - def _coerce_map_from_(self, S): + def _coerce_map_from_base_ring(self): """ - Canonical coercion from ``S`` to this matrix space. + Return a coercion map from the base ring of ``self``. + + .. NOTE:: + + This is only called for algebras of square matrices. EXAMPLES:: sage: MS1 = MatrixSpace(QQ, 3) - sage: MS2 = MatrixSpace(ZZ, 3) - sage: MS1.coerce_map_from(MS2) - Coercion map: - From: Full MatrixSpace of 3 by 3 dense matrices over Integer Ring - To: Full MatrixSpace of 3 by 3 dense matrices over Rational Field - sage: MS2.coerce_map_from(MS1) sage: MS1.coerce_map_from(QQ) Coercion map: From: Rational Field @@ -979,12 +976,32 @@ def _coerce_map_from_(self, S): Coercion map: From: Rational Field To: Full MatrixSpace of 3 by 3 dense matrices over Rational Field + + sage: MS2 = MatrixSpace(ZZ, 3) sage: MS2.coerce_map_from(QQ) sage: MS2.coerce_map_from(ZZ) Coercion map: From: Integer Ring To: Full MatrixSpace of 3 by 3 dense matrices over Integer Ring + sage: MatrixSpace(QQ, 1, 3).coerce_map_from(QQ) + """ + return self._generic_coerce_map(self.base_ring()) + + def _coerce_map_from_(self, S): + """ + Canonical coercion from ``S`` to this matrix space. + + EXAMPLES:: + + sage: MS1 = MatrixSpace(QQ, 3) + sage: MS2 = MatrixSpace(ZZ, 3) + sage: MS1.coerce_map_from(MS2) + Coercion map: + From: Full MatrixSpace of 3 by 3 dense matrices over Integer Ring + To: Full MatrixSpace of 3 by 3 dense matrices over Rational Field + sage: MS2.coerce_map_from(MS1) + There are also coercions possible from matrix group and arithmetic subgroups:: @@ -1065,11 +1082,6 @@ def _coerce_map_from_(self, S): """ B = self.base() - if S is B: - # Coercion from base ring to a scalar matrix, - # but only if matrices are square. - return self.nrows() == self.ncols() - if isinstance(S, MatrixSpace): # Disallow coercion if dimensions do not match if self.nrows() != S.nrows() or self.ncols() != S.ncols(): diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index fd03639df00..be1e36f5190 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -378,26 +378,16 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): sage: MPolynomialRing_libsingular(QQ, -1, [], "lex") Traceback (most recent call last): ... - ValueError: Multivariate Polynomial Rings must have more than 0 variables. + NotImplementedError: polynomials in -1 variables are not supported in Singular """ - MPolynomialRing_base.__init__(self, base_ring, n, names, order) - self._has_singular = True - assert(n == len(self._names)) self.__ngens = n - self._ring = singular_ring_new(base_ring, n, self._names, order) + self._ring = singular_ring_new(base_ring, n, names, order) self._zero_element = new_MP(self, NULL) cdef MPolynomial_libsingular one = new_MP(self, p_ISet(1, self._ring)) self._one_element = one self._one_element_poly = one._poly - # This polynomial ring should belong to Algebras(base_ring). - # Algebras(...).parent_class, which was called from MPolynomialRing_base.__init__, - # tries to provide a conversion from the base ring, if it does not exist. - # This is for algebras that only do the generic stuff in their initialisation. - # But here, we want to use PolynomialBaseringInjection. Hence, we need to - # wipe the memory and construct the conversion from scratch. - from sage.rings.polynomial.polynomial_element import PolynomialBaseringInjection - base_inject = PolynomialBaseringInjection(base_ring, self) - self.register_coercion(base_inject) + MPolynomialRing_base.__init__(self, base_ring, n, names, order) + self._has_singular = True #permanently store a reference to this ring until deallocation works reliably permstore.append(self) @@ -492,6 +482,15 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): """ base_ring = self.base_ring() + if other is base_ring: + # Because this parent class is a Cython class, the method + # UnitalAlgebras.ParentMethods.__init_extra__(), which normally + # registers the coercion map from the base ring, is called only + # when inheriting from this class in Python (cf. Trac #26958). + return self._coerce_map_from_base_ring() + f = self._coerce_map_via([base_ring], other) + if f is not None: + return f if isinstance(other, MPolynomialRing_libsingular): if self is other: @@ -512,8 +511,6 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): elif is_PolynomialRing(other): if base_ring.has_coerce_map_from(other._mpoly_base_ring(self.variable_names())): return True - elif base_ring.has_coerce_map_from(other): - return True Element = MPolynomial_libsingular diff --git a/src/sage/rings/polynomial/multi_polynomial_ring.py b/src/sage/rings/polynomial/multi_polynomial_ring.py index a84496bdfc2..27203ce42e6 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring.py +++ b/src/sage/rings/polynomial/multi_polynomial_ring.py @@ -110,7 +110,11 @@ class MPolynomialRing_polydict( MPolynomialRing_macaulay2_repr, PolynomialRing_s def __init__(self, base_ring, n, names, order): from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular order = TermOrder(order,n) - MPolynomialRing_base.__init__(self, base_ring, n, names, order) + # MPolynomialRing_base.__init__() normally initialises the base ring, + # but it also needs the generators to construct a coercion map from the + # base ring, and the base ring must be set to initialise the generators. + # We set the base ring manually to break this circular dependency. + self._base = base_ring # Construct the generators v = [0] * n one = base_ring(1); @@ -122,17 +126,8 @@ def __init__(self, base_ring, n, names, order): v[i] = 0 self._gens = tuple(self._gens) self._zero_tuple = tuple(v) + MPolynomialRing_base.__init__(self, base_ring, n, names, order) self._has_singular = can_convert_to_singular(self) - # This polynomial ring should belong to Algebras(base_ring). - # Algebras(...).parent_class, which was called from MPolynomialRing_base.__init__, - # tries to provide a conversion from the base ring, if it does not exist. - # This is for algebras that only do the generic stuff in their initialisation. - # But here, we want to use PolynomialBaseringInjection. Hence, we need to - # wipe the memory and construct the conversion from scratch. - if n: - from sage.rings.polynomial.polynomial_element import PolynomialBaseringInjection - base_inject = PolynomialBaseringInjection(base_ring, self) - self.register_coercion(base_inject) def _monomial_order_function(self): return self.__monomial_order_function diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd b/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd index 754098dd67b..7e713c01dac 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pxd @@ -2,7 +2,6 @@ cimport sage.rings.ring from sage.structure.parent cimport Parent cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): - cdef readonly _no_generic_basering_coercion cdef object __ngens cdef object __term_order cdef public object _has_singular diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 22beb25c94a..247be85552d 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -95,10 +95,6 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): category = categories.rings.Rings().Finite() else: category = polynomial_default_category(base_ring.category(), n) - - # Avoid calling __init_extra__ of Algebras(...).parent_class - self._no_generic_basering_coercion = True - sage.rings.ring.Ring.__init__(self, base_ring, names, category=category) def is_integral_domain(self, proof = True): @@ -345,6 +341,50 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): """ return self.remove_var(x)[str(x)] + def _coerce_map_from_base_ring(self): + """ + Return a coercion map from the base ring of ``self``. + + EXAMPLES:: + + sage: R. = QQ[] + sage: R.coerce_map_from(QQ) + Polynomial base injection morphism: + From: Rational Field + To: Multivariate Polynomial Ring in x, y over Rational Field + sage: R.coerce_map_from(ZZ) + Composite map: + From: Integer Ring + To: Multivariate Polynomial Ring in x, y over Rational Field + Defn: Natural morphism: + From: Integer Ring + To: Rational Field + then + Polynomial base injection morphism: + From: Rational Field + To: Multivariate Polynomial Ring in x, y over Rational Field + + sage: A = Zmod(6^12) + sage: S. = A[]; S + Multivariate Polynomial Ring in x, y over Ring of integers modulo 2176782336 + sage: S.coerce_map_from(A) + Polynomial base injection morphism: + From: Ring of integers modulo 2176782336 + To: Multivariate Polynomial Ring in x, y over Ring of integers modulo 2176782336 + + sage: T = PolynomialRing(QQ, []); T + Multivariate Polynomial Ring in no variables over Rational Field + sage: T.coerce_map_from(QQ) + Call morphism: + From: Rational Field + To: Multivariate Polynomial Ring in no variables over Rational Field + """ + if self.ngens(): + from sage.rings.polynomial.polynomial_element import PolynomialBaseringInjection + return PolynomialBaseringInjection(self.base_ring(), self) + else: + return self._generic_coerce_map(self.base_ring()) + cdef _coerce_c_impl(self, x): """ Return the canonical coercion of x to this multivariate diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index 5aff5f39193..f9230c42ba2 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -231,7 +231,7 @@ class PolynomialRing_general(sage.algebras.algebra.Algebra): """ Univariate polynomial ring over a ring. """ - _no_generic_basering_coercion = True + def __init__(self, base_ring, name=None, sparse=False, element_class=None, category=None): """ EXAMPLES:: @@ -301,13 +301,7 @@ def __init__(self, base_ring, name=None, sparse=False, element_class=None, categ self.Element = self._polynomial_class self.__cyclopoly_cache = {} self._has_singular = False - # Algebra.__init__ also calls __init_extra__ of Algebras(...).parent_class, which - # tries to provide a conversion from the base ring, if it does not exist. - # This is for algebras that only do the generic stuff in their initialisation. - # But the attribute _no_generic_basering_coercion prevents that from happening, - # since we want to use PolynomialBaseringInjection. sage.algebras.algebra.Algebra.__init__(self, base_ring, names=name, normalize=True, category=category) - self.__generator = self.element_class(self, [0,1], is_gen=True) self._populate_coercion_lists_( #coerce_list = [base_inject], #convert_list = [list, base_inject], @@ -659,6 +653,32 @@ def completion(self, p, prec=20, extras=None): else: raise TypeError("Cannot complete %s with respect to %s" % (self, p)) + def _coerce_map_from_base_ring(self): + """ + Return a coercion map from the base ring of ``self``. + + EXAMPLES:: + + sage: R. = QQ[] + sage: R.coerce_map_from(QQ) + Polynomial base injection morphism: + From: Rational Field + To: Univariate Polynomial Ring in x over Rational Field + sage: R.coerce_map_from(ZZ) + Composite map: + From: Integer Ring + To: Univariate Polynomial Ring in x over Rational Field + Defn: Natural morphism: + From: Integer Ring + To: Rational Field + then + Polynomial base injection morphism: + From: Rational Field + To: Univariate Polynomial Ring in x over Rational Field + sage: R.coerce_map_from(GF(7)) + """ + return PolynomialBaseringInjection(self.base_ring(), self) + def _coerce_map_from_(self, P): """ The rings that canonically coerce to this polynomial ring are: @@ -682,29 +702,11 @@ def _coerce_map_from_(self, P): EXAMPLES:: sage: R = QQ['x'] - sage: R.has_coerce_map_from(QQ) - True - sage: R.has_coerce_map_from(ZZ) - True - sage: R.has_coerce_map_from(GF(7)) - False sage: R.has_coerce_map_from(ZZ['x']) True sage: R.has_coerce_map_from(ZZ['y']) False - sage: R.coerce_map_from(ZZ) - Composite map: - From: Integer Ring - To: Univariate Polynomial Ring in x over Rational Field - Defn: Natural morphism: - From: Integer Ring - To: Rational Field - then - Polynomial base injection morphism: - From: Rational Field - To: Univariate Polynomial Ring in x over Rational Field - Here we test against the change in the coercions introduced in :trac:`9944`:: @@ -755,10 +757,7 @@ def _coerce_map_from_(self, P): sage: T.has_coerce_map_from(S) False """ - # In the first place, handle the base ring base_ring = self.base_ring() - if P is base_ring: - return PolynomialBaseringInjection(base_ring, self) # handle constants that canonically coerce into self.base_ring() # first, if possible try: @@ -1171,6 +1170,7 @@ def cyclotomic_polynomial(self, n): else: return self(cyclotomic.cyclotomic_coeffs(n), check=True) + @cached_method def gen(self, n=0): """ Return the indeterminate generator of this polynomial ring. @@ -1193,7 +1193,7 @@ def gen(self, n=0): """ if n != 0: raise IndexError("generator n not defined") - return self.__generator + return self.element_class(self, [0,1], is_gen=True) def gens_dict(self): """ diff --git a/src/sage/rings/polynomial/skew_polynomial_ring.py b/src/sage/rings/polynomial/skew_polynomial_ring.py index 8ebbc2ef9e9..24937789e5f 100644 --- a/src/sage/rings/polynomial/skew_polynomial_ring.py +++ b/src/sage/rings/polynomial/skew_polynomial_ring.py @@ -355,7 +355,6 @@ def __init__(self, base_ring, twist_map, name, sparse, element_class): self._polynomial_class = element_class self._map = twist_map self._maps = {0: IdentityMorphism(base_ring), 1: self._map} - self._no_generic_basering_coercion = True Algebra.__init__(self, base_ring, names=name, normalize=True, category=Rings()) base_inject = SkewPolynomialBaseringInjection(base_ring, self) diff --git a/src/sage/structure/coerce.pyx b/src/sage/structure/coerce.pyx index f8915c8545b..597b8bed278 100644 --- a/src/sage/structure/coerce.pyx +++ b/src/sage/structure/coerce.pyx @@ -1647,6 +1647,7 @@ cdef class CoercionModel: Call morphism: From: Multivariate Polynomial Ring in x, y over Integer Ring To: Multivariate Polynomial Ring in x, y over Real Double Field, + (map internal to coercion system -- copy before use) Polynomial base injection morphism: From: Real Double Field To: Multivariate Polynomial Ring in x, y over Real Double Field) From f024ac3c5d886d216d7726eb819061e2e861aae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 28 Feb 2020 14:00:35 +0100 Subject: [PATCH 18/77] minor details in cubic braid groups --- src/sage/groups/cubic_braid.py | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/sage/groups/cubic_braid.py b/src/sage/groups/cubic_braid.py index f2d25b030c3..6b0f2f1142b 100644 --- a/src/sage/groups/cubic_braid.py +++ b/src/sage/groups/cubic_braid.py @@ -75,7 +75,7 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ # **************************************************************************** @@ -476,14 +476,12 @@ def find_root(domain): if not(root_list): domain = min_pol.splitting_field(min_pol_root_bur.variable_name()) min_pol = min_pol_root_bur.change_ring(domain) - else: - domain = domain root_list = min_pol.roots() for root in root_list: - if root[0] == 0: + if root[0] == 0: continue - root_bur = root[0] - if root[1] == 1: + root_bur = root[0] + if root[1] == 1: break return root_bur @@ -519,20 +517,11 @@ def find_root(domain): domain = root_bur.parent() else: # domain is not None - if characteristic is None: - characteristic = domain.characteristic() - elif characteristic != domain.characteristic(): - raise ValueError('characteristic of domain does not match given characteristic') root_bur = find_root(domain) - - else: # root_bur is not!= None + else: # root_bur is not None if domain is None: domain = root_bur.parent() - if characteristic is None: - characteristic = domain.characteristic() - elif characteristic != domain.characteristic(): - raise ValueError('characteristic of domain does not match given characteristic') if 1 not in domain: raise ValueError('root_bur must belong to a domain containing 1') @@ -1474,7 +1463,7 @@ def as_matrix_group(self, root_bur=None, domain=None, characteristic=None, var=' # ------------------------------------------------------------------------------- unitary = False - if type(reduced) == str: + if isinstance(reduced, str): if reduced == 'unitary': unitary = True @@ -1483,10 +1472,10 @@ def as_matrix_group(self, root_bur=None, domain=None, characteristic=None, var=' bur_mat = braid_gen.burau_matrix(root_bur=root_bur, domain=domain, characteristic=characteristic, var=var, reduced=reduced) if unitary: - bur_mat, bur_mat_ad, herm_form = bur_mat + bur_mat, bur_mat_ad, herm_form = bur_mat if domain is None: - domain = bur_mat.base_ring() + domain = bur_mat.base_ring() gen_list.append(bur_mat) @@ -1668,11 +1657,11 @@ def as_classical_group(self, embedded=False): # of one strand more (self.strands() +1) generated by the first self.strands() -1 # generators # ---------------------------------------------------------------------------------------- - return self._classical_embedding + return self._classical_embedding elif self._classical_group is not None: - return self._classical_group + return self._classical_group else: - raise ValueError("no classical embedding defined") + raise ValueError("no classical embedding defined") # ---------------------------------------------------------------------------------- From b8e5d80f96d2ab35f73d4b6d585db9af15919b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 28 Feb 2020 17:46:02 +0100 Subject: [PATCH 19/77] some details in cubic braids --- src/sage/groups/cubic_braid.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/sage/groups/cubic_braid.py b/src/sage/groups/cubic_braid.py index 6b0f2f1142b..0e07ef86be0 100644 --- a/src/sage/groups/cubic_braid.py +++ b/src/sage/groups/cubic_braid.py @@ -912,7 +912,10 @@ def _test_matrix_group(self, **options): sage: CBG2._test_matrix_group() """ tester = self._tester(**options) - F3 = GF(3); r63 = F3(2); F4 = GF(4); r64 = F4.gen() + F3 = GF(3) + r63 = F3(2) + F4 = GF(4) + r64 = F4.gen() MatDEF = self.as_matrix_group() self._internal_test_attached_group(MatDEF, tester) @@ -1261,7 +1264,8 @@ def transvec2mat(v, bas=bas, bform=bform, fact=a): # now 1 + 2*cos(\pi/6)*i\theta = 1 + sqrt(3)*(-sqrt(3)/2 + I/2) = 1- 3/2 + sqrt(3)I/2 = z12^4 = - ~z12^2 # finally: Coxeter's Realization is the unitary Burau representation of Squier for s = ~z12 # ----------------------------------------------------------------------------------------------- - UCF = UniversalCyclotomicField(); z12 = UCF.gen(12) + UCF = UniversalCyclotomicField() + z12 = UCF.gen(12) classical_group = self.as_matrix_group(root_bur=~z12, domain=UCF, reduced='unitary') self._classical_group = classical_group self._classical_base_group = classical_group From 96aefd34d633eaca91e4f88881645f6b8d2a77a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 29 Feb 2020 08:46:25 +0100 Subject: [PATCH 20/77] cleaning the file spike_function.py (lgtm, pep) --- src/sage/functions/spike_function.py | 78 +++++++++++++++------------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/src/sage/functions/spike_function.py b/src/sage/functions/spike_function.py index 56635ca98fa..00bd6ea83de 100644 --- a/src/sage/functions/spike_function.py +++ b/src/sage/functions/spike_function.py @@ -7,15 +7,15 @@ - Karl-Dieter Crisman (2009-09): adding documentation and doctests """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007 William Stein # Copyright (C) 2009 Karl-Dieter Crisman # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from __future__ import print_function import math @@ -24,19 +24,20 @@ from sage.modules.free_module_element import vector from sage.rings.all import RDF + class SpikeFunction: """ Base class for spike functions. INPUT: - - ``v`` - list of pairs (x, height) + - ``v`` - list of pairs (x, height) - - ``eps`` - parameter that determines approximation to a true spike + - ``eps`` - parameter that determines approximation to a true spike OUTPUT: - a function with spikes at each point ``x`` in ``v`` with the given height. + a function with spikes at each point ``x`` in ``v`` with the given height. EXAMPLES:: @@ -62,7 +63,7 @@ class SpikeFunction: """ def __init__(self, v, eps=0.0000001): """ - Initializes base class SpikeFunction. + Initialize base class SpikeFunction. EXAMPLES:: @@ -73,8 +74,8 @@ def __init__(self, v, eps=0.0000001): sage: S.eps 0.00100000000000000 """ - if len(v) == 0: - v = [(0,0)] + if not v: + v = [(0, 0)] v = sorted([(float(x[0]), float(x[1])) for x in v]) notify = False @@ -101,13 +102,14 @@ def __repr__(self): sage: spike_function([(-3,4),(-1,1),(2,3)],0.001) A spike function with spikes at [-3.0, -1.0, 2.0] """ - return "A spike function with spikes at %s"%self.support + return "A spike function with spikes at %s" % self.support def _eval(self, x): """ - Evaluates spike function. Note that when one calls - the function within the tolerance, the return value - is the full height at that point. + Evaluate spike function. + + Note that when one calls the function within the tolerance, + the return value is the full height at that point. EXAMPLES:: @@ -158,10 +160,10 @@ def plot_fft_abs(self, samples=2**12, xmin=None, xmax=None, **kwds): A spike function with spikes at [-3.0, -1.0, 2.0] sage: P = S.plot_fft_abs(8) sage: p = P[0]; p.ydata # abs tol 1e-8 - [5.0, 5.0, 3.367958691924177, 3.367958691924177, 4.123105625617661, 4.123105625617661, 4.759921664218055, 4.759921664218055] + [5.0, 5.0, 3.367958691924177, 3.367958691924177, 4.123105625617661, + 4.123105625617661, 4.759921664218055, 4.759921664218055] """ - w = self.vector(samples = samples, xmin=xmin, xmax=xmax) - xmin, xmax = self._ranges(xmin, xmax) + w = self.vector(samples=samples, xmin=xmin, xmax=xmax) z = w.fft() k = vector(RDF, [abs(z[i]) for i in range(len(z)//2)]) return k.plot(xmin=0, xmax=1, **kwds) @@ -177,36 +179,38 @@ def plot_fft_arg(self, samples=2**12, xmin=None, xmax=None, **kwds): A spike function with spikes at [-3.0, -1.0, 2.0] sage: P = S.plot_fft_arg(8) sage: p = P[0]; p.ydata # abs tol 1e-8 - [0.0, 0.0, -0.211524990023434, -0.211524990023434, 0.244978663126864, 0.244978663126864, -0.149106180027477, -0.149106180027477] + [0.0, 0.0, -0.211524990023434, -0.211524990023434, + 0.244978663126864, 0.244978663126864, -0.149106180027477, + -0.149106180027477] """ - w = self.vector(samples = samples, xmin=xmin, xmax=xmax) - xmin, xmax = self._ranges(xmin, xmax) + w = self.vector(samples=samples, xmin=xmin, xmax=xmax) z = w.fft() k = vector(RDF, [(z[i]).arg() for i in range(len(z)//2)]) return k.plot(xmin=0, xmax=1, **kwds) def vector(self, samples=2**16, xmin=None, xmax=None): """ - Creates a sampling vector of the spike function in question. + Create a sampling vector of the spike function in question. EXAMPLES:: sage: S = spike_function([(-3,4),(-1,1),(2,3)],0.001); S A spike function with spikes at [-3.0, -1.0, 2.0] sage: S.vector(16) - (4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) + (4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0) """ - v = vector(RDF, samples) # creates vector of zeros of length 2^16 + v = vector(RDF, samples) # creates vector of zeros of length 2^16 xmin, xmax = self._ranges(xmin, xmax) - delta = (xmax - xmin)/samples - w = int(math.ceil(self.eps/delta)) + delta = (xmax - xmin) / samples + w = int(math.ceil(self.eps / delta)) for i in range(len(self.support)): x = self.support[i] if x > xmax: break h = self.height[i] - j = int((x - xmin)/delta) - for k in range(j, min(samples, j+w)): + j = int((x - xmin) / delta) + for k in range(j, min(samples, j + w)): v[k] = h return v @@ -222,11 +226,11 @@ def _ranges(self, xmin, xmax): """ width = (self.support[-1] + self.support[0])/float(2) if xmin is None: - xmin = self.support[0] - width/float(5) + xmin = self.support[0] - width/float(5) if xmax is None: - xmax = self.support[-1] + width/float(5) + xmax = self.support[-1] + width/float(5) if xmax <= xmin: - xmax = xmin + 1 + xmax = xmin + 1 return xmin, xmax def plot(self, xmin=None, xmax=None, **kwds): @@ -246,16 +250,16 @@ def plot(self, xmin=None, xmax=None, **kwds): eps = self.eps while x < xmax: y, i = self._eval(x) - v.append( (x, y) ) + v.append((x, y)) if i != -1: x0 = self.support[i] + eps - v.extend([(x0,y), (x0,0)]) + v.extend([(x0, y), (x0, 0)]) if i+1 < len(self.support): - x = self.support[i+1] - eps - v.append( (x, 0) ) + x = self.support[i + 1] - eps + v.append((x, 0)) else: x = xmax - v.append( (xmax, 0) ) + v.append((xmax, 0)) else: new_x = None for j in range(len(self.support)): @@ -264,12 +268,12 @@ def plot(self, xmin=None, xmax=None, **kwds): break if new_x is None: new_x = xmax - v.append( (new_x, 0) ) + v.append((new_x, 0)) x = new_x L = line(v, **kwds) - L.xmin(xmin-1); L.xmax(xmax) + L.xmin(xmin-1) + L.xmax(xmax) return L - spike_function = SpikeFunction From d32acb9dfaa732e149107e9bc298ff7da7a90ebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 29 Feb 2020 09:15:20 +0100 Subject: [PATCH 21/77] remove some imports of six in cython files --- .../finite_dimensional_algebra_element.pyx | 9 +++------ src/sage/graphs/graph_coloring.pyx | 3 +-- src/sage/misc/weak_dict.pyx | 3 +-- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx index bf0a1ffbff8..60148f063c4 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx @@ -1,8 +1,7 @@ """ Elements of Finite Algebras """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2011 Johan Bosman # Copyright (C) 2011, 2013 Peter Bruin # Copyright (C) 2011 Michiel Kosters @@ -11,10 +10,8 @@ Elements of Finite Algebras # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** -from six.moves import range - +# https://www.gnu.org/licenses/ +# **************************************************************************** import re from sage.misc.lazy_attribute import lazy_attribute diff --git a/src/sage/graphs/graph_coloring.pyx b/src/sage/graphs/graph_coloring.pyx index 47b93c1f386..f2200f5712c 100644 --- a/src/sage/graphs/graph_coloring.pyx +++ b/src/sage/graphs/graph_coloring.pyx @@ -53,8 +53,6 @@ Methods # Distributed under the terms of the GNU General Public License (GPL) # https://www.gnu.org/licenses/ # **************************************************************************** -from six.moves import range - from copy import copy from sage.combinat.matrices.dlxcpp import DLXCPP from sage.plot.colors import rainbow @@ -65,6 +63,7 @@ from libcpp.pair cimport pair from sage.numerical.mip import MixedIntegerLinearProgram from sage.numerical.mip import MIPSolverException + def all_graph_colorings(G, n, count_only=False, hex_colors=False, vertex_color_dict=False): r""" Compute all `n`-colorings of a graph. diff --git a/src/sage/misc/weak_dict.pyx b/src/sage/misc/weak_dict.pyx index 0dc1d203cfe..3f1a8333872 100644 --- a/src/sage/misc/weak_dict.pyx +++ b/src/sage/misc/weak_dict.pyx @@ -119,7 +119,6 @@ See :trac:`13394` for a discussion of some of the design considerations. # **************************************************************************** import weakref -import six from weakref import KeyedRef from copy import deepcopy @@ -348,7 +347,7 @@ cdef class WeakValueDictionary(dict): True """ try: - data = six.iteritems(data) + data = iter(data.items()) except AttributeError: pass for (k, v) in data: From eb30f5028b030c23fd550ee59134025705698098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 29 Feb 2020 13:41:28 +0100 Subject: [PATCH 22/77] remove some old deprecated stuff --- src/sage/graphs/graph_plot.py | 12 +-- .../numerical/interactive_simplex_method.py | 91 +------------------ .../quadratic_form__equivalence_testing.py | 26 ++---- 3 files changed, 15 insertions(+), 114 deletions(-) diff --git a/src/sage/graphs/graph_plot.py b/src/sage/graphs/graph_plot.py index 32167ac8920..8bb7708370f 100644 --- a/src/sage/graphs/graph_plot.py +++ b/src/sage/graphs/graph_plot.py @@ -165,7 +165,7 @@ __doc__ = __doc__.format(PLOT_OPTIONS_TABLE=_PLOT_OPTIONS_TABLE) -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2009 Emily Kirkman # 2009 Robert L. Miller # @@ -178,8 +178,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.structure.sage_object import SageObject from sage.plot.all import Graphics, scatter_plot, bezier_path, line, arrow, text, circle from math import sqrt, cos, sin, atan, pi @@ -385,8 +385,6 @@ def set_vertices(self, **vertex_options): sphinx_plot(GP) """ - from sage.misc.superseded import deprecation - # Handle base vertex options voptions = {} @@ -407,10 +405,6 @@ def set_vertices(self, **vertex_options): else: vertex_color = self._options['vertex_color'] - if ('vertex_colors' in self._options and - not isinstance(self._options['vertex_colors'], dict)): - deprecation(21048, "Use of vertex_colors= is deprecated, use vertex_color= and/or vertex_colors=.") - if 'vertex_colors' not in self._options or self._options['vertex_colors'] is None: if self._options['partition'] is not None: from sage.plot.colors import rainbow diff --git a/src/sage/numerical/interactive_simplex_method.py b/src/sage/numerical/interactive_simplex_method.py index 1481066669e..8324bf72430 100644 --- a/src/sage/numerical/interactive_simplex_method.py +++ b/src/sage/numerical/interactive_simplex_method.py @@ -167,23 +167,19 @@ Classes and functions --------------------- """ - - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013 Andrey Novoseltsev # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from __future__ import print_function -from six.moves import range, zip import operator import re - from copy import copy from sage.misc.abstract_method import abstract_method @@ -200,7 +196,6 @@ random) from sage.misc.html import HtmlFragment from sage.misc.misc import get_main_globals -from sage.misc.superseded import deprecation from sage.modules.all import random_vector, vector from sage.plot.all import Graphics, arrow, line, point, rainbow, text from sage.rings.all import Infinity, PolynomialRing, QQ, RDF, ZZ @@ -3984,86 +3979,6 @@ def _latex_(self): lines[l] = lin return "\n".join(lines) - def ELLUL(self, entering, leaving): - r""" - Perform the Enter-Leave-LaTeX-Update-LaTeX step sequence on ``self``. - - INPUT: - - - ``entering`` -- the entering variable - - - ``leaving`` -- the leaving variable - - OUTPUT: - - - a string with LaTeX code for ``self`` before and after update - - EXAMPLES:: - - sage: A = ([1, 1], [3, 1]) - sage: b = (1000, 1500) - sage: c = (10, 5) - sage: P = InteractiveLPProblemStandardForm(A, b, c) - sage: D = P.initial_dictionary() - sage: D.ELLUL("x1", "x4") - doctest:...: DeprecationWarning: ELLUL is deprecated, please use separate enter-leave-update and output commands - See http://trac.sagemath.org/19097 for details. - \renewcommand{\arraystretch}{1.5} %notruncate - \begin{array}{|rcrcrcr|} - \hline - x_{3} \mspace{-6mu}&\mspace{-6mu} = \mspace{-6mu}&\mspace{-6mu} 1000 \mspace{-6mu}&\mspace{-6mu} - \mspace{-6mu}&\color{green}\mspace{-6mu} x_{1} \mspace{-6mu}&\mspace{-6mu} - \mspace{-6mu}&\mspace{-6mu} x_{2}\\ - \color{red}x_{4} \mspace{-6mu}&\color{red}\mspace{-6mu} = \mspace{-6mu}&\color{red}\mspace{-6mu} 1500 \mspace{-6mu}&\color{red}\mspace{-6mu} - \mspace{-6mu}&\color{blue}\mspace{-6mu} 3 x_{1} \mspace{-6mu}&\color{red}\mspace{-6mu} - \mspace{-6mu}&\color{red}\mspace{-6mu} x_{2}\\ - \hline - z \mspace{-6mu}&\mspace{-6mu} = \mspace{-6mu}&\mspace{-6mu} 0 \mspace{-6mu}&\mspace{-6mu} + \mspace{-6mu}&\color{green}\mspace{-6mu} 10 x_{1} \mspace{-6mu}&\mspace{-6mu} + \mspace{-6mu}&\mspace{-6mu} 5 x_{2}\\ - \hline - \\ - \hline - x_{3} \mspace{-6mu}&\mspace{-6mu} = \mspace{-6mu}&\mspace{-6mu} 500 \mspace{-6mu}&\mspace{-6mu} + \mspace{-6mu}&\mspace{-6mu} \frac{1}{3} x_{4} \mspace{-6mu}&\mspace{-6mu} - \mspace{-6mu}&\mspace{-6mu} \frac{2}{3} x_{2}\\ - x_{1} \mspace{-6mu}&\mspace{-6mu} = \mspace{-6mu}&\mspace{-6mu} 500 \mspace{-6mu}&\mspace{-6mu} - \mspace{-6mu}&\mspace{-6mu} \frac{1}{3} x_{4} \mspace{-6mu}&\mspace{-6mu} - \mspace{-6mu}&\mspace{-6mu} \frac{1}{3} x_{2}\\ - \hline - z \mspace{-6mu}&\mspace{-6mu} = \mspace{-6mu}&\mspace{-6mu} 5000 \mspace{-6mu}&\mspace{-6mu} - \mspace{-6mu}&\mspace{-6mu} \frac{10}{3} x_{4} \mspace{-6mu}&\mspace{-6mu} + \mspace{-6mu}&\mspace{-6mu} \frac{5}{3} x_{2}\\ - \hline - \end{array} - - This is how the above output looks when rendered: - - .. MATH:: - - \renewcommand{\arraystretch}{1.5} - \begin{array}{|rcrcrcr|} - \hline - x_{3} \mspace{-6mu}&\mspace{-6mu} = \mspace{-6mu}&\mspace{-6mu} 1000 \mspace{-6mu}&\mspace{-6mu} - \mspace{-6mu}&\color{green}\mspace{-6mu} x_{1} \mspace{-6mu}&\mspace{-6mu} - \mspace{-6mu}&\mspace{-6mu} x_{2}\\ - \color{red}x_{4} \mspace{-6mu}&\color{red}\mspace{-6mu} = \mspace{-6mu}&\color{red}\mspace{-6mu} 1500 \mspace{-6mu}&\color{red}\mspace{-6mu} - \mspace{-6mu}&\color{blue}\mspace{-6mu} 3 x_{1} \mspace{-6mu}&\color{red}\mspace{-6mu} - \mspace{-6mu}&\color{red}\mspace{-6mu} x_{2}\\ - \hline - z \mspace{-6mu}&\mspace{-6mu} = \mspace{-6mu}&\mspace{-6mu} 0 \mspace{-6mu}&\mspace{-6mu} + \mspace{-6mu}&\color{green}\mspace{-6mu} 10 x_{1} \mspace{-6mu}&\mspace{-6mu} + \mspace{-6mu}&\mspace{-6mu} 5 x_{2}\\ - \hline - \\ - \hline - x_{3} \mspace{-6mu}&\mspace{-6mu} = \mspace{-6mu}&\mspace{-6mu} 500 \mspace{-6mu}&\mspace{-6mu} + \mspace{-6mu}&\mspace{-6mu} \frac{1}{3} x_{4} \mspace{-6mu}&\mspace{-6mu} - \mspace{-6mu}&\mspace{-6mu} \frac{2}{3} x_{2}\\ - x_{1} \mspace{-6mu}&\mspace{-6mu} = \mspace{-6mu}&\mspace{-6mu} 500 \mspace{-6mu}&\mspace{-6mu} - \mspace{-6mu}&\mspace{-6mu} \frac{1}{3} x_{4} \mspace{-6mu}&\mspace{-6mu} - \mspace{-6mu}&\mspace{-6mu} \frac{1}{3} x_{2}\\ - \hline - z \mspace{-6mu}&\mspace{-6mu} = \mspace{-6mu}&\mspace{-6mu} 5000 \mspace{-6mu}&\mspace{-6mu} - \mspace{-6mu}&\mspace{-6mu} \frac{10}{3} x_{4} \mspace{-6mu}&\mspace{-6mu} + \mspace{-6mu}&\mspace{-6mu} \frac{5}{3} x_{2}\\ - \hline - \end{array} - - The column of the entering variable is green, while the row of the - leaving variable is red in the original dictionary state on the top. - The new state after the update step is shown on the bottom. - """ - deprecation(19097, "ELLUL is deprecated, please use separate " - "enter-leave-update and output commands") - self.enter(entering) - self.leave(leaving) - result = latex(self).rsplit("\n", 1)[0] # Remove \end{array} - # Make an empty line in the array - if generate_real_LaTeX: - result += "\n" r"\multicolumn{2}{c}{}\\[-3ex]" "\n" - else: - result += "\n\\\\\n" - self.update() - result += latex(self).split("\n", 2)[2] # Remove array header - return LatexExpr(result) - def add_row(self, nonbasic_coefficients, constant, basic_variable=None): r""" Return a dictionary with an additional row based on a given dictionary. diff --git a/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py b/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py index 0b9214b6cb6..f0689ddc741 100644 --- a/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py +++ b/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py @@ -5,8 +5,7 @@ - Anna Haensch (2014-12-01): added test for rational isometry """ -from __future__ import print_function -from __future__ import absolute_import +from __future__ import print_function, absolute_import from sage.arith.all import hilbert_symbol, prime_divisors, is_prime, valuation, GCD, legendre_symbol from sage.rings.integer_ring import ZZ @@ -20,11 +19,13 @@ ## (For now, we require both forms to be positive definite.) ## ################################################################################ -def is_globally_equivalent_to(self, other, return_matrix=False, check_theta_to_precision=None, check_local_equivalence=None): +def is_globally_equivalent_to(self, other, return_matrix=False): """ - Determines if the current quadratic form is equivalent to the - given form over ZZ. If ``return_matrix`` is True, then we return - the transformation matrix `M` so that ``self(M) == other``. + Determine if the current quadratic form is equivalent to the + given form over ZZ. + + If ``return_matrix`` is True, then we return the transformation + matrix `M` so that ``self(M) == other``. INPUT: @@ -77,16 +78,9 @@ def is_globally_equivalent_to(self, other, return_matrix=False, check_theta_to_p ... ValueError: not a definite form in QuadraticForm.is_globally_equivalent_to() - ALGORITHM: this uses the PARI function ``qfisom()``, implementing + ALGORITHM: this uses the PARI function :pari:`qfisom`, implementing an algorithm by Plesken and Souvignier. """ - if check_theta_to_precision is not None: - from sage.misc.superseded import deprecation - deprecation(19111, "The check_theta_to_precision argument is deprecated and ignored") - if check_local_equivalence is not None: - from sage.misc.superseded import deprecation - deprecation(19111, "The check_local_equivalence argument is deprecated and ignored") - ## Check that other is a QuadraticForm if not is_QuadraticForm(other): raise TypeError("you must compare two quadratic forms, but the argument is not a quadratic form") @@ -107,7 +101,7 @@ def is_globally_equivalent_to(self, other, return_matrix=False, check_theta_to_p def is_locally_equivalent_to(self, other, check_primes_only=False, force_jordan_equivalence_test=False): """ - Determines if the current quadratic form (defined over ZZ) is + Determine if the current quadratic form (defined over ZZ) is locally equivalent to the given form over the real numbers and the `p`-adic integers for every prime p. @@ -166,8 +160,6 @@ def is_locally_equivalent_to(self, other, check_primes_only=False, force_jordan_ return True - - def has_equivalent_Jordan_decomposition_at_prime(self, other, p): """ Determines if the given quadratic form has a Jordan decomposition From 0fbb59c853080f61d1f61b4050dd0c942dc3c7a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 29 Feb 2020 18:03:48 +0100 Subject: [PATCH 23/77] use richcmp in interfaces --- src/sage/interfaces/axiom.py | 22 +++++++++------------- src/sage/interfaces/giac.py | 21 +++++++++------------ src/sage/interfaces/interface.py | 18 +++++++----------- src/sage/interfaces/lisp.py | 11 ++++++----- src/sage/interfaces/maple.py | 21 +++++++++------------ src/sage/interfaces/mathematica.py | 17 +++++++---------- src/sage/interfaces/polymake.py | 13 +++++++------ 7 files changed, 54 insertions(+), 69 deletions(-) diff --git a/src/sage/interfaces/axiom.py b/src/sage/interfaces/axiom.py index 3e48a26ce29..ddcdbc6a1b1 100644 --- a/src/sage/interfaces/axiom.py +++ b/src/sage/interfaces/axiom.py @@ -173,10 +173,9 @@ # Distributed under the terms of the GNU General Public License (GPL) # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ ########################################################################### -from __future__ import print_function -from __future__ import absolute_import +from __future__ import print_function, absolute_import import os import re @@ -188,6 +187,8 @@ from sage.misc.multireplace import multiple_replace from sage.interfaces.tab_completion import ExtraTabCompletion from sage.docs.instancedoc import instancedoc +from sage.structure.richcmp import rich_to_bool + # The Axiom commands ")what thing det" ")show Matrix" and ")display # op det" commands, gives a list of all identifiers that begin in @@ -569,7 +570,7 @@ def __call__(self, x): P = self.parent() return P('%s(%s)'%(self.name(), x)) - def _cmp_(self, other): + def _richcmp_(self, other, op): """ EXAMPLES:: @@ -604,18 +605,13 @@ def _cmp_(self, other): """ P = self.parent() if 'true' in P.eval("(%s = %s) :: Boolean"%(self.name(),other.name())): - return 0 + return rich_to_bool(op, 0) elif 'true' in P.eval("(%s < %s) :: Boolean"%(self.name(), other.name())): - return -1 + return rich_to_bool(op, -1) elif 'true' in P.eval("(%s > %s) :: Boolean"%(self.name(),other.name())): - return 1 + return rich_to_bool(op, 1) - # everything is supposed to be comparable in Python, so we define - # the comparison thus when no comparable in interfaced system. - if (hash(self) < hash(other)): - return -1 - else: - return 1 + return NotImplemented def type(self): """ diff --git a/src/sage/interfaces/giac.py b/src/sage/interfaces/giac.py index 1df5d6f72db..f21a06774e4 100644 --- a/src/sage/interfaces/giac.py +++ b/src/sage/interfaces/giac.py @@ -231,6 +231,7 @@ from sage.env import DOT_SAGE from sage.misc.pager import pager from sage.docs.instancedoc import instancedoc +from sage.structure.richcmp import rich_to_bool COMMANDS_CACHE = '%s/giac_commandlist_cache.sobj'%DOT_SAGE @@ -868,7 +869,7 @@ def __hash__(self): """ return hash(giac.eval('string(%s);'%self.name())) - def _cmp_(self, other): + def _richcmp_(self, other, op): """ Compare equality between self and other, using giac. @@ -909,30 +910,26 @@ def _cmp_(self, other): P = self.parent() if P.eval("evalb(%s %s %s)"%(self.name(), P._equality_symbol(), other.name())) == P._true_symbol(): - return 0 + return rich_to_bool(op, 0) # (to be tested with giac). Maple does not allow comparing objects of different types and # it raises an error in this case. # We catch the error, and return True for < try: if P.eval("evalb(%s %s %s)"%(self.name(), P._lessthan_symbol(), other.name())) == P._true_symbol(): - return -1 + return rich_to_bool(op, -1) except RuntimeError as e: msg = str(e) if 'is not valid' in msg and 'to < or <=' in msg: if (hash(str(self)) < hash(str(other))): - return -1 + return rich_to_bool(op, -1) else: - return 1 + return rich_to_bool(op, 1) else: raise RuntimeError(e) if P.eval("evalb(%s %s %s)"%(self.name(), P._greaterthan_symbol(), other.name())) == P._true_symbol(): - return 1 - # everything is supposed to be comparable in Python, so we define - # the comparison thus when no comparable in interfaced system. - if (hash(self) < hash(other)): - return -1 - else: - return 1 + return rich_to_bool(op, 1) + + return NotImplemented def _tab_completion(self): """ diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index 5ced772cee6..1ab71831b94 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -35,7 +35,7 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** from __future__ import print_function from six import iteritems, integer_types, string_types @@ -45,6 +45,7 @@ from sage.structure.sage_object import SageObject from sage.structure.parent_base import ParentWithBase from sage.structure.element import Element, parent +from sage.structure.richcmp import rich_to_bool import sage.misc.sage_eval from sage.misc.fast_methods import WithEqualityById @@ -892,7 +893,7 @@ def __hash__(self): """ return hash('%s' % self) - def _cmp_(self, other): + def _richcmp_(self, other, op): """ Comparison of interface elements. @@ -933,26 +934,21 @@ def _cmp_(self, other): try: if P.eval("%s %s %s"%(self.name(), P._equality_symbol(), other.name())) == P._true_symbol(): - return 0 + return rich_to_bool(op, 0) except RuntimeError: pass try: if P.eval("%s %s %s"%(self.name(), P._lessthan_symbol(), other.name())) == P._true_symbol(): - return -1 + return rich_to_bool(op, -1) except RuntimeError: pass try: if P.eval("%s %s %s"%(self.name(), P._greaterthan_symbol(), other.name())) == P._true_symbol(): - return 1 + return rich_to_bool(op, 1) except Exception: pass - # everything is supposed to be comparable in Python, so we define - # the comparison thus when no comparison is available in interfaced system. - if hash(self) < hash(other): - return -1 - else: - return 1 + return NotImplemented def is_string(self): """ diff --git a/src/sage/interfaces/lisp.py b/src/sage/interfaces/lisp.py index 5fa799702b6..39094d2497d 100644 --- a/src/sage/interfaces/lisp.py +++ b/src/sage/interfaces/lisp.py @@ -48,7 +48,7 @@ # # Distributed under the terms of the GNU General Public License (GPL) # -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ # ########################################################################## @@ -57,6 +57,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.structure.richcmp import rich_to_bool class Lisp(Expect): @@ -387,7 +388,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): + def _richcmp_(self, other, op): """ EXAMPLES:: @@ -411,11 +412,11 @@ def _cmp_(self, other): other = P(other) if P.eval('(= %s %s)'%(self.name(), other.name())) == P._true_symbol(): - return 0 + return rich_to_bool(op, 0) elif P.eval('(< %s %s)'%(self.name(), other.name())) == P._true_symbol(): - return -1 + return rich_to_bool(op, -1) else: - return 1 + return rich_to_bool(op, 1) def __bool__(self): """ diff --git a/src/sage/interfaces/maple.py b/src/sage/interfaces/maple.py index c3182ea7fb7..7c26f4bd8cc 100644 --- a/src/sage/interfaces/maple.py +++ b/src/sage/interfaces/maple.py @@ -244,6 +244,8 @@ from sage.misc.pager import pager from sage.interfaces.tab_completion import ExtraTabCompletion from sage.docs.instancedoc import instancedoc +from sage.structure.richcmp import rich_to_bool + COMMANDS_CACHE = '%s/maple_commandlist_cache.sobj' % DOT_SAGE @@ -947,7 +949,7 @@ def __hash__(self): """ return int(maple.eval('StringTools:-Hash(convert(%s, string))'%self.name())[1:-1],16) - def _cmp_(self, other): + def _richcmp_(self, other, op): """ Compare equality between self and other, using maple. @@ -1001,32 +1003,27 @@ def _cmp_(self, other): P = self.parent() if P.eval("evalb(%s %s %s)" % (self.name(), P._equality_symbol(), other.name())) == P._true_symbol(): - return 0 + return rich_to_bool(op, 0) # Maple does not allow comparing objects of different types and # it raises an error in this case. # We catch the error, and return True for < try: if P.eval("evalb(%s %s %s)" % (self.name(), P._lessthan_symbol(), other.name())) == P._true_symbol(): - return -1 + return rich_to_bool(op, -1) except RuntimeError as e: msg = str(e) if 'is not valid' in msg and 'to < or <=' in msg: if (hash(str(self)) < hash(str(other))): - return -1 + return rich_to_bool(op, -1) else: - return 1 + return rich_to_bool(op, 1) else: raise RuntimeError(e) if P.eval("evalb(%s %s %s)" % (self.name(), P._greaterthan_symbol(), other.name())) == P._true_symbol(): - return 1 - # everything is supposed to be comparable in Python, so we define - # the comparison thus when no comparable in interfaced system. - if (hash(self) < hash(other)): - return -1 - else: - return 1 + return rich_to_bool(op, 1) + return NotImplemented def _mul_(self, right): """ diff --git a/src/sage/interfaces/mathematica.py b/src/sage/interfaces/mathematica.py index 644b0b8ee69..46eb80b1870 100644 --- a/src/sage/interfaces/mathematica.py +++ b/src/sage/interfaces/mathematica.py @@ -368,7 +368,7 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** from __future__ import print_function @@ -381,6 +381,7 @@ from sage.interfaces.interface import AsciiArtString from sage.interfaces.tab_completion import ExtraTabCompletion from sage.docs.instancedoc import instancedoc +from sage.structure.richcmp import rich_to_bool def clean_output(s): @@ -982,19 +983,15 @@ def show(self, ImageSize=600): def str(self): return str(self) - def _cmp_(self, other): - #if not (isinstance(other, ExpectElement) and other.parent() is self.parent()): - # return coerce.cmp(self, other) + def _richcmp_(self, other, op): P = self.parent() if P.eval("%s < %s"%(self.name(), other.name())).strip() == 'True': - return -1 + return rich_to_bool(op, -1) elif P.eval("%s > %s"%(self.name(), other.name())).strip() == 'True': - return 1 + return rich_to_bool(op, 1) elif P.eval("%s == %s"%(self.name(), other.name())).strip() == 'True': - return 0 - else: - return -1 # everything is supposed to be comparable in Python, so we define - # the comparison thus when no comparable in interfaced system. + return rich_to_bool(op, 0) + return NotImplemented def __bool__(self): """ diff --git a/src/sage/interfaces/polymake.py b/src/sage/interfaces/polymake.py index 11bdd5cfeff..8a969a0b5db 100644 --- a/src/sage/interfaces/polymake.py +++ b/src/sage/interfaces/polymake.py @@ -22,7 +22,7 @@ # # The full text of the GPL is available at: # -# hsttp://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ # **************************************************************************** from __future__ import print_function, absolute_import import six @@ -40,6 +40,7 @@ from sage.misc.misc import get_verbose from sage.misc.cachefunc import cached_method from sage.interfaces.tab_completion import ExtraTabCompletion +from sage.structure.richcmp import rich_to_bool import pexpect from random import randrange @@ -979,7 +980,7 @@ def _repr_(self): out = P.get(name).strip() return out - def _cmp_(self, other): + def _richcmp_(self, other, op): """ Comparison of polymake elements. @@ -1011,12 +1012,12 @@ def _cmp_(self, other): """ P = self._check_valid() if P.eval("print {} {} {};".format(self.name(), P._equality_symbol(), other.name())).strip() == P._true_symbol(): - return 0 + return rich_to_bool(op, 0) if P.eval("print {} {} {};".format(self.name(), P._lessthan_symbol(), other.name())).strip() == P._true_symbol(): - return -1 + return rich_to_bool(op, -1) if P.eval("print {} {} {};".format(self.name(), P._greaterthan_symbol(), other.name())).strip() == P._true_symbol(): - return 1 - return -2 # that's supposed to be an error value. + return rich_to_bool(op, 1) + return NotImplemented def __bool__(self): """ From ed53236a08d5d5353b2cd0ed78c02b39ff2edc56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 29 Feb 2020 18:33:41 +0100 Subject: [PATCH 24/77] a typo ticket, once again --- src/sage/coding/goppa_code.py | 3 ++- src/sage/combinat/rsk.py | 4 ++-- .../dynamics/arithmetic_dynamics/projective_ds_helper.pyx | 5 ++--- .../combinatorial_polyhedron/bit_vector_operations.cc | 2 +- .../combinatorial_polyhedron/combinatorial_face.pyx | 8 ++++---- .../combinatorial_polyhedron/polyhedron_face_lattice.pyx | 2 +- src/sage/graphs/graph_latex.py | 2 +- src/sage/graphs/traversals.pyx | 2 +- src/sage/graphs/tutte_polynomial.py | 2 +- src/sage/groups/matrix_gps/matrix_group.py | 3 +-- src/sage/misc/sagedoc.py | 4 ++-- src/sage/numerical/gauss_legendre.pyx | 2 +- src/sage/plot/graphics.py | 8 ++++---- src/sage/rings/localization.py | 6 +++--- 14 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/sage/coding/goppa_code.py b/src/sage/coding/goppa_code.py index 091312c52fa..152877c062e 100644 --- a/src/sage/coding/goppa_code.py +++ b/src/sage/coding/goppa_code.py @@ -61,6 +61,7 @@ def _columnize(element): v = vector(element) return v.column() + class GoppaCode(AbstractLinearCode): r""" Implementation of Goppa codes. @@ -73,7 +74,7 @@ class GoppaCode(AbstractLinearCode): In binary cases, the minimum distance is `2t + 1`, where `t` is the degree of `g`. - INPUTS: + INPUT: - ``generating_pol`` -- a monic polynomial with coefficients in a finite field `\GF{p^m}`, the code is defined over `\GF{p}`, `p` must be a prime number diff --git a/src/sage/combinat/rsk.py b/src/sage/combinat/rsk.py index afc72c79be2..e6a457bcf72 100644 --- a/src/sage/combinat/rsk.py +++ b/src/sage/combinat/rsk.py @@ -2009,7 +2009,7 @@ def to_pairs(self, obj1=None, obj2=None, check=True): two `n`-tuples ``obj1`` `= [a_1, a_2, \ldots, a_n]` and ``obj2`` `= [b_1, b_2, \ldots, b_n]` forming a restricted super biword (i.e., entries with even and odd parity and no - repeatition of corresponding pairs with mixed parity entries) + repetition of corresponding pairs with mixed parity entries) return the array `[(a_1, b_1), (a_2, b_2), \ldots, (a_n, b_n)]`. INPUT: @@ -2053,7 +2053,7 @@ def to_pairs(self, obj1=None, obj2=None, check=True): raise ValueError("the two arrays must be the same length") mixed_parity = [] # Check it is a restricted superbiword: that is, - # the entries can have even or odd parity, but repeatition of + # the entries can have even or odd parity, but repetition of # the pairs of corresponding entries of obj1 # and obj2 with mixed-parity is not allowed for t, b in zip(obj1, obj2): diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx b/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx index 547044ecb17..e3769c89f54 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx @@ -268,12 +268,12 @@ cpdef _normalize_coordinates(list point, int prime, int len_points): for coefficient in xrange(len_points): point[coefficient] = (point[coefficient] * mod_inverse) % prime - + cpdef _all_periodic_points(self): """ Find all periodic points over a finite field. - EXAMPELS:: + EXAMPLES:: sage: from sage.dynamics.arithmetic_dynamics.projective_ds_helper import _all_periodic_points sage: P. = ProjectiveSpace(GF(7), 1) @@ -298,4 +298,3 @@ cpdef _all_periodic_points(self): if next_element in path: periodic_points += path[path.index(next_element):] return periodic_points - diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/bit_vector_operations.cc b/src/sage/geometry/polyhedron/combinatorial_polyhedron/bit_vector_operations.cc index 99f244b1755..6fa2750034f 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/bit_vector_operations.cc +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/bit_vector_operations.cc @@ -184,7 +184,7 @@ size_t bit_repr_to_coatom_rep(uint64_t *face, uint64_t **coatoms, \ for (size_t i = 0; i < n_coatoms; i++){ if (is_subset(face, coatoms[i], face_length)){ // ``face`` is contain in ``coatoms[i]``, - // then ``i`` is an element in the coatom-represention. + // then ``i`` is an element in the coatom-representation. output[count_length] = i; count_length++; } diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx index 1c4654b18e3..78805284ade 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx @@ -548,12 +548,12 @@ cdef class CombinatorialFace(SageObject): return self.ambient_H_indices() cdef size_t length if not self._dual: - # if not dual, the facet-represention corresponds to the coatom-representation + # if not dual, the facet-representation corresponds to the coatom-representation length = self.set_coatom_rep() # fill self.coatom_repr_face return tuple(self._ambient_facets[self.coatom_rep[i]] for i in range(length)) + self._equalities else: - # if dual, the facet-represention corresponds to the atom-representation + # if dual, the facet-representation corresponds to the atom-representation length = self.set_atom_rep() # fill self.atom_repr_face return tuple(self._ambient_facets[self.atom_rep[i]] for i in range(length)) + self._equalities @@ -595,12 +595,12 @@ cdef class CombinatorialFace(SageObject): """ cdef size_t length if not self._dual: - # if not dual, the facet-represention corresponds to the coatom-representation + # if not dual, the facet-representation corresponds to the coatom-representation length = self.set_coatom_rep() # fill self.coatom_repr_face return tuple(smallInteger(self.coatom_rep[i]) for i in range(length)) else: - # if dual, the facet-represention corresponds to the atom-representation + # if dual, the facet-representation corresponds to the atom-representation length = self.set_atom_rep() # fill self.atom_repr_face return tuple(smallInteger(self.atom_rep[i]) for i in range(length)) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx index 730e1cf4110..880e714b5d6 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx @@ -460,7 +460,7 @@ cdef class PolyhedronFaceLattice: """ cdef size_t length if self.dual: - # if dual, the Vrepresention corresponds to the coatom-representation + # if dual, the Vrepresentation corresponds to the coatom-representation dimension = self.dimension - 1 - dimension # if dual, the dimensions are reversed return CombinatorialFace(self, dimension=dimension, index=index) diff --git a/src/sage/graphs/graph_latex.py b/src/sage/graphs/graph_latex.py index 6cc062f127f..da39caab2ce 100644 --- a/src/sage/graphs/graph_latex.py +++ b/src/sage/graphs/graph_latex.py @@ -1071,7 +1071,7 @@ def set_option(self, option_name, option_value=None): # shape" to mirror vertex shapes # - "line width" works for vertices, should be configurable # - allow injection of latex code to style a pre-built style for - # example, \SetUpVertex[style={fill=green}] could overide color + # example, \SetUpVertex[style={fill=green}] could override color # selection in a style like "Art" # - "inner sep" is distance from vertex label to edge of vertex this # should be set as small as possible - but bigger than the line width. diff --git a/src/sage/graphs/traversals.pyx b/src/sage/graphs/traversals.pyx index 5116f71f75b..36a20aabf9e 100644 --- a/src/sage/graphs/traversals.pyx +++ b/src/sage/graphs/traversals.pyx @@ -1290,7 +1290,7 @@ def is_valid_lex_M_order(G, alpha, F): clique. The ordering `\alpha` is a perfect elimination ordering of `H`, so `H` is chordal. See [RTL76]_ for more details. - INPUTS: + INPUT: - ``G`` -- a Graph diff --git a/src/sage/graphs/tutte_polynomial.py b/src/sage/graphs/tutte_polynomial.py index 994ed721492..e5c455ef9f7 100644 --- a/src/sage/graphs/tutte_polynomial.py +++ b/src/sage/graphs/tutte_polynomial.py @@ -671,7 +671,7 @@ def yy(start, end): for d_i in d[:-2]) return result - # Theorem 3 from Haggard, Pearce, and Royle, adapted to multi-eaars + # Theorem 3 from Haggard, Pearce, and Royle, adapted to multi-ears ear = Ear.find_ear(uG) if ear is not None: if (ear.is_cycle and ear.vertices == G.vertices()): diff --git a/src/sage/groups/matrix_gps/matrix_group.py b/src/sage/groups/matrix_gps/matrix_group.py index 90249e2adcf..434e662ca15 100644 --- a/src/sage/groups/matrix_gps/matrix_group.py +++ b/src/sage/groups/matrix_gps/matrix_group.py @@ -48,7 +48,6 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** - from __future__ import absolute_import from sage.categories.groups import Groups @@ -188,7 +187,7 @@ def subgroup(self, generators, check=True): OUTPUT: The subgroup generated by ``generators`` as an instance of FinitelyGeneratedMatrixGroup_gap - EAMPLES:: + EXAMPLES:: sage: UCF = UniversalCyclotomicField() sage: G = GL(3, UCF) diff --git a/src/sage/misc/sagedoc.py b/src/sage/misc/sagedoc.py index c9cafa210d7..1d59629e4b5 100644 --- a/src/sage/misc/sagedoc.py +++ b/src/sage/misc/sagedoc.py @@ -258,7 +258,7 @@ def skip_TESTS_block(docstring): - ``docstring``, a string - A "TESTS" block is a block starting with "TEST:" or "TESTS:" (or + A "TESTS" block is a block starting "TESTS:" (or the same with two colons), on a line on its own, and ending either with a line indented less than "TESTS", or with a line with the same level of indentation -- not more -- matching one of the @@ -284,7 +284,7 @@ def skip_TESTS_block(docstring): sage: from sage.misc.sagedoc import skip_TESTS_block sage: start = ' Docstring\n\n' - sage: test = ' TEST: \n\n Here is a test::\n sage: 2+2 \n 5 \n\n' + sage: test = ' TESTS: \n\n Here is a test::\n sage: 2+2 \n 5 \n\n' sage: test2 = ' TESTS:: \n\n sage: 2+2 \n 6 \n\n' Test lines starting with "REFERENCES:":: diff --git a/src/sage/numerical/gauss_legendre.pyx b/src/sage/numerical/gauss_legendre.pyx index 129edf63dcf..dda596ce0eb 100644 --- a/src/sage/numerical/gauss_legendre.pyx +++ b/src/sage/numerical/gauss_legendre.pyx @@ -53,7 +53,7 @@ def nodes(degree,prec): A list of (node,weight) pairs. - EXAMPLE: + EXAMPLES: The nodes for the Gauss-Legendre scheme are roots of Legendre polynomials. The weights can be computed by a straightforward formula (note that evaluating diff --git a/src/sage/plot/graphics.py b/src/sage/plot/graphics.py index 2a80a050a50..ec0d47e90c1 100644 --- a/src/sage/plot/graphics.py +++ b/src/sage/plot/graphics.py @@ -24,7 +24,7 @@ """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2006 Alex Clemesha # Copyright (C) 2006-2008 William Stein # Copyright (C) 2010 Jason Grout @@ -32,8 +32,8 @@ # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from __future__ import print_function, absolute_import from six.moves import zip from six import integer_types @@ -80,7 +80,7 @@ def _parse_figsize(figsize): - ``figsize`` -- width or [width, height] in inches; if only the width is provided, the height is computed from matplotlib's default aspect ratio - OUPUT: + OUTPUT: - a pair of ``float``'s representing ``(width, height)`` diff --git a/src/sage/rings/localization.py b/src/sage/rings/localization.py index 7c791aa55bc..dad7ae52b33 100644 --- a/src/sage/rings/localization.py +++ b/src/sage/rings/localization.py @@ -167,7 +167,7 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ # **************************************************************************** @@ -495,7 +495,7 @@ class Localization(IntegralDomain, UniqueRepresentation): - :wikipedia:`Ring_(mathematics)#Localization` - EAXAMPLES:: + EXAMPLES:: sage: L = Localization(ZZ, (3,5)) sage: 1/45 in L @@ -554,7 +554,7 @@ def __init__(self, base_ring, additional_units, names=None, normalize=True, cate """ Python constructor of Localization. - TEST:: + TESTS:: sage: L = Localization(ZZ, (3,5)) sage: TestSuite(L).run() From b5ed54cbc7e39a56f92b52af6cb2b0c8e9d031cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 29 Feb 2020 20:57:40 +0100 Subject: [PATCH 25/77] some details --- src/sage/misc/sagedoc.py | 25 +++++++++++++++---------- src/sage/rings/localization.py | 7 +------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/sage/misc/sagedoc.py b/src/sage/misc/sagedoc.py index 1d59629e4b5..85ee7644fac 100644 --- a/src/sage/misc/sagedoc.py +++ b/src/sage/misc/sagedoc.py @@ -31,20 +31,21 @@ sage: "sphinx" in sys.modules False """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2005 William Stein # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** -from __future__ import print_function -from __future__ import absolute_import +from __future__ import print_function, absolute_import from six import string_types, text_type -import os, re, sys +import os +import re +import sys import pydoc from sage.misc.temporary_file import tmp_dir from .viewer import browser @@ -710,9 +711,11 @@ def format(s, embedded=False): i_0 = 0 while True: i = s[i_0:].find("<<<") - if i == -1: break + if i == -1: + break j = s[i_0+i+3:].find('>>>') - if j == -1: break + if j == -1: + break obj = s[i_0+i+3 : i_0+i+3+j] if obj in docs: t = '' @@ -769,9 +772,11 @@ def format_src(s): import sage.all while True: i = s.find("<<<") - if i == -1: break + if i == -1: + break j = s[i+3:].find('>>>') - if j == -1: break + if j == -1: + break obj = s[i+3:i+3+j] if obj in docs: t = '' diff --git a/src/sage/rings/localization.py b/src/sage/rings/localization.py index dad7ae52b33..652d4898bb7 100644 --- a/src/sage/rings/localization.py +++ b/src/sage/rings/localization.py @@ -456,13 +456,8 @@ def _richcmp_(self, other, op): return sval._richcmp_(oval, op) - - - - - class Localization(IntegralDomain, UniqueRepresentation): - """ + r""" The localization generalizes the construction of the field of fractions of an integral domain to an arbitrary ring. Given a (not necessarily commutative) ring `R` and a subset `S` of `R`, there exists a ring `R[S^{-1}]` together with the ring homomorphism `R \longrightarrow R[S^{-1}]` From 5bc693e3ac20dc442687150869882b2445d74aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 1 Mar 2020 08:38:43 +0100 Subject: [PATCH 26/77] little fixes in combinat/combinat --- src/sage/combinat/combinat.py | 60 +++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/src/sage/combinat/combinat.py b/src/sage/combinat/combinat.py index 2bb088f913a..c1e149fb11b 100644 --- a/src/sage/combinat/combinat.py +++ b/src/sage/combinat/combinat.py @@ -171,8 +171,10 @@ def bell_number(n, algorithm='flint', **options): r""" - Return the `n`-th Bell number (the number of ways to partition a set - of `n` elements into pairwise disjoint nonempty subsets). + Return the `n`-th Bell number. + + This is the number of ways to partition a set + of `n` elements into pairwise disjoint nonempty subsets. INPUT: @@ -587,8 +589,12 @@ def eulerian_number(n, k, algorithm='recursive'): sage: [eulerian_number(6,i,"formula") for i in range(6)] [1, 57, 302, 302, 57, 1] + sage: [eulerian_number(3,i) for i in range(-1, 4)] + [0, 1, 4, 1, 0] """ n = ZZ(n) + if k < 0 or k > n - 1: + return ZZ.zero() if k == 0 or k == n - 1: return ZZ.one() if algorithm == "recursive": @@ -707,6 +713,7 @@ def fibonacci(n, algorithm="pari"): else: raise ValueError("no algorithm {}".format(algorithm)) + def lucas_number1(n, P, Q): r""" Return the `n`-th Lucas number "of the first kind" (this is not @@ -773,6 +780,7 @@ def lucas_number1(n, P, Q): from sage.libs.gap.libgap import libgap return libgap.Lucas(P, Q, n)[0].sage() + def lucas_number2(n, P, Q): r""" Return the `n`-th Lucas number "of the second kind" (this is not @@ -856,9 +864,11 @@ def stirling_number1(n, k): def stirling_number2(n, k, algorithm=None): r""" Return the `n`-th Stirling number `S_2(n,k)` of the second - kind (the number of ways to partition a set of `n` elements into `k` - pairwise disjoint nonempty subsets). (The `n`-th Bell number is the - sum of the `S_2(n,k)`'s, `k=0,...,n`.) + kind. + + This is the number of ways to partition a set of `n` elements into `k` + pairwise disjoint nonempty subsets. The `n`-th Bell number is the + sum of the `S_2(n,k)`'s, `k=0,...,n`. INPUT: @@ -1075,7 +1085,7 @@ def _repr_(self): def __eq__(self, other): """ - Test equality of self and other. + Test equality of ``self`` and ``other``. EXAMPLES:: @@ -1230,7 +1240,7 @@ def __add__(self, other): def __hash__(self): """ - Computes the hash of self by computing the hash of the string + Compute the hash of ``self`` by computing the hash of the string representation of self._list. The hash is cached and stored in self._hash. @@ -1480,7 +1490,7 @@ def __init__(self, category = None): def is_finite(self): """ - Returns whether self is finite or not. + Return whether ``self`` is finite or not. EXAMPLES:: @@ -1493,7 +1503,7 @@ def is_finite(self): def __getitem__(self, i): """ - Returns the combinatorial object of rank i. + Return the combinatorial object of rank i. EXAMPLES:: @@ -1514,7 +1524,7 @@ def __getitem__(self, i): def __str__(self): """ - Returns a string representation of self. + Return a string representation of self. EXAMPLES:: @@ -1537,7 +1547,7 @@ def _repr_(self): def __contains__(self, x): """ - Tests whether or not the combinatorial class contains the object x. + Test whether or not the combinatorial class contains the object x. This raises a NotImplementedError as a default since _all_ subclasses of CombinatorialClass should override this. @@ -1576,7 +1586,7 @@ def __eq__(self, other): def __ne__(self, other): """ - Test unequality of self and other. + Test unequality of ``self`` and ``other``. EXAMPLES:: @@ -1629,7 +1639,7 @@ def __cardinality_from_iterator(self): def __call__(self, x): """ - Returns x as an element of the combinatorial class's object class. + Return x as an element of the combinatorial class's object class. EXAMPLES:: @@ -1978,8 +1988,8 @@ def __previous_from_iterator(self, obj): def filter(self, f, name=None): """ - Returns the combinatorial subclass of f which consists of the - elements x of self such that f(x) is True. + Return the combinatorial subclass of f which consists of the + elements x of ``self`` such that f(x) is ``True``. EXAMPLES:: @@ -1992,8 +2002,8 @@ def filter(self, f, name=None): def union(self, right_cc, name=None): """ - Returns the combinatorial class representing the union of self and - right_cc. + Return the combinatorial class representing the union of ``self`` and + ``right_cc``. EXAMPLES:: @@ -2008,7 +2018,7 @@ def union(self, right_cc, name=None): def map(self, f, name=None): r""" - Returns the image `\{f(x) | x \in \text{self}\}` of this combinatorial + Return the image `\{f(x) | x \in \text{self}\}` of this combinatorial class by `f`, as a combinatorial class. `f` is supposed to be injective. @@ -2040,6 +2050,7 @@ class by `f`, as a combinatorial class. """ return MapCombinatorialClass(self, f, name) + class FilteredCombinatorialClass(CombinatorialClass): def __init__(self, combinatorial_class, f, name=None): """ @@ -2118,6 +2129,7 @@ def __iter__(self): if self.f(x): yield x + class UnionCombinatorialClass(CombinatorialClass): def __init__(self, left_cc, right_cc, name=None): """ @@ -2354,7 +2366,7 @@ def __repr__(self): def cardinality(self): """ - Returns the cardinality of this combinatorial class + Return the cardinality of this combinatorial class EXAMPLES:: @@ -2367,7 +2379,7 @@ def cardinality(self): def __iter__(self): """ - Returns an iterator over the elements of this combinatorial class + Return an iterator over the elements of this combinatorial class EXAMPLES:: @@ -2380,7 +2392,7 @@ def __iter__(self): def an_element(self): """ - Returns an element of this combinatorial class + Return an element of this combinatorial class EXAMPLES:: @@ -2404,7 +2416,7 @@ class InfiniteAbstractCombinatorialClass(CombinatorialClass): """ def cardinality(self): """ - Counts the elements of the combinatorial class. + Count the elements of the combinatorial class. EXAMPLES:: @@ -2416,7 +2428,7 @@ def cardinality(self): def list(self): """ - Returns an error since self is an infinite combinatorial class. + Return an error since ``self`` is an infinite combinatorial class. EXAMPLES:: @@ -2430,7 +2442,7 @@ def list(self): def __iter__(self): """ - Returns an iterator for the infinite combinatorial class self if + Return an iterator for the infinite combinatorial class ``self`` if possible or raise a NotImplementedError. EXAMPLES:: From 359813032e0182986e39b5c0a9ed3abbc4b7af99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 1 Mar 2020 09:01:45 +0100 Subject: [PATCH 27/77] trac 29260 do not need iter() --- src/sage/misc/weak_dict.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/weak_dict.pyx b/src/sage/misc/weak_dict.pyx index 3f1a8333872..b2d6fc1f857 100644 --- a/src/sage/misc/weak_dict.pyx +++ b/src/sage/misc/weak_dict.pyx @@ -347,10 +347,10 @@ cdef class WeakValueDictionary(dict): True """ try: - data = iter(data.items()) + data = data.items() except AttributeError: pass - for (k, v) in data: + for k, v in data: self._set_item(k, v) def __copy__(self): From 26ce9c340f27bef0bf5b2488bc59c91ab5e78b14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 1 Mar 2020 19:05:20 +0100 Subject: [PATCH 28/77] fix details --- src/sage/combinat/combinat.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/combinat/combinat.py b/src/sage/combinat/combinat.py index c1e149fb11b..4d16b1ce599 100644 --- a/src/sage/combinat/combinat.py +++ b/src/sage/combinat/combinat.py @@ -980,7 +980,8 @@ def stirling_number2(n, k, algorithm=None): ... ValueError: unknown algorithm: CloudReading """ - n = ZZ(n); k = ZZ(k) + n = ZZ(n) + k = ZZ(k) if algorithm is None: return _stirling_number2(n, k) elif algorithm == 'gap': From 004c1c4211af86c177b8fd537f6aad01cc593623 Mon Sep 17 00:00:00 2001 From: Sebastian Oehms Date: Sun, 1 Mar 2020 21:27:17 +0100 Subject: [PATCH 29/77] 29266 initial version --- .../rings/polynomial/polynomial_element.pyx | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 340fb91fc50..6e1b77ae2ae 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -4277,6 +4277,17 @@ cdef class Polynomial(CommutativeAlgebraElement): sage: p = x^4 + (-5 - 2*t)*x^3 + (-2 + 10*t)*x^2 + (10 + 4*t)*x - 20*t sage: p.factor() (x - 5) * (x - 2*t) * (x^2 - 2) + + Check that :trac:`29266` is fixed: + + sage: f = t*x + t + sage: f.is_irreducible() + True + sage: f = 2*x + 4 + sage: f.is_irreducible() + Traceback (most recent call last): + ... + NotImplementedError """ # PERFORMANCE NOTE: # In many tests with SMALL degree PARI is substantially @@ -4394,8 +4405,11 @@ cdef class Polynomial(CommutativeAlgebraElement): F = R.fraction_field() PF = F[self.variable_name()] pol_frac = PF(self) - return pol_frac.factor(**kwargs).base_change(self.parent()) - except (TypeError, AttributeError): + pol_frac_fact = pol_frac.factor(**kwargs) + if R(pol_frac_fact.unit()).is_unit(): + # Note: :meth:`base_change` may coerce the unit to a non unit + return pol_frac_fact.base_change(self.parent()) + except (TypeError, AttributeError, NotImplementedError): raise NotImplementedError raise NotImplementedError From 749f83e1a74b3b0628bc372c413199103f8188c7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 2 Feb 2020 14:19:22 -0500 Subject: [PATCH 30/77] tox.ini: Add other archs supported by docker --- .gitignore | 5 +++++ tox.ini | 44 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 68172bd7790..ad387f1ae5d 100644 --- a/.gitignore +++ b/.gitignore @@ -97,3 +97,8 @@ gitlab-build-docker.log /src/bin/sage-env-config /build/bin/sage-build-env-config +####################### +# tox generated files # +####################### + +/.tox diff --git a/tox.ini b/tox.ini index 5924bdc54b1..d2b08ba69a5 100644 --- a/tox.ini +++ b/tox.ini @@ -15,7 +15,26 @@ envlist = centos-{7,8}, arch-latest, conda-forge,conda-anaconda3 - }-{minimal,standard,maximal} + } + -{# https://github.com/docker-library/official-images#architectures-other-than-amd64 + # architectures officially supported by Docker, Inc. for running Docker + amd64,arm32v6,arm32v7,arm64v8, + # windows-amd64 # https://hub.docker.com/u/winamd64/ + # Other architectures built by official images: + # (but not officially supported by Docker, Inc.) + arm32v5,ppc64le,s390x,i386} + ### "local" targets should be run from a source tree that is freshly checked out + ### (for example, by 'git worktree add ...') or has been cleaned by 'make bdist-clean' -- + ### because they build within the source tree (because we have no VPATH support). + ### Only one "local" target can be run at a time. + ### However, "local" targets install in a separate prefix (SAGE_LOCAL=.tox/TOXENV/local) + ### rather than "local/" and also place log files into .tox/TOXENV/log, where TOXENV + ### is the name of the environment. + -{minimal,standard,maximal}, + ### The "local-direct" toxenv passes the whole environment on to the sage build. + ### Whatever is in PATH etc. will be used. + local-direct + skipsdist = true [testenv] @@ -96,6 +115,27 @@ setenv = conda-anaconda3: BASE_IMAGE=continuumio/anaconda3:latest conda-anaconda3: CONDARC=/dev/null conda-anaconda3: IGNORE_MISSING_SYSTEM_PACKAGES=yes + # + # Other architectures + # + ARCH_PREFIX= + arm32v5: ARCH_PREFIX=arm32v5/ + arm32v6: ARCH_PREFIX=arm32v6/ + arm32v7: ARCH_PREFIX=arm32v7/ + arm64v8: ARCH_PREFIX=arm64v8/ + i386: ARCH_PREFIX=i386/ + ppc64le: ARCH_PREFIX=ppc64le/ + s390x: ARCH_PREFIX=s390x/ + ARCH_BASE_IMAGE={env:ARCH_PREFIX}{env:BASE_IMAGE} + ### + ### "local" envs + ### + local: HOME={envdir} + local-!direct: PATH=/usr/bin:/bin:/usr/sbin:/sbin + +# environment will be skipped if regular expression does not match against the sys.platform string +platform = + local-macos: darwin whitelist_externals = bash @@ -104,7 +144,7 @@ commands = docker: bash -c 'build/bin/write-dockerfile.sh {env:SYSTEM} "{env:TYPE_PATTERN:}" {env:WITH_SYSTEM_SPKG} {env:IGNORE_MISSING_SYSTEM_PACKAGES} > {envdir}/Dockerfile' docker: docker build . -f {envdir}/Dockerfile \ docker: --build-arg EXTRA_CONFIGURE_ARGS="{env:EXTRA_CONFIGURE_ARGS:}" \ - docker: --build-arg BASE_IMAGE={env:BASE_IMAGE} \ + docker: --build-arg BASE_IMAGE={env:ARCH_BASE_IMAGE} \ docker-conda: --build-arg USE_CONDARC="{env:CONDARC}" \ docker: {env:EXTRA_DOCKER_BUILD_ARGS:} From e941bd55340543b822ab2088b0ca52f49dab5c40 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 2 Feb 2020 16:00:05 -0500 Subject: [PATCH 31/77] fixup for llocal --- tox.ini | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index d2b08ba69a5..7089e326ba2 100644 --- a/tox.ini +++ b/tox.ini @@ -126,7 +126,10 @@ setenv = i386: ARCH_PREFIX=i386/ ppc64le: ARCH_PREFIX=ppc64le/ s390x: ARCH_PREFIX=s390x/ - ARCH_BASE_IMAGE={env:ARCH_PREFIX}{env:BASE_IMAGE} + # + # Many docker images for another architecture are named the same, in the prefix + # + docker: ARCH_BASE_IMAGE={env:ARCH_PREFIX}{env:BASE_IMAGE} ### ### "local" envs ### From 2441fe9c1443fbdcc9bfc50cca7f7a113ae2e545 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 6 Feb 2020 09:38:08 -0500 Subject: [PATCH 32/77] tox.ini: Restructure docker image:tag construction, add multiarch for Linux Docker --- tox.ini | 116 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 71 insertions(+), 45 deletions(-) diff --git a/tox.ini b/tox.ini index 7089e326ba2..7fd961f8550 100644 --- a/tox.ini +++ b/tox.ini @@ -57,79 +57,102 @@ setenv = debian: EXTRA_CONFIGURE_ARGS=--with-system-m4ri=no --with-system-m4rie=no --with-system-givaro=no fedora: EXTRA_CONFIGURE_ARGS=--with-system-m4ri=no --with-system-m4rie=no # + # default tag is "latest" + # + docker: BASE_TAG=latest + # # https://hub.docker.com/_/ubuntu?tab=description # as of 2020-01, latest=bionic=18.04, eoan=rolling=19.10, focal=devel=20.04 # ubuntu: SYSTEM=debian - ubuntu-trusty: BASE_IMAGE=ubuntu:trusty + ubuntu: BASE_IMAGE=ubuntu + ubuntu-trusty: BASE_TAG=trusty ubuntu-trusty: IGNORE_MISSING_SYSTEM_PACKAGES=yes - ubuntu-xenial: BASE_IMAGE=ubuntu:xenial + ubuntu-xenial: BASE_TAG=xenial ubuntu-xenial: IGNORE_MISSING_SYSTEM_PACKAGES=yes - ubuntu-bionic: BASE_IMAGE=ubuntu:bionic - ubuntu-latest: BASE_IMAGE=ubuntu:latest - ubuntu-eoan: BASE_IMAGE=ubuntu:eoan - ubuntu-rolling: BASE_IMAGE=ubuntu:rolling - ubuntu-focal: BASE_IMAGE=ubuntu:focal - ubuntu-devel: BASE_IMAGE=ubuntu:devel + ubuntu-bionic: BASE_TAG=bionic + ubuntu-latest: BASE_TAG=latest + ubuntu-eoan: BASE_TAG=eoan + ubuntu-rolling: BASE_TAG=rolling + ubuntu-focal: BASE_TAG=focal + ubuntu-devel: BASE_TAG=devel # # https://hub.docker.com/_/debian # - debian: SYSTEM=debian - debian-jessie: BASE_IMAGE=debian:jessie - debian-jessie: IGNORE_MISSING_SYSTEM_PACKAGES=yes - debian-stretch: BASE_IMAGE=debian:stretch - debian-buster: BASE_IMAGE=debian:buster - debian-bullseye: BASE_IMAGE=debian:bullseye - debian-sid: BASE_IMAGE=debian:sid + debian: SYSTEM=debian + debian: BASE_IMAGE=debian + debian-jessie: BASE_TAG=jessie + debian-jessie: IGNORE_MISSING_SYSTEM_PACKAGES=yes + debian-stretch: BASE_TAG=stretch + debian-buster: BASE_TAG=buster + debian-bullseye: BASE_TAG=bullseye + debian-sid: BASE_TAG=sid # # https://hub.docker.com/_/fedora # - fedora: SYSTEM=fedora - fedora-26: BASE_IMAGE=fedora:26 - fedora-26: IGNORE_MISSING_SYSTEM_PACKAGES=yes - fedora-27: BASE_IMAGE=fedora:27 - fedora-28: BASE_IMAGE=fedora:28 - fedora-29: BASE_IMAGE=fedora:29 - fedora-30: BASE_IMAGE=fedora:30 - fedora-31: BASE_IMAGE=fedora:31 # latest - fedora-32: BASE_IMAGE=fedora:32 # rawhide + fedora: SYSTEM=fedora + fedora: BASE_IMAGE=fedora + fedora-26: BASE_TAG=26 + fedora-26: IGNORE_MISSING_SYSTEM_PACKAGES=yes + fedora-27: BASE_TAG=27 + fedora-28: BASE_TAG=28 + fedora-29: BASE_TAG=29 + fedora-30: BASE_TAG=30 + fedora-31: BASE_TAG=31 # latest + fedora-32: BASE_TAG=32 # rawhide # # https://hub.docker.com/_/centos # - centos: SYSTEM=fedora - centos: IGNORE_MISSING_SYSTEM_PACKAGES=yes - #centos-6: BASE_IMAGE=centos:centos6 # only has autoconf 2.63 -- too old for bootstrap - centos-7: BASE_IMAGE=centos:centos7 - centos-8: BASE_IMAGE=centos:centos8 + centos: SYSTEM=fedora + centos: BASE_IMAGE=centos + centos: IGNORE_MISSING_SYSTEM_PACKAGES=yes + #centos-6: BASE_TAG=centos6 # only has autoconf 2.63 -- too old for bootstrap + centos-7: BASE_TAG=centos7 + centos-8: BASE_TAG=centos8 # # https://hub.docker.com/_/archlinux/ # - archlinux: SYSTEM=arch - archlinux-latest: BASE_IMAGE=archlinux:latest + archlinux: SYSTEM=arch + archlinux: BASE_IMAGE=archlinux # # https://hub.docker.com/r/continuumio # conda: SYSTEM=conda - conda-forge: BASE_IMAGE=continuumio/miniconda3:latest + conda-forge: BASE_IMAGE=continuumio/miniconda3 conda-forge: CONDARC=condarc.yml - conda-anaconda3: BASE_IMAGE=continuumio/anaconda3:latest + conda-anaconda3: BASE_IMAGE=continuumio/anaconda3 conda-anaconda3: CONDARC=/dev/null conda-anaconda3: IGNORE_MISSING_SYSTEM_PACKAGES=yes # - # Other architectures + # Other architectures: + # + # Many docker images for another architecture are named the same, in the arch prefix. + # All work for Docker on Mac; but only i386 works for Linux Docker. + # + arm32v5: ARCH_IMAGE_PREFIX=arm32v5/ + arm32v6: ARCH_IMAGE_PREFIX=arm32v6/ + arm32v7: ARCH_IMAGE_PREFIX=arm32v7/ + arm64v8: ARCH_IMAGE_PREFIX=arm64v8/ + i386: ARCH_IMAGE_PREFIX=i386/ + ppc64le: ARCH_IMAGE_PREFIX=ppc64le/ + s390x: ARCH_IMAGE_PREFIX=s390x/ + # + # For Linux Docker, we need to work with known multiarch images. + # https://www.ecliptik.com/Cross-Building-and-Running-Multi-Arch-Docker-Images/ + # (or we would need to change our tests from "docker build" to "docker run") # - ARCH_PREFIX= - arm32v5: ARCH_PREFIX=arm32v5/ - arm32v6: ARCH_PREFIX=arm32v6/ - arm32v7: ARCH_PREFIX=arm32v7/ - arm64v8: ARCH_PREFIX=arm64v8/ - i386: ARCH_PREFIX=i386/ - ppc64le: ARCH_PREFIX=ppc64le/ - s390x: ARCH_PREFIX=s390x/ + # https://hub.docker.com/r/multiarch/ubuntu-core: + # multiarch/ubuntu-core:arm64-bionic, multiarch/ubuntu-core:armhf-bionic + ubuntu-arm64: BASE_IMAGE=ubuntu-core + ubuntu-arm64: ARCH_IMAGE_PREFIX=multiarch/ + ubuntu-arm64: ARCH_TAG_PREFIX=arm64- + ubuntu-armhf: BASE_IMAGE=ubuntu-core + ubuntu-armhf: ARCH_IMAGE_PREFIX=multiarch/ + ubuntu-armhf: ARCH_TAG_PREFIX=armhf- # - # Many docker images for another architecture are named the same, in the prefix + # Resulting full image:tag name # - docker: ARCH_BASE_IMAGE={env:ARCH_PREFIX}{env:BASE_IMAGE} + docker: FULL_BASE_IMAGE_AND_TAG={env:ARCH_IMAGE_PREFIX:}{env:BASE_IMAGE}:{env:ARCH_TAG_PREFIX:}{env:BASE_TAG} ### ### "local" envs ### @@ -145,9 +168,12 @@ whitelist_externals = docker commands = docker: bash -c 'build/bin/write-dockerfile.sh {env:SYSTEM} "{env:TYPE_PATTERN:}" {env:WITH_SYSTEM_SPKG} {env:IGNORE_MISSING_SYSTEM_PACKAGES} > {envdir}/Dockerfile' + # From https://hub.docker.com/r/multiarch/ubuntu-core/ + # configure binfmt-support on the Docker host (works locally or remotely, i.e: using boot2docker) + docker-{arm64,armhf}: docker run --rm --privileged multiarch/qemu-user-static:register --reset docker: docker build . -f {envdir}/Dockerfile \ docker: --build-arg EXTRA_CONFIGURE_ARGS="{env:EXTRA_CONFIGURE_ARGS:}" \ - docker: --build-arg BASE_IMAGE={env:ARCH_BASE_IMAGE} \ + docker: --build-arg BASE_IMAGE={env:FULL_BASE_IMAGE_AND_TAG} \ docker-conda: --build-arg USE_CONDARC="{env:CONDARC}" \ docker: {env:EXTRA_DOCKER_BUILD_ARGS:} From 2f057cb8652617283ef27737b8e6b3e970d8d7c3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 8 Feb 2020 22:28:52 -0500 Subject: [PATCH 33/77] tox.ini: Add raspbian --- tox.ini | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tox.ini b/tox.ini index 7fd961f8550..116b8c66009 100644 --- a/tox.ini +++ b/tox.ini @@ -150,6 +150,13 @@ setenv = ubuntu-armhf: ARCH_IMAGE_PREFIX=multiarch/ ubuntu-armhf: ARCH_TAG_PREFIX=armhf- # + # https://hub.docker.com/u/raspbian + # + raspbian: SYSTEM=debian + raspbian: ARCH_IMAGE_PREFIX= + raspbian-jessie: BASE_IMAGE=raspbian/jessie + raspbian-stretch: BASE_IMAGE=raspbian/stretch + # # Resulting full image:tag name # docker: FULL_BASE_IMAGE_AND_TAG={env:ARCH_IMAGE_PREFIX:}{env:BASE_IMAGE}:{env:ARCH_TAG_PREFIX:}{env:BASE_TAG} From 7f122bdda3253eeb23cef16c495491890f712959 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 1 Mar 2020 18:33:14 -0800 Subject: [PATCH 34/77] build/bin/write-dockerfile.sh: src/ext has moved and is no longer needed for the configure phase --- build/bin/write-dockerfile.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/build/bin/write-dockerfile.sh b/build/bin/write-dockerfile.sh index 6fcea1d9214..8d57e177e3d 100755 --- a/build/bin/write-dockerfile.sh +++ b/build/bin/write-dockerfile.sh @@ -138,7 +138,6 @@ ADD build ./build ADD src/bin/sage-version.sh src/bin/sage-version.sh $RUN ./bootstrap #:configuring: -ADD src/ext src/ext ADD src/bin src/bin ADD src/Makefile.in src/Makefile.in ARG EXTRA_CONFIGURE_ARGS="" From a21db2793711b9bd10127911bc9a2c432dca9947 Mon Sep 17 00:00:00 2001 From: Sebastian Oehms <=seb.oehms@gmail.com> Date: Mon, 2 Mar 2020 07:29:23 +0100 Subject: [PATCH 35/77] 29266: correction according to review --- src/sage/rings/polynomial/polynomial_element.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 6e1b77ae2ae..5d639ebf390 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -4407,7 +4407,7 @@ cdef class Polynomial(CommutativeAlgebraElement): pol_frac = PF(self) pol_frac_fact = pol_frac.factor(**kwargs) if R(pol_frac_fact.unit()).is_unit(): - # Note: :meth:`base_change` may coerce the unit to a non unit + # Note: :meth:`base_change` may convert the unit to a non unit return pol_frac_fact.base_change(self.parent()) except (TypeError, AttributeError, NotImplementedError): raise NotImplementedError From 128194eceec1620de4caf4ec7d8883ebf1c87cc9 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Mon, 2 Mar 2020 08:12:41 +0100 Subject: [PATCH 36/77] Trac 29247: put skew polynomial rings into the category of algebras --- .../rings/polynomial/skew_polynomial_ring.py | 54 +++++++++++-------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/src/sage/rings/polynomial/skew_polynomial_ring.py b/src/sage/rings/polynomial/skew_polynomial_ring.py index 24937789e5f..ecd7165c6f6 100644 --- a/src/sage/rings/polynomial/skew_polynomial_ring.py +++ b/src/sage/rings/polynomial/skew_polynomial_ring.py @@ -39,7 +39,7 @@ from sage.structure.unique_representation import UniqueRepresentation from sage.structure.element import Element from sage.rings.ring import Algebra -from sage.categories.rings import Rings +from sage.categories.algebras import Algebras from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.rings.ring import Field @@ -263,20 +263,6 @@ class SkewPolynomialRing_general(Algebra, UniqueRepresentation): sage: loads(dumps(R['x',sigma])) == R['x',sigma] True - There is a coercion map from the base ring of the skew polynomial rings:: - - sage: S.has_coerce_map_from(R) - True - sage: x.parent() - Skew Polynomial Ring in x over Univariate Polynomial Ring in t over Integer Ring - twisted by t |--> t + 1 - sage: t.parent() - Univariate Polynomial Ring in t over Integer Ring - sage: y = x+t; y - x + t - sage: y.parent() is S - True - .. SEEALSO:: :meth:`sage.rings.polynomial.skew_polynomial_ring_constructor.SkewPolynomialRing` @@ -336,6 +322,8 @@ def __init__(self, base_ring, twist_map, name, sparse, element_class): sage: R. = ZZ[] sage: sigma = R.hom([t+1]) sage: S. = SkewPolynomialRing(R,sigma) + sage: S.category() + Category of algebras over (unique factorization domains and commutative algebras over (euclidean domains and infinite enumerated sets and metric spaces) and infinite sets) sage: S([1]) + S([-1]) 0 sage: TestSuite(S).run() @@ -343,8 +331,9 @@ def __init__(self, base_ring, twist_map, name, sparse, element_class): sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: T. = k['x', Frob]; T - Skew Polynomial Ring in x over Finite Field in t of size 5^3 - twisted by t |--> t^5 + Skew Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 + sage: T.category() + Category of algebras over finite enumerated fields We skip the pickling tests currently because ``Frob`` does not pickle correctly (see note on :trac:`13215`):: @@ -355,12 +344,8 @@ def __init__(self, base_ring, twist_map, name, sparse, element_class): self._polynomial_class = element_class self._map = twist_map self._maps = {0: IdentityMorphism(base_ring), 1: self._map} - Algebra.__init__(self, base_ring, names=name, - normalize=True, category=Rings()) - base_inject = SkewPolynomialBaseringInjection(base_ring, self) - self._populate_coercion_lists_( - coerce_list = [base_inject], - convert_list = [list, base_inject]) + Algebra.__init__(self, base_ring, names=name, normalize=True, + category=Algebras(base_ring.category())) def _element_constructor_(self, a=None, check=True, construct=False, **kwds): r""" @@ -424,6 +409,29 @@ def build(check): raise TypeError("unable to coerce string") return C(self, a, check, construct=construct, **kwds) + def _coerce_map_from_base_ring(self): + """ + Return a coercion map from the base ring of ``self``. + + EXAMPLES:: + + sage: R. = ZZ[] + sage: S. = SkewPolynomialRing(R, R.hom([t + 1])) + sage: S.coerce_map_from(R) + Skew Polynomial base injection morphism: + From: Univariate Polynomial Ring in t over Integer Ring + To: Skew Polynomial Ring in x over Univariate Polynomial Ring in t over Integer Ring twisted by t |--> t + 1 + sage: x.parent() + Skew Polynomial Ring in x over Univariate Polynomial Ring in t over Integer Ring twisted by t |--> t + 1 + sage: t.parent() + Univariate Polynomial Ring in t over Integer Ring + sage: y = x + t; y + x + t + sage: y.parent() is S + True + """ + return SkewPolynomialBaseringInjection(self.base_ring(), self) + def _coerce_map_from_(self, P): r""" Check whether ``self`` has a coerce map from ``P``. From 500219a7302262b2ec53f22eccbdbca9b6f5ae8d Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Mon, 2 Mar 2020 08:17:49 +0100 Subject: [PATCH 37/77] Trac 29247: some cleaning up --- src/sage/rings/polynomial/polynomial_ring.py | 5 +---- .../rings/polynomial/skew_polynomial_ring.py | 22 +++++++------------ 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index f9230c42ba2..ce311014d39 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -302,10 +302,7 @@ def __init__(self, base_ring, name=None, sparse=False, element_class=None, categ self.__cyclopoly_cache = {} self._has_singular = False sage.algebras.algebra.Algebra.__init__(self, base_ring, names=name, normalize=True, category=category) - self._populate_coercion_lists_( - #coerce_list = [base_inject], - #convert_list = [list, base_inject], - convert_method_name = '_polynomial_') + self._populate_coercion_lists_(convert_method_name='_polynomial_') def __reduce__(self): from sage.rings.polynomial.polynomial_ring_constructor import unpickle_PolynomialRing diff --git a/src/sage/rings/polynomial/skew_polynomial_ring.py b/src/sage/rings/polynomial/skew_polynomial_ring.py index ecd7165c6f6..c557c21567d 100644 --- a/src/sage/rings/polynomial/skew_polynomial_ring.py +++ b/src/sage/rings/polynomial/skew_polynomial_ring.py @@ -477,24 +477,18 @@ def _coerce_map_from_(self, P): sage: S.coerce_map_from(S) Identity endomorphism of Skew Polynomial Ring in x over Univariate Polynomial Ring in t over Integer Ring twisted by t |--> t + 1 """ + base_ring = self.base_ring() try: - connecting = self.base_ring().coerce_map_from(P) + connecting = base_ring.coerce_map_from(P) if connecting is not None: - return self.coerce_map_from(self.base_ring()) * connecting + return self.coerce_map_from(base_ring) * connecting except TypeError: pass - try: - if isinstance(P, SkewPolynomialRing_general): - if self.__is_sparse and not P.is_sparse(): - return False - if P.variable_name() == self.variable_name(): - if (P.base_ring() is self.base_ring() - and self.base_ring() is ZZ): - if self._implementation_names == ('NTL',): - return False - return self.base_ring().has_coerce_map_from(P.base_ring()) - except AttributeError: - pass + if isinstance(P, SkewPolynomialRing_general): + if self.__is_sparse and not P.is_sparse(): + return False + if P.variable_name() == self.variable_name(): + return base_ring.has_coerce_map_from(P.base_ring()) def _repr_(self): r""" From 357fcd1f30f90c406b2fcbc4bf8433ff2faf592a Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Fri, 14 Feb 2020 11:36:06 +0100 Subject: [PATCH 38/77] set up the hypercube with both Vrep and Hrep --- src/sage/geometry/polyhedron/library.py | 34 ++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/sage/geometry/polyhedron/library.py b/src/sage/geometry/polyhedron/library.py index 1757e194e26..c2c7a26810f 100644 --- a/src/sage/geometry/polyhedron/library.py +++ b/src/sage/geometry/polyhedron/library.py @@ -86,6 +86,7 @@ from sage.combinat.permutation import Permutations from sage.groups.perm_gps.permgroup_named import AlternatingGroup from .constructor import Polyhedron +from .parent import Polyhedra from sage.graphs.digraph import DiGraph from sage.combinat.root_system.associahedron import Associahedron @@ -2792,6 +2793,13 @@ def hypercube(self, dim, intervals=None, backend=None): ... ValueError: the dimension of the hypercube must match the number of intervals + The intervals must be pairs `(a, b)` with `a < b`:: + + sage: w_cube = polytopes.hypercube(3, intervals = [[0,1],[3,2],[0,3]]) + Traceback (most recent call last): + ... + ValueError: each interval must be a pair `(a, b)` with `a < b` + If a string besides 'zero_one' is passed to ``intervals``, return an error:: @@ -2800,18 +2808,42 @@ def hypercube(self, dim, intervals=None, backend=None): ... ValueError: the only allowed string is 'zero_one' """ + parent = Polyhedra(ZZ, dim, backend=backend) + + # Preparing the inequalities: + # If the intervals are (a_1,b_1), ..., (a_dim, b_dim), + # then the inequalites correspond to + # b_1,b_2,...,b_dim, a_1,a_2,...,a_dim + # in that order. + ieqs = [[0]*(dim+1) for _ in range(2*dim)] + for i in range(dim): + ieqs[i][i+1] = -1 + ieqs[dim+i][i+1] = 1 + if intervals is None: cp = list(itertools.product([-1,1], repeat=dim)) + for i in range(dim): + ieqs[i][0] = 1 # An inequality -x_i + 1 >= 0 + ieqs[i+dim][0] = 1 # An inequality x_i + 1 >= 0 elif isinstance(intervals, str): if intervals == 'zero_one': cp = list(itertools.product([0,1], repeat=dim)) + for i in range(dim): + ieqs[i][0] = 1 # An inequality -x_i + 1 >= 0 else: raise ValueError("the only allowed string is 'zero_one'") elif len(intervals) == dim: + if not all(a < b for a,b in intervals): + raise ValueError("each interval must be a pair `(a, b)` with `a < b`") + parent = parent.base_extend(intervals) cp = list(itertools.product(*intervals)) + for i in range(dim): + ieqs[i][0] = intervals[i][1] # An inequality -x_i + b_i >= 0 + ieqs[i+dim][0] = -intervals[i][0] # An inequality x_i - a_i >= 0 + else: raise ValueError("the dimension of the hypercube must match the number of intervals") - return Polyhedron(vertices=cp, backend=backend) + return parent.element_class(parent, [cp, [], []], [ieqs, []], Vrep_minimal=True, Hrep_minimal=True ) def cube(self, intervals=None, backend=None): r""" From 91ae9baed801970849814fcf7d035204dd48686d Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Fri, 14 Feb 2020 14:58:04 +0100 Subject: [PATCH 39/77] fixed doctests fixed more doctests involving order more doctests fixed one more test a new failing doctest failing doctest --- src/sage/geometry/integral_points.pyx | 12 +-- src/sage/geometry/polyhedron/base.py | 98 ++++++++++--------- .../combinatorial_polyhedron/base.pyx | 72 +++++++------- .../face_iterator.pyx | 32 +++--- src/sage/geometry/polyhedron/face.py | 10 +- src/sage/geometry/polyhedron/library.py | 50 +++++++--- src/sage/geometry/polyhedron/plot.py | 8 +- .../geometry/polyhedron/representation.py | 18 ++-- src/sage/geometry/triangulation/element.py | 78 +++++++-------- src/sage/plot/plot3d/shapes2.py | 2 +- 10 files changed, 207 insertions(+), 173 deletions(-) diff --git a/src/sage/geometry/integral_points.pyx b/src/sage/geometry/integral_points.pyx index d11ddb67523..765b0a5bb55 100644 --- a/src/sage/geometry/integral_points.pyx +++ b/src/sage/geometry/integral_points.pyx @@ -507,19 +507,19 @@ cpdef rectangular_box_points(list box_min, list box_max, sage: cube = polytopes.cube() sage: cube.Hrepresentation(0) - An inequality (0, 0, -1) x + 1 >= 0 + An inequality (-1, 0, 0) x + 1 >= 0 sage: cube.Hrepresentation(1) An inequality (0, -1, 0) x + 1 >= 0 sage: cube.Hrepresentation(2) - An inequality (-1, 0, 0) x + 1 >= 0 + An inequality (0, 0, -1) x + 1 >= 0 sage: rectangular_box_points([0]*3, [1]*3, cube, return_saturated=True) (((0, 0, 0), frozenset()), - ((0, 0, 1), frozenset({0})), + ((0, 0, 1), frozenset({2})), ((0, 1, 0), frozenset({1})), - ((0, 1, 1), frozenset({0, 1})), - ((1, 0, 0), frozenset({2})), + ((0, 1, 1), frozenset({1, 2})), + ((1, 0, 0), frozenset({0})), ((1, 0, 1), frozenset({0, 2})), - ((1, 1, 0), frozenset({1, 2})), + ((1, 1, 0), frozenset({0, 1})), ((1, 1, 1), frozenset({0, 1, 2}))) TESTS: diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index 8f740b76212..c77287f7876 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -1430,7 +1430,7 @@ def Hrepresentation(self, index=None): sage: p = polytopes.hypercube(3) sage: p.Hrepresentation(0) - An inequality (0, 0, -1) x + 1 >= 0 + An inequality (-1, 0, 0) x + 1 >= 0 sage: p.Hrepresentation(0) == p.Hrepresentation() [0] True """ @@ -1522,7 +1522,7 @@ def Hrepresentation_str(self, separator='\n', latex=False, style='>=', align=Non sage: c = polytopes.cube() sage: c.Hrepresentation_str(separator=', ', style='positive') - '1 >= x2, 1 >= x1, 1 >= x0, x0 + 1 >= 0, x2 + 1 >= 0, x1 + 1 >= 0' + '1 >= x0, 1 >= x1, 1 >= x2, x0 + 1 >= 0, x2 + 1 >= 0, x1 + 1 >= 0' """ pretty_hs = [h.repr_pretty(split=True, latex=latex, style=style, **kwds) for h in self.Hrepresentation()] shift = any(pretty_h[2].startswith('-') for pretty_h in pretty_hs) @@ -1574,7 +1574,7 @@ def Hrep_generator(self): sage: p = polytopes.hypercube(3) sage: next(p.Hrep_generator()) - An inequality (0, 0, -1) x + 1 >= 0 + An inequality (-1, 0, 0) x + 1 >= 0 """ for H in self.Hrepresentation(): yield H @@ -1993,8 +1993,8 @@ def an_affine_basis(self): sage: P.an_affine_basis() [A vertex at (-1, -1, -1), A vertex at (1, -1, -1), - A vertex at (-1, -1, 1), - A vertex at (-1, 1, -1)] + A vertex at (1, -1, 1), + A vertex at (1, 1, -1)] sage: P = polytopes.permutahedron(5) sage: P.an_affine_basis() @@ -2804,7 +2804,7 @@ def a_maximal_chain(self): A 2-dimensional face of a Polyhedron in ZZ^3 defined as the convex hull of 4 vertices, A 3-dimensional face of a Polyhedron in ZZ^3 defined as the convex hull of 8 vertices] sage: [face.ambient_V_indices() for face in chain] - [(), (0,), (0, 4), (0, 1, 4, 5), (0, 1, 2, 3, 4, 5, 6, 7)] + [(), (5,), (0, 5), (0, 3, 4, 5), (0, 1, 2, 3, 4, 5, 6, 7)] TESTS:: @@ -3333,14 +3333,14 @@ def is_prism(self, certificate=False): True sage: P.is_prism(certificate=True) (True, - [[A vertex at (-1, -1, 1), - A vertex at (-1, 1, 1), - A vertex at (1, -1, 1), - A vertex at (1, 1, 1)], - [A vertex at (-1, -1, -1), + [[A vertex at (1, -1, -1), + A vertex at (1, 1, -1), + A vertex at (1, 1, 1), + A vertex at (1, -1, 1)], + [A vertex at (-1, -1, 1), + A vertex at (-1, -1, -1), A vertex at (-1, 1, -1), - A vertex at (1, -1, -1), - A vertex at (1, 1, -1)]]) + A vertex at (-1, 1, 1)]]) sage: Q = polytopes.cyclic_polytope(3,8) sage: Q.is_prism() False @@ -3740,13 +3740,15 @@ def triangulate(self, engine='auto', connected=True, fine=False, regular=None, s sage: triangulation = cube.triangulate( ....: engine='internal') # to make doctest independent of TOPCOM sage: triangulation - (<0,1,2,7>, <0,1,4,7>, <0,2,4,7>, <1,2,3,7>, <1,4,5,7>, <2,4,6,7>) + (<0,1,2,7>, <0,1,5,7>, <0,2,3,7>, <0,3,4,7>, <0,4,5,7>, <1,5,6,7>) sage: simplex_indices = triangulation[0]; simplex_indices (0, 1, 2, 7) sage: simplex_vertices = [ cube.Vrepresentation(i) for i in simplex_indices ] sage: simplex_vertices - [A vertex at (-1, -1, -1), A vertex at (-1, -1, 1), - A vertex at (-1, 1, -1), A vertex at (1, 1, 1)] + [A vertex at (1, -1, -1), + A vertex at (1, 1, -1), + A vertex at (1, 1, 1), + A vertex at (-1, 1, 1)] sage: Polyhedron(simplex_vertices) A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 4 vertices @@ -4860,13 +4862,13 @@ def face_truncation(self, face, linear_coefficients=None, cut_frac=None): sage: edge_trunc.f_vector() (1, 10, 15, 7, 1) sage: tuple(f.ambient_V_indices() for f in edge_trunc.faces(2)) - ((0, 4, 5, 6), - (0, 1, 6, 7), - (5, 6, 7, 8, 9), - (3, 4, 5, 9), - (1, 2, 7, 8), - (2, 3, 8, 9), - (0, 1, 2, 3, 4)) + ((0, 5, 6, 7), + (1, 4, 5, 6, 8), + (6, 7, 8, 9), + (0, 2, 3, 7, 9), + (1, 2, 8, 9), + (0, 3, 4, 5), + (1, 2, 3, 4)) sage: face_trunc = Cube.face_truncation(Cube.faces(2)[2]) sage: face_trunc.vertices() (A vertex at (1, -1, -1), @@ -5840,23 +5842,27 @@ def faces(self, face_dimension): sage: p = polytopes.hypercube(4) sage: list(f.ambient_V_indices() for f in p.faces(3)) - [(0, 2, 4, 6, 8, 10, 12, 14), - (0, 1, 4, 5, 8, 9, 12, 13), - (0, 1, 2, 3, 8, 9, 10, 11), - (0, 1, 2, 3, 4, 5, 6, 7), - (1, 3, 5, 7, 9, 11, 13, 15), - (2, 3, 6, 7, 10, 11, 14, 15), - (4, 5, 6, 7, 12, 13, 14, 15), - (8, 9, 10, 11, 12, 13, 14, 15)] + [(0, 5, 6, 7, 8, 9, 14, 15), + (1, 4, 5, 6, 10, 13, 14, 15), + (1, 2, 6, 7, 8, 10, 11, 15), + (8, 9, 10, 11, 12, 13, 14, 15), + (0, 3, 4, 5, 9, 12, 13, 14), + (0, 2, 3, 7, 8, 9, 11, 12), + (1, 2, 3, 4, 10, 11, 12, 13), + (0, 1, 2, 3, 4, 5, 6, 7)] sage: face = p.faces(3)[3] sage: face.ambient_Hrepresentation() (An inequality (1, 0, 0, 0) x + 1 >= 0,) sage: face.vertices() - (A vertex at (-1, -1, -1, -1), A vertex at (-1, -1, -1, 1), - A vertex at (-1, -1, 1, -1), A vertex at (-1, -1, 1, 1), - A vertex at (-1, 1, -1, -1), A vertex at (-1, 1, -1, 1), - A vertex at (-1, 1, 1, -1), A vertex at (-1, 1, 1, 1)) + (A vertex at (-1, -1, 1, -1), + A vertex at (-1, -1, 1, 1), + A vertex at (-1, 1, -1, -1), + A vertex at (-1, 1, 1, -1), + A vertex at (-1, 1, 1, 1), + A vertex at (-1, 1, -1, 1), + A vertex at (-1, -1, -1, 1), + A vertex at (-1, -1, -1, -1)) You can use the :meth:`~sage.geometry.polyhedron.representation.PolyhedronRepresentation.index` @@ -5866,19 +5872,19 @@ def faces(self, face_dimension): sage: [get_idx(_) for _ in face.ambient_Hrepresentation()] [4] sage: [get_idx(_) for _ in face.ambient_Vrepresentation()] - [0, 1, 2, 3, 4, 5, 6, 7] + [8, 9, 10, 11, 12, 13, 14, 15] sage: [ ([get_idx(_) for _ in face.ambient_Vrepresentation()], ....: [get_idx(_) for _ in face.ambient_Hrepresentation()]) ....: for face in p.faces(3) ] - [([0, 2, 4, 6, 8, 10, 12, 14], [7]), - ([0, 1, 4, 5, 8, 9, 12, 13], [6]), - ([0, 1, 2, 3, 8, 9, 10, 11], [5]), - ([0, 1, 2, 3, 4, 5, 6, 7], [4]), - ([1, 3, 5, 7, 9, 11, 13, 15], [3]), - ([2, 3, 6, 7, 10, 11, 14, 15], [2]), - ([4, 5, 6, 7, 12, 13, 14, 15], [1]), - ([8, 9, 10, 11, 12, 13, 14, 15], [0])] + [([0, 5, 6, 7, 8, 9, 14, 15], [7]), + ([1, 4, 5, 6, 10, 13, 14, 15], [6]), + ([1, 2, 6, 7, 8, 10, 11, 15], [5]), + ([8, 9, 10, 11, 12, 13, 14, 15], [4]), + ([0, 3, 4, 5, 9, 12, 13, 14], [3]), + ([0, 2, 3, 7, 8, 9, 11, 12], [2]), + ([1, 2, 3, 4, 10, 11, 12, 13], [1]), + ([0, 1, 2, 3, 4, 5, 6, 7], [0])] TESTS:: @@ -6498,7 +6504,7 @@ def one_point_suspension(self, vertex): It works with a polyhedral face as well:: - sage: vv = cube.faces(0)[0] + sage: vv = cube.faces(0)[1] sage: ops_cube2 = cube.one_point_suspension(vv) sage: ops_cube == ops_cube2 True @@ -6674,7 +6680,7 @@ def schlegel_projection(self, projection_dir=None, height=1.1): sage: schlegel_edge_indices = sch_proj.lines sage: schlegel_edges = [sch_proj.coordinates_of(x) for x in schlegel_edge_indices] sage: len([x for x in schlegel_edges if x[0][0] > 0]) - 4 + 5 """ proj = self.projection() if projection_dir is None: diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index 0a05a75ef40..a3d5035e770 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -35,16 +35,16 @@ Construction:: Obtaining edges and ridges:: sage: C.edges()[:2] - ((A vertex at (1, 1, 1, -1), A vertex at (1, 1, 1, 1)), - (A vertex at (1, 1, -1, 1), A vertex at (1, 1, 1, 1))) + ((A vertex at (-1, -1, -1, 1), A vertex at (-1, -1, -1, -1)), + (A vertex at (-1, 1, -1, -1), A vertex at (-1, -1, -1, -1))) sage: C.edges(names=False)[:2] - ((14, 15), (13, 15)) + ((14, 15), (10, 15)) sage: C.ridges()[:2] ((An inequality (0, 0, 1, 0) x + 1 >= 0, - An inequality (0, 0, 0, 1) x + 1 >= 0), - (An inequality (0, 1, 0, 0) x + 1 >= 0, - An inequality (0, 0, 0, 1) x + 1 >= 0)) + An inequality (0, 1, 0, 0) x + 1 >= 0), + (An inequality (0, 0, 0, 1) x + 1 >= 0, + An inequality (0, 1, 0, 0) x + 1 >= 0)) sage: C.ridges(names=False)[:2] ((6, 7), (5, 7)) @@ -817,37 +817,37 @@ cdef class CombinatorialPolyhedron(SageObject): sage: P = polytopes.cube() sage: C = CombinatorialPolyhedron(P) sage: C.facets() - ((A vertex at (-1, -1, 1), - A vertex at (-1, 1, 1), - A vertex at (1, -1, 1), - A vertex at (1, 1, 1)), - (A vertex at (-1, 1, -1), - A vertex at (-1, 1, 1), + ((A vertex at (1, -1, -1), A vertex at (1, 1, -1), - A vertex at (1, 1, 1)), - (A vertex at (1, -1, -1), + A vertex at (1, 1, 1), + A vertex at (1, -1, 1)), + (A vertex at (1, 1, -1), + A vertex at (1, 1, 1), + A vertex at (-1, 1, -1), + A vertex at (-1, 1, 1)), + (A vertex at (1, 1, 1), A vertex at (1, -1, 1), - A vertex at (1, 1, -1), - A vertex at (1, 1, 1)), - (A vertex at (-1, -1, -1), A vertex at (-1, -1, 1), - A vertex at (-1, 1, -1), A vertex at (-1, 1, 1)), - (A vertex at (-1, -1, -1), + (A vertex at (-1, -1, 1), + A vertex at (-1, -1, -1), A vertex at (-1, 1, -1), - A vertex at (1, -1, -1), - A vertex at (1, 1, -1)), - (A vertex at (-1, -1, -1), + A vertex at (-1, 1, 1)), + (A vertex at (1, -1, -1), + A vertex at (1, 1, -1), + A vertex at (-1, -1, -1), + A vertex at (-1, 1, -1)), + (A vertex at (1, -1, -1), + A vertex at (1, -1, 1), A vertex at (-1, -1, 1), - A vertex at (1, -1, -1), - A vertex at (1, -1, 1))) + A vertex at (-1, -1, -1))) sage: C.facets(names=False) - ((1, 3, 5, 7), - (2, 3, 6, 7), + ((0, 1, 2, 3), + (1, 2, 6, 7), + (2, 3, 4, 7), (4, 5, 6, 7), - (0, 1, 2, 3), - (0, 2, 4, 6), - (0, 1, 4, 5)) + (0, 1, 5, 6), + (0, 3, 4, 5)) """ if unlikely(self.dimension() == 0): # Special attention for this trivial case. @@ -889,14 +889,14 @@ cdef class CombinatorialPolyhedron(SageObject): sage: P = polytopes.cube() sage: C = P.combinatorial_polyhedron() sage: C.incidence_matrix() + [1 0 0 0 1 1] + [1 1 0 0 1 0] + [1 1 1 0 0 0] + [1 0 1 0 0 1] + [0 0 1 1 0 1] [0 0 0 1 1 1] - [1 0 0 1 0 1] [0 1 0 1 1 0] - [1 1 0 1 0 0] - [0 0 1 0 1 1] - [1 0 1 0 0 1] - [0 1 1 0 1 0] - [1 1 1 0 0 0] + [0 1 1 1 0 0] sage: P.incidence_matrix() == C.incidence_matrix() True @@ -2010,7 +2010,7 @@ cdef class CombinatorialPolyhedron(SageObject): A 2-dimensional face of a 4-dimensional combinatorial polyhedron, A 3-dimensional face of a 4-dimensional combinatorial polyhedron] sage: [face.ambient_V_indices() for face in chain] - [(0,), (0, 8), (0, 4, 8, 12), (0, 2, 4, 6, 8, 10, 12, 14)] + [(15,), (6, 15), (5, 6, 14, 15), (0, 5, 6, 7, 8, 9, 14, 15)] sage: P = polytopes.permutahedron(4) sage: C = P.combinatorial_polyhedron() diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx index 006c21cdd37..b8cb2a107de 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx @@ -258,13 +258,13 @@ cdef class FaceIterator(SageObject): (1,), (0,), (3, 4), - (2, 4), (1, 4), + (0, 4), (1, 3, 4), - (1, 2, 4), + (0, 1, 4), + (2, 3), (1, 3), - (0, 3), - (0, 1, 3), + (1, 2, 3), (1, 2), (0, 2), (0, 1, 2), @@ -294,22 +294,22 @@ cdef class FaceIterator(SageObject): (1,), (0,), (6, 7), - (5, 7), - (3, 7), + (4, 7), + (2, 7), (4, 5, 6, 7), - (2, 3, 6, 7), - (1, 3, 5, 7), - (4, 6), - (2, 6), - (0, 2, 4, 6), + (1, 2, 6, 7), + (2, 3, 4, 7), + (5, 6), + (1, 6), + (0, 1, 5, 6), (4, 5), - (1, 5), - (0, 1, 4, 5), - (0, 4), + (0, 5), + (0, 3, 4, 5), + (3, 4), (2, 3), - (1, 3), + (0, 3), (0, 1, 2, 3), - (0, 2), + (1, 2), (0, 1)] sage: it = C.face_iter(dual=False) diff --git a/src/sage/geometry/polyhedron/face.py b/src/sage/geometry/polyhedron/face.py index 9fd32385604..e6ded6c1e4e 100644 --- a/src/sage/geometry/polyhedron/face.py +++ b/src/sage/geometry/polyhedron/face.py @@ -535,12 +535,12 @@ def ambient_V_indices(self): sage: P = polytopes.cube() sage: F = P.faces(2) sage: [f.ambient_V_indices() for f in F] - [(0, 1, 4, 5), - (0, 2, 4, 6), - (0, 1, 2, 3), + [(0, 3, 4, 5), + (0, 1, 5, 6), (4, 5, 6, 7), - (2, 3, 6, 7), - (1, 3, 5, 7)] + (2, 3, 4, 7), + (1, 2, 6, 7), + (0, 1, 2, 3)] """ return self._ambient_Vrepresentation_indices diff --git a/src/sage/geometry/polyhedron/library.py b/src/sage/geometry/polyhedron/library.py index c2c7a26810f..d6b0d20bac7 100644 --- a/src/sage/geometry/polyhedron/library.py +++ b/src/sage/geometry/polyhedron/library.py @@ -2760,7 +2760,7 @@ def hypercube(self, dim, intervals=None, backend=None): sage: z_cube = polytopes.hypercube(4,intervals = 'zero_one') sage: z_cube.vertices()[0] - A vertex at (0, 0, 0, 0) + A vertex at (1, 0, 1, 1) sage: z_cube.is_simple() True sage: z_cube.base_ring() @@ -2807,8 +2807,29 @@ def hypercube(self, dim, intervals=None, backend=None): Traceback (most recent call last): ... ValueError: the only allowed string is 'zero_one' + + Check that we set up the hypercube correctly:: + + sage: ls = [randint(-100,100) for _ in range(4)] + sage: intervals = [[x, x+randint(1,50)] for x in ls] + sage: ls = [randint(-100,100) for _ in range(4)] + sage: intervals = [[x, x+randint(1,50)] for x in ls] + sage: P = polytopes.hypercube(4, intervals, backend='field') + sage: P1 = polytopes.hypercube(4, intervals, backend='ppl') + sage: assert P == P1 + + Check that coercion for input invervals is handled correctly:: + + sage: P = polytopes.hypercube(2, [[1/2, 2], [0, 1]]) + sage: P = polytopes.hypercube(2, [[1/2, 2], [0, 1.0]]) + sage: P = polytopes.hypercube(2, [[1/2, 2], [0, AA(2).sqrt()]]) + sage: P = polytopes.hypercube(2, [[1/2, 2], [0, 1.0]], backend='ppl') + Traceback (most recent call last): + ... + ValueError: specified backend ppl cannot handle the intervals """ parent = Polyhedra(ZZ, dim, backend=backend) + convert = False # Preparing the inequalities: # If the intervals are (a_1,b_1), ..., (a_dim, b_dim), @@ -2835,7 +2856,14 @@ def hypercube(self, dim, intervals=None, backend=None): elif len(intervals) == dim: if not all(a < b for a,b in intervals): raise ValueError("each interval must be a pair `(a, b)` with `a < b`") - parent = parent.base_extend(intervals) + parent = parent.base_extend(sum(a + b for a,b in intervals)) + if parent.base_ring() not in (ZZ, QQ): + convert = True + if backend and parent.backend() is not backend: + # If the parent changed backends, but a backend was specified, + # the specified backend cannot handle the intervals. + raise ValueError("specified backend {} cannot handle the intervals".format(backend)) + cp = list(itertools.product(*intervals)) for i in range(dim): ieqs[i][0] = intervals[i][1] # An inequality -x_i + b_i >= 0 @@ -2843,7 +2871,7 @@ def hypercube(self, dim, intervals=None, backend=None): else: raise ValueError("the dimension of the hypercube must match the number of intervals") - return parent.element_class(parent, [cp, [], []], [ieqs, []], Vrep_minimal=True, Hrep_minimal=True ) + return parent([cp, [], []], [ieqs, []], convert=convert, Vrep_minimal=True, Hrep_minimal=True ) def cube(self, intervals=None, backend=None): r""" @@ -2894,14 +2922,14 @@ def cube(self, intervals=None, backend=None): sage: cc = polytopes.cube(intervals ='zero_one') sage: cc.vertices_list() - [[0, 0, 0], - [0, 0, 1], - [0, 1, 0], - [0, 1, 1], - [1, 0, 0], - [1, 0, 1], - [1, 1, 0], - [1, 1, 1]] + [[1, 0, 0], + [1, 1, 0], + [1, 1, 1], + [1, 0, 1], + [0, 0, 1], + [0, 0, 0], + [0, 1, 0], + [0, 1, 1]] """ return self.hypercube(3, backend=backend, intervals=intervals) diff --git a/src/sage/geometry/polyhedron/plot.py b/src/sage/geometry/polyhedron/plot.py index a1235f0861a..dc8ccf3fd4e 100644 --- a/src/sage/geometry/polyhedron/plot.py +++ b/src/sage/geometry/polyhedron/plot.py @@ -152,7 +152,7 @@ class ProjectionFuncStereographic(): sage: cube = polytopes.hypercube(3).vertices() sage: proj = ProjectionFuncStereographic([1.2, 3.4, 5.6]) sage: ppoints = [proj(vector(x)) for x in cube] - sage: ppoints[0] + sage: ppoints[5] (-0.0486511..., 0.0859565...) """ def __init__(self, projection_point): @@ -500,7 +500,7 @@ def coord_index_of(self, v): sage: p = polytopes.hypercube(3) sage: proj = p.projection() sage: proj.coord_index_of(vector((1,1,1))) - 7 + 2 """ try: return self.coords.index(v) @@ -518,7 +518,7 @@ def coord_indices_of(self, v_list): sage: p = polytopes.hypercube(3) sage: proj = p.projection() sage: proj.coord_indices_of([vector((1,1,1)),vector((1,-1,1))]) - [7, 5] + [2, 3] """ return [self.coord_index_of(v) for v in v_list] @@ -928,7 +928,7 @@ def render_wireframe_3d(self, **kwds): sage: cube_proj = cube.projection() sage: wire = cube_proj.render_wireframe_3d() sage: print(wire.tachyon().split('\n')[77]) # for testing - FCylinder base -1.0 1.0 -1.0 apex -1.0 -1.0 -1.0 rad 0.005 texture... + FCylinder base 1.0 1.0 -1.0 apex 1.0 1.0 1.0 rad 0.005 texture... """ wireframe = [] for l in self.lines: diff --git a/src/sage/geometry/polyhedron/representation.py b/src/sage/geometry/polyhedron/representation.py index 8d29c4fac62..502a558afcb 100644 --- a/src/sage/geometry/polyhedron/representation.py +++ b/src/sage/geometry/polyhedron/representation.py @@ -182,7 +182,7 @@ def vector(self, base_ring=None): sage: C = polytopes.cube() sage: C.vertices()[0].vector()[0] = 3 sage: C.vertices()[0] - A vertex at (-1, -1, -1) + A vertex at (1, -1, -1) """ if (base_ring is None) or (base_ring is self._base_ring): return copy(self._vector) @@ -429,7 +429,7 @@ def A(self): sage: C = polytopes.cube() sage: C.inequalities()[0].A()[2] = 5 sage: C.inequalities()[0] - An inequality (0, 0, -1) x + 1 >= 0 + An inequality (-1, 0, 0) x + 1 >= 0 """ return copy(self._A) @@ -1105,12 +1105,12 @@ def is_incident(self, Hobj): sage: p = polytopes.hypercube(3) sage: h1 = next(p.inequality_generator()) sage: h1 - An inequality (0, 0, -1) x + 1 >= 0 + An inequality (-1, 0, 0) x + 1 >= 0 sage: v1 = next(p.vertex_generator()) sage: v1 - A vertex at (-1, -1, -1) + A vertex at (1, -1, -1) sage: v1.is_incident(h1) - False + True """ return self.polyhedron().incidence_matrix()[self.index(), Hobj.index()] == 1 @@ -1124,7 +1124,7 @@ def __mul__(self, Hobj): sage: h1 = next(p.inequality_generator()) sage: v1 = next(p.vertex_generator()) sage: v1.__mul__(h1) - 2 + 0 """ return self.evaluated_on(Hobj) @@ -1252,11 +1252,11 @@ def evaluated_on(self, Hobj): sage: v = next(p.vertex_generator()) sage: h = next(p.inequality_generator()) sage: v - A vertex at (-1, -1, -1) + A vertex at (1, -1, -1) sage: h - An inequality (0, 0, -1) x + 1 >= 0 + An inequality (-1, 0, 0) x + 1 >= 0 sage: v.evaluated_on(h) - 2 + 0 """ return Hobj.A() * self.vector() + Hobj.b() diff --git a/src/sage/geometry/triangulation/element.py b/src/sage/geometry/triangulation/element.py index a80d9111e4d..6f8222d07c2 100644 --- a/src/sage/geometry/triangulation/element.py +++ b/src/sage/geometry/triangulation/element.py @@ -614,23 +614,23 @@ def _boundary_simplex_dictionary(self): sage: triangulation = polytopes.cube().triangulate(engine='internal') sage: triangulation._boundary_simplex_dictionary() {(0, 1, 2): ((0, 1, 2, 7),), - (0, 1, 4): ((0, 1, 4, 7),), - (0, 1, 7): ((0, 1, 2, 7), (0, 1, 4, 7)), - (0, 2, 4): ((0, 2, 4, 7),), - (0, 2, 7): ((0, 1, 2, 7), (0, 2, 4, 7)), - (0, 4, 7): ((0, 1, 4, 7), (0, 2, 4, 7)), - (1, 2, 3): ((1, 2, 3, 7),), - (1, 2, 7): ((0, 1, 2, 7), (1, 2, 3, 7)), - (1, 3, 7): ((1, 2, 3, 7),), - (1, 4, 5): ((1, 4, 5, 7),), - (1, 4, 7): ((0, 1, 4, 7), (1, 4, 5, 7)), - (1, 5, 7): ((1, 4, 5, 7),), - (2, 3, 7): ((1, 2, 3, 7),), - (2, 4, 6): ((2, 4, 6, 7),), - (2, 4, 7): ((0, 2, 4, 7), (2, 4, 6, 7)), - (2, 6, 7): ((2, 4, 6, 7),), - (4, 5, 7): ((1, 4, 5, 7),), - (4, 6, 7): ((2, 4, 6, 7),)} + (0, 1, 5): ((0, 1, 5, 7),), + (0, 1, 7): ((0, 1, 2, 7), (0, 1, 5, 7)), + (0, 2, 3): ((0, 2, 3, 7),), + (0, 2, 7): ((0, 1, 2, 7), (0, 2, 3, 7)), + (0, 3, 4): ((0, 3, 4, 7),), + (0, 3, 7): ((0, 2, 3, 7), (0, 3, 4, 7)), + (0, 4, 5): ((0, 4, 5, 7),), + (0, 4, 7): ((0, 3, 4, 7), (0, 4, 5, 7)), + (0, 5, 7): ((0, 1, 5, 7), (0, 4, 5, 7)), + (1, 2, 7): ((0, 1, 2, 7),), + (1, 5, 6): ((1, 5, 6, 7),), + (1, 5, 7): ((0, 1, 5, 7), (1, 5, 6, 7)), + (1, 6, 7): ((1, 5, 6, 7),), + (2, 3, 7): ((0, 2, 3, 7),), + (3, 4, 7): ((0, 3, 4, 7),), + (4, 5, 7): ((0, 4, 5, 7),), + (5, 6, 7): ((1, 5, 6, 7),)} """ result = dict() for simplex in self: @@ -655,22 +655,22 @@ def boundary(self): sage: triangulation = polytopes.cube().triangulate(engine='internal') sage: triangulation - (<0,1,2,7>, <0,1,4,7>, <0,2,4,7>, <1,2,3,7>, <1,4,5,7>, <2,4,6,7>) + (<0,1,2,7>, <0,1,5,7>, <0,2,3,7>, <0,3,4,7>, <0,4,5,7>, <1,5,6,7>) sage: triangulation.boundary() frozenset({(0, 1, 2), - (0, 1, 4), - (0, 2, 4), - (1, 2, 3), - (1, 3, 7), - (1, 4, 5), - (1, 5, 7), + (0, 1, 5), + (0, 2, 3), + (0, 3, 4), + (0, 4, 5), + (1, 2, 7), + (1, 5, 6), + (1, 6, 7), (2, 3, 7), - (2, 4, 6), - (2, 6, 7), + (3, 4, 7), (4, 5, 7), - (4, 6, 7)}) + (5, 6, 7)}) sage: triangulation.interior_facets() - frozenset({(0, 1, 7), (0, 2, 7), (0, 4, 7), (1, 2, 7), (1, 4, 7), (2, 4, 7)}) + frozenset({(0, 1, 7), (0, 2, 7), (0, 3, 7), (0, 4, 7), (0, 5, 7), (1, 5, 7)}) """ return frozenset(facet for facet, bounded_simplices in iteritems(self._boundary_simplex_dictionary()) @@ -691,22 +691,22 @@ def interior_facets(self): sage: triangulation = polytopes.cube().triangulate(engine='internal') sage: triangulation - (<0,1,2,7>, <0,1,4,7>, <0,2,4,7>, <1,2,3,7>, <1,4,5,7>, <2,4,6,7>) + (<0,1,2,7>, <0,1,5,7>, <0,2,3,7>, <0,3,4,7>, <0,4,5,7>, <1,5,6,7>) sage: triangulation.boundary() frozenset({(0, 1, 2), - (0, 1, 4), - (0, 2, 4), - (1, 2, 3), - (1, 3, 7), - (1, 4, 5), - (1, 5, 7), + (0, 1, 5), + (0, 2, 3), + (0, 3, 4), + (0, 4, 5), + (1, 2, 7), + (1, 5, 6), + (1, 6, 7), (2, 3, 7), - (2, 4, 6), - (2, 6, 7), + (3, 4, 7), (4, 5, 7), - (4, 6, 7)}) + (5, 6, 7)}) sage: triangulation.interior_facets() - frozenset({(0, 1, 7), (0, 2, 7), (0, 4, 7), (1, 2, 7), (1, 4, 7), (2, 4, 7)}) + frozenset({(0, 1, 7), (0, 2, 7), (0, 3, 7), (0, 4, 7), (0, 5, 7), (1, 5, 7)}) """ return frozenset(facet for facet, bounded_simplices in iteritems(self._boundary_simplex_dictionary()) diff --git a/src/sage/plot/plot3d/shapes2.py b/src/sage/plot/plot3d/shapes2.py index b4e9b287baa..1782a434039 100644 --- a/src/sage/plot/plot3d/shapes2.py +++ b/src/sage/plot/plot3d/shapes2.py @@ -1125,7 +1125,7 @@ def point3d(v, size=5, **kwds): sage: c = polytopes.hypercube(3) sage: v = c.vertices()[0]; v - A vertex at (-1, -1, -1) + A vertex at (1, -1, -1) sage: print(point(v)) Graphics3d Object From 39872bcb1754dfa2f45e2ed075ebaa154f89df84 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Mon, 2 Mar 2020 13:42:23 +0100 Subject: [PATCH 40/77] 29268: upgrade dateutil 2.5.3 -> 2.8.1 --- build/pkgs/dateutil/checksums.ini | 6 +++--- build/pkgs/dateutil/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/dateutil/checksums.ini b/build/pkgs/dateutil/checksums.ini index 47c234fc011..e08ee4550d4 100644 --- a/build/pkgs/dateutil/checksums.ini +++ b/build/pkgs/dateutil/checksums.ini @@ -1,4 +1,4 @@ tarball=python-dateutil-VERSION.tar.gz -sha1=a53ebfeecc784ea5781ba504ddf7f4ad13738213 -md5=05ffc6d2cc85a7fd93bb245807f715ef -cksum=1879066915 +sha1=bd26127e57f83a10f656b62c46524c15aeb844dd +md5=f2a1d4b680b297b367a974664ca3a4f6 +cksum=675236266 diff --git a/build/pkgs/dateutil/package-version.txt b/build/pkgs/dateutil/package-version.txt index aedc15bb0c6..dbe59006547 100644 --- a/build/pkgs/dateutil/package-version.txt +++ b/build/pkgs/dateutil/package-version.txt @@ -1 +1 @@ -2.5.3 +2.8.1 From f80864439702ea6913241647c75b1502a1a522c0 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Mon, 2 Mar 2020 13:47:58 +0100 Subject: [PATCH 41/77] 29268: upgrade pyzmq 18.1.0 -> 19.0.0 --- build/pkgs/pyzmq/checksums.ini | 6 +++--- build/pkgs/pyzmq/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/pyzmq/checksums.ini b/build/pkgs/pyzmq/checksums.ini index 07d4c095b56..6e834f7ac78 100644 --- a/build/pkgs/pyzmq/checksums.ini +++ b/build/pkgs/pyzmq/checksums.ini @@ -1,4 +1,4 @@ tarball=pyzmq-VERSION.tar.gz -sha1=64799b73d6109fb6da5b7deb6101ba13cd7fe885 -md5=3c8039d007bbbd08a2275f52f5dc9a35 -cksum=1455168757 +sha1=b84077344ed67649f34d4af8f619d96acbd03e73 +md5=4650e45ebcf8e08620211c0e720d6066 +cksum=2135729608 diff --git a/build/pkgs/pyzmq/package-version.txt b/build/pkgs/pyzmq/package-version.txt index d4df1049f25..49e3587fb62 100644 --- a/build/pkgs/pyzmq/package-version.txt +++ b/build/pkgs/pyzmq/package-version.txt @@ -1 +1 @@ -18.1.0 +19.0.0 From 5578065cfe0b15b5596298d48f0e9b187d2faf48 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Mon, 2 Mar 2020 13:52:02 +0100 Subject: [PATCH 42/77] 29268: upgrade traitlets 4.3.2 -> 4.3.3 --- build/pkgs/traitlets/checksums.ini | 6 +++--- build/pkgs/traitlets/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/traitlets/checksums.ini b/build/pkgs/traitlets/checksums.ini index 3f00b9ccfae..dacc612f744 100644 --- a/build/pkgs/traitlets/checksums.ini +++ b/build/pkgs/traitlets/checksums.ini @@ -1,4 +1,4 @@ tarball=traitlets-VERSION.tar.gz -sha1=5f87b54cc7888b20e1c1c15e052a8c89f23879ea -md5=3068663f2f38fd939a9eb3a500ccc154 -cksum=3471003302 +sha1=1bfff63fcf608ae57202774015b7448e85f650b6 +md5=3a4f263af65d3d79f1c279f0247077ef +cksum=3794332761 diff --git a/build/pkgs/traitlets/package-version.txt b/build/pkgs/traitlets/package-version.txt index cc2fbe89b6c..e91d9be2a86 100644 --- a/build/pkgs/traitlets/package-version.txt +++ b/build/pkgs/traitlets/package-version.txt @@ -1 +1 @@ -4.3.2 +4.3.3 From 96efb1d5d7d69f233457491d467e3695b058d089 Mon Sep 17 00:00:00 2001 From: vipul79321 Date: Mon, 2 Mar 2020 19:32:26 +0530 Subject: [PATCH 43/77] method updated --- src/sage/graphs/generators/families.py | 81 ++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/src/sage/graphs/generators/families.py b/src/sage/graphs/generators/families.py index efae284a634..0cfd3948dd7 100644 --- a/src/sage/graphs/generators/families.py +++ b/src/sage/graphs/generators/families.py @@ -3589,3 +3589,84 @@ def MuzychukS6Graph(n, d, Phi='fixed', Sigma='fixed', verbose=False): if verbose: print('finished at %f (+%f)' % ((time() - t), time() - t1)) return V + +def CubeConnectedCycle(d): + r""" + Returns the cube-connected cycle of dimension `d`. + + The cube-connected cycle of order `d` is the `d`-dimensional hypercube + with each of its vertices replaced by a cycle of length `d`. This graph has + order `d \times 2^d`. + The construction is as follows: + Construct vertex `(x,y)` for `0 <= x < 2^d`, `0 <= y < d`. + For each vertex, `(x,y)`, add an edge between it and `(x, (y-1) \mod d))`, + `(x,(y+1) \mod d)`, and `(x \oplus 2^y, y)`, where `\oplus` is the bitwise + xor operator. + + For `d=1` and `2`, the cube-connected cycle graph contains self-loops or + multiple edges between a pair of vertices, but for all other `d`, it is + simple. + + INPUT: + + - ``d`` -- The dimension of the desired hypercube as well as the length + of the cycle to be placed at each vertex of the `d`-dimensional + hypercube. `d` must be a positive integer. + + EXAMPLES: + + The order of the graph is `d \times 2^d` :: + + sage: d = 10 + sage: g = graphs.CubeConnectedCycle(d) + sage: len(g) == d*2**d + True + + The diameter of cube-connected cycles for `d > 3` is + `2d + \lfloor \frac{d}{2} \rfloor - 2` :: + sage: d = 9 + sage: g = graphs.CubeConnectedCycle(d) + sage: g.diameter() == 2*d+d//2-2 + True + + All vertices have degree `3` when `d > 1` :: + + sage: g = graphs.CubeConnectedCycle(12) + sage: all(g.degree(v) == 3 for v in g) + True + + TEST:: + + sage: g = graphs.CubeConnectedCycle(0) + Traceback (most recent call last): + ... + ValueError: d must be greater than 0. + """ + if d<1: + raise ValueError('d must be greater than 0.') + + G = Graph(name="Cube-Connected Cycle of dimension {}".format(d)) + + if d == 1: + G.allow_loops(True) + #only d = 1 requires loops + G.add_edges([((0,0),(0,1)), ((0,0),(0,0)), ((0,1),(0,1))]) + return G + + if d == 2: + #only d = 2 require multiple edges + #G.allow_multiple_edges(True) + for x in range(1<= 3: + for x in range(1< Date: Mon, 10 Feb 2020 11:22:28 +0530 Subject: [PATCH 44/77] Diagonal matrix function done --- src/sage/matrix/matrix_space.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 65cb888675e..e8f2208e306 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -1582,6 +1582,22 @@ def identity_matrix(self): one = identity_matrix + def diagonal_matrix(diag_elements): + """ Docstring needs to be filled. """ + + if self.__nrows != self.__ncols: + raise TypeError("Diagonal matrix must be square") + elif self.dims()[0] != len(diag_elements): + raise TypeError("Number of elements in the list does not match number of elements on a diagonal of a matrix in this space") + else: + element_list = [0 for i in range(self.dims()[0]**2)] + index = 0 + for i in diag_elements: + element_list[index] = i + index = index + self.dims()[0] + 1 + + return self.matrix(element_list) + def is_dense(self): """ Return whether matrices in ``self`` are dense. From b132688132636c8804bc6130ceaf94d2874e0f14 Mon Sep 17 00:00:00 2001 From: Mahathi Vempati Date: Mon, 10 Feb 2020 15:51:00 +0530 Subject: [PATCH 45/77] Documentation for diagonal matrix done --- src/sage/matrix/matrix_space.py | 54 +++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index e8f2208e306..4c5946e598d 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -1582,13 +1582,61 @@ def identity_matrix(self): one = identity_matrix - def diagonal_matrix(diag_elements): - """ Docstring needs to be filled. """ + def diagonal_matrix(self, diag_elements): + """ + Return a diagonal matrix in ``self`` containing the elements specified in the list. + + EXAMPLES:: + + sage: MS1 = MatrixSpace(ZZ,4) + sage: MS2 = MatrixSpace(QQ,3,4) + sage: D1 = MS1.diagonal_matrix([1, 2, 3, 4]) + sage: D1 + [1 0 0 0] + [0 2 0 0] + [0 0 3 0] + [0 0 0 4] + sage: Er = MS2.diagonal_matrix([1, 2, 3]) + Traceback (most recent call last): + ... + TypeError: Diagonal matrix must be square + + TESTS:: + + sage: MS1.diagonal_matrix([1, 2, 3]) + Traceback (most recent call last): + ... + TypeError: Number of elements in the list does not match number of elements on a diagonal of a matrix in this space + + Coercion of types works the same as the ``matrix()`` function:: + + sage: D2 = MS1.diagonal_matrix([1.0, 2.0, 3.0, 4.0]) + sage: D2 + [1 0 0 0] + [0 2 0 0] + [0 0 3 0] + [0 0 0 4] + + sage: D3 = MS1.diagonal_matrix([1.2, 3.4, 5, 6]) + Traceback (most recent call last): + ... + TypeError: Attempt to coerce non-integral RealNumber to Integer + + Returned matrix is mutable :: + sage: D1[1,2] = 10 + sage: D1 + [ 1 0 0 0] + [ 0 2 10 0] + [ 0 0 3 0] + [ 0 0 0 4] + + """ + if self.__nrows != self.__ncols: raise TypeError("Diagonal matrix must be square") elif self.dims()[0] != len(diag_elements): - raise TypeError("Number of elements in the list does not match number of elements on a diagonal of a matrix in this space") + raise TypeError("Number of elements in the list does not match number of elements on a diagonal of a matrix in this matrix space") else: element_list = [0 for i in range(self.dims()[0]**2)] index = 0 From f56aee3656b3eb92e10a972b7690a1e0bedb36d8 Mon Sep 17 00:00:00 2001 From: Mahathi Vempati Date: Mon, 10 Feb 2020 16:26:45 +0530 Subject: [PATCH 46/77] Pointed ms.diagonal_matrix() to the diagonal_matrix() implementation --- src/sage/matrix/matrix_space.py | 63 ++------------------------------- 1 file changed, 3 insertions(+), 60 deletions(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 4c5946e598d..9e998dcaa7c 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -1582,69 +1582,12 @@ def identity_matrix(self): one = identity_matrix - def diagonal_matrix(self, diag_elements): + def diagonal_matrix(self, entries): """ Return a diagonal matrix in ``self`` containing the elements specified in the list. - - EXAMPLES:: - - sage: MS1 = MatrixSpace(ZZ,4) - sage: MS2 = MatrixSpace(QQ,3,4) - sage: D1 = MS1.diagonal_matrix([1, 2, 3, 4]) - sage: D1 - [1 0 0 0] - [0 2 0 0] - [0 0 3 0] - [0 0 0 4] - sage: Er = MS2.diagonal_matrix([1, 2, 3]) - Traceback (most recent call last): - ... - TypeError: Diagonal matrix must be square - - TESTS:: - - sage: MS1.diagonal_matrix([1, 2, 3]) - Traceback (most recent call last): - ... - TypeError: Number of elements in the list does not match number of elements on a diagonal of a matrix in this space - - Coercion of types works the same as the ``matrix()`` function:: - - sage: D2 = MS1.diagonal_matrix([1.0, 2.0, 3.0, 4.0]) - sage: D2 - [1 0 0 0] - [0 2 0 0] - [0 0 3 0] - [0 0 0 4] - - sage: D3 = MS1.diagonal_matrix([1.2, 3.4, 5, 6]) - Traceback (most recent call last): - ... - TypeError: Attempt to coerce non-integral RealNumber to Integer - - Returned matrix is mutable :: - sage: D1[1,2] = 10 - sage: D1 - [ 1 0 0 0] - [ 0 2 10 0] - [ 0 0 3 0] - [ 0 0 0 4] - + Calls the function sage.matrix.special.diagonal_matrix() with the right arguments. """ - - - if self.__nrows != self.__ncols: - raise TypeError("Diagonal matrix must be square") - elif self.dims()[0] != len(diag_elements): - raise TypeError("Number of elements in the list does not match number of elements on a diagonal of a matrix in this matrix space") - else: - element_list = [0 for i in range(self.dims()[0]**2)] - index = 0 - for i in diag_elements: - element_list[index] = i - index = index + self.dims()[0] + 1 - - return self.matrix(element_list) + return sage.matrix.special.diagonal_matrix(self.base_ring(), self.dims()[0], entries) def is_dense(self): """ From 54620b2083ef8f03638af156ff309f7802b687d7 Mon Sep 17 00:00:00 2001 From: SagnikDey92 Date: Wed, 26 Feb 2020 09:38:09 +0000 Subject: [PATCH 47/77] Added non square matrix error and some documentation. Made diagonal matrix returned immutable --- src/sage/matrix/matrix_space.py | 36 ++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 9e998dcaa7c..8e23b483c00 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -1585,9 +1585,43 @@ def identity_matrix(self): def diagonal_matrix(self, entries): """ Return a diagonal matrix in ``self`` containing the elements specified in the list. + + ``self`` must be a space of square + matrices. The returned matrix is immutable. Please use ``copy`` if + you want a modified copy. + Calls the function sage.matrix.special.diagonal_matrix() with the right arguments. + + EXAMPLES:: + + sage: MS1 = MatrixSpace(ZZ,4) + sage: MS2 = MatrixSpace(QQ,3,4) + sage: I = MS1.diagonal_matrix([1, 2, 3, 4]) + sage: I + [1 0 0 0] + [0 2 0 0] + [0 0 3 0] + [0 0 0 4] + sage: Er = MS2.diagonal_matrix([1, 2]) + Traceback (most recent call last): + ... + TypeError: diagonal matrix must be square + + TESTS:: + + sage: MS1.diag([1, 2, 3, 4])[1,2] = 3 + Traceback (most recent call last): + ... + ValueError: matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M). + """ - return sage.matrix.special.diagonal_matrix(self.base_ring(), self.dims()[0], entries) + if self.__nrows != self.__ncols: + raise TypeError("diagonal matrix must be square") + A = sage.matrix.special.diagonal_matrix(self.base_ring(), self.dims()[0], entries) + A.set_immutable() + return A + + diag = diagonal_matrix def is_dense(self): """ From 5c2a5b2840bc04eb5d59a09c72eec5c5d6826493 Mon Sep 17 00:00:00 2001 From: SagnikDey92 Date: Thu, 27 Feb 2020 09:40:00 +0000 Subject: [PATCH 48/77] Modeled diagonal_matrix on identity_matrix. Changed the documentation accordingly. No longer uses the function in special.py. --- src/sage/matrix/matrix_space.py | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 8e23b483c00..abfaa07c021 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -1586,12 +1586,12 @@ def diagonal_matrix(self, entries): """ Return a diagonal matrix in ``self`` containing the elements specified in the list. - ``self`` must be a space of square - matrices. The returned matrix is immutable. Please use ``copy`` if + ``self`` must be a space of square matrices. Length of ``entries`` must be less + than or equal to matrix dimensions.If length of ``entries`` is less than matrix + dimensions, ``entries`` is padded with zeroes at the end. + The returned matrix is immutable. Please use ``copy`` if you want a modified copy. - Calls the function sage.matrix.special.diagonal_matrix() with the right arguments. - EXAMPLES:: sage: MS1 = MatrixSpace(ZZ,4) @@ -1606,18 +1606,36 @@ def diagonal_matrix(self, entries): Traceback (most recent call last): ... TypeError: diagonal matrix must be square + sage: Er = MS1.diagonal_matrix([1, 2, 3, 4, 5]) + Traceback (most recent call last): + ... + TypeError: number of diagonal matrix entries (5) exceeds the matrix size (4) TESTS:: sage: MS1.diag([1, 2, 3, 4])[1,2] = 3 Traceback (most recent call last): ... - ValueError: matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M). + ValueError: matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M). + + Check different implementations:: + + sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') + sage: M2 = MatrixSpace(ZZ, 2, implementation='generic') + + sage: type(M1.diagonal_matrix([1, 2])) + + sage: type(M2.diagonal_matrix([1, 2])) + """ if self.__nrows != self.__ncols: raise TypeError("diagonal matrix must be square") - A = sage.matrix.special.diagonal_matrix(self.base_ring(), self.dims()[0], entries) + if self.__nrows < len(entries): + raise ValueError('number of diagonal matrix entries (%s) exceeds the matrix size (%s)' % (len(entries), self.__nrows)) + A = self.zero_matrix().__copy__() + for i in range(len(entries)): + A[i, i] = entries[i] A.set_immutable() return A From 14c422a92d7a7d0b49ce0fa6e32c9875c72e26f1 Mon Sep 17 00:00:00 2001 From: SagnikDey92 Date: Fri, 28 Feb 2020 05:32:36 +0000 Subject: [PATCH 49/77] Removed immutability of diagonal matrix and edited documentation appropriately --- src/sage/matrix/matrix_space.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index abfaa07c021..ad7a53135a8 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -1588,9 +1588,7 @@ def diagonal_matrix(self, entries): ``self`` must be a space of square matrices. Length of ``entries`` must be less than or equal to matrix dimensions.If length of ``entries`` is less than matrix - dimensions, ``entries`` is padded with zeroes at the end. - The returned matrix is immutable. Please use ``copy`` if - you want a modified copy. + dimensions, ``entries`` is padded with zeroes at the end. EXAMPLES:: @@ -1611,13 +1609,6 @@ def diagonal_matrix(self, entries): ... TypeError: number of diagonal matrix entries (5) exceeds the matrix size (4) - TESTS:: - - sage: MS1.diag([1, 2, 3, 4])[1,2] = 3 - Traceback (most recent call last): - ... - ValueError: matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M). - Check different implementations:: sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') @@ -1636,7 +1627,6 @@ def diagonal_matrix(self, entries): A = self.zero_matrix().__copy__() for i in range(len(entries)): A[i, i] = entries[i] - A.set_immutable() return A diag = diagonal_matrix From 758e943e041ec7e9887eafe55c33cd156c55bf8f Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" Date: Fri, 28 Feb 2020 12:58:06 -0800 Subject: [PATCH 50/77] trac 28882: reviewer changes --- src/sage/matrix/matrix_space.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index ad7a53135a8..b6c5863ac16 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -1584,11 +1584,17 @@ def identity_matrix(self): def diagonal_matrix(self, entries): """ - Return a diagonal matrix in ``self`` containing the elements specified in the list. + Create a diagonal matrix in ``self`` using the specified elements - ``self`` must be a space of square matrices. Length of ``entries`` must be less - than or equal to matrix dimensions.If length of ``entries`` is less than matrix - dimensions, ``entries`` is padded with zeroes at the end. + INPUT: + + - ``entries`` -- the elements to use as the diagonal entries + + ``self`` must be a space of square matrices. The length of + ``entries`` must be less than or equal to the matrix + dimensions. If the length of ``entries`` is less than the + matrix dimensions, ``entries`` is padded with zeroes at the + end. EXAMPLES:: @@ -1600,14 +1606,18 @@ def diagonal_matrix(self, entries): [0 2 0 0] [0 0 3 0] [0 0 0 4] - sage: Er = MS2.diagonal_matrix([1, 2]) + sage: MS2.diagonal_matrix([1, 2]) Traceback (most recent call last): ... TypeError: diagonal matrix must be square - sage: Er = MS1.diagonal_matrix([1, 2, 3, 4, 5]) + sage: MS1.diagonal_matrix([1, 2, 3, 4, 5]) Traceback (most recent call last): ... - TypeError: number of diagonal matrix entries (5) exceeds the matrix size (4) + ValueError: number of diagonal matrix entries (5) exceeds the matrix size (4) + sage: MS1.diagonal_matrix([1/2, 2, 3, 4]) + Traceback (most recent call last): + ... + TypeError: no conversion of this rational to integer Check different implementations:: @@ -1617,8 +1627,7 @@ def diagonal_matrix(self, entries): sage: type(M1.diagonal_matrix([1, 2])) sage: type(M2.diagonal_matrix([1, 2])) - - + """ if self.__nrows != self.__ncols: raise TypeError("diagonal matrix must be square") @@ -1629,8 +1638,6 @@ def diagonal_matrix(self, entries): A[i, i] = entries[i] return A - diag = diagonal_matrix - def is_dense(self): """ Return whether matrices in ``self`` are dense. From f2d8ea9acfe88a25856e2f844f66f84d1ebfcc41 Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" Date: Mon, 2 Mar 2020 11:48:52 -0800 Subject: [PATCH 51/77] trac 28882: fix doctest in thematic_tutorials --- src/doc/en/thematic_tutorials/coercion_and_categories.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/en/thematic_tutorials/coercion_and_categories.rst b/src/doc/en/thematic_tutorials/coercion_and_categories.rst index bd76813e9c8..b58c9c59de7 100644 --- a/src/doc/en/thematic_tutorials/coercion_and_categories.rst +++ b/src/doc/en/thematic_tutorials/coercion_and_categories.rst @@ -447,10 +447,10 @@ Sage's category framework can differentiate the two cases:: And indeed, ``MS2`` has *more* methods than ``MS1``:: sage: import inspect - sage: len([s for s in dir(MS1) if inspect.ismethod(getattr(MS1,s,None))]) - 81 - sage: len([s for s in dir(MS2) if inspect.ismethod(getattr(MS2,s,None))]) - 121 + sage: L1 = len([s for s in dir(MS1) if inspect.ismethod(getattr(MS1,s,None))]) + sage: L2 = len([s for s in dir(MS2) if inspect.ismethod(getattr(MS2,s,None))]) + sage: L1 < L2 + True This is because the class of ``MS2`` also inherits from the parent class for algebras:: From b5e28e14ef34227f6c0b18a86a51b4ab6e162488 Mon Sep 17 00:00:00 2001 From: Akshat Agrawal Date: Thu, 6 Feb 2020 01:10:35 +0530 Subject: [PATCH 52/77] added edges parameter in dfs --- src/sage/graphs/generic_graph.py | 41 ++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 3539368243d..ef43fba0225 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -17674,7 +17674,7 @@ def breadth_first_search(self, start, ignore_direction=False, yield w def depth_first_search(self, start, ignore_direction=False, - distance=None, neighbors=None): + distance=None, neighbors=None, edges=False): """ Return an iterator over the vertices in a depth-first ordering. @@ -17695,6 +17695,10 @@ def depth_first_search(self, start, ignore_direction=False, digraph, the ``neighbors`` function defaults to the :meth:`~DiGraph.neighbor_out_iterator` function of the graph. + - ``edges`` -- boolean (default ``False``); whether to return the edges + of the DFS tree in the order of visit or the vertices (default). + Edges are directed in root to leaf orientation of the tree. + .. SEEALSO:: - :meth:`breadth_first_search` @@ -17745,13 +17749,30 @@ def depth_first_search(self, start, ignore_direction=False, sage: list(D.breadth_first_search(5, neighbors=D.neighbors_out)) [5, 33, 6, 34, 7, 35, 8, 9] + You can get edges of the DFS tree instead of the vertices using the + ``edges`` parameter:: + + sage: D = DiGraph({1: [2, 3], 2: [4], 3: [4], 4: [1, 5], 5: [2, 6]}) + sage: list(D.depth_first_search(1, edges=True)) + [(1, 3), (3, 4), (4, 5), (5, 6), (5, 2)] + sage: D = DiGraph({1: [2, 3], 2: [4], 3: [4], 4: [1, 5], 5: [2, 6]}) + sage: list(D.depth_first_search(1, ignore_direction=True, edges=True)) + [(1, 4), (4, 5), (5, 6), (5, 2), (4, 3)] + TESTS:: sage: D = DiGraph({1: [0], 2: [0]}) sage: list(D.depth_first_search(0)) [0] - sage: list(D.depth_first_search(0, ignore_direction=True)) - [0, 2, 1] + sage: D = DiGraph({1: [2, 3], 3: [4, 6], 4: [6], 5: [4, 7], 6: [7]}) + sage: list(D.depth_first_search(1)) + [1, 3, 6, 7, 4, 2] + sage: list(D.depth_first_search(1, edges=True)) + [(1, 3), (3, 6), (6, 7), (3, 4), (1, 2)] + sage: list(D.depth_first_search(1, ignore_direction=True)) + [1, 3, 6, 4, 5, 7, 2] + sage: list(D.depth_first_search(1, ignore_direction=True, edges=True)) + [(1, 3), (3, 6), (6, 7), (7, 5), (5, 4), (1, 2)] """ if distance is not None: @@ -17759,7 +17780,7 @@ def depth_first_search(self, start, ignore_direction=False, # Preferably use the Cython implementation if (neighbors is None and not isinstance(start, list) and distance is None - and hasattr(self._backend, "depth_first_search")): + and hasattr(self._backend, "depth_first_search") and not edges): for v in self._backend.depth_first_search(start, ignore_direction=ignore_direction): yield v else: @@ -17768,7 +17789,7 @@ def depth_first_search(self, start, ignore_direction=False, neighbors = self.neighbor_iterator else: neighbors = self.neighbor_out_iterator - seen = set() + seen = list() if isinstance(start, list): # Reverse the list so that the initial vertices come out in the same order queue = [(v, 0) for v in reversed(start)] @@ -17778,8 +17799,14 @@ def depth_first_search(self, start, ignore_direction=False, while queue: v, d = queue.pop() if v not in seen: - yield v - seen.add(v) + if not edges: + yield v + else: + for w in reversed(seen): + if v in neighbors(w): + yield w, v + break + seen.append(v) if distance is None or d < distance: for w in neighbors(v): if w not in seen: From 7510d95eb82b48345f1387c36cf183a60aa4983c Mon Sep 17 00:00:00 2001 From: SagnikDey92 Date: Thu, 27 Feb 2020 11:45:53 +0000 Subject: [PATCH 53/77] Made the DFS edge returning routine linear from quadratic by separating the cases where vertices and edges are returned --- src/sage/graphs/generic_graph.py | 41 +++++++++++++++++++------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index ef43fba0225..802189b043b 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -17789,28 +17789,37 @@ def depth_first_search(self, start, ignore_direction=False, neighbors = self.neighbor_iterator else: neighbors = self.neighbor_out_iterator - seen = list() + seen = set() if isinstance(start, list): # Reverse the list so that the initial vertices come out in the same order queue = [(v, 0) for v in reversed(start)] else: queue = [(start, 0)] - - while queue: - v, d = queue.pop() - if v not in seen: - if not edges: + + if not edges: + while queue: + v, d = queue.pop() + if v not in seen: yield v - else: - for w in reversed(seen): - if v in neighbors(w): - yield w, v - break - seen.append(v) - if distance is None or d < distance: - for w in neighbors(v): - if w not in seen: - queue.append((w, d + 1)) + seen.add(v) + if distance is None or d < distance: + for w in neighbors(v): + if w not in seen: + queue.append((w, d + 1)) + + else: + v, d = queue.pop() + queue.append((None, v, d)) + while queue: + v, w, d = queue.pop() + if w not in seen: + if v is not None: + yield v, w + seen.add(w) + if distance is None or d < distance: + for x in neighbors(w): + if x not in seen: + queue.append((w, x, d + 1)) ### Constructors From 3f2756e1d02e16fd7c907395a62f8bd1d89fa0b5 Mon Sep 17 00:00:00 2001 From: SagnikDey92 Date: Fri, 28 Feb 2020 04:09:52 +0000 Subject: [PATCH 54/77] Fixed errors related to DFS with number of starting vertices not equal to one. Made minor change to documentation of depth_first_search function to maintain uniformity --- src/sage/graphs/generic_graph.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 802189b043b..058b0c478d1 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -17695,7 +17695,7 @@ def depth_first_search(self, start, ignore_direction=False, digraph, the ``neighbors`` function defaults to the :meth:`~DiGraph.neighbor_out_iterator` function of the graph. - - ``edges`` -- boolean (default ``False``); whether to return the edges + - ``edges`` -- boolean (default: ``False``); whether to return the edges of the DFS tree in the order of visit or the vertices (default). Edges are directed in root to leaf orientation of the tree. @@ -17803,13 +17803,11 @@ def depth_first_search(self, start, ignore_direction=False, yield v seen.add(v) if distance is None or d < distance: - for w in neighbors(v): - if w not in seen: - queue.append((w, d + 1)) - + for w in neighbors(v): + if w not in seen: + queue.append((w, d + 1)) else: - v, d = queue.pop() - queue.append((None, v, d)) + queue = [(None, v, d) for v, d in queue] while queue: v, w, d = queue.pop() if w not in seen: From f480fd0c0426ef9dbdb02f128ff702c260763880 Mon Sep 17 00:00:00 2001 From: SagnikDey92 Date: Fri, 28 Feb 2020 12:12:26 +0000 Subject: [PATCH 55/77] Added new tests to demonstrate working in all cases. --- src/sage/graphs/generic_graph.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 058b0c478d1..e40bf71091d 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -17755,7 +17755,6 @@ def depth_first_search(self, start, ignore_direction=False, sage: D = DiGraph({1: [2, 3], 2: [4], 3: [4], 4: [1, 5], 5: [2, 6]}) sage: list(D.depth_first_search(1, edges=True)) [(1, 3), (3, 4), (4, 5), (5, 6), (5, 2)] - sage: D = DiGraph({1: [2, 3], 2: [4], 3: [4], 4: [1, 5], 5: [2, 6]}) sage: list(D.depth_first_search(1, ignore_direction=True, edges=True)) [(1, 4), (4, 5), (5, 6), (5, 2), (4, 3)] @@ -17764,11 +17763,20 @@ def depth_first_search(self, start, ignore_direction=False, sage: D = DiGraph({1: [0], 2: [0]}) sage: list(D.depth_first_search(0)) [0] + sage: G = DiGraph([(0, 1), (1, 2), (3, 4), (4, 5)]) + sage: list(G.depth_first_search([0], edges=True)) + [(0, 1), (1, 2)] + sage: list(G.depth_first_search([0, 3], edges=True)) + [(0, 1), (1, 2), (3, 4), (4, 5)] sage: D = DiGraph({1: [2, 3], 3: [4, 6], 4: [6], 5: [4, 7], 6: [7]}) sage: list(D.depth_first_search(1)) [1, 3, 6, 7, 4, 2] sage: list(D.depth_first_search(1, edges=True)) [(1, 3), (3, 6), (6, 7), (3, 4), (1, 2)] + sage: list(D.depth_first_search([1, 3], edges=True)) + [(1, 3), (3, 6), (6, 7), (3, 4), (1, 2)] + sage: list(D.depth_first_search([], ignore_direction=True, edges=True)) + [] sage: list(D.depth_first_search(1, ignore_direction=True)) [1, 3, 6, 4, 5, 7, 2] sage: list(D.depth_first_search(1, ignore_direction=True, edges=True)) From 4ae1e779bd7d3bf8c385ea61617eb2423d608476 Mon Sep 17 00:00:00 2001 From: paulmasson Date: Mon, 2 Mar 2020 17:04:37 -0800 Subject: [PATCH 56/77] Pass color through to texts --- src/sage/ext_data/threejs/threejs_template.html | 8 +++----- src/sage/plot/plot3d/base.pyx | 5 +++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/sage/ext_data/threejs/threejs_template.html b/src/sage/ext_data/threejs/threejs_template.html index 2935e1ba8e8..0f74e105912 100644 --- a/src/sage/ext_data/threejs/threejs_template.html +++ b/src/sage/ext_data/threejs/threejs_template.html @@ -108,9 +108,7 @@ } - function addLabel( text, x, y, z ) { - - var fontsize = 14; + function addLabel( text, x, y, z, color='black', fontsize=14 ) { var canvas = document.createElement( 'canvas' ); var pixelRatio = Math.round( window.devicePixelRatio ); @@ -121,7 +119,7 @@ var context = canvas.getContext( '2d' ); context.scale( pixelRatio, pixelRatio ); - context.fillStyle = 'black'; + context.fillStyle = color; context.font = fontsize + 'px monospace'; context.textAlign = 'center'; context.textBaseline = 'middle'; @@ -213,7 +211,7 @@ var texts = SAGE_TEXTS; for ( var i=0 ; i < texts.length ; i++ ) - addLabel( texts[i].text, a[0]*texts[i].x, a[1]*texts[i].y, a[2]*texts[i].z ); + addLabel( texts[i].text, a[0]*texts[i].x, a[1]*texts[i].y, a[2]*texts[i].z, texts[i].color ); var points = SAGE_POINTS; for ( var i=0 ; i < points.length ; i++ ) addPoint( points[i] ); diff --git a/src/sage/plot/plot3d/base.pyx b/src/sage/plot/plot3d/base.pyx index 8bda9fa0e3c..6feab418760 100644 --- a/src/sage/plot/plot3d/base.pyx +++ b/src/sage/plot/plot3d/base.pyx @@ -420,8 +420,9 @@ cdef class Graphics3d(SageObject): opacity = p.all[0].texture.opacity self += arrow3d(translated[0], translated[1], width=width, color=color, opacity=opacity) if hasattr(p.all[0], 'string'): - texts.append('{{"text":"{}", "x":{}, "y":{}, "z":{}}}'.format( - p.all[0].string, t[0], t[1], t[2])) + color = '#' + p.all[0].texture.hex_rgb(); + texts.append('{{"text":"{}", "x":{}, "y":{}, "z":{}, "color":"{}"}}'.format( + p.all[0].string, t[0], t[1], t[2], color)) points = '[' + ','.join(points) + ']' lines = '[' + ','.join(lines) + ']' From bc4c440f027587e892c49e1c26288288b75fc781 Mon Sep 17 00:00:00 2001 From: paulmasson Date: Mon, 2 Mar 2020 17:17:58 -0800 Subject: [PATCH 57/77] Cleanup in preparation for #29192 --- .../ext_data/threejs/threejs_template.html | 22 +++++++------ src/sage/plot/plot3d/base.pyx | 31 +++++++++++-------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/sage/ext_data/threejs/threejs_template.html b/src/sage/ext_data/threejs/threejs_template.html index 2935e1ba8e8..a6071144f64 100644 --- a/src/sage/ext_data/threejs/threejs_template.html +++ b/src/sage/ext_data/threejs/threejs_template.html @@ -8,16 +8,18 @@ body { margin: 0px; overflow: hidden; } - #menu-container { position: absolute; bottom: 30px; right: 40px; } + #menu-container { position: absolute; bottom: 30px; right: 40px; cursor: default; } #menu-message { position: absolute; bottom: 0px; right: 0px; white-space: nowrap; - display: none; background-color: #F5F5F5; padding: 10px } + display: none; background-color: #F5F5F5; padding: 10px; } #menu-content { position: absolute; bottom: 0px; right: 0px; display: none; background-color: #F5F5F5; border-bottom: 1px solid black; border-right: 1px solid black; border-left: 1px solid black; } #menu-content div { border-top: 1px solid black; padding: 10px; white-space: nowrap; } + + #menu-content div:hover { background-color: #FEFEFE;; } @@ -61,12 +63,12 @@ var yRange = b[1].y - b[0].y; var zRange = b[1].z - b[0].z; - var ar = options.aspect_ratio; + var ar = options.aspectRatio; var a = [ ar[0], ar[1], ar[2] ]; // aspect multipliers var autoAspect = 2.5; if ( zRange > autoAspect * rRange && a[2] === 1 ) a[2] = autoAspect * rRange / zRange; - // Distance from (xMid,yMid,zMid) to any corner of the bounding box, after applying aspect_ratio. + // Distance from (xMid,yMid,zMid) to any corner of the bounding box, after applying aspectRatio var midToCorner = Math.sqrt( a[0]*a[0]*xRange*xRange + a[1]*a[1]*yRange*yRange + a[2]*a[2]*zRange*zRange ) / 2; var xMid = ( b[0].x + b[1].x ) / 2; @@ -79,11 +81,11 @@ var boxMesh = new THREE.Line( box ); if ( options.frame ) scene.add( new THREE.BoxHelper( boxMesh, 'black' ) ); - if ( options.axes_labels ) { + if ( options.axesLabels ) { var d = options.decimals; // decimals var offsetRatio = 0.1; - var al = options.axes_labels; + var al = options.axesLabels; var offset = offsetRatio * a[1]*( b[1].y - b[0].y ); var xm = xMid.toFixed(d); @@ -413,13 +415,15 @@ function getViewpoint() { + function roundTo( x, n ) { return +x.toFixed(n); } + var v = camera.quaternion.inverse(); var r = Math.sqrt( v.x*v.x + v.y*v.y + v.z*v.z ); - var axis = [ v.x / r, v.y / r, v.z / r ]; - var angle = 2 * Math.atan2( r, v.w ) * 180 / Math.PI; + var axis = [ roundTo( v.x / r, 4 ), roundTo( v.y / r, 4 ), roundTo( v.z / r, 4 ) ]; + var angle = roundTo( 2 * Math.atan2( r, v.w ) * 180 / Math.PI, 2 ); var textArea = document.createElement( 'textarea' ); - textArea.textContent = JSON.stringify( axis ) + ', ' + angle; + textArea.textContent = JSON.stringify( axis ) + ',' + angle; textArea.style.csstext = 'position: absolute; top: -100%'; document.body.append( textArea ); textArea.select(); diff --git a/src/sage/plot/plot3d/base.pyx b/src/sage/plot/plot3d/base.pyx index 8bda9fa0e3c..ecf2e9deaaf 100644 --- a/src/sage/plot/plot3d/base.pyx +++ b/src/sage/plot/plot3d/base.pyx @@ -364,21 +364,28 @@ cdef class Graphics3d(SageObject): OutputSceneThreejs container """ options = self._process_viewing_options(kwds) - # Threejs specific options - options.setdefault('axes_labels', ['x','y','z']) - options.setdefault('decimals', 2) options.setdefault('online', False) - options.setdefault('projection', 'perspective') - if options['projection'] not in ['perspective', 'orthographic']: + + js_options = {} # options passed to Three.js template + + js_options['aspectRatio'] = options.get('aspect_ratio', [1,1,1]) + js_options['axes'] = options.get('axes', False) + js_options['axesLabels'] = options.get('axes_labels', ['x','y','z']) + js_options['decimals'] = options.get('decimals', 2) + js_options['frame'] = options.get('frame', True) + js_options['projection'] = options.get('projection', 'perspective') + + if js_options['projection'] not in ['perspective', 'orthographic']: import warnings - warnings.warn('projection={} is not supported; using perspective'.format(options['projection'])) - options['projection'] = 'perspective' + warnings.warn('projection={} is not supported; using perspective'.format(js_options['projection'])) + js_options['projection'] = 'perspective' + # Normalization of options values for proper JSONing - options['aspect_ratio'] = [float(i) for i in options['aspect_ratio']] - options['decimals'] = int(options['decimals']) + js_options['aspectRatio'] = [float(i) for i in js_options['aspectRatio']] + js_options['decimals'] = int(js_options['decimals']) - if not options['frame']: - options['axes_labels'] = False + if not js_options['frame']: + js_options['axesLabels'] = False from sage.repl.rich_output import get_display_manager scripts = get_display_manager().threejs_scripts(options['online']) @@ -437,8 +444,6 @@ cdef class Graphics3d(SageObject): html = f.read() html = html.replace('SAGE_SCRIPTS', scripts) - js_options = dict((key, options[key]) for key in - ['aspect_ratio', 'axes', 'axes_labels', 'decimals', 'frame', 'projection']) html = html.replace('SAGE_OPTIONS', json.dumps(js_options)) html = html.replace('SAGE_BOUNDS', bounds) html = html.replace('SAGE_LIGHTS', lights) From d8d76c39c743c91c263e3b914bc68514153b76db Mon Sep 17 00:00:00 2001 From: paulmasson Date: Mon, 2 Mar 2020 17:55:14 -0800 Subject: [PATCH 58/77] Update location of extras --- src/doc/en/developer/coding_basics.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/doc/en/developer/coding_basics.rst b/src/doc/en/developer/coding_basics.rst index 31fb975862b..eb22c2733b2 100644 --- a/src/doc/en/developer/coding_basics.rst +++ b/src/doc/en/developer/coding_basics.rst @@ -103,7 +103,7 @@ of the directory containing the Sage sources: SAGE_ROOT/ sage # the Sage launcher Makefile # top level Makefile - build/ # sage's build system + build/ # Sage's build system deps install ... @@ -112,12 +112,12 @@ of the directory containing the Sage sources: setup.py module_list.py ... - sage/ # sage library (formerly devel/sage-main/sage) - ext/ # extra sage resources (formerly devel/ext-main) - mac-app/ # would no longer have to awkwardly be in extcode - bin/ # the scripts in local/bin that are tracked - upstream/ # tarballs of upstream sources - local/ # installed binaries + sage/ # Sage library + ext_data/ # extra Sage resources (formerly src/ext) + mac-app/ # would no longer have to awkwardly be in extcode + bin/ # the scripts in local/bin that are tracked + upstream/ # tarballs of upstream sources + local/ # installed binaries Python Sage library code goes into ``src/`` and uses the following conventions. Directory names may be plural (e.g. ``rings``) and file @@ -155,7 +155,7 @@ Then in the file ``SAGE_ROOT/src/sage/all.py``, add a line :: from sage.measure_theory.all import * Non-Python Sage source code and supporting files should be placed in -appropriate subdirectories of ``SAGE_ROOT/src/ext/``. They will then be +appropriate subdirectories of ``SAGE_ROOT/src/sage/ext_data/``. They will then be automatically copied to the corresponding subdirectories of ``SAGE_ROOT/local/share/sage/ext/`` during the build process and can be accessed at runtime using ``SAGE_EXTCODE``. For example, if ``file`` is placed From 30ab99fc30ca29d25b3818491b9b025684ceba15 Mon Sep 17 00:00:00 2001 From: paulmasson Date: Mon, 2 Mar 2020 18:12:27 -0800 Subject: [PATCH 59/77] One more update --- src/doc/en/developer/coding_basics.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/en/developer/coding_basics.rst b/src/doc/en/developer/coding_basics.rst index eb22c2733b2..8ace4d9b6a8 100644 --- a/src/doc/en/developer/coding_basics.rst +++ b/src/doc/en/developer/coding_basics.rst @@ -159,7 +159,7 @@ appropriate subdirectories of ``SAGE_ROOT/src/sage/ext_data/``. They will then b automatically copied to the corresponding subdirectories of ``SAGE_ROOT/local/share/sage/ext/`` during the build process and can be accessed at runtime using ``SAGE_EXTCODE``. For example, if ``file`` is placed -in ``SAGE_ROOT/src/ext/directory/`` it can be accessed with :: +in ``SAGE_ROOT/src/sage/ext_data/directory/`` it can be accessed with :: from sage.env import SAGE_EXTCODE file = os.path.join(SAGE_EXTCODE, 'directory', 'file') From e84a304f5d6eb7277f573f04dae0ccd2aaece933 Mon Sep 17 00:00:00 2001 From: vipul79321 Date: Tue, 3 Mar 2020 10:15:49 +0530 Subject: [PATCH 60/77] updated according to comment 27 --- src/sage/graphs/generators/families.py | 36 +++++++++++--------------- src/sage/graphs/graph_generators.py | 2 ++ 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/sage/graphs/generators/families.py b/src/sage/graphs/generators/families.py index 0cfd3948dd7..8ff8a76dba6 100644 --- a/src/sage/graphs/generators/families.py +++ b/src/sage/graphs/generators/families.py @@ -3592,17 +3592,17 @@ def MuzychukS6Graph(n, d, Phi='fixed', Sigma='fixed', verbose=False): def CubeConnectedCycle(d): r""" - Returns the cube-connected cycle of dimension `d`. + Return the cube-connected cycle of dimension `d`. The cube-connected cycle of order `d` is the `d`-dimensional hypercube with each of its vertices replaced by a cycle of length `d`. This graph has order `d \times 2^d`. The construction is as follows: - Construct vertex `(x,y)` for `0 <= x < 2^d`, `0 <= y < d`. + Construct vertex `(x,y)` for `0 \leq x < 2^d`, `0 \leq y < d`. For each vertex, `(x,y)`, add an edge between it and `(x, (y-1) \mod d))`, `(x,(y+1) \mod d)`, and `(x \oplus 2^y, y)`, where `\oplus` is the bitwise xor operator. - + For `d=1` and `2`, the cube-connected cycle graph contains self-loops or multiple edges between a pair of vertices, but for all other `d`, it is simple. @@ -3617,33 +3617,33 @@ def CubeConnectedCycle(d): The order of the graph is `d \times 2^d` :: - sage: d = 10 + sage: d = 3 sage: g = graphs.CubeConnectedCycle(d) sage: len(g) == d*2**d True The diameter of cube-connected cycles for `d > 3` is `2d + \lfloor \frac{d}{2} \rfloor - 2` :: - sage: d = 9 + sage: d = 4 sage: g = graphs.CubeConnectedCycle(d) sage: g.diameter() == 2*d+d//2-2 True All vertices have degree `3` when `d > 1` :: - sage: g = graphs.CubeConnectedCycle(12) + sage: g = graphs.CubeConnectedCycle(5) sage: all(g.degree(v) == 3 for v in g) True - TEST:: + TESTS:: sage: g = graphs.CubeConnectedCycle(0) Traceback (most recent call last): ... - ValueError: d must be greater than 0. + ValueError: the dimension d must be greater than 0 """ - if d<1: - raise ValueError('d must be greater than 0.') + if d < 1: + raise ValueError('the dimension d must be greater than 0') G = Graph(name="Cube-Connected Cycle of dimension {}".format(d)) @@ -3653,18 +3653,12 @@ def CubeConnectedCycle(d): G.add_edges([((0,0),(0,1)), ((0,0),(0,0)), ((0,1),(0,1))]) return G - if d == 2: - #only d = 2 require multiple edges - #G.allow_multiple_edges(True) - for x in range(1<= 3: - for x in range(1< Date: Thu, 15 Aug 2019 16:50:29 +0200 Subject: [PATCH 61/77] Class linear_code_no_metric. Moved stuff from linear_code. --- src/sage/coding/abstract_code.py | 4 +- src/sage/coding/encoder.py | 6 +- src/sage/coding/encoders_catalog.py | 6 +- src/sage/coding/golay_code.py | 2 +- src/sage/coding/linear_code.py | 1159 +------------------- src/sage/coding/linear_code_no_metric.py | 1268 ++++++++++++++++++++++ src/sage/coding/punctured_code.py | 2 +- 7 files changed, 1282 insertions(+), 1165 deletions(-) create mode 100644 src/sage/coding/linear_code_no_metric.py diff --git a/src/sage/coding/abstract_code.py b/src/sage/coding/abstract_code.py index 35abdabccf0..22a39b700b8 100644 --- a/src/sage/coding/abstract_code.py +++ b/src/sage/coding/abstract_code.py @@ -950,7 +950,7 @@ def encoder(self, encoder_name=None, *args, **kwargs): ValueError: Constructing the Systematic encoder failed, possibly due to missing or incorrect parameters. The constructor requires no arguments. It takes the optional arguments ['systematic_positions']. - See the documentation of sage.coding.linear_code.LinearCodeSystematicEncoder for more details. + See the documentation of sage.coding.linear_code_no_metric.LinearCodeSystematicEncoder for more details. """ if not self._default_encoder_name: raise NotImplementedError("No encoder implemented for this code.") @@ -991,7 +991,7 @@ def encoders_available(self, classes=False): sage: dictionary = C.encoders_available(True) sage: sorted(dictionary.items()) [('GeneratorMatrix', ), - ('Systematic', )] + ('Systematic', )] """ if classes: return copy(self._registered_encoders) diff --git a/src/sage/coding/encoder.py b/src/sage/coding/encoder.py index 9a8f0dffbb6..0e00a5170de 100644 --- a/src/sage/coding/encoder.py +++ b/src/sage/coding/encoder.py @@ -119,8 +119,8 @@ def encode(self, word): This is a default implementation which assumes that the message space of the encoder is `F^{k}`, where `F` is - :meth:`sage.coding.linear_code.AbstractLinearCode.base_field` - and `k` is :meth:`sage.coding.linear_code.AbstractLinearCode.dimension`. + :meth:`sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric.base_field` + and `k` is :meth:`sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric.dimension`. If this is not the case, this method should be overwritten by the subclass. .. NOTE:: @@ -244,7 +244,7 @@ def unencode(self, c, nocheck=False): sage: C = LinearCode(G) Traceback (most recent call last): ... - ValueError: length must be a positive integer + ValueError: length must be a non-zero positive integer """ if not nocheck and c not in self.code(): raise EncodingError("Given word is not in the code") diff --git a/src/sage/coding/encoders_catalog.py b/src/sage/coding/encoders_catalog.py index e1bed60ae9c..014226cf6da 100644 --- a/src/sage/coding/encoders_catalog.py +++ b/src/sage/coding/encoders_catalog.py @@ -15,7 +15,7 @@ **Generic encoders** - :class:`linear_code.LinearCodeGeneratorMatrixEncoder ` -- :class:`linear_code.LinearCodeSystematicEncoder ` +- :class:`linear_code_no_metric.LinearCodeSystematicEncoder ` **Generalized Reed-Solomon code encoders** @@ -49,8 +49,8 @@ 'CyclicCodeVectorEncoder']) _lazy_import('sage.coding.extended_code', 'ExtendedCodeExtendedMatrixEncoder') _lazy_import('sage.coding.grs_code', ['GRSEvaluationVectorEncoder', 'GRSEvaluationPolynomialEncoder']) -_lazy_import('sage.coding.linear_code', ['LinearCodeGeneratorMatrixEncoder', - 'LinearCodeSystematicEncoder']) +_lazy_import('sage.coding.linear_code', 'LinearCodeGeneratorMatrixEncoder') +_lazy_import('sage.coding.linear_code_no_metric', 'LinearCodeSystematicEncoder') _lazy_import('sage.coding.punctured_code', 'PuncturedCodePuncturedMatrixEncoder') _lazy_import('sage.coding.reed_muller_code', ['ReedMullerVectorEncoder', 'ReedMullerPolynomialEncoder']) _lazy_import('sage.coding.subfield_subcode', 'SubfieldSubcodeParityCheckEncoder') diff --git a/src/sage/coding/golay_code.py b/src/sage/coding/golay_code.py index d88f4cfa601..b4b6d64f847 100644 --- a/src/sage/coding/golay_code.py +++ b/src/sage/coding/golay_code.py @@ -160,7 +160,7 @@ def dual_code(self): If ``self`` is an extended Golay code, ``self`` is returned. Otherwise, it returns the output of - :meth:`sage.coding.linear_code.AbstractLinearCode.dual_code` + :meth:`sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric.dual_code` EXAMPLES:: diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index 65ee7f47441..1a19b8e93c1 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -231,6 +231,7 @@ class should inherit from this class. Also ``AbstractLinearCode`` should never from sage.misc.randstate import current_randstate from sage.combinat.subset import Subsets from sage.features.gap import GapPackage +from sage.coding.linear_code_no_metric import AbstractLinearCodeNoMetric from sage.coding.abstract_code import AbstractCode from .encoder import Encoder from .decoder import Decoder @@ -286,7 +287,7 @@ def _dump_code_in_leon_format(C): return file_loc -class AbstractLinearCode(AbstractCode, Module): +class AbstractLinearCode(AbstractLinearCodeNoMetric): """ Abstract base class for linear codes. @@ -423,77 +424,17 @@ def __init__(self, base_field, length, default_encoder_name, default_decoder_nam False sage: print(C.divisor()) #long time 1 - - TESTS: - - If the name of the default decoder is not known by the class, it will raise - a exception:: - - sage: class MyCodeFamily2(sage.coding.linear_code.AbstractLinearCode): - ....: def __init__(self, field, length, dimension, generator_matrix): - ....: sage.coding.linear_code.AbstractLinearCode.__init__(self,field, length, "GeneratorMatrix", "Fail") - ....: self._dimension = dimension - ....: self._generator_matrix = generator_matrix - ....: def generator_matrix(self): - ....: return self._generator_matrix - ....: def _repr_(self): - ....: return "[%d, %d] dummy code over GF(%s)" % (self.length(), self.dimension(), self.base_field().cardinality()) - - sage: C = MyCodeFamily2(GF(17), 10, 5, generator_matrix) - Traceback (most recent call last): - ... - ValueError: You must set a valid decoder as default decoder for this code, by filling in the dictionary of registered decoders - - If the name of the default encoder is not known by the class, it will raise - an exception:: - - sage: class MyCodeFamily3(sage.coding.linear_code.AbstractLinearCode): - ....: def __init__(self, field, length, dimension, generator_matrix): - ....: sage.coding.linear_code.AbstractLinearCode.__init__(self,field, length, "Fail", "Syndrome") - ....: self._dimension = dimension - ....: self._generator_matrix = generator_matrix - ....: def generator_matrix(self): - ....: return self._generator_matrix - ....: def _repr_(self): - ....: return "[%d, %d] dummy code over GF(%s)" % (self.length(), self.dimension(), self.base_field().cardinality()) - - sage: C = MyCodeFamily3(GF(17), 10, 5, generator_matrix) - Traceback (most recent call last): - ... - ValueError: You must set a valid encoder as default encoder for this code, by filling in the dictionary of registered encoders - - A ring instead of a field:: - - sage: codes.LinearCode(IntegerModRing(4),matrix.ones(4)) - Traceback (most recent call last): - ... - ValueError: 'generator' must be defined on a field (not a ring) """ from sage.coding.information_set_decoder import LinearCodeInformationSetDecoder # Add here any generic encoder or decoder. This allows any class which # inherits from AbstractLinearCode to use generic decoders/encoders - self._registered_encoders['Systematic'] = LinearCodeSystematicEncoder self._registered_decoders['Syndrome'] = LinearCodeSyndromeDecoder self._registered_decoders['NearestNeighbor'] = LinearCodeNearestNeighborDecoder self._registered_decoders['InformationSet'] = LinearCodeInformationSetDecoder - if not isinstance(length, (int, Integer)) or length <= 0: - raise ValueError("length must be a positive integer") - if not base_field.is_field(): - raise ValueError("{} is not a field".format(base_field)) - if not default_encoder_name in self._registered_encoders: - raise ValueError("You must set a valid encoder as default encoder for this code, by filling in the dictionary of registered encoders") - if not default_decoder_name in self._registered_decoders: - raise ValueError("You must set a valid decoder as default decoder for this code, by filling in the dictionary of registered decoders") - - self._default_decoder_name = default_decoder_name - self._default_encoder_name = default_encoder_name - super(AbstractLinearCode, self).__init__(length, default_encoder_name, default_decoder_name) - cat = Modules(base_field).FiniteDimensional().WithBasis().Finite() - facade_for = VectorSpace(base_field, self._length) - self.Element = type(facade_for.an_element()) #for when we made this a non-facade parent - Parent.__init__(self, base=base_field, facade=facade_for, category=cat) + self._generic_constructor = LinearCode + super(AbstractLinearCode, self).__init__(base_field, length, default_encoder_name, default_decoder_name) def _an_element_(self): r""" @@ -570,18 +511,6 @@ def automorphism_group_gens(self, equivalence="semilinear"): return aut_group_can_label.get_autom_gens(), \ aut_group_can_label.get_autom_order() - def ambient_space(self): - r""" - Returns the ambient vector space of ``self``. - - EXAMPLES:: - - sage: C = codes.HammingCode(GF(2), 3) - sage: C.ambient_space() - Vector space of dimension 7 over Finite Field of size 2 - """ - return VectorSpace(self.base_ring(),self.length()) - def assmus_mattson_designs(self, t, mode=None): r""" Assmus and Mattson Theorem (section 8.4, page 303 of [HP2003]_): Let @@ -691,44 +620,6 @@ def assmus_mattson_designs(self, t, mode=None): return ans return 0 - def base_field(self): - r""" - Return the base field of ``self``. - - EXAMPLES:: - - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) - sage: C = LinearCode(G) - sage: C.base_field() - Finite Field of size 2 - """ - return self.base_ring() - - def basis(self): - r""" - Returns a basis of ``self``. - - OUTPUT: - - - ``Sequence`` - an immutable sequence whose universe is ambient space of ``self``. - - EXAMPLES:: - - sage: C = codes.HammingCode(GF(2), 3) - sage: C.basis() - [ - (1, 0, 0, 0, 0, 1, 1), - (0, 1, 0, 0, 1, 0, 1), - (0, 0, 1, 0, 1, 1, 0), - (0, 0, 0, 1, 1, 1, 1) - ] - sage: C.basis().universe() - Vector space of dimension 7 over Finite Field of size 2 - """ - gens = self.gens() - from sage.structure.sequence import Sequence - return Sequence(gens, universe=self.ambient_space(), check = False, immutable=True, cr=True) - # S. Pancratz, 19 Jan 2010: In the doctests below, I removed the example # ``C.binomial_moment(3)``, which was also marked as ``#long``. This way, # we shorten the doctests time while still maintaining a zero and a @@ -894,24 +785,6 @@ def canonical_representative(self, equivalence="semilinear"): return aut_group_can_label.get_canonical_form(), \ aut_group_can_label.get_transporter() - def __contains__(self, v): - r""" - Returns True if `v` can be coerced into ``self``. Otherwise, returns False. - - EXAMPLES:: - - sage: C = codes.HammingCode(GF(2), 3) - sage: vector((1, 0, 0, 0, 0, 1, 1)) in C # indirect doctest - True - sage: vector((1, 0, 0, 0, 2, 1, 1)) in C # indirect doctest - True - sage: vector((1, 0, 0, 0, 0, 1/2, 1)) in C # indirect doctest - False - """ - if not v in self.ambient_space() or len(v) != self.length(): - return False - return self.syndrome(v) == 0 - def characteristic(self): r""" Returns the characteristic of the base ring of ``self``. @@ -1008,46 +881,6 @@ def chinen_polynomial(self): f = CP/CP(1,s) return f(t,sqrt(q)) - @cached_method - def parity_check_matrix(self): - r""" - Returns the parity check matrix of ``self``. - - The parity check matrix of a linear code `C` corresponds to the - generator matrix of the dual code of `C`. - - EXAMPLES:: - - sage: C = codes.HammingCode(GF(2), 3) - sage: Cperp = C.dual_code() - sage: C; Cperp - [7, 4] Hamming Code over GF(2) - [7, 3] linear code over GF(2) - sage: C.generator_matrix() - [1 0 0 0 0 1 1] - [0 1 0 0 1 0 1] - [0 0 1 0 1 1 0] - [0 0 0 1 1 1 1] - sage: C.parity_check_matrix() - [1 0 1 0 1 0 1] - [0 1 1 0 0 1 1] - [0 0 0 1 1 1 1] - sage: Cperp.parity_check_matrix() - [1 0 0 0 0 1 1] - [0 1 0 0 1 0 1] - [0 0 1 0 1 1 0] - [0 0 0 1 1 1 1] - sage: Cperp.generator_matrix() - [1 0 1 0 1 0 1] - [0 1 1 0 0 1 1] - [0 0 0 1 1 1 1] - """ - G = self.generator_matrix() - H = G.right_kernel() - M = H.basis_matrix() - M.set_immutable() - return M - @cached_method def covering_radius(self): r""" @@ -1155,67 +988,6 @@ def projectivize(row): return True - def dual_code(self): - r""" - Returns the dual code `C^{\perp}` of the code `C`, - - .. MATH:: - - C^{\perp} = \{ v \in V\ |\ v\cdot c = 0,\ \forall c \in C \}. - - EXAMPLES:: - - sage: C = codes.HammingCode(GF(2), 3) - sage: C.dual_code() - [7, 3] linear code over GF(2) - sage: C = codes.HammingCode(GF(4, 'a'), 3) - sage: C.dual_code() - [21, 3] linear code over GF(4) - """ - return LinearCode(self.parity_check_matrix()) - - def dimension(self): - r""" - Returns the dimension of this code. - - EXAMPLES:: - - sage: G = matrix(GF(2),[[1,0,0],[1,1,0]]) - sage: C = LinearCode(G) - sage: C.dimension() - 2 - - TESTS: - - Check that :trac:`21156` is fixed:: - - sage: from sage.coding.linear_code import AbstractLinearCode - sage: from sage.coding.encoder import Encoder - sage: class MonkeyCode(AbstractLinearCode): - ....: _registered_encoders = {} - ....: _registered_decoders = {} - ....: def __init__(self): - ....: super(MonkeyCode, self).__init__(GF(5), 10, "Monkey", "Syndrome") - ....: - sage: class MonkeyEncoder(Encoder): - ....: def __init__(self, code): - ....: super(MonkeyEncoder, self).__init__(C) - ....: @cached_method - ....: def generator_matrix(self): - ....: G = identity_matrix(GF(5), 5).augment(matrix(GF(5), 5, 7)) - ....: return G - sage: MonkeyCode._registered_encoders["Monkey"] = MonkeyEncoder - sage: C = MonkeyCode() - sage: C.dimension() - 5 - """ - try: - return self._dimension - except AttributeError: - dimension = self.generator_matrix().nrows() - self._dimension = dimension - return self._dimension - def direct_sum(self, other): """ Direct sum of the codes ``self`` and ``other`` @@ -1501,180 +1273,6 @@ def galois_closure(self, F0): G = MS([Grref.row(i) for i in range(r)]) return LinearCode(G) - def __getitem__(self, i): - r""" - Returns the `i`-th codeword of this code. - - The implementation of this depends on the implementation of the - :meth:`.__iter__` method. - - The implementation is as follows. Suppose that: - - - the primitive element of the base_ring of this code is `a`, - - the prime subfield is `p`, - - the field has order `p^m`, - - the code has dimension `k`, - - and the generator matrix is `G`. - - Then the :meth:`.__iter__` method returns the elements in this order: - - 1. first, the following ordered list is returned: - ``[i*a^0 * G[0] for i in range(p)]`` - 2. Next, the following ordered list is returned: - ``[i*a^0 * G[0] + a^1*G[0] for i in range(p)]`` - 3. This continues till we get - ``[(i*a^0 +(p-1)*a^1 +...+ (p-1)*a^(m-1))*G[0] for i in range(p)]`` - 4. Then, we move to G[1]: - ``[i*a^0 * G[0] + a^0*G[1] for i in range(p)]``, - and so on. - Hence the `i`-th element can be obtained by the p-adic expansion - of `i` as ``[i_0, i_1, ...,i_{m-1}, i_m, i_{m+1}, ..., i_{km-1}].`` - The element that is generated is: - - .. MATH:: - - \begin{aligned} - & (i_0 a^0 + i_1 a^1 + \cdots + i_{m-1} a^{m-1}) G[0] + \\ - & (i_m a^0 + i_{m+1} a^1 + \cdots + i_{2m-1} a^{m-1}) G[1] + \\ - & \vdots\\ - & (i_{(k-1)m} a^0 + \cdots + i_{km-1} a^{m-1}) G[k-1] - \end{aligned} - - EXAMPLES:: - - sage: G = Matrix(GF(3), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) - sage: C = LinearCode(G) - sage: C[24] - (2, 2, 0, 1, 2, 2, 0) - sage: C[24] == C.list()[24] - True - - TESTS:: - - sage: C = random_matrix(GF(25,'a'), 2, 7).row_space() - sage: C = LinearCode(C.basis_matrix()) - sage: Clist = C.list() - sage: all(C[i] == Clist[i] for i in range(len(C))) - True - - Check that only the indices less than the size of the code are - allowed:: - - sage: C[25**2] - Traceback (most recent call last): - ... - IndexError: The value of the index 'i' (=625) must be between - 0 and 'q^k -1' (=624), inclusive, where 'q' is the size of the - base field and 'k' is the dimension of the code. - - Check that codewords are immutable. See :trac:`16338`:: - - sage: C[0].is_immutable() - True - - """ - # IMPORTANT: If the __iter__() function implementation is changed - # then the implementation here must also be changed so that - # list(self)[i] and self[i] both return the same element. - - F = self.base_ring() - maxindex = F.order()**self.dimension()-1 - if i < 0 or i > maxindex: - raise IndexError("The value of the index 'i' (={}) must be between " - "0 and 'q^k -1' (={}), inclusive, where 'q' is " - "the size of the base field and 'k' is the " - "dimension of the code.".format(i, maxindex)) - - a = F.primitive_element() - m = F.degree() - p = F.prime_subfield().order() - A = [a ** k for k in range(m)] - G = self.generator_matrix() - N = self.dimension()*F.degree() # the total length of p-adic vector - ivec = Integer(i).digits(p, padto=N) - - codeword = 0 - row = 0 - for g in G: - codeword += sum(ivec[j+row*m]*A[j] for j in range(m)) * g - row += 1 - - # The codewords for a specific code can not change. So, we set them - # to be immutable. - codeword.set_immutable() - return codeword - - def generator_matrix(self, encoder_name=None, **kwargs): - r""" - Returns a generator matrix of ``self``. - - INPUT: - - - ``encoder_name`` -- (default: ``None``) name of the encoder which will be - used to compute the generator matrix. The default encoder of ``self`` - will be used if default value is kept. - - - ``kwargs`` -- all additional arguments are forwarded to the construction of the - encoder that is used. - - EXAMPLES:: - - sage: G = matrix(GF(3),2,[1,-1,1,-1,1,1]) - sage: code = LinearCode(G) - sage: code.generator_matrix() - [1 2 1] - [2 1 1] - """ - E = self.encoder(encoder_name, **kwargs) - return E.generator_matrix() - - def systematic_generator_matrix(self, systematic_positions=None): - """ - Return a systematic generator matrix of the code. - - A generator matrix of a code is called systematic if it contains - a set of columns forming an identity matrix. - - INPUT: - - - ``systematic_positions`` -- (default: ``None``) if supplied, the set - of systematic positions in the systematic generator matrix. See the - documentation for :class:`LinearCodeSystematicEncoder` details. - - EXAMPLES:: - - sage: G = matrix(GF(3), [[ 1, 2, 1, 0],\ - [ 2, 1, 1, 1]]) - sage: C = LinearCode(G) - sage: C.generator_matrix() - [1 2 1 0] - [2 1 1 1] - sage: C.systematic_generator_matrix() - [1 2 0 1] - [0 0 1 2] - - Specific systematic positions can also be requested: - - sage: C.systematic_generator_matrix(systematic_positions=[3,2]) - [1 2 0 1] - [1 2 1 0] - """ - systematic_positions = tuple(systematic_positions) if systematic_positions else None - return self.encoder("Systematic", systematic_positions=systematic_positions).generator_matrix() - - @cached_method - def gens(self): - r""" - Returns the generators of this code as a list of vectors. - - EXAMPLES:: - - sage: C = codes.HammingCode(GF(2), 3) - sage: C.gens() - [(1, 0, 0, 0, 0, 1, 1), (0, 1, 0, 0, 1, 0, 1), (0, 0, 1, 0, 1, 1, 0), (0, 0, 0, 1, 1, 1, 1)] - """ - return self.generator_matrix().rows() - def genus(self): r""" Returns the "Duursma genus" of the code, `\gamma_C = n+1-k-d`. @@ -1699,120 +1297,6 @@ def genus(self): gammaC = n+1-k-d return gammaC - def __iter__(self): - """ - Return an iterator over the elements of this linear code. - - EXAMPLES:: - - sage: C = codes.HammingCode(GF(2), 3) - sage: [list(c) for c in C if c.hamming_weight() < 4] - [[0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 1, 1], - [0, 1, 0, 0, 1, 0, 1], [0, 0, 1, 0, 1, 1, 0], - [1, 1, 1, 0, 0, 0, 0], [1, 0, 0, 1, 1, 0, 0], - [0, 1, 0, 1, 0, 1, 0], [0, 0, 1, 1, 0, 0, 1]] - - TESTS:: - - sage: C = codes.HammingCode(GF(2), 3) - sage: L = list(C) - sage: L[10].is_immutable() - True - - """ - from sage.modules.finite_submodule_iter import \ - FiniteFieldsubspace_iterator - return FiniteFieldsubspace_iterator(self.generator_matrix(), immutable=True) - - @cached_method - def information_set(self): - """ - Return an information set of the code. - - Return value of this method is cached. - - A set of column positions of a generator matrix of a code - is called an information set if the corresponding columns - form a square matrix of full rank. - - OUTPUT: - - - Information set of a systematic generator matrix of the code. - - EXAMPLES:: - - sage: G = matrix(GF(3),2,[1,2,0,\ - 2,1,1]) - sage: code = LinearCode(G) - sage: code.systematic_generator_matrix() - [1 2 0] - [0 0 1] - sage: code.information_set() - (0, 2) - """ - return self.encoder("Systematic").systematic_positions() - - def is_information_set(self, positions): - """ - Return whether the given positions form an information set. - - INPUT: - - - A list of positions, i.e. integers in the range 0 to `n-1` where `n` - is the length of `self`. - - OUTPUT: - - - A boolean indicating whether the positions form an information set. - - - EXAMPLES:: - - sage: G = matrix(GF(3),2,[1,2,0,\ - 2,1,1]) - sage: code = LinearCode(G) - sage: code.is_information_set([0,1]) - False - sage: code.is_information_set([0,2]) - True - """ - try: - self.encoder("Systematic", systematic_positions=tuple(positions)) - return True - except ValueError: - return False - - def is_permutation_automorphism(self,g): - r""" - Returns `1` if `g` is an element of `S_n` (`n` = length of self) and - if `g` is an automorphism of self. - - EXAMPLES:: - - sage: C = codes.HammingCode(GF(3), 3) - sage: g = SymmetricGroup(13).random_element() - sage: C.is_permutation_automorphism(g) - 0 - sage: MS = MatrixSpace(GF(2),4,8) - sage: G = MS([[1,0,0,0,1,1,1,0],[0,1,1,1,0,0,0,0],[0,0,0,0,0,0,0,1],[0,0,0,0,0,1,0,0]]) - sage: C = LinearCode(G) - sage: S8 = SymmetricGroup(8) - sage: g = S8("(2,3)") - sage: C.is_permutation_automorphism(g) - 1 - sage: g = S8("(1,2,3,4)") - sage: C.is_permutation_automorphism(g) - 0 - """ - basis = self.generator_matrix().rows() - H = self.parity_check_matrix() - V = H.column_space() - HGm = H*g.matrix() - for c in basis: - if HGm*c != V(0): - return False - return True - def is_permutation_equivalent(self,other,algorithm=None): """ Returns ``True`` if ``self`` and ``other`` are permutation equivalent @@ -1863,43 +1347,6 @@ def is_permutation_equivalent(self,other,algorithm=None): return True return False - def is_self_dual(self): - """ - Returns ``True`` if the code is self-dual (in the usual Hamming inner - product) and ``False`` otherwise. - - EXAMPLES:: - - sage: C = codes.GolayCode(GF(2)) - sage: C.is_self_dual() - True - sage: C = codes.HammingCode(GF(2), 3) - sage: C.is_self_dual() - False - """ - return self == self.dual_code() - - def is_self_orthogonal(self): - """ - Returns ``True`` if this code is self-orthogonal and ``False`` - otherwise. - - A code is self-orthogonal if it is a subcode of its dual. - - EXAMPLES:: - - sage: C = codes.GolayCode(GF(2)) - sage: C.is_self_orthogonal() - True - sage: C = codes.HammingCode(GF(2), 3) - sage: C.is_self_orthogonal() - False - sage: C = codes.QuasiQuadraticResidueCode(11) # optional - gap_packages (Guava package) - sage: C.is_self_orthogonal() # optional - gap_packages (Guava package) - True - """ - return self.is_subcode(self.dual_code()) - def is_galois_closed(self): r""" Checks if ``self`` is equal to its Galois closure. @@ -1914,70 +1361,6 @@ def is_galois_closed(self): p = F.characteristic() return self == self.galois_closure(GF(p)) - def is_subcode(self, other): - """ - Returns ``True`` if ``self`` is a subcode of ``other``. - - EXAMPLES:: - - sage: C1 = codes.HammingCode(GF(2), 3) - sage: G1 = C1.generator_matrix() - sage: G2 = G1.matrix_from_rows([0,1,2]) - sage: C2 = LinearCode(G2) - sage: C2.is_subcode(C1) - True - sage: C1.is_subcode(C2) - False - sage: C3 = C1.extended_code() - sage: C1.is_subcode(C3) - False - sage: C4 = C1.punctured([1]) - sage: C4.is_subcode(C1) - False - sage: C5 = C1.shortened([1]) - sage: C5.is_subcode(C1) - False - sage: C1 = codes.HammingCode(GF(9,"z"), 3) - sage: G1 = C1.generator_matrix() - sage: G2 = G1.matrix_from_rows([0,1,2]) - sage: C2 = LinearCode(G2) - sage: C2.is_subcode(C1) - True - """ - G = self.generator_matrix() - for r in G.rows(): - if not(r in other): - return False - return True - - def cardinality(self): - r""" - Return the size of this code. - - EXAMPLES:: - - sage: C = codes.HammingCode(GF(2), 3) - sage: C.cardinality() - 16 - sage: len(C) - 16 - """ - return self.base_ring().order()**self.dimension() - - __len__ = cardinality - - def length(self): - r""" - Returns the length of this code. - - EXAMPLES:: - - sage: C = codes.HammingCode(GF(2), 3) - sage: C.length() - 7 - """ - return self._length - def _magma_init_(self, magma): r""" Retun a string representation in Magma of this linear code. @@ -2356,27 +1739,6 @@ def permutation_automorphism_group(self, algorithm="partition"): return PermutationGroup([x.get_perm() for x in gens]) raise NotImplementedError("The only algorithms implemented currently are 'gap', 'gap+verbose', and 'partition'.") - def permuted_code(self, p): - r""" - Returns the permuted code, which is equivalent to ``self`` via the - column permutation ``p``. - - EXAMPLES:: - - sage: C = codes.HammingCode(GF(2), 3) - sage: G = C.permutation_automorphism_group(); G - Permutation Group with generators [(4,5)(6,7), (4,6)(5,7), (2,3)(6,7), (2,4)(3,5), (1,2)(5,6)] - sage: g = G("(2,3)(6,7)") - sage: Cg = C.permuted_code(g) - sage: Cg - [7, 4] linear code over GF(2) - sage: C.generator_matrix() == Cg.systematic_generator_matrix() - True - """ - G = copy(self.generator_matrix()) - G.permute_columns(p) - return LinearCode(G) - def punctured(self, L): r""" Returns a :class:`sage.coding.punctured_code` object from ``L``. @@ -2432,63 +1794,6 @@ def relative_distance(self): """ return self.minimum_distance() / self.length() - def rate(self): - r""" - Return the ratio of the number of information symbols to - the code length. - - EXAMPLES:: - - sage: C = codes.HammingCode(GF(2), 3) - sage: C.rate() - 4/7 - """ - return self.dimension() / self.length() - - def redundancy_matrix(self): - r""" - Returns the non-identity columns of a systematic generator matrix for - ``self``. - - A systematic generator matrix is a generator matrix such that a subset - of its columns forms the identity matrix. This method returns the - remaining part of the matrix. - - For any given code, there can be many systematic generator matrices - (depending on which positions should form the identity). This method - will use the matrix returned by - :meth:`AbstractLinearCode.systematic_generator_matrix`. - - OUTPUT: - - - An `k \times (n-k)` matrix. - - EXAMPLES:: - - sage: C = codes.HammingCode(GF(2), 3) - sage: C.generator_matrix() - [1 0 0 0 0 1 1] - [0 1 0 0 1 0 1] - [0 0 1 0 1 1 0] - [0 0 0 1 1 1 1] - sage: C.redundancy_matrix() - [0 1 1] - [1 0 1] - [1 1 0] - [1 1 1] - sage: C = LinearCode(matrix(GF(3),2,[1,2,0,\ - 2,1,1])) - sage: C.systematic_generator_matrix() - [1 2 0] - [0 0 1] - sage: C.redundancy_matrix() - [2] - [0] - """ - E = self.encoder("Systematic") - G = E.generator_matrix() - return G.delete_columns(E.systematic_positions()) - def shortened(self, L): r""" Returns the code shortened at the positions ``L``, where @@ -2627,60 +1932,6 @@ def weight_distribution(self, algorithm=None): spectrum = weight_distribution - def standard_form(self, return_permutation=True): - r""" - Returns a linear code which is permutation-equivalent to ``self`` and - admits a generator matrix in standard form. - - A generator matrix is in standard form if it is of the form `[I \vert - A]`, where `I` is the `k \times k` identity matrix. Any code admits a - generator matrix in systematic form, i.e. where a subset of the columns - form the identity matrix, but one might need to permute columns to allow - the identity matrix to be leading. - - INPUT: - - - ``return_permutation`` -- (default: ``True``) if ``True``, the column - permutation which brings ``self`` into the returned code is also - returned. - - OUTPUT: - - - A :class:`LinearCode` whose :meth:`systematic_generator_matrix` is - guaranteed to be of the form `[I \vert A]`. - - EXAMPLES:: - - sage: C = codes.HammingCode(GF(2), 3) - sage: C.generator_matrix() - [1 0 0 0 0 1 1] - [0 1 0 0 1 0 1] - [0 0 1 0 1 1 0] - [0 0 0 1 1 1 1] - sage: Cs,p = C.standard_form() - sage: p - [] - sage: Cs is C - True - sage: C = LinearCode(matrix(GF(2), [[1,0,0,0,1,1,0],\ - [0,1,0,1,0,1,0],\ - [0,0,0,0,0,0,1]])) - sage: Cs, p = C.standard_form() - sage: p - [1, 2, 7, 3, 4, 5, 6] - sage: Cs.generator_matrix() - [1 0 0 0 0 1 1] - [0 1 0 0 1 0 1] - [0 0 1 0 0 0 0] - """ - E = self.encoder("Systematic") - if E.systematic_positions() == tuple(range(self.dimension())): - from sage.combinat.permutation import Permutation - return self, Permutation([]) - else: - perm = E.systematic_permutation() - return self.permuted_code(perm), perm - def support(self): r""" Returns the set of indices `j` where `A_j` is nonzero, where @@ -2703,50 +1954,6 @@ def support(self): V = VectorSpace(F,n+1) return V(self.weight_distribution()).support() - def syndrome(self, r): - r""" - Returns the syndrome of ``r``. - - The syndrome of ``r`` is the result of `H \times r` where `H` is - the parity check matrix of ``self``. If ``r`` belongs to ``self``, - its syndrome equals to the zero vector. - - INPUT: - - - ``r`` -- a vector of the same length as ``self`` - - OUTPUT: - - - a column vector - - EXAMPLES:: - - sage: MS = MatrixSpace(GF(2),4,7) - sage: G = MS([[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) - sage: C = LinearCode(G) - sage: r = vector(GF(2), (1,0,1,0,1,0,1)) - sage: r in C - True - sage: C.syndrome(r) - (0, 0, 0) - - If ``r`` is not a codeword, its syndrome is not equal to zero:: - - sage: r = vector(GF(2), (1,0,1,0,1,1,1)) - sage: r in C - False - sage: C.syndrome(r) - (0, 1, 1) - - Syndrome computation works fine on bigger fields:: - - sage: C = codes.random_linear_code(GF(59), 12, 4) - sage: c = C.random_element() - sage: C.syndrome(c) - (0, 0, 0, 0, 0, 0, 0, 0) - """ - return self.parity_check_matrix()*r - def weight_enumerator(self, names=None, bivariate=True): r""" Return the weight enumerator polynomial of ``self``. @@ -3120,33 +2327,6 @@ def _latex_(self): return "[%s, %s]\\textnormal{ Linear code over }%s"\ % (self.length(), self.dimension(), self.base_ring()._latex_()) - def __hash__(self): - r""" - Returns the hash value of ``self``. - - EXAMPLES:: - - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) - sage: C = LinearCode(G) - sage: hash(C) #random - 9015017528451745710 - - If ``C1`` and ``C2`` are two codes which only differ by the - coefficients of their generator matrices, their hashes are - different (we check that the bug found in :trac:`18813` is - fixed):: - - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) - sage: C1 = LinearCode(G) - sage: G = Matrix(GF(2), [[1,0,0,1,0,1,0],[0,1,0,0,1,0,0],[0,0,1,1,0,1,0],[0,0,0,0,0,0,1]]) - sage: C2 = LinearCode(G) - sage: hash(C1) != hash(C2) - True - """ - Str = str(self) - G = self.generator_matrix() - return hash((Str, G)) ^ hash(Str) ^ hash(G) - def generator_matrix(self, encoder_name=None, **kwargs): r""" Returns a generator matrix of ``self``. @@ -3266,337 +2446,6 @@ def generator_matrix(self): return g -class LinearCodeSystematicEncoder(Encoder): - r""" - Encoder based on a generator matrix in systematic form for Linear codes. - - To encode an element of its message space, this encoder first builds a - generator matrix in systematic form. What is called systematic form here - is the reduced row echelon form of a matrix, which is not necessarily - `[I \vert H]`, where `I` is the identity block and `H` the parity block. - One can refer to :meth:`LinearCodeSystematicEncoder.generator_matrix` - for a concrete example. - Once such a matrix has been computed, it is used to encode any message - into a codeword. - - This encoder can also serve as the default encoder of a code defined by a - parity check matrix: if the :class:`LinearCodeSystematicEncoder` detects - that it is the default encoder, it computes a generator matrix as the - reduced row echelon form of the right kernel of the parity check matrix. - - INPUT: - - - ``code`` -- The associated code of this encoder. - - - ``systematic_positions`` -- (default: ``None``) the positions in codewords that - should correspond to the message symbols. A list of `k` distinct integers in - the range 0 to `n-1` where `n` is the length of the code and `k` its - dimension. The 0th symbol of a message will then be at position - ``systematic_positions[0]``, the 1st index at position - ``systematic_positions[1]``, etc. A ``ValueError`` is raised at - construction time if the supplied indices do not form an information set. - - EXAMPLES: - - The following demonstrates the basic usage of :class:`LinearCodeSystematicEncoder`:: - - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0,0],\ - [1,0,0,1,1,0,0,0],\ - [0,1,0,1,0,1,0,0],\ - [1,1,0,1,0,0,1,1]]) - sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) - sage: E.generator_matrix() - [1 0 0 0 0 1 1 1] - [0 1 0 0 1 0 1 1] - [0 0 1 0 1 1 0 0] - [0 0 0 1 1 1 1 1] - sage: E2 = codes.encoders.LinearCodeSystematicEncoder(C, systematic_positions=[5,4,3,2]) - sage: E2.generator_matrix() - [1 0 0 0 0 1 1 1] - [0 1 0 0 1 0 1 1] - [1 1 0 1 0 0 1 1] - [1 1 1 0 0 0 0 0] - - An error is raised if one specifies systematic positions which do not form - an information set:: - - sage: E3 = codes.encoders.LinearCodeSystematicEncoder(C, systematic_positions=[0,1,6,7]) - Traceback (most recent call last): - ... - ValueError: systematic_positions are not an information set - - - We exemplify how to use :class:`LinearCodeSystematicEncoder` as the default - encoder. The following class is the dual of the repetition code:: - - sage: class DualRepetitionCode(sage.coding.linear_code.AbstractLinearCode): - ....: def __init__(self, field, length): - ....: sage.coding.linear_code.AbstractLinearCode.__init__(self,field, length, "Systematic", "Syndrome") - ....: - ....: def parity_check_matrix(self): - ....: return Matrix(self.base_field(), [1]*self.length()) - ....: - ....: def _repr_(self): - ....: return "Dual of the [%d, 1] Repetition Code over GF(%s)" % (self.length(), self.base_field().cardinality()) - sage: DualRepetitionCode(GF(3), 5).generator_matrix() - [1 0 0 0 2] - [0 1 0 0 2] - [0 0 1 0 2] - [0 0 0 1 2] - - - An exception is thrown if :class:`LinearCodeSystematicEncoder` is the default encoder but no - parity check matrix has been specified for the code:: - - sage: class BadCodeFamily(sage.coding.linear_code.AbstractLinearCode): - ....: def __init__(self, field, length): - ....: sage.coding.linear_code.AbstractLinearCode.__init__(self, field, length, "Systematic", "Syndrome") - ....: - ....: def _repr_(self): - ....: return "I am a badly defined code" - sage: BadCodeFamily(GF(3), 5).generator_matrix() - Traceback (most recent call last): - ... - ValueError: a parity check matrix must be specified if LinearCodeSystematicEncoder is the default encoder - """ - - def __init__(self, code, systematic_positions=None): - r""" - EXAMPLES:: - - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) - sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) - sage: E - Systematic encoder for [7, 4] linear code over GF(2) - """ - super(LinearCodeSystematicEncoder, self).__init__(code) - self._systematic_positions = tuple(systematic_positions) if systematic_positions else None - if systematic_positions: - # Test that systematic_positions consists of integers in the right - # range. We test that len(systematic_positions) = code.dimension() - # in self.generator_matrix() to avoid possible infinite recursion. - if (not all( e in ZZ and e >= 0 and e < code.length() for e in systematic_positions)) \ - or len(systematic_positions) != len(set(systematic_positions)): - raise ValueError("systematic positions must be a tuple of distinct integers in the range 0 to n-1 where n is the length of the code") - # Test that the systematic positions are an information set - self.generator_matrix() - - - def __eq__(self, other): - r""" - Tests equality between LinearCodeSystematicEncoder objects. - - EXAMPLES:: - - sage: G = Matrix(GF(3), [[1,0,0,1,0,1,0,1,2],[0,1,0,2,2,0,1,1,0],[0,0,1,0,2,2,2,1,2]]) - sage: E1 = codes.encoders.LinearCodeSystematicEncoder(LinearCode(G)) - sage: E2 = codes.encoders.LinearCodeSystematicEncoder(LinearCode(G)) - sage: E1 == E2 - True - sage: E1.systematic_positions() - (0, 1, 2) - sage: E3 = codes.encoders.LinearCodeSystematicEncoder(LinearCode(G), systematic_positions=(2,5,6)) - sage: E3.systematic_positions() - (2, 5, 6) - sage: E1 == E3 - False - """ - return isinstance(other, LinearCodeSystematicEncoder)\ - and self.code() == other.code()\ - and self.systematic_positions() == other.systematic_positions() - - def _repr_(self): - r""" - Return a string representation of ``self``. - - EXAMPLES:: - - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) - sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) - sage: E - Systematic encoder for [7, 4] linear code over GF(2) - """ - return "Systematic encoder for %s" % self.code() - - def _latex_(self): - r""" - Return a latex representation of ``self``. - - EXAMPLES:: - - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) - sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) - sage: latex(E) - \textnormal{Systematic encoder for }[7, 4]\textnormal{ Linear code over }\Bold{F}_{2} - """ - return "\\textnormal{Systematic encoder for }%s" % self.code()._latex_() - - @cached_method - def generator_matrix(self): - r""" - Returns a generator matrix in systematic form of the associated code of ``self``. - - Systematic form here means that a subsets of the columns of the matrix - forms the identity matrix. - - .. NOTE:: - - The matrix returned by this method will not necessarily be `[I \vert H]`, where `I` - is the identity block and `H` the parity block. If one wants to know which columns - create the identity block, one can call :meth:`systematic_positions` - - EXAMPLES:: - - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],\ - [1,0,0,1,1,0,0],\ - [0,1,0,1,0,1,0],\ - [1,1,0,1,0,0,1]]) - sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) - sage: E.generator_matrix() - [1 0 0 0 0 1 1] - [0 1 0 0 1 0 1] - [0 0 1 0 1 1 0] - [0 0 0 1 1 1 1] - - We can ask for different systematic positions:: - - sage: E2 = codes.encoders.LinearCodeSystematicEncoder(C, systematic_positions=[5,4,3,2]) - sage: E2.generator_matrix() - [1 0 0 0 0 1 1] - [0 1 0 0 1 0 1] - [1 1 0 1 0 0 1] - [1 1 1 0 0 0 0] - - Another example where there is no generator matrix of the form `[I \vert H]`:: - - sage: G = Matrix(GF(2), [[1,1,0,0,1,0,1],\ - [1,1,0,0,1,0,0],\ - [0,0,1,0,0,1,0],\ - [0,0,1,0,1,0,1]]) - sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) - sage: E.generator_matrix() - [1 1 0 0 0 1 0] - [0 0 1 0 0 1 0] - [0 0 0 0 1 1 0] - [0 0 0 0 0 0 1] - """ - C = self.code() - # This if statement detects if this encoder is itself the default encoder. - # In this case, attempt building the generator matrix from the parity - # check matrix - if hasattr(self, "_use_pc_matrix"): - if self._use_pc_matrix == 1: - self._use_pc_matrix = 2 - return C.parity_check_matrix().right_kernel_matrix() - else: - raise ValueError("a parity check matrix must be specified if LinearCodeSystematicEncoder is the default encoder") - else: - self._use_pc_matrix = 1 - M = copy(C.generator_matrix()) - if not self._systematic_positions: - M.echelonize() - else: - k = M.nrows() # it is important that k is *not* computed as C.dimension() to avoid possible cyclic dependency - if len(self._systematic_positions) != k: - raise ValueError("systematic_positions must be a tuple of length equal to the dimension of the code") - # Permute the columns of M and bring to reduced row echelon formb - perm = self.systematic_permutation() - M.permute_columns(perm) - M.echelonize() - if M[:,:k].is_singular(): - raise ValueError("systematic_positions are not an information set") - M.permute_columns(perm.inverse()) - M.set_immutable() - return M - - def systematic_permutation(self): - r""" - Returns a permutation which would take the systematic positions into [0,..,k-1] - - EXAMPLES:: - - sage: C = LinearCode(matrix(GF(2), [[1,0,0,0,1,1,0],\ - [0,1,0,1,0,1,0],\ - [0,0,0,0,0,0,1]])) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) - sage: E.systematic_positions() - (0, 1, 6) - sage: E.systematic_permutation() - [1, 2, 7, 3, 4, 5, 6] - """ - n = self.code().length() - systematic_positions = self.systematic_positions() - k = len(systematic_positions) - lp = [ None ]*n - for (i,j) in zip(range(k), systematic_positions): - lp[i] = j - j = k - set_sys_pos = set(systematic_positions) - for i in range(n): - if not i in set_sys_pos: - lp[j] = i - j += 1 - from sage.combinat.permutation import Permutation - return Permutation([1 + e for e in lp]) - - def systematic_positions(self): - r""" - Returns a tuple containing the indices of the columns which form an - identity matrix when the generator matrix is in systematic form. - - EXAMPLES:: - - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],\ - [1,0,0,1,1,0,0],\ - [0,1,0,1,0,1,0],\ - [1,1,0,1,0,0,1]]) - sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) - sage: E.systematic_positions() - (0, 1, 2, 3) - - We take another matrix with a less nice shape:: - - sage: G = Matrix(GF(2), [[1,1,0,0,1,0,1],\ - [1,1,0,0,1,0,0],\ - [0,0,1,0,0,1,0],\ - [0,0,1,0,1,0,1]]) - sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) - sage: E.systematic_positions() - (0, 2, 4, 6) - - The systematic positions correspond to the positions which carry information in a codeword:: - - sage: MS = E.message_space() - sage: m = MS.random_element() - sage: c = m * E.generator_matrix() - sage: pos = E.systematic_positions() - sage: info = MS([c[i] for i in pos]) - sage: m == info - True - - When constructing a systematic encoder with specific systematic - positions, then it is guaranteed that this method returns exactly those - positions (even if another choice might also be systematic):: - - sage: G = Matrix(GF(2), [[1,0,0,0],\ - [0,1,0,0],\ - [0,0,1,1]]) - sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C, systematic_positions=[0,1,3]) - sage: E.systematic_positions() - (0, 1, 3) - """ - return self._systematic_positions if self._systematic_positions else self.generator_matrix().pivots() - - ####################### decoders ############################### class LinearCodeSyndromeDecoder(Decoder): diff --git a/src/sage/coding/linear_code_no_metric.py b/src/sage/coding/linear_code_no_metric.py new file mode 100644 index 00000000000..e34c8316378 --- /dev/null +++ b/src/sage/coding/linear_code_no_metric.py @@ -0,0 +1,1268 @@ +r""" +Generic structures for linear codes of any metirc + +Class supporting methods available for linear codes over any metric (Hamming, +rank). +""" + +from copy import copy + +from sage.coding.abstract_code import AbstractCode +from sage.modules.module import Module +from sage.categories.modules import Modules +from sage.modules.free_module import VectorSpace +from sage.coding.encoder import Encoder +from sage.misc.cachefunc import cached_method +from sage.matrix.matrix_space import MatrixSpace +from sage.rings.integer import Integer +from sage.structure.parent import Parent +from sage.rings.integer_ring import ZZ + +class AbstractLinearCodeNoMetric(AbstractCode, Module): + r""" + Abstract class for linear codes of any metric. + + This class contains all the methods that can be used on any linear code + of any metric. Every abstract class of linear codes over some metric (e.g. + abstract class for linear codes over the Hamming metric, + :class:`sage.coding.linear_code.AbstractLinearCode`) should inherit from + this class. + + To create a new class of linear codes over some metrics, you need to: + + - inherit from AbstractLinearCodeNoMetric + + - call AbstractCode ``__init__`` method in the subclass constructor. + Example: ``super(SubclassName, self).__init__(length, "EncoderName", + "DecoderName", "metric")``. + + - add the following two lines on the class level:: + + _registered_encoders = {} + _registered_decoders = {} + + + - fill the dictionary of its encoders in ``sage.coding.__init__.py`` file. + Example: I want to link the encoder ``MyEncoderClass`` to ``MyNewCodeClass`` + under the name ``MyEncoderName``. + All I need to do is to write this line in the ``__init__.py`` file: + ``MyNewCodeClass._registered_encoders["NameOfMyEncoder"] = MyEncoderClass`` + and all instances of ``MyNewCodeClass`` will be able to use instances of + ``MyEncoderClass``. + + - fill the dictionary of its decoders in ``sage.coding.__init__`` file. + Example: I want to link the encoder ``MyDecoderClass`` to ``MyNewCodeClass`` + under the name ``MyDecoderName``. + All I need to do is to write this line in the ``__init__.py`` file: + ``MyNewCodeClass._registered_decoders["NameOfMyDecoder"] = MyDecoderClass`` + and all instances of ``MyNewCodeClass`` will be able to use instances of + ``MyDecoderClass``. + + - create a generic constructor representative of you abstract class. This + generic constructor is a class for unstructured linear codes given by some + generator and considered over the given metric. A good example of this is + :class:`sage.coding.linear_code.LinearCode`, which is a generic constructor + for :class:`sage.coding.linear_code.AbstractLinearCode`, an abstract class + for linear codes over the Hamming metric. + + - set a private field in the ``__init__`` method specifying the generic + constructor, (e.g. ``MyAbstractCode._generic_constructor = MyCode``) + + + It is assumed that the subclass codes are linear over ``base_field``. To + test this, it is recommended to add a test suite test to the generic + constructor. To do this, create a representative of your code `C` and run + ``TestSuite(C).run()``. A good example of this is in + :class:`sage.coding.linear_code.LinearCode`. + + + As AbstractLinearCodeNoMetric is not designed to be implemented, it does not + have any representation methods. You should implement ``_repr_`` and ``_latex_`` + methods in the subclass. + + .. WARNING:: + + A lot of methods of the abstract class rely on the knowledge of a generator matrix. + It is thus strongly recommended to set an encoder with a generator matrix implemented + as a default encoder. + + TESTS: + + If the name of the default decoder is not known by the class, it will raise + a exception:: + + sage: from sage.coding.linear_code_no_metric import AbstractLinearCodeNoMetric + sage: class MyCodeFamily(AbstractLinearCodeNoMetric): + ....: def __init__(self, field, length, dimension, generator_matrix): + ....: AbstractLinearCodeNoMetric.__init__(self, field, length, "Systematic", "Fail", "MyMetric") + ....: self._dimension = dimension + ....: self._generator_matrix = generator_matrix + ....: def generator_matrix(self): + ....: return self._generator_matrix + ....: def _repr_(self): + ....: return "[%d, %d] dummy code over GF(%s)" % (self.length(), self.dimension(), self.base_field().cardinality()) + + sage: generator_matrix = matrix(GF(17), 5, 10, + ....: {(i,i):1 for i in range(5)}) + sage: C = MyCodeFamily(GF(17), 10, 5, generator_matrix) + Traceback (most recent call last): + ... + ValueError: You must set a valid decoder as default decoder for this code, by filling in the dictionary of registered decoders + + If the name of the default encoder is not known by the class, it will raise + an exception:: + + sage: class MyCodeFamily2(sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric): + ....: def __init__(self, field, length, dimension, generator_matrix): + ....: sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric.__init__(self, field, length, "Fail", "Syndrome", "MyMetric") + ....: self._dimension = dimension + ....: self._generator_matrix = generator_matrix + ....: def generator_matrix(self): + ....: return self._generator_matrix + ....: def _repr_(self): + ....: return "[%d, %d] dummy code over GF(%s)" % (self.length(), self.dimension(), self.base_field().cardinality()) + + sage: C = MyCodeFamily2(GF(17), 10, 5, generator_matrix) + Traceback (most recent call last): + ... + ValueError: You must set a valid encoder as default encoder for this code, by filling in the dictionary of registered encoders + + A ring instead of a field:: + + sage: codes.LinearCode(IntegerModRing(4),matrix.ones(4)) + Traceback (most recent call last): + ... + ValueError: 'generator' must be defined on a field (not a ring) + """ + _registered_encoders = {} + _registered_decoders = {} + + def __init__(self, base_field, length, default_encoder_name, default_decoder_name, metric='Hamming'): + """ + Initializes mandatory parameters that any linear code shares. + + This method only exists for inheritance purposes as it initializes + parameters that need to be known by every linear code. The class + :class:`sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric` + should never be directly instantiated. + + INPUT: + + - ``base_field`` -- the base field of ``self`` + + - ``length`` -- the length of ``self`` (a Python int or a Sage Integer, must be > 0) + + - ``default_encoder_name`` -- the name of the default encoder of ``self`` + + - ``default_decoder_name`` -- the name of the default decoder of ``self`` + + - ``metric`` -- (default: ``Hamming``) the metric of ``self`` + """ + + self._registered_encoders['Systematic'] = LinearCodeSystematicEncoder + + if not base_field.is_field(): + raise ValueError("'generator' must be defined on a field (not a ring)") + if not default_encoder_name in self._registered_encoders: + raise ValueError("You must set a valid encoder as default encoder for this code, by filling in the dictionary of registered encoders") + if not default_decoder_name in self._registered_decoders: + raise ValueError("You must set a valid decoder as default decoder for this code, by filling in the dictionary of registered decoders") + + #if not self.dimension() <= length: + # raise ValueError("The dimension of the code can be at most its length, {}".format(length)) + + super(AbstractLinearCodeNoMetric, self).__init__(length, default_encoder_name, default_decoder_name, metric) + cat = Modules(base_field).FiniteDimensional().WithBasis().Finite() + facade_for = VectorSpace(base_field, self._length) + self.Element = type(facade_for.an_element()) #for when we made this a non-facade parent + Parent.__init__(self, base=base_field, facade=facade_for, category=cat) + + def base_field(self): + r""" + Return the base field of ``self``. + + EXAMPLES:: + + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) + sage: C = LinearCode(G) + sage: C.base_field() + Finite Field of size 2 + """ + return self.base_ring() + + def ambient_space(self): + r""" + Returns the ambient vector space of ``self``. + + EXAMPLES:: + + sage: C = codes.HammingCode(GF(2), 3) + sage: C.ambient_space() + Vector space of dimension 7 over Finite Field of size 2 + """ + return VectorSpace(self.base_ring(),self.length()) + + def generator_matrix(self, encoder_name=None, **kwargs): + r""" + Returns a generator matrix of ``self``. + + INPUT: + + - ``encoder_name`` -- (default: ``None``) name of the encoder which will be + used to compute the generator matrix. The default encoder of ``self`` + will be used if default value is kept. + + - ``kwargs`` -- all additional arguments are forwarded to the construction of the + encoder that is used. + + EXAMPLES:: + + sage: G = matrix(GF(3),2,[1,-1,1,-1,1,1]) + sage: code = LinearCode(G) + sage: code.generator_matrix() + [1 2 1] + [2 1 1] + """ + E = self.encoder(encoder_name, **kwargs) + return E.generator_matrix() + + def dimension(self): + r""" + Returns the dimension of this code. + + EXAMPLES:: + + sage: G = matrix(GF(2),[[1,0,0],[1,1,0]]) + sage: C = LinearCode(G) + sage: C.dimension() + 2 + + TESTS: + + Check that :trac:`21156` is fixed:: + + sage: from sage.coding.linear_code import AbstractLinearCode + sage: from sage.coding.encoder import Encoder + sage: class MonkeyCode(AbstractLinearCode): + ....: _registered_encoders = {} + ....: _registered_decoders = {} + ....: def __init__(self): + ....: super(MonkeyCode, self).__init__(GF(5), 10, "Monkey", "Syndrome") + ....: + sage: class MonkeyEncoder(Encoder): + ....: def __init__(self, code): + ....: super(MonkeyEncoder, self).__init__(C) + ....: @cached_method + ....: def generator_matrix(self): + ....: G = identity_matrix(GF(5), 5).augment(matrix(GF(5), 5, 7)) + ....: return G + ....: + sage: MonkeyCode._registered_encoders["Monkey"] = MonkeyEncoder + sage: C = MonkeyCode() + sage: C.dimension() + 5 + """ + try: + return self._dimension + except AttributeError: + dimension = self.generator_matrix().nrows() + self._dimension = dimension + return self._dimension + + def cardinality(self): + r""" + Return the size of this code. + + EXAMPLES:: + + sage: C = codes.HammingCode(GF(2), 3) + sage: C.cardinality() + 16 + sage: len(C) + 16 + """ + return self.base_ring().order()**self.dimension() + + __len__ = cardinality + + def rate(self): + r""" + Return the ratio of the number of information symbols to + the code length. + + EXAMPLES:: + + sage: C = codes.HammingCode(GF(2), 3) + sage: C.rate() + 4/7 + """ + return self.dimension() / self.length() + + @cached_method + def gens(self): + r""" + Returns the generators of this code as a list of vectors. + + EXAMPLES:: + + sage: C = codes.HammingCode(GF(2), 3) + sage: C.gens() + [(1, 0, 0, 0, 0, 1, 1), (0, 1, 0, 0, 1, 0, 1), (0, 0, 1, 0, 1, 1, 0), (0, 0, 0, 1, 1, 1, 1)] + """ + return self.generator_matrix().rows() + + def basis(self): + r""" + Returns a basis of ``self``. + + OUTPUT: + + - ``Sequence`` - an immutable sequence whose universe is ambient space of ``self``. + + EXAMPLES:: + + sage: C = codes.HammingCode(GF(2), 3) + sage: C.basis() + [ + (1, 0, 0, 0, 0, 1, 1), + (0, 1, 0, 0, 1, 0, 1), + (0, 0, 1, 0, 1, 1, 0), + (0, 0, 0, 1, 1, 1, 1) + ] + sage: C.basis().universe() + Vector space of dimension 7 over Finite Field of size 2 + """ + gens = self.gens() + from sage.structure.sequence import Sequence + return Sequence(gens, universe=self.ambient_space(), check = False, immutable=True, cr=True) + + @cached_method + def parity_check_matrix(self): + r""" + Returns the parity check matrix of ``self``. + + The parity check matrix of a linear code `C` corresponds to the + generator matrix of the dual code of `C`. + + EXAMPLES:: + + sage: C = codes.HammingCode(GF(2), 3) + sage: Cperp = C.dual_code() + sage: C; Cperp + [7, 4] Hamming Code over GF(2) + [7, 3] linear code over GF(2) + sage: C.generator_matrix() + [1 0 0 0 0 1 1] + [0 1 0 0 1 0 1] + [0 0 1 0 1 1 0] + [0 0 0 1 1 1 1] + sage: C.parity_check_matrix() + [1 0 1 0 1 0 1] + [0 1 1 0 0 1 1] + [0 0 0 1 1 1 1] + sage: Cperp.parity_check_matrix() + [1 0 0 0 0 1 1] + [0 1 0 0 1 0 1] + [0 0 1 0 1 1 0] + [0 0 0 1 1 1 1] + sage: Cperp.generator_matrix() + [1 0 1 0 1 0 1] + [0 1 1 0 0 1 1] + [0 0 0 1 1 1 1] + """ + G = self.generator_matrix() + H = G.right_kernel() + M = H.basis_matrix() + M.set_immutable() + return M + + def syndrome(self, r): + r""" + Returns the syndrome of ``r``. + + The syndrome of ``r`` is the result of `H \times r` where `H` is + the parity check matrix of ``self``. If ``r`` belongs to ``self``, + its syndrome equals to the zero vector. + + INPUT: + + - ``r`` -- a vector of the same length as ``self`` + + OUTPUT: + + - a column vector + + EXAMPLES:: + + sage: MS = MatrixSpace(GF(2),4,7) + sage: G = MS([[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]]) + sage: C = LinearCode(G) + sage: r = vector(GF(2), (1,0,1,0,1,0,1)) + sage: r in C + True + sage: C.syndrome(r) + (0, 0, 0) + + If ``r`` is not a codeword, its syndrome is not equal to zero:: + + sage: r = vector(GF(2), (1,0,1,0,1,1,1)) + sage: r in C + False + sage: C.syndrome(r) + (0, 1, 1) + + Syndrome computation works fine on bigger fields:: + + sage: C = codes.random_linear_code(GF(59), 12, 4) + sage: c = C.random_element() + sage: C.syndrome(c) + (0, 0, 0, 0, 0, 0, 0, 0) + """ + return self.parity_check_matrix()*r + + def __contains__(self, v): + r""" + Returns True if `v` can be coerced into ``self``. Otherwise, returns False. + + EXAMPLES:: + + sage: C = codes.HammingCode(GF(2), 3) + sage: vector((1, 0, 0, 0, 0, 1, 1)) in C # indirect doctest + True + sage: vector((1, 0, 0, 0, 2, 1, 1)) in C # indirect doctest + True + sage: vector((1, 0, 0, 0, 0, 1/2, 1)) in C # indirect doctest + False + """ + if not v in self.ambient_space() or len(v) != self.length(): + return False + return self.syndrome(v) == 0 + + def systematic_generator_matrix(self, systematic_positions=None): + """ + Return a systematic generator matrix of the code. + + A generator matrix of a code is called systematic if it contains + a set of columns forming an identity matrix. + + INPUT: + + - ``systematic_positions`` -- (default: ``None``) if supplied, the set + of systematic positions in the systematic generator matrix. See the + documentation for :class:`LinearCodeSystematicEncoder` details. + + EXAMPLES:: + + sage: G = matrix(GF(3), [[ 1, 2, 1, 0],\ + [ 2, 1, 1, 1]]) + sage: C = LinearCode(G) + sage: C.generator_matrix() + [1 2 1 0] + [2 1 1 1] + sage: C.systematic_generator_matrix() + [1 2 0 1] + [0 0 1 2] + + Specific systematic positions can also be requested: + + sage: C.systematic_generator_matrix(systematic_positions=[3,2]) + [1 2 0 1] + [1 2 1 0] + """ + systematic_positions = tuple(systematic_positions) if systematic_positions else None + return self.encoder("Systematic", systematic_positions=systematic_positions).generator_matrix() + + def standard_form(self, return_permutation=True): + r""" + Returns a linear code which is permutation-equivalent to ``self`` and + admits a generator matrix in standard form. + + A generator matrix is in standard form if it is of the form `[I \vert + A]`, where `I` is the `k \times k` identity matrix. Any code admits a + generator matrix in systematic form, i.e. where a subset of the columns + form the identity matrix, but one might need to permute columns to allow + the identity matrix to be leading. + + INPUT: + + - ``return_permutation`` -- (default: ``True``) if ``True``, the column + permutation which brings ``self`` into the returned code is also + returned. + + OUTPUT: + + - A :class:`LinearCode` whose :meth:`systematic_generator_matrix` is + guaranteed to be of the form `[I \vert A]`. + + EXAMPLES:: + + sage: C = codes.HammingCode(GF(2), 3) + sage: C.generator_matrix() + [1 0 0 0 0 1 1] + [0 1 0 0 1 0 1] + [0 0 1 0 1 1 0] + [0 0 0 1 1 1 1] + sage: Cs,p = C.standard_form() + sage: p + [] + sage: Cs is C + True + sage: C = LinearCode(matrix(GF(2), [[1,0,0,0,1,1,0],\ + [0,1,0,1,0,1,0],\ + [0,0,0,0,0,0,1]])) + sage: Cs, p = C.standard_form() + sage: p + [1, 2, 7, 3, 4, 5, 6] + sage: Cs.generator_matrix() + [1 0 0 0 0 1 1] + [0 1 0 0 1 0 1] + [0 0 1 0 0 0 0] + """ + E = self.encoder("Systematic") + if E.systematic_positions() == tuple(range(self.dimension())): + from sage.combinat.permutation import Permutation + return self, Permutation([]) + else: + perm = E.systematic_permutation() + return self.permuted_code(perm), perm + + def redundancy_matrix(self): + r""" + Returns the non-identity columns of a systematic generator matrix for + ``self``. + + A systematic generator matrix is a generator matrix such that a subset + of its columns forms the identity matrix. This method returns the + remaining part of the matrix. + + For any given code, there can be many systematic generator matrices + (depending on which positions should form the identity). This method + will use the matrix returned by + :meth:`AbstractLinearCode.systematic_generator_matrix`. + + OUTPUT: + + - An `k \times (n-k)` matrix. + + EXAMPLES:: + + sage: C = codes.HammingCode(GF(2), 3) + sage: C.generator_matrix() + [1 0 0 0 0 1 1] + [0 1 0 0 1 0 1] + [0 0 1 0 1 1 0] + [0 0 0 1 1 1 1] + sage: C.redundancy_matrix() + [0 1 1] + [1 0 1] + [1 1 0] + [1 1 1] + sage: C = LinearCode(matrix(GF(3),2,[1,2,0,\ + 2,1,1])) + sage: C.systematic_generator_matrix() + [1 2 0] + [0 0 1] + sage: C.redundancy_matrix() + [2] + [0] + """ + E = self.encoder("Systematic") + G = E.generator_matrix() + return G.delete_columns(E.systematic_positions()) + + @cached_method + def information_set(self): + """ + Return an information set of the code. + + Return value of this method is cached. + + A set of column positions of a generator matrix of a code + is called an information set if the corresponding columns + form a square matrix of full rank. + + OUTPUT: + + - Information set of a systematic generator matrix of the code. + + EXAMPLES:: + + sage: G = matrix(GF(3),2,[1,2,0,\ + 2,1,1]) + sage: code = LinearCode(G) + sage: code.systematic_generator_matrix() + [1 2 0] + [0 0 1] + sage: code.information_set() + (0, 2) + """ + return self.encoder("Systematic").systematic_positions() + + def is_information_set(self, positions): + """ + Return whether the given positions form an information set. + + INPUT: + + - A list of positions, i.e. integers in the range 0 to `n-1` where `n` + is the length of `self`. + + OUTPUT: + + - A boolean indicating whether the positions form an information set. + + + EXAMPLES:: + + sage: G = matrix(GF(3),2,[1,2,0,\ + 2,1,1]) + sage: code = LinearCode(G) + sage: code.is_information_set([0,1]) + False + sage: code.is_information_set([0,2]) + True + """ + try: + self.encoder("Systematic", systematic_positions=tuple(positions)) + return True + except ValueError: + return False + + def __iter__(self): + """ + Return an iterator over the elements of this linear code. + + EXAMPLES:: + + sage: C = codes.HammingCode(GF(2), 3) + sage: [list(c) for c in C if c.hamming_weight() < 4] + [[0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 1, 1], + [0, 1, 0, 0, 1, 0, 1], [0, 0, 1, 0, 1, 1, 0], + [1, 1, 1, 0, 0, 0, 0], [1, 0, 0, 1, 1, 0, 0], + [0, 1, 0, 1, 0, 1, 0], [0, 0, 1, 1, 0, 0, 1]] + + TESTS:: + + sage: C = codes.HammingCode(GF(2), 3) + sage: L = list(C) + sage: L[10].is_immutable() + True + + """ + from sage.modules.finite_submodule_iter import \ + FiniteFieldsubspace_iterator + return FiniteFieldsubspace_iterator(self.generator_matrix(), immutable=True) + + def __getitem__(self, i): + r""" + Returns the `i`-th codeword of this code. + + The implementation of this depends on the implementation of the + :meth:`.__iter__` method. + + The implementation is as follows. Suppose that: + + - the primitive element of the base_ring of this code is `a`, + - the prime subfield is `p`, + - the field has order `p^m`, + - the code has dimension `k`, + - and the generator matrix is `G`. + + Then the :meth:`.__iter__` method returns the elements in this order: + + 1. first, the following ordered list is returned: + ``[i*a^0 * G[0] for i in range(p)]`` + 2. Next, the following ordered list is returned: + ``[i*a^0 * G[0] + a^1*G[0] for i in range(p)]`` + 3. This continues till we get + ``[(i*a^0 +(p-1)*a^1 +...+ (p-1)*a^(m-1))*G[0] for i in range(p)]`` + 4. Then, we move to G[1]: + ``[i*a^0 * G[0] + a^0*G[1] for i in range(p)]``, + and so on. + Hence the `i`-th element can be obtained by the p-adic expansion + of `i` as ``[i_0, i_1, ...,i_{m-1}, i_m, i_{m+1}, ..., i_{km-1}].`` + The element that is generated is: + + .. MATH:: + + \begin{aligned} + & (i_0 a^0 + i_1 a^1 + \cdots + i_{m-1} a^{m-1}) G[0] + \\ + & (i_m a^0 + i_{m+1} a^1 + \cdots + i_{2m-1} a^{m-1}) G[1] + \\ + & \vdots\\ + & (i_{(k-1)m} a^0 + \cdots + i_{km-1} a^{m-1}) G[k-1] + \end{aligned} + + EXAMPLES:: + + sage: G = Matrix(GF(3), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: C = LinearCode(G) + sage: C[24] + (2, 2, 0, 1, 2, 2, 0) + sage: C[24] == C.list()[24] + True + + TESTS:: + + sage: C = random_matrix(GF(25,'a'), 2, 7).row_space() + sage: C = LinearCode(C.basis_matrix()) + sage: Clist = C.list() + sage: all(C[i] == Clist[i] for i in range(len(C))) + True + + Check that only the indices less than the size of the code are + allowed:: + + sage: C[25**2] + Traceback (most recent call last): + ... + IndexError: The value of the index 'i' (=625) must be between + 0 and 'q^k -1' (=624), inclusive, where 'q' is the size of the + base field and 'k' is the dimension of the code. + + Check that codewords are immutable. See :trac:`16338`:: + + sage: C[0].is_immutable() + True + + """ + # IMPORTANT: If the __iter__() function implementation is changed + # then the implementation here must also be changed so that + # list(self)[i] and self[i] both return the same element. + + F = self.base_ring() + maxindex = F.order()**self.dimension()-1 + if i < 0 or i > maxindex: + raise IndexError("The value of the index 'i' (={}) must be between " + "0 and 'q^k -1' (={}), inclusive, where 'q' is " + "the size of the base field and 'k' is the " + "dimension of the code.".format(i, maxindex)) + + a = F.primitive_element() + m = F.degree() + p = F.prime_subfield().order() + A = [a ** k for k in range(m)] + G = self.generator_matrix() + N = self.dimension()*F.degree() # the total length of p-adic vector + ivec = Integer(i).digits(p, padto=N) + + codeword = 0 + row = 0 + for g in G: + codeword += sum(ivec[j+row*m]*A[j] for j in range(m)) * g + row += 1 + + # The codewords for a specific code can not change. So, we set them + # to be immutable. + codeword.set_immutable() + return codeword + + def __hash__(self): + r""" + Returns the hash value of ``self``. + + EXAMPLES:: + + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: C = LinearCode(G) + sage: hash(C) #random + 9015017528451745710 + + If ``C1`` and ``C2`` are two codes which only differ by the + coefficients of their generator matrices, their hashes are + different (we check that the bug found in :trac:`18813` is + fixed):: + + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: C1 = LinearCode(G) + sage: G = Matrix(GF(2), [[1,0,0,1,0,1,0],[0,1,0,0,1,0,0],[0,0,1,1,0,1,0],[0,0,0,0,0,0,1]]) + sage: C2 = LinearCode(G) + sage: hash(C1) != hash(C2) + True + """ + Str = str(self) + G = self.generator_matrix() + return hash((Str, G)) ^ hash(Str) ^ hash(G) + + def is_subcode(self, other): + """ + Returns ``True`` if ``self`` is a subcode of ``other``. + + EXAMPLES:: + + sage: C1 = codes.HammingCode(GF(2), 3) + sage: G1 = C1.generator_matrix() + sage: G2 = G1.matrix_from_rows([0,1,2]) + sage: C2 = LinearCode(G2) + sage: C2.is_subcode(C1) + True + sage: C1.is_subcode(C2) + False + sage: C3 = C1.extended_code() + sage: C1.is_subcode(C3) + False + sage: C4 = C1.punctured([1]) + sage: C4.is_subcode(C1) + False + sage: C5 = C1.shortened([1]) + sage: C5.is_subcode(C1) + False + sage: C1 = codes.HammingCode(GF(9,"z"), 3) + sage: G1 = C1.generator_matrix() + sage: G2 = G1.matrix_from_rows([0,1,2]) + sage: C2 = LinearCode(G2) + sage: C2.is_subcode(C1) + True + """ + G = self.generator_matrix() + for r in G.rows(): + if not(r in other): + return False + return True + + def is_permutation_automorphism(self,g): + r""" + Returns `1` if `g` is an element of `S_n` (`n` = length of self) and + if `g` is an automorphism of self. + + EXAMPLES:: + + sage: C = codes.HammingCode(GF(3), 3) + sage: g = SymmetricGroup(13).random_element() + sage: C.is_permutation_automorphism(g) + 0 + sage: MS = MatrixSpace(GF(2),4,8) + sage: G = MS([[1,0,0,0,1,1,1,0],[0,1,1,1,0,0,0,0],[0,0,0,0,0,0,0,1],[0,0,0,0,0,1,0,0]]) + sage: C = LinearCode(G) + sage: S8 = SymmetricGroup(8) + sage: g = S8("(2,3)") + sage: C.is_permutation_automorphism(g) + 1 + sage: g = S8("(1,2,3,4)") + sage: C.is_permutation_automorphism(g) + 0 + """ + basis = self.generator_matrix().rows() + H = self.parity_check_matrix() + V = H.column_space() + HGm = H*g.matrix() + for c in basis: + if HGm*c != V(0): + return False + return True + + def permuted_code(self, p): + r""" + Returns the permuted code, which is equivalent to ``self`` via the + column permutation ``p``. + + EXAMPLES:: + + sage: C = codes.HammingCode(GF(2), 3) + sage: G = C.permutation_automorphism_group(); G + Permutation Group with generators [(4,5)(6,7), (4,6)(5,7), (2,3)(6,7), (2,4)(3,5), (1,2)(5,6)] + sage: g = G("(2,3)(6,7)") + sage: Cg = C.permuted_code(g) + sage: Cg + [7, 4] linear code over GF(2) + sage: C.generator_matrix() == Cg.systematic_generator_matrix() + True + """ + if not hasattr(self, "_generic_constructor"): + raise NotImplementedException("Generic constructor not set for the class of codes") + G = copy(self.generator_matrix()) + G.permute_columns(p) + return self._generic_constructor(G) + + def dual_code(self): + r""" + Returns the dual code `C^{\perp}` of the code `C`, + + .. MATH:: + + C^{\perp} = \{ v \in V\ |\ v\cdot c = 0,\ \forall c \in C \}. + + EXAMPLES:: + + sage: C = codes.HammingCode(GF(2), 3) + sage: C.dual_code() + [7, 3] linear code over GF(2) + sage: C = codes.HammingCode(GF(4, 'a'), 3) + sage: C.dual_code() + [21, 3] linear code over GF(4) + """ + if not hasattr(self, "_generic_constructor"): + raise NotImplementedException("Generic constructor not set for the class of codes") + return self._generic_constructor(self.parity_check_matrix()) + + def is_self_dual(self): + """ + Returns ``True`` if the code is self-dual (in the usual Hamming inner + product) and ``False`` otherwise. + + EXAMPLES:: + + sage: C = codes.GolayCode(GF(2)) + sage: C.is_self_dual() + True + sage: C = codes.HammingCode(GF(2), 3) + sage: C.is_self_dual() + False + """ + return self == self.dual_code() + + def is_self_orthogonal(self): + """ + Returns ``True`` if this code is self-orthogonal and ``False`` + otherwise. + + A code is self-orthogonal if it is a subcode of its dual. + + EXAMPLES:: + + sage: C = codes.GolayCode(GF(2)) + sage: C.is_self_orthogonal() + True + sage: C = codes.HammingCode(GF(2), 3) + sage: C.is_self_orthogonal() + False + sage: C = codes.QuasiQuadraticResidueCode(11) # optional - gap_packages (Guava package) + sage: C.is_self_orthogonal() # optional - gap_packages (Guava package) + True + """ + return self.is_subcode(self.dual_code()) + + +####################### encoders ############################### + + +class LinearCodeSystematicEncoder(Encoder): + r""" + Encoder based on a generator matrix in systematic form for Linear codes. + + To encode an element of its message space, this encoder first builds a + generator matrix in systematic form. What is called systematic form here + is the reduced row echelon form of a matrix, which is not necessarily + `[I \vert H]`, where `I` is the identity block and `H` the parity block. + One can refer to :meth:`LinearCodeSystematicEncoder.generator_matrix` + for a concrete example. + Once such a matrix has been computed, it is used to encode any message + into a codeword. + + This encoder can also serve as the default encoder of a code defined by a + parity check matrix: if the :class:`LinearCodeSystematicEncoder` detects + that it is the default encoder, it computes a generator matrix as the + reduced row echelon form of the right kernel of the parity check matrix. + + INPUT: + + - ``code`` -- The associated code of this encoder. + + - ``systematic_positions`` -- (default: ``None``) the positions in codewords that + should correspond to the message symbols. A list of `k` distinct integers in + the range 0 to `n-1` where `n` is the length of the code and `k` its + dimension. The 0th symbol of a message will then be at position + ``systematic_positions[0]``, the 1st index at position + ``systematic_positions[1]``, etc. A ``ValueError`` is raised at + construction time if the supplied indices do not form an information set. + + EXAMPLES: + + The following demonstrates the basic usage of :class:`LinearCodeSystematicEncoder`:: + + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0,0],\ + [1,0,0,1,1,0,0,0],\ + [0,1,0,1,0,1,0,0],\ + [1,1,0,1,0,0,1,1]]) + sage: C = LinearCode(G) + sage: E = codes.encoders.LinearCodeSystematicEncoder(C) + sage: E.generator_matrix() + [1 0 0 0 0 1 1 1] + [0 1 0 0 1 0 1 1] + [0 0 1 0 1 1 0 0] + [0 0 0 1 1 1 1 1] + sage: E2 = codes.encoders.LinearCodeSystematicEncoder(C, systematic_positions=[5,4,3,2]) + sage: E2.generator_matrix() + [1 0 0 0 0 1 1 1] + [0 1 0 0 1 0 1 1] + [1 1 0 1 0 0 1 1] + [1 1 1 0 0 0 0 0] + + An error is raised if one specifies systematic positions which do not form + an information set:: + + sage: E3 = codes.encoders.LinearCodeSystematicEncoder(C, systematic_positions=[0,1,6,7]) + Traceback (most recent call last): + ... + ValueError: systematic_positions are not an information set + + + We exemplify how to use :class:`LinearCodeSystematicEncoder` as the default + encoder. The following class is the dual of the repetition code:: + + sage: class DualRepetitionCode(sage.coding.linear_code.AbstractLinearCode): + ....: def __init__(self, field, length): + ....: sage.coding.linear_code.AbstractLinearCode.__init__(self,field, length, "Systematic", "Syndrome") + ....: + ....: def parity_check_matrix(self): + ....: return Matrix(self.base_field(), [1]*self.length()) + ....: + ....: def _repr_(self): + ....: return "Dual of the [%d, 1] Repetition Code over GF(%s)" % (self.length(), self.base_field().cardinality()) + ....: + sage: DualRepetitionCode(GF(3), 5).generator_matrix() + [1 0 0 0 2] + [0 1 0 0 2] + [0 0 1 0 2] + [0 0 0 1 2] + + + An exception is thrown if :class:`LinearCodeSystematicEncoder` is the default encoder but no + parity check matrix has been specified for the code:: + + sage: class BadCodeFamily(sage.coding.linear_code.AbstractLinearCode): + ....: def __init__(self, field, length): + ....: sage.coding.linear_code.AbstractLinearCode.__init__(self, field, length, "Systematic", "Syndrome") + ....: + ....: def _repr_(self): + ....: return "I am a badly defined code" + ....: + sage: BadCodeFamily(GF(3), 5).generator_matrix() + Traceback (most recent call last): + ... + ValueError: a parity check matrix must be specified if LinearCodeSystematicEncoder is the default encoder + """ + + def __init__(self, code, systematic_positions=None): + r""" + EXAMPLES:: + + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: C = LinearCode(G) + sage: E = codes.encoders.LinearCodeSystematicEncoder(C) + sage: E + Systematic encoder for [7, 4] linear code over GF(2) + """ + super(LinearCodeSystematicEncoder, self).__init__(code) + self._systematic_positions = tuple(systematic_positions) if systematic_positions else None + if systematic_positions: + # Test that systematic_positions consists of integers in the right + # range. We test that len(systematic_positions) = code.dimension() + # in self.generator_matrix() to avoid possible infinite recursion. + if (not all( e in ZZ and e >= 0 and e < code.length() for e in systematic_positions)) \ + or len(systematic_positions) != len(set(systematic_positions)): + raise ValueError("systematic positions must be a tuple of distinct integers in the range 0 to n-1 where n is the length of the code") + # Test that the systematic positions are an information set + self.generator_matrix() + + + def __eq__(self, other): + r""" + Tests equality between LinearCodeSystematicEncoder objects. + + EXAMPLES:: + + sage: G = Matrix(GF(3), [[1,0,0,1,0,1,0,1,2],[0,1,0,2,2,0,1,1,0],[0,0,1,0,2,2,2,1,2]]) + sage: E1 = codes.encoders.LinearCodeSystematicEncoder(LinearCode(G)) + sage: E2 = codes.encoders.LinearCodeSystematicEncoder(LinearCode(G)) + sage: E1 == E2 + True + sage: E1.systematic_positions() + (0, 1, 2) + sage: E3 = codes.encoders.LinearCodeSystematicEncoder(LinearCode(G), systematic_positions=(2,5,6)) + sage: E3.systematic_positions() + (2, 5, 6) + sage: E1 == E3 + False + """ + return isinstance(other, LinearCodeSystematicEncoder)\ + and self.code() == other.code()\ + and self.systematic_positions() == other.systematic_positions() + + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: C = LinearCode(G) + sage: E = codes.encoders.LinearCodeSystematicEncoder(C) + sage: E + Systematic encoder for [7, 4] linear code over GF(2) + """ + return "Systematic encoder for %s" % self.code() + + def _latex_(self): + r""" + Return a latex representation of ``self``. + + EXAMPLES:: + + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]]) + sage: C = LinearCode(G) + sage: E = codes.encoders.LinearCodeSystematicEncoder(C) + sage: latex(E) + \textnormal{Systematic encoder for }[7, 4]\textnormal{ Linear code over }\Bold{F}_{2} + """ + return "\\textnormal{Systematic encoder for }%s" % self.code()._latex_() + + @cached_method + def generator_matrix(self): + r""" + Returns a generator matrix in systematic form of the associated code of ``self``. + + Systematic form here means that a subsets of the columns of the matrix + forms the identity matrix. + + .. NOTE:: + + The matrix returned by this method will not necessarily be `[I \vert H]`, where `I` + is the identity block and `H` the parity block. If one wants to know which columns + create the identity block, one can call :meth:`systematic_positions` + + EXAMPLES:: + + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],\ + [1,0,0,1,1,0,0],\ + [0,1,0,1,0,1,0],\ + [1,1,0,1,0,0,1]]) + sage: C = LinearCode(G) + sage: E = codes.encoders.LinearCodeSystematicEncoder(C) + sage: E.generator_matrix() + [1 0 0 0 0 1 1] + [0 1 0 0 1 0 1] + [0 0 1 0 1 1 0] + [0 0 0 1 1 1 1] + + We can ask for different systematic positions:: + + sage: E2 = codes.encoders.LinearCodeSystematicEncoder(C, systematic_positions=[5,4,3,2]) + sage: E2.generator_matrix() + [1 0 0 0 0 1 1] + [0 1 0 0 1 0 1] + [1 1 0 1 0 0 1] + [1 1 1 0 0 0 0] + + Another example where there is no generator matrix of the form `[I \vert H]`:: + + sage: G = Matrix(GF(2), [[1,1,0,0,1,0,1],\ + [1,1,0,0,1,0,0],\ + [0,0,1,0,0,1,0],\ + [0,0,1,0,1,0,1]]) + sage: C = LinearCode(G) + sage: E = codes.encoders.LinearCodeSystematicEncoder(C) + sage: E.generator_matrix() + [1 1 0 0 0 1 0] + [0 0 1 0 0 1 0] + [0 0 0 0 1 1 0] + [0 0 0 0 0 0 1] + """ + C = self.code() + # This if statement detects if this encoder is itself the default encoder. + # In this case, attempt building the generator matrix from the parity + # check matrix + if hasattr(self, "_use_pc_matrix"): + if self._use_pc_matrix == 1: + self._use_pc_matrix = 2 + return C.parity_check_matrix().right_kernel_matrix() + else: + raise ValueError("a parity check matrix must be specified if LinearCodeSystematicEncoder is the default encoder") + else: + self._use_pc_matrix = 1 + M = copy(C.generator_matrix()) + if not self._systematic_positions: + M.echelonize() + else: + k = M.nrows() # it is important that k is *not* computed as C.dimension() to avoid possible cyclic dependency + if len(self._systematic_positions) != k: + raise ValueError("systematic_positions must be a tuple of length equal to the dimension of the code") + # Permute the columns of M and bring to reduced row echelon formb + perm = self.systematic_permutation() + M.permute_columns(perm) + M.echelonize() + if M[:,:k].is_singular(): + raise ValueError("systematic_positions are not an information set") + M.permute_columns(perm.inverse()) + M.set_immutable() + return M + + def systematic_permutation(self): + r""" + Returns a permutation which would take the systematic positions into [0,..,k-1] + + EXAMPLES:: + + sage: C = LinearCode(matrix(GF(2), [[1,0,0,0,1,1,0],\ + [0,1,0,1,0,1,0],\ + [0,0,0,0,0,0,1]])) + sage: E = codes.encoders.LinearCodeSystematicEncoder(C) + sage: E.systematic_positions() + (0, 1, 6) + sage: E.systematic_permutation() + [1, 2, 7, 3, 4, 5, 6] + """ + n = self.code().length() + systematic_positions = self.systematic_positions() + k = len(systematic_positions) + lp = [ None ]*n + for (i,j) in zip(range(k), systematic_positions): + lp[i] = j + j = k + set_sys_pos = set(systematic_positions) + for i in range(n): + if not i in set_sys_pos: + lp[j] = i + j += 1 + from sage.combinat.permutation import Permutation + return Permutation([1 + e for e in lp]) + + def systematic_positions(self): + r""" + Returns a tuple containing the indices of the columns which form an + identity matrix when the generator matrix is in systematic form. + + EXAMPLES:: + + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],\ + [1,0,0,1,1,0,0],\ + [0,1,0,1,0,1,0],\ + [1,1,0,1,0,0,1]]) + sage: C = LinearCode(G) + sage: E = codes.encoders.LinearCodeSystematicEncoder(C) + sage: E.systematic_positions() + (0, 1, 2, 3) + + We take another matrix with a less nice shape:: + + sage: G = Matrix(GF(2), [[1,1,0,0,1,0,1],\ + [1,1,0,0,1,0,0],\ + [0,0,1,0,0,1,0],\ + [0,0,1,0,1,0,1]]) + sage: C = LinearCode(G) + sage: E = codes.encoders.LinearCodeSystematicEncoder(C) + sage: E.systematic_positions() + (0, 2, 4, 6) + + The systematic positions correspond to the positions which carry information in a codeword:: + + sage: MS = E.message_space() + sage: m = MS.random_element() + sage: c = m * E.generator_matrix() + sage: pos = E.systematic_positions() + sage: info = MS([c[i] for i in pos]) + sage: m == info + True + + When constructing a systematic encoder with specific systematic + positions, then it is guaranteed that this method returns exactly those + positions (even if another choice might also be systematic):: + + sage: G = Matrix(GF(2), [[1,0,0,0],\ + [0,1,0,0],\ + [0,0,1,1]]) + sage: C = LinearCode(G) + sage: E = codes.encoders.LinearCodeSystematicEncoder(C, systematic_positions=[0,1,3]) + sage: E.systematic_positions() + (0, 1, 3) + """ + return self._systematic_positions if self._systematic_positions else self.generator_matrix().pivots() diff --git a/src/sage/coding/punctured_code.py b/src/sage/coding/punctured_code.py index eea926bf884..36a881d6d0a 100644 --- a/src/sage/coding/punctured_code.py +++ b/src/sage/coding/punctured_code.py @@ -239,7 +239,7 @@ def random_element(self, *args, **kwds): Returns a random codeword of ``self``. This method does not trigger the computation of - ``self``'s :meth:`sage.coding.linear_code.generator_matrix`. + ``self``'s :meth:`sage.coding.linear_code_no_metric.generator_matrix`. INPUT: From c7165267cd4bfc9edfd3c087a723088203b3c55e Mon Sep 17 00:00:00 2001 From: Marketa Slukova Date: Mon, 19 Aug 2019 11:21:08 +0200 Subject: [PATCH 62/77] Added no metric to coding documentation index. Moved zero method from AbstractLinearCode. Changed base_field check. --- src/doc/en/reference/coding/index.rst | 1 + src/sage/coding/linear_code.py | 17 ----------------- src/sage/coding/linear_code_no_metric.py | 23 ++++++++++++++++++++--- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/doc/en/reference/coding/index.rst b/src/doc/en/reference/coding/index.rst index 2e3011f37e7..4be4e36ae94 100644 --- a/src/doc/en/reference/coding/index.rst +++ b/src/doc/en/reference/coding/index.rst @@ -14,6 +14,7 @@ decoders. The following modules provide the base classes defining them. :maxdepth: 1 sage/coding/abstract_code + sage/coding/linear_code_no_metric sage/coding/linear_code sage/coding/channel sage/coding/encoder diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index 1a19b8e93c1..3fb144500cb 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -2013,23 +2013,6 @@ def weight_enumerator(self, names=None, bivariate=True): x, = R.gens() return sum(spec[i]*x**i for i in range(n+1)) - @cached_method - def zero(self): - r""" - Returns the zero vector of ``self``. - - EXAMPLES:: - - sage: C = codes.HammingCode(GF(2), 3) - sage: C.zero() - (0, 0, 0, 0, 0, 0, 0) - sage: C.sum(()) # indirect doctest - (0, 0, 0, 0, 0, 0, 0) - sage: C.sum((C.gens())) # indirect doctest - (1, 1, 1, 1, 1, 1, 1) - """ - return self.ambient_space().zero() - def zeta_polynomial(self, name="T"): r""" Returns the Duursma zeta polynomial of this code. diff --git a/src/sage/coding/linear_code_no_metric.py b/src/sage/coding/linear_code_no_metric.py index e34c8316378..c515b67d563 100644 --- a/src/sage/coding/linear_code_no_metric.py +++ b/src/sage/coding/linear_code_no_metric.py @@ -129,10 +129,10 @@ class AbstractLinearCodeNoMetric(AbstractCode, Module): A ring instead of a field:: - sage: codes.LinearCode(IntegerModRing(4),matrix.ones(4)) + sage: MyCodeFamily2(IntegerModRing(4), 4, 4, matrix.ones(4)) Traceback (most recent call last): ... - ValueError: 'generator' must be defined on a field (not a ring) + ValueError: 'base_field' must be a field (and Ring of integers modulo 4 is not one) """ _registered_encoders = {} _registered_decoders = {} @@ -162,7 +162,7 @@ def __init__(self, base_field, length, default_encoder_name, default_decoder_nam self._registered_encoders['Systematic'] = LinearCodeSystematicEncoder if not base_field.is_field(): - raise ValueError("'generator' must be defined on a field (not a ring)") + raise ValueError("'base_field' must be a field (and {} is not one)".format(base_field)) if not default_encoder_name in self._registered_encoders: raise ValueError("You must set a valid encoder as default encoder for this code, by filling in the dictionary of registered encoders") if not default_decoder_name in self._registered_decoders: @@ -931,6 +931,23 @@ def is_self_orthogonal(self): """ return self.is_subcode(self.dual_code()) + @cached_method + def zero(self): + r""" + Returns the zero vector of ``self``. + + EXAMPLES:: + + sage: C = codes.HammingCode(GF(2), 3) + sage: C.zero() + (0, 0, 0, 0, 0, 0, 0) + sage: C.sum(()) # indirect doctest + (0, 0, 0, 0, 0, 0, 0) + sage: C.sum((C.gens())) # indirect doctest + (1, 1, 1, 1, 1, 1, 1) + """ + return self.ambient_space().zero() + ####################### encoders ############################### From 0b5baa0ce9058caf053c06285ce1bf6ea2a32173 Mon Sep 17 00:00:00 2001 From: Durand Amaury Date: Thu, 30 Jan 2020 11:15:14 +0100 Subject: [PATCH 63/77] Add function hash --- src/sage/coding/linear_code.py | 5 +++++ src/sage/coding/linear_code_no_metric.py | 3 +++ 2 files changed, 8 insertions(+) diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index 3fb144500cb..dc27b109203 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -2277,6 +2277,11 @@ def __init__(self, generator, d=None): self._dimension = generator.rank() self._minimum_distance = d + def __hash__(self): + Str = str(self) + G = self.generator_matrix() + return hash((Str, G)) + def _repr_(self): r""" See the docstring for :meth:`LinearCode`. diff --git a/src/sage/coding/linear_code_no_metric.py b/src/sage/coding/linear_code_no_metric.py index c515b67d563..4f5acff9967 100644 --- a/src/sage/coding/linear_code_no_metric.py +++ b/src/sage/coding/linear_code_no_metric.py @@ -226,6 +226,9 @@ def generator_matrix(self, encoder_name=None, **kwargs): E = self.encoder(encoder_name, **kwargs) return E.generator_matrix() + def __eq__(self, other): + return self.generator_matrix() == other.generator_matrix() + def dimension(self): r""" Returns the dimension of this code. From 158d73fbc655eb05ffe09e8dc735833dbb91221b Mon Sep 17 00:00:00 2001 From: Durand Amaury Date: Thu, 30 Jan 2020 11:53:12 +0100 Subject: [PATCH 64/77] Error commit on linear_code_no_metric in precedent commit --- src/sage/coding/linear_code_no_metric.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sage/coding/linear_code_no_metric.py b/src/sage/coding/linear_code_no_metric.py index 4f5acff9967..eb87a84439f 100644 --- a/src/sage/coding/linear_code_no_metric.py +++ b/src/sage/coding/linear_code_no_metric.py @@ -226,8 +226,6 @@ def generator_matrix(self, encoder_name=None, **kwargs): E = self.encoder(encoder_name, **kwargs) return E.generator_matrix() - def __eq__(self, other): - return self.generator_matrix() == other.generator_matrix() def dimension(self): r""" From 52f845182ac6b5c8b957e299118b078e797ac059 Mon Sep 17 00:00:00 2001 From: vipul79321 Date: Tue, 3 Mar 2020 19:10:39 +0530 Subject: [PATCH 65/77] updated according comment 34 --- src/sage/graphs/generators/families.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/sage/graphs/generators/families.py b/src/sage/graphs/generators/families.py index 8ff8a76dba6..708f63abdd0 100644 --- a/src/sage/graphs/generators/families.py +++ b/src/sage/graphs/generators/families.py @@ -3649,18 +3649,30 @@ def CubeConnectedCycle(d): if d == 1: G.allow_loops(True) - #only d = 1 requires loops + # only d = 1 requires loops G.add_edges([((0,0),(0,1)), ((0,0),(0,0)), ((0,1),(0,1))]) return G - - for x in range(1< Date: Tue, 3 Mar 2020 21:53:17 +0530 Subject: [PATCH 66/77] updated for d = 2 --- src/sage/graphs/generators/families.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/sage/graphs/generators/families.py b/src/sage/graphs/generators/families.py index 708f63abdd0..f670b7dcf35 100644 --- a/src/sage/graphs/generators/families.py +++ b/src/sage/graphs/generators/families.py @@ -3652,27 +3652,17 @@ def CubeConnectedCycle(d): # only d = 1 requires loops G.add_edges([((0,0),(0,1)), ((0,0),(0,0)), ((0,1),(0,1))]) return G - + if d == 2: # only d = 2 require multiple edges G.allow_multiple_edges(True) - for x in range(1< Date: Wed, 4 Mar 2020 00:25:37 +0530 Subject: [PATCH 67/77] Fixed ticket 29275 --- src/sage/graphs/graph_input.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/graph_input.py b/src/sage/graphs/graph_input.py index dc4a21f9931..724f8b9162f 100644 --- a/src/sage/graphs/graph_input.py +++ b/src/sage/graphs/graph_input.py @@ -392,7 +392,7 @@ def from_oriented_incidence_matrix(G, M, loops=False, multiedges=False, weighted if len(NZ) != 2: raise ValueError("there must be two nonzero entries (-1 & 1) per column") L = sorted(set(c.list())) - if L != [-1, 0, 1]: + if L != [-1, 0, 1] and L != [-1, 1]: raise ValueError("each column represents an edge: -1 goes to 1") if c[NZ[0]] == -1: positions.append(tuple(NZ)) From 109da234a0e3c499a6ec1cf2a05496a19599b9c7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 3 Mar 2020 18:20:41 -0500 Subject: [PATCH 68/77] src/doc/en/developer/doctesting.rst: Mention use of tox --- src/doc/en/developer/doctesting.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/doc/en/developer/doctesting.rst b/src/doc/en/developer/doctesting.rst index 1db4909e8b5..70c715f7c42 100644 --- a/src/doc/en/developer/doctesting.rst +++ b/src/doc/en/developer/doctesting.rst @@ -106,6 +106,12 @@ Sage to test its own modules. Even if we have a system-wide Sage installation, using that version to doctest the modules of a local installation is a recipe for confusion. +If your system Python has the ``tox`` package, you can also run the Sage +doctester as follows:: + + [jdemeyer@sage sage-6.0]$ cd src + [jdemeyer@sage src]$ tox -- sage/games/sudoku.py + Troubleshooting =============== From a1f0cbe2c1ad23e8940247be1a83fa15fb302b5e Mon Sep 17 00:00:00 2001 From: vipul79321 Date: Wed, 4 Mar 2020 13:58:18 +0530 Subject: [PATCH 69/77] update according to comment 3 --- src/sage/graphs/graph_input.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/graph_input.py b/src/sage/graphs/graph_input.py index 724f8b9162f..78f29fccaeb 100644 --- a/src/sage/graphs/graph_input.py +++ b/src/sage/graphs/graph_input.py @@ -391,8 +391,8 @@ def from_oriented_incidence_matrix(G, M, loops=False, multiedges=False, weighted NZ = c.nonzero_positions() if len(NZ) != 2: raise ValueError("there must be two nonzero entries (-1 & 1) per column") - L = sorted(set(c.list())) - if L != [-1, 0, 1] and L != [-1, 1]: + L = sorted([c[i] for i in NZ]) + if L != [-1, 1]: raise ValueError("each column represents an edge: -1 goes to 1") if c[NZ[0]] == -1: positions.append(tuple(NZ)) From d7fc60e464a05a081d1fa097f77d1c600e1a0b23 Mon Sep 17 00:00:00 2001 From: vipul79321 Date: Wed, 4 Mar 2020 14:56:59 +0530 Subject: [PATCH 70/77] Tests added for ticket 29276 and 29275 --- src/sage/graphs/graph_input.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/sage/graphs/graph_input.py b/src/sage/graphs/graph_input.py index 78f29fccaeb..86f7eeb7ac7 100644 --- a/src/sage/graphs/graph_input.py +++ b/src/sage/graphs/graph_input.py @@ -382,6 +382,27 @@ def from_oriented_incidence_matrix(G, M, loops=False, multiedges=False, weighted Traceback (most recent call last): ... ValueError: each column represents an edge: -1 goes to 1 + + Handle incidence matrix containing a column with only zeros (:trac:`29276`):: + + sage: m = Matrix([[0,1],[0,-1],[0,0]]) + sage: m + [ 0 1] + [ 0 -1] + [ 0 0] + sage: G = DiGraph(m,format='incidence_matrix') + sage: list(G.edges(labels=False)) + [(1, 0)] + + Handle incidence matrix [[1],[-1]] (:trac:`29275`):: + + sage: m = Matrix([[1],[-1]]) + sage: m + [ 1] + [-1] + sage: G = DiGraph(m,format='incidence_matrix') + sage: list(G.edges(labels=False)) + [(1, 0)] """ from sage.structure.element import is_Matrix assert is_Matrix(M) @@ -389,6 +410,8 @@ def from_oriented_incidence_matrix(G, M, loops=False, multiedges=False, weighted positions = [] for c in M.columns(): NZ = c.nonzero_positions() + if not NZ: + continue if len(NZ) != 2: raise ValueError("there must be two nonzero entries (-1 & 1) per column") L = sorted([c[i] for i in NZ]) From 8f364e5fea9148fd33ad0e55e78947239de3bd30 Mon Sep 17 00:00:00 2001 From: Simon Brandhorst Date: Wed, 4 Mar 2020 10:58:12 +0100 Subject: [PATCH 71/77] hardcode some elements in the doctests and pep --- src/sage/groups/fqf_orthogonal.py | 54 +++++++++++++++++-------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/sage/groups/fqf_orthogonal.py b/src/sage/groups/fqf_orthogonal.py index 41e33d0a0c1..4294048425f 100644 --- a/src/sage/groups/fqf_orthogonal.py +++ b/src/sage/groups/fqf_orthogonal.py @@ -14,8 +14,9 @@ The isometries act on elements of their domain:: - sage: T.gen(0) * Oq.an_element() - (1, 3) + sage: g = Oq(matrix(ZZ, 2, [0, 3, 1, 2])) + sage: T.gen(0) * g + (0, 3) Isometries are represented with respect to the Smith form generators of `T`:: @@ -70,7 +71,7 @@ class FqfIsometry(AbelianGroupAutomorphism): sage: q = matrix.diagonal([2/3]) sage: q = TorsionQuadraticForm(q) sage: G = q.orthogonal_group() - sage: g = G(matrix(ZZ,1,[2])) + sage: g = G(matrix(ZZ, 1, [2])) sage: g [2] """ @@ -81,7 +82,7 @@ def _repr_(self): EXAMPLES:: - sage: q = matrix.diagonal([2/3,4/3]) + sage: q = matrix.diagonal([2/3, 4/3]) sage: q = TorsionQuadraticForm(q) sage: G = q.orthogonal_group() sage: g = G.one() @@ -97,10 +98,10 @@ def __call__(self, x): EXAMPLES:: - sage: q = matrix.diagonal([2/3,4/3]) + sage: q = matrix.diagonal([2/3, 4/3]) sage: q = TorsionQuadraticForm(q) sage: G = q.orthogonal_group() - sage: g = G(matrix(ZZ,2,[1,0,0,2])) + sage: g = G(matrix(ZZ, 2, [1, 0, 0, 2])) sage: g [1 0] [0 2] @@ -142,20 +143,20 @@ class FqfOrthogonalGroup(AbelianGroupAutomorphismGroup_subgroup): [ 0 2/3 0] [ 0 0 2/3] generated by 2 elements - sage: q = matrix.diagonal(QQ,[3/2,1/4,1/4]) + sage: q = matrix.diagonal(QQ, [3/2, 1/4, 1/4]) sage: T = TorsionQuadraticForm(q) sage: T.orthogonal_group().order() 8 Action on an invariant subquotient:: - sage: T = TorsionQuadraticForm(matrix.diagonal([2/9]+ [2/27])) + sage: T = TorsionQuadraticForm(matrix.diagonal([2/9] + [2/27])) sage: S1 = 3 * T sage: S2 = 9 * T sage: Q = S1/S2 sage: G = T.orthogonal_group() - sage: g = G(matrix(ZZ,2,[8,0,0,1])) - sage: Q.1*g + sage: g = G(matrix(ZZ, 2, [8, 0, 0, 1])) + sage: Q.1 * g (0, 2) """ Element = FqfIsometry @@ -218,7 +219,9 @@ def _element_constructor_(self, x, check=False): sage: q = L.discriminant_group() sage: OL = L.orthogonal_group() sage: Oq = q.orthogonal_group() - sage: f = OL.an_element() + sage: f = matrix(ZZ, 2, [0, 1, -1, -1]) + sage: f = matrix.block_diagonal([f, f]) + sage: f = OL(f) sage: fbar = Oq(f) sage: fbar [4 3] @@ -296,7 +299,7 @@ def _get_action_(self, S, op, self_on_left): EXAMPLES:: - sage: q = matrix.diagonal([2/3,4/3]) + sage: q = matrix.diagonal([2/3, 4/3]) sage: q = TorsionQuadraticForm(q) sage: G = q.orthogonal_group() sage: G._get_action_(q, operator.mul, False) @@ -344,7 +347,7 @@ def _subgroup_constructor(self, libgap_subgroup): EXAMPLES:: - sage: q = TorsionQuadraticForm(matrix.diagonal([2/3,2/3])) + sage: q = TorsionQuadraticForm(matrix.diagonal([2/3, 2/3])) sage: G = q.orthogonal_group() sage: G.subgroup(G.gens()[:1]) # indirect doctest Group of isometries of @@ -388,15 +391,15 @@ class ActionOnFqf(Action): EXAMPLES:: - sage: q = matrix.diagonal([2/3,4/3]) + sage: q = matrix.diagonal([2/3, 4/3]) sage: q = TorsionQuadraticForm(q) sage: G = q.orthogonal_group() - sage: g = G(matrix.diagonal([2,2])) + sage: g = G(matrix.diagonal([2, 2])) sage: g [2 0] [0 2] sage: x = q.0 - sage: x*g + sage: x * g (2, 0) """ def __init__(self, orthogonal_grp, fqf, on_subquotient=False, is_left=False): @@ -438,8 +441,9 @@ def _act_(self, g, a): sage: from sage.groups.fqf_orthogonal import ActionOnFqf sage: q = matrix.diagonal([2/3, 4/3]) sage: q = TorsionQuadraticForm(q) - sage: G = q.orthogonal_group() - sage: g = G.gens()[0] + sage: g1 = 2 * matrix.identity(2) + sage: g2 = matrix(ZZ, 2, [1, 0, 0, 2]) + sage: G = q.orthogonal_group(gens=[g1, g2]) sage: A = ActionOnFqf(G, q) sage: A Right action by Group of isometries of @@ -453,16 +457,16 @@ def _act_(self, g, a): [ 0 2/3] sage: x = q.an_element() sage: g = G.an_element() - sage: A(x,g).parent() + sage: A(x, g).parent() Finite quadratic module over Integer Ring with invariants (3, 3) Gram matrix of the quadratic form with values in Q/2Z: [4/3 0] [ 0 2/3] - sage: q = TorsionQuadraticForm(matrix.diagonal([2/3,2/3,6/8,1/4])) + sage: q = TorsionQuadraticForm(matrix.diagonal([2/3, 2/3, 6/8, 1/4])) sage: G = q.orthogonal_group() sage: q2 = q.primary_part(2) - sage: g = G(matrix.diagonal([1,7])) - sage: q2.gen(1)*g + sage: g = G(matrix.diagonal([1, 7])) + sage: q2.gen(1) * g (0, 3) """ if self.is_left(): @@ -497,7 +501,7 @@ def _isom_fqf(A, B=None): EXAMPLES:: - sage: q = matrix.diagonal(QQ,3*[2/3]) + sage: q = matrix.diagonal(QQ, 3*[2/3]) sage: q = TorsionQuadraticForm(q) sage: gens = sage.groups.fqf_orthogonal._isom_fqf(q, q) sage: q1 = q.submodule_with_gens(gens) @@ -507,9 +511,9 @@ def _isom_fqf(A, B=None): TESTS:: sage: for p in primes_first_n(7)[1:]: # long time - ....: q = matrix.diagonal(QQ,3*[2/p]) # long time + ....: q = matrix.diagonal(QQ, 3 * [2/p]) # long time ....: q = TorsionQuadraticForm(q) # long time - ....: assert q.orthogonal_group().order()==GO(3,p).order() # long time + ....: assert q.orthogonal_group().order()==GO(3, p).order() # long time """ def orbits(G, L): r""" From 139c77461f7f67b7f9059d674d8ad315e0d6611e Mon Sep 17 00:00:00 2001 From: vipul79321 Date: Wed, 4 Mar 2020 19:16:41 +0530 Subject: [PATCH 72/77] issues merged --- src/sage/graphs/graph_input.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/graph_input.py b/src/sage/graphs/graph_input.py index 86f7eeb7ac7..972742d6195 100644 --- a/src/sage/graphs/graph_input.py +++ b/src/sage/graphs/graph_input.py @@ -383,7 +383,7 @@ def from_oriented_incidence_matrix(G, M, loops=False, multiedges=False, weighted ... ValueError: each column represents an edge: -1 goes to 1 - Handle incidence matrix containing a column with only zeros (:trac:`29276`):: + Handle incidence matrix containing a column with only zeros (:trac:`29275`):: sage: m = Matrix([[0,1],[0,-1],[0,0]]) sage: m From db76cac22774408fe7a15a03b78ccf88bec8c72f Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Wed, 4 Mar 2020 17:25:30 +0100 Subject: [PATCH 73/77] Trac 29247: change doctest to prevent merge conflict with #28882 --- src/doc/en/thematic_tutorials/coercion_and_categories.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/en/thematic_tutorials/coercion_and_categories.rst b/src/doc/en/thematic_tutorials/coercion_and_categories.rst index 9e5fdb47f71..b58c9c59de7 100644 --- a/src/doc/en/thematic_tutorials/coercion_and_categories.rst +++ b/src/doc/en/thematic_tutorials/coercion_and_categories.rst @@ -447,10 +447,10 @@ Sage's category framework can differentiate the two cases:: And indeed, ``MS2`` has *more* methods than ``MS1``:: sage: import inspect - sage: len([s for s in dir(MS1) if inspect.ismethod(getattr(MS1,s,None))]) - 82 - sage: len([s for s in dir(MS2) if inspect.ismethod(getattr(MS2,s,None))]) - 121 + sage: L1 = len([s for s in dir(MS1) if inspect.ismethod(getattr(MS1,s,None))]) + sage: L2 = len([s for s in dir(MS2) if inspect.ismethod(getattr(MS2,s,None))]) + sage: L1 < L2 + True This is because the class of ``MS2`` also inherits from the parent class for algebras:: From 91664c655108ac8de81eeaf648351f0f11859737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 4 Mar 2020 21:27:43 +0100 Subject: [PATCH 74/77] fix oeis doctest in tutorial --- src/sage/combinat/tutorial.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/tutorial.py b/src/sage/combinat/tutorial.py index 05308b2cc58..676fb6b3141 100644 --- a/src/sage/combinat/tutorial.py +++ b/src/sage/combinat/tutorial.py @@ -1731,8 +1731,8 @@ sage: oeis(L) # optional -- internet 0: A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1. - 1: A212804: Expansion of (1-x)/(1-x-x^2). - 2: A132636: a(n) = Fibonacci(n) mod n^3. + 1: ... + 2: ... This is an immediate consequence of the recurrence relation. One can also generate immediately all the Fibonacci words of a given length, From 85f81c6819c61f7985b4d641f823eb95a6d60f4c Mon Sep 17 00:00:00 2001 From: vipul79321 Date: Thu, 5 Mar 2020 09:09:52 +0530 Subject: [PATCH 75/77] updated to comment 39 --- src/sage/graphs/generators/families.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/generators/families.py b/src/sage/graphs/generators/families.py index f670b7dcf35..11ced1b92f0 100644 --- a/src/sage/graphs/generators/families.py +++ b/src/sage/graphs/generators/families.py @@ -3609,9 +3609,9 @@ def CubeConnectedCycle(d): INPUT: - - ``d`` -- The dimension of the desired hypercube as well as the length - of the cycle to be placed at each vertex of the `d`-dimensional - hypercube. `d` must be a positive integer. + - ``d`` -- The dimension of the desired hypercube as well as the length + of the cycle to be placed at each vertex of the `d`-dimensional + hypercube. `d` must be a positive integer. EXAMPLES: @@ -3624,6 +3624,7 @@ def CubeConnectedCycle(d): The diameter of cube-connected cycles for `d > 3` is `2d + \lfloor \frac{d}{2} \rfloor - 2` :: + sage: d = 4 sage: g = graphs.CubeConnectedCycle(d) sage: g.diameter() == 2*d+d//2-2 @@ -3656,7 +3657,10 @@ def CubeConnectedCycle(d): if d == 2: # only d = 2 require multiple edges G.allow_multiple_edges(True) - G.add_edges([((0, 0), (0, 1)), ((0, 0), (0, 1)), ((0, 0), (1, 0)), ((0, 1), (2, 1)), ((1, 0), (1, 1)), ((1, 0), (1, 1)), ((1, 1), (3, 1)), ((2, 0), (2, 1)), ((2, 0), (2, 1)), ((2, 0), (3, 0)), ((3, 0), (3, 1)), ((3, 0), (3, 1))]) + G.add_edges([((0, 0), (0, 1)), ((0, 0), (0, 1)), ((0, 0), (1, 0)), + ((0, 1), (2, 1)), ((1, 0), (1, 1)), ((1, 0), (1, 1)), + ((1, 1), (3, 1)), ((2, 0), (2, 1)), ((2, 0), (2, 1)), + ((2, 0), (3, 0)), ((3, 0), (3, 1)), ((3, 0), (3, 1))]) return G for x in range(1< Date: Thu, 5 Mar 2020 13:14:54 +0530 Subject: [PATCH 76/77] Patchbot issues fixed --- src/sage/graphs/generators/families.py | 18 ++++++++++++------ src/sage/graphs/graph_generators.py | 6 ++++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/sage/graphs/generators/families.py b/src/sage/graphs/generators/families.py index 11ced1b92f0..142e7768e67 100644 --- a/src/sage/graphs/generators/families.py +++ b/src/sage/graphs/generators/families.py @@ -407,7 +407,8 @@ def EgawaGraph(p, s): prefix = v[:i] suffix = v[i+1:] for el in X: - if el == v[i]: continue + if el == v[i]: + continue u = prefix + (el,) + suffix g.add_edge(v,u) return g @@ -488,7 +489,8 @@ def HammingGraph(n, q, X=None): prefix = v[:i] suffix = v[i+1:] for el in X: - if el == v[i]: continue + if el == v[i]: + continue u = prefix + (el,) + suffix g.add_edge(v,u) return g @@ -1561,7 +1563,8 @@ def FibonacciTree(n): def fib(level, node, y): pos[node] = (node, y) - if level < 2: return + if level < 2: + return level -= 1 y -= s diff = F[level] @@ -1900,7 +1903,8 @@ def MycielskiGraph(k=1, relabel=True): g0 = MycielskiGraph(k-1) g = MycielskiStep(g0) g.name("Mycielski Graph " + str(k)) - if relabel: g.relabel() + if relabel: + g.relabel() return g @@ -2480,7 +2484,8 @@ def HanoiTowerGraph(pegs, disks, labels=True, positions=True): one = Integer(1) if positions: radius_multiplier = 1 + csc(pi/pegs) - sine = []; cosine = [] + sine = [] + cosine = [] for i in range(pegs): angle = 2*i*pi/float(pegs) sine.append(sin(angle)) @@ -2493,7 +2498,8 @@ def HanoiTowerGraph(pegs, disks, labels=True, positions=True): mapping[i] = tuple(state) state.reverse() if positions: - locx = 0.0; locy = 0.0 + locx = 0.0 + locy = 0.0 radius = 1.0 parity = -1.0 for index in range(disks): diff --git a/src/sage/graphs/graph_generators.py b/src/sage/graphs/graph_generators.py index d76ee2c123b..a0c9973abcf 100644 --- a/src/sage/graphs/graph_generators.py +++ b/src/sage/graphs/graph_generators.py @@ -794,7 +794,8 @@ def extra_property(x): gens = [] for i in range(vertices-1): gen = list(range(i)) - gen.append(i+1); gen.append(i) + gen.append(i+1) + gen.append(i) gen += list(range(i + 2, vertices)) gens.append(gen) for gg in canaug_traverse_edge(g, gens, property, loops=loops, sparse=sparse): @@ -2428,7 +2429,8 @@ def canaug_traverse_edge(g, aut_gens, property, dig=False, loops=False, sparse=T max_size = n*(n-1) else: max_size = (n*(n-1))>>1 # >> 1 is just / 2 (this is n choose 2) - if loops: max_size += n + if loops: + max_size += n if g.size() < max_size: # build a list representing C(g) - the edge to be added # is one of max_size choices From 6db1a26f5e25ac32752e1151514e3e38c7bde98c Mon Sep 17 00:00:00 2001 From: Release Manager Date: Sun, 8 Mar 2020 15:19:44 +0100 Subject: [PATCH 77/77] Updated SageMath version to 9.1.beta7 --- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 6 +++--- build/pkgs/configure/package-version.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index 26fb0956a5e..e900f3515ef 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 9.1.beta6, Release Date: 2020-03-01 +SageMath version 9.1.beta7, Release Date: 2020-03-08 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 2dca2ceb877..a08412a8fae 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=63dd5a30099d2285ba7d8914dc6a94213e704258 -md5=767a51cc156fec7e49d08cbaefc38d24 -cksum=1354891695 +sha1=7dcc12151cfd28e51461d4fd3495e1dbe40db8f0 +md5=536088bf9fed3f0904958b51bc872c43 +cksum=1081491918 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 41251af48f9..44754d5aeb1 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -30cb9d11bc3889744a2a27db00041d9cb40df522 +d77360886b95a58e3b7ba146fa464c91a0790876 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 624b0aa65b2..7348913b560 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -1,5 +1,5 @@ # Sage version information for shell scripts # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='9.1.beta6' -SAGE_RELEASE_DATE='2020-03-01' -SAGE_VERSION_BANNER='SageMath version 9.1.beta6, Release Date: 2020-03-01' +SAGE_VERSION='9.1.beta7' +SAGE_RELEASE_DATE='2020-03-08' +SAGE_VERSION_BANNER='SageMath version 9.1.beta7, Release Date: 2020-03-08' diff --git a/src/sage/version.py b/src/sage/version.py index 238d45f36fb..60cc79f7167 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '9.1.beta6' -date = '2020-03-01' -banner = 'SageMath version 9.1.beta6, Release Date: 2020-03-01' +version = '9.1.beta7' +date = '2020-03-08' +banner = 'SageMath version 9.1.beta7, Release Date: 2020-03-08'