From 10a3d1bf43adb57bfc5cbf2c51fcc8704b39bc9d Mon Sep 17 00:00:00 2001 From: Julian Rueth Date: Tue, 9 Apr 2013 18:44:45 +0000 Subject: [PATCH 001/698] (HEAD, refs/heads/stefan) Trac #14432: Fix __hash__ for unions of sets --- src/sage/sets/set.py | 339 ++++++++++++++++++------------------------- 1 file changed, 143 insertions(+), 196 deletions(-) diff --git a/src/sage/sets/set.py b/src/sage/sets/set.py index 242221a3cf5..5369c0f2fb5 100644 --- a/src/sage/sets/set.py +++ b/src/sage/sets/set.py @@ -14,10 +14,14 @@ - Florent Hivert (2010-06-17) - Adapted to categories - Nicolas M. Thiery (2011-03-15) - Added subset and superset methods + +- Julian Rueth (2013-04-09) - Collected common code in Set_object_binary, fixed __hash__. + """ #***************************************************************************** # Copyright (C) 2005 William Stein +# 2013 Julian Rueth # # Distributed under the terms of the GNU General Public License (GPL) # @@ -103,9 +107,9 @@ def Set(X): Set of all prime numbers: 2, 3, 5, 7, ... sage: Set(Subsets([1,2,3])).cardinality() 8 - sage: Set(iter([1,2,3])) + sage: S = Set(iter([1,2,3])); S {1, 2, 3} - sage: type(_) + sage: type(S) sage: S = Set([]) sage: TestSuite(S).run() @@ -964,7 +968,112 @@ def symmetric_difference(self, other): return Set_object.symmetric_difference(self, other) return Set_object_enumerated(self.set().symmetric_difference(other.set())) -class Set_object_union(Set_object): +class Set_object_binary(Set_object): + """ + An abstract common base class for :class:`Set_object_union`, + :class:`Set_object_intersection`, :class:`Set_object_difference`, and + :class:`Set_object_symmetric_difference`. + + INPUT: + + - ``X``, ``Y`` -- sets, the operands to ``op`` + + - ``op`` -- a string describing the binary operation + + - ``latex_op`` -- a string used for rendering this object in LaTeX + + EXAMPLES:: + + sage: X = Set(QQ^2) + sage: Y = Set(ZZ) + sage: from sage.sets.set import Set_object_binary + sage: S = Set_object_binary(X,Y,"union","\\cup"); S + Set-theoretic union of Set of elements of Vector space of dimension 2 over Rational Field and Set of elements of Integer Ring + + """ + def __init__(self, X, Y, op, latex_op): + """ + Initialization. + + TESTS:: + + sage: from sage.sets.set import Set_object_binary + sage: X = Set(QQ^2) + sage: Y = Set(ZZ) + sage: S = Set_object_binary(X,Y,"union","\\cup") + sage: type(S) + + + """ + self._X = X + self._Y = Y + self._op = op + self._latex_op = latex_op + Set_object.__init__(self, self) + + def _repr_(self): + r""" + Return a string representation of this set. + + EXAMPLES:: + + sage: Set(ZZ).union(Set(GF(5))) + Set-theoretic union of Set of elements of Integer Ring and {0, 1, 2, 3, 4} + + """ + return "Set-theoretic %s of %s and %s"%(self._op, self._X, self._Y) + + def _latex_(self): + r""" + Return a latex representation of this set. + + EXAMPLES:: + + sage: latex(Set(ZZ).union(Set(GF(5)))) + \Bold{Z} \cup \left\{0, 1, 2, 3, 4\right\} + + """ + return '%s %s %s'%(latex(self._X), self._latex_op, latex(self._Y)) + + def cardinality(self): + """ + This tries to return the cardinality of this set. + + Note that this is not likely to work in very much generality, + and may just hang if either set involved is infinite. + + EXAMPLES:: + + sage: X = Set(GF(13)).intersection(Set(ZZ)) + sage: X.cardinality() + 13 + """ + return len(list(self)) + + def __hash__(self): + """ + The hash value of this set. + + EXAMPLES:: + + sage: X = Set(GF(13)).intersection(Set(ZZ)) + sage: hash(X) + -7116597539855252506 # 64-bit + # 32-bit + + TESTS: + + Test that :trac:`14432` has been resolved:: + + sage: S=Set(ZZ).union(Set([infinity])) + sage: hash(S) + 1474285102670710969 # 64-bit + # 32-bit + + """ + return hash((self._X,self._Y,self._op)) + +class Set_object_union(Set_object_binary): """ A formal union of two sets. """ @@ -982,9 +1091,7 @@ def __init__(self, X, Y): sage: TestSuite(X).run() """ - self.__X = X - self.__Y = Y - Set_object.__init__(self, self) + Set_object_binary.__init__(self, X, Y, "union", "\\cup") def __cmp__(self, right): r""" @@ -1018,34 +1125,11 @@ def __cmp__(self, right): return -1 if not isinstance(right, Set_object_union): return -1 - if self.__X == right.__X and self.__Y == right.__Y or \ - self.__X == right.__Y and self.__Y == right.__X: + if self._X == right._X and self._Y == right._Y or \ + self._X == right._Y and self._Y == right._X: return 0 return -1 - def _repr_(self): - r""" - Return string representation of self. - - EXAMPLES:: - - sage: Set(ZZ).union(Set(GF(5))) - Set-theoretic union of Set of elements of Integer Ring and {0, 1, 2, 3, 4} - """ - return "Set-theoretic union of %s and %s"%(self.__X, - self.__Y) - - def _latex_(self): - r""" - Return latex representation of self. - - EXAMPLES:: - - sage: latex(Set(ZZ).union(Set(GF(5)))) - \Bold{Z} \cup \left\{0, 1, 2, 3, 4\right\} - """ - return '%s \\cup %s'%(latex(self.__X), latex(self.__Y)) - def __iter__(self): """ Return iterator over the elements of self. @@ -1055,9 +1139,9 @@ def __iter__(self): sage: [x for x in Set(GF(3)).union(Set(GF(2)))] [0, 1, 2, 0, 1] """ - for x in self.__X: + for x in self._X: yield x - for y in self.__Y: + for y in self._Y: yield y def __contains__(self, x): @@ -1076,7 +1160,7 @@ def __contains__(self, x): sage: GF(5)(0) in X False """ - return x in self.__X or x in self.__Y + return x in self._X or x in self._Y def cardinality(self): """ @@ -1094,9 +1178,9 @@ def cardinality(self): sage: X.cardinality() +Infinity """ - return self.__X.cardinality() + self.__Y.cardinality() + return self._X.cardinality() + self._Y.cardinality() -class Set_object_intersection(Set_object): +class Set_object_intersection(Set_object_binary): """ Formal intersection of two sets. """ @@ -1114,10 +1198,7 @@ def __init__(self, X, Y): sage: X = Set(IntegerRange(100)).intersection(Primes()) sage: TestSuite(X).run() """ - self.__X = X - self.__Y = Y - Set_object.__init__(self, self) - + Set_object_binary.__init__(self, X, Y, "intersection", "\\cap") def __cmp__(self, right): r""" @@ -1151,38 +1232,11 @@ def __cmp__(self, right): return -1 if not isinstance(right, Set_object_intersection): return -1 - if self.__X == right.__X and self.__Y == right.__Y or \ - self.__X == right.__Y and self.__Y == right.__X: + if self._X == right._X and self._Y == right._Y or \ + self._X == right._Y and self._Y == right._X: return 0 return -1 - def _repr_(self): - """ - Return string representation of self. - - EXAMPLES:: - - sage: X = Set(ZZ).intersection(Set(QQ)); X - Set-theoretic intersection of Set of elements of Integer Ring and Set of elements of Rational Field - sage: X.rename('Z /\ Q') - sage: X - Z /\ Q - """ - return "Set-theoretic intersection of %s and %s"%(self.__X, - self.__Y) - - def _latex_(self): - r""" - Return latex representation of self. - - EXAMPLES:: - - sage: X = Set(ZZ).intersection(Set(QQ)) - sage: latex(X) - \Bold{Z} \cap \Bold{Q} - """ - return '%s \\cap %s'%(latex(self.__X), latex(self.__Y)) - def __iter__(self): """ Return iterator through elements of self. @@ -1198,8 +1252,8 @@ def __iter__(self): sage: I.next() 2 """ - for x in self.__X: - if x in self.__Y: + for x in self._X: + if x in self._Y: yield x def __contains__(self, x): @@ -1227,26 +1281,9 @@ def __contains__(self, x): sage: pi in X False """ - return x in self.__X and x in self.__Y - - def cardinality(self): - """ - This tries to return the cardinality of this formal intersection. - - Note that this is not likely to work in very much generality, - and may just hang if either set involved is infinite. - - EXAMPLES:: - - sage: X = Set(GF(13)).intersection(Set(ZZ)) - sage: X.cardinality() - 13 - """ - return len(list(self)) + return x in self._X and x in self._Y - - -class Set_object_difference(Set_object): +class Set_object_difference(Set_object_binary): """ Formal difference of two sets. """ @@ -1257,16 +1294,13 @@ def __init__(self, X, Y): sage: S = Set(QQ) sage: T = Set(ZZ) sage: X = S.difference(T); X - Set-theoretic difference between Set of elements of Rational Field and Set of elements of Integer Ring + Set-theoretic difference of Set of elements of Rational Field and Set of elements of Integer Ring sage: latex(X) \Bold{Q} - \Bold{Z} sage: TestSuite(X).run() """ - self.__X = X - self.__Y = Y - Set_object.__init__(self, self) - + Set_object_binary.__init__(self, X, Y, "difference", "-") def __cmp__(self, right): r""" @@ -1304,37 +1338,10 @@ def __cmp__(self, right): return -1 if not isinstance(right, Set_object_difference): return -1 - if self.__X == right.__X and self.__Y == right.__Y: + if self._X == right._X and self._Y == right._Y: return 0 return -1 - def _repr_(self): - """ - Return string representation of self. - - EXAMPLES:: - - sage: X = Set(QQ).difference(Set(ZZ)); X - Set-theoretic difference between Set of elements of Rational Field and Set of elements of Integer Ring - sage: X.rename('Q - Z') - sage: X - Q - Z - """ - return "Set-theoretic difference between %s and %s"%(self.__X, - self.__Y) - - def _latex_(self): - r""" - Return latex representation of self. - - EXAMPLES:: - - sage: X = Set(QQ).difference(Set(ZZ)) - sage: latex(X) - \Bold{Q} - \Bold{Z} - """ - return '%s - %s'%(latex(self.__X), latex(self.__Y)) - def __iter__(self): """ Return iterator through elements of self. @@ -1358,8 +1365,8 @@ def __iter__(self): sage: I.next() -3 """ - for x in self.__X: - if x not in self.__Y: + for x in self._X: + if x not in self._Y: yield x def __contains__(self, x): @@ -1383,24 +1390,10 @@ def __contains__(self, x): sage: 5/2 in X True """ - return x in self.__X and x not in self.__Y - - def cardinality(self): - """ - This tries to return the cardinality of this formal intersection. - - Note that this is not likely to work in very much generality, - and may just hang if either set involved is infinite. + return x in self._X and x not in self._Y - EXAMPLES:: - sage: X = Set(GF(13)).difference(Set(Primes())) - sage: X.cardinality() - 8 - """ - return len(list(self)) - -class Set_object_symmetric_difference(Set_object): +class Set_object_symmetric_difference(Set_object_binary): """ Formal symmetric difference of two sets. """ @@ -1417,10 +1410,7 @@ def __init__(self, X, Y): sage: TestSuite(X).run() """ - self.__X = X - self.__Y = Y - Set_object.__init__(self, self) - + Set_object_binary.__init__(self, X, Y, "symmetric difference", "\\bigtriangleup") def __cmp__(self, right): r""" @@ -1448,38 +1438,11 @@ def __cmp__(self, right): return -1 if not isinstance(right, Set_object_symmetric_difference): return -1 - if self.__X == right.__X and self.__Y == right.__Y or \ - self.__X == right.__Y and self.__Y == right.__X: + if self._X == right._X and self._Y == right._Y or \ + self._X == right._Y and self._Y == right._X: return 0 return -1 - def _repr_(self): - """ - Return string representation of self. - - EXAMPLES:: - - sage: X = Set(ZZ).symmetric_difference(Set(QQ)); X - Set-theoretic symmetric difference of Set of elements of Integer Ring and Set of elements of Rational Field - sage: X.rename('Z symdif Q') - sage: X - Z symdif Q - """ - return "Set-theoretic symmetric difference of %s and %s"%(self.__X, - self.__Y) - - def _latex_(self): - r""" - Return latex representation of self. - - EXAMPLES:: - - sage: X = Set(ZZ).symmetric_difference(Set(QQ)) - sage: latex(X) - \Bold{Z} \bigtriangleup \Bold{Q} - """ - return '%s \\bigtriangleup %s'%(latex(self.__X), latex(self.__Y)) - def __iter__(self): """ Return iterator through elements of self. @@ -1504,15 +1467,14 @@ def __iter__(self): sage: I.next() -3 """ - for x in self.__X: - if x not in self.__Y: + for x in self._X: + if x not in self._Y: yield x - for y in self.__Y: - if y not in self.__X: + for y in self._Y: + if y not in self._X: yield y - def __contains__(self, x): """ Return true if self contains x. @@ -1538,20 +1500,5 @@ def __contains__(self, x): sage: 3 in X False """ - return (x in self.__X and x not in self.__Y) \ - or (x in self.__Y and x not in self.__X) - - def cardinality(self): - """ - This tries to return the cardinality of this formal symmetric difference. - - Note that this is not likely to work in very much generality, - and may just hang if either set involved is infinite. - - EXAMPLES:: - - sage: X = Set(GF(13)).symmetric_difference(Set(range(5))) - sage: X.cardinality() - 8 - """ - return len(list(self)) + return (x in self._X and x not in self._Y) \ + or (x in self._Y and x not in self._X) From e851c6f179661e67e79e8aac44aa82371e7ff963 Mon Sep 17 00:00:00 2001 From: Julian Rueth Date: Wed, 28 Aug 2013 16:05:00 +0200 Subject: [PATCH 002/698] fixed doctest for the hash of a union/intersection/... of sets --- src/sage/sets/set.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/sage/sets/set.py b/src/sage/sets/set.py index 5369c0f2fb5..014d10227a4 100644 --- a/src/sage/sets/set.py +++ b/src/sage/sets/set.py @@ -1054,21 +1054,25 @@ def __hash__(self): """ The hash value of this set. - EXAMPLES:: + + EXAMPLES: + + The hash values of equal sets are in general not equal since it is not + decidable whether two sets are equal:: sage: X = Set(GF(13)).intersection(Set(ZZ)) - sage: hash(X) - -7116597539855252506 # 64-bit - # 32-bit + sage: Y = Set(ZZ).intersection(Set(GF(13))) + sage: hash(X) == hash(Y) + False TESTS: Test that :trac:`14432` has been resolved:: - sage: S=Set(ZZ).union(Set([infinity])) - sage: hash(S) - 1474285102670710969 # 64-bit - # 32-bit + sage: S = Set(ZZ).union(Set([infinity])) + sage: T = Set(ZZ).union(Set([infinity])) + sage: hash(S) == hash(T) + True """ return hash((self._X,self._Y,self._op)) From 96aac188ea19fdf840cb5e75b649c873a49aaefe Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Mon, 1 Apr 2013 22:51:33 +0000 Subject: [PATCH 003/698] trac #14396: ISGCI update, small graphs and recognition --- build/pkgs/graphs/SPKG.txt | 3 + build/pkgs/graphs/checksums.ini | 6 +- build/pkgs/graphs/package-version.txt | 2 +- src/sage/graphs/isgci.py | 404 +++++++++++++++++++------- 4 files changed, 298 insertions(+), 117 deletions(-) diff --git a/build/pkgs/graphs/SPKG.txt b/build/pkgs/graphs/SPKG.txt index 195a82c7905..e959d94a449 100644 --- a/build/pkgs/graphs/SPKG.txt +++ b/build/pkgs/graphs/SPKG.txt @@ -20,6 +20,9 @@ N/A == Changelog == +== graphs-20130920.p5 (Nathann Cohen, 2013-09-20) == + * #14396: Update of isgci_sage.xml, added smallgraphs.txt + == graphs-20120404.p4 (R. Andrew Ohana, 2012-05-17) == * #13123: Move SAGE_DATA to SAGE_LOCAL/share diff --git a/build/pkgs/graphs/checksums.ini b/build/pkgs/graphs/checksums.ini index d180503bde6..8978e68f0ee 100644 --- a/build/pkgs/graphs/checksums.ini +++ b/build/pkgs/graphs/checksums.ini @@ -1,4 +1,4 @@ tarball=graphs-VERSION.tar.bz2 -sha1=3454dcbb5162f937f2bb62355cdfffd31ee70eee -md5=e738851391f5351bbd5d1a0e5e952fe3 -cksum=3090942230 +sha1=f78fa61daf3baafa088921f5e578ea19f556f963 +md5=2621b6cfd61797ab0be179653d7bcf3e +cksum=2747417664 diff --git a/build/pkgs/graphs/package-version.txt b/build/pkgs/graphs/package-version.txt index 2cdd9d04b50..fbae6e7f7f5 100644 --- a/build/pkgs/graphs/package-version.txt +++ b/build/pkgs/graphs/package-version.txt @@ -1 +1 @@ -20120404.p4 +20130920.p5 diff --git a/src/sage/graphs/isgci.py b/src/sage/graphs/isgci.py index 5124bd24134..2492ea61be0 100644 --- a/src/sage/graphs/isgci.py +++ b/src/sage/graphs/isgci.py @@ -13,10 +13,6 @@ How to use it? -------------- -The current limited aim of this module is to provide a pure Sage/Python -interface which is easier to deal with than a XML file. I hope it will be -rewritten many times until it stabilizes :-) - Presently, it is possible to use this database through the variables and methods present in the :obj:`graph_classes ` object. For instance:: @@ -24,6 +20,9 @@ sage: Trees = graph_classes.Tree sage: Chordal = graph_classes.Chordal +Inclusions +^^^^^^^^^^ + It is then possible to check the inclusion of classes inside of others, if the information is available in the database:: @@ -32,28 +31,29 @@ And indeed, trees are chordal graphs. -.. WARNING:: +The ISGCI database is not all-knowing, and so comparing two classes can return +``True``, ``False``, or ``Unknown`` (see the :mod:`documentation of the Unknown +truth value `). - The ISGCI database is not all-knowing, and so comparing two classes can - return ``True``, ``False``, or ``Unknown`` (see the :mod:`documentation of - the Unknown truth value `). +An *unknown* answer to ``A <= B`` only means that ISGCI cannot deduce from the +information in its database that ``A`` is a subclass of ``B`` nor that it is +not. For instance, ISGCI does not know at the moment that some chordal graphs +are not trees:: - An *unknown* answer to ``A <= B`` only means that ISGCI cannot deduce from - the information in its database that ``A`` is a subclass of ``B`` nor that - it is not. For instance, ISGCI does not know at the moment that some chordal - graphs are not trees:: + sage: graph_classes.Chordal <= graph_classes.Tree + Unknown - sage: graph_classes.Chordal <= graph_classes.Tree - Unknown +Descriptions +^^^^^^^^^^^^ -Given a graph class, one can obtain its associated information in the -ISGCI database with the :meth:`~GraphClass.description` method:: +Given a graph class, one can obtain its associated information in the ISGCI +database with the :meth:`~GraphClass.description` method:: sage: Chordal.description() Class of graphs : Chordal ------------------------- type : base - ID : gc_32 + id : gc_32 name : chordal Problems : @@ -64,18 +64,26 @@ Cliquewidth : Unbounded Cliquewidth expression : NP-complete Colourability : Linear + Cutwidth : NP-complete Domination : NP-complete + Feedback vertex set : Polynomial + Hamiltonian cycle : NP-complete + Hamiltonian path : NP-complete Independent set : Linear + Maximum bisection : Unknown + Maximum cut : NP-complete + Minimum bisection : Unknown Recognition : Linear Treewidth : Polynomial Weighted clique : Polynomial + Weighted feedback vertex set : Unknown Weighted independent set : Linear It is possible to obtain the complete list of the classes stored in ISGCI by calling the :meth:`~GraphClasses.show_all` method (beware -- long output):: sage: graph_classes.show_all() - ID | name | type | smallgraph + id | name | type | smallgraph ---------------------------------------------------------------------------------------------------------------------- gc_309 | $K_4$--minor--free | base | gc_541 | $N^*$ | base | @@ -96,6 +104,39 @@ sage: GC $P_4$--bipartite graphs +Recognition of graphs +^^^^^^^^^^^^^^^^^^^^^ + +The graph classes represented by the ISGCI database can alternatively be used to +access recognition algorithms. For instance, in order to check that a given +graph is a tree one has the following the options :: + + sage: graphs.PathGraph(5) in graph_classes.Tree + True + +or:: + + sage: graphs.PathGraph(5).is_tree() + True + +Furthermore, all ISGCI graph classes which are defined by the exclusion of a +finite sequence of induced subgraphs benefit from a generic recognition +algorithm. For instance :: + + sage: g = graphs.PetersenGraph() + sage: g in graph_classes.ClawFree + False + sage: g.line_graph() in graph_classes.ClawFree + True + +Or directly from ISGCI :: + + sage: gc = graph_classes.get_class("gc_441") + sage: gc + diamond--free graphs + sage: graphs.PetersenGraph() in gc + True + Predefined classes ------------------ @@ -120,12 +161,15 @@ * - Block - - :meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cut_vertices`, + - :meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cut_vertices` * - Chordal - :meth:`~sage.graphs.generic_graph.GenericGraph.is_chordal` + * - Claw-Free + - :meth:`~sage.graphs.graph_generators.GraphGenerators.ClawGraph` + * - Comparability - @@ -175,10 +219,9 @@ :meth:`~Graph.is_tree` * - UnitDisk - - :meth:`~sage.graphs.graph_generators.GraphGenerators.IntervalGraph`, + - :meth:`~sage.graphs.graph_generators.GraphGenerators.IntervalGraph` * - UnitInterval - - :meth:`~sage.graphs.generic_graph.GenericGraph.is_interval` Sage's view of ISGCI @@ -191,7 +234,7 @@ Below is what Sage knows of ``gc_249``:: sage: graph_classes.classes()['gc_249'] # random - {'problems': + {'problem': {'Independent set': 'Polynomial', 'Treewidth': 'Unknown', 'Weighted independent set': 'Polynomial', @@ -205,7 +248,7 @@ '3-Colourability': 'NP-complete', 'Recognition': 'Linear'}, 'type': 'base', - 'ID': 'gc_249', + 'id': 'gc_249', 'name': 'line'} **The class inclusion digraph**: Sage remembers the class inclusions through @@ -340,6 +383,7 @@ class is included in another one, we have to check whether there is in the #***************************************************************************** _XML_FILE = "isgci_sage.xml" +_SMALLGRAPHS_FILE = "smallgraphs.txt" class GraphClass(SageObject, CachedRepresentation): r""" @@ -364,10 +408,18 @@ class GraphClass(SageObject, CachedRepresentation): sage: Chordal >= Trees True """ - def __init__(self, name, gc_id): + def __init__(self, name, gc_id, recognition_function = None): r""" Class constructor + INPUT: + + - ``gc_id`` -- the ISGCI class ID + + - ``recognition_function`` -- a function of one argument `g`, which + return boolan answers to the question : *does ``g`` belong to the + class represented by ``gc_id`` ?* + EXAMPLE:: sage: graph_classes.Chordal # indirect doctest @@ -376,6 +428,9 @@ def __init__(self, name, gc_id): self._name = name self._gc_id = gc_id + if not recognition_function is None: + self._recognition_function = recognition_function + def _repr_(self): r""" Returns a short description of the class @@ -459,6 +514,90 @@ def __lt__(self, other): __gt__ = __ne__ = __lt__ + def forbidden_subgraphs(self): + r""" + Returns the list of forbidden induced subgraphs defining the class. + + If the graph class is not defined by a *finite* list of forbidden induced + subgraphs, ``None`` is returned instead. + + EXAMPLES:: + + sage: graph_classes.Perfect.forbidden_subgraphs() + sage: gc = graph_classes.get_class('gc_62') + sage: gc + claw--free graphs + sage: gc.forbidden_subgraphs() + [Graph on 4 vertices] + sage: gc.forbidden_subgraphs()[0].is_isomorphic(graphs.ClawGraph()) + True + """ + classes = GraphClasses().classes() + gc = classes[self._gc_id] + + if gc.get("type",None) != "forbidden": + return None + + excluded = gc.get("smallgraph", None) + + if not excluded: + return None + + if not isinstance(excluded,list): + excluded = [excluded] + + smallgraphs = GraphClasses().smallgraphs() + + if not all(g in smallgraphs for g in excluded): + return None + + return [smallgraphs[g] for g in excluded] + + def __contains__(self, g): + r""" + Tests if ``g`` belongs to the graph class represented by ``self``. + + EXAMPLES:: + + sage: graphs.CompleteBipartiteGraph(3,3) in graph_classes.Bipartite + True + sage: graphs.CompleteGraph(4) in graph_classes.Chordal + True + sage: graphs.CompleteGraph(4) in graph_classes.Comparability + True + sage: graphs.CompleteGraph(4) in graph_classes.Interval + True + sage: graphs.CompleteGraph(4) in graph_classes.Line + True + sage: graphs.CompleteGraph(4) in graph_classes.Perfect + True + sage: graphs.CompleteGraph(4) in graph_classes.Planar + True + sage: graphs.CompleteGraph(4) in graph_classes.Split + True + sage: graphs.PathGraph(4) in graph_classes.Tree + True + """ + from sage.graphs.graph import Graph + + if not isinstance(g, Graph): + return False + + if hasattr(self, "_recognition_function"): + return self._recognition_function(g) + + excluded = self.forbidden_subgraphs() + + if excluded is None: + raise NotImplementedError("No recognition agorithm is available"+ + "for this class.") + + for gg in excluded: + if g.subgraph_search(gg, induced = True): + return False + + return True + def description(self): r""" Prints the information of ISGCI about the current class. @@ -469,7 +608,7 @@ def description(self): Class of graphs : Chordal ------------------------- type : base - ID : gc_32 + id : gc_32 name : chordal Problems : @@ -480,31 +619,39 @@ def description(self): Cliquewidth : Unbounded Cliquewidth expression : NP-complete Colourability : Linear + Cutwidth : NP-complete Domination : NP-complete + Feedback vertex set : Polynomial + Hamiltonian cycle : NP-complete + Hamiltonian path : NP-complete Independent set : Linear + Maximum bisection : Unknown + Maximum cut : NP-complete + Minimum bisection : Unknown Recognition : Linear Treewidth : Polynomial Weighted clique : Polynomial + Weighted feedback vertex set : Unknown Weighted independent set : Linear """ - classes = GraphClasses().classes() - cls = classes[self._gc_id] + print "Class of graphs : "+self._name print "-"*(len(self._name)+18) for key, value in cls.iteritems(): - if value != "" and key != "problems": + if value != "" and key != "problem": print "{0:30} : ".format(key), print value print "\nProblems :" print "-"*11 - for key, value in sorted(cls["problems"].iteritems()): - if value != "": - print "{0:30} : ".format(key), - print value + + for pbname,data in sorted(cls["problem"].items()): + if "complexity" in data: + print "{0:30} : ".format(pbname), + print data["complexity"] from sage.misc.cachefunc import cached_method @@ -540,7 +687,7 @@ def get_class(self, id): if id in classes: c = classes[id] - if "name" in c and c["name"] != "": + if c.get("name",""): name = c["name"] else: name = "class "+str(id) @@ -563,15 +710,14 @@ def classes(self): sage: type(t) sage: sorted(t["gc_151"].keys()) - ['ID', 'name', 'problems', 'type'] + ['id', 'name', 'problem', 'type'] sage: t["gc_151"]['name'] 'cograph' - sage: t["gc_151"]['problems']['Clique'] - 'Linear' + sage: t["gc_151"]['problem']['Clique'] + {'complexity': 'Linear'} """ - classes, inclusions = self._get_ISGCI() - self.inclusions.set_cache(inclusions) - return classes + self._get_ISGCI() + return self.classes() @cached_method def inclusions(self): @@ -593,9 +739,28 @@ def inclusions(self): sage: t[0] {'super': 'gc_2', 'sub': 'gc_1'} """ - self.classes() + self._get_ISGCI() return self.inclusions() + @cached_method + def smallgraphs(self): + r""" + Returns a dictionary associating a graph to a graph description string. + + Upon the first call, this loads the database from the local + XML files. Subsequent calls are cached. + + EXAMPLES:: + + sage: t = graph_classes.inclusions() + sage: type(t) + + sage: t[0] + {'super': 'gc_2', 'sub': 'gc_1'} + """ + self._get_ISGCI() + return self.smallgraphs() + @cached_method def inclusion_digraph(self): r""" @@ -646,81 +811,56 @@ def _download_db(self): try: z.extract(_XML_FILE, os.path.join(SAGE_SHARE,'graphs')) + z.extract(_SMALLGRAPHS_FILE, os.path.join(SAGE_SHARE,'graphs')) except IOError: z.extract(_XML_FILE, SAGE_TMP) + z.extract(_SMALLGRAPHS_FILE, os.path.join(SAGE_SHARE,'graphs')) - - def _parse_db(self, xml_file): + def _parse_db(self, directory): r""" - Parses the ISGCI database and returns its content as Python objects. + Parses the ISGCI database and stores its content in ``self``. INPUT: - - ``xml_file`` -- the name of an XML file containing the data from ISGCI + - ``directory`` -- the name of the directory containing the latest + version of the database. EXAMPLE:: sage: import os sage: from sage.misc.misc import SAGE_SHARE - sage: map(type, graph_classes._parse_db(os.path.join(SAGE_SHARE,'graphs','isgci_sage.xml'))) - [, ] + sage: graph_classes._parse_db(os.path.join(SAGE_SHARE,'graphs')) """ - import xml.dom.minidom - from xml.dom.minidom import Node - - # This method is there to parse the XML file containing the ISGCI - # database. It is admittedly not very pretty, but it builds the class we - # want from the XML file and that's more or less all we ask it to do :-p - - doc = xml.dom.minidom.parse(xml_file) + import xml.etree.cElementTree as ET + import os.path + from sage.graphs.graph import Graph - classes = {} + xml_file = os.path.join(SAGE_SHARE,'graphs',_XML_FILE) + tree = ET.ElementTree(file=xml_file) + root = tree.getroot() + DB = _XML_to_dict(root) giveme = lambda x,y : str(x.getAttribute(y)) - for node in doc.getElementsByTagName("GraphClass"): - ID = str(node.getAttribute("id")) - Dl = {} - smallgraph = [] - Dl["ID"] = giveme(node, "id") - problems = {} - for node2 in node.childNodes: - name = str(node2.nodeName) - if name == "name": - Dl[name] = str(node2.childNodes[0].nodeValue) - - elif name == "smallgraph": - smallgraph.append(str(node2.childNodes[0].nodeValue)) - - elif name == "problem": - problems[giveme(node2, "name")] = giveme(node2, "complexity") - - Dl["problems"] = problems - - if smallgraph: - Dl["smallgraph"] = smallgraph - - if giveme(node, "type"): - Dl["type"] = giveme(node, "type") + classes = {c['id']:c for c in DB['GraphClasses']["GraphClass"]} + for c in classes.itervalues(): + c["problem"] = { pb.pop("name"):pb for pb in c["problem"]} + inclusions = DB['Inclusions']['incl'] - classes[giveme(node, "id")] = Dl + # Parses the list of ISGCI small graphs + smallgraph_file = open(os.path.join(SAGE_SHARE,'graphs',_SMALLGRAPHS_FILE),'r') + smallgraphs = {} - inclusions = [] - for node in doc.getElementsByTagName("incl"): - Dl = {} - for name in ["proper", "confidence", "super", "sub"]: - if giveme(node, name): - Dl[name] = giveme(node, name) + for l in smallgraph_file.readlines(): + key, string = l.split("\t") + smallgraphs[key] = Graph(string) - for node2 in node.childNodes: - name = str(node2.nodeName) - if name == "ref": - Dl[name] = str(node2.childNodes[0].nodeValue) + smallgraph_file.close() - inclusions.append(Dl) - - return classes, inclusions + self.inclusions.set_cache(inclusions) + self.classes.set_cache(classes) + self.smallgraphs.set_cache(smallgraphs) def update_db(self): r""" @@ -769,7 +909,7 @@ def _get_ISGCI(self): EXAMPLE:: - sage: classes, inclusions = graph_classes._get_ISGCI() # long time (4s on sage.math, 2012) + sage: graph_classes._get_ISGCI() # long time (4s on sage.math, 2012) """ import os.path @@ -783,15 +923,15 @@ def _get_ISGCI(self): if (os.path.getmtime(os.path.join(SAGE_DB,_XML_FILE)) > os.path.getmtime(os.path.join(SAGE_SHARE,'graphs',_XML_FILE))): - filename = os.path.join(SAGE_DB,_XML_FILE) + directory = os.path.join(SAGE_DB,_XML_FILE) else: - filename = os.path.join(SAGE_SHARE,'graphs',_XML_FILE) + directory = os.path.join(SAGE_SHARE,'graphs',_XML_FILE) except IOError as e: - filename = os.path.join(SAGE_SHARE,'graphs',_XML_FILE) + directory = os.path.join(SAGE_SHARE,'graphs',_XML_FILE) - return self._parse_db(filename) + self._parse_db(directory) def show_all(self): r""" @@ -800,7 +940,7 @@ def show_all(self): EXAMPLE:: sage: graph_classes.show_all() - ID | name | type | smallgraph + id | name | type | smallgraph ---------------------------------------------------------------------------------------------------------------------- gc_309 | $K_4$--minor--free | base | gc_541 | $N^*$ | base | @@ -817,7 +957,7 @@ def show_all(self): # We want to print the different fields, and this dictionary stores the # maximal number of characters of each field. MAX = { - "ID" : 0, + "id" : 0, "type" : 0, "smallgraph": 0, "name": 0 @@ -825,7 +965,7 @@ def show_all(self): # We sort the classes alphabetically, though we would like to display the # meaningful classes at the top of the list - classes_list.sort(key = lambda x:x.get("name","zzzzz")+"{0:4}".format(int(x["ID"].split('_')[1]))) + classes_list.sort(key = lambda x:x.get("name","zzzzz")+"{0:4}".format(int(x["id"].split('_')[1]))) # Maximum width of a field MAX_LEN = 40 @@ -839,34 +979,72 @@ def show_all(self): MAX[key] = min(length, MAX_LEN) # Head of the table - print ("{0:"+str(MAX["ID"])+"} | {1:"+str(MAX["name"])+"} | {2:"+str(MAX["type"])+"} | {3:"+str(MAX["smallgraph"])+"}").format("ID", "name", "type", "smallgraph") + print ("{0:"+str(MAX["id"])+"} | {1:"+str(MAX["name"])+"} | {2:"+str(MAX["type"])+"} | {3:"+str(MAX["smallgraph"])+"}").format("id", "name", "type", "smallgraph") print "-"*(sum(MAX.values())+9) # Entries for entry in classes_list: - ID = entry.get("ID","") + ID = entry.get("id","") name = entry.get("name","") type = entry.get("type","") smallgraph = entry.get("smallgraph","") - print ("{0:"+str(MAX["ID"])+"} | {1:"+str(MAX["name"])+"} | {2:"+str(MAX["type"])+"} | ").format(ID, name[:MAX_LEN], type[:MAX_LEN])+str(smallgraph)[:MAX_LEN] + print ("{0:"+str(MAX["id"])+"} | {1:"+str(MAX["name"])+"} | {2:"+str(MAX["type"])+"} | ").format(ID, name[:MAX_LEN], type[:MAX_LEN])+str(smallgraph)[:MAX_LEN] + +def _XML_to_dict(root): + r""" + Returns the XML data as a dictionary + + INPUT: + + - ``root`` -- an ``xml.etree.cElementTree.ElementTree`` object. + + OUTPUT: + + A dictionary representing the XML data. + + EXAMPLE:: + + sage: graph_classes.Perfect.description() # indirect doctest + Class of graphs : Perfect + ------------------------- + type : base + id : gc_56 + name : perfect + ... + """ + ans = root.attrib.copy() + for child in root: + if child.tag in ans: + if not isinstance(ans[child.tag],list): + ans[child.tag] = [ans[child.tag]] + ans[child.tag].append(_XML_to_dict(child)) + else: + ans[child.tag] = _XML_to_dict(child) + + # If the dictionary is empty, perhaps the only content is a text, and we + # return this instead. Useful sometimes in the ISGCI db, for graph names. + if not ans: + return root.text + return ans graph_classes = GraphClasses() # Any object added to this list should also appear in the class' documentation, at the top of the file. graph_classes.BinaryTrees = GraphClass("BinaryTrees", "gc_847") -graph_classes.Bipartite = GraphClass("Bipartite", "gc_69") +graph_classes.Bipartite = GraphClass("Bipartite", "gc_69", recognition_function = lambda x:x.is_bipartite()) graph_classes.Block = GraphClass("Block", "gc_93") -graph_classes.Chordal = GraphClass("Chordal", "gc_32") -graph_classes.Comparability = GraphClass("Comparability", "gc_72") +graph_classes.Chordal = GraphClass("Chordal", "gc_32", recognition_function = lambda x:x.is_chordal()) +graph_classes.ClawFree = GraphClass("Claw-free", "gc_62") +graph_classes.Comparability = GraphClass("Comparability", "gc_72", recognition_function = lambda x: __import__('sage').graphs.comparability.is_comparability) graph_classes.Gallai = GraphClass("Gallai", "gc_73") graph_classes.Grid = GraphClass("Grid", "gc_464") -graph_classes.Interval = GraphClass("Interval", "gc_234") -graph_classes.Line = GraphClass("Line", "gc_249") +graph_classes.Interval = GraphClass("Interval", "gc_234", recognition_function = lambda x:x.is_interval()) +graph_classes.Line = GraphClass("Line", "gc_249", recognition_function = lambda x:x.is_line_graph()) graph_classes.Modular = GraphClass("Modular", "gc_50") graph_classes.Outerplanar = GraphClass("Outerplanar", "gc_110") -graph_classes.Perfect = GraphClass("Perfect", "gc_56") -graph_classes.Planar = GraphClass("Planar", "gc_43") -graph_classes.Split = GraphClass("Split", "gc_39") -graph_classes.Tree = GraphClass("Tree", "gc_342") +graph_classes.Perfect = GraphClass("Perfect", "gc_56", recognition_function = lambda x:x.is_perfect()) +graph_classes.Planar = GraphClass("Planar", "gc_43", recognition_function = lambda x:x.is_planar()) +graph_classes.Split = GraphClass("Split", "gc_39", recognition_function = lambda x:x.is_split()) +graph_classes.Tree = GraphClass("Tree", "gc_342", recognition_function = lambda x:x.is_tree()) graph_classes.UnitDisk = GraphClass("UnitDisk", "gc_389") graph_classes.UnitInterval = GraphClass("UnitInterval", "gc_299") From 2e06ddb568811cd552cc02695d2e8f87792ca9d8 Mon Sep 17 00:00:00 2001 From: William Stein Date: Sun, 2 Aug 2009 18:52:16 +0000 Subject: [PATCH 004/698] trac #6666 -- implement analytic modular symbols algorithm and cusp transformation matrix --- .../elliptic_curves/ell_rational_field.py | 6 + .../schemes/elliptic_curves/period_lattice.py | 157 +++++++++++++++++- 2 files changed, 162 insertions(+), 1 deletion(-) diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 036ccb7e7eb..6a1b84a57af 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -64,6 +64,10 @@ import padic_lseries import padics +from sage.misc.lazy_import import lazy_import +lazy_import('sage.schemes.elliptic_curves.period_lattice', + 'modular_symbol_numerical') + from sage.modular.modsym.modsym import ModularSymbols import sage.modular.modform.constructor @@ -1231,6 +1235,8 @@ def modular_symbol(self, sign=1, use_eclib = False, normalize = "L_ratio"): self.__modular_symbol[typ] = M return M + modular_symbol_numerical = modular_symbol_numerical + padic_lseries = padics.padic_lseries def newform(self): diff --git a/src/sage/schemes/elliptic_curves/period_lattice.py b/src/sage/schemes/elliptic_curves/period_lattice.py index dc91f6e7255..83f2c291c58 100644 --- a/src/sage/schemes/elliptic_curves/period_lattice.py +++ b/src/sage/schemes/elliptic_curves/period_lattice.py @@ -95,7 +95,7 @@ """ from sage.modules.free_module import FreeModule_generic_pid -from sage.rings.all import ZZ, QQ, RealField, ComplexField, QQbar, AA +from sage.rings.all import ZZ, QQ, RealField, ComplexField, QQbar, AA, CDF from sage.rings.real_mpfr import is_RealField from sage.rings.complex_field import is_ComplexField from sage.rings.real_mpfr import RealNumber as RealNumber @@ -105,6 +105,7 @@ from sage.schemes.elliptic_curves.constructor import EllipticCurve from sage.misc.cachefunc import cached_method + class PeriodLattice(FreeModule_generic_pid): """ The class for the period lattice of an algebraic variety. @@ -1803,3 +1804,157 @@ def extended_agm_iteration(a,b,c): return a,b,c c*=f a,b = a1,b1 + +################################################################################ +# Double precision analytic computation of the period mapping (modular symbol) +# associated to an elliptic curve, without doing linear algebra. +################################################################################ + + +def period_matrices(E, tau): + """ + Return the period matrices of E at the cusp tau ? + + EXAMPLES:: + + sage: from sage.schemes.elliptic_curves.period_lattice import period_matrices + sage: E = EllipticCurve('11a1') + sage: period_matrices(E,0) + (2, [[1 0] + [0 1], [1 0] + [0 1], [ 6 1] + [11 2]]) + """ + from sage.modular.cusps import Cusps + from sage.sets.all import Primes + from sage.rings.all import next_prime + N = E.conductor() + # 1. find a prime p that is suitable, along with matrices M[i] + for p in Primes(): + if N % p == 0: + continue + # are the cusps tau, p*tau, and (tau+j)/p for j=0,...,p-1 all equivalent? + t = Cusps(tau) + M = [] + b, m = t.is_gamma0_equiv(p*tau, N, transformation='matrix') + if not b: + continue + M.append(m) + bad = False + for j in range(p): + b, m = t.is_gamma0_equiv((tau+j)/p, N, transformation='matrix') + if not b: + bad = True + break + M.append(m) + if bad: + p = next_prime(p) + continue + # Found it! + break + return p, M + +def modsym(E, tau, prec=53, terms=100): + """ + Compute the modular symbol {oo, tau} analytically + + This does not use any linear algebra! + + The result is phi(tau) = sum(omega(m) for m in M)/(1+p-a_p), where + + EXAMPLES:: + + sage: from sage.schemes.elliptic_curves.period_lattice import modsym + sage: E = EllipticCurve('17a1') + sage: modsym(E,0) # abs tol 1e-10 + 0.386769938388 - 4.26405203974e-17*I + """ + p, M = period_matrices(E, tau) + return sum(period(E, m, prec, terms) for m in M)/(1+p-E.ap(p)) + +def period(E, M, prec=53, abs_prec=10): + """ + omega(m) = 2*pi*I*integral_{tau,M(tau)} f(z) dz + + See pages 35-36, Section 2.10 of Cremona's book for how to do this, + in particular, Prop. 2.10.3. + + EXAMPLES:: + + sage: from sage.schemes.elliptic_curves.period_lattice import period + sage: E = EllipticCurve('19a1') + sage: M = matrix(ZZ,[[10,1],[19,2]]) + sage: period(E, M) # abs tol 1e-10 + 1.35975973351 - 1.09779285698e-16*I + """ + eps = -E.root_number() + N = E.conductor() + if M[1, 1] < 0: + M = -M + assert M.det() == 1 + a, b, c, d = M.list() + c = ZZ(c/N) + if prec <= 53: + K = CDF + else: + K = ComplexField(prec) + + a, b, c, d = K(a), K(b), K(c), K(d) + pi = K.pi() + i = K.gen() + sqrtN = K(N).sqrt() + s = K(0) + + R = RealField(prec) + delta = R(10)**(-abs_prec) + terms = (-R(d)*R(N).sqrt()*delta.log() / (2*R.pi())).ceil() + + from sage.misc.all import verbose + tm = verbose("computing %s terms of anlist..." % terms) + an = E.anlist(terms+1) + tm = verbose("got anlist; now computing formal sum", tm) + for n in range(1, terms+1): + npi2 = 2*pi*n + w = (-npi2/(d*sqrtN)).exp() + t = (K(an[n])/K(n))*((eps-1)*(-npi2/sqrtN).exp() + + w * ((i*npi2*b/d).exp() - eps*(i*npi2*c/d).exp())) + s += t + verbose("computed sum", tm) + return -s # minus because cremona's I_f is backwards from ours + +def modular_symbol_numerical(self, sign, prec=53, abs_prec=10): + """ + Return the modular symbol as a numerical function + + EXAMPLES:: + + sage: E = EllipticCurve('19a1') + sage: f = E.modular_symbol_numerical(1) # indirect doctest + sage: g = E.modular_symbol(1) + sage: f(2), g(2) + (0.333333333333, 1/3) + sage: f(oo), g(oo) + (0.0, 0) + + sage: E = EllipticCurve('79a1') + sage: f = E.modular_symbol_numerical(-1) # indirect doctest + sage: g = E.modular_symbol(-1) + sage: f(1), g(1) # rel tol 1e-4 + (-2.18603704428e-12, 0) + sage: f(oo), g(oo) + (0.0, 0) + """ + lam = self.period_lattice().basis(prec=prec) + if sign == 1: + def f(a): + s = modsym(self, a, prec, abs_prec) + return s.real()/lam[0].real() + + return f + else: + P = lam[1].imag() + def f(a): + s = modsym(self, a, prec, abs_prec) + return s.imag()/P + + return f From c84246e912c9380936c9e122934ed94ab160453f Mon Sep 17 00:00:00 2001 From: Emmanuel Jeanvoine Date: Mon, 14 Feb 2011 08:51:59 +0000 Subject: [PATCH 005/698] #10779: Improve coverage test for structure/element.pyx --- src/sage/structure/element.pyx | 253 +++++++++++++++++++++------------ 1 file changed, 164 insertions(+), 89 deletions(-) diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index b233a1ee85e..3b312375562 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -224,11 +224,11 @@ def py_scalar_to_element(py): elif PyComplex_Check(py): return CDF(py) else: - raise TypeError, "Not a scalar" + raise TypeError("Not a scalar") def is_Element(x): """ - Return True if x is of type Element. + Return ``True`` if x is of type Element. EXAMPLES:: @@ -319,7 +319,7 @@ cdef class Element(sage_object.SageObject): AttributeError: 'LeftZeroSemigroup_with_category.element_class' object has no attribute 'blah_blah' We test that "private" attributes are not requested from the element class - of the category (trac ticket #10467):: + of the category (:trac:`10467`):: sage: C = EuclideanDomains() sage: P. = QQ[] @@ -447,8 +447,8 @@ cdef class Element(sage_object.SageObject): def _im_gens_(self, codomain, im_gens): """ - Return the image of self in codomain under the map that sends - the images of the generators of the parent of self to the + Return the image of ``self`` in codomain under the map that sends + the images of the generators of the parent of ``self`` to the tuple of elements of im_gens. """ raise NotImplementedError @@ -470,6 +470,13 @@ cdef class Element(sage_object.SageObject): def base_ring(self): """ Returns the base ring of this element's parent (if that makes sense). + + TESTS:: + + sage: QQ.base_ring() + Rational Field + sage: identity_matrix(3).base_ring() + Integer Ring """ return self._parent.base_ring() @@ -637,15 +644,15 @@ cdef class Element(sage_object.SageObject): sage: (2/3).n() 0.666666666666667 - sage: pi.n(digits=10) + sage: pi.n(digits=10) # indirect doctest 3.141592654 - sage: pi.n(prec=20) # 20 bits + sage: pi.n(prec=20) # indirect doctest 3.1416 """ - import sage.misc.functional - return sage.misc.functional.numerical_approx(self, prec=prec, digits=digits) - n=numerical_approx - N=n + from sage.misc.functional import numerical_approx + return numerical_approx(self, prec=prec, digits=digits) + n = numerical_approx + N = n def _mpmath_(self, prec=53, rounding=None): """ @@ -706,7 +713,7 @@ cdef class Element(sage_object.SageObject): cpdef _act_on_(self, x, bint self_on_left): """ - Use this method to implement self acting on x. + Use this method to implement ``self`` acting on x. Return None or raise a CoercionException if no such action is defined here. @@ -715,7 +722,7 @@ cdef class Element(sage_object.SageObject): cpdef _acted_upon_(self, x, bint self_on_left): """ - Use this method to implement self acted on by x. + Use this method to implement ``self`` acted on by x. Return None or raise a CoercionException if no such action is defined here. @@ -724,8 +731,8 @@ cdef class Element(sage_object.SageObject): def __xor__(self, right): - raise RuntimeError, "Use ** for exponentiation, not '^', which means xor\n"+\ - "in Python, and has the wrong precedence." + raise RuntimeError("Use ** for exponentiation, not '^', which means xor\n"+\ + "in Python, and has the wrong precedence.") def __pos__(self): return self @@ -751,7 +758,7 @@ cdef class Element(sage_object.SageObject): def _is_atomic(self): """ - Return True if and only if parenthesis are not required when + Return ``True`` if and only if parenthesis are not required when *printing* out any of `x - s`, `x + s`, `x^s` and `x/s`. EXAMPLES:: @@ -768,7 +775,7 @@ cdef class Element(sage_object.SageObject): def __nonzero__(self): r""" - Return True if self does not equal self.parent()(0). + Return ``True`` if ``self`` does not equal self.parent()(0). Note that this is automatically called when converting to boolean, as in the conditional of an if or while statement. @@ -793,7 +800,7 @@ cdef class Element(sage_object.SageObject): def is_zero(self): """ - Return True if self equals self.parent()(0). The default + Return ``True`` if ``self`` equals self.parent()(0). The default implementation is to fall back to 'not self.__nonzero__'. .. warning:: @@ -937,7 +944,7 @@ cdef class Element(sage_object.SageObject): cdef int _cmp_c_impl(left, Element right) except -2: ### For derived Cython code, you *MUST* ALSO COPY the __richcmp__ above ### into your class!!! For Python code just use __cmp__. - raise NotImplementedError, "BUG: sort algorithm for elements of '%s' not implemented"%right.parent() + raise NotImplementedError("BUG: sort algorithm for elements of '%s' not implemented"%right.parent()) cdef inline bint _rich_to_bool(int op, int r): if op == Py_LT: #< @@ -956,7 +963,7 @@ cdef inline bint _rich_to_bool(int op, int r): def is_ModuleElement(x): """ - Return True if x is of type ModuleElement. + Return ``True`` if x is of type ModuleElement. This is even faster than using isinstance inline. @@ -980,7 +987,7 @@ cdef class ElementWithCachedMethod(Element): The :class:`~sage.misc.cachefunc.cached_method` decorator provides a convenient way to automatically cache the result of a computation. - Since trac ticket #11115, the cached method decorator applied to a + Since :trac:`11115`, the cached method decorator applied to a method without optional arguments is faster than a hand-written cache in Python, and a cached method without any arguments (except ``self``) is actually faster than a Python method that does nothing more but @@ -1220,7 +1227,7 @@ cdef class ModuleElement(Element): return coercion_model.bin_op(left, right, add) cpdef ModuleElement _add_(left, ModuleElement right): - raise TypeError, arith_error_message(left, right, add) + raise TypeError(arith_error_message(left, right, add)) def __iadd__(ModuleElement self, right): if have_same_parent(self, right): @@ -1299,7 +1306,7 @@ cdef class ModuleElement(Element): if PyInt_CheckExact(left): return (right)._mul_long(PyInt_AS_LONG(left)) if have_same_parent(left, right): - raise TypeError, arith_error_message(left, right, mul) + raise TypeError(arith_error_message(left, right, mul)) # Always do this global coercion_model return coercion_model.bin_op(left, right, mul) @@ -1372,7 +1379,7 @@ cdef class ModuleElement(Element): def is_MonoidElement(x): """ - Return True if x is of type MonoidElement. + Return ``True`` if x is of type MonoidElement. """ return IS_INSTANCE(x, MonoidElement) @@ -1430,7 +1437,7 @@ cdef class MonoidElement(Element): Return the (integral) power of self. """ if dummy is not None: - raise RuntimeError, "__pow__ dummy argument not used" + raise RuntimeError("__pow__ dummy argument not used") return generic_power_c(self,n,None) def __nonzero__(self): @@ -1438,7 +1445,7 @@ cdef class MonoidElement(Element): def is_AdditiveGroupElement(x): """ - Return True if x is of type AdditiveGroupElement. + Return ``True`` if x is of type AdditiveGroupElement. """ return IS_INSTANCE(x, AdditiveGroupElement) @@ -1453,7 +1460,7 @@ cdef class AdditiveGroupElement(ModuleElement): return self.additive_order() def __invert__(self): - raise NotImplementedError, "multiplicative inverse not defined for additive group elements" + raise NotImplementedError("multiplicative inverse not defined for additive group elements") cpdef ModuleElement _rmul_(self, RingElement left): return self._lmul_(left) @@ -1470,7 +1477,7 @@ cdef class AdditiveGroupElement(ModuleElement): def is_MultiplicativeGroupElement(x): """ - Return True if x is of type MultiplicativeGroupElement. + Return ``True`` if x is of type MultiplicativeGroupElement. """ return IS_INSTANCE(x, MultiplicativeGroupElement) @@ -1485,7 +1492,7 @@ cdef class MultiplicativeGroupElement(MonoidElement): return self.multiplicative_order() def _add_(self, x): - raise ArithmeticError, "addition not defined in a multiplicative group" + raise ArithmeticError("addition not defined in a multiplicative group") def __div__(left, right): if have_same_parent(left, right): @@ -1508,7 +1515,7 @@ cdef class MultiplicativeGroupElement(MonoidElement): def is_RingElement(x): """ - Return True if x is of type RingElement. + Return ``True`` if x is of type RingElement. """ return IS_INSTANCE(x, RingElement) @@ -1705,7 +1712,7 @@ cdef class RingElement(ModuleElement): Cython classes should override this function to implement multiplication. See extensive documentation at the top of element.pyx. """ - raise TypeError, arith_error_message(self, right, mul) + raise TypeError(arith_error_message(self, right, mul)) def __imul__(left, right): if have_same_parent(left, right): @@ -1766,7 +1773,7 @@ cdef class RingElement(ModuleElement): sage: 2r^(1/2) sqrt(2) - Exponent overflow should throw an OverflowError (trac #2956):: + Exponent overflow should throw an OverflowError (:trac:`2956`):: sage: K. = AA[] sage: x^(2^64 + 12345) @@ -1774,7 +1781,7 @@ cdef class RingElement(ModuleElement): ... OverflowError: Exponent overflow (2147483648). - Another example from trac #2956; this should overflow on x32 + Another example from :trac:`2956`; this should overflow on x32 and succeed on x64:: sage: K. = ZZ[] @@ -1786,7 +1793,7 @@ cdef class RingElement(ModuleElement): """ if dummy is not None: - raise RuntimeError, "__pow__ dummy argument not used" + raise RuntimeError("__pow__ dummy argument not used") return generic_power_c(self,n,None) ################################## @@ -1821,9 +1828,9 @@ cdef class RingElement(ModuleElement): return self._parent.fraction_field()(self, right) except AttributeError: if not right: - raise ZeroDivisionError, "Cannot divide by zero" + raise ZeroDivisionError("Cannot divide by zero") else: - raise TypeError, arith_error_message(self, right, div) + raise TypeError(arith_error_message(self, right, div)) def __idiv__(self, right): """ @@ -1874,11 +1881,11 @@ cdef class RingElement(ModuleElement): def multiplicative_order(self): r""" - Return the multiplicative order of self, if self is a unit, or raise + Return the multiplicative order of self, if ``self`` is a unit, or raise ``ArithmeticError`` otherwise. """ if not self.is_unit(): - raise ArithmeticError, "self (=%s) must be a unit to have a multiplicative order." + raise ArithmeticError("self (=%s) must be a unit to have a multiplicative order.") raise NotImplementedError def is_unit(self): @@ -1888,8 +1895,22 @@ cdef class RingElement(ModuleElement): def is_nilpotent(self): """ - Return True if self is nilpotent, i.e., some power of self + Return ``True`` if ``self`` is nilpotent, i.e., some power of self is 0. + + TESTS:: + + sage: a=QQ(2) + sage: a.is_nilpotent() + False + sage: a=QQ(0) + sage: a.is_nilpotent() + True + sage: m=matrix(RR,3,[[3,2,3],[9,0,3],[-9,0,-3]]) + sage: m.is_nilpotent() + Traceback (most recent call last): + ... + NotImplementedError """ if self.is_unit(): return False @@ -1921,7 +1942,19 @@ cdef class RingElement(ModuleElement): def is_CommutativeRingElement(x): """ - Return True if x is of type CommutativeRingElement. + Return ``True`` if x is of type CommutativeRingElement. + + TESTS:: + + sage: is_CommutativeRingElement(oo) + doctest:...: DeprecationWarning: + Using is_CommutativeRingElement from the top level is deprecated since it was designed to be used by developers rather than end users. + It most likely does not do what you would expect it to do. If you really need to use it, import it from the module that it is defined in. + See http://trac.sagemath.org/10107 for details. + False + + sage: is_CommutativeRingElement(1) + True """ return IS_INSTANCE(x, CommutativeRingElement) @@ -1933,14 +1966,14 @@ cdef class CommutativeRingElement(RingElement): def inverse_mod(self, I): r""" - Return an inverse of self modulo the ideal `I`, if defined, - i.e., if `I` and self together generate the unit ideal. + Return an inverse of ``self`` modulo the ideal `I`, if defined, + i.e., if `I` and ``self`` together generate the unit ideal. """ raise NotImplementedError def divides(self, x): """ - Return True if self divides x. + Return ``True`` if ``self`` divides x. EXAMPLES:: @@ -1959,7 +1992,7 @@ cdef class CommutativeRingElement(RingElement): sage: (x^2+2).divides(x) False - Ticket \#5347 has been fixed:: + :trac:`5347` has been fixed:: sage: K = GF(7) sage: K(3).divides(1) @@ -1987,7 +2020,7 @@ cdef class CommutativeRingElement(RingElement): If x has different parent than `self`, they are first coerced to a common parent if possible. If this coercion fails, it returns a - TypeError. This fixes \#5759 + TypeError. This fixes :trac:`5759` :: sage: Zmod(2)(0).divides(Zmod(2)(0)) @@ -2042,7 +2075,7 @@ cdef class CommutativeRingElement(RingElement): def mod(self, I): r""" - Return a representative for self modulo the ideal I (or the ideal + Return a representative for ``self`` modulo the ideal I (or the ideal generated by the elements of I if I is not an ideal.) EXAMPLE: Integers @@ -2120,7 +2153,7 @@ cdef class CommutativeRingElement(RingElement): def is_square(self, root=False): """ Returns whether or not ring element is a square. If the optional - argument root is True, then also returns the square root (or None, + argument root is ``True``, then also returns the square root (or None, if the it is not a square). INPUT: @@ -2169,17 +2202,17 @@ cdef class CommutativeRingElement(RingElement): INPUT: - - ``extend`` - Whether to make a ring extension containing a square root if self is not a square (default: True) + - ``extend`` - Whether to make a ring extension containing a square root if ``self`` is not a square (default: ``True``) - ``all`` - Whether to return a list of all square roots or just a square root (default: False) - - ``name`` - Required when extend=True and self is not a square. This will be the name of the generator extension. + - ``name`` - Required when extend=``True`` and ``self`` is not a square. This will be the name of the generator extension. OUTPUT: - - if all=False it returns a square root. (throws an error if extend=False and self is not a square) + - if all=False it returns a square root. (throws an error if extend=False and ``self`` is not a square) - - if all=True it returns a list of all the square roots (could be empty if extend=False and self is not a square) + - if all=``True`` it returns a list of all the square roots (could be empty if extend=False and ``self`` is not a square) ALGORITHM: @@ -2274,10 +2307,10 @@ cdef class CommutativeRingElement(RingElement): #all square roots of a non-square should be an empty list if all: return [] - raise ValueError, 'trying to take square root of non-square %s with extend = False' % self + raise ValueError('trying to take square root of non-square %s with extend = False' % self) if name == None: - raise TypeError ("Polynomial is not a square. You must specify the name of the square root when using the default extend = True") + raise TypeError("Polynomial is not a square. You must specify the name of the square root when using the default extend = True") from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing PY = PolynomialRing(P,'y') y = PY.gen() @@ -2474,10 +2507,10 @@ cdef class Vector(ModuleElement): return coercion_model.bin_op(left, right, mul) cpdef Element _dot_product_(Vector left, Vector right): - raise TypeError, arith_error_message(left, right, mul) + raise TypeError(arith_error_message(left, right, mul)) cpdef Vector _pairwise_product_(Vector left, Vector right): - raise TypeError, "unsupported operation for '%s' and '%s'"%(parent_c(left), parent_c(right)) + raise TypeError("unsupported operation for '%s' and '%s'"%(parent_c(left), parent_c(right))) def __div__(self, right): if PY_IS_NUMERIC(right): @@ -2491,10 +2524,10 @@ cdef class Vector(ModuleElement): return W.coordinates(self)[0] / W.coordinates(right)[0] except ArithmeticError: if right.is_zero(): - raise ZeroDivisionError, "division by zero vector" + raise ZeroDivisionError("division by zero vector") else: - raise ArithmeticError, "vector is not in free module" - raise TypeError, arith_error_message(self, right, div) + raise ArithmeticError("vector is not in free module") + raise TypeError(arith_error_message(self, right, div)) def _magma_init_(self, magma): """ @@ -2766,7 +2799,7 @@ def is_Matrix(x): def is_IntegralDomainElement(x): """ - Return True if x is of type IntegralDomainElement. + Return ``True`` if x is of type IntegralDomainElement. """ return IS_INSTANCE(x, IntegralDomainElement) @@ -2777,7 +2810,7 @@ cdef class IntegralDomainElement(CommutativeRingElement): def is_DedekindDomainElement(x): """ - Return True if x is of type DedekindDomainElement. + Return ``True`` if x is of type DedekindDomainElement. """ return IS_INSTANCE(x, DedekindDomainElement) @@ -2786,14 +2819,14 @@ cdef class DedekindDomainElement(IntegralDomainElement): def is_PrincipalIdealDomainElement(x): """ - Return True if x is of type PrincipalIdealDomainElement. + Return ``True`` if x is of type PrincipalIdealDomainElement. """ return IS_INSTANCE(x, PrincipalIdealDomainElement) cdef class PrincipalIdealDomainElement(DedekindDomainElement): def lcm(self, right): """ - Returns the least common multiple of self and right. + Returns the least common multiple of ``self`` and right. """ if not PY_TYPE_CHECK(right, Element) or not ((right)._parent is self._parent): return coercion_model.bin_op(self, right, lcm) @@ -2801,7 +2834,7 @@ cdef class PrincipalIdealDomainElement(DedekindDomainElement): def gcd(self, right): """ - Returns the gcd of self and right, or 0 if both are 0. + Returns the gcd of ``self`` and right, or 0 if both are 0. """ if not PY_TYPE_CHECK(right, Element) or not ((right)._parent is self._parent): return coercion_model.bin_op(self, right, gcd) @@ -2809,10 +2842,10 @@ cdef class PrincipalIdealDomainElement(DedekindDomainElement): def xgcd(self, right): r""" - Return the extended gcd of self and other, i.e., elements `r, s, t` such that + Return the extended gcd of ``self`` and other, i.e., elements `r, s, t` such that .. math:: - r = s \cdot self + t \cdot other. + r = s \cdot ``self`` + t \cdot other. .. note:: @@ -2832,7 +2865,7 @@ PY_SET_TP_NEW(EuclideanDomainElement, Element) def is_EuclideanDomainElement(x): """ - Return True if x is of type EuclideanDomainElement. + Return ``True`` if x is of type EuclideanDomainElement. """ return IS_INSTANCE(x, EuclideanDomainElement) @@ -2843,7 +2876,7 @@ cdef class EuclideanDomainElement(PrincipalIdealDomainElement): def _gcd(self, other): """ - Return the greatest common divisor of self and other. + Return the greatest common divisor of ``self`` and other. Algorithm 3.2.1 in Cohen, GTM 138. """ @@ -2863,7 +2896,7 @@ cdef class EuclideanDomainElement(PrincipalIdealDomainElement): def __divmod__(self, other): """ - Return the quotient and remainder of self divided by other. + Return the quotient and remainder of ``self`` divided by other. EXAMPLES:: @@ -2883,14 +2916,14 @@ cdef class EuclideanDomainElement(PrincipalIdealDomainElement): def __floordiv__(self,right): """ - Quotient of division of self by other. This is denoted //. + Quotient of division of ``self`` by other. This is denoted //. """ Q, _ = self.quo_rem(right) return Q def __mod__(self, other): """ - Remainder of division of self by other. + Remainder of division of ``self`` by other. EXAMPLES:: @@ -2905,7 +2938,7 @@ cdef class EuclideanDomainElement(PrincipalIdealDomainElement): def is_FieldElement(x): """ - Return True if x is of type FieldElement. + Return ``True`` if x is of type FieldElement. """ return IS_INSTANCE(x, FieldElement) @@ -2916,7 +2949,7 @@ cdef class FieldElement(CommutativeRingElement): def is_unit(self): """ - Return True if self is a unit in its parent ring. + Return ``True`` if ``self`` is a unit in its parent ring. EXAMPLES:: @@ -2941,7 +2974,7 @@ cdef class FieldElement(CommutativeRingElement): def _gcd(self, FieldElement other): """ - Return the greatest common divisor of self and other. + Return the greatest common divisor of ``self`` and other. """ if self.is_zero() and other.is_zero(): return self @@ -2950,7 +2983,7 @@ cdef class FieldElement(CommutativeRingElement): def _lcm(self, FieldElement other): """ - Return the least common multiple of self and other. + Return the least common multiple of ``self`` and other. """ if self.is_zero() and other.is_zero(): return self @@ -2990,7 +3023,7 @@ cdef class FieldElement(CommutativeRingElement): def divides(self, FieldElement other): r""" - Check whether self divides other, for field elements. + Check whether ``self`` divides other, for field elements. Since this is a field, all values divide all other values, except that zero does not divide any non-zero values. @@ -3013,7 +3046,20 @@ cdef class FieldElement(CommutativeRingElement): def is_AlgebraElement(x): """ - Return True if x is of type AlgebraElement. + Return ``True`` if x is of type AlgebraElement. + + TESTS:: + + sage: R. = FreeAlgebra(QQ,2) + sage: is_AlgebraElement(x*y) + doctest:...: DeprecationWarning: + Using is_AlgebraElement from the top level is deprecated since it was designed to be used by developers rather than end users. + It most likely does not do what you would expect it to do. If you really need to use it, import it from the module that it is defined in. + See http://trac.sagemath.org/10107 for details. + True + + sage: is_AlgebraElement(1) + False """ return IS_INSTANCE(x, AlgebraElement) @@ -3022,7 +3068,7 @@ cdef class AlgebraElement(RingElement): def is_CommutativeAlgebraElement(x): """ - Return True if x is of type CommutativeAlgebraElement. + Return ``True`` if x is of type CommutativeAlgebraElement. """ return IS_INSTANCE(x, CommutativeAlgebraElement) @@ -3031,7 +3077,19 @@ cdef class CommutativeAlgebraElement(CommutativeRingElement): def is_InfinityElement(x): """ - Return True if x is of type InfinityElement. + Return ``True`` if x is of type InfinityElement. + + TESTS:: + + sage: is_InfinityElement(1) + doctest:...: DeprecationWarning: + Using is_InfinityElement from the top level is deprecated since it was designed to be used by developers rather than end users. + It most likely does not do what you would expect it to do. If you really need to use it, import it from the module that it is defined in. + See http://trac.sagemath.org/10107 for details. + False + + sage: is_InfinityElement(oo) + True """ return IS_INSTANCE(x, InfinityElement) @@ -3104,12 +3162,12 @@ cdef class CoercionModel: cpdef canonical_coercion(self, x, y): if parent_c(x) is parent_c(y): return x,y - raise TypeError, "no common canonical parent for objects with parents: '%s' and '%s'"%(parent_c(x), parent_c(y)) + raise TypeError("no common canonical parent for objects with parents: '%s' and '%s'"%(parent_c(x), parent_c(y))) cpdef bin_op(self, x, y, op): if parent_c(x) is parent_c(y): return op(x,y) - raise TypeError, arith_error_message(x,y,op) + raise TypeError(arith_error_message(x,y,op)) import coerce cdef CoercionModel coercion_model = coerce.CoercionModel_cache_maps() @@ -3331,19 +3389,36 @@ coerce_binop = NamedBinopMethod ############################################################################### -def lcm(x,y): +def lcm(x, y): + """ + TESTS:: + + sage: lcm(3,-4) + 12 + """ from sage.rings.arith import lcm - return lcm(x,y) + return lcm(x, y) -def gcd(x,y): - from sage.rings.arith import gcd - return gcd(x,y) +def gcd(x, y): + """ + TESTS:: -def xgcd(x,y): - from sage.rings.arith import xgcd - return xgcd(x,y) + sage: gcd(12,15) + 3 + """ + from sage.rings.arith import gcd + return gcd(x, y) +def xgcd(x, y): + """ + TESTS:: + sage: x = polygen(QQ) + sage: xgcd(x^3 - 1, x^2 - 1) + (x - 1, 1, -x) + """ + from sage.rings.arith import xgcd + return xgcd(x, y) ###################### @@ -3395,7 +3470,7 @@ cdef generic_power_c(a, nn, one): from sage.rings.integer import Integer n = int(Integer(nn)) except TypeError: - raise NotImplementedError, "non-integral exponents not supported" + raise NotImplementedError("non-integral exponents not supported") if not n: if one is None: From 93cefff357a7942b4c7ea539f1d97c9b0e32acb7 Mon Sep 17 00:00:00 2001 From: Frederic Chapoton Date: Thu, 6 Sep 2012 07:59:56 +0000 Subject: [PATCH 006/698] trac #12916 : implements the Dedekind-MacNeil completion of posets --- src/sage/combinat/posets/posets.py | 99 ++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 590cea342d3..ed0dc176711 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -130,6 +130,7 @@ from sage.misc.superseded import deprecated_function_alias from sage.categories.category import Category from sage.categories.sets_cat import Sets +from sage.sets.set import Set from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.categories.posets import Posets from sage.categories.finite_posets import FinitePosets @@ -4275,6 +4276,104 @@ def p_partition_enumerator(self, tup, R, check=False): res += QR.Fundamental()(Composition(from_subset=(descents, n))) return res + def set_of_upper_bounds(self, A): + r""" + Return the set of upper bounds of the subset `A` of ``self`` + + An element `x` is called an upper bound of `A` if `a\leq x` + for all `a \in A` + + INPUT: + + - `A` -- a subset of the poset ``self`` + + OUTPUT: + + - a subset of the poset ``self`` + + EXAMPLES:: + + sage: P = posets.PentagonPoset() + sage: P.set_of_upper_bounds([P(0), P(1)]) + {1, 4} + sage: P.set_of_upper_bounds([u for u in P]) + {4} + sage: P.set_of_upper_bounds([P(0)]) + {1, 0, 3, 2, 4} + """ + return Set([x for x in self if all([x >= a for a in A])]) + + def set_of_lower_bounds(self, A): + r""" + Return the set of lower bounds of the subset `A` of ``self`` + + An element `x` is called an lower bound of `A` if `x\leq a` + for all `a \in A` + + INPUT: + + - `A` -- a subset of the poset ``self`` + + OUTPUT: + + - a subset of the poset ``self`` + + EXAMPLES:: + + sage: P = posets.PentagonPoset() + sage: P.set_of_lower_bounds([P(1), P(4)]) + {1, 0} + sage: P.set_of_lower_bounds([u for u in P]) + {0} + sage: P.set_of_lower_bounds([P(4)]) + {1, 0, 3, 2, 4} + """ + return Set([x for x in self if all([x <= a for a in A])]) + + def cuts(self): + """ + Return the set of cuts of the poset ``self`` + + A cut is a subset `A` of ``self`` such that the set of lower + bounds of the set of upper bounds of `A` is exactly `A`. + + EXAMPLES:: + + sage: P = posets.AntichainPoset(3) + sage: P.cuts() + [{}, {1}, {0}, {2}, {1, 0, 2}] + """ + return [A for A in Set(self).subsets() + if self.set_of_lower_bounds(self.set_of_upper_bounds([self(a) for a in A])) == Set([self(a) for a in A])] + + def completion_by_cuts(self): + """ + Return the completion by cuts of ``self`` + + This is also called the Dedekind-MacNeille completion. + + See the :wikipedia:`Wikipedia page `. + + The algorithm is naive. + + OUTPUT: + + - a finite poset + + EXAMPLES:: + + sage: P = posets.PentagonPoset() + sage: P.completion_by_cuts().is_isomorphic(P) + True + sage: P = posets.AntichainPoset(3) + sage: Q = P.completion_by_cuts(); Q + Finite poset containing 5 elements + sage: Q.is_isomorphic(posets.DiamondPoset(5)) + True + """ + from sage.misc.misc import attrcall + return Poset((self.cuts(), attrcall("issubset"))) + FinitePoset._dual_class = FinitePoset ##### Posets ##### From b3eee8a1f30a328eeb14080f07dee9ae26ab0ec5 Mon Sep 17 00:00:00 2001 From: Julian Rueth Date: Sat, 20 Oct 2012 20:49:57 +0000 Subject: [PATCH 007/698] Trac #13442: rings can provide _gcd_univariate_polynomial for polynomial factorization --- src/sage/categories/fields.py | 27 +++++++++ .../rings/polynomial/polynomial_element.pyx | 57 ++++++++++++++++++- 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/sage/categories/fields.py b/src/sage/categories/fields.py index 52398f5089a..9b27ab71cad 100644 --- a/src/sage/categories/fields.py +++ b/src/sage/categories/fields.py @@ -194,6 +194,33 @@ def is_integrally_closed(self): """ return True + def _gcd_univariate_polynomial(self, f, g): + """ + Return the greatest common divisor of ``f`` and ``g``, as a + monic polynomial. + + INPUT: + + - ``f``, ``g`` -- two polynomials defined over ``self`` + + .. NOTE:: + + This is a helper method for + :meth:`sage.rings.polynomial.polynomial_element.Polynomial.gcd`. + + EXAMPLES:: + + sage: R. = QQbar[] + sage: QQbar._gcd_univariate_polynomial(2*x,2*x^2) + x + + """ + ret = EuclideanDomains().ElementMethods().gcd(f,g) + c = ret.leading_coefficient() + if c.is_unit(): + return (1/c)*ret + return ret + def _test_characteristic_fields(self, **options): """ Run generic tests on the method :meth:`.characteristic`. diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 6e22c1f090d..83c802be183 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -3395,6 +3395,61 @@ cdef class Polynomial(CommutativeAlgebraElement): pari.set_real_precision(n) # restore precision return Factorization(F, unit) + @coerce_binop + def gcd(self, other): + """ + Compute a greatest common divisor of ``self`` and ``other``. + + INPUT: + + - ``other`` -- a polynomial in the same ring as ``self`` + + OUTPUT: + + A greatest common divisor of ``self`` and ``other`` as a polynomial + in the same ring as ``self``. Over a field, the return value will + be a monic polynomial. + + .. NOTE:: + + The actual algorithm for computing greatest common divisors depends + on the base ring underlying the polynomial ring. If the base ring + defines a method ``_gcd_univariate_polynomial``, then this method + will be called (see examples below). + + EXAMPLES:: + + sage: R. = QQ[] + sage: (2*x^2).gcd(2*x) + x + sage: R.zero().gcd(0) + 0 + sage: (2*x).gcd(0) + x + + One can easily add gcd functionality to new rings by providing a + method ``_gcd_univariate_polynomial``:: + + sage: R. = QQ[] + sage: S. = R[] + sage: h1 = y*x + sage: h2 = y^2*x^2 + sage: h1.gcd(h2) + Traceback (most recent call last): + ... + NotImplementedError: Univariate Polynomial Ring in x over Rational Field does not provide a gcd implementation for univariate polynomials + sage: T. = QQ[] + sage: R._gcd_univariate_polynomial = lambda f,g: S(T(f).gcd(g)) + sage: h1.gcd(h2) + x*y + sage: del R._gcd_univariate_polynomial + + """ + if hasattr(self.base_ring(), '_gcd_univariate_polynomial'): + return self.base_ring()._gcd_univariate_polynomial(self, other) + else: + raise NotImplementedError("%s does not provide a gcd implementation for univariate polynomials"%self.base_ring()) + @coerce_binop def lcm(self, other): """ @@ -5999,7 +6054,7 @@ cdef class Polynomial(CommutativeAlgebraElement): sage: (2*x*y).is_squarefree() # R does not provide a gcd implementation Traceback (most recent call last): ... - AttributeError: 'sage.rings.polynomial.polynomial_element.Polynomial_generic_dense' object has no attribute 'gcd' + NotImplementedError: Univariate Polynomial Ring in y over Rational Field does not provide a gcd implementation for univariate polynomials sage: (2*x*y^2).is_squarefree() False From a3bf5a1772a929434ab2ee22370bd9a29fb32b4c Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Mon, 3 Mar 2014 02:33:14 -0800 Subject: [PATCH 008/698] USe GMP or MPIR as default MP library. --- build/deps | 62 ++++++++++++++-------------- build/install | 80 ++++++++++++++++++++++++++++++++---- build/pkgs/gmp/spkg-install | 11 ++--- build/pkgs/mpir/spkg-install | 19 ++++++--- 4 files changed, 123 insertions(+), 49 deletions(-) diff --git a/build/deps b/build/deps index 3809e9555d2..8cb688922bf 100644 --- a/build/deps +++ b/build/deps @@ -72,7 +72,6 @@ all-sage: \ $(INST)/$(MPC) \ $(INST)/$(MPFI) \ $(INST)/$(MPFR) \ - $(INST)/$(MPIR) \ $(INST)/$(MPMATH) \ $(INST)/$(NETWORKX) \ $(INST)/$(NTL) \ @@ -109,6 +108,7 @@ all-sage: \ $(INST)/$(NCURSES) \ $(INST)/$(ZLIB) \ $(INST)/$(ZNPOLY) \ + $(INST)/$(SAGE_MP_LIBRARY) \ $(INST)/sage \ $(INST)/csage \ $(EXTCODE) \ @@ -126,7 +126,7 @@ toolchain: $(TOOLCHAIN) # See #14168 and #14232. toolchain-deps: $(MAKE) $(INST)/$(ZLIB) - $(MAKE) $(INST)/$(MPIR) + $(MAKE) $(INST)/$(SAGE_MP_LIBRARY) $(MAKE) $(INST)/$(MPFR) $(MAKE) $(INST)/$(MPC) $(MAKE) $(INST)/$(PPL) @@ -167,6 +167,9 @@ $(INST)/$(PATCH): $(INST)/$(BZIP2) # Building normal packages ############################################################################### +$(INST)/$(SAGE_MP_LIBRARY): $(INST)/$(ICONV) + +$(PIPE) "$(SAGE_SPKG) $(SAGE_MP_LIBRARY) 2>&1" "tee -a $(SAGE_LOGS)/$(SAGE_MP_LIBRARY).log" + $(INST)/$(ATLAS): $(INST)/$(PYTHON) +$(PIPE) "$(SAGE_SPKG) $(ATLAS) 2>&1" "tee -a $(SAGE_LOGS)/$(ATLAS).log" @@ -202,29 +205,26 @@ $(INST)/$(CONWAY): $(SAGERUNTIME) $(INST)/$(GRAPHS): +$(PIPE) "$(SAGE_SPKG) $(GRAPHS) 2>&1" "tee -a $(SAGE_LOGS)/$(GRAPHS).log" -$(INST)/$(GLPK): $(INST)/$(MPIR) $(INST)/$(ZLIB) +$(INST)/$(GLPK): $(INST)/$(SAGE_MP_LIBRARY) $(INST)/$(ZLIB) +$(PIPE) "$(SAGE_SPKG) $(GLPK) 2>&1" "tee -a $(SAGE_LOGS)/$(GLPK).log" $(INST)/$(PYTHON): $(INST)/$(ZLIB) $(INST)/$(BZIP2) \ $(INST)/$(READLINE) $(INST)/$(SQLITE) $(INST)/$(LIBPNG) +$(PIPE) "$(SAGE_SPKG) $(PYTHON) 2>&1" "tee -a $(SAGE_LOGS)/$(PYTHON).log" -$(INST)/$(MPIR): $(INST)/$(ICONV) - +$(PIPE) "$(SAGE_SPKG) $(MPIR) 2>&1" "tee -a $(SAGE_LOGS)/$(MPIR).log" - $(INST)/$(GSL): $(INST)/$(ATLAS) +$(PIPE) "$(SAGE_SPKG) $(GSL) 2>&1" "tee -a $(SAGE_LOGS)/$(GSL).log" $(INST)/$(GF2X): +$(PIPE) "$(SAGE_SPKG) $(GF2X) 2>&1" "tee -a $(SAGE_LOGS)/$(GF2X).log" -$(INST)/$(NTL): $(INST)/$(MPIR) $(INST)/$(GF2X) +$(INST)/$(NTL): $(INST)/$(SAGE_MP_LIBRARY) $(INST)/$(GF2X) +$(PIPE) "$(SAGE_SPKG) $(NTL) 2>&1" "tee -a $(SAGE_LOGS)/$(NTL).log" -$(INST)/$(FPLLL): $(INST)/$(MPIR) $(INST)/$(MPFR) +$(INST)/$(FPLLL): $(INST)/$(SAGE_MP_LIBRARY) $(INST)/$(MPFR) +$(PIPE) "$(SAGE_SPKG) $(FPLLL) 2>&1" "tee -a $(SAGE_LOGS)/$(FPLLL).log" -$(INST)/$(PARI): $(INST)/$(READLINE) $(INST)/$(MPIR) \ +$(INST)/$(PARI): $(INST)/$(READLINE) $(INST)/$(SAGE_MP_LIBRARY) \ $(INST)/$(PARI_GALDATA) $(INST)/$(PARI_SEADATA_SMALL) +$(PIPE) "$(SAGE_SPKG) $(PARI) 2>&1" "tee -a $(SAGE_LOGS)/$(PARI).log" @@ -242,34 +242,34 @@ $(INST)/$(POLYBORI): $(INST)/$(PYTHON) $(INST)/$(IPYTHON) \ $(INST)/$(POLYTOPES_DB): +$(PIPE) "$(SAGE_SPKG) $(POLYTOPES_DB) 2>&1" "tee -a $(SAGE_LOGS)/$(POLYTOPES_DB).log" -$(INST)/$(PPL): $(INST)/$(MPIR) $(INST)/$(GLPK) +$(INST)/$(PPL): $(INST)/$(SAGE_MP_LIBRARY) $(INST)/$(GLPK) +$(PIPE) "$(SAGE_SPKG) $(PPL) 2>&1" "tee -a $(SAGE_LOGS)/$(PPL).log" -$(INST)/$(MPC): $(INST)/$(MPIR) $(INST)/$(MPFR) +$(INST)/$(MPC): $(INST)/$(SAGE_MP_LIBRARY) $(INST)/$(MPFR) +$(PIPE) "$(SAGE_SPKG) $(MPC) 2>&1" "tee -a $(SAGE_LOGS)/$(MPC).log" -$(INST)/$(MPFR): $(INST)/$(MPIR) +$(INST)/$(MPFR): $(INST)/$(SAGE_MP_LIBRARY) +$(PIPE) "$(SAGE_SPKG) $(MPFR) 2>&1" "tee -a $(SAGE_LOGS)/$(MPFR).log" -$(INST)/$(MPFI): $(INST)/$(MPIR) $(INST)/$(MPFR) +$(INST)/$(MPFI): $(INST)/$(SAGE_MP_LIBRARY) $(INST)/$(MPFR) +$(PIPE) "$(SAGE_SPKG) $(MPFI) 2>&1" "tee -a $(SAGE_LOGS)/$(MPFI).log" -$(INST)/$(GIVARO): $(INST)/$(MPIR) +$(INST)/$(GIVARO): $(INST)/$(SAGE_MP_LIBRARY) +$(PIPE) "$(SAGE_SPKG) $(GIVARO) 2>&1" "tee -a $(SAGE_LOGS)/$(GIVARO).log" $(INST)/$(GIT): $(INST)/$(ZLIB) $(INST)/$(PYTHON) +$(PIPE) "$(SAGE_SPKG) $(GIT) 2>&1" "tee -a $(SAGE_LOGS)/$(GIT).log" -$(INST)/$(FFLASFFPACK): $(INST)/$(MPIR) $(INST)/$(GIVARO) \ +$(INST)/$(FFLASFFPACK): $(INST)/$(SAGE_MP_LIBRARY) $(INST)/$(GIVARO) \ $(INST)/$(GSL) $(INST)/$(ATLAS) +$(PIPE) "$(SAGE_SPKG) $(FFLASFFPACK) 2>&1" "tee -a $(SAGE_LOGS)/$(FFLASFFPACK).log" -$(INST)/$(LINBOX): $(INST)/$(MPIR) $(INST)/$(NTL) $(INST)/$(GIVARO) \ +$(INST)/$(LINBOX): $(INST)/$(SAGE_MP_LIBRARY) $(INST)/$(NTL) $(INST)/$(GIVARO) \ $(INST)/$(MPFR) $(INST)/$(FPLLL) $(INST)/$(IML) \ $(INST)/$(M4RI) $(INST)/$(M4RIE) $(INST)/$(FFLASFFPACK) +$(PIPE) "$(SAGE_SPKG) $(LINBOX) 2>&1" "tee -a $(SAGE_LOGS)/$(LINBOX).log" -$(INST)/$(IML): $(INST)/$(MPIR) $(INST)/$(GSL) $(INST)/$(ATLAS) +$(INST)/$(IML): $(INST)/$(SAGE_MP_LIBRARY) $(INST)/$(GSL) $(INST)/$(ATLAS) +$(PIPE) "$(SAGE_SPKG) $(IML) 2>&1" "tee -a $(SAGE_LOGS)/$(IML).log" $(INST)/$(GENUS2REDUCTION): $(INST)/$(PARI) @@ -293,7 +293,7 @@ $(INST)/$(SYMPOW): $(INST)/$(SYMMETRICA): +$(PIPE) "$(SAGE_SPKG) $(SYMMETRICA) 2>&1" "tee -a $(SAGE_LOGS)/$(SYMMETRICA).log" -$(INST)/$(GAP): $(INST)/$(NCURSES) $(INST)/$(READLINE) $(INST)/$(MPIR) +$(INST)/$(GAP): $(INST)/$(NCURSES) $(INST)/$(READLINE) $(INST)/$(SAGE_MP_LIBRARY) +$(PIPE) "$(SAGE_SPKG) $(GAP) 2>&1" "tee -a $(SAGE_LOGS)/$(GAP).log" $(INST)/$(LIBGAP): $(INST)/$(GAP) @@ -330,7 +330,7 @@ $(INST)/$(SAGETEX): $(INST)/$(PYTHON) \ $(INST)/$(SETUPTOOLS): $(INST)/$(PYTHON) +$(PIPE) "$(SAGE_SPKG) $(SETUPTOOLS) 2>&1" "tee -a $(SAGE_LOGS)/$(SETUPTOOLS).log" -$(INST)/$(SINGULAR): $(INST)/$(MPIR) $(INST)/$(NTL) \ +$(INST)/$(SINGULAR): $(INST)/$(SAGE_MP_LIBRARY) $(INST)/$(NTL) \ $(INST)/$(READLINE) $(INST)/$(MPFR) +$(PIPE) "$(SAGE_SPKG) $(SINGULAR) 2>&1" "tee -a $(SAGE_LOGS)/$(SINGULAR).log" @@ -360,22 +360,22 @@ $(INST)/$(MATPLOTLIB): $(INST)/$(PYTHON) $(INST)/$(NUMPY) \ $(INST)/$(GDMODULE) +$(PIPE) "$(SAGE_SPKG) $(MATPLOTLIB) 2>&1" "tee -a $(SAGE_LOGS)/$(MATPLOTLIB).log" -$(INST)/$(CDDLIB): $(INST)/$(MPIR) +$(INST)/$(CDDLIB): $(INST)/$(SAGE_MP_LIBRARY) +$(PIPE) "$(SAGE_SPKG) $(CDDLIB) 2>&1" "tee -a $(SAGE_LOGS)/$(CDDLIB).log" -$(INST)/$(GFAN): $(INST)/$(MPIR) $(INST)/$(CDDLIB) +$(INST)/$(GFAN): $(INST)/$(SAGE_MP_LIBRARY) $(INST)/$(CDDLIB) +$(PIPE) "$(SAGE_SPKG) $(GFAN) 2>&1" "tee -a $(SAGE_LOGS)/$(GFAN).log" $(INST)/$(TACHYON): $(INST)/$(LIBPNG) +$(PIPE) "$(SAGE_SPKG) $(TACHYON) 2>&1" "tee -a $(SAGE_LOGS)/$(TACHYON).log" -$(INST)/$(ECM): $(INST)/$(MPIR) +$(INST)/$(ECM): $(INST)/$(SAGE_MP_LIBRARY) +$(PIPE) "$(SAGE_SPKG) $(ECM) 2>&1" "tee -a $(SAGE_LOGS)/$(ECM).log" -$(INST)/$(RATPOINTS): $(INST)/$(MPIR) +$(INST)/$(RATPOINTS): $(INST)/$(SAGE_MP_LIBRARY) +$(PIPE) "$(SAGE_SPKG) $(RATPOINTS) 2>&1" "tee -a $(SAGE_LOGS)/$(RATPOINTS).log" -$(INST)/$(ECL): $(INST)/$(MPIR) $(INST)/$(READLINE) $(INST)/$(BOEHM_GC) +$(INST)/$(ECL): $(INST)/$(SAGE_MP_LIBRARY) $(INST)/$(READLINE) $(INST)/$(BOEHM_GC) +$(PIPE) "$(SAGE_SPKG) $(ECL) 2>&1" "tee -a $(SAGE_LOGS)/$(ECL).log" $(INST)/$(MAXIMA): $(INST)/$(ECL) @@ -393,10 +393,10 @@ $(INST)/$(SYMPY): $(INST)/$(PYTHON) $(INST)/$(CYTHON): $(INST)/$(PYTHON) +$(PIPE) "$(SAGE_SPKG) $(CYTHON) 2>&1" "tee -a $(SAGE_LOGS)/$(CYTHON).log" -$(INST)/$(FLINTQS): $(INST)/$(MPIR) +$(INST)/$(FLINTQS): $(INST)/$(SAGE_MP_LIBRARY) +$(PIPE) "$(SAGE_SPKG) $(FLINTQS) 2>&1" "tee -a $(SAGE_LOGS)/$(FLINTQS).log" -$(INST)/$(FLINT): $(INST)/$(MPIR) $(INST)/$(MPFR) $(INST)/$(NTL) +$(INST)/$(FLINT): $(INST)/$(SAGE_MP_LIBRARY) $(INST)/$(MPFR) $(INST)/$(NTL) +$(PIPE) "$(SAGE_SPKG) $(FLINT) 2>&1" "tee -a $(SAGE_LOGS)/$(FLINT).log" $(INST)/$(ECLIB): $(INST)/$(PARI) $(INST)/$(NTL) $(INST)/$(FLINT) @@ -410,7 +410,7 @@ $(INST)/$(M4RIE): $(INST)/$(M4RI) $(INST)/$(GIVARO) $(INST)/$(NTL) # zn_poly really does depend on Python, despite this is far from obvious. # The 'configure' script in zn_poly calls Python to make a 'makefile'. -$(INST)/$(ZNPOLY): $(INST)/$(MPIR) $(INST)/$(PYTHON) +$(INST)/$(ZNPOLY): $(INST)/$(SAGE_MP_LIBRARY) $(INST)/$(PYTHON) +$(PIPE) "$(SAGE_SPKG) $(ZNPOLY) 2>&1" "tee -a $(SAGE_LOGS)/$(ZNPOLY).log" $(INST)/$(SAGENB): $(INST)/$(PYTHON) $(INST)/$(SETUPTOOLS) $(INST)/$(PEXPECT) \ @@ -433,7 +433,7 @@ $(INST)/$(PYGMENTS): $(INST)/$(PYTHON) $(INST)/$(SETUPTOOLS) # List all *build-time* dependencies of the Sage library. These are, # on the one hand, programs needed for the build/install process of the # Sage library (e.g. JINJA2), and on the -# other hand all dependencies for Cython files (e.g. PARI, NTL, MPIR). +# other hand all dependencies for Cython files (e.g. PARI, NTL, SAGE_MP_LIBRARY). $(INST)/sage: \ $(INST)/$(ATLAS) \ $(INST)/$(CEPHES) \ @@ -459,7 +459,7 @@ $(INST)/sage: \ $(INST)/$(MPC) \ $(INST)/$(MPFI) \ $(INST)/$(MPFR) \ - $(INST)/$(MPIR) \ + $(INST)/$(SAGE_MP_LIBRARY) \ $(INST)/$(NTL) \ $(INST)/$(NUMPY) \ $(INST)/$(PARI) \ @@ -480,7 +480,7 @@ $(INST)/sage: \ fi $(INST)/csage: $(INST)/$(SCONS) \ - $(INST)/$(MPIR) \ + $(INST)/$(SAGE_MP_LIBRARY) \ $(INST)/$(NTL) \ $(INST)/$(PARI) \ $(INST)/$(PYTHON) @@ -494,7 +494,7 @@ $(INST)/ccache: $(BASE) $(INST)/$(ZLIB) +$(PIPE) "$(SAGE_SPKG) ccache 2>&1" "tee -a $(SAGE_LOGS)/ccache.log" touch $(INST)/ccache -$(INST)/$(GCC): $(INST)/$(MPIR) $(INST)/$(MPFR) $(INST)/$(MPC) \ +$(INST)/$(GCC): $(INST)/$(SAGE_MP_LIBRARY) $(INST)/$(MPFR) $(INST)/$(MPC) \ $(INST)/$(ZLIB) +$(PIPE) "$(SAGE_SPKG) $(GCC) 2>&1" "tee -a $(SAGE_LOGS)/$(GCC).log" diff --git a/build/install b/build/install index 05d0b575b07..e990f5008d6 100755 --- a/build/install +++ b/build/install @@ -43,12 +43,6 @@ EOF exit 2 fi -if [ "$SAGE_UPGRADING" = yes ]; then - # We're doing an upgrade. Let build/Makefile call sage-spkg with - # "-f" to force rebuilding dependent packages, too: - export SAGE_SPKG_OPTS="-f" -fi - ############################################################################### # Create basic directories needed for Sage ############################################################################### @@ -61,6 +55,70 @@ mkdir -p "$SAGE_LOCAL/lib" mkdir -p "$SAGE_SPKG_INST" mkdir -p "$SAGE_SHARE" +############################################################################### +# Determine whether to use MPIR (default standard pkg) or GMP (optional pkg). +############################################################################### + +if [ -z "$SAGE_MP_LIBRARY" ]; then + # Automatic detection of installed MP library. + if [ ! -f "$SAGE_LOCAL/share/mp_config" ]; then + echo "MPIR" > "$SAGE_LOCAL/share/mp_config" + fi + SAGE_MP_LIBRARY=`cat "$SAGE_LOCAL/share/mp_config"` +fi + +SAGE_OLD_MP_LIBRARY=`cat "$SAGE_LOCAL/share/mp_config"` +if [ "$SAGE_MP_LIBRARY" != "$SAGE_OLD_MP_LIBRARY" ]; then + SAGE_CHANGE_MP_LIBRARY=yes +else + SAGE_CHANGE_MP_LIBRARY=no +fi + +case "$SAGE_MP_LIBRARY" in + MPIR|GMP) + echo "Using $SAGE_MP_LIBRARY as default MP library." + echo $SAGE_MP_LIBRARY > "$SAGE_LOCAL/share/mp_config" + ;; + *) + echo "Allowed values for SAGE_MP_LIBRARY are \"MPIR\" and \"GMP\"." + echo "If you did not set this variable, check the content of" + echo "\"$SAGE_LOCAL/share/mp_config\"." + exit 1 + ;; +esac + +if [ "$SAGE_CHANGE_MP_LIBRARY" = "yes" ]; then + if [ -f "$SAGE_LOCAL/bin/gcc" ]; then + echo "Deleting old GCC install as the default MP library changes." + rm -f "$SAGE_LOCAL/bin/gcc" + rm -f "$SAGE_LOCAL/bin/cpp" + rm -f "$SAGE_LOCAL/bin/g++" + rm -f "$SAGE_LOCAL/bin/gfortran" + fi + if [ -z "$SAGE_UPGRADING" ]; then + echo "Setting SAGE_UPGRADING to yes as the default MP library changes." + SAGE_UPGRADING=yes + else + if [ "$SAGE_UPGRADING" != "yes" ]; then + echo "SAGE_UPGRADING is set to something different from yes" + echo "whereas the default MP library changes." + echo "You might end up with a broken Sage installation." + fi + fi +fi + +export SAGE_MP_LIBRARY SAGE_CHANGE_MP_LIBRARY + +############################################################################### +# Determine whether we should automatically rebuild dependencies. +############################################################################### + +if [ "$SAGE_UPGRADING" = yes ]; then + # We're doing an upgrade. Let build/Makefile call sage-spkg with + # "-f" to force rebuilding dependent packages, too: + export SAGE_SPKG_OPTS="-f" +fi + ############################################################################### # Determine whether to install GCC (gcc, g++, gfortran). ############################################################################### @@ -401,7 +459,6 @@ MAXIMA=`newest_version maxima` MPC=`newest_version mpc` MPFI=`newest_version mpfi` MPFR=`newest_version mpfr` -MPIR=`newest_version mpir` MPMATH=`newest_version mpmath` NETWORKX=`newest_version networkx` NTL=`newest_version ntl` @@ -447,6 +504,15 @@ INST=`echo "$SAGE_SPKG_INST" | sed 's/ /\\\\ /g'` EOF +# Sage MP library +sage_mp_library=`echo "$SAGE_MP_LIBRARY" | tr '[A-Z]' '[a-z]'` +cat >&5 << EOF +# Sage MP library +$(SAGE_MP_LIBRARY)=`newest_version $(sage_mp_library)` +SAGE_MP_LIBRARY=$(SAGE_MP_LIBRARY) + +EOF + # $(TOOLCHAIN) variable containing prerequisites for the build echo >&5 -n 'TOOLCHAIN =' if [ "$SAGE_INSTALL_CCACHE" = yes ]; then diff --git a/build/pkgs/gmp/spkg-install b/build/pkgs/gmp/spkg-install index a911077431d..cedead6d99b 100755 --- a/build/pkgs/gmp/spkg-install +++ b/build/pkgs/gmp/spkg-install @@ -311,13 +311,16 @@ rm -f "$SAGE_LOCAL"/include/{gmp,mpir}*.h # Do NOT delete old GMP/GMP shared libraries as Sage's versions of libraries # used by GCC might still refer to them, such that their deletion would break # GCC inside Sage. (We could perhaps remove libgmp* though.) -if false; then +# Unless we are switching the default MP library which breaks GCC anyway. +if [ ! -x "$SAGE_LOCAL/bin/gcc" ] || [ "$SAGE_CHANGE_MP_LIBRARY" = "yes" ]; then echo "Removing old GMP/MPIR libraries..." rm -f "$SAGE_LOCAL"/lib/lib{gmp,mpir}* + rm -f "$SAGE_LOCAL"/bin/cyg{gmp,mpir}* else echo "Not removing old GMP/MPIR shared libraries, as other libraries" echo "and executables might still refer to them:" - ls -l "$SAGE_LOCAL"/lib/lib{gmp,mpir}*.so.* + ls -l "$SAGE_LOCAL"/lib/lib{gmp,mpir}* + ls -l "$SAGE_LOCAL"/bin/cyg{gmp,mpir}* echo "(Libraries with the same version number will get updated though.)" fi @@ -330,9 +333,7 @@ echo "Now installing GMP..." $MAKE install if [ $? -ne 0 ]; then echo >&2 "Error installing GMP." - if [ "$UNAME" != "CYGWIN" ]; then # On Cygwin an error is not fatal. - exit 1 - fi + exit 1 fi echo diff --git a/build/pkgs/mpir/spkg-install b/build/pkgs/mpir/spkg-install index 7172e4a76bd..dd8817866a7 100755 --- a/build/pkgs/mpir/spkg-install +++ b/build/pkgs/mpir/spkg-install @@ -193,7 +193,13 @@ export ABI CFLAGS CXXFLAGS LDFLAGS # Partially redundant, but safe(r). # Now configure MPIR, eventually modifying CFLAGS [further]: ############################################################################### -MPIR_CONFIGURE="--enable-gmpcompat --enable-shared $MPIR_CONFIGURE" +MPIR_CONFIGURE="--enable-shared $MPIR_CONFIGURE" + +# Don't install GMP compat headers and symlinks if MPIR is not the default MP +# library. +if [ `cat "SAGE_LOCAL/share/mp_config"` = "MPIR" ]; then + MPIR_CONFIGURE="--enable-gmpcompat $MPIR_CONFIGURE" +fi # If we're bootstrapping GCC from the GCC spkg, don't build the C++ # interface (cf. #12782), static libraries and disable fat binary. @@ -334,13 +340,16 @@ rm -f "$SAGE_LOCAL"/include/{gmp,mpir}*.h # Do NOT delete old GMP/MPIR shared libraries as Sage's versions of libraries # used by GCC might still refer to them, such that their deletion would break # GCC inside Sage. (We could perhaps remove libmpir* though.) -if false; then +# Unless we are switching the default MP library which breaks GCC anyway. +if [ ! -x "$SAGE_LOCAL/bin/gcc" ] || [ "$SAGE_CHANGE_MP_LIBRARY" = "yes" ]; then echo "Removing old GMP/MPIR libraries..." rm -f "$SAGE_LOCAL"/lib/lib{gmp,mpir}* + rm -f "$SAGE_LOCAL"/bin/cyg{gmp,mpir}* else echo "Not removing old GMP/MPIR shared libraries, as other libraries" echo "and executables might still refer to them:" - ls -l "$SAGE_LOCAL"/lib/lib{gmp,mpir}*.so.* + ls -l "$SAGE_LOCAL"/lib/lib{gmp,mpir}* + ls -l "$SAGE_LOCAL"/bin/cyg{gmp,mpir}* echo "(Libraries with the same version number will get updated though.)" fi @@ -353,9 +362,7 @@ echo "Now installing MPIR..." $MAKE install if [ $? -ne 0 ]; then echo >&2 "Error installing MPIR." - if [ "$UNAME" != "CYGWIN" ]; then # On Cygwin an error is not fatal. - exit 1 - fi + exit 1 fi echo From 64802d4fd81be99903abe87c2c77261cef77808c Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Mon, 17 Mar 2014 08:49:42 -0700 Subject: [PATCH 009/698] Introduce variables to switch between MPIR and GMP. One case play with: * SAGE_MP_LIBRARY; * SAGE_CHANGE_MP_LIBRARY; * SAGE_UPGRADING. --- build/install | 36 +++++++++++++++++++++++++++--------- build/pkgs/gmp/spkg-install | 4 +--- build/pkgs/mpir/spkg-install | 6 ++---- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/build/install b/build/install index 8b5801d11da..3c0ee98d95e 100755 --- a/build/install +++ b/build/install @@ -68,10 +68,12 @@ if [ -z "$SAGE_MP_LIBRARY" ]; then fi SAGE_OLD_MP_LIBRARY=`cat "$SAGE_LOCAL/share/mp_config"` -if [ "$SAGE_MP_LIBRARY" != "$SAGE_OLD_MP_LIBRARY" ]; then - SAGE_CHANGE_MP_LIBRARY=yes -else - SAGE_CHANGE_MP_LIBRARY=no +if [ -z "$SAGE_CHANGE_MP_LIBRARY" ]; then + if [ "$SAGE_MP_LIBRARY" != "$SAGE_OLD_MP_LIBRARY" ]; then + SAGE_CHANGE_MP_LIBRARY=yes + else + SAGE_CHANGE_MP_LIBRARY=no + fi fi case "$SAGE_MP_LIBRARY" in @@ -88,20 +90,37 @@ case "$SAGE_MP_LIBRARY" in esac if [ "$SAGE_CHANGE_MP_LIBRARY" = "yes" ]; then + echo "SAGE_CHANGE_MP_LIBRARY has been set to yes automatically or by the user." + echo "Therefore, the previous versions of MP/MPFR/MPC/PPL and potentially GCC" + echo "will be deleted and rebuilt." + echo "This may lead to an unusable installation." + echo "If that was not your intention, you have 5 seconds to kill this process." + sleep 5 + + echo "Deleting old MP/MPFR/MPC/PPL install as the default MP library changed." + rm -f "$SAGE_LOCAL"/lib/lib{gmp,mpir}* + rm -f "$SAGE_LOCAL"/lib/libmpfr* + rm -f "$SAGE_LOCAL"/lib/libmpc* + rm -f "$SAGE_LOCAL"/lib/libppl* + if [ -f "$SAGE_LOCAL/bin/gcc" ]; then - echo "Deleting old GCC install as the default MP library changes." + echo "Deleting old GCC install as the default MP library changed." rm -f "$SAGE_LOCAL/bin/gcc" rm -f "$SAGE_LOCAL/bin/cpp" rm -f "$SAGE_LOCAL/bin/g++" rm -f "$SAGE_LOCAL/bin/gfortran" fi + + echo "Triggering rebuild of MP library." + rm -f "$SAGE_SPKG_INST"/{gmp,mpir}* + if [ -z "$SAGE_UPGRADING" ]; then - echo "Setting SAGE_UPGRADING to yes as the default MP library changes." + echo "Setting SAGE_UPGRADING to yes as the default MP library changed." SAGE_UPGRADING=yes else if [ "$SAGE_UPGRADING" != "yes" ]; then echo "SAGE_UPGRADING is set to something different from yes" - echo "whereas the default MP library changes." + echo "whereas the default MP library changed." echo "You might end up with a broken Sage installation." fi fi @@ -476,8 +495,7 @@ EOF sage_mp_library=`echo "$SAGE_MP_LIBRARY" | tr '[A-Z]' '[a-z]'` cat >&5 << EOF # Sage MP library -$(SAGE_MP_LIBRARY)=`newest_version $(sage_mp_library)` -SAGE_MP_LIBRARY=$(SAGE_MP_LIBRARY) +SAGE_MP_LIBRARY=`newest_version $sage_mp_library` EOF diff --git a/build/pkgs/gmp/spkg-install b/build/pkgs/gmp/spkg-install index cedead6d99b..f1762badbc9 100755 --- a/build/pkgs/gmp/spkg-install +++ b/build/pkgs/gmp/spkg-install @@ -312,15 +312,13 @@ rm -f "$SAGE_LOCAL"/include/{gmp,mpir}*.h # used by GCC might still refer to them, such that their deletion would break # GCC inside Sage. (We could perhaps remove libgmp* though.) # Unless we are switching the default MP library which breaks GCC anyway. -if [ ! -x "$SAGE_LOCAL/bin/gcc" ] || [ "$SAGE_CHANGE_MP_LIBRARY" = "yes" ]; then +if [ "$SAGE_CHANGE_MP_LIBRARY" = "yes" ]; then echo "Removing old GMP/MPIR libraries..." rm -f "$SAGE_LOCAL"/lib/lib{gmp,mpir}* - rm -f "$SAGE_LOCAL"/bin/cyg{gmp,mpir}* else echo "Not removing old GMP/MPIR shared libraries, as other libraries" echo "and executables might still refer to them:" ls -l "$SAGE_LOCAL"/lib/lib{gmp,mpir}* - ls -l "$SAGE_LOCAL"/bin/cyg{gmp,mpir}* echo "(Libraries with the same version number will get updated though.)" fi diff --git a/build/pkgs/mpir/spkg-install b/build/pkgs/mpir/spkg-install index dd8817866a7..2c46e0e6b9b 100755 --- a/build/pkgs/mpir/spkg-install +++ b/build/pkgs/mpir/spkg-install @@ -197,7 +197,7 @@ MPIR_CONFIGURE="--enable-shared $MPIR_CONFIGURE" # Don't install GMP compat headers and symlinks if MPIR is not the default MP # library. -if [ `cat "SAGE_LOCAL/share/mp_config"` = "MPIR" ]; then +if [ `cat "$SAGE_LOCAL/share/mp_config"` = "MPIR" ]; then MPIR_CONFIGURE="--enable-gmpcompat $MPIR_CONFIGURE" fi @@ -341,15 +341,13 @@ rm -f "$SAGE_LOCAL"/include/{gmp,mpir}*.h # used by GCC might still refer to them, such that their deletion would break # GCC inside Sage. (We could perhaps remove libmpir* though.) # Unless we are switching the default MP library which breaks GCC anyway. -if [ ! -x "$SAGE_LOCAL/bin/gcc" ] || [ "$SAGE_CHANGE_MP_LIBRARY" = "yes" ]; then +if [ "$SAGE_CHANGE_MP_LIBRARY" = "yes" ]; then echo "Removing old GMP/MPIR libraries..." rm -f "$SAGE_LOCAL"/lib/lib{gmp,mpir}* - rm -f "$SAGE_LOCAL"/bin/cyg{gmp,mpir}* else echo "Not removing old GMP/MPIR shared libraries, as other libraries" echo "and executables might still refer to them:" ls -l "$SAGE_LOCAL"/lib/lib{gmp,mpir}* - ls -l "$SAGE_LOCAL"/bin/cyg{gmp,mpir}* echo "(Libraries with the same version number will get updated though.)" fi From 28062ed51a00c44f37f783b6d3d4e65b7114b1d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Wed, 9 Apr 2014 10:21:34 +0200 Subject: [PATCH 010/698] Experiment with moving the indexes around and toward the source tree --- ...lgebra.rst => algebraic_combinatorics.rst} | 20 +- src/doc/en/reference/combinat/developer.rst | 2 - src/doc/en/reference/combinat/index.rst | 157 +-------------- src/doc/en/reference/combinat/module_list.rst | 122 ++++++++++++ src/doc/en/reference/combinat/ncsf_qsym.rst | 10 +- src/doc/en/reference/combinat/partitions.rst | 1 + src/doc/en/reference/combinat/posets.rst | 1 + .../combinat/symmetric_functions.rst | 40 ++-- src/doc/en/reference/combinat/tableaux.rst | 1 + src/sage/combinat/__init__.py | 95 ++++++++++ src/sage/combinat/index.py | 179 ++++++++++++++++++ 11 files changed, 449 insertions(+), 179 deletions(-) rename src/doc/en/reference/combinat/{algebra.rst => algebraic_combinatorics.rst} (57%) create mode 100644 src/doc/en/reference/combinat/module_list.rst create mode 100644 src/sage/combinat/index.py diff --git a/src/doc/en/reference/combinat/algebra.rst b/src/doc/en/reference/combinat/algebraic_combinatorics.rst similarity index 57% rename from src/doc/en/reference/combinat/algebra.rst rename to src/doc/en/reference/combinat/algebraic_combinatorics.rst index 860f25ab1d4..8352070ad1a 100644 --- a/src/doc/en/reference/combinat/algebra.rst +++ b/src/doc/en/reference/combinat/algebraic_combinatorics.rst @@ -1,17 +1,29 @@ -Combinatorial Algebras -====================== +.. _algebraic_combinatorics: + +Algebraic combinatorics +======================= + +- :class:`sage.combinat.diagram_algebras.PartitionAlgebra` + .. toctree:: :maxdepth: 2 - ../sage/combinat/free_module - ../sage/combinat/combinatorial_algebra ../sage/combinat/descent_algebra ../sage/combinat/diagram_algebras ../sage/combinat/symmetric_group_algebra ../sage/combinat/symmetric_group_representations + ../sage/combinat/yang_baxter_graph + ../sage/combinat/schubert_polynomial ../sage/combinat/partition_algebra ../sage/algebras/iwahori_hecke_algebra ../sage/algebras/nil_coxeter_algebra ../sage/algebras/affine_nil_temperley_lieb + + ../sage/combinat/kazhdan_lusztig + + ../symmetric_functions + ../ncsf_qsym + ../ncsym + ../sage/combinat/hall_polynomial diff --git a/src/doc/en/reference/combinat/developer.rst b/src/doc/en/reference/combinat/developer.rst index 96fe8685a22..da4c0f99874 100644 --- a/src/doc/en/reference/combinat/developer.rst +++ b/src/doc/en/reference/combinat/developer.rst @@ -4,12 +4,10 @@ Developer Tools .. toctree:: :maxdepth: 2 - ../sage/combinat/backtrack ../sage/combinat/output ../sage/combinat/permutation_nk ../sage/combinat/split_nk ../sage/combinat/choose_nk ../sage/combinat/multichoose_nk - ../sage/combinat/tools ../sage/combinat/ranker diff --git a/src/doc/en/reference/combinat/index.rst b/src/doc/en/reference/combinat/index.rst index cf8f9662364..4b2090e2d8c 100644 --- a/src/doc/en/reference/combinat/index.rst +++ b/src/doc/en/reference/combinat/index.rst @@ -1,162 +1,23 @@ Combinatorics ============= -**Algebra** +Introductory material +--------------------- -.. toctree:: - :maxdepth: 1 - - cluster_algebras - algebra - -**Backtracking solvers** - -.. toctree:: - :maxdepth: 1 - - sage/combinat/tiling - sage/combinat/dlx - sage/combinat/matrices/dlxcpp - -**Compositions** - -.. toctree:: - :maxdepth: 1 - - sage/combinat/composition_signed - sage/combinat/composition - -**Counting** +- :mod:`sage.combinat` +- :mod:`sage.combinat.tutorial` -.. toctree:: - :maxdepth: 1 - - sage/combinat/sloane_functions - sage/databases/oeis - sage/combinat/expnums - sage/combinat/combinat - -**Integer lists/matrices/vectors** - -.. toctree:: - :maxdepth: 1 - sage/combinat/integer_list - sage/combinat/integer_matrices - sage/combinat/integer_vector - sage/combinat/integer_vector_weighted +Thematic indexes +---------------- -**Partitions** +- :ref:`algebraic_combinatorics` -.. toctree:: - :maxdepth: 1 - - partitions - sage/combinat/partition - sage/combinat/partition_tuple - sage/combinat/set_partition_ordered - sage/combinat/set_partition - sage/combinat/skew_partition - sage/combinat/vector_partition - -**Permutations** +.. .. include:: sage/combinat/index.rst .. toctree:: :maxdepth: 1 - sage/combinat/permutation - sage/combinat/affine_permutation - sage/combinat/derangements - sage/combinat/integer_vectors_mod_permgroup - sage/combinat/enumeration_mod_permgroup - -**Symmetric functions** - -.. toctree:: - :maxdepth: 1 - - symmetric_functions - ncsf_qsym - ncsym - -**Trees** - -.. toctree:: - :maxdepth: 1 - - sage/combinat/abstract_tree - sage/combinat/ordered_tree - sage/combinat/binary_tree - -**Word** - -.. toctree:: - :maxdepth: 1 - - words - sage/combinat/subword - sage/combinat/lyndon_word - sage/combinat/dyck_word - - -**Unsorted** - -.. toctree:: - :maxdepth: 1 - - sage/combinat/tutorial - sage/combinat/alternating_sign_matrix - sage/combinat/cartesian_product - sage/combinat/combination - sage/combinat/core - sage/combinat/debruijn_sequence - sage/combinat/degree_sequences - sage/combinat/tamari_lattices - sage/combinat/e_one_star - sage/combinat/finite_class - sage/combinat/hall_polynomial - sage/combinat/matrices/hadamard_matrix - sage/combinat/restricted_growth - sage/combinat/yang_baxter_graph - sage/combinat/gelfand_tsetlin_patterns - sage/combinat/graph_path - sage/combinat/matrices/latin - sage/combinat/necklace - sage/combinat/non_decreasing_parking_function - sage/combinat/parking_functions - sage/combinat/perfect_matching - sage/combinat/q_analogues - sage/combinat/q_bernoulli - sage/combinat/rsk - sage/combinat/sidon_sets - sage/combinat/six_vertex_model - sage/combinat/similarity_class_type - sage/combinat/subset - sage/combinat/subsets_pairwise - - sage/combinat/tuple - - sage/combinat/binary_recurrence_sequences - - tableaux - root_systems - - sage/combinat/kazhdan_lusztig - sage/combinat/knutson_tao_puzzles - - crystals - posets - rigged_configurations - designs - species - developer - sage/combinat/finite_state_machine - - - sage/combinat/dict_addition - sage/combinat/misc - sage/combinat/combinatorial_map - - + module_list .. include:: ../footer.txt diff --git a/src/doc/en/reference/combinat/module_list.rst b/src/doc/en/reference/combinat/module_list.rst new file mode 100644 index 00000000000..87d55d9b91b --- /dev/null +++ b/src/doc/en/reference/combinat/module_list.rst @@ -0,0 +1,122 @@ +Alphabetical module list +======================== + +Submodules +---------- + +.. toctree:: + :maxdepth: 1 + + symmetric_functions + ncsf_qsym + posets + root_systems + crystals + +.. sage/combinat/ncsf_qsym/index +.. sage/combinat/ncsym/index +.. sage/combinat/posets/index +.. sage/combinat/cluster_algebras/index +.. sage/combinat/crystals/index +.. sage/combinat/designs/index +.. sage/combinat/rigged_configurations/index +.. sage/combinat/root_systems/index +.. sage/combinat/sf/index +.. sage/combinat/species/index +.. sage/combinat/words/index + +Modules +------- + +.. toctree:: + :maxdepth: 2 + + sage/algebras/affine_nil_temperley_lieb + sage/algebras/iwahori_hecke_algebra + sage/algebras/nil_coxeter_algebra + sage/combinat/abstract_tree + sage/combinat/affine_permutation + sage/combinat/alternating_sign_matrix + sage/combinat/binary_recurrence_sequences + sage/combinat/binary_tree + sage/combinat/cartesian_product + sage/combinat/combinat + sage/combinat/combination + sage/combinat/combinatorial_algebra + sage/combinat/combinatorial_map + sage/combinat/composition + sage/combinat/composition_signed + sage/combinat/core + sage/combinat/debruijn_sequence + sage/combinat/degree_sequences + sage/combinat/derangements + sage/combinat/descent_algebra + sage/combinat/diagram_algebras + sage/combinat/dict_addition + sage/combinat/dlx + sage/combinat/dyck_word + sage/combinat/e_one_star + sage/combinat/enumeration_mod_permgroup + sage/combinat/expnums + sage/combinat/finite_class + sage/combinat/finite_state_machine + sage/combinat/free_module + sage/combinat/gelfand_tsetlin_patterns + sage/combinat/graph_path + sage/combinat/hall_polynomial + sage/combinat/hall_polynomial + sage/combinat/integer_list + sage/combinat/integer_matrices + sage/combinat/integer_vector + sage/combinat/integer_vector_weighted + sage/combinat/integer_vectors_mod_permgroup + sage/combinat/k_tableau + sage/combinat/kazhdan_lusztig + sage/combinat/kazhdan_lusztig + sage/combinat/knutson_tao_puzzles + sage/combinat/lyndon_word + sage/combinat/matrices/dlxcpp + sage/combinat/matrices/hadamard_matrix + sage/combinat/matrices/latin + sage/combinat/misc + sage/combinat/necklace + sage/combinat/non_decreasing_parking_function + sage/combinat/ordered_tree + sage/combinat/parking_functions + sage/combinat/partition + sage/combinat/partition + sage/combinat/partition_algebra + sage/combinat/partition_tuple + sage/combinat/partition_tuple + sage/combinat/perfect_matching + sage/combinat/permutation + sage/combinat/q_analogues + sage/combinat/q_bernoulli + sage/combinat/restricted_growth + sage/combinat/ribbon + sage/combinat/ribbon_tableau + sage/combinat/rsk + sage/combinat/schubert_polynomial + sage/combinat/set_partition + sage/combinat/set_partition_ordered + sage/combinat/sidon_sets + sage/combinat/similarity_class_type + sage/combinat/six_vertex_model + sage/combinat/skew_partition + sage/combinat/skew_tableau + sage/combinat/sloane_functions + sage/combinat/subset + sage/combinat/subsets_pairwise + sage/combinat/subword + sage/combinat/symmetric_group_algebra + sage/combinat/symmetric_group_representations + sage/combinat/tableau + sage/combinat/tableau_tuple + sage/combinat/tamari_lattices + sage/combinat/tiling + sage/combinat/tuple + sage/combinat/tutorial + sage/combinat/vector_partition + sage/combinat/yang_baxter_graph + +.. include:: ../footer.txt diff --git a/src/doc/en/reference/combinat/ncsf_qsym.rst b/src/doc/en/reference/combinat/ncsf_qsym.rst index 286d42edec6..3a9c05aff62 100644 --- a/src/doc/en/reference/combinat/ncsf_qsym.rst +++ b/src/doc/en/reference/combinat/ncsf_qsym.rst @@ -4,8 +4,8 @@ Non-Commutative Symmetric Functions and Quasi-Symmetric Functions .. toctree:: :maxdepth: 2 - ../sage/combinat/ncsf_qsym/tutorial - ../sage/combinat/ncsf_qsym/combinatorics - ../sage/combinat/ncsf_qsym/generic_basis_code - ../sage/combinat/ncsf_qsym/ncsf - ../sage/combinat/ncsf_qsym/qsym + sage/combinat/ncsf_qsym/tutorial + sage/combinat/ncsf_qsym/combinatorics + sage/combinat/ncsf_qsym/generic_basis_code + sage/combinat/ncsf_qsym/ncsf + sage/combinat/ncsf_qsym/qsym diff --git a/src/doc/en/reference/combinat/partitions.rst b/src/doc/en/reference/combinat/partitions.rst index 19b3f4feb7f..27e33587feb 100644 --- a/src/doc/en/reference/combinat/partitions.rst +++ b/src/doc/en/reference/combinat/partitions.rst @@ -7,3 +7,4 @@ Partitions and Partition-like Objects sage/combinat/partition sage/combinat/partition_tuple sage/combinat/skew_partition + sage/combinat/core diff --git a/src/doc/en/reference/combinat/posets.rst b/src/doc/en/reference/combinat/posets.rst index 54cecfec639..1fc10a80466 100644 --- a/src/doc/en/reference/combinat/posets.rst +++ b/src/doc/en/reference/combinat/posets.rst @@ -10,3 +10,4 @@ Posets ../sage/combinat/posets/lattices ../sage/combinat/posets/linear_extensions ../sage/combinat/posets/poset_examples + ../sage/combinat/tamari_lattices diff --git a/src/doc/en/reference/combinat/symmetric_functions.rst b/src/doc/en/reference/combinat/symmetric_functions.rst index 4a25c4c0f45..d5cc76667a9 100644 --- a/src/doc/en/reference/combinat/symmetric_functions.rst +++ b/src/doc/en/reference/combinat/symmetric_functions.rst @@ -4,23 +4,23 @@ Symmetric Functions .. toctree:: :maxdepth: 2 - ../sage/combinat/sf/sfa - ../sage/combinat/sf/sf - ../sage/combinat/sf/classical - ../sage/combinat/sf/schur - ../sage/combinat/sf/monomial - ../sage/combinat/sf/multiplicative - ../sage/combinat/sf/elementary - ../sage/combinat/sf/homogeneous - ../sage/combinat/sf/powersum - ../sage/combinat/sf/dual - ../sage/combinat/sf/orthotriang - ../sage/combinat/sf/kfpoly - ../sage/combinat/sf/hall_littlewood - ../sage/combinat/sf/jack - ../sage/combinat/sf/new_kschur - ../sage/combinat/sf/k_dual - ../sage/combinat/sf/llt - ../sage/combinat/sf/macdonald - ../sage/combinat/sf/ns_macdonald - ../sage/combinat/sf/witt + sage/combinat/sf/sfa + sage/combinat/sf/sf + sage/combinat/sf/classical + sage/combinat/sf/schur + sage/combinat/sf/monomial + sage/combinat/sf/multiplicative + sage/combinat/sf/elementary + sage/combinat/sf/homogeneous + sage/combinat/sf/powersum + sage/combinat/sf/dual + sage/combinat/sf/orthotriang + sage/combinat/sf/kfpoly + sage/combinat/sf/hall_littlewood + sage/combinat/sf/jack + sage/combinat/sf/new_kschur + sage/combinat/sf/k_dual + sage/combinat/sf/llt + sage/combinat/sf/macdonald + sage/combinat/sf/ns_macdonald + sage/combinat/sf/witt diff --git a/src/doc/en/reference/combinat/tableaux.rst b/src/doc/en/reference/combinat/tableaux.rst index f33bd3db3ef..18568c7a91f 100644 --- a/src/doc/en/reference/combinat/tableaux.rst +++ b/src/doc/en/reference/combinat/tableaux.rst @@ -10,3 +10,4 @@ Tableaux and Tableaux-like Objects sage/combinat/ribbon_tableau sage/combinat/tableau_tuple sage/combinat/k_tableau + sage/combinat/rsk diff --git a/src/sage/combinat/__init__.py b/src/sage/combinat/__init__.py index 3f4a1cc701b..03e579c9ca1 100644 --- a/src/sage/combinat/__init__.py +++ b/src/sage/combinat/__init__.py @@ -1 +1,96 @@ +__doc__ = r""" +Combinatorics quickref +---------------------- + + - :mod:`sage.combinat.demo` + - sage.combinat.demo_short + - sage.combinat.combinat? (pretty outdated) + - sage.combinat.root_systems? + - sage.combinat.species? + +See also: + - :class:`EnumeratedSets`, :class:`FiniteEnumeratedSets` + +* Integer Sequences + +sloane_find(list), sloane. +s = sloane.find([1,3,19,211])[0] +s = sloane.i_am_lucky([1,3,19,211]) +s(5), s.references() + +* Combinatorial objects: + +P = Partitions(10); P.count(); P. +C = Combinations([1,3,7]); C.list() +Compositions(5, max_part = 3, ...).unrank(3) +Tableau + +* Constructions and Species + +for (p, c) in CartesianProduct(P, C): ... + +DisjointUnion(Family(lambda n: IntegerVectors(n, 3), NonNegativeIntegers)) + +* Words + +W=Words('abc') W('aabca') + +Franco: what about putting W('aabca').bar(), where bar would be some flashy feature? + +* Posets + +Posets: Poset([[1,2],[4],[3],[4],[]]) + +* Polytopes + +L =LatticePolytope(random_matrix(ZZ, 3,6, x=7)) +L.npoints() L.plot3d() + +* Root systems, Coxeter and Weyl groups + +See: sage.combinat.root_system? + +* Crystals + +CrystalOfTableaux(["A",3], shape = [3,2]) + +See sage.combinat.crystals? + +* Symmetric functions and combinatorial Hopf algebras + + Sym = SymmetricFunctions(QQ) + %from Sym.shortcuts() import * / %from Sym.shortcuts() import s, h, m + Sym.import_shortcuts() / Sym.import_shortcuts("s,h,m") + s[3] * h[2] ... + + NCSF + QSym + MultivariatePolynomials + + SymmetricGroupAlgebra + + HeckeAlgebra + +* Discrete groups, Permutation groups + +See sage.groups? + + S = SymmetricGroup(4) + M = MultivariatePolynomials('x0,x1,x2,x3') + M(...).action??? S. + +* Lattices + +* Graph theory and posets + +See Graph?, Digraph?, graphs? + +Poset({1: [2,3], 2: [4], 3: [4]}).some_snappy_feature() + +""" + +import demo +import demo_short +import demo_algebraic_combinatorics +import tutorial_enumerated_sets import tutorial diff --git a/src/sage/combinat/index.py b/src/sage/combinat/index.py new file mode 100644 index 00000000000..fde61cc02ee --- /dev/null +++ b/src/sage/combinat/index.py @@ -0,0 +1,179 @@ +""" +Combinatorics +============= + +Introductory material +--------------------- + + :mod:`sage.combinat` + :mod:`sage.combinat.tutorial` + +Enumerated sets +--------------- + +**Basic enumerated sets** + + :class:`subsets.Subsets` + :class:`subsets_pairwise.PairwiseCompatibleSubsets` + :class:`tuple.Tuple` + :class:`finite_class.FiniteClass` + :class:`combination.Combinations` + :class:`combination.Combinations` + :class:`cartesian_product.CartesianProduct` + +**Generic enumerated sets** + +.. toctree:: + :maxdepth: 1 + + :class:`backtrack.GenericBacktracker` + :class:`backtrack.TransitiveIdeal` + :class:`backtrack.TransitiveIdealGraded` + :func:`tools.transitive_ideal` + :class:`backtrack.SearchForest` + :mod:`tiling` + :mod:`dlx` + :mod:`matrices/dlxcpp` + :mod:`species` + :class:`integer_list.IntegerListsLex` + +**Compositions** + +.. toctree:: + :maxdepth: 1 + +**Counting** + +.. toctree:: + :maxdepth: 1 + + :mod:`sage/databases/oeis` + :mod:`sage/combinat/sloane_functions` + :mod:`sage/combinat/expnums` + :mod:`sage/combinat/q_analogues` + :mod:`sage/combinat/q_bernoulli` + :mod:`sage/combinat/binary_recurrence_sequences` + sage/combinat/combinat + +**Integer lists/matrices/vectors** + +.. toctree:: + :maxdepth: 1 + + :class:`compositions.Compositions` + :class:`composition_signed.SignedCompositions` + + sage/combinat/integer_vector + sage/combinat/integer_vector_weighted + +**Partitions** + +.. toctree:: + :maxdepth: 1 + + partitions + sage/combinat/set_partition_ordered + sage/combinat/set_partition + sage/combinat/vector_partition + tableaux + +**Permutations** + +.. toctree:: + :maxdepth: 1 + + sage/combinat/permutation + sage/combinat/affine_permutation + sage/combinat/derangements + sage/combinat/integer_vectors_mod_permgroup + sage/combinat/enumeration_mod_permgroup + +**Enumerated sets of matrices** + +.. toctree:: + :maxdepth: 1 + + sage/combinat/integer_matrices + sage/combinat/matrices/hadamard_matrix + sage/combinat/matrices/latin + sage/combinat/alternating_sign_matrix + sage/combinat/six_vertex_model + sage/combinat/similarity_class_type + +**Trees** + +.. toctree:: + :maxdepth: 1 + + sage/combinat/abstract_tree + sage/combinat/ordered_tree + sage/combinat/binary_tree + +**Enumerated sets related to graphs** + +.. toctree:: + :maxdepth: 1 + + sage/combinat/degree_sequences + sage/combinat/graph_path + sage/combinat/perfect_matching + +**Misc enumerated sets** + +.. toctree:: + :maxdepth: 1 + + designs + sage/combinat/non_decreasing_parking_function + sage/combinat/parking_functions + sage/combinat/restricted_growth + sage/combinat/sidon_sets + +Word theory +----------- + +.. toctree:: + :maxdepth: 1 + + words + sage/combinat/finite_state_machine + sage/combinat/subword + sage/combinat/necklace + sage/combinat/lyndon_word + sage/combinat/dyck_word + sage/combinat/debruijn_sequence + +Algebraic combinatorics +----------------------- + +.. toctree:: + :maxdepth: 1 + + cluster_algebras + algebra + root_systems + crystals + rigged_configurations + +Dynamical systems +----------------- + + sage/combinat/e_one_star + +Miscellaneous +------------- + +.. toctree:: + :maxdepth: 1 + + sage/combinat/gelfand_tsetlin_patterns + sage/combinat/knutson_tao_puzzles + + posets + developer + + sage/combinat/misc + sage/combinat/combinatorial_map + +.. include:: ../footer.txt +""" From a564118a655d3af6730c103ba18ef6f7fb0cb397 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Sun, 13 Apr 2014 21:43:59 +0200 Subject: [PATCH 011/698] Update MPIR to 2.7.0.alpha4 --- build/pkgs/mpir/checksums.ini | 6 +- build/pkgs/mpir/package-version.txt | 2 +- build/pkgs/mpir/patches/apple.patch | 40 - build/pkgs/mpir/patches/clang-config.patch | 219 - build/pkgs/mpir/patches/configure-cxx.patch | 330 -- build/pkgs/mpir/patches/configure.patch | 4271 ----------------- .../patches/core-prescott-configure.patch | 107 - build/pkgs/mpir/patches/gmp-h.in.patch | 15 - .../mpir/patches/mpz__t-scan-bugfix.patch | 11 - build/pkgs/mpir/patches/quote_asm.patch | 864 ---- build/pkgs/mpir/spkg-install | 8 +- 11 files changed, 9 insertions(+), 5864 deletions(-) delete mode 100644 build/pkgs/mpir/patches/apple.patch delete mode 100644 build/pkgs/mpir/patches/clang-config.patch delete mode 100644 build/pkgs/mpir/patches/configure-cxx.patch delete mode 100644 build/pkgs/mpir/patches/configure.patch delete mode 100644 build/pkgs/mpir/patches/core-prescott-configure.patch delete mode 100644 build/pkgs/mpir/patches/gmp-h.in.patch delete mode 100644 build/pkgs/mpir/patches/mpz__t-scan-bugfix.patch delete mode 100644 build/pkgs/mpir/patches/quote_asm.patch diff --git a/build/pkgs/mpir/checksums.ini b/build/pkgs/mpir/checksums.ini index 26e36e37b0f..07b4087050e 100644 --- a/build/pkgs/mpir/checksums.ini +++ b/build/pkgs/mpir/checksums.ini @@ -1,4 +1,4 @@ tarball=mpir-VERSION.tar.bz2 -sha1=a9fbfe30db672939abab06d16ce48087ee1b0d01 -md5=1567cd6e25370e5d86aab271f63bc209 -cksum=1562020278 +sha1=7d5a66f83acfc420dac41bda06928d2564bd0c79 +md5=820a690643e2708f244eae9aac668d8a +cksum=2611197091 diff --git a/build/pkgs/mpir/package-version.txt b/build/pkgs/mpir/package-version.txt index f492b63115f..3e703e0948f 100644 --- a/build/pkgs/mpir/package-version.txt +++ b/build/pkgs/mpir/package-version.txt @@ -1 +1 @@ -2.6.0.p4 +2.7.0.alpha4 diff --git a/build/pkgs/mpir/patches/apple.patch b/build/pkgs/mpir/patches/apple.patch deleted file mode 100644 index bef9e44e428..00000000000 --- a/build/pkgs/mpir/patches/apple.patch +++ /dev/null @@ -1,40 +0,0 @@ -diff -dru src.orig/configure src/configure ---- src.orig/configure 2012-12-04 10:54:58.329999299 +0100 -+++ src/configure 2012-12-04 11:08:46.105968510 +0100 -@@ -4689,12 +4689,10 @@ - - # 32bit apple darwin doesn't like our PIC format asm code - case $host in -- core2-apple-darwin* | penryn-apple-darwin*) path="x86/applenopic/core2 x86/applenopic" ;; -- prescott-apple-darwin* | pentium4-apple-darwin*) path="x86/applenopic" ;; -- pentium3-apple-darwin* | pentium2-apple-darwin*) path="x86/applenopic" ;; -- i686-apple-darwin* | pentiumpro-apple-darwin*) path="x86/applenopic" ;; -- core-apple-darwin*) path="x86/applenopic" ;; -- *) ;; -+ i[34567]86-apple-darwin* | pentium*-apple-darwin* | prescott-apple-darwin* | core-apple-darwin* ) path="x86/applenopic" ;; -+ # assume Core2 or later -+ *-apple-darwin* ) path="x86/applenopic/core2 x86/applenopic" ;; -+ *) ;; - esac - - # If the user asked for a fat build, override the path set above -diff -dru src.orig/configure.in src/configure.in ---- src.orig/configure.in 2012-12-04 10:54:56.681999359 +0100 -+++ src/configure.in 2012-12-04 11:09:04.321968955 +0100 -@@ -1122,12 +1122,10 @@ - - # 32bit apple darwin doesn't like our PIC format asm code - case $host in -- core2-apple-darwin* | penryn-apple-darwin*) path="x86/applenopic/core2 x86/applenopic" ;; -- prescott-apple-darwin* | pentium4-apple-darwin*) path="x86/applenopic" ;; -- pentium3-apple-darwin* | pentium2-apple-darwin*) path="x86/applenopic" ;; -- i686-apple-darwin* | pentiumpro-apple-darwin*) path="x86/applenopic" ;; -- core-apple-darwin*) path="x86/applenopic" ;; -- *) ;; -+ i[34567]86-apple-darwin* | pentium*-apple-darwin* | prescott-apple-darwin* | core-apple-darwin* ) path="x86/applenopic" ;; -+ # assume Core2 or later -+ *-apple-darwin* ) path="x86/applenopic/core2 x86/applenopic" ;; -+ *) ;; - esac - - # If the user asked for a fat build, override the path set above diff --git a/build/pkgs/mpir/patches/clang-config.patch b/build/pkgs/mpir/patches/clang-config.patch deleted file mode 100644 index 77c59cbb3f1..00000000000 --- a/build/pkgs/mpir/patches/clang-config.patch +++ /dev/null @@ -1,219 +0,0 @@ -diff -ru src/acinclude.m4 b/acinclude.m4 ---- src/acinclude.m4 2012-10-23 16:56:46.000000000 +0200 -+++ b/acinclude.m4 2013-10-02 09:22:41.958758575 +0200 -@@ -480,29 +480,6 @@ - # first see a simple "main()" works, then go on to other checks - GMP_PROG_CC_WORKS_PART([$1], []) - --GMP_PROG_CC_WORKS_PART_MAIN([$1], [gcc-4.3.2 on 64bit is bad , try -O1 or -fno-strict-aliasing for the flags], --[/* The following aborts with gcc-4.3.2 on a 64bit system which is an unusable compiler */ --#if defined(__GNUC__) && !defined(__INTEL_COMPILER) --int __attribute__((noinline)) --foo(int i) --{ -- int *p = __builtin_malloc (4 * sizeof(int)); -- *p = 0; -- p[i] = 1; -- return *p; --} --extern void abort (void); --int main() --{ -- if (foo(0) != 1) -- abort (); -- return 0; --} --#else --int main(){return 0;} --#endif --]) -- - GMP_PROG_CC_WORKS_PART([$1], [function pointer return], - [/* The following provokes an internal error from gcc 2.95.2 -mpowerpc64 - (without -maix64), hence detecting an unusable compiler */ -@@ -570,6 +547,10 @@ - - #ifdef __GNUC__ - typedef unsigned long long t1;typedef t1*t2; -+/* Clang fails to link this on XCode 5 unless static is added */ -+#ifdef __clang__ -+static -+#endif - __inline__ t1 e(t2 rp,t2 up,int n,t1 v0) - {t1 c,x,r;int i;if(v0){c=1;for(i=1;iconftest.c <&5 -- gmp_compile="$cc $cflags $cppflags conftest.c >&5" -- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 -- (eval $gmp_compile) 2>&5 -- ac_status=$? -- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; }; then -- cc_works_part=yes -- if test "$cross_compiling" = no; then -- if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest' -- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 -- (eval $ac_try) 2>&5 -- ac_status=$? -- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; }; }; then :; -- else -- cc_works_part=norun -- fi -- fi -- else -- cc_works_part=no -- fi -- if test "$cc_works_part" != yes; then -- echo "failed program was:" >&5 -- cat conftest.c >&5 -- fi -- rm -f conftest* a.out b.out a.exe a_out.exe -- case $cc_works_part in -- yes) -- -- ;; -- no) -- gmp_prog_cc_works="no, gcc-4.3.2 on 64bit is bad , try -O1 or -fno-strict-aliasing for the flags" -- ;; -- norun) -- gmp_prog_cc_works="no, gcc-4.3.2 on 64bit is bad , try -O1 or -fno-strict-aliasing for the flags, program does not run" -- ;; -- esac --fi -- -- -- --if test "$gmp_prog_cc_works" = yes; then -- # remove anything that might look like compiler output to our "||" expression -- rm -f conftest* a.out b.out a.exe a_out.exe -- cat >conftest.c <conftest.c <&5 -- gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" -- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 -- (eval $gmp_compile) 2>&5 -- ac_status=$? -- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; }; then -- cc_works_part=yes -- if test "$cross_compiling" = no; then -- if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest' -- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 -- (eval $ac_try) 2>&5 -- ac_status=$? -- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; }; }; then :; -- else -- cc_works_part=norun -- fi -- fi -- else -- cc_works_part=no -- fi -- if test "$cc_works_part" != yes; then -- echo "failed program was:" >&5 -- cat conftest.c >&5 -- fi -- rm -f conftest* a.out b.out a.exe a_out.exe -- case $cc_works_part in -- yes) -- -- ;; -- no) -- gmp_prog_cc_works="no, gcc-4.3.2 on 64bit is bad , try -O1 or -fno-strict-aliasing for the flags" -- ;; -- norun) -- gmp_prog_cc_works="no, gcc-4.3.2 on 64bit is bad , try -O1 or -fno-strict-aliasing for the flags, program does not run" -- ;; -- esac --fi -- -- -- --if test "$gmp_prog_cc_works" = yes; then -- # remove anything that might look like compiler output to our "||" expression -- rm -f conftest* a.out b.out a.exe a_out.exe -- cat >conftest.c <&AC_FD_CC - cxxflags_ac_prog_cxx=$CXXFLAGS -@@ -1738,15 +1738,6 @@ - - AM_CONDITIONAL(WANT_CXX, test $want_cxx = yes) - --# FIXME: We're not interested in CXXCPP for ourselves, but if we don't do it --# here then AC_PROG_LIBTOOL will AC_REQUIRE it (via _LT_AC_TAGCONFIG) and --# hence execute it unconditionally, and that will fail if there's no C++ --# compiler (and no generic /lib/cpp). --# --if test $want_cxx = yes; then -- AC_PROG_CXXCPP --fi -- - if test -z "$MPN_PATH"; then - path="$add_path $path" - fi -diff -druN src.orig/configure src/configure ---- src.orig/configure 2012-11-08 23:13:27.000000000 +0100 -+++ src/configure 2013-11-06 20:55:30.322220739 +0100 -@@ -658,6 +658,7 @@ - ENABLE_SHARED_TRUE - ENABLE_STATIC_FALSE - ENABLE_STATIC_TRUE -+CXXCPP - OTOOL64 - OTOOL - LIPO -@@ -679,7 +680,6 @@ - ac_ct_DUMPBIN - DUMPBIN - AR --CXXCPP - WANT_CXX_FALSE - WANT_CXX_TRUE - ac_ct_CXX -@@ -1873,43 +1873,6 @@ - - } # ac_fn_cxx_try_compile - --# ac_fn_cxx_try_cpp LINENO --# ------------------------ --# Try to preprocess conftest.$ac_ext, and return whether this succeeded. --ac_fn_cxx_try_cpp () --{ -- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack -- if { { ac_try="$ac_cpp conftest.$ac_ext" --case "(($ac_try" in -- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -- *) ac_try_echo=$ac_try;; --esac --eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" --$as_echo "$ac_try_echo"; } >&5 -- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err -- ac_status=$? -- if test -s conftest.err; then -- grep -v '^ *+' conftest.err >conftest.er1 -- cat conftest.er1 >&5 -- mv -f conftest.er1 conftest.err -- fi -- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; } > conftest.i && { -- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || -- test ! -s conftest.err -- }; then : -- ac_retval=0 --else -- $as_echo "$as_me: failed program was:" >&5 --sed 's/^/| /' conftest.$ac_ext >&5 -- -- ac_retval=1 --fi -- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno -- as_fn_set_status $ac_retval -- --} # ac_fn_cxx_try_cpp -- - # ac_fn_c_try_link LINENO - # ----------------------- - # Try to link conftest.$ac_ext, and return whether this succeeded. -@@ -2023,6 +1986,43 @@ - - } # ac_fn_c_check_func - -+# ac_fn_cxx_try_cpp LINENO -+# ------------------------ -+# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -+ac_fn_cxx_try_cpp () -+{ -+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack -+ if { { ac_try="$ac_cpp conftest.$ac_ext" -+case "(($ac_try" in -+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -+ *) ac_try_echo=$ac_try;; -+esac -+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -+$as_echo "$ac_try_echo"; } >&5 -+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err -+ ac_status=$? -+ if test -s conftest.err; then -+ grep -v '^ *+' conftest.err >conftest.er1 -+ cat conftest.er1 >&5 -+ mv -f conftest.er1 conftest.err -+ fi -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; } > conftest.i && { -+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || -+ test ! -s conftest.err -+ }; then : -+ ac_retval=0 -+else -+ $as_echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_retval=1 -+fi -+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno -+ as_fn_set_status $ac_retval -+ -+} # ac_fn_cxx_try_cpp -+ - # ac_fn_cxx_try_link LINENO - # ------------------------- - # Try to link conftest.$ac_ext, and return whether this succeeded. -@@ -9913,10 +9913,10 @@ - - - # The C++ compiler, if desired. --want_cxx=no --if test $enable_cxx != no; then -- test_CXXFLAGS=${CXXFLAGS+set} -- ac_ext=cpp -+ -+# The following test is quick and harmless. -+# It defaults to 'g++' if no compiler is found. -+ac_ext=cpp - ac_cpp='$CXXCPP $CPPFLAGS' - ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' - ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -@@ -10174,6 +10174,11 @@ - ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -+# Now actually check that the C++ compiler works if it is needed. -+want_cxx=no -+if test $enable_cxx != no; then -+ test_CXXFLAGS=${CXXFLAGS+set} -+ - echo "CXXFLAGS chosen by autoconf: $CXXFLAGS" >&5 - cxxflags_ac_prog_cxx=$CXXFLAGS - cxxflags_list=ac_prog_cxx -@@ -10358,147 +10363,6 @@ - fi - - --# FIXME: We're not interested in CXXCPP for ourselves, but if we don't do it --# here then AC_PROG_LIBTOOL will AC_REQUIRE it (via _LT_AC_TAGCONFIG) and --# hence execute it unconditionally, and that will fail if there's no C++ --# compiler (and no generic /lib/cpp). --# --if test $want_cxx = yes; then -- ac_ext=cpp --ac_cpp='$CXXCPP $CPPFLAGS' --ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' --ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' --ac_compiler_gnu=$ac_cv_cxx_compiler_gnu --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 --$as_echo_n "checking how to run the C++ preprocessor... " >&6; } --if test -z "$CXXCPP"; then -- if ${ac_cv_prog_CXXCPP+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- # Double quotes because CXXCPP needs to be expanded -- for CXXCPP in "$CXX -E" "/lib/cpp" -- do -- ac_preproc_ok=false --for ac_cxx_preproc_warn_flag in '' yes --do -- # Use a header file that comes with gcc, so configuring glibc -- # with a fresh cross-compiler works. -- # Prefer to if __STDC__ is defined, since -- # exists even on freestanding compilers. -- # On the NeXT, cc -E runs the code through the compiler's parser, -- # not just through cpp. "Syntax error" is here to catch this case. -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ --#ifdef __STDC__ --# include --#else --# include --#endif -- Syntax error --_ACEOF --if ac_fn_cxx_try_cpp "$LINENO"; then : -- --else -- # Broken: fails on valid input. --continue --fi --rm -f conftest.err conftest.i conftest.$ac_ext -- -- # OK, works on sane cases. Now check whether nonexistent headers -- # can be detected and how. -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ --#include --_ACEOF --if ac_fn_cxx_try_cpp "$LINENO"; then : -- # Broken: success on invalid input. --continue --else -- # Passes both tests. --ac_preproc_ok=: --break --fi --rm -f conftest.err conftest.i conftest.$ac_ext -- --done --# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. --rm -f conftest.i conftest.err conftest.$ac_ext --if $ac_preproc_ok; then : -- break --fi -- -- done -- ac_cv_prog_CXXCPP=$CXXCPP -- --fi -- CXXCPP=$ac_cv_prog_CXXCPP --else -- ac_cv_prog_CXXCPP=$CXXCPP --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 --$as_echo "$CXXCPP" >&6; } --ac_preproc_ok=false --for ac_cxx_preproc_warn_flag in '' yes --do -- # Use a header file that comes with gcc, so configuring glibc -- # with a fresh cross-compiler works. -- # Prefer to if __STDC__ is defined, since -- # exists even on freestanding compilers. -- # On the NeXT, cc -E runs the code through the compiler's parser, -- # not just through cpp. "Syntax error" is here to catch this case. -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ --#ifdef __STDC__ --# include --#else --# include --#endif -- Syntax error --_ACEOF --if ac_fn_cxx_try_cpp "$LINENO"; then : -- --else -- # Broken: fails on valid input. --continue --fi --rm -f conftest.err conftest.i conftest.$ac_ext -- -- # OK, works on sane cases. Now check whether nonexistent headers -- # can be detected and how. -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ --#include --_ACEOF --if ac_fn_cxx_try_cpp "$LINENO"; then : -- # Broken: success on invalid input. --continue --else -- # Passes both tests. --ac_preproc_ok=: --break --fi --rm -f conftest.err conftest.i conftest.$ac_ext -- --done --# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. --rm -f conftest.i conftest.err conftest.$ac_ext --if $ac_preproc_ok; then : -- --else -- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 --$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} --as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check --See \`config.log' for more details" "$LINENO" 5; } --fi -- --ac_ext=c --ac_cpp='$CPP $CPPFLAGS' --ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' --ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' --ac_compiler_gnu=$ac_cv_c_compiler_gnu -- --fi -- - if test -z "$MPN_PATH"; then - path="$add_path $path" - fi diff --git a/build/pkgs/mpir/patches/configure.patch b/build/pkgs/mpir/patches/configure.patch deleted file mode 100644 index 17810e74d79..00000000000 --- a/build/pkgs/mpir/patches/configure.patch +++ /dev/null @@ -1,4271 +0,0 @@ -diff -dru src/acinclude.m4 b/acinclude.m4 ---- src/acinclude.m4 2011-07-27 00:59:54.000000000 -0700 -+++ b/acinclude.m4 2012-06-19 12:53:56.000000000 -0700 -@@ -519,31 +519,45 @@ - int cmov () { return (n >= 0 ? n : 0); } - ]) - --GMP_PROG_CC_WORKS_PART([$1], [double -> ulong conversion], -+GMP_PROG_CC_WORKS_PART_MAIN([$1], [double -> ulong conversion], - [/* The following provokes a linker invocation problem with gcc 3.0.3 - on AIX 4.3 under "-maix64 -mpowerpc64 -mcpu=630". The -mcpu=630 - option causes gcc to incorrectly select the 32-bit libgcc.a, not - the 64-bit one, and consequently it misses out on the __fixunsdfdi -- helper (double -> uint64 conversion). */ --double d; --unsigned long gcc303 () { return (unsigned long) d; } -+ helper (double -> uint64 conversion). -+ This also provokers errors on x86 when AVX instructions are -+ generated but not understood by the assembler or processor.*/ -+volatile double d; -+volatile unsigned long u; -+int main() { d = 0.1; u = (unsigned long)d; return (int)u; } - ]) - --GMP_PROG_CC_WORKS_PART([$1], [double negation], -+GMP_PROG_CC_WORKS_PART_MAIN([$1], [double negation], - [/* The following provokes an error from hppa gcc 2.95 under -mpa-risc-2-0 if - the assembler doesn't know hppa 2.0 instructions. fneg is a 2.0 - instruction, and a negation like this comes out using it. */ --double fneg_data; --unsigned long fneg () { return -fneg_data; } -+volatile double d; -+volatile double d2; -+int main() { d = -0.1; d2 = -d; return (int)d2; } - ]) - --GMP_PROG_CC_WORKS_PART([$1], [double -> float conversion], -+GMP_PROG_CC_WORKS_PART_MAIN([$1], [double -> float conversion], - [/* The following makes gcc 3.3 -march=pentium4 generate an SSE2 xmm insn - (cvtsd2ss) which will provoke an error if the assembler doesn't recognise - those instructions. Not sure how much of the gmp code will come out - wanting sse2, but it's easiest to reject an option we know is bad. */ --double ftod_data; --float ftod () { return (float) ftod_data; } -+volatile double d; -+volatile float f; -+int main() { d = 0.1; f = (float)d; return (int)f; } -+]) -+ -+GMP_PROG_CC_WORKS_PART_MAIN([$1], [unsigned long/double division], -+[/* The following generates a vmovd instruction on Sandy Bridge. -+ Check that the assembler knows this instruction. */ -+volatile unsigned long a; -+volatile double b; -+int main() -+{ a = 1; b = 3; return (int)(a/b); } - ]) - - # __builtin_alloca is not available everywhere, check it exists before -diff -dru src/configure.in b/configure.in ---- src/configure.in 2012-03-08 23:21:29.000000000 -0800 -+++ b/configure.in 2012-06-19 12:53:56.000000000 -0700 -@@ -1918,16 +1918,6 @@ - fi - fi - --# The dead hand of AC_REQUIRE makes AC_PROG_LIBTOOL expand and execute --# AC_PROG_F77, even when F77 is not in the selected with_tags. This is --# probably harmless, but it's unsightly and bloats our configure, so pretend --# AC_PROG_F77 has been expanded already. --# --# FIXME: Rumour has it libtool will one day provide a way for a configure.in --# to say what it wants from among supported languages etc. --# --AC_PROVIDE([AC_PROG_F77]) -- - AC_PROG_LIBTOOL - - # Generate an error here if attempting to build both shared and static when -diff -dru src/yasm/Makefile.in b/yasm/Makefile.in ---- src/yasm/Makefile.in 2012-03-10 23:16:35.000000000 -0800 -+++ b/yasm/Makefile.in 2012-06-19 12:53:56.000000000 -0700 -@@ -3747,7 +3747,8 @@ - check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) - $(MAKE) $(AM_MAKEFLAGS) check-TESTS --check: -+check: $(BUILT_SOURCES) -+ $(MAKE) $(AM_MAKEFLAGS) check-recursive - all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(MANS) $(HEADERS) config.h \ - all-local - installdirs: installdirs-recursive -@@ -3755,7 +3756,8 @@ - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man7dir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(modincludedir)" "$(DESTDIR)$(includedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done --install: -+install: $(BUILT_SOURCES) -+ $(MAKE) $(AM_MAKEFLAGS) install-recursive - install-exec: install-exec-recursive - install-data: install-data-recursive - uninstall: uninstall-recursive -diff -dru src/configure b/configure ---- src/configure 2012-06-19 12:53:56.000000000 -0700 -+++ b/configure 2012-03-10 01:07:26.000000000 -0800 -@@ -2069,52 +2069,6 @@ - - } # ac_fn_cxx_try_link - --# ac_fn_f77_try_link LINENO --# ------------------------- --# Try to link conftest.$ac_ext, and return whether this succeeded. --ac_fn_f77_try_link () --{ -- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack -- rm -f conftest.$ac_objext conftest$ac_exeext -- if { { ac_try="$ac_link" --case "(($ac_try" in -- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; -- *) ac_try_echo=$ac_try;; --esac --eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" --$as_echo "$ac_try_echo"; } >&5 -- (eval "$ac_link") 2>conftest.err -- ac_status=$? -- if test -s conftest.err; then -- grep -v '^ *+' conftest.err >conftest.er1 -- cat conftest.er1 >&5 -- mv -f conftest.er1 conftest.err -- fi -- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; } && { -- test -z "$ac_f77_werror_flag" || -- test ! -s conftest.err -- } && test -s conftest$ac_exeext && { -- test "$cross_compiling" = yes || -- $as_test_x conftest$ac_exeext -- }; then : -- ac_retval=0 --else -- $as_echo "$as_me: failed program was:" >&5 --sed 's/^/| /' conftest.$ac_ext >&5 -- -- ac_retval=1 --fi -- # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information -- # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would -- # interfere with the next link command; also delete a directory that is -- # left behind by Apple's compiler. We do this before executing the actions. -- rm -rf conftest.dSYM conftest_ipa8_conftest.oo -- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno -- as_fn_set_status $ac_retval -- --} # ac_fn_f77_try_link -- - # ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES - # --------------------------------------------- - # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR -@@ -5311,11 +5265,13 @@ - on AIX 4.3 under "-maix64 -mpowerpc64 -mcpu=630". The -mcpu=630 - option causes gcc to incorrectly select the 32-bit libgcc.a, not - the 64-bit one, and consequently it misses out on the __fixunsdfdi -- helper (double -> uint64 conversion). */ --double d; --unsigned long gcc303 () { return (unsigned long) d; } -+ helper (double -> uint64 conversion). -+ This also provokers errors on x86 when AVX instructions are -+ generated but not understood by the assembler or processor.*/ -+volatile double d; -+volatile unsigned long u; -+int main() { d = 0.1; u = (unsigned long)d; return (int)u; } - --int main () { return 0; } - EOF - echo "Test compile: double -> ulong conversion" >&5 - gmp_compile="$cc $cflags $cppflags conftest.c >&5" -@@ -5359,7 +5315,6 @@ - - - -- - if test "$gmp_prog_cc_works" = yes; then - # remove anything that might look like compiler output to our "||" expression - rm -f conftest* a.out b.out a.exe a_out.exe -@@ -5367,10 +5322,10 @@ - /* The following provokes an error from hppa gcc 2.95 under -mpa-risc-2-0 if - the assembler doesn't know hppa 2.0 instructions. fneg is a 2.0 - instruction, and a negation like this comes out using it. */ --double fneg_data; --unsigned long fneg () { return -fneg_data; } -+volatile double d; -+volatile double d2; -+int main() { d = -0.1; d2 = -d; return (int)d2; } - --int main () { return 0; } - EOF - echo "Test compile: double negation" >&5 - gmp_compile="$cc $cflags $cppflags conftest.c >&5" -@@ -5414,7 +5369,6 @@ - - - -- - if test "$gmp_prog_cc_works" = yes; then - # remove anything that might look like compiler output to our "||" expression - rm -f conftest* a.out b.out a.exe a_out.exe -@@ -5423,10 +5377,10 @@ - (cvtsd2ss) which will provoke an error if the assembler doesn't recognise - those instructions. Not sure how much of the gmp code will come out - wanting sse2, but it's easiest to reject an option we know is bad. */ --double ftod_data; --float ftod () { return (float) ftod_data; } -+volatile double d; -+volatile float f; -+int main() { d = 0.1; f = (float)d; return (int)f; } - --int main () { return 0; } - EOF - echo "Test compile: double -> float conversion" >&5 - gmp_compile="$cc $cflags $cppflags conftest.c >&5" -@@ -5470,6 +5424,59 @@ - - - -+if test "$gmp_prog_cc_works" = yes; then -+ # remove anything that might look like compiler output to our "||" expression -+ rm -f conftest* a.out b.out a.exe a_out.exe -+ cat >conftest.c <&5 -+ gmp_compile="$cc $cflags $cppflags conftest.c >&5" -+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 -+ (eval $gmp_compile) 2>&5 -+ ac_status=$? -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; }; then -+ cc_works_part=yes -+ if test "$cross_compiling" = no; then -+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest' -+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; }; }; then :; -+ else -+ cc_works_part=norun -+ fi -+ fi -+ else -+ cc_works_part=no -+ fi -+ if test "$cc_works_part" != yes; then -+ echo "failed program was:" >&5 -+ cat conftest.c >&5 -+ fi -+ rm -f conftest* a.out b.out a.exe a_out.exe -+ case $cc_works_part in -+ yes) -+ -+ ;; -+ no) -+ gmp_prog_cc_works="no, unsigned long/double division" -+ ;; -+ norun) -+ gmp_prog_cc_works="no, unsigned long/double division, program does not run" -+ ;; -+ esac -+fi -+ -+ - - # __builtin_alloca is not available everywhere, check it exists before - # seeing that it works -@@ -6572,11 +6579,13 @@ - on AIX 4.3 under "-maix64 -mpowerpc64 -mcpu=630". The -mcpu=630 - option causes gcc to incorrectly select the 32-bit libgcc.a, not - the 64-bit one, and consequently it misses out on the __fixunsdfdi -- helper (double -> uint64 conversion). */ --double d; --unsigned long gcc303 () { return (unsigned long) d; } -+ helper (double -> uint64 conversion). -+ This also provokers errors on x86 when AVX instructions are -+ generated but not understood by the assembler or processor.*/ -+volatile double d; -+volatile unsigned long u; -+int main() { d = 0.1; u = (unsigned long)d; return (int)u; } - --int main () { return 0; } - EOF - echo "Test compile: double -> ulong conversion" >&5 - gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" -@@ -6620,7 +6629,6 @@ - - - -- - if test "$gmp_prog_cc_works" = yes; then - # remove anything that might look like compiler output to our "||" expression - rm -f conftest* a.out b.out a.exe a_out.exe -@@ -6628,10 +6636,10 @@ - /* The following provokes an error from hppa gcc 2.95 under -mpa-risc-2-0 if - the assembler doesn't know hppa 2.0 instructions. fneg is a 2.0 - instruction, and a negation like this comes out using it. */ --double fneg_data; --unsigned long fneg () { return -fneg_data; } -+volatile double d; -+volatile double d2; -+int main() { d = -0.1; d2 = -d; return (int)d2; } - --int main () { return 0; } - EOF - echo "Test compile: double negation" >&5 - gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" -@@ -6675,7 +6683,6 @@ - - - -- - if test "$gmp_prog_cc_works" = yes; then - # remove anything that might look like compiler output to our "||" expression - rm -f conftest* a.out b.out a.exe a_out.exe -@@ -6684,10 +6691,10 @@ - (cvtsd2ss) which will provoke an error if the assembler doesn't recognise - those instructions. Not sure how much of the gmp code will come out - wanting sse2, but it's easiest to reject an option we know is bad. */ --double ftod_data; --float ftod () { return (float) ftod_data; } -+volatile double d; -+volatile float f; -+int main() { d = 0.1; f = (float)d; return (int)f; } - --int main () { return 0; } - EOF - echo "Test compile: double -> float conversion" >&5 - gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" -@@ -6731,6 +6738,59 @@ - - - -+if test "$gmp_prog_cc_works" = yes; then -+ # remove anything that might look like compiler output to our "||" expression -+ rm -f conftest* a.out b.out a.exe a_out.exe -+ cat >conftest.c <&5 -+ gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5" -+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5 -+ (eval $gmp_compile) 2>&5 -+ ac_status=$? -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; }; then -+ cc_works_part=yes -+ if test "$cross_compiling" = no; then -+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest' -+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; }; }; then :; -+ else -+ cc_works_part=norun -+ fi -+ fi -+ else -+ cc_works_part=no -+ fi -+ if test "$cc_works_part" != yes; then -+ echo "failed program was:" >&5 -+ cat conftest.c >&5 -+ fi -+ rm -f conftest* a.out b.out a.exe a_out.exe -+ case $cc_works_part in -+ yes) -+ -+ ;; -+ no) -+ gmp_prog_cc_works="no, unsigned long/double division" -+ ;; -+ norun) -+ gmp_prog_cc_works="no, unsigned long/double division, program does not run" -+ ;; -+ esac -+fi -+ -+ - - # __builtin_alloca is not available everywhere, check it exists before - # seeing that it works -@@ -11689,16 +11749,6 @@ - fi - fi - --# The dead hand of AC_REQUIRE makes AC_PROG_LIBTOOL expand and execute --# AC_PROG_F77, even when F77 is not in the selected with_tags. This is --# probably harmless, but it's unsightly and bloats our configure, so pretend --# AC_PROG_F77 has been expanded already. --# --# FIXME: Rumour has it libtool will one day provide a way for a configure.in --# to say what it wants from among supported languages etc. --# -- -- - case `pwd` in - *\ * | *\ *) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 -@@ -14582,7 +14632,6 @@ - - - -- - # Set options - - -@@ -21736,2721 +21785,6 @@ - - - -- ac_ext=f --ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' --ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' --ac_compiler_gnu=$ac_cv_f77_compiler_gnu -- --if test -z "$F77" || test "X$F77" = "Xno"; then -- _lt_disable_F77=yes --fi -- --archive_cmds_need_lc_F77=no --allow_undefined_flag_F77= --always_export_symbols_F77=no --archive_expsym_cmds_F77= --export_dynamic_flag_spec_F77= --hardcode_direct_F77=no --hardcode_direct_absolute_F77=no --hardcode_libdir_flag_spec_F77= --hardcode_libdir_flag_spec_ld_F77= --hardcode_libdir_separator_F77= --hardcode_minus_L_F77=no --hardcode_automatic_F77=no --inherit_rpath_F77=no --module_cmds_F77= --module_expsym_cmds_F77= --link_all_deplibs_F77=unknown --old_archive_cmds_F77=$old_archive_cmds --reload_flag_F77=$reload_flag --reload_cmds_F77=$reload_cmds --no_undefined_flag_F77= --whole_archive_flag_spec_F77= --enable_shared_with_static_runtimes_F77=no -- --# Source file extension for f77 test sources. --ac_ext=f -- --# Object file extension for compiled f77 test sources. --objext=o --objext_F77=$objext -- --# No sense in running all these tests if we already determined that --# the F77 compiler isn't working. Some variables (like enable_shared) --# are currently assumed to apply to all compilers on this platform, --# and will be corrupted by setting them based on a non-working compiler. --if test "$_lt_disable_F77" != yes; then -- # Code to be used in simple compile tests -- lt_simple_compile_test_code="\ -- subroutine t -- return -- end --" -- -- # Code to be used in simple link tests -- lt_simple_link_test_code="\ -- program t -- end --" -- -- # ltmain only uses $CC for tagged configurations so make sure $CC is set. -- -- -- -- -- -- --# If no C compiler was specified, use CC. --LTCC=${LTCC-"$CC"} -- --# If no C compiler flags were specified, use CFLAGS. --LTCFLAGS=${LTCFLAGS-"$CFLAGS"} -- --# Allow CC to be a program name with arguments. --compiler=$CC -- -- -- # save warnings/boilerplate of simple test code -- ac_outfile=conftest.$ac_objext --echo "$lt_simple_compile_test_code" >conftest.$ac_ext --eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err --_lt_compiler_boilerplate=`cat conftest.err` --$RM conftest* -- -- ac_outfile=conftest.$ac_objext --echo "$lt_simple_link_test_code" >conftest.$ac_ext --eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err --_lt_linker_boilerplate=`cat conftest.err` --$RM -r conftest* -- -- -- # Allow CC to be a program name with arguments. -- lt_save_CC="$CC" -- lt_save_GCC=$GCC -- lt_save_CFLAGS=$CFLAGS -- CC=${F77-"f77"} -- CFLAGS=$FFLAGS -- compiler=$CC -- compiler_F77=$CC -- for cc_temp in $compiler""; do -- case $cc_temp in -- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; -- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; -- \-*) ;; -- *) break;; -- esac --done --cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` -- -- GCC=$G77 -- if test -n "$compiler"; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 --$as_echo_n "checking if libtool supports shared libraries... " >&6; } -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 --$as_echo "$can_build_shared" >&6; } -- -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 --$as_echo_n "checking whether to build shared libraries... " >&6; } -- test "$can_build_shared" = "no" && enable_shared=no -- -- # On AIX, shared libraries and static libraries use the same namespace, and -- # are all built from PIC. -- case $host_os in -- aix3*) -- test "$enable_shared" = yes && enable_static=no -- if test -n "$RANLIB"; then -- archive_cmds="$archive_cmds~\$RANLIB \$lib" -- postinstall_cmds='$RANLIB $lib' -- fi -- ;; -- aix[4-9]*) -- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then -- test "$enable_shared" = yes && enable_static=no -- fi -- ;; -- esac -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 --$as_echo "$enable_shared" >&6; } -- -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 --$as_echo_n "checking whether to build static libraries... " >&6; } -- # Make sure either enable_shared or enable_static is yes. -- test "$enable_shared" = yes || enable_static=yes -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 --$as_echo "$enable_static" >&6; } -- -- GCC_F77="$G77" -- LD_F77="$LD" -- -- ## CAVEAT EMPTOR: -- ## There is no encapsulation within the following macros, do not change -- ## the running order or otherwise move them around unless you know exactly -- ## what you are doing... -- lt_prog_compiler_wl_F77= --lt_prog_compiler_pic_F77= --lt_prog_compiler_static_F77= -- -- -- if test "$GCC" = yes; then -- lt_prog_compiler_wl_F77='-Wl,' -- lt_prog_compiler_static_F77='-static' -- -- case $host_os in -- aix*) -- # All AIX code is PIC. -- if test "$host_cpu" = ia64; then -- # AIX 5 now supports IA64 processor -- lt_prog_compiler_static_F77='-Bstatic' -- fi -- ;; -- -- amigaos*) -- case $host_cpu in -- powerpc) -- # see comment about AmigaOS4 .so support -- lt_prog_compiler_pic_F77='-fPIC' -- ;; -- m68k) -- # FIXME: we need at least 68020 code to build shared libraries, but -- # adding the `-m68020' flag to GCC prevents building anything better, -- # like `-m68040'. -- lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4' -- ;; -- esac -- ;; -- -- beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) -- # PIC is the default for these OSes. -- ;; -- -- mingw* | cygwin* | pw32* | os2* | cegcc*) -- # This hack is so that the source file can tell whether it is being -- # built for inclusion in a dll (and should export symbols for example). -- # Although the cygwin gcc ignores -fPIC, still need this for old-style -- # (--disable-auto-import) libraries -- lt_prog_compiler_pic_F77='-DDLL_EXPORT' -- ;; -- -- darwin* | rhapsody*) -- # PIC is the default on this platform -- # Common symbols not allowed in MH_DYLIB files -- lt_prog_compiler_pic_F77='-fno-common' -- ;; -- -- haiku*) -- # PIC is the default for Haiku. -- # The "-static" flag exists, but is broken. -- lt_prog_compiler_static_F77= -- ;; -- -- hpux*) -- # PIC is the default for 64-bit PA HP-UX, but not for 32-bit -- # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag -- # sets the default TLS model and affects inlining. -- case $host_cpu in -- hppa*64*) -- # +Z the default -- ;; -- *) -- lt_prog_compiler_pic_F77='-fPIC' -- ;; -- esac -- ;; -- -- interix[3-9]*) -- # Interix 3.x gcc -fpic/-fPIC options generate broken code. -- # Instead, we relocate shared libraries at runtime. -- ;; -- -- msdosdjgpp*) -- # Just because we use GCC doesn't mean we suddenly get shared libraries -- # on systems that don't support them. -- lt_prog_compiler_can_build_shared_F77=no -- enable_shared=no -- ;; -- -- *nto* | *qnx*) -- # QNX uses GNU C++, but need to define -shared option too, otherwise -- # it will coredump. -- lt_prog_compiler_pic_F77='-fPIC -shared' -- ;; -- -- sysv4*MP*) -- if test -d /usr/nec; then -- lt_prog_compiler_pic_F77=-Kconform_pic -- fi -- ;; -- -- *) -- lt_prog_compiler_pic_F77='-fPIC' -- ;; -- esac -- -- case $cc_basename in -- nvcc*) # Cuda Compiler Driver 2.2 -- lt_prog_compiler_wl_F77='-Xlinker ' -- lt_prog_compiler_pic_F77='-Xcompiler -fPIC' -- ;; -- esac -- else -- # PORTME Check for flag to pass linker flags through the system compiler. -- case $host_os in -- aix*) -- lt_prog_compiler_wl_F77='-Wl,' -- if test "$host_cpu" = ia64; then -- # AIX 5 now supports IA64 processor -- lt_prog_compiler_static_F77='-Bstatic' -- else -- lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp' -- fi -- ;; -- -- mingw* | cygwin* | pw32* | os2* | cegcc*) -- # This hack is so that the source file can tell whether it is being -- # built for inclusion in a dll (and should export symbols for example). -- lt_prog_compiler_pic_F77='-DDLL_EXPORT' -- ;; -- -- hpux9* | hpux10* | hpux11*) -- lt_prog_compiler_wl_F77='-Wl,' -- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but -- # not for PA HP-UX. -- case $host_cpu in -- hppa*64*|ia64*) -- # +Z the default -- ;; -- *) -- lt_prog_compiler_pic_F77='+Z' -- ;; -- esac -- # Is there a better lt_prog_compiler_static that works with the bundled CC? -- lt_prog_compiler_static_F77='${wl}-a ${wl}archive' -- ;; -- -- irix5* | irix6* | nonstopux*) -- lt_prog_compiler_wl_F77='-Wl,' -- # PIC (with -KPIC) is the default. -- lt_prog_compiler_static_F77='-non_shared' -- ;; -- -- linux* | k*bsd*-gnu | kopensolaris*-gnu) -- case $cc_basename in -- # old Intel for x86_64 which still supported -KPIC. -- ecc*) -- lt_prog_compiler_wl_F77='-Wl,' -- lt_prog_compiler_pic_F77='-KPIC' -- lt_prog_compiler_static_F77='-static' -- ;; -- # icc used to be incompatible with GCC. -- # ICC 10 doesn't accept -KPIC any more. -- icc* | ifort*) -- lt_prog_compiler_wl_F77='-Wl,' -- lt_prog_compiler_pic_F77='-fPIC' -- lt_prog_compiler_static_F77='-static' -- ;; -- # Lahey Fortran 8.1. -- lf95*) -- lt_prog_compiler_wl_F77='-Wl,' -- lt_prog_compiler_pic_F77='--shared' -- lt_prog_compiler_static_F77='--static' -- ;; -- nagfor*) -- # NAG Fortran compiler -- lt_prog_compiler_wl_F77='-Wl,-Wl,,' -- lt_prog_compiler_pic_F77='-PIC' -- lt_prog_compiler_static_F77='-Bstatic' -- ;; -- pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) -- # Portland Group compilers (*not* the Pentium gcc compiler, -- # which looks to be a dead project) -- lt_prog_compiler_wl_F77='-Wl,' -- lt_prog_compiler_pic_F77='-fpic' -- lt_prog_compiler_static_F77='-Bstatic' -- ;; -- ccc*) -- lt_prog_compiler_wl_F77='-Wl,' -- # All Alpha code is PIC. -- lt_prog_compiler_static_F77='-non_shared' -- ;; -- xl* | bgxl* | bgf* | mpixl*) -- # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene -- lt_prog_compiler_wl_F77='-Wl,' -- lt_prog_compiler_pic_F77='-qpic' -- lt_prog_compiler_static_F77='-qstaticlink' -- ;; -- *) -- case `$CC -V 2>&1 | sed 5q` in -- *Sun\ F* | *Sun*Fortran*) -- # Sun Fortran 8.3 passes all unrecognized flags to the linker -- lt_prog_compiler_pic_F77='-KPIC' -- lt_prog_compiler_static_F77='-Bstatic' -- lt_prog_compiler_wl_F77='' -- ;; -- *Sun\ C*) -- # Sun C 5.9 -- lt_prog_compiler_pic_F77='-KPIC' -- lt_prog_compiler_static_F77='-Bstatic' -- lt_prog_compiler_wl_F77='-Wl,' -- ;; -- esac -- ;; -- esac -- ;; -- -- newsos6) -- lt_prog_compiler_pic_F77='-KPIC' -- lt_prog_compiler_static_F77='-Bstatic' -- ;; -- -- *nto* | *qnx*) -- # QNX uses GNU C++, but need to define -shared option too, otherwise -- # it will coredump. -- lt_prog_compiler_pic_F77='-fPIC -shared' -- ;; -- -- osf3* | osf4* | osf5*) -- lt_prog_compiler_wl_F77='-Wl,' -- # All OSF/1 code is PIC. -- lt_prog_compiler_static_F77='-non_shared' -- ;; -- -- rdos*) -- lt_prog_compiler_static_F77='-non_shared' -- ;; -- -- solaris*) -- lt_prog_compiler_pic_F77='-KPIC' -- lt_prog_compiler_static_F77='-Bstatic' -- case $cc_basename in -- f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) -- lt_prog_compiler_wl_F77='-Qoption ld ';; -- *) -- lt_prog_compiler_wl_F77='-Wl,';; -- esac -- ;; -- -- sunos4*) -- lt_prog_compiler_wl_F77='-Qoption ld ' -- lt_prog_compiler_pic_F77='-PIC' -- lt_prog_compiler_static_F77='-Bstatic' -- ;; -- -- sysv4 | sysv4.2uw2* | sysv4.3*) -- lt_prog_compiler_wl_F77='-Wl,' -- lt_prog_compiler_pic_F77='-KPIC' -- lt_prog_compiler_static_F77='-Bstatic' -- ;; -- -- sysv4*MP*) -- if test -d /usr/nec ;then -- lt_prog_compiler_pic_F77='-Kconform_pic' -- lt_prog_compiler_static_F77='-Bstatic' -- fi -- ;; -- -- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) -- lt_prog_compiler_wl_F77='-Wl,' -- lt_prog_compiler_pic_F77='-KPIC' -- lt_prog_compiler_static_F77='-Bstatic' -- ;; -- -- unicos*) -- lt_prog_compiler_wl_F77='-Wl,' -- lt_prog_compiler_can_build_shared_F77=no -- ;; -- -- uts4*) -- lt_prog_compiler_pic_F77='-pic' -- lt_prog_compiler_static_F77='-Bstatic' -- ;; -- -- *) -- lt_prog_compiler_can_build_shared_F77=no -- ;; -- esac -- fi -- --case $host_os in -- # For platforms which do not support PIC, -DPIC is meaningless: -- *djgpp*) -- lt_prog_compiler_pic_F77= -- ;; -- *) -- lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77" -- ;; --esac -- --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 --$as_echo_n "checking for $compiler option to produce PIC... " >&6; } --if ${lt_cv_prog_compiler_pic_F77+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- lt_cv_prog_compiler_pic_F77=$lt_prog_compiler_pic_F77 --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_F77" >&5 --$as_echo "$lt_cv_prog_compiler_pic_F77" >&6; } --lt_prog_compiler_pic_F77=$lt_cv_prog_compiler_pic_F77 -- --# --# Check to make sure the PIC flag actually works. --# --if test -n "$lt_prog_compiler_pic_F77"; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5 --$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... " >&6; } --if ${lt_cv_prog_compiler_pic_works_F77+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- lt_cv_prog_compiler_pic_works_F77=no -- ac_outfile=conftest.$ac_objext -- echo "$lt_simple_compile_test_code" > conftest.$ac_ext -- lt_compiler_flag="$lt_prog_compiler_pic_F77" -- # Insert the option either (1) after the last *FLAGS variable, or -- # (2) before a word containing "conftest.", or (3) at the end. -- # Note that $ac_compile itself does not contain backslashes and begins -- # with a dollar sign (not a hyphen), so the echo should work correctly. -- # The option is referenced via a variable to avoid confusing sed. -- lt_compile=`echo "$ac_compile" | $SED \ -- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -- -e 's:$: $lt_compiler_flag:'` -- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) -- (eval "$lt_compile" 2>conftest.err) -- ac_status=$? -- cat conftest.err >&5 -- echo "$as_me:$LINENO: \$? = $ac_status" >&5 -- if (exit $ac_status) && test -s "$ac_outfile"; then -- # The compiler can only warn and ignore the option if not recognized -- # So say no if there are warnings other than the usual output. -- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp -- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 -- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then -- lt_cv_prog_compiler_pic_works_F77=yes -- fi -- fi -- $RM conftest* -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_F77" >&5 --$as_echo "$lt_cv_prog_compiler_pic_works_F77" >&6; } -- --if test x"$lt_cv_prog_compiler_pic_works_F77" = xyes; then -- case $lt_prog_compiler_pic_F77 in -- "" | " "*) ;; -- *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;; -- esac --else -- lt_prog_compiler_pic_F77= -- lt_prog_compiler_can_build_shared_F77=no --fi -- --fi -- -- -- -- -- --# --# Check to make sure the static flag actually works. --# --wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\" --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 --$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } --if ${lt_cv_prog_compiler_static_works_F77+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- lt_cv_prog_compiler_static_works_F77=no -- save_LDFLAGS="$LDFLAGS" -- LDFLAGS="$LDFLAGS $lt_tmp_static_flag" -- echo "$lt_simple_link_test_code" > conftest.$ac_ext -- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then -- # The linker can only warn and ignore the option if not recognized -- # So say no if there are warnings -- if test -s conftest.err; then -- # Append any errors to the config.log. -- cat conftest.err 1>&5 -- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp -- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 -- if diff conftest.exp conftest.er2 >/dev/null; then -- lt_cv_prog_compiler_static_works_F77=yes -- fi -- else -- lt_cv_prog_compiler_static_works_F77=yes -- fi -- fi -- $RM -r conftest* -- LDFLAGS="$save_LDFLAGS" -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_F77" >&5 --$as_echo "$lt_cv_prog_compiler_static_works_F77" >&6; } -- --if test x"$lt_cv_prog_compiler_static_works_F77" = xyes; then -- : --else -- lt_prog_compiler_static_F77= --fi -- -- -- -- -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 --$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } --if ${lt_cv_prog_compiler_c_o_F77+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- lt_cv_prog_compiler_c_o_F77=no -- $RM -r conftest 2>/dev/null -- mkdir conftest -- cd conftest -- mkdir out -- echo "$lt_simple_compile_test_code" > conftest.$ac_ext -- -- lt_compiler_flag="-o out/conftest2.$ac_objext" -- # Insert the option either (1) after the last *FLAGS variable, or -- # (2) before a word containing "conftest.", or (3) at the end. -- # Note that $ac_compile itself does not contain backslashes and begins -- # with a dollar sign (not a hyphen), so the echo should work correctly. -- lt_compile=`echo "$ac_compile" | $SED \ -- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -- -e 's:$: $lt_compiler_flag:'` -- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) -- (eval "$lt_compile" 2>out/conftest.err) -- ac_status=$? -- cat out/conftest.err >&5 -- echo "$as_me:$LINENO: \$? = $ac_status" >&5 -- if (exit $ac_status) && test -s out/conftest2.$ac_objext -- then -- # The compiler can only warn and ignore the option if not recognized -- # So say no if there are warnings -- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp -- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 -- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then -- lt_cv_prog_compiler_c_o_F77=yes -- fi -- fi -- chmod u+w . 2>&5 -- $RM conftest* -- # SGI C++ compiler will create directory out/ii_files/ for -- # template instantiation -- test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files -- $RM out/* && rmdir out -- cd .. -- $RM -r conftest -- $RM conftest* -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_F77" >&5 --$as_echo "$lt_cv_prog_compiler_c_o_F77" >&6; } -- -- -- -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 --$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } --if ${lt_cv_prog_compiler_c_o_F77+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- lt_cv_prog_compiler_c_o_F77=no -- $RM -r conftest 2>/dev/null -- mkdir conftest -- cd conftest -- mkdir out -- echo "$lt_simple_compile_test_code" > conftest.$ac_ext -- -- lt_compiler_flag="-o out/conftest2.$ac_objext" -- # Insert the option either (1) after the last *FLAGS variable, or -- # (2) before a word containing "conftest.", or (3) at the end. -- # Note that $ac_compile itself does not contain backslashes and begins -- # with a dollar sign (not a hyphen), so the echo should work correctly. -- lt_compile=`echo "$ac_compile" | $SED \ -- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -- -e 's:$: $lt_compiler_flag:'` -- (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) -- (eval "$lt_compile" 2>out/conftest.err) -- ac_status=$? -- cat out/conftest.err >&5 -- echo "$as_me:$LINENO: \$? = $ac_status" >&5 -- if (exit $ac_status) && test -s out/conftest2.$ac_objext -- then -- # The compiler can only warn and ignore the option if not recognized -- # So say no if there are warnings -- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp -- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 -- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then -- lt_cv_prog_compiler_c_o_F77=yes -- fi -- fi -- chmod u+w . 2>&5 -- $RM conftest* -- # SGI C++ compiler will create directory out/ii_files/ for -- # template instantiation -- test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files -- $RM out/* && rmdir out -- cd .. -- $RM -r conftest -- $RM conftest* -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_F77" >&5 --$as_echo "$lt_cv_prog_compiler_c_o_F77" >&6; } -- -- -- -- --hard_links="nottested" --if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then -- # do not overwrite the value of need_locks provided by the user -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 --$as_echo_n "checking if we can lock with hard links... " >&6; } -- hard_links=yes -- $RM conftest* -- ln conftest.a conftest.b 2>/dev/null && hard_links=no -- touch conftest.a -- ln conftest.a conftest.b 2>&5 || hard_links=no -- ln conftest.a conftest.b 2>/dev/null && hard_links=no -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 --$as_echo "$hard_links" >&6; } -- if test "$hard_links" = no; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 --$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} -- need_locks=warn -- fi --else -- need_locks=no --fi -- -- -- -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 --$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } -- -- runpath_var= -- allow_undefined_flag_F77= -- always_export_symbols_F77=no -- archive_cmds_F77= -- archive_expsym_cmds_F77= -- compiler_needs_object_F77=no -- enable_shared_with_static_runtimes_F77=no -- export_dynamic_flag_spec_F77= -- export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' -- hardcode_automatic_F77=no -- hardcode_direct_F77=no -- hardcode_direct_absolute_F77=no -- hardcode_libdir_flag_spec_F77= -- hardcode_libdir_flag_spec_ld_F77= -- hardcode_libdir_separator_F77= -- hardcode_minus_L_F77=no -- hardcode_shlibpath_var_F77=unsupported -- inherit_rpath_F77=no -- link_all_deplibs_F77=unknown -- module_cmds_F77= -- module_expsym_cmds_F77= -- old_archive_from_new_cmds_F77= -- old_archive_from_expsyms_cmds_F77= -- thread_safe_flag_spec_F77= -- whole_archive_flag_spec_F77= -- # include_expsyms should be a list of space-separated symbols to be *always* -- # included in the symbol list -- include_expsyms_F77= -- # exclude_expsyms can be an extended regexp of symbols to exclude -- # it will be wrapped by ` (' and `)$', so one must not match beginning or -- # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', -- # as well as any symbol that contains `d'. -- exclude_expsyms_F77='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' -- # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out -- # platforms (ab)use it in PIC code, but their linkers get confused if -- # the symbol is explicitly referenced. Since portable code cannot -- # rely on this symbol name, it's probably fine to never include it in -- # preloaded symbol tables. -- # Exclude shared library initialization/finalization symbols. -- extract_expsyms_cmds= -- -- case $host_os in -- cygwin* | mingw* | pw32* | cegcc*) -- # FIXME: the MSVC++ port hasn't been tested in a loooong time -- # When not using gcc, we currently assume that we are using -- # Microsoft Visual C++. -- if test "$GCC" != yes; then -- with_gnu_ld=no -- fi -- ;; -- interix*) -- # we just hope/assume this is gcc and not c89 (= MSVC++) -- with_gnu_ld=yes -- ;; -- openbsd*) -- with_gnu_ld=no -- ;; -- esac -- -- ld_shlibs_F77=yes -- -- # On some targets, GNU ld is compatible enough with the native linker -- # that we're better off using the native interface for both. -- lt_use_gnu_ld_interface=no -- if test "$with_gnu_ld" = yes; then -- case $host_os in -- aix*) -- # The AIX port of GNU ld has always aspired to compatibility -- # with the native linker. However, as the warning in the GNU ld -- # block says, versions before 2.19.5* couldn't really create working -- # shared libraries, regardless of the interface used. -- case `$LD -v 2>&1` in -- *\ \(GNU\ Binutils\)\ 2.19.5*) ;; -- *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; -- *\ \(GNU\ Binutils\)\ [3-9]*) ;; -- *) -- lt_use_gnu_ld_interface=yes -- ;; -- esac -- ;; -- *) -- lt_use_gnu_ld_interface=yes -- ;; -- esac -- fi -- -- if test "$lt_use_gnu_ld_interface" = yes; then -- # If archive_cmds runs LD, not CC, wlarc should be empty -- wlarc='${wl}' -- -- # Set some defaults for GNU ld with shared library support. These -- # are reset later if shared libraries are not supported. Putting them -- # here allows them to be overridden if necessary. -- runpath_var=LD_RUN_PATH -- hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' -- export_dynamic_flag_spec_F77='${wl}--export-dynamic' -- # ancient GNU ld didn't support --whole-archive et. al. -- if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then -- whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' -- else -- whole_archive_flag_spec_F77= -- fi -- supports_anon_versioning=no -- case `$LD -v 2>&1` in -- *GNU\ gold*) supports_anon_versioning=yes ;; -- *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 -- *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... -- *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... -- *\ 2.11.*) ;; # other 2.11 versions -- *) supports_anon_versioning=yes ;; -- esac -- -- # See if GNU ld supports shared libraries. -- case $host_os in -- aix[3-9]*) -- # On AIX/PPC, the GNU linker is very broken -- if test "$host_cpu" != ia64; then -- ld_shlibs_F77=no -- cat <<_LT_EOF 1>&2 -- --*** Warning: the GNU linker, at least up to release 2.19, is reported --*** to be unable to reliably create shared libraries on AIX. --*** Therefore, libtool is disabling shared libraries support. If you --*** really care for shared libraries, you may want to install binutils --*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. --*** You will then need to restart the configuration process. -- --_LT_EOF -- fi -- ;; -- -- amigaos*) -- case $host_cpu in -- powerpc) -- # see comment about AmigaOS4 .so support -- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' -- archive_expsym_cmds_F77='' -- ;; -- m68k) -- archive_cmds_F77='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' -- hardcode_libdir_flag_spec_F77='-L$libdir' -- hardcode_minus_L_F77=yes -- ;; -- esac -- ;; -- -- beos*) -- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then -- allow_undefined_flag_F77=unsupported -- # Joseph Beckenbach says some releases of gcc -- # support --undefined. This deserves some investigation. FIXME -- archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' -- else -- ld_shlibs_F77=no -- fi -- ;; -- -- cygwin* | mingw* | pw32* | cegcc*) -- # _LT_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless, -- # as there is no search path for DLLs. -- hardcode_libdir_flag_spec_F77='-L$libdir' -- export_dynamic_flag_spec_F77='${wl}--export-all-symbols' -- allow_undefined_flag_F77=unsupported -- always_export_symbols_F77=no -- enable_shared_with_static_runtimes_F77=yes -- export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' -- exclude_expsyms_F77='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' -- -- if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then -- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' -- # If the export-symbols file already is a .def file (1st line -- # is EXPORTS), use it as is; otherwise, prepend... -- archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then -- cp $export_symbols $output_objdir/$soname.def; -- else -- echo EXPORTS > $output_objdir/$soname.def; -- cat $export_symbols >> $output_objdir/$soname.def; -- fi~ -- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' -- else -- ld_shlibs_F77=no -- fi -- ;; -- -- haiku*) -- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' -- link_all_deplibs_F77=yes -- ;; -- -- interix[3-9]*) -- hardcode_direct_F77=no -- hardcode_shlibpath_var_F77=no -- hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' -- export_dynamic_flag_spec_F77='${wl}-E' -- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. -- # Instead, shared libraries are loaded at an image base (0x10000000 by -- # default) and relocated if they conflict, which is a slow very memory -- # consuming and fragmenting process. To avoid this, we pick a random, -- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link -- # time. Moving up from 0x10000000 also allows more sbrk(2) space. -- archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' -- archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' -- ;; -- -- gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) -- tmp_diet=no -- if test "$host_os" = linux-dietlibc; then -- case $cc_basename in -- diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) -- esac -- fi -- if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ -- && test "$tmp_diet" = no -- then -- tmp_addflag=' $pic_flag' -- tmp_sharedflag='-shared' -- case $cc_basename,$host_cpu in -- pgcc*) # Portland Group C compiler -- whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' -- tmp_addflag=' $pic_flag' -- ;; -- pgf77* | pgf90* | pgf95* | pgfortran*) -- # Portland Group f77 and f90 compilers -- whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' -- tmp_addflag=' $pic_flag -Mnomain' ;; -- ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 -- tmp_addflag=' -i_dynamic' ;; -- efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 -- tmp_addflag=' -i_dynamic -nofor_main' ;; -- ifc* | ifort*) # Intel Fortran compiler -- tmp_addflag=' -nofor_main' ;; -- lf95*) # Lahey Fortran 8.1 -- whole_archive_flag_spec_F77= -- tmp_sharedflag='--shared' ;; -- xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) -- tmp_sharedflag='-qmkshrobj' -- tmp_addflag= ;; -- nvcc*) # Cuda Compiler Driver 2.2 -- whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' -- compiler_needs_object_F77=yes -- ;; -- esac -- case `$CC -V 2>&1 | sed 5q` in -- *Sun\ C*) # Sun C 5.9 -- whole_archive_flag_spec_F77='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' -- compiler_needs_object_F77=yes -- tmp_sharedflag='-G' ;; -- *Sun\ F*) # Sun Fortran 8.3 -- tmp_sharedflag='-G' ;; -- esac -- archive_cmds_F77='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' -- -- if test "x$supports_anon_versioning" = xyes; then -- archive_expsym_cmds_F77='echo "{ global:" > $output_objdir/$libname.ver~ -- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ -- echo "local: *; };" >> $output_objdir/$libname.ver~ -- $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' -- fi -- -- case $cc_basename in -- xlf* | bgf* | bgxlf* | mpixlf*) -- # IBM XL Fortran 10.1 on PPC cannot create shared libs itself -- whole_archive_flag_spec_F77='--whole-archive$convenience --no-whole-archive' -- hardcode_libdir_flag_spec_F77= -- hardcode_libdir_flag_spec_ld_F77='-rpath $libdir' -- archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' -- if test "x$supports_anon_versioning" = xyes; then -- archive_expsym_cmds_F77='echo "{ global:" > $output_objdir/$libname.ver~ -- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ -- echo "local: *; };" >> $output_objdir/$libname.ver~ -- $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' -- fi -- ;; -- esac -- else -- ld_shlibs_F77=no -- fi -- ;; -- -- netbsd*) -- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then -- archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' -- wlarc= -- else -- archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' -- archive_expsym_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' -- fi -- ;; -- -- solaris*) -- if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then -- ld_shlibs_F77=no -- cat <<_LT_EOF 1>&2 -- --*** Warning: The releases 2.8.* of the GNU linker cannot reliably --*** create shared libraries on Solaris systems. Therefore, libtool --*** is disabling shared libraries support. We urge you to upgrade GNU --*** binutils to release 2.9.1 or newer. Another option is to modify --*** your PATH or compiler configuration so that the native linker is --*** used, and then restart. -- --_LT_EOF -- elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then -- archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' -- archive_expsym_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' -- else -- ld_shlibs_F77=no -- fi -- ;; -- -- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) -- case `$LD -v 2>&1` in -- *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) -- ld_shlibs_F77=no -- cat <<_LT_EOF 1>&2 -- --*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not --*** reliably create shared libraries on SCO systems. Therefore, libtool --*** is disabling shared libraries support. We urge you to upgrade GNU --*** binutils to release 2.16.91.0.3 or newer. Another option is to modify --*** your PATH or compiler configuration so that the native linker is --*** used, and then restart. -- --_LT_EOF -- ;; -- *) -- # For security reasons, it is highly recommended that you always -- # use absolute paths for naming shared libraries, and exclude the -- # DT_RUNPATH tag from executables and libraries. But doing so -- # requires that you compile everything twice, which is a pain. -- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then -- hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' -- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' -- archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' -- else -- ld_shlibs_F77=no -- fi -- ;; -- esac -- ;; -- -- sunos4*) -- archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' -- wlarc= -- hardcode_direct_F77=yes -- hardcode_shlibpath_var_F77=no -- ;; -- -- *) -- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then -- archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' -- archive_expsym_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' -- else -- ld_shlibs_F77=no -- fi -- ;; -- esac -- -- if test "$ld_shlibs_F77" = no; then -- runpath_var= -- hardcode_libdir_flag_spec_F77= -- export_dynamic_flag_spec_F77= -- whole_archive_flag_spec_F77= -- fi -- else -- # PORTME fill in a description of your system's linker (not GNU ld) -- case $host_os in -- aix3*) -- allow_undefined_flag_F77=unsupported -- always_export_symbols_F77=yes -- archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' -- # Note: this linker hardcodes the directories in LIBPATH if there -- # are no directories specified by -L. -- hardcode_minus_L_F77=yes -- if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then -- # Neither direct hardcoding nor static linking is supported with a -- # broken collect2. -- hardcode_direct_F77=unsupported -- fi -- ;; -- -- aix[4-9]*) -- if test "$host_cpu" = ia64; then -- # On IA64, the linker does run time linking by default, so we don't -- # have to do anything special. -- aix_use_runtimelinking=no -- exp_sym_flag='-Bexport' -- no_entry_flag="" -- else -- # If we're using GNU nm, then we don't want the "-C" option. -- # -C means demangle to AIX nm, but means don't demangle with GNU nm -- # Also, AIX nm treats weak defined symbols like other global -- # defined symbols, whereas GNU nm marks them as "W". -- if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then -- export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' -- else -- export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' -- fi -- aix_use_runtimelinking=no -- -- # Test if we are trying to use run time linking or normal -- # AIX style linking. If -brtl is somewhere in LDFLAGS, we -- # need to do runtime linking. -- case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) -- for ld_flag in $LDFLAGS; do -- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then -- aix_use_runtimelinking=yes -- break -- fi -- done -- ;; -- esac -- -- exp_sym_flag='-bexport' -- no_entry_flag='-bnoentry' -- fi -- -- # When large executables or shared objects are built, AIX ld can -- # have problems creating the table of contents. If linking a library -- # or program results in "error TOC overflow" add -mminimal-toc to -- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not -- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. -- -- archive_cmds_F77='' -- hardcode_direct_F77=yes -- hardcode_direct_absolute_F77=yes -- hardcode_libdir_separator_F77=':' -- link_all_deplibs_F77=yes -- file_list_spec_F77='${wl}-f,' -- -- if test "$GCC" = yes; then -- case $host_os in aix4.[012]|aix4.[012].*) -- # We only want to do this on AIX 4.2 and lower, the check -- # below for broken collect2 doesn't work under 4.3+ -- collect2name=`${CC} -print-prog-name=collect2` -- if test -f "$collect2name" && -- strings "$collect2name" | $GREP resolve_lib_name >/dev/null -- then -- # We have reworked collect2 -- : -- else -- # We have old collect2 -- hardcode_direct_F77=unsupported -- # It fails to find uninstalled libraries when the uninstalled -- # path is not listed in the libpath. Setting hardcode_minus_L -- # to unsupported forces relinking -- hardcode_minus_L_F77=yes -- hardcode_libdir_flag_spec_F77='-L$libdir' -- hardcode_libdir_separator_F77= -- fi -- ;; -- esac -- shared_flag='-shared' -- if test "$aix_use_runtimelinking" = yes; then -- shared_flag="$shared_flag "'${wl}-G' -- fi -- else -- # not using gcc -- if test "$host_cpu" = ia64; then -- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release -- # chokes on -Wl,-G. The following line is correct: -- shared_flag='-G' -- else -- if test "$aix_use_runtimelinking" = yes; then -- shared_flag='${wl}-G' -- else -- shared_flag='${wl}-bM:SRE' -- fi -- fi -- fi -- -- export_dynamic_flag_spec_F77='${wl}-bexpall' -- # It seems that -bexpall does not export symbols beginning with -- # underscore (_), so it is better to generate a list of symbols to export. -- always_export_symbols_F77=yes -- if test "$aix_use_runtimelinking" = yes; then -- # Warning - without using the other runtime loading flags (-brtl), -- # -berok will link without error, but may produce a broken library. -- allow_undefined_flag_F77='-berok' -- # Determine the default libpath from the value encoded in an -- # empty executable. -- if test "${lt_cv_aix_libpath+set}" = set; then -- aix_libpath=$lt_cv_aix_libpath --else -- if ${lt_cv_aix_libpath__F77+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- cat > conftest.$ac_ext <<_ACEOF -- program main -- -- end --_ACEOF --if ac_fn_f77_try_link "$LINENO"; then : -- -- lt_aix_libpath_sed=' -- /Import File Strings/,/^$/ { -- /^0/ { -- s/^0 *\([^ ]*\) *$/\1/ -- p -- } -- }' -- lt_cv_aix_libpath__F77=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -- # Check for a 64-bit object if we didn't find anything. -- if test -z "$lt_cv_aix_libpath__F77"; then -- lt_cv_aix_libpath__F77=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -- fi --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext -- if test -z "$lt_cv_aix_libpath__F77"; then -- lt_cv_aix_libpath__F77="/usr/lib:/lib" -- fi -- --fi -- -- aix_libpath=$lt_cv_aix_libpath__F77 --fi -- -- hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" -- archive_expsym_cmds_F77='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" -- else -- if test "$host_cpu" = ia64; then -- hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib' -- allow_undefined_flag_F77="-z nodefs" -- archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" -- else -- # Determine the default libpath from the value encoded in an -- # empty executable. -- if test "${lt_cv_aix_libpath+set}" = set; then -- aix_libpath=$lt_cv_aix_libpath --else -- if ${lt_cv_aix_libpath__F77+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- cat > conftest.$ac_ext <<_ACEOF -- program main -- -- end --_ACEOF --if ac_fn_f77_try_link "$LINENO"; then : -- -- lt_aix_libpath_sed=' -- /Import File Strings/,/^$/ { -- /^0/ { -- s/^0 *\([^ ]*\) *$/\1/ -- p -- } -- }' -- lt_cv_aix_libpath__F77=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -- # Check for a 64-bit object if we didn't find anything. -- if test -z "$lt_cv_aix_libpath__F77"; then -- lt_cv_aix_libpath__F77=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -- fi --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext -- if test -z "$lt_cv_aix_libpath__F77"; then -- lt_cv_aix_libpath__F77="/usr/lib:/lib" -- fi -- --fi -- -- aix_libpath=$lt_cv_aix_libpath__F77 --fi -- -- hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" -- # Warning - without using the other run time loading flags, -- # -berok will link without error, but may produce a broken library. -- no_undefined_flag_F77=' ${wl}-bernotok' -- allow_undefined_flag_F77=' ${wl}-berok' -- if test "$with_gnu_ld" = yes; then -- # We only use this code for GNU lds that support --whole-archive. -- whole_archive_flag_spec_F77='${wl}--whole-archive$convenience ${wl}--no-whole-archive' -- else -- # Exported symbols can be pulled into shared objects from archives -- whole_archive_flag_spec_F77='$convenience' -- fi -- archive_cmds_need_lc_F77=yes -- # This is similar to how AIX traditionally builds its shared libraries. -- archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' -- fi -- fi -- ;; -- -- amigaos*) -- case $host_cpu in -- powerpc) -- # see comment about AmigaOS4 .so support -- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' -- archive_expsym_cmds_F77='' -- ;; -- m68k) -- archive_cmds_F77='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' -- hardcode_libdir_flag_spec_F77='-L$libdir' -- hardcode_minus_L_F77=yes -- ;; -- esac -- ;; -- -- bsdi[45]*) -- export_dynamic_flag_spec_F77=-rdynamic -- ;; -- -- cygwin* | mingw* | pw32* | cegcc*) -- # When not using gcc, we currently assume that we are using -- # Microsoft Visual C++. -- # hardcode_libdir_flag_spec is actually meaningless, as there is -- # no search path for DLLs. -- case $cc_basename in -- cl*) -- # Native MSVC -- hardcode_libdir_flag_spec_F77=' ' -- allow_undefined_flag_F77=unsupported -- always_export_symbols_F77=yes -- file_list_spec_F77='@' -- # Tell ltmain to make .lib files, not .a files. -- libext=lib -- # Tell ltmain to make .dll files, not .so files. -- shrext_cmds=".dll" -- # FIXME: Setting linknames here is a bad hack. -- archive_cmds_F77='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' -- archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then -- sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; -- else -- sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; -- fi~ -- $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ -- linknames=' -- # The linker will not automatically build a static lib if we build a DLL. -- # _LT_TAGVAR(old_archive_from_new_cmds, F77)='true' -- enable_shared_with_static_runtimes_F77=yes -- export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' -- # Don't use ranlib -- old_postinstall_cmds_F77='chmod 644 $oldlib' -- postlink_cmds_F77='lt_outputfile="@OUTPUT@"~ -- lt_tool_outputfile="@TOOL_OUTPUT@"~ -- case $lt_outputfile in -- *.exe|*.EXE) ;; -- *) -- lt_outputfile="$lt_outputfile.exe" -- lt_tool_outputfile="$lt_tool_outputfile.exe" -- ;; -- esac~ -- if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then -- $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; -- $RM "$lt_outputfile.manifest"; -- fi' -- ;; -- *) -- # Assume MSVC wrapper -- hardcode_libdir_flag_spec_F77=' ' -- allow_undefined_flag_F77=unsupported -- # Tell ltmain to make .lib files, not .a files. -- libext=lib -- # Tell ltmain to make .dll files, not .so files. -- shrext_cmds=".dll" -- # FIXME: Setting linknames here is a bad hack. -- archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' -- # The linker will automatically build a .lib file if we build a DLL. -- old_archive_from_new_cmds_F77='true' -- # FIXME: Should let the user specify the lib program. -- old_archive_cmds_F77='lib -OUT:$oldlib$oldobjs$old_deplibs' -- enable_shared_with_static_runtimes_F77=yes -- ;; -- esac -- ;; -- -- darwin* | rhapsody*) -- -- -- archive_cmds_need_lc_F77=no -- hardcode_direct_F77=no -- hardcode_automatic_F77=yes -- hardcode_shlibpath_var_F77=unsupported -- if test "$lt_cv_ld_force_load" = "yes"; then -- whole_archive_flag_spec_F77='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' -- else -- whole_archive_flag_spec_F77='' -- fi -- link_all_deplibs_F77=yes -- allow_undefined_flag_F77="$_lt_dar_allow_undefined" -- case $cc_basename in -- ifort*) _lt_dar_can_shared=yes ;; -- *) _lt_dar_can_shared=$GCC ;; -- esac -- if test "$_lt_dar_can_shared" = "yes"; then -- output_verbose_link_cmd=func_echo_all -- archive_cmds_F77="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -- module_cmds_F77="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds_F77="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -- module_expsym_cmds_F77="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" -- -- else -- ld_shlibs_F77=no -- fi -- -- ;; -- -- dgux*) -- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' -- hardcode_libdir_flag_spec_F77='-L$libdir' -- hardcode_shlibpath_var_F77=no -- ;; -- -- freebsd1*) -- ld_shlibs_F77=no -- ;; -- -- # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor -- # support. Future versions do this automatically, but an explicit c++rt0.o -- # does not break anything, and helps significantly (at the cost of a little -- # extra space). -- freebsd2.2*) -- archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' -- hardcode_libdir_flag_spec_F77='-R$libdir' -- hardcode_direct_F77=yes -- hardcode_shlibpath_var_F77=no -- ;; -- -- # Unfortunately, older versions of FreeBSD 2 do not have this feature. -- freebsd2*) -- archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' -- hardcode_direct_F77=yes -- hardcode_minus_L_F77=yes -- hardcode_shlibpath_var_F77=no -- ;; -- -- # FreeBSD 3 and greater uses gcc -shared to do shared libraries. -- freebsd* | dragonfly*) -- archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' -- hardcode_libdir_flag_spec_F77='-R$libdir' -- hardcode_direct_F77=yes -- hardcode_shlibpath_var_F77=no -- ;; -- -- hpux9*) -- if test "$GCC" = yes; then -- archive_cmds_F77='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' -- else -- archive_cmds_F77='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' -- fi -- hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' -- hardcode_libdir_separator_F77=: -- hardcode_direct_F77=yes -- -- # hardcode_minus_L: Not really in the search PATH, -- # but as the default location of the library. -- hardcode_minus_L_F77=yes -- export_dynamic_flag_spec_F77='${wl}-E' -- ;; -- -- hpux10*) -- if test "$GCC" = yes && test "$with_gnu_ld" = no; then -- archive_cmds_F77='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' -- else -- archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' -- fi -- if test "$with_gnu_ld" = no; then -- hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' -- hardcode_libdir_flag_spec_ld_F77='+b $libdir' -- hardcode_libdir_separator_F77=: -- hardcode_direct_F77=yes -- hardcode_direct_absolute_F77=yes -- export_dynamic_flag_spec_F77='${wl}-E' -- # hardcode_minus_L: Not really in the search PATH, -- # but as the default location of the library. -- hardcode_minus_L_F77=yes -- fi -- ;; -- -- hpux11*) -- if test "$GCC" = yes && test "$with_gnu_ld" = no; then -- case $host_cpu in -- hppa*64*) -- archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' -- ;; -- ia64*) -- archive_cmds_F77='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' -- ;; -- *) -- archive_cmds_F77='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' -- ;; -- esac -- else -- case $host_cpu in -- hppa*64*) -- archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' -- ;; -- ia64*) -- archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' -- ;; -- *) -- archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' -- ;; -- esac -- fi -- if test "$with_gnu_ld" = no; then -- hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' -- hardcode_libdir_separator_F77=: -- -- case $host_cpu in -- hppa*64*|ia64*) -- hardcode_direct_F77=no -- hardcode_shlibpath_var_F77=no -- ;; -- *) -- hardcode_direct_F77=yes -- hardcode_direct_absolute_F77=yes -- export_dynamic_flag_spec_F77='${wl}-E' -- -- # hardcode_minus_L: Not really in the search PATH, -- # but as the default location of the library. -- hardcode_minus_L_F77=yes -- ;; -- esac -- fi -- ;; -- -- irix5* | irix6* | nonstopux*) -- if test "$GCC" = yes; then -- archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' -- # Try to use the -exported_symbol ld option, if it does not -- # work, assume that -exports_file does not work either and -- # implicitly export all symbols. -- # This should be the same for all languages, so no per-tag cache variable. -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 --$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } --if ${lt_cv_irix_exported_symbol+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- save_LDFLAGS="$LDFLAGS" -- LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" -- cat > conftest.$ac_ext <<_ACEOF -- -- subroutine foo -- end --_ACEOF --if ac_fn_f77_try_link "$LINENO"; then : -- lt_cv_irix_exported_symbol=yes --else -- lt_cv_irix_exported_symbol=no --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext -- LDFLAGS="$save_LDFLAGS" --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 --$as_echo "$lt_cv_irix_exported_symbol" >&6; } -- if test "$lt_cv_irix_exported_symbol" = yes; then -- archive_expsym_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' -- fi -- else -- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' -- archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' -- fi -- archive_cmds_need_lc_F77='no' -- hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' -- hardcode_libdir_separator_F77=: -- inherit_rpath_F77=yes -- link_all_deplibs_F77=yes -- ;; -- -- netbsd*) -- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then -- archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out -- else -- archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF -- fi -- hardcode_libdir_flag_spec_F77='-R$libdir' -- hardcode_direct_F77=yes -- hardcode_shlibpath_var_F77=no -- ;; -- -- newsos6) -- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' -- hardcode_direct_F77=yes -- hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' -- hardcode_libdir_separator_F77=: -- hardcode_shlibpath_var_F77=no -- ;; -- -- *nto* | *qnx*) -- ;; -- -- openbsd*) -- if test -f /usr/libexec/ld.so; then -- hardcode_direct_F77=yes -- hardcode_shlibpath_var_F77=no -- hardcode_direct_absolute_F77=yes -- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then -- archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' -- archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' -- hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' -- export_dynamic_flag_spec_F77='${wl}-E' -- else -- case $host_os in -- openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) -- archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' -- hardcode_libdir_flag_spec_F77='-R$libdir' -- ;; -- *) -- archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' -- hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' -- ;; -- esac -- fi -- else -- ld_shlibs_F77=no -- fi -- ;; -- -- os2*) -- hardcode_libdir_flag_spec_F77='-L$libdir' -- hardcode_minus_L_F77=yes -- allow_undefined_flag_F77=unsupported -- archive_cmds_F77='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' -- old_archive_from_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' -- ;; -- -- osf3*) -- if test "$GCC" = yes; then -- allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' -- archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' -- else -- allow_undefined_flag_F77=' -expect_unresolved \*' -- archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' -- fi -- archive_cmds_need_lc_F77='no' -- hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' -- hardcode_libdir_separator_F77=: -- ;; -- -- osf4* | osf5*) # as osf3* with the addition of -msym flag -- if test "$GCC" = yes; then -- allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' -- archive_cmds_F77='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' -- hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' -- else -- allow_undefined_flag_F77=' -expect_unresolved \*' -- archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' -- archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ -- $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' -- -- # Both c and cxx compiler support -rpath directly -- hardcode_libdir_flag_spec_F77='-rpath $libdir' -- fi -- archive_cmds_need_lc_F77='no' -- hardcode_libdir_separator_F77=: -- ;; -- -- solaris*) -- no_undefined_flag_F77=' -z defs' -- if test "$GCC" = yes; then -- wlarc='${wl}' -- archive_cmds_F77='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' -- archive_expsym_cmds_F77='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ -- $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' -- else -- case `$CC -V 2>&1` in -- *"Compilers 5.0"*) -- wlarc='' -- archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' -- archive_expsym_cmds_F77='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ -- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' -- ;; -- *) -- wlarc='${wl}' -- archive_cmds_F77='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' -- archive_expsym_cmds_F77='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ -- $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' -- ;; -- esac -- fi -- hardcode_libdir_flag_spec_F77='-R$libdir' -- hardcode_shlibpath_var_F77=no -- case $host_os in -- solaris2.[0-5] | solaris2.[0-5].*) ;; -- *) -- # The compiler driver will combine and reorder linker options, -- # but understands `-z linker_flag'. GCC discards it without `$wl', -- # but is careful enough not to reorder. -- # Supported since Solaris 2.6 (maybe 2.5.1?) -- if test "$GCC" = yes; then -- whole_archive_flag_spec_F77='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' -- else -- whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' -- fi -- ;; -- esac -- link_all_deplibs_F77=yes -- ;; -- -- sunos4*) -- if test "x$host_vendor" = xsequent; then -- # Use $CC to link under sequent, because it throws in some extra .o -- # files that make .init and .fini sections work. -- archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' -- else -- archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' -- fi -- hardcode_libdir_flag_spec_F77='-L$libdir' -- hardcode_direct_F77=yes -- hardcode_minus_L_F77=yes -- hardcode_shlibpath_var_F77=no -- ;; -- -- sysv4) -- case $host_vendor in -- sni) -- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' -- hardcode_direct_F77=yes # is this really true??? -- ;; -- siemens) -- ## LD is ld it makes a PLAMLIB -- ## CC just makes a GrossModule. -- archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' -- reload_cmds_F77='$CC -r -o $output$reload_objs' -- hardcode_direct_F77=no -- ;; -- motorola) -- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' -- hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie -- ;; -- esac -- runpath_var='LD_RUN_PATH' -- hardcode_shlibpath_var_F77=no -- ;; -- -- sysv4.3*) -- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' -- hardcode_shlibpath_var_F77=no -- export_dynamic_flag_spec_F77='-Bexport' -- ;; -- -- sysv4*MP*) -- if test -d /usr/nec; then -- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' -- hardcode_shlibpath_var_F77=no -- runpath_var=LD_RUN_PATH -- hardcode_runpath_var=yes -- ld_shlibs_F77=yes -- fi -- ;; -- -- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) -- no_undefined_flag_F77='${wl}-z,text' -- archive_cmds_need_lc_F77=no -- hardcode_shlibpath_var_F77=no -- runpath_var='LD_RUN_PATH' -- -- if test "$GCC" = yes; then -- archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' -- archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' -- else -- archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' -- archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' -- fi -- ;; -- -- sysv5* | sco3.2v5* | sco5v6*) -- # Note: We can NOT use -z defs as we might desire, because we do not -- # link with -lc, and that would cause any symbols used from libc to -- # always be unresolved, which means just about no library would -- # ever link correctly. If we're not using GNU ld we use -z text -- # though, which does catch some bad symbols but isn't as heavy-handed -- # as -z defs. -- no_undefined_flag_F77='${wl}-z,text' -- allow_undefined_flag_F77='${wl}-z,nodefs' -- archive_cmds_need_lc_F77=no -- hardcode_shlibpath_var_F77=no -- hardcode_libdir_flag_spec_F77='${wl}-R,$libdir' -- hardcode_libdir_separator_F77=':' -- link_all_deplibs_F77=yes -- export_dynamic_flag_spec_F77='${wl}-Bexport' -- runpath_var='LD_RUN_PATH' -- -- if test "$GCC" = yes; then -- archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' -- archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' -- else -- archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' -- archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' -- fi -- ;; -- -- uts4*) -- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' -- hardcode_libdir_flag_spec_F77='-L$libdir' -- hardcode_shlibpath_var_F77=no -- ;; -- -- *) -- ld_shlibs_F77=no -- ;; -- esac -- -- if test x$host_vendor = xsni; then -- case $host in -- sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) -- export_dynamic_flag_spec_F77='${wl}-Blargedynsym' -- ;; -- esac -- fi -- fi -- --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_F77" >&5 --$as_echo "$ld_shlibs_F77" >&6; } --test "$ld_shlibs_F77" = no && can_build_shared=no -- --with_gnu_ld_F77=$with_gnu_ld -- -- -- -- -- -- --# --# Do we need to explicitly link libc? --# --case "x$archive_cmds_need_lc_F77" in --x|xyes) -- # Assume -lc should be added -- archive_cmds_need_lc_F77=yes -- -- if test "$enable_shared" = yes && test "$GCC" = yes; then -- case $archive_cmds_F77 in -- *'~'*) -- # FIXME: we may have to deal with multi-command sequences. -- ;; -- '$CC '*) -- # Test whether the compiler implicitly links with -lc since on some -- # systems, -lgcc has to come before -lc. If gcc already passes -lc -- # to ld, don't add -lc before -lgcc. -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 --$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } --if ${lt_cv_archive_cmds_need_lc_F77+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- $RM conftest* -- echo "$lt_simple_compile_test_code" > conftest.$ac_ext -- -- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 -- (eval $ac_compile) 2>&5 -- ac_status=$? -- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; } 2>conftest.err; then -- soname=conftest -- lib=conftest -- libobjs=conftest.$ac_objext -- deplibs= -- wl=$lt_prog_compiler_wl_F77 -- pic_flag=$lt_prog_compiler_pic_F77 -- compiler_flags=-v -- linker_flags=-v -- verstring= -- output_objdir=. -- libname=conftest -- lt_save_allow_undefined_flag=$allow_undefined_flag_F77 -- allow_undefined_flag_F77= -- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_F77 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 -- (eval $archive_cmds_F77 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 -- ac_status=$? -- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -- test $ac_status = 0; } -- then -- lt_cv_archive_cmds_need_lc_F77=no -- else -- lt_cv_archive_cmds_need_lc_F77=yes -- fi -- allow_undefined_flag_F77=$lt_save_allow_undefined_flag -- else -- cat conftest.err 1>&5 -- fi -- $RM conftest* -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_F77" >&5 --$as_echo "$lt_cv_archive_cmds_need_lc_F77" >&6; } -- archive_cmds_need_lc_F77=$lt_cv_archive_cmds_need_lc_F77 -- ;; -- esac -- fi -- ;; --esac -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 --$as_echo_n "checking dynamic linker characteristics... " >&6; } -- --library_names_spec= --libname_spec='lib$name' --soname_spec= --shrext_cmds=".so" --postinstall_cmds= --postuninstall_cmds= --finish_cmds= --finish_eval= --shlibpath_var= --shlibpath_overrides_runpath=unknown --version_type=none --dynamic_linker="$host_os ld.so" --sys_lib_dlsearch_path_spec="/lib /usr/lib" --need_lib_prefix=unknown --hardcode_into_libs=no -- --# when you set need_version to no, make sure it does not cause -set_version --# flags to be left without arguments --need_version=unknown -- --case $host_os in --aix3*) -- version_type=linux -- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' -- shlibpath_var=LIBPATH -- -- # AIX 3 has no versioning support, so we append a major version to the name. -- soname_spec='${libname}${release}${shared_ext}$major' -- ;; -- --aix[4-9]*) -- version_type=linux -- need_lib_prefix=no -- need_version=no -- hardcode_into_libs=yes -- if test "$host_cpu" = ia64; then -- # AIX 5 supports IA64 -- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' -- shlibpath_var=LD_LIBRARY_PATH -- else -- # With GCC up to 2.95.x, collect2 would create an import file -- # for dependence libraries. The import file would start with -- # the line `#! .'. This would cause the generated library to -- # depend on `.', always an invalid library. This was fixed in -- # development snapshots of GCC prior to 3.0. -- case $host_os in -- aix4 | aix4.[01] | aix4.[01].*) -- if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' -- echo ' yes ' -- echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then -- : -- else -- can_build_shared=no -- fi -- ;; -- esac -- # AIX (on Power*) has no versioning support, so currently we can not hardcode correct -- # soname into executable. Probably we can add versioning support to -- # collect2, so additional links can be useful in future. -- if test "$aix_use_runtimelinking" = yes; then -- # If using run time linking (on AIX 4.2 or later) use lib.so -- # instead of lib.a to let people know that these are not -- # typical AIX shared libraries. -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' -- else -- # We preserve .a as extension for shared libraries through AIX4.2 -- # and later when we are not doing run time linking. -- library_names_spec='${libname}${release}.a $libname.a' -- soname_spec='${libname}${release}${shared_ext}$major' -- fi -- shlibpath_var=LIBPATH -- fi -- ;; -- --amigaos*) -- case $host_cpu in -- powerpc) -- # Since July 2007 AmigaOS4 officially supports .so libraries. -- # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' -- ;; -- m68k) -- library_names_spec='$libname.ixlibrary $libname.a' -- # Create ${libname}_ixlibrary.a entries in /sys/libs. -- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' -- ;; -- esac -- ;; -- --beos*) -- library_names_spec='${libname}${shared_ext}' -- dynamic_linker="$host_os ld.so" -- shlibpath_var=LIBRARY_PATH -- ;; -- --bsdi[45]*) -- version_type=linux -- need_version=no -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' -- soname_spec='${libname}${release}${shared_ext}$major' -- finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' -- shlibpath_var=LD_LIBRARY_PATH -- sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" -- sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" -- # the default ld.so.conf also contains /usr/contrib/lib and -- # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow -- # libtool to hard-code these into programs -- ;; -- --cygwin* | mingw* | pw32* | cegcc*) -- version_type=windows -- shrext_cmds=".dll" -- need_version=no -- need_lib_prefix=no -- -- case $GCC,$cc_basename in -- yes,*) -- # gcc -- library_names_spec='$libname.dll.a' -- # DLL is installed to $(libdir)/../bin by postinstall_cmds -- postinstall_cmds='base_file=`basename \${file}`~ -- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ -- dldir=$destdir/`dirname \$dlpath`~ -- test -d \$dldir || mkdir -p \$dldir~ -- $install_prog $dir/$dlname \$dldir/$dlname~ -- chmod a+x \$dldir/$dlname~ -- if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then -- eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; -- fi' -- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ -- dlpath=$dir/\$dldll~ -- $RM \$dlpath' -- shlibpath_overrides_runpath=yes -- -- case $host_os in -- cygwin*) -- # Cygwin DLLs use 'cyg' prefix rather than 'lib' -- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' -- -- ;; -- mingw* | cegcc*) -- # MinGW DLLs use traditional 'lib' prefix -- soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' -- ;; -- pw32*) -- # pw32 DLLs use 'pw' prefix rather than 'lib' -- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' -- ;; -- esac -- dynamic_linker='Win32 ld.exe' -- ;; -- -- *,cl*) -- # Native MSVC -- libname_spec='$name' -- soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' -- library_names_spec='${libname}.dll.lib' -- -- case $build_os in -- mingw*) -- sys_lib_search_path_spec= -- lt_save_ifs=$IFS -- IFS=';' -- for lt_path in $LIB -- do -- IFS=$lt_save_ifs -- # Let DOS variable expansion print the short 8.3 style file name. -- lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` -- sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" -- done -- IFS=$lt_save_ifs -- # Convert to MSYS style. -- sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` -- ;; -- cygwin*) -- # Convert to unix form, then to dos form, then back to unix form -- # but this time dos style (no spaces!) so that the unix form looks -- # like /cygdrive/c/PROGRA~1:/cygdr... -- sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` -- sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` -- sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` -- ;; -- *) -- sys_lib_search_path_spec="$LIB" -- if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then -- # It is most probably a Windows format PATH. -- sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` -- else -- sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` -- fi -- # FIXME: find the short name or the path components, as spaces are -- # common. (e.g. "Program Files" -> "PROGRA~1") -- ;; -- esac -- -- # DLL is installed to $(libdir)/../bin by postinstall_cmds -- postinstall_cmds='base_file=`basename \${file}`~ -- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ -- dldir=$destdir/`dirname \$dlpath`~ -- test -d \$dldir || mkdir -p \$dldir~ -- $install_prog $dir/$dlname \$dldir/$dlname' -- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ -- dlpath=$dir/\$dldll~ -- $RM \$dlpath' -- shlibpath_overrides_runpath=yes -- dynamic_linker='Win32 link.exe' -- ;; -- -- *) -- # Assume MSVC wrapper -- library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' -- dynamic_linker='Win32 ld.exe' -- ;; -- esac -- # FIXME: first we should search . and the directory the executable is in -- shlibpath_var=PATH -- ;; -- --darwin* | rhapsody*) -- dynamic_linker="$host_os dyld" -- version_type=darwin -- need_lib_prefix=no -- need_version=no -- library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' -- soname_spec='${libname}${release}${major}$shared_ext' -- shlibpath_overrides_runpath=yes -- shlibpath_var=DYLD_LIBRARY_PATH -- shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' -- -- sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' -- ;; -- --dgux*) -- version_type=linux -- need_lib_prefix=no -- need_version=no -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' -- soname_spec='${libname}${release}${shared_ext}$major' -- shlibpath_var=LD_LIBRARY_PATH -- ;; -- --freebsd1*) -- dynamic_linker=no -- ;; -- --freebsd* | dragonfly*) -- # DragonFly does not have aout. When/if they implement a new -- # versioning mechanism, adjust this. -- if test -x /usr/bin/objformat; then -- objformat=`/usr/bin/objformat` -- else -- case $host_os in -- freebsd[123]*) objformat=aout ;; -- *) objformat=elf ;; -- esac -- fi -- version_type=freebsd-$objformat -- case $version_type in -- freebsd-elf*) -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' -- need_version=no -- need_lib_prefix=no -- ;; -- freebsd-*) -- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' -- need_version=yes -- ;; -- esac -- shlibpath_var=LD_LIBRARY_PATH -- case $host_os in -- freebsd2*) -- shlibpath_overrides_runpath=yes -- ;; -- freebsd3.[01]* | freebsdelf3.[01]*) -- shlibpath_overrides_runpath=yes -- hardcode_into_libs=yes -- ;; -- freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ -- freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) -- shlibpath_overrides_runpath=no -- hardcode_into_libs=yes -- ;; -- *) # from 4.6 on, and DragonFly -- shlibpath_overrides_runpath=yes -- hardcode_into_libs=yes -- ;; -- esac -- ;; -- --gnu*) -- version_type=linux -- need_lib_prefix=no -- need_version=no -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' -- soname_spec='${libname}${release}${shared_ext}$major' -- shlibpath_var=LD_LIBRARY_PATH -- hardcode_into_libs=yes -- ;; -- --haiku*) -- version_type=linux -- need_lib_prefix=no -- need_version=no -- dynamic_linker="$host_os runtime_loader" -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' -- soname_spec='${libname}${release}${shared_ext}$major' -- shlibpath_var=LIBRARY_PATH -- shlibpath_overrides_runpath=yes -- sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' -- hardcode_into_libs=yes -- ;; -- --hpux9* | hpux10* | hpux11*) -- # Give a soname corresponding to the major version so that dld.sl refuses to -- # link against other versions. -- version_type=sunos -- need_lib_prefix=no -- need_version=no -- case $host_cpu in -- ia64*) -- shrext_cmds='.so' -- hardcode_into_libs=yes -- dynamic_linker="$host_os dld.so" -- shlibpath_var=LD_LIBRARY_PATH -- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' -- soname_spec='${libname}${release}${shared_ext}$major' -- if test "X$HPUX_IA64_MODE" = X32; then -- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" -- else -- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" -- fi -- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec -- ;; -- hppa*64*) -- shrext_cmds='.sl' -- hardcode_into_libs=yes -- dynamic_linker="$host_os dld.sl" -- shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH -- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' -- soname_spec='${libname}${release}${shared_ext}$major' -- sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" -- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec -- ;; -- *) -- shrext_cmds='.sl' -- dynamic_linker="$host_os dld.sl" -- shlibpath_var=SHLIB_PATH -- shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' -- soname_spec='${libname}${release}${shared_ext}$major' -- ;; -- esac -- # HP-UX runs *really* slowly unless shared libraries are mode 555, ... -- postinstall_cmds='chmod 555 $lib' -- # or fails outright, so override atomically: -- install_override_mode=555 -- ;; -- --interix[3-9]*) -- version_type=linux -- need_lib_prefix=no -- need_version=no -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' -- soname_spec='${libname}${release}${shared_ext}$major' -- dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' -- shlibpath_var=LD_LIBRARY_PATH -- shlibpath_overrides_runpath=no -- hardcode_into_libs=yes -- ;; -- --irix5* | irix6* | nonstopux*) -- case $host_os in -- nonstopux*) version_type=nonstopux ;; -- *) -- if test "$lt_cv_prog_gnu_ld" = yes; then -- version_type=linux -- else -- version_type=irix -- fi ;; -- esac -- need_lib_prefix=no -- need_version=no -- soname_spec='${libname}${release}${shared_ext}$major' -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' -- case $host_os in -- irix5* | nonstopux*) -- libsuff= shlibsuff= -- ;; -- *) -- case $LD in # libtool.m4 will add one of these switches to LD -- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") -- libsuff= shlibsuff= libmagic=32-bit;; -- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") -- libsuff=32 shlibsuff=N32 libmagic=N32;; -- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") -- libsuff=64 shlibsuff=64 libmagic=64-bit;; -- *) libsuff= shlibsuff= libmagic=never-match;; -- esac -- ;; -- esac -- shlibpath_var=LD_LIBRARY${shlibsuff}_PATH -- shlibpath_overrides_runpath=no -- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" -- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" -- hardcode_into_libs=yes -- ;; -- --# No shared lib support for Linux oldld, aout, or coff. --linux*oldld* | linux*aout* | linux*coff*) -- dynamic_linker=no -- ;; -- --# This must be Linux ELF. --linux* | k*bsd*-gnu | kopensolaris*-gnu) -- version_type=linux -- need_lib_prefix=no -- need_version=no -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' -- soname_spec='${libname}${release}${shared_ext}$major' -- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' -- shlibpath_var=LD_LIBRARY_PATH -- shlibpath_overrides_runpath=no -- -- # Some binutils ld are patched to set DT_RUNPATH -- if ${lt_cv_shlibpath_overrides_runpath+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- lt_cv_shlibpath_overrides_runpath=no -- save_LDFLAGS=$LDFLAGS -- save_libdir=$libdir -- eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_F77\"; \ -- LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_F77\"" -- cat > conftest.$ac_ext <<_ACEOF -- program main -- -- end --_ACEOF --if ac_fn_f77_try_link "$LINENO"; then : -- if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : -- lt_cv_shlibpath_overrides_runpath=yes --fi --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext -- LDFLAGS=$save_LDFLAGS -- libdir=$save_libdir -- --fi -- -- shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath -- -- # This implies no fast_install, which is unacceptable. -- # Some rework will be needed to allow for fast_install -- # before this can be enabled. -- hardcode_into_libs=yes -- -- # Add ABI-specific directories to the system library path. -- sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" -- -- # Append ld.so.conf contents to the search path -- if test -f /etc/ld.so.conf; then -- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` -- sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" -- -- fi -- -- # We used to test for /lib/ld.so.1 and disable shared libraries on -- # powerpc, because MkLinux only supported shared libraries with the -- # GNU dynamic linker. Since this was broken with cross compilers, -- # most powerpc-linux boxes support dynamic linking these days and -- # people can always --disable-shared, the test was removed, and we -- # assume the GNU/Linux dynamic linker is in use. -- dynamic_linker='GNU/Linux ld.so' -- ;; -- --netbsd*) -- version_type=sunos -- need_lib_prefix=no -- need_version=no -- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' -- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' -- dynamic_linker='NetBSD (a.out) ld.so' -- else -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' -- soname_spec='${libname}${release}${shared_ext}$major' -- dynamic_linker='NetBSD ld.elf_so' -- fi -- shlibpath_var=LD_LIBRARY_PATH -- shlibpath_overrides_runpath=yes -- hardcode_into_libs=yes -- ;; -- --newsos6) -- version_type=linux -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' -- shlibpath_var=LD_LIBRARY_PATH -- shlibpath_overrides_runpath=yes -- ;; -- --*nto* | *qnx*) -- version_type=qnx -- need_lib_prefix=no -- need_version=no -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' -- soname_spec='${libname}${release}${shared_ext}$major' -- shlibpath_var=LD_LIBRARY_PATH -- shlibpath_overrides_runpath=no -- hardcode_into_libs=yes -- dynamic_linker='ldqnx.so' -- ;; -- --openbsd*) -- version_type=sunos -- sys_lib_dlsearch_path_spec="/usr/lib" -- need_lib_prefix=no -- # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. -- case $host_os in -- openbsd3.3 | openbsd3.3.*) need_version=yes ;; -- *) need_version=no ;; -- esac -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' -- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' -- shlibpath_var=LD_LIBRARY_PATH -- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then -- case $host_os in -- openbsd2.[89] | openbsd2.[89].*) -- shlibpath_overrides_runpath=no -- ;; -- *) -- shlibpath_overrides_runpath=yes -- ;; -- esac -- else -- shlibpath_overrides_runpath=yes -- fi -- ;; -- --os2*) -- libname_spec='$name' -- shrext_cmds=".dll" -- need_lib_prefix=no -- library_names_spec='$libname${shared_ext} $libname.a' -- dynamic_linker='OS/2 ld.exe' -- shlibpath_var=LIBPATH -- ;; -- --osf3* | osf4* | osf5*) -- version_type=osf -- need_lib_prefix=no -- need_version=no -- soname_spec='${libname}${release}${shared_ext}$major' -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' -- shlibpath_var=LD_LIBRARY_PATH -- sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" -- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" -- ;; -- --rdos*) -- dynamic_linker=no -- ;; -- --solaris*) -- version_type=linux -- need_lib_prefix=no -- need_version=no -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' -- soname_spec='${libname}${release}${shared_ext}$major' -- shlibpath_var=LD_LIBRARY_PATH -- shlibpath_overrides_runpath=yes -- hardcode_into_libs=yes -- # ldd complains unless libraries are executable -- postinstall_cmds='chmod +x $lib' -- ;; -- --sunos4*) -- version_type=sunos -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' -- finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' -- shlibpath_var=LD_LIBRARY_PATH -- shlibpath_overrides_runpath=yes -- if test "$with_gnu_ld" = yes; then -- need_lib_prefix=no -- fi -- need_version=yes -- ;; -- --sysv4 | sysv4.3*) -- version_type=linux -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' -- soname_spec='${libname}${release}${shared_ext}$major' -- shlibpath_var=LD_LIBRARY_PATH -- case $host_vendor in -- sni) -- shlibpath_overrides_runpath=no -- need_lib_prefix=no -- runpath_var=LD_RUN_PATH -- ;; -- siemens) -- need_lib_prefix=no -- ;; -- motorola) -- need_lib_prefix=no -- need_version=no -- shlibpath_overrides_runpath=no -- sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' -- ;; -- esac -- ;; -- --sysv4*MP*) -- if test -d /usr/nec ;then -- version_type=linux -- library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' -- soname_spec='$libname${shared_ext}.$major' -- shlibpath_var=LD_LIBRARY_PATH -- fi -- ;; -- --sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) -- version_type=freebsd-elf -- need_lib_prefix=no -- need_version=no -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' -- soname_spec='${libname}${release}${shared_ext}$major' -- shlibpath_var=LD_LIBRARY_PATH -- shlibpath_overrides_runpath=yes -- hardcode_into_libs=yes -- if test "$with_gnu_ld" = yes; then -- sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' -- else -- sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' -- case $host_os in -- sco3.2v5*) -- sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" -- ;; -- esac -- fi -- sys_lib_dlsearch_path_spec='/usr/lib' -- ;; -- --tpf*) -- # TPF is a cross-target only. Preferred cross-host = GNU/Linux. -- version_type=linux -- need_lib_prefix=no -- need_version=no -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' -- shlibpath_var=LD_LIBRARY_PATH -- shlibpath_overrides_runpath=no -- hardcode_into_libs=yes -- ;; -- --uts4*) -- version_type=linux -- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' -- soname_spec='${libname}${release}${shared_ext}$major' -- shlibpath_var=LD_LIBRARY_PATH -- ;; -- --*) -- dynamic_linker=no -- ;; --esac --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 --$as_echo "$dynamic_linker" >&6; } --test "$dynamic_linker" = no && can_build_shared=no -- --variables_saved_for_relink="PATH $shlibpath_var $runpath_var" --if test "$GCC" = yes; then -- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" --fi -- --if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then -- sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" --fi --if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then -- sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" --fi -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 --$as_echo_n "checking how to hardcode library paths into programs... " >&6; } --hardcode_action_F77= --if test -n "$hardcode_libdir_flag_spec_F77" || -- test -n "$runpath_var_F77" || -- test "X$hardcode_automatic_F77" = "Xyes" ; then -- -- # We can hardcode non-existent directories. -- if test "$hardcode_direct_F77" != no && -- # If the only mechanism to avoid hardcoding is shlibpath_var, we -- # have to relink, otherwise we might link with an installed library -- # when we should be linking with a yet-to-be-installed one -- ## test "$_LT_TAGVAR(hardcode_shlibpath_var, F77)" != no && -- test "$hardcode_minus_L_F77" != no; then -- # Linking always hardcodes the temporary library directory. -- hardcode_action_F77=relink -- else -- # We can link without hardcoding, and we can hardcode nonexisting dirs. -- hardcode_action_F77=immediate -- fi --else -- # We cannot hardcode anything, or else we can only hardcode existing -- # directories. -- hardcode_action_F77=unsupported --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_F77" >&5 --$as_echo "$hardcode_action_F77" >&6; } -- --if test "$hardcode_action_F77" = relink || -- test "$inherit_rpath_F77" = yes; then -- # Fast installation is not supported -- enable_fast_install=no --elif test "$shlibpath_overrides_runpath" = yes || -- test "$enable_shared" = no; then -- # Fast installation is not necessary -- enable_fast_install=needless --fi -- -- -- -- -- -- -- -- fi # test -n "$compiler" -- -- GCC=$lt_save_GCC -- CC="$lt_save_CC" -- CFLAGS="$lt_save_CFLAGS" --fi # test "$_lt_disable_F77" != yes -- --ac_ext=c --ac_cpp='$CPP $CPPFLAGS' --ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' --ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' --ac_compiler_gnu=$ac_cv_c_compiler_gnu -- - - - -@@ -29343,103 +26677,54 @@ - postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' - compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' - LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' --LD_F77='`$ECHO "$LD_F77" | $SED "$delay_single_quote_subst"`' - reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' --reload_flag_F77='`$ECHO "$reload_flag_F77" | $SED "$delay_single_quote_subst"`' - reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' --reload_cmds_F77='`$ECHO "$reload_cmds_F77" | $SED "$delay_single_quote_subst"`' - old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' --old_archive_cmds_F77='`$ECHO "$old_archive_cmds_F77" | $SED "$delay_single_quote_subst"`' - compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' --compiler_F77='`$ECHO "$compiler_F77" | $SED "$delay_single_quote_subst"`' - GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' --GCC_F77='`$ECHO "$GCC_F77" | $SED "$delay_single_quote_subst"`' - lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' --lt_prog_compiler_no_builtin_flag_F77='`$ECHO "$lt_prog_compiler_no_builtin_flag_F77" | $SED "$delay_single_quote_subst"`' - lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' --lt_prog_compiler_pic_F77='`$ECHO "$lt_prog_compiler_pic_F77" | $SED "$delay_single_quote_subst"`' - lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' --lt_prog_compiler_wl_F77='`$ECHO "$lt_prog_compiler_wl_F77" | $SED "$delay_single_quote_subst"`' - lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' --lt_prog_compiler_static_F77='`$ECHO "$lt_prog_compiler_static_F77" | $SED "$delay_single_quote_subst"`' - lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' --lt_cv_prog_compiler_c_o_F77='`$ECHO "$lt_cv_prog_compiler_c_o_F77" | $SED "$delay_single_quote_subst"`' - archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' --archive_cmds_need_lc_F77='`$ECHO "$archive_cmds_need_lc_F77" | $SED "$delay_single_quote_subst"`' - enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' --enable_shared_with_static_runtimes_F77='`$ECHO "$enable_shared_with_static_runtimes_F77" | $SED "$delay_single_quote_subst"`' - export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' --export_dynamic_flag_spec_F77='`$ECHO "$export_dynamic_flag_spec_F77" | $SED "$delay_single_quote_subst"`' - whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' --whole_archive_flag_spec_F77='`$ECHO "$whole_archive_flag_spec_F77" | $SED "$delay_single_quote_subst"`' - compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' --compiler_needs_object_F77='`$ECHO "$compiler_needs_object_F77" | $SED "$delay_single_quote_subst"`' - old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' --old_archive_from_new_cmds_F77='`$ECHO "$old_archive_from_new_cmds_F77" | $SED "$delay_single_quote_subst"`' - old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' --old_archive_from_expsyms_cmds_F77='`$ECHO "$old_archive_from_expsyms_cmds_F77" | $SED "$delay_single_quote_subst"`' - archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' --archive_cmds_F77='`$ECHO "$archive_cmds_F77" | $SED "$delay_single_quote_subst"`' - archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' --archive_expsym_cmds_F77='`$ECHO "$archive_expsym_cmds_F77" | $SED "$delay_single_quote_subst"`' - module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' --module_cmds_F77='`$ECHO "$module_cmds_F77" | $SED "$delay_single_quote_subst"`' - module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' --module_expsym_cmds_F77='`$ECHO "$module_expsym_cmds_F77" | $SED "$delay_single_quote_subst"`' - with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' --with_gnu_ld_F77='`$ECHO "$with_gnu_ld_F77" | $SED "$delay_single_quote_subst"`' - allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' --allow_undefined_flag_F77='`$ECHO "$allow_undefined_flag_F77" | $SED "$delay_single_quote_subst"`' - no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' --no_undefined_flag_F77='`$ECHO "$no_undefined_flag_F77" | $SED "$delay_single_quote_subst"`' - hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_libdir_flag_spec_F77='`$ECHO "$hardcode_libdir_flag_spec_F77" | $SED "$delay_single_quote_subst"`' - hardcode_libdir_flag_spec_ld_CXX='`$ECHO "$hardcode_libdir_flag_spec_ld_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_libdir_flag_spec_ld_F77='`$ECHO "$hardcode_libdir_flag_spec_ld_F77" | $SED "$delay_single_quote_subst"`' - hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_libdir_separator_F77='`$ECHO "$hardcode_libdir_separator_F77" | $SED "$delay_single_quote_subst"`' - hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_direct_F77='`$ECHO "$hardcode_direct_F77" | $SED "$delay_single_quote_subst"`' - hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_direct_absolute_F77='`$ECHO "$hardcode_direct_absolute_F77" | $SED "$delay_single_quote_subst"`' - hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_minus_L_F77='`$ECHO "$hardcode_minus_L_F77" | $SED "$delay_single_quote_subst"`' - hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_shlibpath_var_F77='`$ECHO "$hardcode_shlibpath_var_F77" | $SED "$delay_single_quote_subst"`' - hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_automatic_F77='`$ECHO "$hardcode_automatic_F77" | $SED "$delay_single_quote_subst"`' - inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' --inherit_rpath_F77='`$ECHO "$inherit_rpath_F77" | $SED "$delay_single_quote_subst"`' - link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' --link_all_deplibs_F77='`$ECHO "$link_all_deplibs_F77" | $SED "$delay_single_quote_subst"`' - always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' --always_export_symbols_F77='`$ECHO "$always_export_symbols_F77" | $SED "$delay_single_quote_subst"`' - export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' --export_symbols_cmds_F77='`$ECHO "$export_symbols_cmds_F77" | $SED "$delay_single_quote_subst"`' - exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' --exclude_expsyms_F77='`$ECHO "$exclude_expsyms_F77" | $SED "$delay_single_quote_subst"`' - include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' --include_expsyms_F77='`$ECHO "$include_expsyms_F77" | $SED "$delay_single_quote_subst"`' - prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' --prelink_cmds_F77='`$ECHO "$prelink_cmds_F77" | $SED "$delay_single_quote_subst"`' - postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' --postlink_cmds_F77='`$ECHO "$postlink_cmds_F77" | $SED "$delay_single_quote_subst"`' - file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' --file_list_spec_F77='`$ECHO "$file_list_spec_F77" | $SED "$delay_single_quote_subst"`' - hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_action_F77='`$ECHO "$hardcode_action_F77" | $SED "$delay_single_quote_subst"`' - compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' --compiler_lib_search_dirs_F77='`$ECHO "$compiler_lib_search_dirs_F77" | $SED "$delay_single_quote_subst"`' - predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' --predep_objects_F77='`$ECHO "$predep_objects_F77" | $SED "$delay_single_quote_subst"`' - postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' --postdep_objects_F77='`$ECHO "$postdep_objects_F77" | $SED "$delay_single_quote_subst"`' - predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' --predeps_F77='`$ECHO "$predeps_F77" | $SED "$delay_single_quote_subst"`' - postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' --postdeps_F77='`$ECHO "$postdeps_F77" | $SED "$delay_single_quote_subst"`' - compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' --compiler_lib_search_path_F77='`$ECHO "$compiler_lib_search_path_F77" | $SED "$delay_single_quote_subst"`' - - LTCC='$LTCC' - LTCFLAGS='$LTCFLAGS' -@@ -29527,57 +26812,31 @@ - postdeps \ - compiler_lib_search_path \ - LD_CXX \ --LD_F77 \ - reload_flag_CXX \ --reload_flag_F77 \ - compiler_CXX \ --compiler_F77 \ - lt_prog_compiler_no_builtin_flag_CXX \ --lt_prog_compiler_no_builtin_flag_F77 \ - lt_prog_compiler_pic_CXX \ --lt_prog_compiler_pic_F77 \ - lt_prog_compiler_wl_CXX \ --lt_prog_compiler_wl_F77 \ - lt_prog_compiler_static_CXX \ --lt_prog_compiler_static_F77 \ - lt_cv_prog_compiler_c_o_CXX \ --lt_cv_prog_compiler_c_o_F77 \ - export_dynamic_flag_spec_CXX \ --export_dynamic_flag_spec_F77 \ - whole_archive_flag_spec_CXX \ --whole_archive_flag_spec_F77 \ - compiler_needs_object_CXX \ --compiler_needs_object_F77 \ - with_gnu_ld_CXX \ --with_gnu_ld_F77 \ - allow_undefined_flag_CXX \ --allow_undefined_flag_F77 \ - no_undefined_flag_CXX \ --no_undefined_flag_F77 \ - hardcode_libdir_flag_spec_CXX \ --hardcode_libdir_flag_spec_F77 \ - hardcode_libdir_flag_spec_ld_CXX \ --hardcode_libdir_flag_spec_ld_F77 \ - hardcode_libdir_separator_CXX \ --hardcode_libdir_separator_F77 \ - exclude_expsyms_CXX \ --exclude_expsyms_F77 \ - include_expsyms_CXX \ --include_expsyms_F77 \ - file_list_spec_CXX \ --file_list_spec_F77 \ - compiler_lib_search_dirs_CXX \ --compiler_lib_search_dirs_F77 \ - predep_objects_CXX \ --predep_objects_F77 \ - postdep_objects_CXX \ --postdep_objects_F77 \ - predeps_CXX \ --predeps_F77 \ - postdeps_CXX \ --postdeps_F77 \ --compiler_lib_search_path_CXX \ --compiler_lib_search_path_F77; do -+compiler_lib_search_path_CXX; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" -@@ -29609,27 +26868,16 @@ - sys_lib_search_path_spec \ - sys_lib_dlsearch_path_spec \ - reload_cmds_CXX \ --reload_cmds_F77 \ - old_archive_cmds_CXX \ --old_archive_cmds_F77 \ - old_archive_from_new_cmds_CXX \ --old_archive_from_new_cmds_F77 \ - old_archive_from_expsyms_cmds_CXX \ --old_archive_from_expsyms_cmds_F77 \ - archive_cmds_CXX \ --archive_cmds_F77 \ - archive_expsym_cmds_CXX \ --archive_expsym_cmds_F77 \ - module_cmds_CXX \ --module_cmds_F77 \ - module_expsym_cmds_CXX \ --module_expsym_cmds_F77 \ - export_symbols_cmds_CXX \ --export_symbols_cmds_F77 \ - prelink_cmds_CXX \ --prelink_cmds_F77 \ --postlink_cmds_CXX \ --postlink_cmds_F77; do -+postlink_cmds_CXX; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" -@@ -29662,8 +26910,6 @@ - - - -- -- - _ACEOF - - cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -@@ -30377,7 +27623,7 @@ - - - # The names of the tagged configurations supported by this script. --available_tags="CXX F77 " -+available_tags="CXX " - - # ### BEGIN LIBTOOL CONFIG - -@@ -31131,163 +28377,6 @@ - # ### END LIBTOOL TAG CONFIG: CXX - _LT_EOF - -- -- cat <<_LT_EOF >> "$ofile" -- --# ### BEGIN LIBTOOL TAG CONFIG: F77 -- --# The linker used to build libraries. --LD=$lt_LD_F77 -- --# How to create reloadable object files. --reload_flag=$lt_reload_flag_F77 --reload_cmds=$lt_reload_cmds_F77 -- --# Commands used to build an old-style archive. --old_archive_cmds=$lt_old_archive_cmds_F77 -- --# A language specific compiler. --CC=$lt_compiler_F77 -- --# Is the compiler the GNU compiler? --with_gcc=$GCC_F77 -- --# Compiler flag to turn off builtin functions. --no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77 -- --# Additional compiler flags for building library objects. --pic_flag=$lt_lt_prog_compiler_pic_F77 -- --# How to pass a linker flag through the compiler. --wl=$lt_lt_prog_compiler_wl_F77 -- --# Compiler flag to prevent dynamic linking. --link_static_flag=$lt_lt_prog_compiler_static_F77 -- --# Does compiler simultaneously support -c and -o options? --compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77 -- --# Whether or not to add -lc for building shared libraries. --build_libtool_need_lc=$archive_cmds_need_lc_F77 -- --# Whether or not to disallow shared libs when runtime libs are static. --allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77 -- --# Compiler flag to allow reflexive dlopens. --export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77 -- --# Compiler flag to generate shared objects directly from archives. --whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77 -- --# Whether the compiler copes with passing no objects directly. --compiler_needs_object=$lt_compiler_needs_object_F77 -- --# Create an old-style archive from a shared archive. --old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77 -- --# Create a temporary old-style archive to link instead of a shared archive. --old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77 -- --# Commands used to build a shared archive. --archive_cmds=$lt_archive_cmds_F77 --archive_expsym_cmds=$lt_archive_expsym_cmds_F77 -- --# Commands used to build a loadable module if different from building --# a shared archive. --module_cmds=$lt_module_cmds_F77 --module_expsym_cmds=$lt_module_expsym_cmds_F77 -- --# Whether we are building with GNU ld or not. --with_gnu_ld=$lt_with_gnu_ld_F77 -- --# Flag that allows shared libraries with undefined symbols to be built. --allow_undefined_flag=$lt_allow_undefined_flag_F77 -- --# Flag that enforces no undefined symbols. --no_undefined_flag=$lt_no_undefined_flag_F77 -- --# Flag to hardcode \$libdir into a binary during linking. --# This must work even if \$libdir does not exist --hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77 -- --# If ld is used when linking, flag to hardcode \$libdir into a binary --# during linking. This must work even if \$libdir does not exist. --hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77 -- --# Whether we need a single "-rpath" flag with a separated argument. --hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77 -- --# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes --# DIR into the resulting binary. --hardcode_direct=$hardcode_direct_F77 -- --# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes --# DIR into the resulting binary and the resulting library dependency is --# "absolute",i.e impossible to change by setting \${shlibpath_var} if the --# library is relocated. --hardcode_direct_absolute=$hardcode_direct_absolute_F77 -- --# Set to "yes" if using the -LDIR flag during linking hardcodes DIR --# into the resulting binary. --hardcode_minus_L=$hardcode_minus_L_F77 -- --# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR --# into the resulting binary. --hardcode_shlibpath_var=$hardcode_shlibpath_var_F77 -- --# Set to "yes" if building a shared library automatically hardcodes DIR --# into the library and all subsequent libraries and executables linked --# against it. --hardcode_automatic=$hardcode_automatic_F77 -- --# Set to yes if linker adds runtime paths of dependent libraries --# to runtime path list. --inherit_rpath=$inherit_rpath_F77 -- --# Whether libtool must link a program against all its dependency libraries. --link_all_deplibs=$link_all_deplibs_F77 -- --# Set to "yes" if exported symbols are required. --always_export_symbols=$always_export_symbols_F77 -- --# The commands to list exported symbols. --export_symbols_cmds=$lt_export_symbols_cmds_F77 -- --# Symbols that should not be listed in the preloaded symbols. --exclude_expsyms=$lt_exclude_expsyms_F77 -- --# Symbols that must always be exported. --include_expsyms=$lt_include_expsyms_F77 -- --# Commands necessary for linking programs (against libraries) with templates. --prelink_cmds=$lt_prelink_cmds_F77 -- --# Commands necessary for finishing linking programs. --postlink_cmds=$lt_postlink_cmds_F77 -- --# Specify filename containing input files. --file_list_spec=$lt_file_list_spec_F77 -- --# How to hardcode a shared library path into an executable. --hardcode_action=$hardcode_action_F77 -- --# The directories searched by this compiler when creating a shared library. --compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_F77 -- --# Dependencies to place before and after the objects being linked to --# create a shared library. --predep_objects=$lt_predep_objects_F77 --postdep_objects=$lt_postdep_objects_F77 --predeps=$lt_predeps_F77 --postdeps=$lt_postdeps_F77 -- --# The library search path used internally by the compiler when linking --# a shared library. --compiler_lib_search_path=$lt_compiler_lib_search_path_F77 -- --# ### END LIBTOOL TAG CONFIG: F77 --_LT_EOF -- - ;; - - esac -@@ -32366,103 +29455,54 @@ - postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' - compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' - LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' --LD_F77='`$ECHO "$LD_F77" | $SED "$delay_single_quote_subst"`' - reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' --reload_flag_F77='`$ECHO "$reload_flag_F77" | $SED "$delay_single_quote_subst"`' - reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' --reload_cmds_F77='`$ECHO "$reload_cmds_F77" | $SED "$delay_single_quote_subst"`' - old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' --old_archive_cmds_F77='`$ECHO "$old_archive_cmds_F77" | $SED "$delay_single_quote_subst"`' - compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' --compiler_F77='`$ECHO "$compiler_F77" | $SED "$delay_single_quote_subst"`' - GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' --GCC_F77='`$ECHO "$GCC_F77" | $SED "$delay_single_quote_subst"`' - lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' --lt_prog_compiler_no_builtin_flag_F77='`$ECHO "$lt_prog_compiler_no_builtin_flag_F77" | $SED "$delay_single_quote_subst"`' - lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' --lt_prog_compiler_pic_F77='`$ECHO "$lt_prog_compiler_pic_F77" | $SED "$delay_single_quote_subst"`' - lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' --lt_prog_compiler_wl_F77='`$ECHO "$lt_prog_compiler_wl_F77" | $SED "$delay_single_quote_subst"`' - lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' --lt_prog_compiler_static_F77='`$ECHO "$lt_prog_compiler_static_F77" | $SED "$delay_single_quote_subst"`' - lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' --lt_cv_prog_compiler_c_o_F77='`$ECHO "$lt_cv_prog_compiler_c_o_F77" | $SED "$delay_single_quote_subst"`' - archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' --archive_cmds_need_lc_F77='`$ECHO "$archive_cmds_need_lc_F77" | $SED "$delay_single_quote_subst"`' - enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' --enable_shared_with_static_runtimes_F77='`$ECHO "$enable_shared_with_static_runtimes_F77" | $SED "$delay_single_quote_subst"`' - export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' --export_dynamic_flag_spec_F77='`$ECHO "$export_dynamic_flag_spec_F77" | $SED "$delay_single_quote_subst"`' - whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' --whole_archive_flag_spec_F77='`$ECHO "$whole_archive_flag_spec_F77" | $SED "$delay_single_quote_subst"`' - compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' --compiler_needs_object_F77='`$ECHO "$compiler_needs_object_F77" | $SED "$delay_single_quote_subst"`' - old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' --old_archive_from_new_cmds_F77='`$ECHO "$old_archive_from_new_cmds_F77" | $SED "$delay_single_quote_subst"`' - old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' --old_archive_from_expsyms_cmds_F77='`$ECHO "$old_archive_from_expsyms_cmds_F77" | $SED "$delay_single_quote_subst"`' - archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' --archive_cmds_F77='`$ECHO "$archive_cmds_F77" | $SED "$delay_single_quote_subst"`' - archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' --archive_expsym_cmds_F77='`$ECHO "$archive_expsym_cmds_F77" | $SED "$delay_single_quote_subst"`' - module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' --module_cmds_F77='`$ECHO "$module_cmds_F77" | $SED "$delay_single_quote_subst"`' - module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' --module_expsym_cmds_F77='`$ECHO "$module_expsym_cmds_F77" | $SED "$delay_single_quote_subst"`' - with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' --with_gnu_ld_F77='`$ECHO "$with_gnu_ld_F77" | $SED "$delay_single_quote_subst"`' - allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' --allow_undefined_flag_F77='`$ECHO "$allow_undefined_flag_F77" | $SED "$delay_single_quote_subst"`' - no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' --no_undefined_flag_F77='`$ECHO "$no_undefined_flag_F77" | $SED "$delay_single_quote_subst"`' - hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_libdir_flag_spec_F77='`$ECHO "$hardcode_libdir_flag_spec_F77" | $SED "$delay_single_quote_subst"`' - hardcode_libdir_flag_spec_ld_CXX='`$ECHO "$hardcode_libdir_flag_spec_ld_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_libdir_flag_spec_ld_F77='`$ECHO "$hardcode_libdir_flag_spec_ld_F77" | $SED "$delay_single_quote_subst"`' - hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_libdir_separator_F77='`$ECHO "$hardcode_libdir_separator_F77" | $SED "$delay_single_quote_subst"`' - hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_direct_F77='`$ECHO "$hardcode_direct_F77" | $SED "$delay_single_quote_subst"`' - hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_direct_absolute_F77='`$ECHO "$hardcode_direct_absolute_F77" | $SED "$delay_single_quote_subst"`' - hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_minus_L_F77='`$ECHO "$hardcode_minus_L_F77" | $SED "$delay_single_quote_subst"`' - hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_shlibpath_var_F77='`$ECHO "$hardcode_shlibpath_var_F77" | $SED "$delay_single_quote_subst"`' - hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_automatic_F77='`$ECHO "$hardcode_automatic_F77" | $SED "$delay_single_quote_subst"`' - inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' --inherit_rpath_F77='`$ECHO "$inherit_rpath_F77" | $SED "$delay_single_quote_subst"`' - link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' --link_all_deplibs_F77='`$ECHO "$link_all_deplibs_F77" | $SED "$delay_single_quote_subst"`' - always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' --always_export_symbols_F77='`$ECHO "$always_export_symbols_F77" | $SED "$delay_single_quote_subst"`' - export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' --export_symbols_cmds_F77='`$ECHO "$export_symbols_cmds_F77" | $SED "$delay_single_quote_subst"`' - exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' --exclude_expsyms_F77='`$ECHO "$exclude_expsyms_F77" | $SED "$delay_single_quote_subst"`' - include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' --include_expsyms_F77='`$ECHO "$include_expsyms_F77" | $SED "$delay_single_quote_subst"`' - prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' --prelink_cmds_F77='`$ECHO "$prelink_cmds_F77" | $SED "$delay_single_quote_subst"`' - postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' --postlink_cmds_F77='`$ECHO "$postlink_cmds_F77" | $SED "$delay_single_quote_subst"`' - file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' --file_list_spec_F77='`$ECHO "$file_list_spec_F77" | $SED "$delay_single_quote_subst"`' - hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_action_F77='`$ECHO "$hardcode_action_F77" | $SED "$delay_single_quote_subst"`' - compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' --compiler_lib_search_dirs_F77='`$ECHO "$compiler_lib_search_dirs_F77" | $SED "$delay_single_quote_subst"`' - predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' --predep_objects_F77='`$ECHO "$predep_objects_F77" | $SED "$delay_single_quote_subst"`' - postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' --postdep_objects_F77='`$ECHO "$postdep_objects_F77" | $SED "$delay_single_quote_subst"`' - predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' --predeps_F77='`$ECHO "$predeps_F77" | $SED "$delay_single_quote_subst"`' - postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' --postdeps_F77='`$ECHO "$postdeps_F77" | $SED "$delay_single_quote_subst"`' - compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' --compiler_lib_search_path_F77='`$ECHO "$compiler_lib_search_path_F77" | $SED "$delay_single_quote_subst"`' - - LTCC='$LTCC' - LTCFLAGS='$LTCFLAGS' -@@ -32550,57 +29590,31 @@ - postdeps \ - compiler_lib_search_path \ - LD_CXX \ --LD_F77 \ - reload_flag_CXX \ --reload_flag_F77 \ - compiler_CXX \ --compiler_F77 \ - lt_prog_compiler_no_builtin_flag_CXX \ --lt_prog_compiler_no_builtin_flag_F77 \ - lt_prog_compiler_pic_CXX \ --lt_prog_compiler_pic_F77 \ - lt_prog_compiler_wl_CXX \ --lt_prog_compiler_wl_F77 \ - lt_prog_compiler_static_CXX \ --lt_prog_compiler_static_F77 \ - lt_cv_prog_compiler_c_o_CXX \ --lt_cv_prog_compiler_c_o_F77 \ - export_dynamic_flag_spec_CXX \ --export_dynamic_flag_spec_F77 \ - whole_archive_flag_spec_CXX \ --whole_archive_flag_spec_F77 \ - compiler_needs_object_CXX \ --compiler_needs_object_F77 \ - with_gnu_ld_CXX \ --with_gnu_ld_F77 \ - allow_undefined_flag_CXX \ --allow_undefined_flag_F77 \ - no_undefined_flag_CXX \ --no_undefined_flag_F77 \ - hardcode_libdir_flag_spec_CXX \ --hardcode_libdir_flag_spec_F77 \ - hardcode_libdir_flag_spec_ld_CXX \ --hardcode_libdir_flag_spec_ld_F77 \ - hardcode_libdir_separator_CXX \ --hardcode_libdir_separator_F77 \ - exclude_expsyms_CXX \ --exclude_expsyms_F77 \ - include_expsyms_CXX \ --include_expsyms_F77 \ - file_list_spec_CXX \ --file_list_spec_F77 \ - compiler_lib_search_dirs_CXX \ --compiler_lib_search_dirs_F77 \ - predep_objects_CXX \ --predep_objects_F77 \ - postdep_objects_CXX \ --postdep_objects_F77 \ - predeps_CXX \ --predeps_F77 \ - postdeps_CXX \ --postdeps_F77 \ --compiler_lib_search_path_CXX \ --compiler_lib_search_path_F77; do -+compiler_lib_search_path_CXX; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" -@@ -32632,27 +29646,16 @@ - sys_lib_search_path_spec \ - sys_lib_dlsearch_path_spec \ - reload_cmds_CXX \ --reload_cmds_F77 \ - old_archive_cmds_CXX \ --old_archive_cmds_F77 \ - old_archive_from_new_cmds_CXX \ --old_archive_from_new_cmds_F77 \ - old_archive_from_expsyms_cmds_CXX \ --old_archive_from_expsyms_cmds_F77 \ - archive_cmds_CXX \ --archive_cmds_F77 \ - archive_expsym_cmds_CXX \ --archive_expsym_cmds_F77 \ - module_cmds_CXX \ --module_cmds_F77 \ - module_expsym_cmds_CXX \ --module_expsym_cmds_F77 \ - export_symbols_cmds_CXX \ --export_symbols_cmds_F77 \ - prelink_cmds_CXX \ --prelink_cmds_F77 \ --postlink_cmds_CXX \ --postlink_cmds_F77; do -+postlink_cmds_CXX; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" -@@ -32682,8 +29685,6 @@ - - - -- -- - ac_aux_dir='$ac_aux_dir' - - -@@ -33402,7 +30403,7 @@ - - - # The names of the tagged configurations supported by this script. --available_tags="CXX F77 " -+available_tags="CXX " - - # ### BEGIN LIBTOOL CONFIG - -@@ -34156,163 +31157,6 @@ - # ### END LIBTOOL TAG CONFIG: CXX - _LT_EOF - -- -- cat <<_LT_EOF >> "$ofile" -- --# ### BEGIN LIBTOOL TAG CONFIG: F77 -- --# The linker used to build libraries. --LD=$lt_LD_F77 -- --# How to create reloadable object files. --reload_flag=$lt_reload_flag_F77 --reload_cmds=$lt_reload_cmds_F77 -- --# Commands used to build an old-style archive. --old_archive_cmds=$lt_old_archive_cmds_F77 -- --# A language specific compiler. --CC=$lt_compiler_F77 -- --# Is the compiler the GNU compiler? --with_gcc=$GCC_F77 -- --# Compiler flag to turn off builtin functions. --no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77 -- --# Additional compiler flags for building library objects. --pic_flag=$lt_lt_prog_compiler_pic_F77 -- --# How to pass a linker flag through the compiler. --wl=$lt_lt_prog_compiler_wl_F77 -- --# Compiler flag to prevent dynamic linking. --link_static_flag=$lt_lt_prog_compiler_static_F77 -- --# Does compiler simultaneously support -c and -o options? --compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77 -- --# Whether or not to add -lc for building shared libraries. --build_libtool_need_lc=$archive_cmds_need_lc_F77 -- --# Whether or not to disallow shared libs when runtime libs are static. --allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77 -- --# Compiler flag to allow reflexive dlopens. --export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77 -- --# Compiler flag to generate shared objects directly from archives. --whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77 -- --# Whether the compiler copes with passing no objects directly. --compiler_needs_object=$lt_compiler_needs_object_F77 -- --# Create an old-style archive from a shared archive. --old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77 -- --# Create a temporary old-style archive to link instead of a shared archive. --old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77 -- --# Commands used to build a shared archive. --archive_cmds=$lt_archive_cmds_F77 --archive_expsym_cmds=$lt_archive_expsym_cmds_F77 -- --# Commands used to build a loadable module if different from building --# a shared archive. --module_cmds=$lt_module_cmds_F77 --module_expsym_cmds=$lt_module_expsym_cmds_F77 -- --# Whether we are building with GNU ld or not. --with_gnu_ld=$lt_with_gnu_ld_F77 -- --# Flag that allows shared libraries with undefined symbols to be built. --allow_undefined_flag=$lt_allow_undefined_flag_F77 -- --# Flag that enforces no undefined symbols. --no_undefined_flag=$lt_no_undefined_flag_F77 -- --# Flag to hardcode \$libdir into a binary during linking. --# This must work even if \$libdir does not exist --hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77 -- --# If ld is used when linking, flag to hardcode \$libdir into a binary --# during linking. This must work even if \$libdir does not exist. --hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77 -- --# Whether we need a single "-rpath" flag with a separated argument. --hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77 -- --# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes --# DIR into the resulting binary. --hardcode_direct=$hardcode_direct_F77 -- --# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes --# DIR into the resulting binary and the resulting library dependency is --# "absolute",i.e impossible to change by setting \${shlibpath_var} if the --# library is relocated. --hardcode_direct_absolute=$hardcode_direct_absolute_F77 -- --# Set to "yes" if using the -LDIR flag during linking hardcodes DIR --# into the resulting binary. --hardcode_minus_L=$hardcode_minus_L_F77 -- --# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR --# into the resulting binary. --hardcode_shlibpath_var=$hardcode_shlibpath_var_F77 -- --# Set to "yes" if building a shared library automatically hardcodes DIR --# into the library and all subsequent libraries and executables linked --# against it. --hardcode_automatic=$hardcode_automatic_F77 -- --# Set to yes if linker adds runtime paths of dependent libraries --# to runtime path list. --inherit_rpath=$inherit_rpath_F77 -- --# Whether libtool must link a program against all its dependency libraries. --link_all_deplibs=$link_all_deplibs_F77 -- --# Set to "yes" if exported symbols are required. --always_export_symbols=$always_export_symbols_F77 -- --# The commands to list exported symbols. --export_symbols_cmds=$lt_export_symbols_cmds_F77 -- --# Symbols that should not be listed in the preloaded symbols. --exclude_expsyms=$lt_exclude_expsyms_F77 -- --# Symbols that must always be exported. --include_expsyms=$lt_include_expsyms_F77 -- --# Commands necessary for linking programs (against libraries) with templates. --prelink_cmds=$lt_prelink_cmds_F77 -- --# Commands necessary for finishing linking programs. --postlink_cmds=$lt_postlink_cmds_F77 -- --# Specify filename containing input files. --file_list_spec=$lt_file_list_spec_F77 -- --# How to hardcode a shared library path into an executable. --hardcode_action=$hardcode_action_F77 -- --# The directories searched by this compiler when creating a shared library. --compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_F77 -- --# Dependencies to place before and after the objects being linked to --# create a shared library. --predep_objects=$lt_predep_objects_F77 --postdep_objects=$lt_postdep_objects_F77 --predeps=$lt_predeps_F77 --postdeps=$lt_postdeps_F77 -- --# The library search path used internally by the compiler when linking --# a shared library. --compiler_lib_search_path=$lt_compiler_lib_search_path_F77 -- --# ### END LIBTOOL TAG CONFIG: F77 --_LT_EOF -- - ;; - - esac -@@ -35395,103 +32239,54 @@ - postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' - compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' - LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' --LD_F77='`$ECHO "$LD_F77" | $SED "$delay_single_quote_subst"`' - reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' --reload_flag_F77='`$ECHO "$reload_flag_F77" | $SED "$delay_single_quote_subst"`' - reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' --reload_cmds_F77='`$ECHO "$reload_cmds_F77" | $SED "$delay_single_quote_subst"`' - old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' --old_archive_cmds_F77='`$ECHO "$old_archive_cmds_F77" | $SED "$delay_single_quote_subst"`' - compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' --compiler_F77='`$ECHO "$compiler_F77" | $SED "$delay_single_quote_subst"`' - GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' --GCC_F77='`$ECHO "$GCC_F77" | $SED "$delay_single_quote_subst"`' - lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' --lt_prog_compiler_no_builtin_flag_F77='`$ECHO "$lt_prog_compiler_no_builtin_flag_F77" | $SED "$delay_single_quote_subst"`' - lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' --lt_prog_compiler_pic_F77='`$ECHO "$lt_prog_compiler_pic_F77" | $SED "$delay_single_quote_subst"`' - lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' --lt_prog_compiler_wl_F77='`$ECHO "$lt_prog_compiler_wl_F77" | $SED "$delay_single_quote_subst"`' - lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' --lt_prog_compiler_static_F77='`$ECHO "$lt_prog_compiler_static_F77" | $SED "$delay_single_quote_subst"`' - lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' --lt_cv_prog_compiler_c_o_F77='`$ECHO "$lt_cv_prog_compiler_c_o_F77" | $SED "$delay_single_quote_subst"`' - archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' --archive_cmds_need_lc_F77='`$ECHO "$archive_cmds_need_lc_F77" | $SED "$delay_single_quote_subst"`' - enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' --enable_shared_with_static_runtimes_F77='`$ECHO "$enable_shared_with_static_runtimes_F77" | $SED "$delay_single_quote_subst"`' - export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' --export_dynamic_flag_spec_F77='`$ECHO "$export_dynamic_flag_spec_F77" | $SED "$delay_single_quote_subst"`' - whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' --whole_archive_flag_spec_F77='`$ECHO "$whole_archive_flag_spec_F77" | $SED "$delay_single_quote_subst"`' - compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' --compiler_needs_object_F77='`$ECHO "$compiler_needs_object_F77" | $SED "$delay_single_quote_subst"`' - old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' --old_archive_from_new_cmds_F77='`$ECHO "$old_archive_from_new_cmds_F77" | $SED "$delay_single_quote_subst"`' - old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' --old_archive_from_expsyms_cmds_F77='`$ECHO "$old_archive_from_expsyms_cmds_F77" | $SED "$delay_single_quote_subst"`' - archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' --archive_cmds_F77='`$ECHO "$archive_cmds_F77" | $SED "$delay_single_quote_subst"`' - archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' --archive_expsym_cmds_F77='`$ECHO "$archive_expsym_cmds_F77" | $SED "$delay_single_quote_subst"`' - module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' --module_cmds_F77='`$ECHO "$module_cmds_F77" | $SED "$delay_single_quote_subst"`' - module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' --module_expsym_cmds_F77='`$ECHO "$module_expsym_cmds_F77" | $SED "$delay_single_quote_subst"`' - with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' --with_gnu_ld_F77='`$ECHO "$with_gnu_ld_F77" | $SED "$delay_single_quote_subst"`' - allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' --allow_undefined_flag_F77='`$ECHO "$allow_undefined_flag_F77" | $SED "$delay_single_quote_subst"`' - no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' --no_undefined_flag_F77='`$ECHO "$no_undefined_flag_F77" | $SED "$delay_single_quote_subst"`' - hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_libdir_flag_spec_F77='`$ECHO "$hardcode_libdir_flag_spec_F77" | $SED "$delay_single_quote_subst"`' - hardcode_libdir_flag_spec_ld_CXX='`$ECHO "$hardcode_libdir_flag_spec_ld_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_libdir_flag_spec_ld_F77='`$ECHO "$hardcode_libdir_flag_spec_ld_F77" | $SED "$delay_single_quote_subst"`' - hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_libdir_separator_F77='`$ECHO "$hardcode_libdir_separator_F77" | $SED "$delay_single_quote_subst"`' - hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_direct_F77='`$ECHO "$hardcode_direct_F77" | $SED "$delay_single_quote_subst"`' - hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_direct_absolute_F77='`$ECHO "$hardcode_direct_absolute_F77" | $SED "$delay_single_quote_subst"`' - hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_minus_L_F77='`$ECHO "$hardcode_minus_L_F77" | $SED "$delay_single_quote_subst"`' - hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_shlibpath_var_F77='`$ECHO "$hardcode_shlibpath_var_F77" | $SED "$delay_single_quote_subst"`' - hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_automatic_F77='`$ECHO "$hardcode_automatic_F77" | $SED "$delay_single_quote_subst"`' - inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' --inherit_rpath_F77='`$ECHO "$inherit_rpath_F77" | $SED "$delay_single_quote_subst"`' - link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' --link_all_deplibs_F77='`$ECHO "$link_all_deplibs_F77" | $SED "$delay_single_quote_subst"`' - always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' --always_export_symbols_F77='`$ECHO "$always_export_symbols_F77" | $SED "$delay_single_quote_subst"`' - export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' --export_symbols_cmds_F77='`$ECHO "$export_symbols_cmds_F77" | $SED "$delay_single_quote_subst"`' - exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' --exclude_expsyms_F77='`$ECHO "$exclude_expsyms_F77" | $SED "$delay_single_quote_subst"`' - include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' --include_expsyms_F77='`$ECHO "$include_expsyms_F77" | $SED "$delay_single_quote_subst"`' - prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' --prelink_cmds_F77='`$ECHO "$prelink_cmds_F77" | $SED "$delay_single_quote_subst"`' - postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' --postlink_cmds_F77='`$ECHO "$postlink_cmds_F77" | $SED "$delay_single_quote_subst"`' - file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' --file_list_spec_F77='`$ECHO "$file_list_spec_F77" | $SED "$delay_single_quote_subst"`' - hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' --hardcode_action_F77='`$ECHO "$hardcode_action_F77" | $SED "$delay_single_quote_subst"`' - compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' --compiler_lib_search_dirs_F77='`$ECHO "$compiler_lib_search_dirs_F77" | $SED "$delay_single_quote_subst"`' - predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' --predep_objects_F77='`$ECHO "$predep_objects_F77" | $SED "$delay_single_quote_subst"`' - postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' --postdep_objects_F77='`$ECHO "$postdep_objects_F77" | $SED "$delay_single_quote_subst"`' - predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' --predeps_F77='`$ECHO "$predeps_F77" | $SED "$delay_single_quote_subst"`' - postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' --postdeps_F77='`$ECHO "$postdeps_F77" | $SED "$delay_single_quote_subst"`' - compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' --compiler_lib_search_path_F77='`$ECHO "$compiler_lib_search_path_F77" | $SED "$delay_single_quote_subst"`' - - LTCC='$LTCC' - LTCFLAGS='$LTCFLAGS' -@@ -35579,57 +32374,31 @@ - postdeps \ - compiler_lib_search_path \ - LD_CXX \ --LD_F77 \ - reload_flag_CXX \ --reload_flag_F77 \ - compiler_CXX \ --compiler_F77 \ - lt_prog_compiler_no_builtin_flag_CXX \ --lt_prog_compiler_no_builtin_flag_F77 \ - lt_prog_compiler_pic_CXX \ --lt_prog_compiler_pic_F77 \ - lt_prog_compiler_wl_CXX \ --lt_prog_compiler_wl_F77 \ - lt_prog_compiler_static_CXX \ --lt_prog_compiler_static_F77 \ - lt_cv_prog_compiler_c_o_CXX \ --lt_cv_prog_compiler_c_o_F77 \ - export_dynamic_flag_spec_CXX \ --export_dynamic_flag_spec_F77 \ - whole_archive_flag_spec_CXX \ --whole_archive_flag_spec_F77 \ - compiler_needs_object_CXX \ --compiler_needs_object_F77 \ - with_gnu_ld_CXX \ --with_gnu_ld_F77 \ - allow_undefined_flag_CXX \ --allow_undefined_flag_F77 \ - no_undefined_flag_CXX \ --no_undefined_flag_F77 \ - hardcode_libdir_flag_spec_CXX \ --hardcode_libdir_flag_spec_F77 \ - hardcode_libdir_flag_spec_ld_CXX \ --hardcode_libdir_flag_spec_ld_F77 \ - hardcode_libdir_separator_CXX \ --hardcode_libdir_separator_F77 \ - exclude_expsyms_CXX \ --exclude_expsyms_F77 \ - include_expsyms_CXX \ --include_expsyms_F77 \ - file_list_spec_CXX \ --file_list_spec_F77 \ - compiler_lib_search_dirs_CXX \ --compiler_lib_search_dirs_F77 \ - predep_objects_CXX \ --predep_objects_F77 \ - postdep_objects_CXX \ --postdep_objects_F77 \ - predeps_CXX \ --predeps_F77 \ - postdeps_CXX \ --postdeps_F77 \ --compiler_lib_search_path_CXX \ --compiler_lib_search_path_F77; do -+compiler_lib_search_path_CXX; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" -@@ -35661,27 +32430,16 @@ - sys_lib_search_path_spec \ - sys_lib_dlsearch_path_spec \ - reload_cmds_CXX \ --reload_cmds_F77 \ - old_archive_cmds_CXX \ --old_archive_cmds_F77 \ - old_archive_from_new_cmds_CXX \ --old_archive_from_new_cmds_F77 \ - old_archive_from_expsyms_cmds_CXX \ --old_archive_from_expsyms_cmds_F77 \ - archive_cmds_CXX \ --archive_cmds_F77 \ - archive_expsym_cmds_CXX \ --archive_expsym_cmds_F77 \ - module_cmds_CXX \ --module_cmds_F77 \ - module_expsym_cmds_CXX \ --module_expsym_cmds_F77 \ - export_symbols_cmds_CXX \ --export_symbols_cmds_F77 \ - prelink_cmds_CXX \ --prelink_cmds_F77 \ --postlink_cmds_CXX \ --postlink_cmds_F77; do -+postlink_cmds_CXX; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" -@@ -35711,8 +32469,6 @@ - - - -- -- - ac_aux_dir='$ac_aux_dir' - ac_aux_dir='$ac_aux_dir' - -@@ -36433,7 +33189,7 @@ - - - # The names of the tagged configurations supported by this script. --available_tags="CXX F77 " -+available_tags="CXX " - - # ### BEGIN LIBTOOL CONFIG - -@@ -37187,163 +33943,6 @@ - # ### END LIBTOOL TAG CONFIG: CXX - _LT_EOF - -- -- cat <<_LT_EOF >> "$ofile" -- --# ### BEGIN LIBTOOL TAG CONFIG: F77 -- --# The linker used to build libraries. --LD=$lt_LD_F77 -- --# How to create reloadable object files. --reload_flag=$lt_reload_flag_F77 --reload_cmds=$lt_reload_cmds_F77 -- --# Commands used to build an old-style archive. --old_archive_cmds=$lt_old_archive_cmds_F77 -- --# A language specific compiler. --CC=$lt_compiler_F77 -- --# Is the compiler the GNU compiler? --with_gcc=$GCC_F77 -- --# Compiler flag to turn off builtin functions. --no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77 -- --# Additional compiler flags for building library objects. --pic_flag=$lt_lt_prog_compiler_pic_F77 -- --# How to pass a linker flag through the compiler. --wl=$lt_lt_prog_compiler_wl_F77 -- --# Compiler flag to prevent dynamic linking. --link_static_flag=$lt_lt_prog_compiler_static_F77 -- --# Does compiler simultaneously support -c and -o options? --compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77 -- --# Whether or not to add -lc for building shared libraries. --build_libtool_need_lc=$archive_cmds_need_lc_F77 -- --# Whether or not to disallow shared libs when runtime libs are static. --allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77 -- --# Compiler flag to allow reflexive dlopens. --export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77 -- --# Compiler flag to generate shared objects directly from archives. --whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77 -- --# Whether the compiler copes with passing no objects directly. --compiler_needs_object=$lt_compiler_needs_object_F77 -- --# Create an old-style archive from a shared archive. --old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77 -- --# Create a temporary old-style archive to link instead of a shared archive. --old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77 -- --# Commands used to build a shared archive. --archive_cmds=$lt_archive_cmds_F77 --archive_expsym_cmds=$lt_archive_expsym_cmds_F77 -- --# Commands used to build a loadable module if different from building --# a shared archive. --module_cmds=$lt_module_cmds_F77 --module_expsym_cmds=$lt_module_expsym_cmds_F77 -- --# Whether we are building with GNU ld or not. --with_gnu_ld=$lt_with_gnu_ld_F77 -- --# Flag that allows shared libraries with undefined symbols to be built. --allow_undefined_flag=$lt_allow_undefined_flag_F77 -- --# Flag that enforces no undefined symbols. --no_undefined_flag=$lt_no_undefined_flag_F77 -- --# Flag to hardcode \$libdir into a binary during linking. --# This must work even if \$libdir does not exist --hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77 -- --# If ld is used when linking, flag to hardcode \$libdir into a binary --# during linking. This must work even if \$libdir does not exist. --hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77 -- --# Whether we need a single "-rpath" flag with a separated argument. --hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77 -- --# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes --# DIR into the resulting binary. --hardcode_direct=$hardcode_direct_F77 -- --# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes --# DIR into the resulting binary and the resulting library dependency is --# "absolute",i.e impossible to change by setting \${shlibpath_var} if the --# library is relocated. --hardcode_direct_absolute=$hardcode_direct_absolute_F77 -- --# Set to "yes" if using the -LDIR flag during linking hardcodes DIR --# into the resulting binary. --hardcode_minus_L=$hardcode_minus_L_F77 -- --# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR --# into the resulting binary. --hardcode_shlibpath_var=$hardcode_shlibpath_var_F77 -- --# Set to "yes" if building a shared library automatically hardcodes DIR --# into the library and all subsequent libraries and executables linked --# against it. --hardcode_automatic=$hardcode_automatic_F77 -- --# Set to yes if linker adds runtime paths of dependent libraries --# to runtime path list. --inherit_rpath=$inherit_rpath_F77 -- --# Whether libtool must link a program against all its dependency libraries. --link_all_deplibs=$link_all_deplibs_F77 -- --# Set to "yes" if exported symbols are required. --always_export_symbols=$always_export_symbols_F77 -- --# The commands to list exported symbols. --export_symbols_cmds=$lt_export_symbols_cmds_F77 -- --# Symbols that should not be listed in the preloaded symbols. --exclude_expsyms=$lt_exclude_expsyms_F77 -- --# Symbols that must always be exported. --include_expsyms=$lt_include_expsyms_F77 -- --# Commands necessary for linking programs (against libraries) with templates. --prelink_cmds=$lt_prelink_cmds_F77 -- --# Commands necessary for finishing linking programs. --postlink_cmds=$lt_postlink_cmds_F77 -- --# Specify filename containing input files. --file_list_spec=$lt_file_list_spec_F77 -- --# How to hardcode a shared library path into an executable. --hardcode_action=$hardcode_action_F77 -- --# The directories searched by this compiler when creating a shared library. --compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_F77 -- --# Dependencies to place before and after the objects being linked to --# create a shared library. --predep_objects=$lt_predep_objects_F77 --postdep_objects=$lt_postdep_objects_F77 --predeps=$lt_predeps_F77 --postdeps=$lt_postdeps_F77 -- --# The library search path used internally by the compiler when linking --# a shared library. --compiler_lib_search_path=$lt_compiler_lib_search_path_F77 -- --# ### END LIBTOOL TAG CONFIG: F77 --_LT_EOF -- - ;; - - esac diff --git a/build/pkgs/mpir/patches/core-prescott-configure.patch b/build/pkgs/mpir/patches/core-prescott-configure.patch deleted file mode 100644 index fd829357ee9..00000000000 --- a/build/pkgs/mpir/patches/core-prescott-configure.patch +++ /dev/null @@ -1,107 +0,0 @@ ---- src/acinclude.m4 2013-02-27 04:51:08.528733998 +0100 -+++ src/acinclude.m4 2013-02-27 06:19:10.558735026 +0100 -@@ -41,7 +41,7 @@ - [[powerpc64-*-* | powerpc64le-*-* | powerpc620-*-* | powerpc630-*-* | powerpc970-*-* | power[3-9]-*-*]]) - - define(X86_PATTERN, --[[i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | athlon-*-* | viac3*-*-*]]) -+[[i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | prescott-*-* | core-*-* | athlon-*-* | viac3*-*-*]]) - - define(X86_64_PATTERN, - [[x86_64-*-* | netburst-*-* | netburstlahf-*-* | k8-*-* | k10-*-* | k102-*-* | k103-*-* | core2-*-* | penryn-*-* | nehalem-*-* | westmere-*-* | sandybridge-*-* | atom-*-* | nano-*-* | bobcat-*-* | bulldozer-*-*]]) ---- src/configure.in 2013-02-27 04:51:08.538733998 +0100 -+++ src/configure.in 2013-02-27 06:19:10.558735026 +0100 -@@ -1018,6 +1018,10 @@ - gcc_cflags_cpu="-mtune=pentium3 -mcpu=pentium3 -mcpu=pentiumpro -mcpu=i486 -m486" - gcc_cflags_arch="-march=pentium3 -march=pentiumpro -march=pentium" - ;; -+ core) -+ gcc_cflags_cpu="-mtune=pentium-m -mtune=pentium3m -mtune=pentium3 -mcpu=pentium3 -mcpu=pentiumpro -mcpu=i486 -m486" -+ gcc_cflags_arch="-march=pentium-m -march=pentium3m -march=pentium3 -march=pentiumpro -march=pentium" -+ ;; - k6) - gcc_cflags_cpu="-mtune=k6 -mcpu=k6 -mcpu=i486 -m486" - gcc_cflags_arch="-march=k6" -@@ -1104,6 +1108,7 @@ - i686 | pentiumpro) path="x86/p6 x86" ;; - pentium2) path="x86/p6/mmx x86/p6 x86" ;; - pentium3) path="x86/p6/p3mmx x86/p6/mmx x86/p6 x86";; -+ core) path="x86/p6/p3mmx x86/p6/mmx x86/p6 x86";; - [k6[23]]) path="x86/k6/k62mmx x86/k6/mmx x86/k6 x86" ;; - k6) path="x86/k6/mmx x86/k6 x86" ;; - athlon | k7 | x86_64 | atom) path="x86/k7/mmx x86/k7 x86" ;; ---- src/configure 2013-02-27 04:51:08.638733998 +0100 -+++ src/configure 2013-02-27 06:19:33.298735030 +0100 -@@ -4445,7 +4445,7 @@ - # mode, in case -m32 has failed not because it's an old gcc, but because - # it's a dual 32/64-bit gcc without a 32-bit libc, or whatever. - # -- i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | athlon-*-* | viac3*-*-* | x86_64-*-* | netburst-*-* | netburstlahf-*-* | k8-*-* | k10-*-* | k102-*-* | k103-*-* | core2-*-* | penryn-*-* | nehalem-*-* | westmere-*-* | sandybridge-*-* | atom-*-* | nano-*-* | bobcat-*-* | bulldozer-*-*) -+ i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | prescott-*-* | core-*-* | athlon-*-* | viac3*-*-* | x86_64-*-* | netburst-*-* | netburstlahf-*-* | k8-*-* | k10-*-* | k102-*-* | k103-*-* | core2-*-* | penryn-*-* | nehalem-*-* | westmere-*-* | sandybridge-*-* | atom-*-* | nano-*-* | bobcat-*-* | bulldozer-*-*) - abilist="32" - cclist="gcc icc cc" - gcc_cflags="-O2 $fomit_frame_pointer" -@@ -4539,6 +4539,10 @@ - gcc_cflags_cpu="-mtune=pentium3 -mcpu=pentium3 -mcpu=pentiumpro -mcpu=i486 -m486" - gcc_cflags_arch="-march=pentium3 -march=pentiumpro -march=pentium" - ;; -+ core) -+ gcc_cflags_cpu="-mtune=pentium-m -mtune=pentium3m -mtune=pentium3 -mcpu=pentium3 -mcpu=pentiumpro -mcpu=i486 -m486" -+ gcc_cflags_arch="-march=pentium-m -march=pentium3m -march=pentium3 -march=pentiumpro -march=pentium" -+ ;; - k6) - gcc_cflags_cpu="-mtune=k6 -mcpu=k6 -mcpu=i486 -m486" - gcc_cflags_arch="-march=k6" -@@ -4625,6 +4629,7 @@ - i686 | pentiumpro) path="x86/p6 x86" ;; - pentium2) path="x86/p6/mmx x86/p6 x86" ;; - pentium3) path="x86/p6/p3mmx x86/p6/mmx x86/p6 x86";; -+ core) path="x86/p6/p3mmx x86/p6/mmx x86/p6 x86";; - k6[23]) path="x86/k6/k62mmx x86/k6/mmx x86/k6 x86" ;; - k6) path="x86/k6/mmx x86/k6 x86" ;; - athlon | k7 | x86_64 | atom) path="x86/k7/mmx x86/k7 x86" ;; -@@ -5905,7 +5910,7 @@ - # - if test "$gmp_prog_cc_works" = yes; then - case $host in -- i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | athlon-*-* | viac3*-*-*) -+ i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | prescott-*-* | core-*-* | athlon-*-* | viac3*-*-*) - # this problem only arises in PIC code, so don't need to test when - # --disable-shared. We don't necessarily have $enable_shared set to - # yes at this point, it will still be unset for the default (which is -@@ -7219,7 +7224,7 @@ - # - if test "$gmp_prog_cc_works" = yes; then - case $host in -- i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | athlon-*-* | viac3*-*-*) -+ i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | prescott-*-* | core-*-* | athlon-*-* | viac3*-*-*) - # this problem only arises in PIC code, so don't need to test when - # --disable-shared. We don't necessarily have $enable_shared set to - # yes at this point, it will still be unset for the default (which is -@@ -10598,7 +10603,7 @@ - # enough assembler. - # - case $host in -- i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | athlon-*-* | viac3*-*-* | x86_64-*-* | netburst-*-* | netburstlahf-*-* | k8-*-* | k10-*-* | k102-*-* | k103-*-* | core2-*-* | penryn-*-* | nehalem-*-* | westmere-*-* | sandybridge-*-* | atom-*-* | nano-*-* | bobcat-*-* | bulldozer-*-*) -+ i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | prescott-*-* | core-*-* | athlon-*-* | viac3*-*-* | x86_64-*-* | netburst-*-* | netburstlahf-*-* | k8-*-* | k10-*-* | k102-*-* | k103-*-* | core2-*-* | penryn-*-* | nehalem-*-* | westmere-*-* | sandybridge-*-* | atom-*-* | nano-*-* | bobcat-*-* | bulldozer-*-*) - if test "$ABI" = 32; then - case "$path $fat_path" in - *mmx*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the assembler knows about MMX instructions" >&5 -@@ -24443,7 +24448,7 @@ - else - - case $host in --i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | athlon-*-* | viac3*-*-* | x86_64-*-*) -+i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | prescott-*-* | core-*-* | athlon-*-* | viac3*-*-* | x86_64-*-*) - gmp_cv_asm_rodata="$gmp_cv_asm_data" ;; - *) - gmp_cv_asm_rodata="$gmp_cv_asm_text" ;; -@@ -25098,7 +25103,7 @@ - ;; - esac - ;; -- i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | athlon-*-* | viac3*-*-* | x86_64-*-* | netburst-*-* | netburstlahf-*-* | k8-*-* | k10-*-* | k102-*-* | k103-*-* | core2-*-* | penryn-*-* | nehalem-*-* | westmere-*-* | sandybridge-*-* | atom-*-* | nano-*-* | bobcat-*-* | bulldozer-*-*) -+ i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | prescott-*-* | core-*-* | athlon-*-* | viac3*-*-* | x86_64-*-* | netburst-*-* | netburstlahf-*-* | k8-*-* | k10-*-* | k102-*-* | k103-*-* | core2-*-* | penryn-*-* | nehalem-*-* | westmere-*-* | sandybridge-*-* | atom-*-* | nano-*-* | bobcat-*-* | bulldozer-*-*) - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the .align directive accepts an 0x90 fill in .text" >&5 - $as_echo_n "checking if the .align directive accepts an 0x90 fill in .text... " >&6; } diff --git a/build/pkgs/mpir/patches/gmp-h.in.patch b/build/pkgs/mpir/patches/gmp-h.in.patch deleted file mode 100644 index beedf3e10c4..00000000000 --- a/build/pkgs/mpir/patches/gmp-h.in.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff -ru src/gmp-h.in src.patched/gmp-h.in ---- src/gmp-h.in 2011-06-14 07:33:49.000000000 +0200 -+++ src.patched/gmp-h.in 2012-04-07 14:32:53.758280009 +0200 -@@ -22,6 +22,11 @@ - - #ifndef __GMP_H__ - -+#ifdef __SUNPRO_CC /* See: http://trac.sagemath.org/sage_trac/ticket/7849 */ -+#include /* This is Bill Hart's fix, but I've applied it only */ -+#include /* on Sun Studio */ -+#endif -+ - #if defined (__cplusplus) - #include /* for std::istream, std::ostream, std::string */ - #include diff --git a/build/pkgs/mpir/patches/mpz__t-scan-bugfix.patch b/build/pkgs/mpir/patches/mpz__t-scan-bugfix.patch deleted file mode 100644 index 9693cbc01ec..00000000000 --- a/build/pkgs/mpir/patches/mpz__t-scan-bugfix.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- mpir-2.6.0/tests/mpz/t-scan.c 2012-10-03 22:07:32.000000000 +0200 -+++ mpir-2.6.0/tests/mpz/t-scan.c 2013-04-02 18:39:17.704366985 +0200 -@@ -84,7 +84,7 @@ - - for (isize = 0; isize <= size; isize++) - { -- for (oindex = 0; oindex <= numberof (offset); oindex++) -+ for (oindex = 0; oindex < numberof (offset); oindex++) - { - o = offset[oindex]; - if ((int) isize*GMP_NUMB_BITS < -o) diff --git a/build/pkgs/mpir/patches/quote_asm.patch b/build/pkgs/mpir/patches/quote_asm.patch deleted file mode 100644 index e18cade4cf0..00000000000 --- a/build/pkgs/mpir/patches/quote_asm.patch +++ /dev/null @@ -1,864 +0,0 @@ -diff -ru src/mpn/alpha/addlsh1_n.asm src.patched/mpn/alpha/addlsh1_n.asm ---- src/mpn/alpha/addlsh1_n.asm 2010-12-31 08:26:24.000000000 +0100 -+++ src.patched/mpn/alpha/addlsh1_n.asm 2012-04-07 14:27:57.058280100 +0200 -@@ -54,7 +54,7 @@ - define(`ps', `r25') - define(`sl', `r28') - --define(OPERATION_addlsh1_n,1) -+define(`OPERATION_addlsh1_n',1) - - ifdef(`OPERATION_addlsh1_n',` - define(ADDSUB, addq) -diff -ru src/mpn/alpha/sublsh1_n.asm src.patched/mpn/alpha/sublsh1_n.asm ---- src/mpn/alpha/sublsh1_n.asm 2010-12-31 08:26:10.000000000 +0100 -+++ src.patched/mpn/alpha/sublsh1_n.asm 2012-04-07 14:27:57.048279798 +0200 -@@ -54,7 +54,7 @@ - define(`ps', `r25') - define(`sl', `r28') - --define(OPERATION_sublsh1_n,1) -+define(`OPERATION_sublsh1_n',1) - - ifdef(`OPERATION_addlsh1_n',` - define(ADDSUB, addq) -diff -ru src/mpn/ia64/add_n.asm src.patched/mpn/ia64/add_n.asm ---- src/mpn/ia64/add_n.asm 2010-12-31 08:21:21.000000000 +0100 -+++ src.patched/mpn/ia64/add_n.asm 2012-04-07 14:27:57.628279922 +0200 -@@ -33,7 +33,7 @@ - define(`vp',`r34') - define(`n',`r35') - --define(OPERATION_add_n,1) -+define(`OPERATION_add_n',1) - - ifdef(`OPERATION_add_n',` - define(ADDSUB, add) -diff -ru src/mpn/ia64/addlsh1_n.asm src.patched/mpn/ia64/addlsh1_n.asm ---- src/mpn/ia64/addlsh1_n.asm 2010-12-31 08:25:53.000000000 +0100 -+++ src.patched/mpn/ia64/addlsh1_n.asm 2012-04-07 14:27:57.668283269 +0200 -@@ -32,7 +32,7 @@ - define(`vp',`r34') - define(`n',`r35') - --define(OPERATION_addlsh1_n,1) -+define(`OPERATION_addlsh1_n',1) - - ifdef(`OPERATION_addlsh1_n',` - define(ADDSUB, add) -diff -ru src/mpn/ia64/and_n.asm src.patched/mpn/ia64/and_n.asm ---- src/mpn/ia64/and_n.asm 2010-12-31 08:11:37.000000000 +0100 -+++ src.patched/mpn/ia64/and_n.asm 2012-04-07 14:27:57.678272121 +0200 -@@ -34,7 +34,7 @@ - define(`vp', `r34') - define(`n', `r35') - --define(OPERATION_and_n,1) -+define(`OPERATION_and_n',1) - - ifdef(`OPERATION_and_n', - ` define(`func',`mpn_and_n') -diff -ru src/mpn/ia64/andn_n.asm src.patched/mpn/ia64/andn_n.asm ---- src/mpn/ia64/andn_n.asm 2010-12-31 08:11:10.000000000 +0100 -+++ src.patched/mpn/ia64/andn_n.asm 2012-04-07 14:27:57.468269051 +0200 -@@ -34,7 +34,7 @@ - define(`vp', `r34') - define(`n', `r35') - --define(OPERATION_andn_n,1) -+define(`OPERATION_andn_n',1) - - ifdef(`OPERATION_and_n', - ` define(`func',`mpn_and_n') -diff -ru src/mpn/ia64/ior_n.asm src.patched/mpn/ia64/ior_n.asm ---- src/mpn/ia64/ior_n.asm 2010-12-31 08:12:01.000000000 +0100 -+++ src.patched/mpn/ia64/ior_n.asm 2012-04-07 14:27:57.448269684 +0200 -@@ -34,7 +34,7 @@ - define(`vp', `r34') - define(`n', `r35') - --define(OPERATION_ior_n,1) -+define(`OPERATION_ior_n',1) - - ifdef(`OPERATION_and_n', - ` define(`func',`mpn_and_n') -diff -ru src/mpn/ia64/iorn_n.asm src.patched/mpn/ia64/iorn_n.asm ---- src/mpn/ia64/iorn_n.asm 2010-12-31 08:12:11.000000000 +0100 -+++ src.patched/mpn/ia64/iorn_n.asm 2012-04-07 14:27:57.658279932 +0200 -@@ -34,7 +34,7 @@ - define(`vp', `r34') - define(`n', `r35') - --define(OPERATION_iorn_n,1) -+define(`OPERATION_iorn_n',1) - - ifdef(`OPERATION_and_n', - ` define(`func',`mpn_and_n') -diff -ru src/mpn/ia64/lshift.asm src.patched/mpn/ia64/lshift.asm ---- src/mpn/ia64/lshift.asm 2010-12-31 08:26:45.000000000 +0100 -+++ src.patched/mpn/ia64/lshift.asm 2012-04-07 14:27:57.618271813 +0200 -@@ -39,7 +39,7 @@ - - define(`tnc',`r9') - --define(OPERATION_lshift,1) -+define(`OPERATION_lshift',1) - - ifdef(`OPERATION_lshift',` - define(`FSH',`shl') -diff -ru src/mpn/ia64/nand_n.asm src.patched/mpn/ia64/nand_n.asm ---- src/mpn/ia64/nand_n.asm 2010-12-31 08:11:26.000000000 +0100 -+++ src.patched/mpn/ia64/nand_n.asm 2012-04-07 14:27:57.488270124 +0200 -@@ -34,7 +34,7 @@ - define(`vp', `r34') - define(`n', `r35') - --define(OPERATION_nand_n,1) -+define(`OPERATION_nand_n',1) - - ifdef(`OPERATION_and_n', - ` define(`func',`mpn_and_n') -diff -ru src/mpn/ia64/nior_n.asm src.patched/mpn/ia64/nior_n.asm ---- src/mpn/ia64/nior_n.asm 2010-12-31 08:12:21.000000000 +0100 -+++ src.patched/mpn/ia64/nior_n.asm 2012-04-07 14:27:57.548279945 +0200 -@@ -34,7 +34,7 @@ - define(`vp', `r34') - define(`n', `r35') - --define(OPERATION_nior_n,1) -+define(`OPERATION_nior_n',1) - - ifdef(`OPERATION_and_n', - ` define(`func',`mpn_and_n') -diff -ru src/mpn/ia64/rsh1add_n.asm src.patched/mpn/ia64/rsh1add_n.asm ---- src/mpn/ia64/rsh1add_n.asm 2010-12-31 08:24:25.000000000 +0100 -+++ src.patched/mpn/ia64/rsh1add_n.asm 2012-04-07 14:27:57.538280044 +0200 -@@ -33,7 +33,7 @@ - define(`vp',`r34') - define(`n',`r35') - --define(OPERATION_rsh1add_n,1) -+define(`OPERATION_rsh1add_n',1) - - ifdef(`OPERATION_rsh1add_n',` - define(ADDSUB, add) -diff -ru src/mpn/ia64/rsh1sub_n.asm src.patched/mpn/ia64/rsh1sub_n.asm ---- src/mpn/ia64/rsh1sub_n.asm 2010-12-31 08:24:36.000000000 +0100 -+++ src.patched/mpn/ia64/rsh1sub_n.asm 2012-04-07 14:27:57.508269882 +0200 -@@ -33,7 +33,7 @@ - define(`vp',`r34') - define(`n',`r35') - --define(OPERATION_rsh1sub_n,1) -+define(`OPERATION_rsh1sub_n',1) - - ifdef(`OPERATION_rsh1add_n',` - define(ADDSUB, add) -diff -ru src/mpn/ia64/rshift.asm src.patched/mpn/ia64/rshift.asm ---- src/mpn/ia64/rshift.asm 2010-12-31 08:26:55.000000000 +0100 -+++ src.patched/mpn/ia64/rshift.asm 2012-04-07 14:27:57.628279922 +0200 -@@ -39,7 +39,7 @@ - - define(`tnc',`r9') - --define(OPERATION_rshift,1) -+define(`OPERATION_rshift',1) - - ifdef(`OPERATION_lshift',` - define(`FSH',`shl') -diff -ru src/mpn/ia64/sub_n.asm src.patched/mpn/ia64/sub_n.asm ---- src/mpn/ia64/sub_n.asm 2010-12-31 08:21:31.000000000 +0100 -+++ src.patched/mpn/ia64/sub_n.asm 2012-04-07 14:27:57.518279963 +0200 -@@ -33,7 +33,7 @@ - define(`vp',`r34') - define(`n',`r35') - --define(OPERATION_sub_n,1) -+define(`OPERATION_sub_n',1) - - ifdef(`OPERATION_add_n',` - define(ADDSUB, add) -diff -ru src/mpn/ia64/sublsh1_n.asm src.patched/mpn/ia64/sublsh1_n.asm ---- src/mpn/ia64/sublsh1_n.asm 2010-12-31 08:25:40.000000000 +0100 -+++ src.patched/mpn/ia64/sublsh1_n.asm 2012-04-07 14:27:57.638269756 +0200 -@@ -32,7 +32,7 @@ - define(`vp',`r34') - define(`n',`r35') - --define(OPERATION_sublsh1_n,1) -+define(`OPERATION_sublsh1_n',1) - - ifdef(`OPERATION_addlsh1_n',` - define(ADDSUB, add) -diff -ru src/mpn/ia64/xnor_n.asm src.patched/mpn/ia64/xnor_n.asm ---- src/mpn/ia64/xnor_n.asm 2010-12-31 08:12:45.000000000 +0100 -+++ src.patched/mpn/ia64/xnor_n.asm 2012-04-07 14:27:57.608279181 +0200 -@@ -34,7 +34,7 @@ - define(`vp', `r34') - define(`n', `r35') - --define(OPERATION_xnor_n,1) -+define(`OPERATION_xnor_n',1) - - ifdef(`OPERATION_and_n', - ` define(`func',`mpn_and_n') -diff -ru src/mpn/ia64/xor_n.asm src.patched/mpn/ia64/xor_n.asm ---- src/mpn/ia64/xor_n.asm 2010-12-31 08:12:33.000000000 +0100 -+++ src.patched/mpn/ia64/xor_n.asm 2012-04-07 14:27:57.608279181 +0200 -@@ -34,7 +34,7 @@ - define(`vp', `r34') - define(`n', `r35') - --define(OPERATION_xor_n,1) -+define(`OPERATION_xor_n',1) - - ifdef(`OPERATION_and_n', - ` define(`func',`mpn_and_n') -diff -ru src/mpn/powerpc32/vmx/and_n.asm src.patched/mpn/powerpc32/vmx/and_n.asm ---- src/mpn/powerpc32/vmx/and_n.asm 2010-12-31 08:16:01.000000000 +0100 -+++ src.patched/mpn/powerpc32/vmx/and_n.asm 2012-04-07 14:27:52.968280448 +0200 -@@ -56,7 +56,7 @@ - define(`vnegb', `') C default neg-before to null - define(`vnega', `') C default neg-before to null - --define(OPERATION_and_n,1) -+define(`OPERATION_and_n',1) - - ifdef(`OPERATION_and_n', - ` define(`func', `mpn_and_n') -diff -ru src/mpn/powerpc32/vmx/andn_n.asm src.patched/mpn/powerpc32/vmx/andn_n.asm ---- src/mpn/powerpc32/vmx/andn_n.asm 2010-12-31 08:16:13.000000000 +0100 -+++ src.patched/mpn/powerpc32/vmx/andn_n.asm 2012-04-07 14:27:52.918280512 +0200 -@@ -56,7 +56,7 @@ - define(`vnegb', `') C default neg-before to null - define(`vnega', `') C default neg-before to null - --define(OPERATION_andn_n,1) -+define(`OPERATION_andn_n',1) - - ifdef(`OPERATION_and_n', - ` define(`func', `mpn_and_n') -diff -ru src/mpn/powerpc32/vmx/ior_n.asm src.patched/mpn/powerpc32/vmx/ior_n.asm ---- src/mpn/powerpc32/vmx/ior_n.asm 2010-12-31 08:16:39.000000000 +0100 -+++ src.patched/mpn/powerpc32/vmx/ior_n.asm 2012-04-07 14:27:52.918280512 +0200 -@@ -56,7 +56,7 @@ - define(`vnegb', `') C default neg-before to null - define(`vnega', `') C default neg-before to null - --define(OPERATION_ior_n,1) -+define(`OPERATION_ior_n',1) - - ifdef(`OPERATION_and_n', - ` define(`func', `mpn_and_n') -diff -ru src/mpn/powerpc32/vmx/iorn_n.asm src.patched/mpn/powerpc32/vmx/iorn_n.asm ---- src/mpn/powerpc32/vmx/iorn_n.asm 2010-12-31 08:16:51.000000000 +0100 -+++ src.patched/mpn/powerpc32/vmx/iorn_n.asm 2012-04-07 14:27:52.968280448 +0200 -@@ -56,7 +56,7 @@ - define(`vnegb', `') C default neg-before to null - define(`vnega', `') C default neg-before to null - --define(OPERATION_iorn_n,1) -+define(`OPERATION_iorn_n',1) - - ifdef(`OPERATION_and_n', - ` define(`func', `mpn_and_n') -diff -ru src/mpn/powerpc32/vmx/nand_n.asm src.patched/mpn/powerpc32/vmx/nand_n.asm ---- src/mpn/powerpc32/vmx/nand_n.asm 2010-12-31 08:16:26.000000000 +0100 -+++ src.patched/mpn/powerpc32/vmx/nand_n.asm 2012-04-07 14:27:52.928276559 +0200 -@@ -56,7 +56,7 @@ - define(`vnegb', `') C default neg-before to null - define(`vnega', `') C default neg-before to null - --define(OPERATION_nand_n,1) -+define(`OPERATION_nand_n',1) - - ifdef(`OPERATION_and_n', - ` define(`func', `mpn_and_n') -diff -ru src/mpn/powerpc32/vmx/nior_n.asm src.patched/mpn/powerpc32/vmx/nior_n.asm ---- src/mpn/powerpc32/vmx/nior_n.asm 2010-12-31 08:17:04.000000000 +0100 -+++ src.patched/mpn/powerpc32/vmx/nior_n.asm 2012-04-07 14:27:52.938268875 +0200 -@@ -56,7 +56,7 @@ - define(`vnegb', `') C default neg-before to null - define(`vnega', `') C default neg-before to null - --define(OPERATION_nior_n,1) -+define(`OPERATION_nior_n',1) - - ifdef(`OPERATION_and_n', - ` define(`func', `mpn_and_n') -diff -ru src/mpn/powerpc32/vmx/xnor_n.asm src.patched/mpn/powerpc32/vmx/xnor_n.asm ---- src/mpn/powerpc32/vmx/xnor_n.asm 2010-12-31 08:17:31.000000000 +0100 -+++ src.patched/mpn/powerpc32/vmx/xnor_n.asm 2012-04-07 14:27:52.958279999 +0200 -@@ -56,7 +56,7 @@ - define(`vnegb', `') C default neg-before to null - define(`vnega', `') C default neg-before to null - --define(OPERATION_xnor_n,1) -+define(`OPERATION_xnor_n',1) - - ifdef(`OPERATION_and_n', - ` define(`func', `mpn_and_n') -diff -ru src/mpn/powerpc32/vmx/xor_n.asm src.patched/mpn/powerpc32/vmx/xor_n.asm ---- src/mpn/powerpc32/vmx/xor_n.asm 2010-12-31 08:17:18.000000000 +0100 -+++ src.patched/mpn/powerpc32/vmx/xor_n.asm 2012-04-07 14:27:52.958279999 +0200 -@@ -56,7 +56,7 @@ - define(`vnegb', `') C default neg-before to null - define(`vnega', `') C default neg-before to null - --define(OPERATION_xor_n,1) -+define(`OPERATION_xor_n',1) - - ifdef(`OPERATION_and_n', - ` define(`func', `mpn_and_n') -diff -ru src/mpn/x86/add_n.asm src.patched/mpn/x86/add_n.asm ---- src/mpn/x86/add_n.asm 2010-12-31 08:30:17.000000000 +0100 -+++ src.patched/mpn/x86/add_n.asm 2012-04-07 14:27:56.118269524 +0200 -@@ -30,7 +30,7 @@ - C K7: 2.25 - C P4: 8.75 - --define(OPERATION_add_n,1) -+define(`OPERATION_add_n',1) - - ifdef(`OPERATION_add_n',` - define(M4_inst, adcl) -diff -ru src/mpn/x86/addmul_1.asm src.patched/mpn/x86/addmul_1.asm ---- src/mpn/x86/addmul_1.asm 2010-12-31 08:21:58.000000000 +0100 -+++ src.patched/mpn/x86/addmul_1.asm 2012-04-07 14:27:55.848269439 +0200 -@@ -38,7 +38,7 @@ - C K7: 5.25 - C K8: - --define(OPERATION_addmul_1,1) -+define(`OPERATION_addmul_1',1) - - ifdef(`OPERATION_addmul_1',` - define(M4_inst, addl) -diff -ru src/mpn/x86/applenopic/addmul_1.asm src.patched/mpn/x86/applenopic/addmul_1.asm ---- src/mpn/x86/applenopic/addmul_1.asm 2010-12-31 08:22:55.000000000 +0100 -+++ src.patched/mpn/x86/applenopic/addmul_1.asm 2012-04-07 14:27:56.058280957 +0200 -@@ -38,7 +38,7 @@ - C K7: 5.25 - C K8: - --define(OPERATION_addmul_1,1) -+define(`OPERATION_addmul_1',1) - - ifdef(`OPERATION_addmul_1',` - define(M4_inst, addl) -diff -ru src/mpn/x86/applenopic/submul_1.asm src.patched/mpn/x86/applenopic/submul_1.asm ---- src/mpn/x86/applenopic/submul_1.asm 2010-12-31 08:23:06.000000000 +0100 -+++ src.patched/mpn/x86/applenopic/submul_1.asm 2012-04-07 14:27:56.028279791 +0200 -@@ -38,7 +38,7 @@ - C K7: 5.25 - C K8: - --define(OPERATION_submul_1,1) -+define(`OPERATION_submul_1',1) - - ifdef(`OPERATION_addmul_1',` - define(M4_inst, addl) -diff -ru src/mpn/x86/core2/add_n.asm src.patched/mpn/x86/core2/add_n.asm ---- src/mpn/x86/core2/add_n.asm 2010-12-31 08:30:57.000000000 +0100 -+++ src.patched/mpn/x86/core2/add_n.asm 2012-04-07 14:27:55.428291699 +0200 -@@ -35,7 +35,7 @@ - - deflit(UNROLL_COUNT, 16) - --define(OPERATION_add_n,1) -+define(`OPERATION_add_n',1) - - ifdef(`OPERATION_add_n', ` - define(M4_inst, adcl) -diff -ru src/mpn/x86/core2/sub_n.asm src.patched/mpn/x86/core2/sub_n.asm ---- src/mpn/x86/core2/sub_n.asm 2010-12-31 08:31:08.000000000 +0100 -+++ src.patched/mpn/x86/core2/sub_n.asm 2012-04-07 14:27:55.368279962 +0200 -@@ -35,7 +35,7 @@ - - deflit(UNROLL_COUNT, 16) - --define(OPERATION_sub_n,1) -+define(`OPERATION_sub_n',1) - - ifdef(`OPERATION_add_n', ` - define(M4_inst, adcl) -diff -ru src/mpn/x86/k6/add_n.asm src.patched/mpn/x86/k6/add_n.asm ---- src/mpn/x86/k6/add_n.asm 2010-12-31 08:29:14.000000000 +0100 -+++ src.patched/mpn/x86/k6/add_n.asm 2012-04-07 14:27:55.778269241 +0200 -@@ -24,7 +24,7 @@ - - C K6: normal 3.25 cycles/limb, in-place 2.75 cycles/limb. - --define(OPERATION_add_n,1) -+define(`OPERATION_add_n',1) - - ifdef(`OPERATION_add_n', ` - define(M4_inst, adcl) -diff -ru src/mpn/x86/k6/addmul_1.asm src.patched/mpn/x86/k6/addmul_1.asm ---- src/mpn/x86/k6/addmul_1.asm 2010-12-31 08:29:47.000000000 +0100 -+++ src.patched/mpn/x86/k6/addmul_1.asm 2012-04-07 14:27:55.628279965 +0200 -@@ -52,7 +52,7 @@ - - deflit(UNROLL_COUNT, 16) - --define(OPERATION_addmul_1,1) -+define(`OPERATION_addmul_1',1) - - ifdef(`OPERATION_addmul_1', ` - define(M4_inst, addl) -diff -ru src/mpn/x86/k6/mmx/and_n.asm src.patched/mpn/x86/k6/mmx/and_n.asm ---- src/mpn/x86/k6/mmx/and_n.asm 2010-12-31 08:13:39.000000000 +0100 -+++ src.patched/mpn/x86/k6/mmx/and_n.asm 2012-04-07 14:27:55.758280292 +0200 -@@ -41,7 +41,7 @@ - dnl M4_*_neg_dst means whether to negate the final result before writing - dnl M4_*_neg_src2 means whether to negate the src2 values before using them - --define(OPERATION_and_n,1) -+define(`OPERATION_and_n',1) - - define(M4_choose_op, - m4_assert_numargs(7) -diff -ru src/mpn/x86/k6/mmx/andn_n.asm src.patched/mpn/x86/k6/mmx/andn_n.asm ---- src/mpn/x86/k6/mmx/andn_n.asm 2010-12-31 08:13:53.000000000 +0100 -+++ src.patched/mpn/x86/k6/mmx/andn_n.asm 2012-04-07 14:27:55.668280102 +0200 -@@ -41,7 +41,7 @@ - dnl M4_*_neg_dst means whether to negate the final result before writing - dnl M4_*_neg_src2 means whether to negate the src2 values before using them - --define(OPERATION_andn_n,1) -+define(`OPERATION_andn_n',1) - - define(M4_choose_op, - m4_assert_numargs(7) -diff -ru src/mpn/x86/k6/mmx/hamdist.asm src.patched/mpn/x86/k6/mmx/hamdist.asm ---- src/mpn/x86/k6/mmx/hamdist.asm 2010-12-31 08:19:05.000000000 +0100 -+++ src.patched/mpn/x86/k6/mmx/hamdist.asm 2012-04-07 14:27:55.698278894 +0200 -@@ -34,7 +34,7 @@ - C The code here isn't optimal, but it's already a 2x speedup over the plain - C integer mpn/generic/popcount.c,hamdist.c. - --define(OPERATION_hamdist,1) -+define(`OPERATION_hamdist',1) - - ifdef(`OPERATION_popcount',, - `ifdef(`OPERATION_hamdist',, -diff -ru src/mpn/x86/k6/mmx/ior_n.asm src.patched/mpn/x86/k6/mmx/ior_n.asm ---- src/mpn/x86/k6/mmx/ior_n.asm 2010-12-31 08:14:20.000000000 +0100 -+++ src.patched/mpn/x86/k6/mmx/ior_n.asm 2012-04-07 14:27:55.668280102 +0200 -@@ -41,7 +41,7 @@ - dnl M4_*_neg_dst means whether to negate the final result before writing - dnl M4_*_neg_src2 means whether to negate the src2 values before using them - --define(OPERATION_ior_n,1) -+define(`OPERATION_ior_n',1) - - define(M4_choose_op, - m4_assert_numargs(7) -diff -ru src/mpn/x86/k6/mmx/iorn_n.asm src.patched/mpn/x86/k6/mmx/iorn_n.asm ---- src/mpn/x86/k6/mmx/iorn_n.asm 2010-12-31 08:14:32.000000000 +0100 -+++ src.patched/mpn/x86/k6/mmx/iorn_n.asm 2012-04-07 14:27:55.748280101 +0200 -@@ -41,7 +41,7 @@ - dnl M4_*_neg_dst means whether to negate the final result before writing - dnl M4_*_neg_src2 means whether to negate the src2 values before using them - --define(OPERATION_iorn_n,1) -+define(`OPERATION_iorn_n',1) - - define(M4_choose_op, - m4_assert_numargs(7) -diff -ru src/mpn/x86/k6/mmx/nand_n.asm src.patched/mpn/x86/k6/mmx/nand_n.asm ---- src/mpn/x86/k6/mmx/nand_n.asm 2010-12-31 08:14:07.000000000 +0100 -+++ src.patched/mpn/x86/k6/mmx/nand_n.asm 2012-04-07 14:27:55.678270024 +0200 -@@ -41,7 +41,7 @@ - dnl M4_*_neg_dst means whether to negate the final result before writing - dnl M4_*_neg_src2 means whether to negate the src2 values before using them - --define(OPERATION_nand_n,1) -+define(`OPERATION_nand_n',1) - - define(M4_choose_op, - m4_assert_numargs(7) -diff -ru src/mpn/x86/k6/mmx/nior_n.asm src.patched/mpn/x86/k6/mmx/nior_n.asm ---- src/mpn/x86/k6/mmx/nior_n.asm 2010-12-31 08:14:43.000000000 +0100 -+++ src.patched/mpn/x86/k6/mmx/nior_n.asm 2012-04-07 14:27:55.708275203 +0200 -@@ -41,7 +41,7 @@ - dnl M4_*_neg_dst means whether to negate the final result before writing - dnl M4_*_neg_src2 means whether to negate the src2 values before using them - --define(OPERATION_nior_n,1) -+define(`OPERATION_nior_n',1) - - define(M4_choose_op, - m4_assert_numargs(7) -diff -ru src/mpn/x86/k6/mmx/popcount.asm src.patched/mpn/x86/k6/mmx/popcount.asm ---- src/mpn/x86/k6/mmx/popcount.asm 2010-12-31 08:18:54.000000000 +0100 -+++ src.patched/mpn/x86/k6/mmx/popcount.asm 2012-04-07 14:27:55.688279899 +0200 -@@ -34,7 +34,7 @@ - C The code here isn't optimal, but it's already a 2x speedup over the plain - C integer mpn/generic/popcount.c,hamdist.c. - --define(OPERATION_popcount,1) -+define(`OPERATION_popcount',1) - - ifdef(`OPERATION_popcount',, - `ifdef(`OPERATION_hamdist',, -diff -ru src/mpn/x86/k6/mmx/xnor_n.asm src.patched/mpn/x86/k6/mmx/xnor_n.asm ---- src/mpn/x86/k6/mmx/xnor_n.asm 2010-12-31 08:15:05.000000000 +0100 -+++ src.patched/mpn/x86/k6/mmx/xnor_n.asm 2012-04-07 14:27:55.718279824 +0200 -@@ -41,7 +41,7 @@ - dnl M4_*_neg_dst means whether to negate the final result before writing - dnl M4_*_neg_src2 means whether to negate the src2 values before using them - --define(OPERATION_xnor_n,1) -+define(`OPERATION_xnor_n',1) - - define(M4_choose_op, - m4_assert_numargs(7) -diff -ru src/mpn/x86/k6/mmx/xor_n.asm src.patched/mpn/x86/k6/mmx/xor_n.asm ---- src/mpn/x86/k6/mmx/xor_n.asm 2010-12-31 08:14:55.000000000 +0100 -+++ src.patched/mpn/x86/k6/mmx/xor_n.asm 2012-04-07 14:27:55.728269986 +0200 -@@ -41,7 +41,7 @@ - dnl M4_*_neg_dst means whether to negate the final result before writing - dnl M4_*_neg_src2 means whether to negate the src2 values before using them - --define(OPERATION_xor_n,1) -+define(`OPERATION_xor_n',1) - - define(M4_choose_op, - m4_assert_numargs(7) -diff -ru src/mpn/x86/k6/sub_n.asm src.patched/mpn/x86/k6/sub_n.asm ---- src/mpn/x86/k6/sub_n.asm 2010-12-31 08:29:24.000000000 +0100 -+++ src.patched/mpn/x86/k6/sub_n.asm 2012-04-07 14:27:55.598269852 +0200 -@@ -24,7 +24,7 @@ - - C K6: normal 3.25 cycles/limb, in-place 2.75 cycles/limb. - --define(OPERATION_sub_n,1) -+define(`OPERATION_sub_n',1) - - ifdef(`OPERATION_add_n', ` - define(M4_inst, adcl) -diff -ru src/mpn/x86/k6/submul_1.asm src.patched/mpn/x86/k6/submul_1.asm ---- src/mpn/x86/k6/submul_1.asm 2010-12-31 08:29:58.000000000 +0100 -+++ src.patched/mpn/x86/k6/submul_1.asm 2012-04-07 14:27:55.608280112 +0200 -@@ -52,7 +52,7 @@ - - deflit(UNROLL_COUNT, 16) - --define(OPERATION_submul_1,1) -+define(`OPERATION_submul_1',1) - - ifdef(`OPERATION_addmul_1', ` - define(M4_inst, addl) -diff -ru src/mpn/x86/k7/add_n.asm src.patched/mpn/x86/k7/add_n.asm ---- src/mpn/x86/k7/add_n.asm 2010-12-31 08:27:25.000000000 +0100 -+++ src.patched/mpn/x86/k7/add_n.asm 2012-04-07 14:27:56.808269459 +0200 -@@ -35,7 +35,7 @@ - - deflit(UNROLL_COUNT, 16) - --define(OPERATION_add_n,1) -+define(`OPERATION_add_n',1) - - ifdef(`OPERATION_add_n', ` - define(M4_inst, adcl) -diff -ru src/mpn/x86/k7/addmul_1.asm src.patched/mpn/x86/k7/addmul_1.asm ---- src/mpn/x86/k7/addmul_1.asm 2010-12-31 08:28:08.000000000 +0100 -+++ src.patched/mpn/x86/k7/addmul_1.asm 2012-04-07 14:27:56.698279971 +0200 -@@ -47,7 +47,7 @@ - - deflit(UNROLL_COUNT, 16) - --define(OPERATION_addmul_1,1) -+define(`OPERATION_addmul_1',1) - - ifdef(`OPERATION_addmul_1',` - define(M4_inst, addl) -diff -ru src/mpn/x86/k7/mmx/hamdist.asm src.patched/mpn/x86/k7/mmx/hamdist.asm ---- src/mpn/x86/k7/mmx/hamdist.asm 2010-12-31 08:20:40.000000000 +0100 -+++ src.patched/mpn/x86/k7/mmx/hamdist.asm 2012-04-07 14:27:56.728280013 +0200 -@@ -38,7 +38,7 @@ - C MMX instructions" in the Athlon Optimization Guide, AMD document 22007, - C page 158 of rev E (reference in mpn/x86/k7/README). - --define(OPERATION_hamdist,1) -+define(`OPERATION_hamdist',1) - - ifdef(`OPERATION_popcount',, - `ifdef(`OPERATION_hamdist',, -diff -ru src/mpn/x86/k7/mmx/popcount.asm src.patched/mpn/x86/k7/mmx/popcount.asm ---- src/mpn/x86/k7/mmx/popcount.asm 2010-12-31 08:20:30.000000000 +0100 -+++ src.patched/mpn/x86/k7/mmx/popcount.asm 2012-04-07 14:27:56.728280013 +0200 -@@ -38,7 +38,7 @@ - C MMX instructions" in the Athlon Optimization Guide, AMD document 22007, - C page 158 of rev E (reference in mpn/x86/k7/README). - --define(OPERATION_popcount,1) -+define(`OPERATION_popcount',1) - - ifdef(`OPERATION_popcount',, - `ifdef(`OPERATION_hamdist',, -diff -ru src/mpn/x86/k7/sub_n.asm src.patched/mpn/x86/k7/sub_n.asm ---- src/mpn/x86/k7/sub_n.asm 2010-12-31 08:27:37.000000000 +0100 -+++ src.patched/mpn/x86/k7/sub_n.asm 2012-04-07 14:27:56.668269259 +0200 -@@ -35,7 +35,7 @@ - - deflit(UNROLL_COUNT, 16) - --define(OPERATION_sub_n,1) -+define(`OPERATION_sub_n',1) - - ifdef(`OPERATION_add_n', ` - define(M4_inst, adcl) -diff -ru src/mpn/x86/k7/submul_1.asm src.patched/mpn/x86/k7/submul_1.asm ---- src/mpn/x86/k7/submul_1.asm 2010-12-31 08:28:18.000000000 +0100 -+++ src.patched/mpn/x86/k7/submul_1.asm 2012-04-07 14:27:56.678279889 +0200 -@@ -47,7 +47,7 @@ - - deflit(UNROLL_COUNT, 16) - --define(OPERATION_submul_1,1) -+define(`OPERATION_submul_1',1) - - ifdef(`OPERATION_addmul_1',` - define(M4_inst, addl) -diff -ru src/mpn/x86/nehalem/hamdist.asm src.patched/mpn/x86/nehalem/hamdist.asm ---- src/mpn/x86/nehalem/hamdist.asm 2010-12-31 08:20:07.000000000 +0100 -+++ src.patched/mpn/x86/nehalem/hamdist.asm 2012-04-07 14:27:55.478269000 +0200 -@@ -38,7 +38,7 @@ - C might be possible, but 8.5 c/l relying on out-of-order execution is - C already quite reasonable. - --define(OPERATION_hamdist,1) -+define(`OPERATION_hamdist',1) - - ifdef(`OPERATION_popcount',, - `ifdef(`OPERATION_hamdist',, -diff -ru src/mpn/x86/nehalem/popcount.asm src.patched/mpn/x86/nehalem/popcount.asm ---- src/mpn/x86/nehalem/popcount.asm 2010-12-31 08:19:57.000000000 +0100 -+++ src.patched/mpn/x86/nehalem/popcount.asm 2012-04-07 14:27:55.468288235 +0200 -@@ -38,7 +38,7 @@ - C might be possible, but 8.5 c/l relying on out-of-order execution is - C already quite reasonable. - --define(OPERATION_popcount,1) -+define(`OPERATION_popcount',1) - - ifdef(`OPERATION_popcount',, - `ifdef(`OPERATION_hamdist',, -diff -ru src/mpn/x86/p6/addmul_1.asm src.patched/mpn/x86/p6/addmul_1.asm ---- src/mpn/x86/p6/addmul_1.asm 2012-10-03 22:07:16.000000000 +0200 -+++ src.patched/mpn/x86/p6/addmul_1.asm 2012-11-29 13:27:59.761725414 +0100 -@@ -46,7 +46,7 @@ - - deflit(UNROLL_COUNT, 16) - --define(OPERATION_addmul_1,1) -+define(`OPERATION_addmul_1',1) - - ifdef(`OPERATION_addmul_1', ` - define(M4_inst, addl) -diff -ru src/mpn/x86/p6/submul_1.asm src.patched/mpn/x86/p6/submul_1.asm ---- src/mpn/x86/p6/submul_1.asm 2012-10-03 22:07:16.000000000 +0200 -+++ src.patched/mpn/x86/p6/submul_1.asm 2012-11-29 13:27:59.681725417 +0100 -@@ -46,7 +46,7 @@ - - deflit(UNROLL_COUNT, 16) - --define(OPERATION_submul_1,1) -+define(`OPERATION_submul_1',1) - - ifdef(`OPERATION_addmul_1', ` - define(M4_inst, addl) -diff -ru src/mpn/x86/pentium/add_n.asm src.patched/mpn/x86/pentium/add_n.asm ---- src/mpn/x86/pentium/add_n.asm 2010-12-31 08:32:53.000000000 +0100 -+++ src.patched/mpn/x86/pentium/add_n.asm 2012-04-07 14:27:56.318273599 +0200 -@@ -25,7 +25,7 @@ - - C P5: 2.375 cycles/limb - --define(OPERATION_add_n,1) -+define(`OPERATION_add_n',1) - - ifdef(`OPERATION_add_n',` - define(M4_inst, adcl) -diff -ru src/mpn/x86/pentium/addmul_1.asm src.patched/mpn/x86/pentium/addmul_1.asm ---- src/mpn/x86/pentium/addmul_1.asm 2010-12-31 08:33:16.000000000 +0100 -+++ src.patched/mpn/x86/pentium/addmul_1.asm 2012-04-07 14:27:56.238269339 +0200 -@@ -25,7 +25,7 @@ - - C P5: 14.0 cycles/limb - --define(OPERATION_addmul_1,1) -+define(`OPERATION_addmul_1',1) - - ifdef(`OPERATION_addmul_1', ` - define(M4_inst, addl) -diff -ru src/mpn/x86/pentium/and_n.asm src.patched/mpn/x86/pentium/and_n.asm ---- src/mpn/x86/pentium/and_n.asm 2010-12-31 07:06:04.000000000 +0100 -+++ src.patched/mpn/x86/pentium/and_n.asm 2012-04-07 14:27:56.348273028 +0200 -@@ -25,7 +25,7 @@ - C P5: 3.0 c/l and, ior, xor - C 3.5 c/l andn, iorn, nand, nior, xnor - --define(OPERATION_and_n,1) -+define(`OPERATION_and_n',1) - - define(M4_choose_op, - `ifdef(`OPERATION_$1',` -diff -ru src/mpn/x86/pentium/andn_n.asm src.patched/mpn/x86/pentium/andn_n.asm ---- src/mpn/x86/pentium/andn_n.asm 2010-12-31 07:08:32.000000000 +0100 -+++ src.patched/mpn/x86/pentium/andn_n.asm 2012-04-07 14:27:56.148279866 +0200 -@@ -25,7 +25,7 @@ - C P5: 3.0 c/l and, ior, xor - C 3.5 c/l andn, iorn, nand, nior, xnor - --define(OPERATION_andn_n,1) -+define(`OPERATION_andn_n',1) - - define(M4_choose_op, - `ifdef(`OPERATION_$1',` -diff -ru src/mpn/x86/pentium/ior_n.asm src.patched/mpn/x86/pentium/ior_n.asm ---- src/mpn/x86/pentium/ior_n.asm 2010-12-31 07:00:34.000000000 +0100 -+++ src.patched/mpn/x86/pentium/ior_n.asm 2012-04-07 14:27:56.128280857 +0200 -@@ -25,7 +25,7 @@ - C P5: 3.0 c/l and, ior, xor - C 3.5 c/l andn, iorn, nand, nior, xnor - --define(OPERATION_ior_n,1) -+define(`OPERATION_ior_n',1) - - define(M4_choose_op, - `ifdef(`OPERATION_$1',` -diff -ru src/mpn/x86/pentium/iorn_n.asm src.patched/mpn/x86/pentium/iorn_n.asm ---- src/mpn/x86/pentium/iorn_n.asm 2010-12-31 07:01:04.000000000 +0100 -+++ src.patched/mpn/x86/pentium/iorn_n.asm 2012-04-07 14:27:56.338280957 +0200 -@@ -25,7 +25,7 @@ - C P5: 3.0 c/l and, ior, xor - C 3.5 c/l andn, iorn, nand, nior, xnor - --define(OPERATION_iorn_n,1) -+define(`OPERATION_iorn_n',1) - - define(M4_choose_op, - `ifdef(`OPERATION_$1',` -diff -ru src/mpn/x86/pentium/nand_n.asm src.patched/mpn/x86/pentium/nand_n.asm ---- src/mpn/x86/pentium/nand_n.asm 2010-12-31 07:08:55.000000000 +0100 -+++ src.patched/mpn/x86/pentium/nand_n.asm 2012-04-07 14:27:56.158270225 +0200 -@@ -25,7 +25,7 @@ - C P5: 3.0 c/l and, ior, xor - C 3.5 c/l andn, iorn, nand, nior, xnor - --define(OPERATION_nand_n,1) -+define(`OPERATION_nand_n',1) - - define(M4_choose_op, - `ifdef(`OPERATION_$1',` -diff -ru src/mpn/x86/pentium/nior_n.asm src.patched/mpn/x86/pentium/nior_n.asm ---- src/mpn/x86/pentium/nior_n.asm 2010-12-31 07:01:31.000000000 +0100 -+++ src.patched/mpn/x86/pentium/nior_n.asm 2012-04-07 14:27:56.188269997 +0200 -@@ -25,7 +25,7 @@ - C P5: 3.0 c/l and, ior, xor - C 3.5 c/l andn, iorn, nand, nior, xnor - --define(OPERATION_nior_n,1) -+define(`OPERATION_nior_n',1) - - define(M4_choose_op, - `ifdef(`OPERATION_$1',` -diff -ru src/mpn/x86/pentium/sub_n.asm src.patched/mpn/x86/pentium/sub_n.asm ---- src/mpn/x86/pentium/sub_n.asm 2010-12-31 08:33:04.000000000 +0100 -+++ src.patched/mpn/x86/pentium/sub_n.asm 2012-04-07 14:27:56.178269643 +0200 -@@ -25,7 +25,7 @@ - - C P5: 2.375 cycles/limb - --define(OPERATION_sub_n,1) -+define(`OPERATION_sub_n',1) - - ifdef(`OPERATION_add_n',` - define(M4_inst, adcl) -diff -ru src/mpn/x86/pentium/submul_1.asm src.patched/mpn/x86/pentium/submul_1.asm ---- src/mpn/x86/pentium/submul_1.asm 2010-12-31 08:33:30.000000000 +0100 -+++ src.patched/mpn/x86/pentium/submul_1.asm 2012-04-07 14:27:56.198268327 +0200 -@@ -25,7 +25,7 @@ - - C P5: 14.0 cycles/limb - --define(OPERATION_submul_1,1) -+define(`OPERATION_submul_1',1) - - ifdef(`OPERATION_addmul_1', ` - define(M4_inst, addl) -diff -ru src/mpn/x86/pentium/xnor_n.asm src.patched/mpn/x86/pentium/xnor_n.asm ---- src/mpn/x86/pentium/xnor_n.asm 2010-12-31 07:09:38.000000000 +0100 -+++ src.patched/mpn/x86/pentium/xnor_n.asm 2012-04-07 14:27:56.258279761 +0200 -@@ -25,7 +25,7 @@ - C P5: 3.0 c/l and, ior, xor - C 3.5 c/l andn, iorn, nand, nior, xnor - --define(OPERATION_xnor_n,1) -+define(`OPERATION_xnor_n',1) - - define(M4_choose_op, - `ifdef(`OPERATION_$1',` -diff -ru src/mpn/x86/pentium/xor_n.asm src.patched/mpn/x86/pentium/xor_n.asm ---- src/mpn/x86/pentium/xor_n.asm 2010-12-31 07:09:16.000000000 +0100 -+++ src.patched/mpn/x86/pentium/xor_n.asm 2012-04-07 14:27:56.268279961 +0200 -@@ -25,7 +25,7 @@ - C P5: 3.0 c/l and, ior, xor - C 3.5 c/l andn, iorn, nand, nior, xnor - --define(OPERATION_xor_n,1) -+define(`OPERATION_xor_n',1) - - define(M4_choose_op, - `ifdef(`OPERATION_$1',` -diff -ru src/mpn/x86/pentium4/mmx/hamdist.asm src.patched/mpn/x86/pentium4/mmx/hamdist.asm ---- src/mpn/x86/pentium4/mmx/hamdist.asm 2010-12-31 08:19:38.000000000 +0100 -+++ src.patched/mpn/x86/pentium4/mmx/hamdist.asm 2012-04-07 14:27:56.508279960 +0200 -@@ -38,7 +38,7 @@ - C might be possible, but 8.5 c/l relying on out-of-order execution is - C already quite reasonable. - --define(OPERATION_hamdist,1) -+define(`OPERATION_hamdist',1) - - ifdef(`OPERATION_popcount',, - `ifdef(`OPERATION_hamdist',, -diff -ru src/mpn/x86/pentium4/mmx/popcount.asm src.patched/mpn/x86/pentium4/mmx/popcount.asm ---- src/mpn/x86/pentium4/mmx/popcount.asm 2010-12-31 08:19:29.000000000 +0100 -+++ src.patched/mpn/x86/pentium4/mmx/popcount.asm 2012-04-07 14:27:56.498279890 +0200 -@@ -38,7 +38,7 @@ - C might be possible, but 8.5 c/l relying on out-of-order execution is - C already quite reasonable. - --define(OPERATION_popcount,1) -+define(`OPERATION_popcount',1) - - ifdef(`OPERATION_popcount',, - `ifdef(`OPERATION_hamdist',, -diff -ru src/mpn/x86/sub_n.asm src.patched/mpn/x86/sub_n.asm ---- src/mpn/x86/sub_n.asm 2010-12-31 08:30:28.000000000 +0100 -+++ src.patched/mpn/x86/sub_n.asm 2012-04-07 14:27:55.438279940 +0200 -@@ -30,7 +30,7 @@ - C K7: 2.25 - C P4: 8.75 - --define(OPERATION_sub_n,1) -+define(`OPERATION_sub_n',1) - - ifdef(`OPERATION_add_n',` - define(M4_inst, adcl) -diff -ru src/mpn/x86/submul_1.asm src.patched/mpn/x86/submul_1.asm ---- src/mpn/x86/submul_1.asm 2010-12-31 08:21:49.000000000 +0100 -+++ src.patched/mpn/x86/submul_1.asm 2012-04-07 14:27:55.808285202 +0200 -@@ -38,7 +38,7 @@ - C K7: 5.25 - C K8: - --define(OPERATION_submul_1,1) -+define(`OPERATION_submul_1',1) - - ifdef(`OPERATION_addmul_1',` - define(M4_inst, addl) diff --git a/build/pkgs/mpir/spkg-install b/build/pkgs/mpir/spkg-install index 7172e4a76bd..4800849f1e9 100755 --- a/build/pkgs/mpir/spkg-install +++ b/build/pkgs/mpir/spkg-install @@ -162,9 +162,11 @@ case "$UNAME" in fi ;; # Linux CYGWIN) - # For the moment, Cygwin is only 32-bits - # and configure gets lost if the hardware is 64 bits - ABI=32 + if uname -a | grep x86_64 ; then + ABI=64 + else + ABI=32 + fi ;; *) # e.g. AIX or HP-UX echo >&2 "Warning: Your platform ($UNAME) isn't yet explicitly supported" \ From 5d7a2e99278f657b5d17f527d3d8f1c38e125a02 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Sun, 13 Apr 2014 21:44:20 +0200 Subject: [PATCH 012/698] Remove unnecessary fix for MPIR. --- build/pkgs/mpir/checksums.ini | 6 +++--- build/pkgs/mpir/spkg-install | 14 +------------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/build/pkgs/mpir/checksums.ini b/build/pkgs/mpir/checksums.ini index 07b4087050e..173e594f5a3 100644 --- a/build/pkgs/mpir/checksums.ini +++ b/build/pkgs/mpir/checksums.ini @@ -1,4 +1,4 @@ tarball=mpir-VERSION.tar.bz2 -sha1=7d5a66f83acfc420dac41bda06928d2564bd0c79 -md5=820a690643e2708f244eae9aac668d8a -cksum=2611197091 +sha1=e677ffb80ef7a04d99c017fcc365cff2a212b7aa +md5=f606b224589aee316d9f902b8973bf68 +cksum=3791195729 diff --git a/build/pkgs/mpir/spkg-install b/build/pkgs/mpir/spkg-install index 4800849f1e9..6ded48b3c96 100755 --- a/build/pkgs/mpir/spkg-install +++ b/build/pkgs/mpir/spkg-install @@ -14,21 +14,9 @@ cd src/ # Apply patches (if any): ############################################################################### -# Before applying patches, we manually move two wrongly named files, -# rather than doing this with diff/patch which lacks the ability of properly -# detecting filename changes. See Trac #13137. -# This fix can (and will have to) be removed once integrated upstream. -echo "Renaming *,asm files to *.asm..." -mv mpn/x86/p6/addmul_1,asm mpn/x86/p6/addmul_1.asm && -mv mpn/x86/p6/submul_1,asm mpn/x86/p6/submul_1.asm -if [ $? -ne 0 ]; then - echo >&2 "Error: moving *,asm files failed." - exit 1 -fi - echo "Applying patches to upstream sources..." for patch in ../patches/*.patch; do - patch -p1 <"$patch" + patch -p1 <"$patch" || continue if [ $? -ne 0 ]; then echo >&2 "Error: '$patch' failed to apply." exit 1 From da483e1e109f71c93d22fa1ab115b12ede4fcaca Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Mon, 14 Apr 2014 03:02:24 -0700 Subject: [PATCH 013/698] Correct MPIR spkg-install scripts for non-exisiting patches. --- build/pkgs/mpir/spkg-install | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/pkgs/mpir/spkg-install b/build/pkgs/mpir/spkg-install index 6ded48b3c96..6157f605992 100755 --- a/build/pkgs/mpir/spkg-install +++ b/build/pkgs/mpir/spkg-install @@ -16,7 +16,8 @@ cd src/ echo "Applying patches to upstream sources..." for patch in ../patches/*.patch; do - patch -p1 <"$patch" || continue + [ -r "$patch" ] || continue # ignore non-readable / non-existent files + patch -p1 <"$patch" if [ $? -ne 0 ]; then echo >&2 "Error: '$patch' failed to apply." exit 1 From 499aae1d2aa8c875cabf0d35ab68416e04758843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Mon, 21 Apr 2014 22:51:16 +0200 Subject: [PATCH 014/698] Trac 16058: change the label in the sphinx-autodoc files for .__init__.py to --- src/doc/common/builder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/common/builder.py b/src/doc/common/builder.py index 41237bfe72e..cd2518bfc3b 100644 --- a/src/doc/common/builder.py +++ b/src/doc/common/builder.py @@ -958,7 +958,7 @@ def write_auto_rest_file(self, module_name): # Don't doctest the autogenerated file. outfile.write(".. nodoctest\n\n") # Now write the actual content. - outfile.write(".. _%s:\n\n"%module_name) + outfile.write(".. _%s:\n\n"%(module_name.replace(".__init__",""))) outfile.write(title + '\n') outfile.write('='*len(title) + "\n\n") outfile.write('.. This file has been autogenerated.\n\n') From 6755031ec0d09d584b23f58663f2f9da896cfc84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Tue, 22 Apr 2014 10:49:14 +0200 Subject: [PATCH 015/698] Trac 16058: Reorganize the documentation indexes into src/sage/combinat - For example, the thematic index src/doc/en/reference/combinat/crystals.rst is now in: src/sage/combinat/crystals/__init__.py and is accessible through sage.combinat.crystals? (to be discussed: should this be put in all.py instead?) - What's left in doc/en/reference/combinat is basically autogenerated. (the building of module_list.rst there still needs to be regenerated by hand) - All p/cython files in sage/combinat/ are now included in the reference manual - Improved thematic indexes - New thematic indexes: algebraic_combinatorics, catalog_partitions, counting, enumerated_sets - Fixed some documentation syntax glitches here and there - Added the catalogs of permutation groups and matrix groups to the reference manual so that we can link to them. - Draft of sage.combinat.quickref TODO: - proof reading - choosing the right entry points - checking that the links are functional - deciding on how to link to classes/functions (in the index we would want to have the title of the documentation of the class rather than the name of the class. Or maybe both). --- src/doc/en/reference/algebras/index.rst | 3 + .../combinat/algebraic_combinatorics.rst | 29 -- .../reference/combinat/cluster_algebras.rst | 9 - src/doc/en/reference/combinat/crystals.rst | 38 -- src/doc/en/reference/combinat/designs.rst | 23 - src/doc/en/reference/combinat/developer.rst | 13 - src/doc/en/reference/combinat/index.rst | 14 +- src/doc/en/reference/combinat/module_list.rst | 405 +++++++++++++----- src/doc/en/reference/combinat/ncsf_qsym.rst | 11 - src/doc/en/reference/combinat/ncsym.rst | 10 - src/doc/en/reference/combinat/partitions.rst | 10 - src/doc/en/reference/combinat/posets.rst | 13 - .../en/reference/combinat/rc_bijections.rst | 17 - .../combinat/rigged_configurations.rst | 19 - .../en/reference/combinat/root_systems.rst | 47 -- src/doc/en/reference/combinat/species.rst | 54 --- .../combinat/symmetric_functions.rst | 26 -- src/doc/en/reference/combinat/tableaux.rst | 13 - src/doc/en/reference/combinat/words.rst | 17 - src/sage/combinat/__init__.py | 116 ++--- src/sage/combinat/algebraic_combinatorics.py | 60 +++ src/sage/combinat/catalog_partitions.py | 22 + .../cluster_algebra_quiver/__init__.py | 14 +- src/sage/combinat/counting.py | 12 + src/sage/combinat/crystals/__init__.py | 34 +- src/sage/combinat/crystals/catalog.py | 2 + src/sage/combinat/crystals/crystals.py | 3 +- src/sage/combinat/designs/__init__.py | 20 + src/sage/combinat/enumerated_sets.py | 132 ++++++ src/sage/combinat/index.py | 179 -------- src/sage/combinat/ncsf_qsym/__init__.py | 9 + src/sage/combinat/ncsym/__init__.py | 10 + src/sage/combinat/partition.py | 2 +- src/sage/combinat/posets/__init__.py | 12 +- src/sage/combinat/quickref.py | 53 +++ .../rigged_configurations/__init__.py | 27 ++ src/sage/combinat/root_system/__init__.py | 50 +++ .../combinat/root_system/pieri_factors.py | 57 +-- src/sage/combinat/root_system/root_system.py | 5 +- src/sage/combinat/sf/__init__.py | 28 ++ src/sage/combinat/species/__init__.py | 53 +++ src/sage/combinat/words/__init__.py | 19 + .../combinat/words/word_infinite_datatypes.py | 5 +- 43 files changed, 925 insertions(+), 770 deletions(-) delete mode 100644 src/doc/en/reference/combinat/algebraic_combinatorics.rst delete mode 100644 src/doc/en/reference/combinat/cluster_algebras.rst delete mode 100644 src/doc/en/reference/combinat/crystals.rst delete mode 100644 src/doc/en/reference/combinat/designs.rst delete mode 100644 src/doc/en/reference/combinat/developer.rst delete mode 100644 src/doc/en/reference/combinat/ncsf_qsym.rst delete mode 100644 src/doc/en/reference/combinat/ncsym.rst delete mode 100644 src/doc/en/reference/combinat/partitions.rst delete mode 100644 src/doc/en/reference/combinat/posets.rst delete mode 100644 src/doc/en/reference/combinat/rc_bijections.rst delete mode 100644 src/doc/en/reference/combinat/rigged_configurations.rst delete mode 100644 src/doc/en/reference/combinat/root_systems.rst delete mode 100644 src/doc/en/reference/combinat/species.rst delete mode 100644 src/doc/en/reference/combinat/symmetric_functions.rst delete mode 100644 src/doc/en/reference/combinat/tableaux.rst delete mode 100644 src/doc/en/reference/combinat/words.rst create mode 100644 src/sage/combinat/algebraic_combinatorics.py create mode 100644 src/sage/combinat/catalog_partitions.py create mode 100644 src/sage/combinat/counting.py create mode 100644 src/sage/combinat/enumerated_sets.py delete mode 100644 src/sage/combinat/index.py create mode 100644 src/sage/combinat/quickref.py diff --git a/src/doc/en/reference/algebras/index.rst b/src/doc/en/reference/algebras/index.rst index f13340962dc..08a4fc84ec8 100644 --- a/src/doc/en/reference/algebras/index.rst +++ b/src/doc/en/reference/algebras/index.rst @@ -22,6 +22,9 @@ Algebras sage/algebras/group_algebra_new sage/algebras/iwahori_hecke_algebra + sage/algebras/iwahori_hecke_algebra + sage/algebras/nil_coxeter_algebra + sage/algebras/affine_nil_temperley_lieb sage/algebras/hall_algebra diff --git a/src/doc/en/reference/combinat/algebraic_combinatorics.rst b/src/doc/en/reference/combinat/algebraic_combinatorics.rst deleted file mode 100644 index 8352070ad1a..00000000000 --- a/src/doc/en/reference/combinat/algebraic_combinatorics.rst +++ /dev/null @@ -1,29 +0,0 @@ -.. _algebraic_combinatorics: - -Algebraic combinatorics -======================= - -- :class:`sage.combinat.diagram_algebras.PartitionAlgebra` - - -.. toctree:: - :maxdepth: 2 - - ../sage/combinat/descent_algebra - ../sage/combinat/diagram_algebras - ../sage/combinat/symmetric_group_algebra - ../sage/combinat/symmetric_group_representations - ../sage/combinat/yang_baxter_graph - - ../sage/combinat/schubert_polynomial - ../sage/combinat/partition_algebra - ../sage/algebras/iwahori_hecke_algebra - ../sage/algebras/nil_coxeter_algebra - ../sage/algebras/affine_nil_temperley_lieb - - ../sage/combinat/kazhdan_lusztig - - ../symmetric_functions - ../ncsf_qsym - ../ncsym - ../sage/combinat/hall_polynomial diff --git a/src/doc/en/reference/combinat/cluster_algebras.rst b/src/doc/en/reference/combinat/cluster_algebras.rst deleted file mode 100644 index 926496fe874..00000000000 --- a/src/doc/en/reference/combinat/cluster_algebras.rst +++ /dev/null @@ -1,9 +0,0 @@ -Cluster Algebras and Quivers -============================ - -.. toctree:: - :maxdepth: 2 - - ../sage/combinat/cluster_algebra_quiver/quiver_mutation_type - ../sage/combinat/cluster_algebra_quiver/quiver - ../sage/combinat/cluster_algebra_quiver/cluster_seed diff --git a/src/doc/en/reference/combinat/crystals.rst b/src/doc/en/reference/combinat/crystals.rst deleted file mode 100644 index c7888ada12e..00000000000 --- a/src/doc/en/reference/combinat/crystals.rst +++ /dev/null @@ -1,38 +0,0 @@ -Crystals -======== - -Catalogs --------- - -.. toctree:: - :maxdepth: 2 - - sage/combinat/crystals/catalog - sage/combinat/crystals/catalog_elementary_crystals - sage/combinat/crystals/catalog_infinity_crystals - sage/combinat/crystals/catalog_kirillov_reshetikhin - -Crystal Modules ---------------- - -.. toctree:: - :maxdepth: 2 - - sage/combinat/crystals/affine - sage/combinat/crystals/affine_factorization - sage/combinat/crystals/alcove_path - sage/combinat/crystals/infinity_crystals - sage/combinat/crystals/crystals - sage/combinat/crystals/generalized_young_walls - sage/combinat/crystals/letters - sage/combinat/crystals/monomial_crystals - sage/combinat/crystals/direct_sum - sage/combinat/crystals/elementary_crystals - sage/combinat/crystals/fast_crystals - sage/combinat/crystals/highest_weight_crystals - sage/combinat/crystals/kirillov_reshetikhin - sage/combinat/crystals/kyoto_path_model - sage/combinat/crystals/littelmann_path - sage/combinat/crystals/spins - sage/combinat/crystals/tensor_product - diff --git a/src/doc/en/reference/combinat/designs.rst b/src/doc/en/reference/combinat/designs.rst deleted file mode 100644 index 4d414d18bf4..00000000000 --- a/src/doc/en/reference/combinat/designs.rst +++ /dev/null @@ -1,23 +0,0 @@ -Designs and Incidence Structures -================================ - -.. toctree:: - :maxdepth: 1 - - ../sage/combinat/designs/covering_design - ../sage/combinat/designs/ext_rep - ../sage/combinat/designs/incidence_structures - ../sage/combinat/designs/design_catalog - -Constructions -------------- - -.. toctree:: - :maxdepth: 1 - - ../sage/combinat/designs/block_design - ../sage/combinat/designs/bibd - ../sage/combinat/designs/steiner_quadruple_systems - ../sage/combinat/designs/latin_squares - ../sage/combinat/designs/orthogonal_arrays - diff --git a/src/doc/en/reference/combinat/developer.rst b/src/doc/en/reference/combinat/developer.rst deleted file mode 100644 index da4c0f99874..00000000000 --- a/src/doc/en/reference/combinat/developer.rst +++ /dev/null @@ -1,13 +0,0 @@ -Developer Tools -=============== - -.. toctree:: - :maxdepth: 2 - - ../sage/combinat/output - ../sage/combinat/permutation_nk - ../sage/combinat/split_nk - ../sage/combinat/choose_nk - ../sage/combinat/multichoose_nk - ../sage/combinat/ranker - diff --git a/src/doc/en/reference/combinat/index.rst b/src/doc/en/reference/combinat/index.rst index 4b2090e2d8c..e2c2c7389a8 100644 --- a/src/doc/en/reference/combinat/index.rst +++ b/src/doc/en/reference/combinat/index.rst @@ -1,19 +1,7 @@ Combinatorics ============= -Introductory material ---------------------- - -- :mod:`sage.combinat` -- :mod:`sage.combinat.tutorial` - - -Thematic indexes ----------------- - -- :ref:`algebraic_combinatorics` - -.. .. include:: sage/combinat/index.rst +.. automodule:: sage.combinat .. toctree:: :maxdepth: 1 diff --git a/src/doc/en/reference/combinat/module_list.rst b/src/doc/en/reference/combinat/module_list.rst index 87d55d9b91b..88aad47ef79 100644 --- a/src/doc/en/reference/combinat/module_list.rst +++ b/src/doc/en/reference/combinat/module_list.rst @@ -1,122 +1,307 @@ Alphabetical module list ======================== -Submodules ----------- +.. NOTE:: -.. toctree:: - :maxdepth: 1 + This is built automatically by running in src/sage/combinat: - symmetric_functions - ncsf_qsym - posets - root_systems - crystals + for x in **/*.py*; do echo " sage/combinat/"`echo $x | sed 's/\.py.?$//'`; done >! /tmp/module_list -.. sage/combinat/ncsf_qsym/index -.. sage/combinat/ncsym/index -.. sage/combinat/posets/index -.. sage/combinat/cluster_algebras/index -.. sage/combinat/crystals/index -.. sage/combinat/designs/index -.. sage/combinat/rigged_configurations/index -.. sage/combinat/root_systems/index -.. sage/combinat/sf/index -.. sage/combinat/species/index -.. sage/combinat/words/index +.. TODO:: -Modules -------- + Improve by not flattening the module hierarchical structure .. toctree:: - :maxdepth: 2 + :maxdepth: 1 + + sage/combinat/abstract_tree + sage/combinat/affine_permutation + sage/combinat/algebraic_combinatorics + sage/combinat/all + sage/combinat/alternating_sign_matrix + sage/combinat/backtrack + sage/combinat/binary_recurrence_sequences + sage/combinat/binary_tree + sage/combinat/cartesian_product + sage/combinat/catalog_partitions + sage/combinat/choose_nk + sage/combinat/cluster_algebra_quiver/all + sage/combinat/cluster_algebra_quiver/cluster_seed + sage/combinat/cluster_algebra_quiver/__init__ + sage/combinat/cluster_algebra_quiver/mutation_class + sage/combinat/cluster_algebra_quiver/mutation_type + sage/combinat/cluster_algebra_quiver/quiver_mutation_type + sage/combinat/cluster_algebra_quiver/quiver + sage/combinat/combinat_cython + sage/combinat/combination + sage/combinat/combinatorial_algebra + sage/combinat/combinatorial_map + sage/combinat/combinat + sage/combinat/composition + sage/combinat/composition_signed + sage/combinat/composition_tableau + sage/combinat/core + sage/combinat/counting + sage/combinat/crystals/affine_factorization + sage/combinat/crystals/affine + sage/combinat/crystals/alcove_path + sage/combinat/crystals/all + sage/combinat/crystals/catalog_elementary_crystals + sage/combinat/crystals/catalog_infinity_crystals + sage/combinat/crystals/catalog_kirillov_reshetikhin + sage/combinat/crystals/catalog + sage/combinat/crystals/crystals + sage/combinat/crystals/direct_sum + sage/combinat/crystals/elementary_crystals + sage/combinat/crystals/fast_crystals + sage/combinat/crystals/generalized_young_walls + sage/combinat/crystals/highest_weight_crystals + sage/combinat/crystals/infinity_crystals + sage/combinat/crystals/__init__ + sage/combinat/crystals/kirillov_reshetikhin + sage/combinat/crystals/kyoto_path_model + sage/combinat/crystals/letters + sage/combinat/crystals/littelmann_path + sage/combinat/crystals/monomial_crystals + sage/combinat/crystals/spins + sage/combinat/crystals/tensor_product + sage/combinat/cyclic_sieving_phenomenon + sage/combinat/debruijn_sequence + sage/combinat/degree_sequences + sage/combinat/derangements + sage/combinat/descent_algebra + sage/combinat/designs/all + sage/combinat/designs/bibd + sage/combinat/designs/block_design + sage/combinat/designs/covering_design + sage/combinat/designs/design_catalog + sage/combinat/designs/ext_rep + sage/combinat/designs/incidence_structures + sage/combinat/designs/__init__ + sage/combinat/designs/latin_squares + sage/combinat/designs/orthogonal_arrays + sage/combinat/designs/steiner_quadruple_systems + sage/combinat/diagram_algebras + sage/combinat/dict_addition + sage/combinat/dlx + sage/combinat/dyck_word + sage/combinat/enumerated_sets + sage/combinat/enumeration_mod_permgroup + sage/combinat/e_one_star + sage/combinat/expnums + sage/combinat/family + sage/combinat/finite_class + sage/combinat/finite_state_machine + sage/combinat/free_module + sage/combinat/gelfand_tsetlin_patterns + sage/combinat/graph_path + sage/combinat/hall_polynomial + sage/combinat/__init__ + sage/combinat/integer_list + sage/combinat/integer_matrices + sage/combinat/integer_vector + sage/combinat/integer_vectors_mod_permgroup + sage/combinat/integer_vector_weighted + sage/combinat/kazhdan_lusztig + sage/combinat/knutson_tao_puzzles + sage/combinat/k_tableau + sage/combinat/lyndon_word + sage/combinat/matrices/all + sage/combinat/matrices/dancing_links + sage/combinat/matrices/dlxcpp + sage/combinat/matrices/hadamard_matrix + sage/combinat/matrices/__init__ + sage/combinat/matrices/latin + sage/combinat/misc + sage/combinat/multichoose_nk + sage/combinat/ncsf_qsym/all + sage/combinat/ncsf_qsym/combinatorics + sage/combinat/ncsf_qsym/generic_basis_code + sage/combinat/ncsf_qsym/__init__ + sage/combinat/ncsf_qsym/ncsf + sage/combinat/ncsf_qsym/qsym + sage/combinat/ncsf_qsym/tutorial + sage/combinat/ncsym/all + sage/combinat/ncsym/bases + sage/combinat/ncsym/dual + sage/combinat/ncsym/__init__ + sage/combinat/ncsym/ncsym + sage/combinat/necklace + sage/combinat/non_decreasing_parking_function + sage/combinat/ordered_tree + sage/combinat/output + sage/combinat/parking_functions + sage/combinat/partition_algebra + sage/combinat/partition + sage/combinat/partitions + sage/combinat/partition_tuple + sage/combinat/perfect_matching + sage/combinat/permutation_cython + sage/combinat/permutation_nk + sage/combinat/permutation + sage/combinat/posets/all + sage/combinat/posets/elements + sage/combinat/posets/hasse_diagram + sage/combinat/posets/__init__ + sage/combinat/posets/lattices + sage/combinat/posets/linear_extensions + sage/combinat/posets/poset_examples + sage/combinat/posets/posets + sage/combinat/q_analogues + sage/combinat/q_bernoulli + sage/combinat/quickref + sage/combinat/ranker + sage/combinat/restricted_growth + sage/combinat/ribbon + sage/combinat/ribbon_shaped_tableau + sage/combinat/ribbon_tableau + sage/combinat/rigged_configurations/all + sage/combinat/rigged_configurations/bij_abstract_class + sage/combinat/rigged_configurations/bijection + sage/combinat/rigged_configurations/bij_type_A2_dual + sage/combinat/rigged_configurations/bij_type_A2_even + sage/combinat/rigged_configurations/bij_type_A2_odd + sage/combinat/rigged_configurations/bij_type_A + sage/combinat/rigged_configurations/bij_type_B + sage/combinat/rigged_configurations/bij_type_C + sage/combinat/rigged_configurations/bij_type_D + sage/combinat/rigged_configurations/bij_type_D_twisted + sage/combinat/rigged_configurations/__init__ + sage/combinat/rigged_configurations/kleber_tree + sage/combinat/rigged_configurations/kr_tableaux + sage/combinat/rigged_configurations/rigged_configuration_element + sage/combinat/rigged_configurations/rigged_configurations + sage/combinat/rigged_configurations/rigged_partition + sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element + sage/combinat/rigged_configurations/tensor_product_kr_tableaux + sage/combinat/root_system/all + sage/combinat/root_system/ambient_space + sage/combinat/root_system/associahedron + sage/combinat/root_system/branching_rules + sage/combinat/root_system/cartan_matrix + sage/combinat/root_system/cartan_type + sage/combinat/root_system/coxeter_group + sage/combinat/root_system/coxeter_matrix + sage/combinat/root_system/dynkin_diagram + sage/combinat/root_system/__init__ + sage/combinat/root_system/pieri_factors + sage/combinat/root_system/plot + sage/combinat/root_system/root_lattice_realizations + sage/combinat/root_system/root_space + sage/combinat/root_system/root_system + sage/combinat/root_system/type_A_affine + sage/combinat/root_system/type_affine + sage/combinat/root_system/type_A + sage/combinat/root_system/type_B_affine + sage/combinat/root_system/type_BC_affine + sage/combinat/root_system/type_B + sage/combinat/root_system/type_C_affine + sage/combinat/root_system/type_C + sage/combinat/root_system/type_D_affine + sage/combinat/root_system/type_D + sage/combinat/root_system/type_dual + sage/combinat/root_system/type_E_affine + sage/combinat/root_system/type_E + sage/combinat/root_system/type_F_affine + sage/combinat/root_system/type_folded + sage/combinat/root_system/type_F + sage/combinat/root_system/type_G_affine + sage/combinat/root_system/type_G + sage/combinat/root_system/type_H + sage/combinat/root_system/type_I + sage/combinat/root_system/type_reducible + sage/combinat/root_system/type_relabel + sage/combinat/root_system/weight_lattice_realizations + sage/combinat/root_system/weight_space + sage/combinat/root_system/weyl_characters + sage/combinat/root_system/weyl_group + sage/combinat/rsk + sage/combinat/schubert_polynomial + sage/combinat/set_partition_ordered + sage/combinat/set_partition + sage/combinat/sf/all + sage/combinat/sf/classical + sage/combinat/sf/dual + sage/combinat/sf/elementary + sage/combinat/sf/hall_littlewood + sage/combinat/sf/homogeneous + sage/combinat/sf/__init__ + sage/combinat/sf/jack + sage/combinat/sf/k_dual + sage/combinat/sf/kfpoly + sage/combinat/sf/llt + sage/combinat/sf/macdonald + sage/combinat/sf/monomial + sage/combinat/sf/multiplicative + sage/combinat/sf/new_kschur + sage/combinat/sf/ns_macdonald + sage/combinat/sf/orthotriang + sage/combinat/sf/powersum + sage/combinat/sf/schur + sage/combinat/sf/sfa + sage/combinat/sf/sf + sage/combinat/sf/witt + sage/combinat/sidon_sets + sage/combinat/similarity_class_type + sage/combinat/six_vertex_model + sage/combinat/skew_partition + sage/combinat/skew_tableau + sage/combinat/sloane_functions + sage/combinat/species/all + sage/combinat/species/characteristic_species + sage/combinat/species/combinatorial_logarithm + sage/combinat/species/composition_species + sage/combinat/species/cycle_species + sage/combinat/species/empty_species + sage/combinat/species/functorial_composition_species + sage/combinat/species/generating_series + sage/combinat/species/__init__ + sage/combinat/species/library + sage/combinat/species/linear_order_species + sage/combinat/species/misc + sage/combinat/species/partition_species + sage/combinat/species/permutation_species + sage/combinat/species/product_species + sage/combinat/species/recursive_species + sage/combinat/species/series_order + sage/combinat/species/series + sage/combinat/species/set_species + sage/combinat/species/species + sage/combinat/species/stream + sage/combinat/species/structure + sage/combinat/species/subset_species + sage/combinat/species/sum_species + sage/combinat/split_nk + sage/combinat/subset + sage/combinat/subsets_pairwise + sage/combinat/subword + sage/combinat/symmetric_group_algebra + sage/combinat/symmetric_group_representations + sage/combinat/tableau + sage/combinat/tableau_tuple + sage/combinat/tamari_lattices + sage/combinat/tiling + sage/combinat/tools + sage/combinat/tuple + sage/combinat/tutorial + sage/combinat/vector_partition + sage/combinat/words/abstract_word + sage/combinat/words/all + sage/combinat/words/alphabet + sage/combinat/words/finite_word + sage/combinat/words/infinite_word + sage/combinat/words/__init__ + sage/combinat/words/morphism + sage/combinat/words/paths + sage/combinat/words/shuffle_product + sage/combinat/words/suffix_trees + sage/combinat/words/word_datatypes + sage/combinat/words/word_generators + sage/combinat/words/word_infinite_datatypes + sage/combinat/words/word_options + sage/combinat/words/word + sage/combinat/words/words + sage/combinat/yang_baxter_graph - sage/algebras/affine_nil_temperley_lieb - sage/algebras/iwahori_hecke_algebra - sage/algebras/nil_coxeter_algebra - sage/combinat/abstract_tree - sage/combinat/affine_permutation - sage/combinat/alternating_sign_matrix - sage/combinat/binary_recurrence_sequences - sage/combinat/binary_tree - sage/combinat/cartesian_product - sage/combinat/combinat - sage/combinat/combination - sage/combinat/combinatorial_algebra - sage/combinat/combinatorial_map - sage/combinat/composition - sage/combinat/composition_signed - sage/combinat/core - sage/combinat/debruijn_sequence - sage/combinat/degree_sequences - sage/combinat/derangements - sage/combinat/descent_algebra - sage/combinat/diagram_algebras - sage/combinat/dict_addition - sage/combinat/dlx - sage/combinat/dyck_word - sage/combinat/e_one_star - sage/combinat/enumeration_mod_permgroup - sage/combinat/expnums - sage/combinat/finite_class - sage/combinat/finite_state_machine - sage/combinat/free_module - sage/combinat/gelfand_tsetlin_patterns - sage/combinat/graph_path - sage/combinat/hall_polynomial - sage/combinat/hall_polynomial - sage/combinat/integer_list - sage/combinat/integer_matrices - sage/combinat/integer_vector - sage/combinat/integer_vector_weighted - sage/combinat/integer_vectors_mod_permgroup - sage/combinat/k_tableau - sage/combinat/kazhdan_lusztig - sage/combinat/kazhdan_lusztig - sage/combinat/knutson_tao_puzzles - sage/combinat/lyndon_word - sage/combinat/matrices/dlxcpp - sage/combinat/matrices/hadamard_matrix - sage/combinat/matrices/latin - sage/combinat/misc - sage/combinat/necklace - sage/combinat/non_decreasing_parking_function - sage/combinat/ordered_tree - sage/combinat/parking_functions - sage/combinat/partition - sage/combinat/partition - sage/combinat/partition_algebra - sage/combinat/partition_tuple - sage/combinat/partition_tuple - sage/combinat/perfect_matching - sage/combinat/permutation - sage/combinat/q_analogues - sage/combinat/q_bernoulli - sage/combinat/restricted_growth - sage/combinat/ribbon - sage/combinat/ribbon_tableau - sage/combinat/rsk - sage/combinat/schubert_polynomial - sage/combinat/set_partition - sage/combinat/set_partition_ordered - sage/combinat/sidon_sets - sage/combinat/similarity_class_type - sage/combinat/six_vertex_model - sage/combinat/skew_partition - sage/combinat/skew_tableau - sage/combinat/sloane_functions - sage/combinat/subset - sage/combinat/subsets_pairwise - sage/combinat/subword - sage/combinat/symmetric_group_algebra - sage/combinat/symmetric_group_representations - sage/combinat/tableau - sage/combinat/tableau_tuple - sage/combinat/tamari_lattices - sage/combinat/tiling - sage/combinat/tuple - sage/combinat/tutorial - sage/combinat/vector_partition - sage/combinat/yang_baxter_graph .. include:: ../footer.txt diff --git a/src/doc/en/reference/combinat/ncsf_qsym.rst b/src/doc/en/reference/combinat/ncsf_qsym.rst deleted file mode 100644 index 3a9c05aff62..00000000000 --- a/src/doc/en/reference/combinat/ncsf_qsym.rst +++ /dev/null @@ -1,11 +0,0 @@ -Non-Commutative Symmetric Functions and Quasi-Symmetric Functions -================================================================= - -.. toctree:: - :maxdepth: 2 - - sage/combinat/ncsf_qsym/tutorial - sage/combinat/ncsf_qsym/combinatorics - sage/combinat/ncsf_qsym/generic_basis_code - sage/combinat/ncsf_qsym/ncsf - sage/combinat/ncsf_qsym/qsym diff --git a/src/doc/en/reference/combinat/ncsym.rst b/src/doc/en/reference/combinat/ncsym.rst deleted file mode 100644 index e06e8345861..00000000000 --- a/src/doc/en/reference/combinat/ncsym.rst +++ /dev/null @@ -1,10 +0,0 @@ -Symmetric Functions in Non-Commuting Variables -============================================== - -.. toctree:: - :maxdepth: 2 - - ../sage/combinat/ncsym/bases - ../sage/combinat/ncsym/dual - ../sage/combinat/ncsym/ncsym - diff --git a/src/doc/en/reference/combinat/partitions.rst b/src/doc/en/reference/combinat/partitions.rst deleted file mode 100644 index 27e33587feb..00000000000 --- a/src/doc/en/reference/combinat/partitions.rst +++ /dev/null @@ -1,10 +0,0 @@ -Partitions and Partition-like Objects -===================================== - -.. toctree:: - :maxdepth: 2 - - sage/combinat/partition - sage/combinat/partition_tuple - sage/combinat/skew_partition - sage/combinat/core diff --git a/src/doc/en/reference/combinat/posets.rst b/src/doc/en/reference/combinat/posets.rst deleted file mode 100644 index 1fc10a80466..00000000000 --- a/src/doc/en/reference/combinat/posets.rst +++ /dev/null @@ -1,13 +0,0 @@ -Posets -====== - -.. toctree:: - :maxdepth: 1 - - ../sage/combinat/posets/posets - ../sage/combinat/posets/hasse_diagram - ../sage/combinat/posets/elements - ../sage/combinat/posets/lattices - ../sage/combinat/posets/linear_extensions - ../sage/combinat/posets/poset_examples - ../sage/combinat/tamari_lattices diff --git a/src/doc/en/reference/combinat/rc_bijections.rst b/src/doc/en/reference/combinat/rc_bijections.rst deleted file mode 100644 index f20901e3382..00000000000 --- a/src/doc/en/reference/combinat/rc_bijections.rst +++ /dev/null @@ -1,17 +0,0 @@ -Rigged Configuration Bijections -=============================== - -.. toctree:: - :maxdepth: 1 - - ../sage/combinat/rigged_configurations/bijection - ../sage/combinat/rigged_configurations/bij_abstract_class - ../sage/combinat/rigged_configurations/bij_type_A - ../sage/combinat/rigged_configurations/bij_type_B - ../sage/combinat/rigged_configurations/bij_type_C - ../sage/combinat/rigged_configurations/bij_type_D - ../sage/combinat/rigged_configurations/bij_type_A2_odd - ../sage/combinat/rigged_configurations/bij_type_A2_even - ../sage/combinat/rigged_configurations/bij_type_A2_dual - ../sage/combinat/rigged_configurations/bij_type_D_twisted - diff --git a/src/doc/en/reference/combinat/rigged_configurations.rst b/src/doc/en/reference/combinat/rigged_configurations.rst deleted file mode 100644 index 730755de6af..00000000000 --- a/src/doc/en/reference/combinat/rigged_configurations.rst +++ /dev/null @@ -1,19 +0,0 @@ -Rigged Configurations -===================== - -.. toctree:: - :maxdepth: 1 - - ../sage/combinat/rigged_configurations/rigged_configurations - ../sage/combinat/rigged_configurations/rigged_configuration_element - - ../sage/combinat/rigged_configurations/tensor_product_kr_tableaux - ../sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element - ../sage/combinat/rigged_configurations/kr_tableaux - - ../sage/combinat/rigged_configurations/kleber_tree - - ../sage/combinat/rigged_configurations/rigged_partition - - rc_bijections - diff --git a/src/doc/en/reference/combinat/root_systems.rst b/src/doc/en/reference/combinat/root_systems.rst deleted file mode 100644 index 88b30756a1d..00000000000 --- a/src/doc/en/reference/combinat/root_systems.rst +++ /dev/null @@ -1,47 +0,0 @@ -Root Systems -============ - -.. toctree:: - :maxdepth: 2 - - ../sage/combinat/root_system/cartan_type - ../sage/combinat/root_system/dynkin_diagram - ../sage/combinat/root_system/cartan_matrix - ../sage/combinat/root_system/coxeter_matrix - ../sage/combinat/root_system/type_folded - - ../sage/combinat/root_system/root_system - ../sage/combinat/root_system/plot - ../sage/combinat/root_system/root_lattice_realizations - ../sage/combinat/root_system/weight_lattice_realizations - ../sage/combinat/root_system/root_space - ../sage/combinat/root_system/weight_space - ../sage/combinat/root_system/ambient_space - - ../sage/combinat/root_system/coxeter_group - ../sage/combinat/root_system/weyl_group - - ../sage/combinat/root_system/weyl_characters - ../sage/combinat/root_system/branching_rules - - ../sage/combinat/root_system/type_affine - ../sage/combinat/root_system/type_dual - ../sage/combinat/root_system/type_reducible - ../sage/combinat/root_system/type_relabel - ../sage/combinat/root_system/type_A - ../sage/combinat/root_system/type_B - ../sage/combinat/root_system/type_C - ../sage/combinat/root_system/type_D - ../sage/combinat/root_system/type_E - ../sage/combinat/root_system/type_F - ../sage/combinat/root_system/type_G - ../sage/combinat/root_system/type_H - ../sage/combinat/root_system/type_I - ../sage/combinat/root_system/type_A_affine - ../sage/combinat/root_system/type_B_affine - ../sage/combinat/root_system/type_C_affine - ../sage/combinat/root_system/type_D_affine - ../sage/combinat/root_system/type_E_affine - ../sage/combinat/root_system/type_F_affine - ../sage/combinat/root_system/type_G_affine - ../sage/combinat/root_system/type_BC_affine diff --git a/src/doc/en/reference/combinat/species.rst b/src/doc/en/reference/combinat/species.rst deleted file mode 100644 index 76f62e4c96d..00000000000 --- a/src/doc/en/reference/combinat/species.rst +++ /dev/null @@ -1,54 +0,0 @@ -Combinatorial Species -===================== - - -Power Series ------------- - -.. toctree:: - :maxdepth: 2 - - ../sage/combinat/species/stream - ../sage/combinat/species/series_order - ../sage/combinat/species/series - ../sage/combinat/species/generating_series - -Basic Species -------------- - -.. toctree:: - :maxdepth: 2 - - ../sage/combinat/species/species - ../sage/combinat/species/empty_species - ../sage/combinat/species/recursive_species - ../sage/combinat/species/characteristic_species - ../sage/combinat/species/cycle_species - ../sage/combinat/species/partition_species - ../sage/combinat/species/permutation_species - ../sage/combinat/species/linear_order_species - ../sage/combinat/species/set_species - ../sage/combinat/species/subset_species - ../sage/combinat/species/library - -Operations on Species ---------------------- - -.. toctree:: - :maxdepth: 2 - - ../sage/combinat/species/sum_species - ../sage/combinat/species/product_species - ../sage/combinat/species/composition_species - ../sage/combinat/species/functorial_composition_species - -Miscellaneous -------------- - -.. toctree:: - :maxdepth: 2 - - ../sage/combinat/species/structure - ../sage/combinat/species/misc - ../sage/combinat/species/combinatorial_logarithm - diff --git a/src/doc/en/reference/combinat/symmetric_functions.rst b/src/doc/en/reference/combinat/symmetric_functions.rst deleted file mode 100644 index d5cc76667a9..00000000000 --- a/src/doc/en/reference/combinat/symmetric_functions.rst +++ /dev/null @@ -1,26 +0,0 @@ -Symmetric Functions -=================== - -.. toctree:: - :maxdepth: 2 - - sage/combinat/sf/sfa - sage/combinat/sf/sf - sage/combinat/sf/classical - sage/combinat/sf/schur - sage/combinat/sf/monomial - sage/combinat/sf/multiplicative - sage/combinat/sf/elementary - sage/combinat/sf/homogeneous - sage/combinat/sf/powersum - sage/combinat/sf/dual - sage/combinat/sf/orthotriang - sage/combinat/sf/kfpoly - sage/combinat/sf/hall_littlewood - sage/combinat/sf/jack - sage/combinat/sf/new_kschur - sage/combinat/sf/k_dual - sage/combinat/sf/llt - sage/combinat/sf/macdonald - sage/combinat/sf/ns_macdonald - sage/combinat/sf/witt diff --git a/src/doc/en/reference/combinat/tableaux.rst b/src/doc/en/reference/combinat/tableaux.rst deleted file mode 100644 index 18568c7a91f..00000000000 --- a/src/doc/en/reference/combinat/tableaux.rst +++ /dev/null @@ -1,13 +0,0 @@ -Tableaux and Tableaux-like Objects -================================== - -.. toctree:: - :maxdepth: 2 - - sage/combinat/tableau - sage/combinat/skew_tableau - sage/combinat/ribbon - sage/combinat/ribbon_tableau - sage/combinat/tableau_tuple - sage/combinat/k_tableau - sage/combinat/rsk diff --git a/src/doc/en/reference/combinat/words.rst b/src/doc/en/reference/combinat/words.rst deleted file mode 100644 index eb827ea8984..00000000000 --- a/src/doc/en/reference/combinat/words.rst +++ /dev/null @@ -1,17 +0,0 @@ -Words -===== - -.. toctree:: - :maxdepth: 2 - - ../sage/combinat/words/alphabet - ../sage/combinat/words/abstract_word - ../sage/combinat/words/finite_word - ../sage/combinat/words/infinite_word - ../sage/combinat/words/word - ../sage/combinat/words/word_generators - ../sage/combinat/words/words - ../sage/combinat/words/shuffle_product - ../sage/combinat/words/suffix_trees - ../sage/combinat/words/morphism - ../sage/combinat/words/paths diff --git a/src/sage/combinat/__init__.py b/src/sage/combinat/__init__.py index 03e579c9ca1..0b12e6dbf2b 100644 --- a/src/sage/combinat/__init__.py +++ b/src/sage/combinat/__init__.py @@ -1,96 +1,48 @@ __doc__ = r""" -Combinatorics quickref ----------------------- +Combinatorics +============= - - :mod:`sage.combinat.demo` - - sage.combinat.demo_short - - sage.combinat.combinat? (pretty outdated) - - sage.combinat.root_systems? - - sage.combinat.species? +Introductory material +--------------------- -See also: - - :class:`EnumeratedSets`, :class:`FiniteEnumeratedSets` +- :ref:`sage.combinat.quickref` +- :ref:`sage.combinat.tutorial` -* Integer Sequences +Thematic indexes +---------------- -sloane_find(list), sloane. -s = sloane.find([1,3,19,211])[0] -s = sloane.i_am_lucky([1,3,19,211]) -s(5), s.references() +- :ref:`sage.combinat.counting` +- :ref:`sage.combinat.enumerated_sets` +- :ref:`sage.combinat.catalog_partitions` +- :ref:`sage.combinat.species` +- :ref:`sage.combinat.algebraic_combinatorics` +- :ref:`sage.combinat.posets` +- :ref:`sage.combinat.words` -* Combinatorial objects: +Graphs +------ -P = Partitions(10); P.count(); P. -C = Combinations([1,3,7]); C.list() -Compositions(5, max_part = 3, ...).unrank(3) -Tableau +.. TODO:: point instead to the main entry point for graphs -* Constructions and Species +- :ref:`Graph`, :ref:`DiGraph`, :obj:`graphs`, :obj:`digraphs` -for (p, c) in CartesianProduct(P, C): ... +Dynamical systems +----------------- -DisjointUnion(Family(lambda n: IntegerVectors(n, 3), NonNegativeIntegers)) +- :ref:`sage.combinat.e_one_star` -* Words - -W=Words('abc') W('aabca') - -Franco: what about putting W('aabca').bar(), where bar would be some flashy feature? - -* Posets - -Posets: Poset([[1,2],[4],[3],[4],[]]) - -* Polytopes - -L =LatticePolytope(random_matrix(ZZ, 3,6, x=7)) -L.npoints() L.plot3d() - -* Root systems, Coxeter and Weyl groups - -See: sage.combinat.root_system? - -* Crystals - -CrystalOfTableaux(["A",3], shape = [3,2]) - -See sage.combinat.crystals? - -* Symmetric functions and combinatorial Hopf algebras - - Sym = SymmetricFunctions(QQ) - %from Sym.shortcuts() import * / %from Sym.shortcuts() import s, h, m - Sym.import_shortcuts() / Sym.import_shortcuts("s,h,m") - s[3] * h[2] ... - - NCSF - QSym - MultivariatePolynomials - - SymmetricGroupAlgebra - - HeckeAlgebra - -* Discrete groups, Permutation groups - -See sage.groups? - - S = SymmetricGroup(4) - M = MultivariatePolynomials('x0,x1,x2,x3') - M(...).action??? S. - -* Lattices - -* Graph theory and posets - -See Graph?, Digraph?, graphs? - -Poset({1: [2,3], 2: [4], 3: [4]}).some_snappy_feature() +Miscellaneous +------------- +- :ref:`sage.combinat.finite_state_machine` +- :ref:`sage.combinat.output` +- :ref:`sage.combinat.ranker` +- :ref:`sage.combinat.misc` +- :func:`sage.combinat.combinatorial_map.combinatorial_map` """ - -import demo -import demo_short -import demo_algebraic_combinatorics -import tutorial_enumerated_sets +#import demo +#import demo_short +#import demo_algebraic_combinatorics +#import tutorial_enumerated_sets +import quickref import tutorial diff --git a/src/sage/combinat/algebraic_combinatorics.py b/src/sage/combinat/algebraic_combinatorics.py new file mode 100644 index 00000000000..fb2d1cd6706 --- /dev/null +++ b/src/sage/combinat/algebraic_combinatorics.py @@ -0,0 +1,60 @@ +r""" +Algebraic combinatorics +======================= + +Quickref +-------- + +.. TODO:: write it! + +Thematic tutorials +------------------ + +.. TODO:: how to link to those? + +- thematic_tutorials/algebraic_combinatorics +- thematic_tutorials/lie +- thematic_tutorials/MILP + +Enumerated sets of combinatorial objects +---------------------------------------- + +- :ref:`sage.combinat.catalog_partitions` +- :class:`sage.combinat.gelfand_tsetlin_patterns.GelfandTsetlinPattern`, :class:`sage.combinat.gelfand_tsetlin_patterns.GelfandTsetlinPatterns` +- :class:`sage.combinat.knutson_tao_puzzles.KnutsonTaoPuzzleSolver` + +Combinatorial Hopf Algebras +--------------------------- + +- :class:`Symmetric Functions ` +- :ref:`sage.combinat.ncsf_qsym` +- :ref:`sage.combinat.schubert_polynomial` +- :class:`sage.combinat.ncsym.ncsym.SymmetricFunctionsNonCommutingVariables` + +Groups and Algebras +------------------- + +- :obj:`groups`, :obj:`algebras` +- :class:`SymmetricGroup`, :class:`CoxeterGroup`, :class:`WeylGroup` +- :class:`sage.combinat.diagram_algebras.PartitionAlgebra` +- :class:`sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra` +- :class:`sage.combinat.symmetric_group_algebra.SymmetricGroupAlgebra` +- :class:`sage.algebras.nil_coxeter_algebra.NilCoxeterAlgebra` +- :class:`sage.algebras.affine_nil_temperley_lieb.AffineNilTemperleyLiebTypeA` + +Combinatorial Representation Theory +----------------------------------- + +- :ref:`sage.combinat.root_system` +- :ref:`sage.combinat.crystals` +- :ref:`sage.combinat.rigged_configurations` +- :ref:`sage.combinat.cluster_algebra_quiver` +- :class:`sage.combinat.kazhdan_lusztig.KazhdanLusztigPolynomial` +- :class:`sage.combinat.symmetric_group_representations.SymmetricGroupRepresentation` + +# ../sage/combinat/descent_algebra +# ../sage/combinat/diagram_algebras +# ../sage/combinat/yang_baxter_graph + +# ../sage/combinat/hall_polynomial +""" diff --git a/src/sage/combinat/catalog_partitions.py b/src/sage/combinat/catalog_partitions.py new file mode 100644 index 00000000000..a890577ac07 --- /dev/null +++ b/src/sage/combinat/catalog_partitions.py @@ -0,0 +1,22 @@ +r""" +Enumerated sets of partitions, tableaux, ... +============================================ + +Quickref +-------- + +Catalog +------- + +- :ref:`sage.combinat.partition` +- :ref:`sage.combinat.tableau` +- :ref:`sage.combinat.partition_tuple` +- :ref:`sage.combinat.tableau_tuple` +- :ref:`sage.combinat.skew_partition` +- :ref:`sage.combinat.skew_tableau` +- :ref:`sage.combinat.ribbon` +- :ref:`sage.combinat.ribbon_tableau` +- :ref:`sage.combinat.core` +- :ref:`sage.combinat.k_tableau` +- :ref:`sage.combinat.rsk` +""" diff --git a/src/sage/combinat/cluster_algebra_quiver/__init__.py b/src/sage/combinat/cluster_algebra_quiver/__init__.py index dde638a6077..6c1cfe5eb7e 100644 --- a/src/sage/combinat/cluster_algebra_quiver/__init__.py +++ b/src/sage/combinat/cluster_algebra_quiver/__init__.py @@ -1 +1,13 @@ -# Initialization file for cluster algebras and quivers +__doc__ = r""" +Cluster Algebras and Quivers +============================ + +.. TODO:: + + Populate + + ../sage/combinat/cluster_algebra_quiver/quiver_mutation_type + ../sage/combinat/cluster_algebra_quiver/quiver + ../sage/combinat/cluster_algebra_quiver/cluster_seed + +""" diff --git a/src/sage/combinat/counting.py b/src/sage/combinat/counting.py new file mode 100644 index 00000000000..cfcbad13716 --- /dev/null +++ b/src/sage/combinat/counting.py @@ -0,0 +1,12 @@ +r""" +Counting +======== + + :mod:`sage/databases/oeis` + :mod:`sage/combinat/sloane_functions` + :mod:`sage/combinat/expnums` + :mod:`sage/combinat/q_analogues` + :mod:`sage/combinat/q_bernoulli` + :mod:`sage/combinat/binary_recurrence_sequences` + :mod:`sage/combinat/combinat` +""" diff --git a/src/sage/combinat/crystals/__init__.py b/src/sage/combinat/crystals/__init__.py index 149bd499807..affd1895d5b 100644 --- a/src/sage/combinat/crystals/__init__.py +++ b/src/sage/combinat/crystals/__init__.py @@ -1,5 +1,33 @@ -#This makes sure that sage.combinat.crystals? points to the correct -#documentation about crystals -from crystals import __doc__ +__doc__ = r""" +Crystals +======== + +Quickref +-------- + +.. TODO:: Write it! + +Introductory material +--------------------- + +- :ref:`sage.combinat.crystals` -- This overview +- :ref:`sage.combinat.crystals.crystals` +- The ``Lie Methods and Related Combinatorics`` thematic tutorial + +Catalogs of crystals +-------------------- + +- :ref:`sage.combinat.crystals.catalog` +- :ref:`sage.combinat.crystals.catalog_elementary_crystals` +- :ref:`sage.combinat.crystals.catalog_infinity_crystals` +- :ref:`sage.combinat.crystals.catalog_kirillov_reshetikhin` + +See also +-------- + +- :class:`Crystals`, :class:`HighestWeightCrystals`, :class:`FiniteCrystals`, :class:`ClassicalCrystals`, :class:`RegularCrystals` -- The categories for crystals +- :ref:`sage.combinat.root_system` -- Root systems + +""" import all diff --git a/src/sage/combinat/crystals/catalog.py b/src/sage/combinat/crystals/catalog.py index 9eb17ceb9ea..20f7ff85f2e 100644 --- a/src/sage/combinat/crystals/catalog.py +++ b/src/sage/combinat/crystals/catalog.py @@ -4,6 +4,8 @@ Definition of a Crystal ----------------------- +.. TODO:: This documentation duplicates that of sage.combinat.crystals.crystals + Let `C` be a CartanType with index set `I`, and `P` be the corresponding weight lattice of the type `C`. Let `\alpha_i` and `\alpha^{\vee}_i` denote the corresponding simple roots diff --git a/src/sage/combinat/crystals/crystals.py b/src/sage/combinat/crystals/crystals.py index 9898892da4b..94fac683935 100644 --- a/src/sage/combinat/crystals/crystals.py +++ b/src/sage/combinat/crystals/crystals.py @@ -1,5 +1,6 @@ r""" -Crystals +An introduction to crystals +=========================== Let `T` be a CartanType with index set `I`, and `W` be a realization of the type `T` weight diff --git a/src/sage/combinat/designs/__init__.py b/src/sage/combinat/designs/__init__.py index e69de29bb2d..a8d677a6803 100644 --- a/src/sage/combinat/designs/__init__.py +++ b/src/sage/combinat/designs/__init__.py @@ -0,0 +1,20 @@ +__doc__ = r""" +Designs and Incidence Structures +================================ + +.. TODO:: Proofread / point to the main classes rather than the modules? + +- :mod:`sage.combinat.designs.covering_design` +- :mod:`sage.combinat.designs.ext_rep` +- :mod:`sage.combinat.designs.incidence_structures` +- :mod:`sage.combinat.designs.design_catalog` + +Constructions +------------- + +- :mod:`sage.combinat.designs.block_design` +- :mod:`sage.combinat.designs.bibd` +- :mod:`sage.combinat.designs.steiner_quadruple_systems` +- :mod:`sage.combinat.designs.latin_squares` +- :mod:`sage.combinat.designs.orthogonal_arrays` +""" diff --git a/src/sage/combinat/enumerated_sets.py b/src/sage/combinat/enumerated_sets.py new file mode 100644 index 00000000000..20af23d4219 --- /dev/null +++ b/src/sage/combinat/enumerated_sets.py @@ -0,0 +1,132 @@ +""" +Enumerated sets and combinatorial objects +========================================= + +.. TODO:: Proofread / point to the main classes rather than the modules + +Categories +---------- + +- :class:`EnumeratedSets`, :class:`FiniteEnumeratedSets` + +Basic enumerated sets +--------------------- + +- :class:`sage.combinat.subset.Subsets`, :class:`sage.combinat.combination.Combinations`, :class:`sage.combinat.permutation.Arrangements` +- :class:`sage.sets.finite_enumerated_set.FiniteEnumeratedSet` +- :class:`DisjointUnionEnumeratedSets`, :class:`CartesianProduct` + +Integer lists +------------- + +- :ref:`sage.combinat.partition` +- :ref:`sage.combinat.composition` +- :class:`sage.combinat.composition_signed.SignedCompositions` + +- :class:`sage.combinat.integer_vector.IntegerVectors` +- :func:`sage.combinat.integer_vector_weighted.WeightedIntegerVectors` +- :class:`sage.combinat.integer_vectors_mod_permgroup.IntegerVectorsModPermutationGroup` + +- :mod:`sage.combinat.parking_functions` +- :mod:`sage.combinat.non_decreasing_parking_function` + +- :mod:`sage.combinat.sidon_sets` + +Words +----- + +- :class:`Words` +- :mod:`sage.combinat.subword` +- :mod:`sage.combinat.necklace` +- :mod:`sage.combinat.lyndon_word` +- :mod:`sage.combinat.dyck_word` +- :mod:`sage.combinat.debruijn_sequence` + +Permutations, ... +----------------- + +- :mod:`sage.combinat.permutation` +- :mod:`sage.combinat.affine_permutation` +- :class:`sage.combinat.permutation.Arrangements` +- :mod:`sage.combinat.derangements` +- :mod:`sage.combinat.integer_vectors_mod_permgroup` +- :mod:`sage.combinat.rsk` + +.. SEEALSO:: + + - :class:`PermutationGroup`, :class:`SymmetricGroup` + - :class:`FiniteSetMaps` + +Partitions, tableaux, ... +------------------------- + +See: :mod:`sage.combinat.catalog_partitions` + +Integer matrices, ... +--------------------- + +- :mod:`sage.combinat.integer_matrices` +- :mod:`sage.combinat.matrices.hadamard_matrix` +- :mod:`sage.combinat.matrices.latin` +- :mod:`sage.combinat.alternating_sign_matrix` +- :mod:`sage.combinat.six_vertex_model` +- :mod:`sage.combinat.similarity_class_type` +- :mod:`sage.combinat.restricted_growth` +- :mod:`sage.combinat.vector_partition` + +.. SEEALSO:: + + - :class:`MatrixSpace` + - :mod:`groups.matrix` + +Set partitions, ... +------------------- + +- :mod:`sage.combinat.set_partition_ordered` +- :mod:`sage.combinat.set_partition` +- :class:`sage.combinat.subsets_pairwise.PairwiseCompatibleSubsets` + +Trees +----- + +- :ref:`sage.combinat.abstract_tree` +- :ref:`sage.combinat.ordered_tree` +- :ref:`sage.combinat.binary_tree` + +Enumerated sets related to graphs +--------------------------------- + +- :ref:`sage.combinat.degree_sequences` +- :ref:`sage.combinat.graph_path` +- :ref:`sage.combinat.perfect_matching` + +Generic enumerated sets +----------------------- + +- :class:`sage.combinat.backtrack.GenericBacktracker` +- :class:`sage.combinat.backtrack.TransitiveIdeal` +- :class:`sage.combinat.backtrack.TransitiveIdealGraded` +- :func:`sage.combinat.tools.transitive_ideal` +- :class:`sage.combinat.backtrack.SearchForest` +- :ref:`sage.combinat.tiling` +- :ref:`sage.combinat.dlx` +- :ref:`sage.combinat.matrices.dlxcpp` +- :ref:`sage.combinat.species` +- :class:`sage.combinat.integer_list.IntegerListsLex` +- :class:`sage.combinat.integer_vectors_mod_permgroup.IntegerVectorsModPermutationGroup` + +Low level enumerated sets +------------------------- + +- :mod:`sage.combinat.permutation_nk` +- :mod:`sage.combinat.split_nk` +- :mod:`sage.combinat.choose_nk` +- :mod:`sage.combinat.multichoose_nk` + +Misc enumerated sets +-------------------- + +- :class:`sage.combinat.gelfand_tsetlin_patterns.GelfandTsetlinPattern`, :class:`sage.combinat.gelfand_tsetlin_patterns.GelfandTsetlinPatterns` +- :class:`sage.combinat.knutson_tao_puzzles.KnutsonTaoPuzzleSolver` +- :func:`LatticePolytope` +""" diff --git a/src/sage/combinat/index.py b/src/sage/combinat/index.py deleted file mode 100644 index fde61cc02ee..00000000000 --- a/src/sage/combinat/index.py +++ /dev/null @@ -1,179 +0,0 @@ -""" -Combinatorics -============= - -Introductory material ---------------------- - - :mod:`sage.combinat` - :mod:`sage.combinat.tutorial` - -Enumerated sets ---------------- - -**Basic enumerated sets** - - :class:`subsets.Subsets` - :class:`subsets_pairwise.PairwiseCompatibleSubsets` - :class:`tuple.Tuple` - :class:`finite_class.FiniteClass` - :class:`combination.Combinations` - :class:`combination.Combinations` - :class:`cartesian_product.CartesianProduct` - -**Generic enumerated sets** - -.. toctree:: - :maxdepth: 1 - - :class:`backtrack.GenericBacktracker` - :class:`backtrack.TransitiveIdeal` - :class:`backtrack.TransitiveIdealGraded` - :func:`tools.transitive_ideal` - :class:`backtrack.SearchForest` - :mod:`tiling` - :mod:`dlx` - :mod:`matrices/dlxcpp` - :mod:`species` - :class:`integer_list.IntegerListsLex` - -**Compositions** - -.. toctree:: - :maxdepth: 1 - -**Counting** - -.. toctree:: - :maxdepth: 1 - - :mod:`sage/databases/oeis` - :mod:`sage/combinat/sloane_functions` - :mod:`sage/combinat/expnums` - :mod:`sage/combinat/q_analogues` - :mod:`sage/combinat/q_bernoulli` - :mod:`sage/combinat/binary_recurrence_sequences` - sage/combinat/combinat - -**Integer lists/matrices/vectors** - -.. toctree:: - :maxdepth: 1 - - :class:`compositions.Compositions` - :class:`composition_signed.SignedCompositions` - - sage/combinat/integer_vector - sage/combinat/integer_vector_weighted - -**Partitions** - -.. toctree:: - :maxdepth: 1 - - partitions - sage/combinat/set_partition_ordered - sage/combinat/set_partition - sage/combinat/vector_partition - tableaux - -**Permutations** - -.. toctree:: - :maxdepth: 1 - - sage/combinat/permutation - sage/combinat/affine_permutation - sage/combinat/derangements - sage/combinat/integer_vectors_mod_permgroup - sage/combinat/enumeration_mod_permgroup - -**Enumerated sets of matrices** - -.. toctree:: - :maxdepth: 1 - - sage/combinat/integer_matrices - sage/combinat/matrices/hadamard_matrix - sage/combinat/matrices/latin - sage/combinat/alternating_sign_matrix - sage/combinat/six_vertex_model - sage/combinat/similarity_class_type - -**Trees** - -.. toctree:: - :maxdepth: 1 - - sage/combinat/abstract_tree - sage/combinat/ordered_tree - sage/combinat/binary_tree - -**Enumerated sets related to graphs** - -.. toctree:: - :maxdepth: 1 - - sage/combinat/degree_sequences - sage/combinat/graph_path - sage/combinat/perfect_matching - -**Misc enumerated sets** - -.. toctree:: - :maxdepth: 1 - - designs - sage/combinat/non_decreasing_parking_function - sage/combinat/parking_functions - sage/combinat/restricted_growth - sage/combinat/sidon_sets - -Word theory ------------ - -.. toctree:: - :maxdepth: 1 - - words - sage/combinat/finite_state_machine - sage/combinat/subword - sage/combinat/necklace - sage/combinat/lyndon_word - sage/combinat/dyck_word - sage/combinat/debruijn_sequence - -Algebraic combinatorics ------------------------ - -.. toctree:: - :maxdepth: 1 - - cluster_algebras - algebra - root_systems - crystals - rigged_configurations - -Dynamical systems ------------------ - - sage/combinat/e_one_star - -Miscellaneous -------------- - -.. toctree:: - :maxdepth: 1 - - sage/combinat/gelfand_tsetlin_patterns - sage/combinat/knutson_tao_puzzles - - posets - developer - - sage/combinat/misc - sage/combinat/combinatorial_map - -.. include:: ../footer.txt -""" diff --git a/src/sage/combinat/ncsf_qsym/__init__.py b/src/sage/combinat/ncsf_qsym/__init__.py index e69de29bb2d..a69be87a569 100644 --- a/src/sage/combinat/ncsf_qsym/__init__.py +++ b/src/sage/combinat/ncsf_qsym/__init__.py @@ -0,0 +1,9 @@ +__doc__ = r""" +Non-Commutative Symmetric Functions and Quasi-Symmetric Functions +================================================================= + +- :ref:`sage.combinat.ncsf_qsym.tutorial` +- :class:`sage.combinat.ncsf_qsym.ncsf.NonCommutativeSymmetricFunctions` +- :class:`sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions` + +""" diff --git a/src/sage/combinat/ncsym/__init__.py b/src/sage/combinat/ncsym/__init__.py index e69de29bb2d..9afdd274cad 100644 --- a/src/sage/combinat/ncsym/__init__.py +++ b/src/sage/combinat/ncsym/__init__.py @@ -0,0 +1,10 @@ +__doc__ = r""" +Symmetric Functions in Non-Commuting Variables +============================================== + +.. TODO:: Populate + + ../sage/combinat/ncsym/bases + ../sage/combinat/ncsym/dual + ../sage/combinat/ncsym/ncsym +""" diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 3257a11486c..29bfa67dacc 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -1,5 +1,5 @@ r""" -Partitions +Integer partitions A partition `p` of a nonnegative integer `n` is a non-increasing list of positive integers (the *parts* of the diff --git a/src/sage/combinat/posets/__init__.py b/src/sage/combinat/posets/__init__.py index a4e4d22acb8..40777857262 100644 --- a/src/sage/combinat/posets/__init__.py +++ b/src/sage/combinat/posets/__init__.py @@ -1,3 +1,13 @@ -# this file shouldn't be empty :) +__doc__ = r""" +Posets +====== + +- :mod:`sage.combinat.posets` +- :func:`Poset`, :func:`MeetSemiLattice`, :func:`JoinSemiLattice`, :func:`LatticePoset` +- :class:`sage.categories.posets.Posets`, :class:`sage.categories.lattices.Lattices` +- :obj:`Posets` +- :func:`TamariLattice` +- :class:`sage.combinat.posets.linear_extensions.LinearExtensionOfPoset`, :class:`sage.combinat.posets.linear_extensions.LinearExtensionsOfPoset` +""" import all diff --git a/src/sage/combinat/quickref.py b/src/sage/combinat/quickref.py new file mode 100644 index 00000000000..258d795fe82 --- /dev/null +++ b/src/sage/combinat/quickref.py @@ -0,0 +1,53 @@ +r""" +Combinatorics quickref +---------------------- + +Integer Sequences:: + + sage: oeis([1,3,19,211]) + 0: A000275: Coefficients of a Bessel function (reciprocal of J_0(z)); also pairs of permutations with rise/rise forbidden. + sage: s.programs() + 0: (PARI) a(n)=if(n<0,0,n!^2*4^n*polcoeff(1/besselj(0,x+x*O(x^(2*n))),2*n)) /* Michael Somos May 17 2004 */ + +Combinatorial objects:: + + sage: P = Partitions(10); P.cardinality(); P. + sage: C = Combinations([1,3,7]); C.list() + sage: Compositions(5, max_part = 3).unrank(3) + +Constructions and Species:: + + sage: for (p, c) in CartesianProduct(P, C): print p, c + sage: DisjointUnionEnumeratedSets(Family(lambda n: IntegerVectors(n, 3), NonNegativeIntegers)) + +Words:: + + sage: W=Words('abc') + sage: Word('aabca').some_flashy_feature() + +Polytopes:: + + sage: L = LatticePolytope(random_matrix(ZZ, 3,6, x=7)) + sage: L.npoints(); L.plot3d() + +Root systems, Coxeter and Weyl groups (:mod:`sage.combinat.root_system`):: + +Crystals (:mod:`sage.combinat.crystals`):: + + sage: CrystalOfTableaux(["A",3], shape = [3,2]) + +Symmetric functions and combinatorial Hopf algebras (:mod:`sage.combinat.algebraic_combinatorics`):: + + sage: Sym = SymmetricFunctions(QQ); Sym.inject_shorthands() + sage: s[3] * h[2] ... + +Discrete groups, Permutation groups (:mod:`sage.groups`):: + + sage: S = SymmetricGroup(4) + sage: M = MultivariatePolynomials('x0,x1,x2,x3') + sage: M(...).action??? S. + +Graph theory, posets, lattices (:class:`Graph`, :class:`Digraph`, :mod:`sage.combinat.posets`):: + + sage: Poset({1: [2,3], 2: [4], 3: [4]}).some_snappy_feature() +""" diff --git a/src/sage/combinat/rigged_configurations/__init__.py b/src/sage/combinat/rigged_configurations/__init__.py index 8b137891791..e1bab73be99 100644 --- a/src/sage/combinat/rigged_configurations/__init__.py +++ b/src/sage/combinat/rigged_configurations/__init__.py @@ -1 +1,28 @@ +__doc__ = r""" +Rigged Configurations +===================== +.. TODO:: Proofread / point to the main classes rather than the modules? + +- :mod:`sage.combinat.rigged_configurations.rigged_configurations` +- :mod:`sage.combinat.rigged_configurations.rigged_configuration_element` +- :mod:`sage.combinat.rigged_configurations.tensor_product_kr_tableaux` +- :mod:`sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element` +- :mod:`sage.combinat.rigged_configurations.kr_tableaux` +- :mod:`sage.combinat.rigged_configurations.kleber_tree` +- :mod:`sage.combinat.rigged_configurations.rigged_partition` + +Bijections +---------- + +- :mod:`sage.combinat.rigged_configurations.bijection` +- :mod:`sage.combinat.rigged_configurations.bij_abstract_class` +- :mod:`sage.combinat.rigged_configurations.bij_type_A` +- :mod:`sage.combinat.rigged_configurations.bij_type_B` +- :mod:`sage.combinat.rigged_configurations.bij_type_C` +- :mod:`sage.combinat.rigged_configurations.bij_type_D` +- :mod:`sage.combinat.rigged_configurations.bij_type_A2_odd` +- :mod:`sage.combinat.rigged_configurations.bij_type_A2_even` +- :mod:`sage.combinat.rigged_configurations.bij_type_A2_dual` +- :mod:`sage.combinat.rigged_configurations.bij_type_D_twisted` +""" diff --git a/src/sage/combinat/root_system/__init__.py b/src/sage/combinat/root_system/__init__.py index c338db5c640..6ddb46f0045 100644 --- a/src/sage/combinat/root_system/__init__.py +++ b/src/sage/combinat/root_system/__init__.py @@ -11,3 +11,53 @@ import type_G import all + +""" +Root Systems +============ + +.. toctree:: + :maxdepth: 2 + + ../sage/combinat/root_system/cartan_type + ../sage/combinat/root_system/dynkin_diagram + ../sage/combinat/root_system/cartan_matrix + ../sage/combinat/root_system/coxeter_matrix + ../sage/combinat/root_system/type_folded + + ../sage/combinat/root_system/root_system + ../sage/combinat/root_system/plot + ../sage/combinat/root_system/root_lattice_realizations + ../sage/combinat/root_system/weight_lattice_realizations + ../sage/combinat/root_system/root_space + ../sage/combinat/root_system/weight_space + ../sage/combinat/root_system/ambient_space + + ../sage/combinat/root_system/coxeter_group + ../sage/combinat/root_system/weyl_group + + ../sage/combinat/root_system/weyl_characters + ../sage/combinat/root_system/branching_rules + + ../sage/combinat/root_system/type_affine + ../sage/combinat/root_system/type_dual + ../sage/combinat/root_system/type_reducible + ../sage/combinat/root_system/type_relabel + ../sage/combinat/root_system/type_A + ../sage/combinat/root_system/type_B + ../sage/combinat/root_system/type_C + ../sage/combinat/root_system/type_D + ../sage/combinat/root_system/type_E + ../sage/combinat/root_system/type_F + ../sage/combinat/root_system/type_G + ../sage/combinat/root_system/type_H + ../sage/combinat/root_system/type_I + ../sage/combinat/root_system/type_A_affine + ../sage/combinat/root_system/type_B_affine + ../sage/combinat/root_system/type_C_affine + ../sage/combinat/root_system/type_D_affine + ../sage/combinat/root_system/type_E_affine + ../sage/combinat/root_system/type_F_affine + ../sage/combinat/root_system/type_G_affine + ../sage/combinat/root_system/type_BC_affine +""" diff --git a/src/sage/combinat/root_system/pieri_factors.py b/src/sage/combinat/root_system/pieri_factors.py index 62f0fdf7743..2b2e79d42b8 100644 --- a/src/sage/combinat/root_system/pieri_factors.py +++ b/src/sage/combinat/root_system/pieri_factors.py @@ -34,11 +34,12 @@ class PieriFactors(UniqueRepresentation, Parent): type can be realized as an order ideal of the Bruhat order poset generated by a certain set of maximal elements. - See also: - * :meth:`WeylGroups.ParentMethods.pieri_factors` - * :meth:`WeylGroups.ElementMethods.stanley_symmetric_function` + .. SEEALSO:: - EXAMPLES:: + - :meth:`WeylGroups.ParentMethods.pieri_factors` + - :meth:`WeylGroups.ElementMethods.stanley_symmetric_function` + + EXAMPLES:: sage: W = WeylGroup(['A',4]) sage: PF = W.pieri_factors() @@ -144,10 +145,12 @@ def elements(self): sage: [w.reduced_word() for w in PF.elements()] [[3, 2, 1], [2, 1], [1], [], [3, 1], [3], [3, 2], [2]] - ..seealso:: :meth:`maximal_elements` + .. SEEALSO:: :meth:`maximal_elements` + + .. TODO:: - TODO: possibly remove this method and instead have this class - inherit from :class:`TransitiveIdeal`. + Possibly remove this method and instead have this class + inherit from :class:`TransitiveIdeal`. """ return TransitiveIdeal(attrcall('bruhat_lower_covers'), self.maximal_elements()) @@ -240,8 +243,8 @@ def _test_maximal_elements(self, **options): @cached_method def max_length(self): - """ - Returns the maximal length of a Pieri factor + r""" + Return the maximal length of a Pieri factor. EXAMPLES: @@ -328,10 +331,11 @@ class PieriFactors_affine_type(PieriFactors): def maximal_elements(self): r""" - Returns the maximal elements of ``self`` with respect to - Bruhat order. The current implementation is via a conjectural - type-free formula. Use maximal_elements_combinatorial() for - proven type-specific implementations. To compare type-free and + Return the maximal elements of ``self`` with respect to Bruhat order. + + The current implementation is via a conjectural type-free + formula. Use maximal_elements_combinatorial() for proven + type-specific implementations. To compare type-free and type-specific (combinatorial) implementations, use method :meth:`_test_maximal_elements`. @@ -370,11 +374,12 @@ def maximal_elements(self): class PieriFactors_type_A(PieriFactors_finite_type): - r""" - The set of Pieri factors for finite type A. This is the set of elements of the - Weyl group that have a reduced word that is strictly decreasing. May also be - viewed as the restriction of affine type A Pieri factors to finite Weyl group + The set of Pieri factors for finite type A. + + This is the set of elements of the Weyl group that have a reduced + word that is strictly decreasing. May also be viewed as the + restriction of affine type A Pieri factors to finite Weyl group elements. """ @@ -423,7 +428,6 @@ def stanley_symm_poly_weight(self,w): class PieriFactors_type_B(PieriFactors_finite_type): - r""" The type B finite Pieri factors are realized as the set of elements that have a reduced word that is a subword of 12...(n-1)n(n-1)...21. They are the restriction @@ -500,7 +504,7 @@ class PieriFactors_type_A_affine(PieriFactors_affine_type): @staticmethod def __classcall__(cls, W, min_length = 0, max_length = infinity, min_support = frozenset([]), max_support = None): - """ + r""" TESTS:: sage: W = WeylGroup(['A',5,1]) @@ -616,7 +620,7 @@ def maximal_elements_combinatorial(self): return self.subset(self._max_length) def _test_maximal_elements(self, **options): - """ + r""" Same as :meth:`PieriFactors._test_maximal_elements`, but skips the tests if ``self`` is not the full set of Pieri factors. @@ -694,7 +698,7 @@ def __getitem__(self, support): Returns the cyclicaly decreasing element associated with ``support``. EXAMPLES:: -: + sage: W = WeylGroup(["A", 5, 1]) sage: W.pieri_factors()[[0,1,2,3,5]].reduced_word() [3, 2, 1, 0, 5] @@ -866,10 +870,11 @@ class PieriFactors_type_B_affine(PieriFactors_affine_type): r""" The type B affine Pieri factors are realized as the order ideal (in Bruhat order) generated by the following elements: - * cyclic rotations of the element with reduced word 234...(n-1)n(n-1)...3210, - except for 123...n...320 and 023...n...321. - * 123...(n-1)n(n-1)...321 - * 023...(n-1)n(n-1)...320 + + - cyclic rotations of the element with reduced word 234...(n-1)n(n-1)...3210, + except for 123...n...320 and 023...n...321. + - 123...(n-1)n(n-1)...321 + - 023...(n-1)n(n-1)...320 EXAMPLES:: @@ -964,7 +969,7 @@ def stanley_symm_poly_weight(self,w): return DiGraph(DynkinDiagram(ct)).subgraph(support_complement, algorithm="delete").connected_components_number() - 1 class PieriFactors_type_D_affine(PieriFactors_affine_type): - """ + r""" The type D affine Pieri factors are realized as the order ideal (in Bruhat order) generated by the following elements: diff --git a/src/sage/combinat/root_system/root_system.py b/src/sage/combinat/root_system/root_system.py index 1b563bfaa0d..1ca5d232ad8 100644 --- a/src/sage/combinat/root_system/root_system.py +++ b/src/sage/combinat/root_system/root_system.py @@ -1,5 +1,6 @@ -""" +r""" Root systems +============ Quickref -------- @@ -24,7 +25,7 @@ -------- - :class:`CoxeterGroups`, :class:`WeylGroups`, ...-- The categories of Coxeter and Weyl groups -- :ref:`sage.combinat.crystals.crystals` -- An introduction to crystals +- :ref:`sage.combinat.crystals` -- Crystals - :mod:`.type_A`, :mod:`.type_B_affine`, ... -- Type specific root system data """ diff --git a/src/sage/combinat/sf/__init__.py b/src/sage/combinat/sf/__init__.py index 8b137891791..7b1951ca3fe 100644 --- a/src/sage/combinat/sf/__init__.py +++ b/src/sage/combinat/sf/__init__.py @@ -1 +1,29 @@ +__doc__ = r""" +Symmetric Functions +=================== +.. TODO:: + + Populate + + sage/combinat/sf/sfa + sage/combinat/sf/sf + sage/combinat/sf/classical + sage/combinat/sf/schur + sage/combinat/sf/monomial + sage/combinat/sf/multiplicative + sage/combinat/sf/elementary + sage/combinat/sf/homogeneous + sage/combinat/sf/powersum + sage/combinat/sf/dual + sage/combinat/sf/orthotriang + sage/combinat/sf/kfpoly + sage/combinat/sf/hall_littlewood + sage/combinat/sf/jack + sage/combinat/sf/new_kschur + sage/combinat/sf/k_dual + sage/combinat/sf/llt + sage/combinat/sf/macdonald + sage/combinat/sf/ns_macdonald + sage/combinat/sf/witt +""" diff --git a/src/sage/combinat/species/__init__.py b/src/sage/combinat/species/__init__.py index c9fecacd721..be08cb20da1 100644 --- a/src/sage/combinat/species/__init__.py +++ b/src/sage/combinat/species/__init__.py @@ -1 +1,54 @@ +__doc__ = r""" +Combinatorial Species +===================== + +.. TODO:: Short blurb about species + +.. TODO:: Proofread / point to the main classes rather than the modules? + +Introductory material +--------------------- + +- :ref:`section-examples-catalan` +- :ref:`section-generic-species` + +Lazy Power Series +----------------- + +- :mod:`sage/combinat/species/stream` +- :mod:`sage/combinat/species/series_order` +- :mod:`sage/combinat/species/series` +- :mod:`sage/combinat/species/generating_series` + +Basic Species +------------- + +- :mod:`sage/combinat/species/species` +- :mod:`sage/combinat/species/empty_species` +- :mod:`sage/combinat/species/recursive_species` +- :mod:`sage/combinat/species/characteristic_species` +- :mod:`sage/combinat/species/cycle_species` +- :mod:`sage/combinat/species/partition_species` +- :mod:`sage/combinat/species/permutation_species` +- :mod:`sage/combinat/species/linear_order_species` +- :mod:`sage/combinat/species/set_species` +- :mod:`sage/combinat/species/subset_species` +- :mod:`sage/combinat/species/library` + +Operations on Species +--------------------- + +- :mod:`sage/combinat/species/sum_species` +- :mod:`sage/combinat/species/product_species` +- :mod:`sage/combinat/species/composition_species` +- :mod:`sage/combinat/species/functorial_composition_species` + +Miscellaneous +------------- + +- :mod:`sage/combinat/species/structure` +- :mod:`sage/combinat/species/misc` +- :mod:`sage/combinat/species/combinatorial_logarithm` +""" + import all diff --git a/src/sage/combinat/words/__init__.py b/src/sage/combinat/words/__init__.py index c9fecacd721..ab290aad8c6 100644 --- a/src/sage/combinat/words/__init__.py +++ b/src/sage/combinat/words/__init__.py @@ -1 +1,20 @@ +__doc__ = r""" +Words +===== + +.. TODO:: + + - Check that those are the important entry points + - Add links from the module documentation to the important classes/functions + +- :func:`sage.combinat.words.alphabet.build_alphabet` +- :func:`sage.combinat.word.Word` +- :func:`sage.combinat.words.Words` +- :ref:`sage.combinat.words.word_generators` +- :class:`sage.combinat.words.shuffle_product.ShuffleProduct`, :class:`sage.combinat.words.shuffle_product.ShuffleProduct` ??? +- :ref:`sage.combinat.words.suffix_trees` +- :ref:`sage.combinat.words.morphism` +- :ref:`sage.combinat.words.paths` +""" +# Is this really needed? import all diff --git a/src/sage/combinat/words/word_infinite_datatypes.py b/src/sage/combinat/words/word_infinite_datatypes.py index f3b5e08e68a..0b643a052ea 100644 --- a/src/sage/combinat/words/word_infinite_datatypes.py +++ b/src/sage/combinat/words/word_infinite_datatypes.py @@ -533,9 +533,10 @@ def flush(self): r""" Empty the associated cache of letters. - EXAMPLES:: + EXAMPLES: + + The first 40 (by default) values are always cached:: - The first 40 (by default) values are always cached. sage: w = words.ThueMorseWord() sage: w._letter_cache {0: 0, 1: 1, 2: 1, 3: 0, 4: 1, 5: 0, 6: 0, 7: 1, 8: 1, 9: 0, 10: 0, 11: 1, 12: 0, 13: 1, 14: 1, 15: 0, 16: 1, 17: 0, 18: 0, 19: 1, 20: 0, 21: 1, 22: 1, 23: 0, 24: 0, 25: 1, 26: 1, 27: 0, 28: 1, 29: 0, 30: 0, 31: 1, 32: 1, 33: 0, 34: 0, 35: 1, 36: 0, 37: 1, 38: 1, 39: 0} From 3b84036c7a2c08f5adef73851e4f40ef838a4b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Tue, 22 Apr 2014 19:29:48 +0200 Subject: [PATCH 016/698] Trac 16058: Reorganize the documentation indexes into src/sage/combinat (follow up little fixes) --- src/doc/en/reference/combinat/module_list.rst | 4 +- src/doc/en/reference/groups/index.rst | 2 + src/sage/combinat/__init__.py | 2 +- src/sage/combinat/enumerated_sets.py | 60 +++++++++---------- 4 files changed, 35 insertions(+), 33 deletions(-) diff --git a/src/doc/en/reference/combinat/module_list.rst b/src/doc/en/reference/combinat/module_list.rst index 88aad47ef79..01e6dbc975c 100644 --- a/src/doc/en/reference/combinat/module_list.rst +++ b/src/doc/en/reference/combinat/module_list.rst @@ -3,13 +3,13 @@ Alphabetical module list .. NOTE:: - This is built automatically by running in src/sage/combinat: + This is built automatically by running in src/sage/combinat:: for x in **/*.py*; do echo " sage/combinat/"`echo $x | sed 's/\.py.?$//'`; done >! /tmp/module_list .. TODO:: - Improve by not flattening the module hierarchical structure + Improve this list by not flattening the module hierarchical structure. .. toctree:: :maxdepth: 1 diff --git a/src/doc/en/reference/groups/index.rst b/src/doc/en/reference/groups/index.rst index 384f0976103..6c42143c887 100644 --- a/src/doc/en/reference/groups/index.rst +++ b/src/doc/en/reference/groups/index.rst @@ -21,11 +21,13 @@ Groups sage/groups/abelian_gps/abelian_group_morphism sage/groups/additive_abelian/additive_abelian_group sage/groups/additive_abelian/additive_abelian_wrapper + sage/groups/perm_gps/permutation_groups_catalog sage/groups/perm_gps/permgroup sage/groups/perm_gps/permgroup_named sage/groups/perm_gps/permgroup_element sage/groups/perm_gps/permgroup_morphism sage/groups/perm_gps/cubegroup + sage/groups/matrix_gps/catalog sage/groups/matrix_gps/matrix_group sage/groups/matrix_gps/group_element sage/groups/matrix_gps/finitely_generated diff --git a/src/sage/combinat/__init__.py b/src/sage/combinat/__init__.py index 0b12e6dbf2b..f1df4876300 100644 --- a/src/sage/combinat/__init__.py +++ b/src/sage/combinat/__init__.py @@ -24,7 +24,7 @@ .. TODO:: point instead to the main entry point for graphs -- :ref:`Graph`, :ref:`DiGraph`, :obj:`graphs`, :obj:`digraphs` +- :class:`Graph`, :class:`DiGraph`, :obj:`graphs`, :obj:`digraphs` Dynamical systems ----------------- diff --git a/src/sage/combinat/enumerated_sets.py b/src/sage/combinat/enumerated_sets.py index 20af23d4219..726dbcc4f7f 100644 --- a/src/sage/combinat/enumerated_sets.py +++ b/src/sage/combinat/enumerated_sets.py @@ -27,63 +27,63 @@ - :func:`sage.combinat.integer_vector_weighted.WeightedIntegerVectors` - :class:`sage.combinat.integer_vectors_mod_permgroup.IntegerVectorsModPermutationGroup` -- :mod:`sage.combinat.parking_functions` -- :mod:`sage.combinat.non_decreasing_parking_function` +- :ref:`sage.combinat.parking_functions` +- :ref:`sage.combinat.non_decreasing_parking_function` -- :mod:`sage.combinat.sidon_sets` +- :ref:`sage.combinat.sidon_sets` Words ----- - :class:`Words` -- :mod:`sage.combinat.subword` -- :mod:`sage.combinat.necklace` -- :mod:`sage.combinat.lyndon_word` -- :mod:`sage.combinat.dyck_word` -- :mod:`sage.combinat.debruijn_sequence` +- :ref:`sage.combinat.subword` +- :ref:`sage.combinat.necklace` +- :ref:`sage.combinat.lyndon_word` +- :ref:`sage.combinat.dyck_word` +- :ref:`sage.combinat.debruijn_sequence` Permutations, ... ----------------- -- :mod:`sage.combinat.permutation` -- :mod:`sage.combinat.affine_permutation` +- :ref:`sage.combinat.permutation` +- :ref:`sage.combinat.affine_permutation` - :class:`sage.combinat.permutation.Arrangements` -- :mod:`sage.combinat.derangements` -- :mod:`sage.combinat.integer_vectors_mod_permgroup` -- :mod:`sage.combinat.rsk` +- :ref:`sage.combinat.derangements` +- :ref:`sage.combinat.integer_vectors_mod_permgroup` +- :ref:`sage.combinat.rsk` .. SEEALSO:: - - :class:`PermutationGroup`, :class:`SymmetricGroup` + - :class:`SymmetricGroup`, :class:`PermutationGroup`, :ref:`sage.groups.perm_gps.permutation_groups_catalog` - :class:`FiniteSetMaps` Partitions, tableaux, ... ------------------------- -See: :mod:`sage.combinat.catalog_partitions` +See: :ref:`sage.combinat.catalog_partitions` Integer matrices, ... --------------------- -- :mod:`sage.combinat.integer_matrices` -- :mod:`sage.combinat.matrices.hadamard_matrix` -- :mod:`sage.combinat.matrices.latin` -- :mod:`sage.combinat.alternating_sign_matrix` -- :mod:`sage.combinat.six_vertex_model` -- :mod:`sage.combinat.similarity_class_type` -- :mod:`sage.combinat.restricted_growth` -- :mod:`sage.combinat.vector_partition` +- :ref:`sage.combinat.integer_matrices` +- :ref:`sage.combinat.matrices.hadamard_matrix` +- :ref:`sage.combinat.matrices.latin` +- :ref:`sage.combinat.alternating_sign_matrix` +- :ref:`sage.combinat.six_vertex_model` +- :ref:`sage.combinat.similarity_class_type` +- :ref:`sage.combinat.restricted_growth` +- :ref:`sage.combinat.vector_partition` .. SEEALSO:: - :class:`MatrixSpace` - - :mod:`groups.matrix` + - :ref:`sage.groups.matrix_gps.catalog` Set partitions, ... ------------------- -- :mod:`sage.combinat.set_partition_ordered` -- :mod:`sage.combinat.set_partition` +- :ref:`sage.combinat.set_partition_ordered` +- :ref:`sage.combinat.set_partition` - :class:`sage.combinat.subsets_pairwise.PairwiseCompatibleSubsets` Trees @@ -118,10 +118,10 @@ Low level enumerated sets ------------------------- -- :mod:`sage.combinat.permutation_nk` -- :mod:`sage.combinat.split_nk` -- :mod:`sage.combinat.choose_nk` -- :mod:`sage.combinat.multichoose_nk` +- :ref:`sage.combinat.permutation_nk` +- :ref:`sage.combinat.split_nk` +- :ref:`sage.combinat.choose_nk` +- :ref:`sage.combinat.multichoose_nk` Misc enumerated sets -------------------- From b57017903cfe976bc3c8f1adda47127467b2f73c Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Sun, 27 Apr 2014 14:37:05 +0200 Subject: [PATCH 017/698] trac 14567: continued fraction (based on 6.2.rc0) - new file continued_fraction in sage/rings that implements various continued fractions (finite, periodic, infinite) - move some methods in sage.rings.arith in sage/rings/continued_fraction - modify appropriately the code and doctests of other modules --- .../diophantine_approximation/conf.py | 1 + .../diophantine_approximation/index.rst | 13 + src/doc/en/reference/index.rst | 1 + src/sage/calculus/wester.py | 2 +- src/sage/combinat/words/word_generators.py | 18 +- src/sage/databases/oeis.py | 6 +- src/sage/geometry/cone.py | 2 +- src/sage/modular/modsym/ambient.py | 5 +- src/sage/modular/modsym/modular_symbols.py | 4 +- src/sage/plot/misc.py | 9 +- src/sage/rings/all.py | 13 +- src/sage/rings/arith.py | 425 +-- src/sage/rings/contfrac.py | 1080 ++------ src/sage/rings/continued_fraction.py | 2379 +++++++++++++++++ .../number_field_element_quadratic.pyx | 62 + src/sage/rings/rational.pyx | 121 + src/sage/tests/book_stein_ent.py | 52 +- src/sage/tests/book_stein_modform.py | 2 +- 18 files changed, 2818 insertions(+), 1377 deletions(-) create mode 120000 src/doc/en/reference/diophantine_approximation/conf.py create mode 100644 src/doc/en/reference/diophantine_approximation/index.rst create mode 100644 src/sage/rings/continued_fraction.py diff --git a/src/doc/en/reference/diophantine_approximation/conf.py b/src/doc/en/reference/diophantine_approximation/conf.py new file mode 120000 index 00000000000..2bdf7e68470 --- /dev/null +++ b/src/doc/en/reference/diophantine_approximation/conf.py @@ -0,0 +1 @@ +../conf_sub.py \ No newline at end of file diff --git a/src/doc/en/reference/diophantine_approximation/index.rst b/src/doc/en/reference/diophantine_approximation/index.rst new file mode 100644 index 00000000000..a1c49919f81 --- /dev/null +++ b/src/doc/en/reference/diophantine_approximation/index.rst @@ -0,0 +1,13 @@ +Diophantine approximation +========================= + +The diophantine approximation deals with the approximation of real numbers +(or real vectors) with rational numbers (or rational vectors). +See the article :wikipedia:`Diophantine_approximation` for more information. + +.. toctree:: + :maxdepth: 2 + + sage/rings/continued_fraction + +.. include:: ../footer.txt diff --git a/src/doc/en/reference/index.rst b/src/doc/en/reference/index.rst index 9683ebed0ff..5051fcc0bb0 100644 --- a/src/doc/en/reference/index.rst +++ b/src/doc/en/reference/index.rst @@ -96,6 +96,7 @@ Geometry and Topology Number Theory, Algebraic Geometry --------------------------------- +* :doc:`Diophantine approximation ` * :doc:`Quadratic Forms ` * :doc:`L-Functions ` * :doc:`Schemes ` diff --git a/src/sage/calculus/wester.py b/src/sage/calculus/wester.py index 8107fc8c828..4a88873a688 100644 --- a/src/sage/calculus/wester.py +++ b/src/sage/calculus/wester.py @@ -53,7 +53,7 @@ sage: # (YES) Continued fraction of 3.1415926535 sage: a = 3.1415926535 sage: continued_fraction(a) - [3, 7, 15, 1, 292, 1, 1, 6, 2, 13, 4] + [3; 7, 15, 1, 292, 1, 1, 6, 2, 13, 4] :: diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index ec3be815a82..e1c283b2968 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -198,8 +198,8 @@ def __init__(self, p, q, alphabet=(0,1), algorithm='cf'): elif (p, q) == (1, 0): w = [alphabet[1]] else: - from sage.rings.all import QQ, CFF - cf = CFF(QQ((p, q))) + from sage.rings.rational_field import QQ + cf = QQ((p, q)).continued_fraction_list() u = [alphabet[0]] v = [alphabet[1]] #do not consider the first zero if p < q @@ -874,8 +874,12 @@ def CharacteristicSturmianWord(self, slope, alphabet=(0, 1), bits=None): msg = "The argument slope (=%s) must be in ]0,1[."%slope raise ValueError(msg) from sage.rings.all import CFF - cf = iter(CFF(slope, bits=bits)) - length = 'finite' + cf = CFF(slope, bits=bits) + if cf.length() == Infinity: + length = Infinity + else: + length = 'finite' + cf = iter(cf) elif hasattr(slope, '__iter__'): cf = iter(slope) length = Infinity @@ -913,16 +917,16 @@ def _CharacteristicSturmianWord_LetterIterator(self, cf, alphabet=(0,1)): EXAMPLES:: sage: CFF(1/golden_ratio^2)[:8] - [0, 2, 1, 1, 1, 1, 1, 1] + [0; 2, 1, 1, 1, 1, 2] sage: cf = iter(_) sage: Word(words._CharacteristicSturmianWord_LetterIterator(cf)) - word: 0100101001001010010100100101001001 + word: 0100101001001010010100100101001010 :: sage: alpha = (sqrt(3)-1)/2 sage: CFF(alpha)[:10] - [0, 2, 1, 2, 1, 2, 1, 2, 1, 2] + [0; 2, 1, 2, 1, 2, 1, 2, 1, 2] sage: cf = iter(_) sage: Word(words._CharacteristicSturmianWord_LetterIterator(cf)) word: 0100100101001001001010010010010100100101... diff --git a/src/sage/databases/oeis.py b/src/sage/databases/oeis.py index 99a3d56ab9f..ed0ac591a27 100644 --- a/src/sage/databases/oeis.py +++ b/src/sage/databases/oeis.py @@ -10,7 +10,9 @@ AUTHORS: - - Thierry Monteil (2012-02-10 -- 2013-06-21): initial version. +- Thierry Monteil (2012-02-10 -- 2013-06-21): initial version. + +- Vincent Delecroix (2014): modifies continued fractions because of trac:`14567` EXAMPLES:: @@ -928,7 +930,7 @@ def natural_object(self): sage: s = oeis._imaginary_sequence('nonn,cofr') sage: s.natural_object().parent() - Field of all continued fractions + QQ as continued fractions sage: s = oeis._imaginary_sequence('nonn') sage: s.natural_object().parent() diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index ad1447a1563..ae2869337a2 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -1065,7 +1065,7 @@ def classify_cone_2d(ray0, ray1, check=True): ... d, k = classify_cone_2d(ray0, ray1, check=True) ... assert (d,k) == classify_cone_2d(ray1, ray0) ... if d == 0: continue - ... frac = Hirzebruch_Jung_continued_fraction_list(k/d) + ... frac = (k/d).continued_fraction_list("hj") ... if len(frac)>100: continue # avoid expensive computation ... hilb = Cone([ray0, ray1]).Hilbert_basis() ... assert len(hilb) == len(frac) + 1 diff --git a/src/sage/modular/modsym/ambient.py b/src/sage/modular/modsym/ambient.py index ff6a4dc82fb..87ec99a8b9f 100644 --- a/src/sage/modular/modsym/ambient.py +++ b/src/sage/modular/modsym/ambient.py @@ -640,7 +640,10 @@ def _modular_symbol_0_to_alpha(self, alpha, i=0): """ if alpha.is_infinity(): return self.manin_symbol((i,0,1), check=False) - v, c = arith.continued_fraction_list(alpha._rational_(), partial_convergents=True) + # v, c = arith.continued_fraction_list(alpha._rational_(), partial_convergents=True) + cf = alpha._rational_().continued_fraction() + v = list(cf) + c = [(cf.p(k),cf.q(k)) for k in xrange(len(cf))] a = self(0) zero = rings.ZZ(0) one = rings.ZZ(1) diff --git a/src/sage/modular/modsym/modular_symbols.py b/src/sage/modular/modsym/modular_symbols.py index c46f143369a..ed2146dabb3 100644 --- a/src/sage/modular/modsym/modular_symbols.py +++ b/src/sage/modular/modsym/modular_symbols.py @@ -36,7 +36,6 @@ import sage.modular.modsym.manin_symbols from sage.structure.sage_object import SageObject import sage.structure.formal_sum as formal_sum -import sage.rings.arith as arith from sage.rings.integer_ring import ZZ from sage.misc.latex import latex @@ -333,7 +332,8 @@ def __manin_symbol_rep(self, alpha): k = space.weight() v = [(0,1), (1,0)] if not alpha.is_infinity(): - v += [(x.numerator(), x.denominator()) for x in arith.convergents(alpha._rational_())] + cf = alpha._rational_().continued_fraction() + v.extend((cf.p(k),cf.q(k)) for k in xrange(len(cf))) sign = 1 apply = sage.modular.modsym.manin_symbols.apply_to_monomial mansym = sage.modular.modsym.manin_symbols.ManinSymbol diff --git a/src/sage/plot/misc.py b/src/sage/plot/misc.py index 86a5a157016..0c4dbd56bf6 100644 --- a/src/sage/plot/misc.py +++ b/src/sage/plot/misc.py @@ -233,9 +233,12 @@ def _multiple_of_constant(n,pos,const): sage: plot(x^2, (x,0,10), ticks=[sqrt(2),8], tick_formatter=sqrt(2)) """ from sage.misc.latex import latex - from sage.rings.arith import convergents - c=[i for i in convergents(n/const.n()) if i.denominator()<12] - return '$%s$'%latex(c[-1]*const) + from sage.rings.continued_fraction import continued_fraction + cf = continued_fraction(n/const) + k = 1 + while cf.quotient(k) and cf.denominator(k) < 12: + k += 1 + return '$%s$'%latex(cf.convergent(k-1)*const) def get_matplotlib_linestyle(linestyle, return_type): diff --git a/src/sage/rings/all.py b/src/sage/rings/all.py index 7389443dee0..a064b8e98d2 100644 --- a/src/sage/rings/all.py +++ b/src/sage/rings/all.py @@ -131,9 +131,6 @@ from fraction_field import FractionField Frac = FractionField -# continued fractions -from contfrac import continued_fraction, CFF, ContinuedFractionField - # Arithmetic from arith import algdep, bernoulli, is_prime, is_prime_power, \ is_pseudoprime, is_pseudoprime_small_power, valuation, \ @@ -148,7 +145,6 @@ CRT_vectors, multinomial, multinomial_coefficients, \ kronecker_symbol, kronecker, legendre_symbol, \ primitive_root, nth_prime, quadratic_residues, moebius, \ - farey, continued_fraction_list, convergent, convergents, \ continuant, number_of_divisors, hilbert_symbol, hilbert_conductor, \ hilbert_conductor_inverse, falling_factorial, rising_factorial, \ integer_ceil, integer_floor, two_squares, four_squares, \ @@ -156,7 +152,7 @@ sort_complex_numbers_for_display, \ fundamental_discriminant, squarefree_divisors, \ Sigma, radical, Euler_Phi, binomial_coefficients, jacobi_symbol, \ - Moebius, Hirzebruch_Jung_continued_fraction_list, dedekind_sum, \ + Moebius, dedekind_sum, \ prime_factors @@ -186,3 +182,10 @@ from sage.misc.lazy_import import lazy_import lazy_import('sage.rings.invariant_theory', 'invariant_theory') + +# continued fractions +from sage.rings.continued_fraction import (farey, convergents, + continued_fraction, continued_fraction_list, + Hirzebruch_Jung_continued_fraction_list) +# and deprecated continued fractions +from sage.rings.contfrac import (CFF, ContinuedFractionField) diff --git a/src/sage/rings/arith.py b/src/sage/rings/arith.py index b9efb9f7b7f..d7ed1bee90e 100644 --- a/src/sage/rings/arith.py +++ b/src/sage/rings/arith.py @@ -3934,428 +3934,9 @@ def range(self, start, stop=None, step=None): moebius = Moebius() -def farey(v, lim): - """ - Return the Farey sequence associated to the floating point number - v. - - INPUT: - - - - ``v`` - float (automatically converted to a float) - - - ``lim`` - maximum denominator. - - - OUTPUT: Results are (numerator, denominator); (1, 0) is "infinity". - - EXAMPLES:: - - sage: farey(2.0, 100) - (2, 1) - sage: farey(2.0, 1000) - (2, 1) - sage: farey(2.1, 1000) - (21, 10) - sage: farey(2.1, 100000) - (21, 10) - sage: farey(pi, 100000) - (312689, 99532) - - AUTHORS: - - - Scott David Daniels: Python Cookbook, 2nd Ed., Recipe 18.13 - """ - v = float(v) - if v < 0: - n, d = farey(-v, lim) - return -n, d - z = lim - lim # Get a "0 of the right type" for denominator - lower, upper = (z, z+1), (z+1, z) - while True: - mediant = (lower[0] + upper[0]), (lower[1] + upper[1]) - if v * mediant[1] > mediant[0]: - if lim < mediant[1]: - return upper - lower = mediant - elif v * mediant[1] == mediant[0]: - if lim >= mediant[1]: - return mediant - if lower[1] < upper[1]: - return lower - return upper - else: - if lim < mediant[1]: - return lower - upper = mediant - - -## def convergents_pnqn(x): -## """ -## Return the pairs (pn,qn) that are the numerators and denominators -## of the partial convergents of the continued fraction of x. We -## include (0,1) and (1,0) at the beginning of the list (these are -## the -2 and -1 th convergents). -## """ -## v = pari(x).contfrac() -## w = [(0,1), (1,0)] -## for n in range(len(v)): -## pn = w[n+1][0]*v[n] + w[n][0] -## qn = w[n+1][1]*v[n] + w[n][1] -## w.append(int(pn), int(qn)) -## return w - -def continued_fraction_list(x, partial_convergents=False, bits=None, nterms=None): - r""" - Returns the continued fraction of x as a list. - - The continued fraction expansion of `x` are the coefficients `a_i` in - - .. math:: - - x = a_1 + 1/(a_2+1/(...) ... ) - - with `a_1` integer and `a_2`, `...` positive integers. - - .. note:: - - This may be slow for real number input, since it's implemented in pure - Python. For rational number input the PARI C library is used. - - .. SEEALSO:: - - :func:`Hirzebruch_Jung_continued_fraction_list` for - Hirzebruch-Jung continued fractions. - - INPUT: - - - ``x`` -- exact rational or floating-point number. The number to - compute the continued fraction of. - - - ``partial_convergents`` -- boolean. Whether to return the partial convergents. - - - ``bits`` -- integer. the precision of the real interval field - that is used internally. - - - ``nterms`` -- integer. The upper bound on the number of terms in - the continued fraction expansion to return. - - OUTPUT: - - A lits of integers, the coefficients in the continued fraction - expansion of ``x``. If ``partial_convergents=True`` is passed, a - pair containing the coefficient list and the partial convergents - list is returned. - - EXAMPLES:: - - sage: continued_fraction_list(45/17) - [2, 1, 1, 1, 5] - sage: continued_fraction_list(e, bits=20) - [2, 1, 2, 1, 1, 4, 1, 1] - sage: continued_fraction_list(e, bits=30) - [2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8] - sage: continued_fraction_list(sqrt(2)) - [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] - sage: continued_fraction_list(sqrt(4/19)) - [0, 2, 5, 1, 1, 2, 1, 16, 1, 2, 1, 1, 5, 4, 5, 1, 1, 2, 1] - sage: continued_fraction_list(RR(pi), partial_convergents=True) - ([3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 3], - [(3, 1), - (22, 7), - (333, 106), - (355, 113), - (103993, 33102), - (104348, 33215), - (208341, 66317), - (312689, 99532), - (833719, 265381), - (1146408, 364913), - (4272943, 1360120), - (5419351, 1725033), - (80143857, 25510582), - (245850922, 78256779)]) - sage: continued_fraction_list(e) - [2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1] - sage: continued_fraction_list(RR(e)) - [2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1] - sage: continued_fraction_list(RealField(200)(e)) - [2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1, - 14, 1, 1, 16, 1, 1, 18, 1, 1, 20, 1, 1, 22, 1, 1, 24, 1, 1, - 26, 1, 1, 28, 1, 1, 30, 1, 1, 32, 1, 1, 34, 1, 1, 36, 1, 1, 38, 1, 1] - - TESTS:: - - sage: continued_fraction_list(1 + 10^-10, nterms=3) - [1, 10000000000] - sage: continued_fraction_list(1 + 10^-20 - e^-100, bits=10, nterms=3) - [1, 100000000000000000000, 2688] - sage: continued_fraction_list(1 + 10^-20 - e^-100, bits=10, nterms=5) - [1, 100000000000000000000, 2688, 8, 1] - sage: continued_fraction_list(1 + 10^-20 - e^-100, bits=1000, nterms=5) - [1, 100000000000000000000, 2688, 8, 1] - - Check that :trac:`14858` is fixed:: - - sage: continued_fraction_list(3/4) == continued_fraction_list(SR(3/4)) - True - - """ - if isinstance(x, sage.symbolic.expression.Expression): - try: - x = x.pyobject() - except TypeError: - pass - - if isinstance(x, (integer.Integer, int, long)): - if partial_convergents: - return [x], [(x,1)] - else: - return [x] - - if isinstance(x, sage.rings.rational.Rational): - if bits is not None and nterms is None: - x = RealIntervalField(bits)(x) - else: - # PARI is faster than the pure Python below, but doesn't give us the convergents. - v = pari(x).contfrac().python() - if nterms is not None: - v = v[:nterms] - if partial_convergents: - w = [(0,1), (1,0)] - for a in v: - pn = a*w[-1][0] + w[-2][0] - qn = a*w[-1][1] + w[-2][1] - w.append((pn, qn)) - return v, w[2:] - else: - return v - - # Work in interval field, increasing precision as needed. - if bits is None: - try: - bits = x.prec() - except AttributeError: - bits = 53 - RIF = RealIntervalField(bits) - v = [] - w = [(0,1), (1,0)] - orig, x = x, RIF(x) - - while True: - try: - a = x.unique_floor() - except ValueError: - # Either we're done or we need more precision. - if nterms is None: - break - else: - RIF = RIF.to_prec(2*RIF.prec()) - x = RIF(orig) - for a in v: x = ~(x-a) - continue - if partial_convergents: - pn = a*w[-1][0] + w[-2][0] - qn = a*w[-1][1] + w[-2][1] - w.append((pn, qn)) - v.append(a) - if x == a or nterms is not None and len(v) >= nterms: - break - x = ~(x-a) - - if partial_convergents: - return v, w[2:] - else: - return v - - -def Hirzebruch_Jung_continued_fraction_list(x, bits=None, nterms=None): - r""" - Return the Hirzebruch-Jung continued fraction of ``x`` as a list. - - The Hirzebruch-Jung continued fraction of `x` is similar to the - ordinary continued fraction expansion, but with minus signs. That - is, the coefficients `a_i` in - - .. math:: - - x = a_1 - 1/(a_2-1/(...) ... ) - - with `a_1` integer and `a_2`, `...` positive integers. - - .. SEEALSO:: - - :func:`continued_fraction_list` for ordinary continued fractions. - - INPUT: - - - ``x`` -- exact rational or something that can be numerically - evaluated. The number to compute the continued fraction of. - - - ``bits`` -- integer (default: the precision of ``x``). the - precision of the real interval field that is used - internally. This is only used if ``x`` is not an exact fraction. - - - ``nterms`` -- integer (default: None). The upper bound on the - number of terms in the continued fraction expansion to return. - - OUTPUT: - - A lits of integers, the coefficients in the Hirzebruch-Jung continued - fraction expansion of ``x``. - - EXAMPLES:: - - sage: Hirzebruch_Jung_continued_fraction_list(17/11) - [2, 3, 2, 2, 2, 2] - sage: Hirzebruch_Jung_continued_fraction_list(45/17) - [3, 3, 6] - sage: Hirzebruch_Jung_continued_fraction_list(e, bits=20) - [3, 4, 3, 2, 2, 2, 3, 7] - sage: Hirzebruch_Jung_continued_fraction_list(e, bits=30) - [3, 4, 3, 2, 2, 2, 3, 8, 3, 2, 2, 2, 2, 2, 2, 2, 3] - sage: Hirzebruch_Jung_continued_fraction_list(sqrt(2), bits=100) - [2, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, - 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 2] - sage: Hirzebruch_Jung_continued_fraction_list(sqrt(4/19)) - [1, 2, 7, 3, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 7, - 2, 2, 2, 7, 3, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] - sage: Hirzebruch_Jung_continued_fraction_list(pi) - [4, 2, 2, 2, 2, 2, 2, 17, 294, 3, 4, 5, 16, 2, 2] - sage: Hirzebruch_Jung_continued_fraction_list(e) - [3, 4, 3, 2, 2, 2, 3, 8, 3, 2, 2, 2, 2, 2, 2, 2, - 3, 12, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 10] - sage: Hirzebruch_Jung_continued_fraction_list(e, nterms=20) - [3, 4, 3, 2, 2, 2, 3, 8, 3, 2, 2, 2, 2, 2, 2, 2, 3, 12, 3, 2] - sage: len(_) == 20 - True - - TESTS:: - - sage: Hirzebruch_Jung_continued_fraction_list(1 - 10^-10, nterms=3) - [1, 10000000000] - sage: Hirzebruch_Jung_continued_fraction_list(1 - 10^-10 - e^-100, bits=100, nterms=5) - [1, 10000000000] - sage: Hirzebruch_Jung_continued_fraction_list(1 - 10^-20 - e^-100, bits=1000, nterms=5) - [1, 100000000000000000000, 2689, 2, 2] - """ - if not isinstance(x, sage.rings.rational.Rational): - try: - x = QQ(x) - except TypeError: - # Numerically evaluate x - if bits is None: - try: - bits = x.prec() - except AttributeError: - bits = 53 - x = QQ(x.n(bits)) - v = [] - while True: - div, mod = divmod(x.numerator(), x.denominator()) - if mod == 0: - v.append(div) - break - v.append(div+1) - if nterms is not None and len(v) >= nterms: - break - x = 1/(div+1-x) - return v - - -def convergent(v, n): - r""" - Return the n-th continued fraction convergent of the continued - fraction defined by the sequence of integers v. We assume - `n \geq 0`. - - INPUT: - - - - ``v`` - list of integers - - - ``n`` - integer - - - OUTPUT: a rational number - - If the continued fraction integers are - - .. math:: - - v = [a_0, a_1, a_2, \ldots, a_k] - - - then ``convergent(v,2)`` is the rational number - - .. math:: - - a_0 + 1/a_1 - - and ``convergent(v,k)`` is the rational number - - .. math:: - - a1 + 1/(a2+1/(...) ... ) - - represented by the continued fraction. - - EXAMPLES:: - - sage: convergent([2, 1, 2, 1, 1, 4, 1, 1], 7) - 193/71 - """ - if hasattr(v, 'convergent'): - return v.convergent(n) - i = int(n) - x = QQ(v[i]) - i -= 1 - while i >= 0: - x = QQ(v[i]) + 1/x - i -= 1 - return x - - -def convergents(v): - """ - Return all the partial convergents of a continued fraction defined - by the sequence of integers v. - - If v is not a list, compute the continued fraction of v and return - its convergents (this is potentially much faster than calling - continued_fraction first, since continued fractions are - implemented using PARI and there is overhead moving the answer back - from PARI). - - INPUT: - - - - ``v`` - list of integers or a rational number - - - OUTPUT: - - - - ``list`` - of partial convergents, as rational - numbers - - - EXAMPLES:: - - sage: convergents([2, 1, 2, 1, 1, 4, 1, 1]) - [2, 3, 8/3, 11/4, 19/7, 87/32, 106/39, 193/71] - """ - if hasattr(v, 'convergents'): - return v.convergents() - if not isinstance(v, list): - v = pari(v).contfrac() - w = [(0,1), (1,0)] - for n in range(len(v)): - pn = w[n+1][0]*v[n] + w[n][0] - qn = w[n+1][1]*v[n] + w[n][1] - w.append((pn, qn)) - return [QQ(x) for x in w[2:]] +## Note: farey, convergent, continued_fraction_list and convergents have been moved to +## sage.rings.continued_fraction ## def continuant(v, n=None): ## """ @@ -4402,7 +3983,7 @@ def continuant(v, n=None): sage: q = continuant([1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10]) sage: p/q 517656/190435 - sage: convergent([2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10],14) + sage: continued_fraction([2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10]).convergent(14) 517656/190435 sage: x = PolynomialRing(RationalField(),'x',5).gens() sage: continuant(x) diff --git a/src/sage/rings/contfrac.py b/src/sage/rings/contfrac.py index cfd8a42a343..101e55c5a67 100644 --- a/src/sage/rings/contfrac.py +++ b/src/sage/rings/contfrac.py @@ -1,310 +1,214 @@ r""" -Continued Fractions +Continued fraction field Sage implements the field ``ContinuedFractionField`` (or ``CFF`` -for short) of finite simple continued fractions. This is really +for short) of finite simple continued fractions. This is really isomorphic to the field `\QQ` of rational numbers, but with different printing and semantics. It should be possible to use this field in -most cases where one could use `\QQ`, except arithmetic is slower. - -The ``continued_fraction(x)`` command returns an element of -``CFF`` that defines a continued fraction expansion to `x`. The -command ``continued_fraction(x,bits)`` computes the continued -fraction expansion of an approximation to `x` with given bits of -precision. Use ``show(c)`` to see a continued fraction nicely -typeset, and ``latex(c)`` to obtain the typeset version, e.g., for -inclusion in a paper. - -EXAMPLES: -We create some example elements of the continued fraction field:: - - sage: c = continued_fraction([1,2]); c - [1, 2] - sage: c = continued_fraction([3,7,15,1,292]); c - [3, 7, 15, 1, 292] - sage: c = continued_fraction(pi); c - [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14] - sage: c.value() - 80143857/25510582 - sage: QQ(c) - 80143857/25510582 - sage: RealField(200)(QQ(c) - pi) - -5.7908701643756732744264903067012149647564522968979302505514e-16 - -We can also create matrices, polynomials, vectors, etc., over the continued -fraction field. - -:: +most cases where one could use `\QQ`, except arithmetic is *much* slower. + +EXAMPLES:: + +We can create matrices, polynomials, vectors, etc., over the continued fraction +field:: sage: a = random_matrix(CFF, 4) sage: a - [ [-1, 2] [-1, 1, 94] [0, 2] [-12]] - [ [-1] [0, 2] [-1, 1, 3] [0, 1, 2]] - [ [-3, 2] [0] [0, 1, 2] [-1]] - [ [1] [-1] [0, 3] [1]] + [ [-1; 2] [-1; 1, 94] [0; 2] [-12]] + [ [-1] [0; 2] [-1; 1, 3] [0; 1, 2]] + [ [-3; 2] [0] [0; 1, 2] [-1]] + [ [1] [-1] [0; 3] [1]] sage: f = a.charpoly() sage: f - [1]*x^4 + ([-2, 3])*x^3 + [14, 1, 1, 1, 9, 1, 8]*x^2 + ([-13, 4, 1, 2, 1, 1, 1, 1, 1, 2, 2])*x + [-6, 1, 5, 9, 1, 5] + [1]*x^4 + ([-2; 3])*x^3 + [14; 1, 1, 1, 9, 1, 8]*x^2 + ([-13; 4, 1, 2, 1, 1, 1, 1, 1, 2, 2])*x + [-6; 1, 5, 9, 1, 5] sage: f(a) [[0] [0] [0] [0]] [[0] [0] [0] [0]] [[0] [0] [0] [0]] [[0] [0] [0] [0]] sage: vector(CFF, [1/2, 2/3, 3/4, 4/5]) - ([0, 2], [0, 1, 2], [0, 1, 3], [0, 1, 4]) + ([0; 2], [0; 1, 2], [0; 1, 3], [0; 1, 4]) AUTHORS: -- Niles Johnson (2010-08): Trac #3893: ``random_element()`` should pass on ``*args`` and ``**kwds``. - +- Niles Johnson (2010-08): ``random_element()`` should pass on ``*args`` and + ``**kwds`` (:trac:`3893`). """ -from sage.structure.element import FieldElement -from sage.structure.parent_gens import ParentWithGens -from sage.libs.pari.all import pari -from field import Field -from rational_field import QQ -from integer_ring import ZZ -from infinity import infinity -from real_mpfr import is_RealNumber, RealField -from real_double import RDF -from arith import (continued_fraction_list, - convergent, convergents) +from sage.structure.unique_representation import UniqueRepresentation +from sage.rings.ring import Field +from sage.structure.element import FieldElement +from continued_fraction import ContinuedFraction_periodic, ZZ_0 -class ContinuedFractionField_class(Field): +class ContinuedFractionField(UniqueRepresentation,Field): """ - The field of all finite continued fraction of real numbers. + The field of rational implemented as continued fraction. + + The code here is deprecated since in all situations it is better to use + ``QQ``. + + .. SEEALSO:: + + :func:`continued_fraction` EXAMPLES:: sage: CFF - Field of all continued fractions + QQ as continued fractions + sage: CFF([0,1,3,2]) + [0; 1, 3, 2] + sage: CFF(133/25) + [5; 3, 8] + + sage: CFF.category() + Category of fields The continued fraction field inherits from the base class - :class:`sage.rings.ring.Field`. However it was initialised - as such only since trac ticket #11900:: + :class:`sage.rings.ring.Field`. However it was initialised as such only + since trac ticket :trac:`11900`:: sage: CFF.category() Category of fields - """ - def __init__(self): - """ - EXAMPLES:: - - sage: ContinuedFractionField() - Field of all continued fractions - - TESTS:: - - sage: CFF._repr_option('element_is_atomic') - False - """ - Field.__init__(self, self) - self._assign_names(('x'),normalize=False) + class Element(ContinuedFraction_periodic,FieldElement): + r""" + A continued fraction of a rational number. - def __cmp__(self, right): - """ EXAMPLES:: - sage: CFF == ContinuedFractionField() - True - sage: CFF == CDF - False - sage: loads(dumps(CFF)) == CFF - True + sage: CFF(1/3) + [0; 3] + sage: CFF([1,2,3]) + [1; 2, 3] """ - return cmp(type(self), type(right)) + def __init__(self, x1, x2=None): + r""" + INPUT: - def __iter__(self): - """ - EXAMPLES:: + - ``parent`` - the parent - sage: i = 0 - sage: for a in CFF: - ... print a - ... i += 1 - ... if i > 5: break - ... - [0] - [1] - [-1] - [0, 2] - [-1, 2] - [2] - """ - for n in QQ: - yield self(n) + - ``x`` - the quotients of the continued fraction + TESTS:: - def _latex_(self): - r""" - EXAMPLES:: + sage: TestSuite(CFF.an_element()).run() + """ + ContinuedFraction_periodic.__init__(self, x1) + FieldElement.__init__(self, parent=CFF) - sage: latex(CFF) - \Bold{CFF} - """ - return "\\Bold{CFF}" + def _add_(self, other): + r""" + Add two continued fractions. - def _is_valid_homomorphism_(self, codomain, im_gens): - """ - Return whether or not the map to codomain by sending the - continued fraction [1] of self to im_gens[0] is a - homomorphism. + EXAMPLES:: - EXAMPLES:: + sage: CFF(1/3) + CFF([0,1,2,3]) + [1; 30] + """ + return self.parent()(self.value() + other.value()) - sage: CFF._is_valid_homomorphism_(ZZ,[ZZ(1)]) - False - sage: CFF._is_valid_homomorphism_(CFF,[CFF(1)]) - True - """ - try: - return im_gens[0] == codomain._coerce_(self(1)) - except TypeError: - return False + def _mul_(self, other): + r""" + Multiply two continued fractions. - def _repr_(self): - """ - EXAMPLES:: + EXAMPLES:: - sage: CFF - Field of all continued fractions - """ - return "Field of all continued fractions" + sage: CFF(1/3) * CFF([0,1,2,3]) + [0; 4, 3, 2] + """ + return self.parent()(self.value() * other.value()) - def _coerce_impl(self, x): - """ - Anything that implicitly coerces to the rationals or a real - field, implicitly coerces to the continued fraction field. - - EXAMPLES: - - The additions below call _coerce_impl implicitly:: - - sage: a = CFF(3/5); a - [0, 1, 1, 2] - sage: a + 2/5 - [1] - sage: 2/5 + a - [1] - sage: 1.5 + a - [2, 10] - sage: a + 1.5 - [2, 10] - """ - if is_RealNumber(x): - return self(x) - return self._coerce_try(x, [QQ, RDF]) + def _div_(self, other): + r""" + Divides two continued fractions. - def __call__(self, x, bits=None, nterms=None): - """ - INPUT: + EXAMPLES:: - - `x` -- a number + sage: CFF(1/3) / CFF(4/5) + [0; 2, 2, 2] + """ + return self.parent()(self.value() / other.value()) - - ``bits`` -- integer (optional) the number of bits of the - input number to use when computing the continued fraction. + def __reduce__(self): + r""" + Pickling helper. - EXAMPLES:: + EXAMPLES:: - sage: CFF(1.5) - [1, 2] - sage: CFF(e) - [2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1] - sage: CFF(pi) - [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14] - sage: CFF([1,2,3]) - [1, 2, 3] - sage: CFF(15/17) - [0, 1, 7, 2] - sage: c2 = loads(dumps(CFF)) - sage: c2(CFF(15/17)).parent() is c2 - True + sage: x = CFF(1/3) + sage: loads(dumps(x)) == x + True + """ + return (self.parent(), (self.value(),)) - We illustrate varying the bits parameter:: - - sage: CFF(pi) - [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14] - sage: CFF(pi, bits=20) - [3, 7] - sage: CFF(pi, bits=80) - [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, 1] - sage: CFF(pi, bits=100) - [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, 1, 84, 2, 1, 1, 15, 3] - - And varying the nterms parameter:: - - sage: CFF(pi, nterms=3) - [3, 7, 15] - sage: CFF(pi, nterms=10) - [3, 7, 15, 1, 292, 1, 1, 1, 2, 1] - sage: CFF(pi, bits=10, nterms=10) - [3, 7, 15, 1, 292, 1, 1, 1, 2, 1] - """ - return ContinuedFraction(self, x, bits, nterms) + def __init__(self): + r""" + TESTS:: - def __len__(self): + sage: TestSuite(CFF(1/3)).run() + sage: TestSuite(CFF([1,2,3])).run() """ + Field.__init__(self, self) + + def _latex_(self): + r""" EXAMPLES:: - sage: len(CFF) - Traceback (most recent call last): - ... - TypeError: len() of unsized object + sage: latex(CFF) + \Bold{CFF} """ - raise TypeError('len() of unsized object') + return "\\Bold{CFF}" - def gens(self): + def _repr_(self): """ EXAMPLES:: - sage: CFF.gens() - ([1],) + sage: CFF + QQ as continued fractions """ - return (self(1), ) + return "QQ as continued fractions" + + def an_element(self): + r""" + Returns a continued fraction. - def gen(self, n=0): - """ EXAMPLES:: - sage: CFF.gen() - [1] - sage: CFF.0 - [1] + sage: CFF.an_element() + [-1; 2, 3] """ + return self([-1,2,3]) - if n == 0: - return self(1) - else: - raise IndexError("n must be 0") + def some_elements(self): + r""" + Return some continued fractions. - def degree(self): - """ EXAMPLES:: - sage: CFF.degree() - 1 + sage: CFF.some_elements() + ([0], [1], [1], [-1; 2], [3; 1, 2, 3]) """ - return 1 + return (self([0]), self([1]), self([0,1]), self([-1,2]), self([3,1,2,3])) - def ngens(self): + def is_field(self, proof=True): """ + Return True. + EXAMPLES:: - sage: CFF.ngens() - 1 + sage: CFF.is_field() + True """ - return 1 + return True - def is_field(self, proof = True): - """ - Return True, since the continued fraction field is a field. + def is_exact(self): + r""" + Return True. EXAMPLES:: - sage: CFF.is_field() + sage: CFF.is_exact() True """ return True @@ -331,7 +235,7 @@ def characteristic(self): sage: parent(c) Integer Ring """ - return ZZ(0) + return ZZ_0 def order(self): """ @@ -340,706 +244,74 @@ def order(self): sage: CFF.order() +Infinity """ - return infinity + from sage.rings.infinity import Infinity + return Infinity def random_element(self, *args, **kwds): """ - EXAMPLES:: - - sage: CFF.random_element(10,10) - [0, 4] - - Passes extra positional or keyword arguments through:: - - sage: [CFF.random_element(den_bound=10, num_bound=2) for x in range(4)] - [[-1, 1, 3], [0, 7], [0, 3], [0, 4]] - - - - """ - return self(QQ.random_element(*args, **kwds)) - - -class ContinuedFraction(FieldElement): - """ - A continued fraction object. - - EXAMPLES:: - - sage: continued_fraction(pi) - [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14] - sage: CFF(pi) - [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14] - """ - def __init__(self, parent, x, bits=None, nterms=None): - """ - EXAMPLES:: - - sage: sage.rings.contfrac.ContinuedFraction(CFF,[1,2,3,4,1,2]) - [1, 2, 3, 4, 1, 2] - sage: sage.rings.contfrac.ContinuedFraction(CFF,[1,2,3,4,-1,2]) - Traceback (most recent call last): - ... - ValueError: each entry except the first must be positive - """ - FieldElement.__init__(self, parent) - if isinstance(x, ContinuedFraction): - self._x = list(x._x) - elif isinstance(x, (list, tuple)): - x = [ZZ(a) for a in x] - for i in range(1,len(x)): - if x[i] <= 0: - raise ValueError("each entry except the first must be positive") - self._x = list(x) - else: - self._x = [ZZ(a) for a in continued_fraction_list(x, bits=bits, nterms=nterms)] - - def __getitem__(self, n): - """ - Returns `n`-th term of the continued fraction. - - OUTPUT: - - an integer or a a continued fraction - - EXAMPLES:: - - sage: a = continued_fraction(pi); a - [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14] - sage: a[4] - 292 - sage: a[-1] - 14 - sage: a[2:5] - [15, 1, 292] - sage: a[:3] - [3, 7, 15] - sage: a[4:] - [292, 1, 1, 1, 2, 1, 3, 1, 14] - sage: a[4::2] - [292, 1, 2, 3, 14] - """ - if isinstance(n, slice): - start, stop, step = n.indices(len(self)) - return ContinuedFraction(self.parent(), self._x[start:stop:step]) - else: - return self._x[n] - - def _repr_(self): - """ - EXAMPLES:: - - sage: a = continued_fraction(pi); a - [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14] - sage: a.rename('continued fraction of pi') - sage: a - continued fraction of pi - """ - return str(self._x) - - def convergents(self): - """ - Return a list of rational numbers, which are the partial - convergents of this continued fraction. - - OUTPUT: - - - list of rational numbers - - EXAMPLES:: - - sage: a = CFF(pi, bits=34); a - [3, 7, 15, 1, 292] - sage: a.convergents() - [3, 22/7, 333/106, 355/113, 103993/33102] - sage: a.value() - 103993/33102 - sage: a[:-1].value() - 355/113 - """ - return convergents(self._x) - - def convergent(self, n): - """ - Return the `n`-th partial convergent to self. - - OUTPUT: - - rational number - - EXAMPLES:: - - sage: a = CFF(pi, bits=34); a - [3, 7, 15, 1, 292] - sage: a.convergents() - [3, 22/7, 333/106, 355/113, 103993/33102] - sage: a.convergent(0) - 3 - sage: a.convergent(1) - 22/7 - sage: a.convergent(4) - 103993/33102 - """ - return convergent(self._x, n) - - def __len__(self): - """ - Return the number of terms in this continued fraction. - - EXAMPLES:: - - sage: len(continued_fraction([1,2,3,4,5]) ) - 5 - """ - return len(self._x) - - def pn(self, n): - """ - Return the numerator of the `n`-th partial convergent, computed - using the recurrence. - - EXAMPLES:: - - sage: c = continued_fraction(pi); c - [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14] - sage: c.pn(0), c.qn(0) - (3, 1) - sage: len(c) - 13 - sage: c.pn(12), c.qn(12) - (80143857, 25510582) - """ - if n < -2: - raise ValueError("n must be at least -2") - if n > len(self._x): - raise ValueError("n must be at most %s"%len(self._x)) - try: - return self.__pn[n+2] - except AttributeError: - self.__pn = [0, 1, self._x[0]] - self.__qn = [1, 0, 1] - except IndexError: - pass - for k in range(len(self.__pn), n+3): - self.__pn.append(self._x[k-2]*self.__pn[k-1] + self.__pn[k-2]) - self.__qn.append(self._x[k-2]*self.__qn[k-1] + self.__qn[k-2]) - return self.__pn[n+2] - - def qn(self, n): - """ - Return the denominator of the `n`-th partial convergent, computed - using the recurrence. - - EXAMPLES:: - - sage: c = continued_fraction(pi); c - [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14] - sage: c.qn(0), c.pn(0) - (1, 3) - sage: len(c) - 13 - sage: c.pn(12), c.qn(12) - (80143857, 25510582) - """ - if n < -2: - raise ValueError("n must be at least -2") - if n > len(self._x): - raise ValueError("n must be at most %s"%len(self._x)) - try: - return self.__qn[n+2] - except (AttributeError, IndexError): - pass - self.pn(n) - return self.__qn[n+2] - - def _rational_(self): - """ - EXAMPLES:: - - sage: a = CFF(-17/389); a - [-1, 1, 21, 1, 7, 2] - sage: a._rational_() - -17/389 - sage: QQ(a) - -17/389 - """ - try: - return self.__rational - except AttributeError: - r = convergents(self._x)[-1] - self.__rational =r - return r - - def value(self): - """ - EXAMPLES:: - - sage: a = CFF(-17/389); a - [-1, 1, 21, 1, 7, 2] - sage: a.value() - -17/389 - sage: QQ(a) - -17/389 - """ - return self._rational_() - - def numerator(self): - """ - EXAMPLES:: - - sage: a = CFF(-17/389); a - [-1, 1, 21, 1, 7, 2] - sage: a.numerator() - -17 - """ - return self._rational_().numerator() - - def denominator(self): - """ - EXAMPLES:: - - sage: a = CFF(-17/389); a - [-1, 1, 21, 1, 7, 2] - sage: a.denominator() - 389 - """ - return self._rational_().denominator() - - def __int__(self): - """ - EXAMPLES:: - - sage: a = CFF(-17/389); a - [-1, 1, 21, 1, 7, 2] - sage: int(a) - -1 - """ - return int(self._rational_()) - - def __long__(self): - """ - EXAMPLES:: - - sage: a = CFF(-17/389); a - [-1, 1, 21, 1, 7, 2] - sage: long(a) - -1L - """ - return long(self._rational_()) - - def __float__(self): - """ - EXAMPLES:: - - sage: a = CFF(-17/389); a - [-1, 1, 21, 1, 7, 2] - sage: float(a) - -0.043701799485861184 - """ - return float(self._rational_()) - - def _add_(self, right): - """ - EXAMPLES:: - - sage: a = CFF(-17/389) - sage: b = CFF(1/389) - sage: c = a+b; c - [-1, 1, 23, 3, 5] - sage: c.value() - -16/389 - """ - return ContinuedFraction(self.parent(), - self._rational_() + right._rational_()) - - def _sub_(self, right): - """ - EXAMPLES:: - - sage: a = CFF(-17/389) - sage: b = CFF(1/389) - sage: c = a - b; c - [-1, 1, 20, 1, 1, 1, 1, 3] - sage: c.value() - -18/389 - """ - return ContinuedFraction(self.parent(), - self._rational_() - right._rational_()) - - def _mul_(self, right): - """ - EXAMPLES:: - - sage: a = CFF(-17/389) - sage: b = CFF(1/389) - sage: c = a * b; c - [-1, 1, 8900, 4, 4] - sage: c.value(), (-1/389)*(17/389) - (-17/151321, -17/151321) - """ - return ContinuedFraction(self.parent(), - self._rational_() * right._rational_()) - - def _div_(self, right): - """ - EXAMPLES:: - - sage: a = CFF(-17/389) - sage: b = CFF(1/389) - sage: c = a / b; c - [-17] - sage: c.value(), (17/389) / (-1/389) - (-17, -17) - """ - return ContinuedFraction(self.parent(), - self._rational_() / right._rational_()) - - def __cmp__(self, right): - """ - EXAMPLES:: - - sage: a = CFF(-17/389) - sage: b = CFF(1/389) - sage: a < b - True - sage: QQ(a) < QQ(b) - True - sage: QQ(a) - -17/389 - sage: QQ(b) - 1/389 - """ - return cmp(self._rational_(), right._rational_()) - - def _latex_(self): - """ - EXAMPLES:: - - sage: a = CFF(-17/389) - sage: latex(a) - -1+ \frac{\displaystyle 1}{\displaystyle 1+ \frac{\displaystyle 1}{\displaystyle 21+ \frac{\displaystyle 1}{\displaystyle 1+ \frac{\displaystyle 1}{\displaystyle 7+ \frac{\displaystyle 1}{\displaystyle 2}}}}} - """ - v = self._x - if len(v) == 0: - return '0' - s = str(v[0]) - for i in range(1,len(v)): - s += '+ \\frac{\\displaystyle 1}{\\displaystyle %s'%v[i] - s += '}'*(len(v)-1) - return s - - def sqrt(self, prec=53, all=False): - """ - Return continued fraction approximation to square root of the - value of this continued fraction. + Return a somewhat random continued fraction (the result is either + finite or ultimately periodic). INPUT: - - `prec` -- integer (default: 53) precision of square root - that is approximated - - - `all` -- bool (default: False); if True, return all square - roots of self, instead of just one. - - EXAMPLES:: - - sage: a = CFF(4/19); a - [0, 4, 1, 3] - sage: b = a.sqrt(); b - [0, 2, 5, 1, 1, 2, 1, 16, 1, 2, 1, 1, 5, 4, 5, 1, 1, 2, 1] - sage: b.value() - 4508361/9825745 - sage: float(b.value()^2 - a) - -5.451492525672688e-16 - sage: b = a.sqrt(prec=100); b - [0, 2, 5, 1, 1, 2, 1, 16, 1, 2, 1, 1, 5, 4, 5, 1, 1, 2, 1, 16, 1, 2, 1, 1, 5, 4, 5, 1, 1, 2, 1, 16, 1, 2, 1, 1, 5] - sage: b^2 - [0, 4, 1, 3, 7849253184229368265220252099, 1, 3] - sage: a.sqrt(all=True) - [[0, 2, 5, 1, 1, 2, 1, 16, 1, 2, 1, 1, 5, 4, 5, 1, 1, 2, 1], - [-1, 1, 1, 5, 1, 1, 2, 1, 16, 1, 2, 1, 1, 5, 4, 5, 1, 1, 2, 1]] - sage: a = CFF(4/25).sqrt(); a - [0, 2, 2] - sage: a.value() - 2/5 - """ - r = self._rational_() - if r < 0: - raise ValueError("self must be positive") - X = r.sqrt(all=all, prec=prec) - if not all: - return ContinuedFraction(self.parent(), X) - else: - return [ContinuedFraction(self.parent(), x) for x in X] - - def list(self): - """ - Return copy of the underlying list of this continued fraction. - - EXAMPLES:: - - sage: a = CFF(e); v = a.list(); v - [2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1] - sage: v[0] = 5 - sage: a - [2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1] - """ - return list(self._x) - - def __hash__(self): - """ - Return hash of self, which is the same as the hash of the value - of self, as a rational number. - - EXAMPLES:: - - sage: a = CFF(e) - sage: hash(a) - 19952398 - sage: hash(QQ(a)) - 19952398 - """ - return hash(self._rational_()) - - def __invert__(self): - """ - Return the multiplicative inverse of self. + - ``args``, ``kwds`` - arguments passed to ``QQ.random_element`` EXAMPLES:: - sage: a = CFF(e) - sage: b = ~a; b - [0, 2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 2] - sage: b*a - [1] + sage: CFF.random_element() # random + [0; 4, 7] """ - return ContinuedFraction(self.parent(), - self._rational_().__invert__()) + from sage.rings.rational_field import QQ + return self(QQ.random_element()) - def __pow__(self, n): - """ - Return self to the power of `n`. - - EXAMPLES:: - - sage: a = CFF([1,2,3]); a - [1, 2, 3] - sage: a^3 - [2, 1, 10, 1, 4, 1, 4] - sage: QQ(a)^3 == QQ(a^3) - True - sage: a^(-3) - [0, 2, 1, 10, 1, 4, 1, 4] - sage: QQ(a)^(-3) == QQ(a^(-3)) - True - """ - return ContinuedFraction(self.parent(), - self._rational_()**n) - - def __neg__(self): - """ - Return additive inverse of self. - - EXAMPLES:: - - sage: a = CFF(-17/389); a - [-1, 1, 21, 1, 7, 2] - sage: -a - [0, 22, 1, 7, 2] - sage: QQ(-a) - 17/389 - """ - return ContinuedFraction(self.parent(), - self._rational_().__neg__()) - - def __abs__(self): - """ - Return absolute value of self. + def _element_constructor_(self, data, *extra_args): + r""" + Build an element of that field. - EXAMPLES:: + TESTS:: - sage: a = CFF(-17/389); a - [-1, 1, 21, 1, 7, 2] - sage: abs(a) - [0, 22, 1, 7, 2] - sage: QQ(abs(a)) - 17/389 - """ - return ContinuedFraction(self.parent(), - self._rational_().__abs__()) + sage: CFF(1/3) + [0; 3] + sage: CFF([1,3,2]) + [1; 3, 2] + sage: CFF(CFF(1/3)) + [0; 3] + """ + if isinstance(data, FieldElement) and data.parent() is self: + data = list(data) + if extra_args: + print "data",data,type(data) + print "extra_args",extra_args, type(extra_args[0]) + data = list(extra_args[0]) + if not isinstance(data, (tuple,list)): + from sage.rings.rational_field import QQ + data = QQ(data).continued_fraction_list() + else: + from continued_fraction import check_and_reduce_pair + data,_ = check_and_reduce_pair(data, []) + return self.element_class(data) - def is_one(self): - """ - Return True if self is one. + def _coerce_map_from_(self, R): + r""" + Return True for ZZ and QQ. EXAMPLES:: - sage: continued_fraction(1).is_one() + sage: CFF.has_coerce_map_from(ZZ) # indirect doctest True - sage: continued_fraction(2).is_one() - False - """ - return self._rational_().is_one() - - def __nonzero__(self): - """ - Return False if self is zero. - - EXAMPLES:: - - sage: continued_fraction(0).is_zero() + sage: CFF.has_coerce_map_from(QQ) True - sage: continued_fraction(1).is_zero() + sage: CFF.has_coerce_map_from(RR) False """ - return not self._rational_().is_zero() - - def _pari_(self): - """ - Return PARI list corresponding to this continued fraction. - - EXAMPLES:: - - sage: c = continued_fraction(0.12345); c - [0, 8, 9, 1, 21, 1, 1] - sage: pari(c) - [0, 8, 9, 1, 21, 1, 1] - """ - return pari(self._x) - - def _interface_init_(self, I=None): - """ - Return list representation for other systems corresponding to - this continued fraction. - - EXAMPLES:: - - sage: c = continued_fraction(0.12345); c - [0, 8, 9, 1, 21, 1, 1] - sage: gp(c) - [0, 8, 9, 1, 21, 1, 1] - sage: gap(c) - [ 0, 8, 9, 1, 21, 1, 1 ] - sage: maxima(c) - [0,8,9,1,21,1,1] - """ - return str(self._x) - - def additive_order(self): - """ - Return the additive order of this continued fraction, - which we defined to be the additive order of its value. - - EXAMPLES:: - - sage: CFF(-1).additive_order() - +Infinity - sage: CFF(0).additive_order() - 1 - """ - return self.value().additive_order() - - def multiplicative_order(self): - """ - Return the multiplicative order of this continued fraction, - which we defined to be the multiplicative order of its value. - - EXAMPLES:: - - sage: CFF(-1).multiplicative_order() - 2 - sage: CFF(1).multiplicative_order() - 1 - sage: CFF(pi).multiplicative_order() - +Infinity - """ - return self.value().multiplicative_order() - - -CFF = ContinuedFractionField_class() - -def ContinuedFractionField(): - """ - Return the (unique) field of all continued fractions. - - EXAMPLES:: - - sage: ContinuedFractionField() - Field of all continued fractions - """ - return CFF - -def continued_fraction(x, bits=None, nterms=None): - """ - Return the truncated continued fraction expansion of the real number - `x`, computed with an interval floating point approximation of `x` - to the given number of bits of precision. The returned continued - fraction is a list-like object, with a value method and partial - convergents method. - - If bits is not given, then use the number of valid bits of - precision of `x`, if `x` is a floating point number, or 53 bits - otherwise. If nterms is given, the precision is increased until - the specified number of terms can be computed, if possible. - - INPUT: - - - `x` -- number - - - ``bits`` -- None (default) or a positive integer - - - ``nterms`` -- None (default) or a positive integer - - OUTPUT: - - - a continued fraction - - EXAMPLES:: - - sage: v = continued_fraction(sqrt(2)); v - [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] - sage: v = continued_fraction(sqrt(2), nterms=22); v - [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] - sage: type(v) - - sage: parent(v) - Field of all continued fractions - sage: v.value() - 131836323/93222358 - sage: RR(v.value()) == RR(sqrt(2)) - True - sage: v.convergents() - [1, 3/2, 7/5, 17/12, 41/29, 99/70, 239/169,...131836323/93222358] - sage: [RR(x) for x in v.convergents()] - [1.00000000000000, 1.50000000000000, 1.40000000000000, 1.41666666666667, ...1.41421356237310] - sage: continued_fraction(sqrt(2), 10) - [1, 2, 2] - sage: v.numerator() - 131836323 - sage: v.denominator() - 93222358 - sage: [v.pn(i) for i in range(10)] - [1, 3, 7, 17, 41, 99, 239, 577, 1393, 3363] - sage: [v.qn(i) for i in range(10)] - [1, 2, 5, 12, 29, 70, 169, 408, 985, 2378] - - Here are some more examples:: - - sage: continued_fraction(e, bits=20) - [2, 1, 2, 1, 1, 4, 1, 1] - sage: continued_fraction(e, bits=30) - [2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8] - sage: continued_fraction(RealField(200)(e)) - [2, 1, 2, 1, 1, 4, 1, 1, 6, ...36, 1, 1, 38, 1, 1] - - Initial rounding can result in incorrect trailing digits:: - - sage: continued_fraction(RealField(39)(e)) - [2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 2] - sage: continued_fraction(RealIntervalField(39)(e)) - [2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10] - """ - return CFF(x, bits=bits, nterms=nterms) - + from sage.rings.integer_ring import ZZ + from sage.rings.rational_field import QQ + return R is ZZ or R is QQ +CFF = ContinuedFractionField() +# Unpickling support is needed as the class ContinuedFractionField_class has +# been renamed into ContinuedFractionField in the ticket 14567 +from sage.structure.sage_object import register_unpickle_override +register_unpickle_override('sage.rings.contfrac', 'ContinuedFractionField_class',ContinuedFractionField) diff --git a/src/sage/rings/continued_fraction.py b/src/sage/rings/continued_fraction.py new file mode 100644 index 00000000000..7fd67d5513a --- /dev/null +++ b/src/sage/rings/continued_fraction.py @@ -0,0 +1,2379 @@ +r""" +Continued fractions + +A continued fraction is a representation of a real number in terms of a sequence +of integers denoted `[a_0; a_1, a_2, \ldots]`. The well known decimal expansion +is another way of representing a real number by a sequence of integers. The +value of a continued fraction is defined recursively as: + +.. MATH:: + + [a_0; a_1, a_2, \ldots] = a_0 + \frac{1}{[a_1; a_2, \ldots]} = a_0 + + \frac{\displaystyle 1} + {\displaystyle a_1 + \frac{\displaystyle 1} + {\displaystyle a_2 + \frac{\displaystyle 1} + {\ldots}}} + +In this expansion, all coefficients `a_n` are integers and only the value `a_0` +may be non positive. Note that `a_0` is nothing else but the floor (this remark +provides a way to build the continued fraction expansion from a given real +number). As examples + +.. MATH:: + + \frac{45}{38} = 1 + \frac{\displaystyle 1} + {\displaystyle 5 + \frac{\displaystyle 1} + {\displaystyle 2 + \frac{\displaystyle 1} + {\displaystyle 3}}} + +.. MATH:: + + \pi = 3 + \frac{\displaystyle 1} + {\displaystyle 7 + \frac{\displaystyle 1} + {\displaystyle 15 + \frac{\displaystyle 1} + {\displaystyle 1 + \frac{\displaystyle 1} + {\displaystyle 292 + \frac{\displaystyle 1} + {\ldots}}}}} + +It is quite remarkable that + +- any real number admits a unique continued fraction expansion +- finite expansions correspond to rationals +- ultimately periodic expansions correspond to quadratic numbers (ie numbers of + the form `a + b \sqrt{D}` with `a` and `b` rationals and `D` square free + positive integer) +- two real numbers `x` and `y` have the same tail (up to a shift) in their + continued fraction expansion if and only if there are integers `a,b,c,d` with + `|ad - bc| = 1` and such that `y = (ax + b) / (cx + d)`. + +Moreover, the rational numbers obtained by truncation of the expansion of a real +number gives its so-called best approximations. For more informations on +continued fractions, you may have a look at :wikipedia:`Continued_fraction`. + +EXAMPLES: + +If you want to create the continued fraction of some real number you may either +use its method continued_fraction (if it exists) or call +:func:`continued_fraction`:: + + sage: (13/27).continued_fraction() + [0; 2, 13] + sage: 0 + 1/(2 + 1/13) + 13/27 + + sage: continued_fraction(22/45) + [0; 2, 22] + sage: 0 + 1/(2 + 1/22) + 22/45 + + sage: continued_fraction(pi) + [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, ...] + + sage: K. = NumberField(x^3 - 5, embedding=1.709) + sage: continued_fraction(cbrt5) + [1; 1, 2, 2, 4, 3, 3, 1, 5, 1, 1, 4, 10, 17, 1, 14, 1, 1, 3052, 1, ...] + +It is also possible to create a continued fraction from a list of partial +quotients:: + + sage: continued_fraction([-3,1,2,3,4,1,2]) + [-3; 1, 2, 3, 4, 1, 2] + +Even infinite:: + + sage: w = words.ThueMorseWord([1,2]) + sage: w + word: 1221211221121221211212211221211221121221... + sage: continued_fraction(w) + [1; 2, 2, 1, 2, 1, 1, 2, 2, 1...] + +To go back and forth between the value (as a real number) and the partial +quotients (seen as a finite or infinite list) you can use the methods +``quotients`` and ``value``:: + + sage: cf = (13/27).continued_fraction() + sage: cf.quotients() + [0, 2, 13] + sage: cf.value() + 13/27 + + sage: cf = continued_fraction(pi) + sage: cf.quotients() + lazy list [3, 7, 15, ...] + sage: cf.value() + pi + +The method ``value`` is currently not supported for continued fractions built +from an infinite sequence:: + + sage: w = words.FibonacciWord([1,2]) + sage: cf = continued_fraction(w) + sage: cf.quotients() + word: 1211212112112121121211211212112112121121... + sage: cf.value() + Traceback (most recent call last): + ... + NotImplementedError: Real numbers built from continued fractions are not yet implemented + +Recall that quadratic numbers correspond to ultimately periodic continued +fractions. For them special methods give access to preperiod and period:: + + sage: K. = QuadraticField(2) + sage: cf = continued_fraction(sqrt2); cf + [1; (2)*] + sage: cf.value() + sqrt2 + sage: cf.preperiod() + (1,) + sage: cf.period() + (2,) + + sage: cf = (3*sqrt2 + 1/2).continued_fraction(); cf + [4; (1, 2, 1, 7)*] + + sage: cf = continued_fraction([(1,2,3),(1,4)]); cf + [1; 2, 3, (1, 4)*] + sage: cf.value() + -2/23*sqrt2 + 36/23 + +On the following we can remark how the tail may change even in the same +quadratic field:: + + sage: for i in xrange(20): print continued_fraction(i*sqrt2) + [0] + [1; (2)*] + [2; (1, 4)*] + [4; (4, 8)*] + [5; (1, 1, 1, 10)*] + [7; (14)*] + ... + [24; (24, 48)*] + [25; (2, 5, 6, 5, 2, 50)*] + [26; (1, 6, 1, 2, 3, 2, 26, 2, 3, 2, 1, 6, 1, 52)*] + +Nevertheless, the tail is preserved under invertible integer homographies:: + + sage: apply_homography = lambda m,z: (m[0,0]*z + m[0,1]) / (m[1,0]*z + m[1,1]) + sage: m1 = SL2Z([60,13,83,18]) + sage: m2 = SL2Z([27,80,28,83]) + sage: a = sqrt2/3 + sage: a.continued_fraction() + [0; 2, (8, 4)*] + sage: b = apply_homography(m1, a) + sage: b.continued_fraction() + [0; 1, 2, 1, 1, 1, 1, 6, (8, 4)*] + sage: c = apply_homography(m2, a) + sage: c.continued_fraction() + [0; 1, 26, 1, 2, 2, (8, 4)*] + sage: d = apply_homography(m1**2*m2**3, a) + sage: d.continued_fraction() + [0; 1, 2, 1, 1, 1, 1, 5, 2, 1, 1, 1, 1, 5, 26, 1, 2, 1, 26, 1, 2, 1, 26, 1, 2, 2, (8, 4)*] + +.. TODO:: + + - Interactions with integer/rational and reals. + + - Gosper's algorithm to compute the continued fraction of (ax + b)/(cx + d) + knowing the one of x (see Gosper (1972, + http://www.inwap.com/pdp10/hbaker/hakmem/cf.html), Knuth (1998, TAOCP vol + 2, Exercise 4.5.3.15), Fowler (1999). See also Liardet, P. and Stambul, P. + "Algebraic Computation with Continued Fractions." J. Number Th. 73, + 92-121, 1998. + + - Improve numerical approximation (the method + :meth:`~ContinuedFraction_base._mpfr_` is quite slow compared to the + same method for an element of a number field) + + - Make a class for generalized continued fractions of the form `a_0 + + b_0/(a_1 + b_1/(...))` (the standard continued fractions are when all + `b_n= 1` while the Hirzebruch-Jung continued fractions are the one for + which `b_n = -1` for all `n`). See + :wikipedia:`Generalized_continued_fraction`. + + - look at the function ContinuedFractionApproximationOfRoot in GAP + +AUTHORS: + +- Vincent Delecroix (2014): cleaning, refactorisation, documentation from the + old implementation in ``contfrac`` (:trac:`14567`). +""" +from sage.structure.sage_object import SageObject +from integer import Integer +from infinity import Infinity + +ZZ_0 = Integer(0) +ZZ_1 = Integer(1) +ZZ_m1 = Integer(-1) +ZZ_2 = Integer(2) + +def last_two_convergents(x): + """ + Given the list ``x`` that consists of numbers, return the two last + convergents `p_{n-1}, q_{n-1}, p_n, q_n`. + + This function is principally used to compute the value of a ultimately + periodic continued fraction. + + EXAMPLES:: + + sage: from sage.rings.continued_fraction import last_two_convergents + sage: last_two_convergents([]) + (0, 1, 1, 0) + sage: last_two_convergents([0]) + (1, 0, 0, 1) + sage: last_two_convergents([-1,1,3,2]) + (-1, 4, -2, 9) + """ + p0, p1 = 0, 1 + q0, q1 = 1, 0 + for a in x: + p0, p1 = p1, a*p1+p0 + q0, q1 = q1, a*q1+q0 + return p0, q0, p1, q1 + +def rat_interval_cf_list(r1, r2): + r""" + Return the common prefix of r1 and r2 seen as continued fractions. + + EXAMPLES:: + + sage: from sage.rings.continued_fraction import rat_interval_cf_list + sage: for prec in xrange(10,54): + ....: R = RealIntervalField(20) + ....: for _ in xrange(100): + ....: x = R.random_element() * R.random_element() + R.random_element() / 100 + ....: l = x.lower().exact_rational() + ....: u = x.upper().exact_rational() + ....: cf = rat_interval_cf_list(l,u) + ....: a = continued_fraction(cf).value() + ....: b = continued_fraction(cf+[1]).value() + ....: if a > b: + ....: a,b = b,a + ....: assert a <= l + ....: assert b >= u + """ + l = [] + c1 = r1.floor() + c2 = r2.floor() + while c1 == c2: + l.append(c1) + r1 -= c1 + if r1 == 0: + break + r2 -= c2 + if r2 == 0: + break + + r1 = ~r1 + r2 = ~r2 + + c1 = r1.floor() + c2 = r2.floor() + return l + + +class ContinuedFraction_base(SageObject): + r""" + Base class for (standard) continued fractions. + + If you want to implement your own continued fraction, simply derived from + this class and implement the following methods: + + - ``def quotient(self, n)``: return the ``n``-th quotient of ``self`` as a + Sage integer + + - ``def length(self)``: the number of partial quotients of ``self`` as a + Sage integer or ``Infinity``. + + and optionally: + + - ``def value(self)``: return the value of ``self`` (an exact real number) + + This base class will provide: + + - computation of convergents in :meth:`convergent`, :meth:`numerator` and + :meth:`denominator` + + - comparison with other continued fractions (see :meth:`__cmp__`) + + - elementary arithmetic function :meth:`floor`, :meth:`ceil`, :meth:`sign` + + - accurate numerical approximations :meth:`_mpfr_` + + All other methods, in particular the ones involving binary operations like + sum or product, rely on the optional method :meth:`value` (and not on + convergents) and may fail at execution if it is not implemented. + """ + def __init__(self): + r""" + INPUT: + + - ``parent`` -- the parent of ``self`` + + TESTS:: + + sage: TestSuite(continued_fraction(3)).run() + """ + self._pn = [ZZ_0, ZZ_1] + self._qn = [ZZ_1, ZZ_0] + + def __abs__(self): + """ + Return absolute value of self. + + EXAMPLES:: + + sage: a = continued_fraction(-17/389); a + [-1; 1, 21, 1, 7, 2] + sage: abs(a) + [0; 22, 1, 7, 2] + sage: QQ(abs(a)) + 17/389 + """ + if self.quotient(0) >= 0: + return self + return self.__neg__() + + def __cmp__(self, other): + """ + EXAMPLES:: + + sage: a = continued_fraction(-17/389) + sage: b = continued_fraction(1/389) + sage: c = continued_fraction([(),(1,)]) # the golden ratio + sage: d = continued_fraction([(-1,),(1,)]) + sage: d < a and a < b and b < c + True + sage: d >= a + False + sage: d == d + True + """ + i = 0 + + while True: + a = self.quotient(i) + b = other.quotient(i) + test = cmp(a,b) + if test == 1: # a > b + return -1 if i % 2 else 1 + if test == -1: # b > a + return 1 if i % 2 else -1 + if a == ZZ_0 and b == ZZ_0 and i: # rational case + return 0 + i += 1 + + def _mpfr_(self, R): + r""" + Return a numerical approximation of ``self`` in the real mpfr ring ``R``. + + The output result is accurate: when the rounding mode of + ``R`` is 'RNDN' then the result is the nearest binary number of ``R`` to + ``self``. The other rounding mode are 'RNDD' (toward +infinity), 'RNDU' + (toward -infinity) and 'RNDZ' (toward zero). + + EXAMPLES:: + + sage: continued_fraction(1/2).n() + 0.500000000000000 + sage: continued_fraction([0,4]).n() + 0.250000000000000 + sage: continued_fraction([12,1,3,4,2,2,3,1,2]).n(digits=4) + 12.76 + + sage: continued_fraction(12/7).n(digits=13) == (12/7).n(digits=13) + True + sage: continued_fraction(-14/333).n(digits=21) == (-14/333).n(digits=21) + True + + sage: a = (106*pi - 333) / (355 - 113*pi) - 292 + sage: cf = continued_fraction(a); cf + [0; 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, 1, 84, 2, 1, ...] + sage: cf.n(digits=3) + 0.635 + sage: cf.n(digits=4) + 0.6346 + sage: cf.n(digits=5) + 0.63459 + sage: cf.n(digits=6) + 0.634591 + sage: cf.n(digits=7) + 0.6345910 + sage: cf.n(digits=8) + 0.63459101 + + sage: K. = NumberField(x^3-2, 'a', embedding=1.25) + sage: b = 504/253*a^2 + 635/253*a + 661/253 + sage: cf = continued_fraction(b); cf + [8; 1, 14, 1, 10, 2, 1, 4, 12, 2, 3, 2, 1, 3, 4, 1, 1, 2, 14, 3, ...] + sage: cf.n(digits=3) + 8.94 + sage: cf.n(digits=6) + 8.93715 + sage: cf.n(digits=7) + 8.937154 + sage: cf.n(digits=8) + 8.9371541 + sage: cf.n(digits=9) + 8.93715414 + sage: cf.n(digits=10) + 8.937154138 + sage: cf.n(digits=11) + 8.9371541378 + + TESTS:: + + We check that the rounding works as expected, at least in the rational + case:: + + sage: for _ in xrange(100): + ....: a = QQ.random_element(num_bound=1<<64) + ....: cf = continued_fraction(a) + ....: for prec in 17,24,53,128,256: + ....: for rnd in 'RNDN','RNDD','RNDU','RNDZ': + ....: R = RealField(prec=prec, rnd=rnd) + ....: assert R(cf) == R(a) + """ + # 1. integer case + if self.quotient(1) is Infinity: + return R(self.quotient(0)) + + # 2. negative numbers + # TODO: it is possible to deal with negative values. The only problem is + # that we need to find the good value for N (which involves + # self.quotient(k) for k=0,1,2) + if self.quotient(0) < 0: + rnd = R.rounding_mode() + if rnd == 'RNDN' or rnd == 'RNDZ': + return -R(-self) + elif rnd == 'RNDD': + r = R(-self) + s,m,e = r.sign_mantissa_exponent() + if e < 0: + return -(R(m+1) >> (-e)) + return -(R(m+1) << e) + else: + r = R(-self) + s,m,e = r.sign_mantissa_exponent() + if e < 0: + return -(R(m-1) >> (-e)) + return -(R(m-1) << e) + + # 3. positive non integer + if self.quotient(0) == 0: # 0 <= self < 1 + N = R.prec() + self.quotient(1).nbits() - 1 + if self.quotient(2) is Infinity and self.quotient(1) % (1 << (self.quotient(1).nbits()-1)) == 0: + # if self is of the form [0; 2^N] then we need the following + N -= 1 + else: # self > 1 + N = R.prec() - self.quotient(0).nbits() + + # even/odd convergents are respectively below/above + k = 0 + p_even = self.numerator(2*k) + p_odd = self.numerator(2*k+1) + q_even = self.denominator(2*k) + q_odd = self.denominator(2*k+1) + m_even = (p_even << N) // q_even # floor((2^N p_even) / q_even) + m_odd = (p_odd << N + q_odd - 1) // q_odd # ceil((2^N p_odd) / q_odd) + while (m_odd - m_even) > 1: + k += 1 + p_even = self.numerator(2*k) + p_odd = self.numerator(2*k+1) + q_even = self.denominator(2*k) + q_odd = self.denominator(2*k+1) + m_even = (p_even << N) // q_even + m_odd = ((p_odd << N) + q_odd - 1) // q_odd + + assert m_odd.nbits() == R.prec() or m_even.nbits() == R.prec() + + if m_even == m_odd: # no need to worry (we have a decimal number) + return R(m_even) >> N + + # check ordering + # m_even/2^N <= p_even/q_even <= self <= p_odd/q_odd <= m_odd/2^N + assert m_odd == m_even + 1 + assert m_even / (ZZ_1 << N) <= p_even/q_even + assert p_even / q_even <= p_odd / q_odd + assert p_odd / q_odd <= m_odd / (ZZ_1 << N) + + rnd = R.rounding_mode() + if rnd == 'RNDN': # round to the nearest + # in order to find the nearest approximation we possibly need to + # augment our precision on convergents. + while True: + assert not(p_odd << (N+1) <= (2*m_odd-1) * q_odd) or not(p_even << (N+1) >= (2*m_even+1) * q_even) + if p_odd << (N+1) <= (2*m_odd-1) * q_odd: + return R(m_even) >> N + if p_even << (N+1) >= (2*m_even+1) * q_even: + return R(m_odd) >> N + k += 1 + p_even = self.numerator(2*k) + p_odd = self.numerator(2*k+1) + q_even = self.denominator(2*k) + q_odd = self.denominator(2*k+1) + elif rnd == 'RNDU': # round up (toward +infinity) + return R(m_odd) >> N + elif rnd == 'RNDD': # round down (toward -infinity) + return R(m_even) >> N + elif rnd == 'RNDZ': # round toward zero + if m_even.sign() == 1: + return R(m_even) >> N + else: + return R(m_odd) >> N + else: + raise ValueError("%s unknown rounding mode" % rnd) + + def __float__(self): + """ + EXAMPLES:: + + sage: a = continued_fraction(-17/389); a + [-1; 1, 21, 1, 7, 2] + sage: float(a) + -0.043701799485861184 + sage: float(-17/389) + -0.043701799485861184 + """ + from sage.rings.real_mpfr import RR + return float(self._mpfr_(RR)) + + def numerator(self, n): + """ + Return the numerator of the `n`-th partial convergent of ``self``. + + EXAMPLES:: + + sage: c = continued_fraction(pi); c + [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, ...] + sage: c.numerator(0) + 3 + sage: c.numerator(12) + 80143857 + sage: c.numerator(152) + 3943771611212266962743738812600748213157266596588744951727393497446921245353005283 + """ + n = Integer(n) + + p = self._pn + q = self._qn + + if n < -2: + raise ValueError("n must be at least -2") + + for k in xrange(len(p), n+3): + x = self.quotient(k-2) + if x is Infinity and k != 2: + return p[-1] + p.append(x*p[k-1] + p[k-2]) + q.append(x*q[k-1] + q[k-2]) + + return p[n+2] + + p = numerator + + def pn(self, n): + r""" + Return the numerator of the `n`-th partial convergent of ``self``. + + This method is deprecated since :trac:`14567` and :meth:`numerator` + should be used instead. + + EXAMPLES:: + + sage: continued_fraction([1,2,3,5,4]).pn(3) + doctest:...: DeprecationWarning: pn is deprecated. Use the methods p or numerator instead. + See http://trac.sagemath.org/14567 for details. + 53 + """ + from sage.misc.superseded import deprecation + deprecation(14567, 'pn is deprecated. Use the methods p or numerator instead.') + return self.numerator(n) + + def denominator(self, n): + """ + Return the denominator of the ``n``-th partial convergent of ``self``. + + EXAMPLES:: + + sage: c = continued_fraction(pi); c + [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, ...] + sage: c.denominator(0) + 1 + sage: c.denominator(12) + 25510582 + sage: c.denominator(152) + 1255341492699841451528811722575401081588363886480089431843026103930863337221076748 + """ + self.numerator(n) # ! silent computation of qn + if len(self._qn) < n+3: + return self._qn[-1] + return self._qn[n+2] + + q = denominator + + def qn(self, n): + r""" + Return the denominator of the ``n``-th partial convergent of ``self``. + + This method is deprecated since :trac:`14567`. Use :meth:`denominator` + instead. + + EXAMPLES:: + + sage: continued_fraction([1,2,3,12,1]).qn(3) + doctest:...: DeprecationWarning: qn is deprecated. Use the methods q or denominator instead. + See http://trac.sagemath.org/14567 for details. + 93 + """ + from sage.misc.superseded import deprecation + deprecation(14567, 'qn is deprecated. Use the methods q or denominator instead.') + return self.denominator(n) + + def convergent(self, n): + """ + Return the ``n``-th partial convergent to self. + + EXAMPLES:: + + sage: a = continued_fraction(pi); a + [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, ...] + sage: a.convergent(3) + 355/113 + sage: a.convergent(15) + 411557987/131002976 + """ + return self.numerator(n) / self.denominator(n) + + def convergents(self): + """ + Return the list of partial convergents of ``self``. + + If ``self`` is an infinite continued fraction, then the object returned + is a :class:`~sage.misc.lazy_list.lazy_list` which behave like an + infinite list. + + EXAMPLES:: + + sage: a = continued_fraction(23/157); a + [0; 6, 1, 4, 1, 3] + sage: a.convergents() + [0, 1/6, 1/7, 5/34, 6/41, 23/157] + + sage: #TODO: example with infinite list + """ + if self.length() == Infinity: + from sage.misc.lazy_list import lazy_list + from itertools import count + return lazy_list(self.numerator(n) / self.denominator(n) for n in count()) + return [self.numerator(n) / self.denominator(n) for n in xrange(len(self))] + + def quotients(self): + r""" + Return the list of partial quotients of ``self``. + + If ``self`` is an infinite continued fraction, the the object returned + is a :class:``~sage.misc.lazy_list.lazy_list`` which behave like an + infinite list. + + EXAMPLES:: + + sage: a = continued_fraction(23/157); a + [0; 6, 1, 4, 1, 3] + sage: a.quotients() + [0, 6, 1, 4, 1, 3] + + sage: #TODO: example with infinite list + """ + if self.length() == Infinity: + from sage.misc.lazy_list import lazy_list + from itertools import count + return lazy_list(self.quotient(n) for n in count()) + return [self.quotient(n) for n in xrange(len(self))] + + def __getitem__(self, n): + r""" + Return the ``n``-th partial quotient of ``self`` or a continued fraction + associated to a sublist of the partial quotients of ``self``. + + TESTS:: + + sage: cf1 = continued_fraction(pi); cf1 + [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, ...] + sage: cf2 = continued_fraction(QuadraticField(2).gen()); cf2 + [1; (2)*] + sage: cf3 = continued_fraction(4/17); cf3 + [0; 4, 4] + sage: cf1[3:17] + [1; 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2] + sage: cf2[:10] + [1; 2, 2, 2, 2, 2, 2, 2, 2, 2] + sage: cf3[1:16] + [4; 4] + + Be careful that the truncation of an infinite continued fraction might + be shorter by one:: + + sage: len(continued_fraction(golden_ratio)[:8]) + 7 + """ + if isinstance(n, slice): + quots = self.quotients().__getitem__(n) + if n.stop is not None: + quots = list(quots) + return continued_fraction(quots) + + try: + n = n.__index__() + except (AttributeError, ValueError): + raise ValueError("n (=%s) should be an integer" % n) + if n < 0: + raise ValueError("n (=%s) should be positive" % n) + q = self.quotient(n) + if q is Infinity: + raise IndexError("index out of range") + + return q + + def __iter__(self): + r""" + Iterate over the partial quotient of self. + + EXAMPLES:: + + sage: cf = continued_fraction(pi) + sage: i = iter(cf) + sage: [i.next() for _ in xrange(10)] + [3, 7, 15, 1, 292, 1, 1, 1, 2, 1] + sage: [i.next() for _ in xrange(10)] + [3, 1, 14, 2, 1, 1, 2, 2, 2, 2] + sage: [i.next() for _ in xrange(10)] + [1, 84, 2, 1, 1, 15, 3, 13, 1, 4] + """ + yield self.quotient(0) + i = 1 + while True: + q = self.quotient(i) + if q is Infinity: + break + yield q + i += 1 + + def __int__(self): + """ + EXAMPLES:: + + sage: a = continued_fraction(-17/389); a + [-1; 1, 21, 1, 7, 2] + sage: int(a) + -1 + """ + return int(self.quotient(0)) + + def __long__(self): + """ + EXAMPLES:: + + sage: a = continued_fraction(-17/389); a + [-1; 1, 21, 1, 7, 2] + sage: long(a) + -1L + """ + return long(self.quotient(0)) + + def sign(self): + r""" + Returns the sign of self as an Integer. + + The sign is defined to be ``0`` if ``self`` is ``0``, ``1`` if ``self`` + is positive and ``-1`` if ``self`` is negative. + + EXAMPLES:: + + sage: continued_fraction(tan(pi/7)).sign() + 1 + sage: continued_fraction(-34/2115).sign() + -1 + sage: continued_fraction([0]).sign() + 0 + """ + if self.quotient(0) == 0: + if self.quotient(1) is Infinity: + return ZZ_0 + return ZZ_1 + return self.quotient(0).sign() + + def floor(self): + r""" + Return the floor of ``self``. + + EXAMPLES:: + + sage: cf = continued_fraction([2,1,2,3]) + sage: cf.floor() + 2 + """ + return self.quotient(0) + + def ceil(self): + r""" + Return the ceil of ``self``. + + EXAMPLES:: + + sage: cf = continued_fraction([2,1,3,4]) + sage: cf.ceil() + 3 + """ + if self.length() == 1: + return self.quotient(0) + return self.quotient(0)+1 + + def __nonzero__(self): + """ + Return False if self is zero. + + EXAMPLES:: + + sage: continued_fraction(0).is_zero() # indirect doctest + True + sage: continued_fraction(1).is_zero() # indirect doctest + False + sage: continued_fraction([(),(1,)]).is_zero() # indirect doctest + False + sage: continued_fraction([(0,),(1,2)]).is_zero() # indirect doctest + False + """ + return bool(self.quotient(0)) or self.quotient(1) is not Infinity + + def is_zero(self): + r""" + Test whether ``self`` is zero. + + EXAMPLES:: + + sage: continued_fraction(0).is_zero() + True + sage: continued_fraction((0,1)).is_zero() + False + sage: continued_fraction(-1/2).is_zero() + False + sage: continued_fraction(pi).is_zero() + False + """ + return self.quotient(0) == ZZ_0 and self.quotient(1) is Infinity + + def is_one(self): + r""" + Test whether ``self`` is one. + + EXAMPLES:: + + sage: continued_fraction(1).is_one() + True + sage: continued_fraction(5/4).is_one() + False + sage: continued_fraction(0).is_one() + False + sage: continued_fraction(pi).is_one() + False + """ + return self.quotient(0) == ZZ_1 and self.quotient(1) is Infinity + + def is_minus_one(self): + r""" + Test whether ``self`` is minus one. + + EXAMPLES:: + + sage: continued_fraction(-1).is_minus_one() + True + sage: continued_fraction(1).is_minus_one() + False + sage: continued_fraction(0).is_minus_one() + False + sage: continued_fraction(-2).is_minus_one() + False + sage: continued_fraction([-1,1]).is_minus_one() + False + """ + return self.quotient(0) == ZZ_m1 and self.quotient(1) is Infinity + + def additive_order(self): + """ + Return the additive order of this continued fraction, + which we defined to be the additive order of its value. + + EXAMPLES:: + + sage: continued_fraction(-1).additive_order() + +Infinity + sage: continued_fraction(0).additive_order() + 1 + """ + return Infinity if self else ZZ_1 + + def multiplicative_order(self): + """ + Return the multiplicative order of this continued fraction, + which we defined to be the multiplicative order of its value. + + EXAMPLES:: + + sage: continued_fraction(-1).multiplicative_order() + 2 + sage: continued_fraction(1).multiplicative_order() + 1 + sage: continued_fraction(pi).multiplicative_order() + +Infinity + """ + if self.is_zero(): + return Infinity + if self.is_one(): + return ZZ_1 + if self.is_minus_one(): + return ZZ_2 + return Infinity + + def numerical_approx(self, prec=None, digits=None, algorithm=None): + """ + Return a numerical approximation of this continued fraction. + + INPUT: + + - ``prec`` - the precision + + - ``digits`` - the number of digits + + - ``algorithm`` - the algorithm to use + + See :func:`sage.misc.functional.numerical_approx` for more information + on the input. + + EXAMPLES:: + + sage: w = words.FibonacciWord([1,3]) + sage: cf = continued_fraction(w) + sage: cf + [1; 3, 1, 1, 3, 1, 3, 1, 1, 3, 1, 1, 3, 1, 3, 1, 1, 3, 1, 3...] + sage: cf.numerical_approx(prec=53) + 1.28102513329557 + + The method `n` is a shortcut to this one:: + + sage: cf.n(digits=25) + 1.281025133295569815552930 + sage: cf.n(digits=33) + 1.28102513329556981555293038097590 + """ + import sage.misc.functional + return sage.misc.functional.numerical_approx(self, prec=prec, + digits=digits, + algorithm=algorithm) + n = numerical_approx + + +class ContinuedFraction_periodic(ContinuedFraction_base): + r""" + Continued fraction associated with rational or quadratic number. + + A rational number has a finite continued fraction expansion (or ultimately + 0). The one of a quadratic number, ie a number of the form `a + b \sqrt{D}` + with `a` and `b` rational, is ultimately periodic. + + .. NOTE:: + + This class stores a tuple ``_x1`` for the preperiod and a tuple ``_x2`` + for the period. In the purely periodic case ``_x1`` is empty while in + the rational case ``_x2`` is the tuple ``(0,)``. + """ + def __init__(self, x1, x2=None, check=True): + r""" + INPUT: + + - ``x1`` - a tuple of integers + + - ``x2`` - a tuple of integers + + TESTS:: + + sage: cf = continued_fraction((1,1,2,3,4)) # indirect doctest + sage: loads(dumps(cf)) == cf + True + sage: cf = continued_fraction((1,5),(3,2)) # indirect doctest + sage: loads(dumps(cf)) == cf + True + """ + ContinuedFraction_base.__init__(self) + self._x1 = tuple(x1) + if not x2: + self._x2 = (Infinity,) + else: + self._x2 = tuple(x2) + + def period(self): + r""" + Return the periodic part of ``self``. + + EXAMPLES:: + + sage: K. = QuadraticField(3) + sage: cf = continued_fraction(sqrt3); cf + [1; (1, 2)*] + sage: cf.period() + (1, 2) + + sage: for k in xsrange(2,40): + ....: if not k.is_square(): + ....: s = QuadraticField(k).gen() + ....: cf = continued_fraction(s) + ....: print '%2d %d %s'%(k, len(cf.period()), cf) + 2 1 [1; (2)*] + 3 2 [1; (1, 2)*] + 5 1 [2; (4)*] + 6 2 [2; (2, 4)*] + 7 4 [2; (1, 1, 1, 4)*] + 8 2 [2; (1, 4)*] + 10 1 [3; (6)*] + 11 2 [3; (3, 6)*] + 12 2 [3; (2, 6)*] + 13 5 [3; (1, 1, 1, 1, 6)*] + 14 4 [3; (1, 2, 1, 6)*] + ... + 35 2 [5; (1, 10)*] + 37 1 [6; (12)*] + 38 2 [6; (6, 12)*] + 39 2 [6; (4, 12)*] + """ + if self._x2[0] is Infinity: + return () + return self._x2 + + def preperiod(self): + r""" + Return the preperiodic part of ``self``. + + EXAMPLES:: + + sage: K. = QuadraticField(3) + sage: cf = continued_fraction(sqrt3); cf + [1; (1, 2)*] + sage: cf.preperiod() + (1,) + + sage: cf = continued_fraction(sqrt3/7); cf + [0; 4, (24, 8)*] + sage: cf.preperiod() + (0, 4) + """ + return self._x1 + + def quotient(self, n): + r""" + Return the ``n``-th partial quotient of ``self``. + + EXAMPLES:: + + sage: cf = continued_fraction([(12,5),(1,3)]) + sage: [cf.quotient(i) for i in xrange(10)] + [12, 5, 1, 3, 1, 3, 1, 3, 1, 3] + """ + n = int(n) + if n < 0: + raise ValueError("n (=%d) should be positive" % n) + if n < len(self._x1): + return self._x1[n] + return self._x2[(n-len(self._x1)) % len(self._x2)] + + def length(self): + r""" + Returns the number of partial quotients of ``self``. + + EXAMPLES:: + + sage: continued_fraction(2/5).length() + 3 + sage: cf = continued_fraction([(0,1),(2,)]); cf + [0; 1, (2)*] + sage: cf.length() + +Infinity + """ + if len(self._x2) > 1 or self._x2[0] is not Infinity: + return Infinity + return Integer(len(self._x1)) + + def __cmp__(self, other): + r""" + EXAMPLES:: + + sage: a = continued_fraction([(0,),(1,2,3,1,2,3,1)]); a.n() + 0.694249167819459 + sage: b = continued_fraction([(0,),(1,2,3)]); b.n() + 0.694254176766073 + sage: c = continued_fraction([(0,1),(2,3)]); c.n() + 0.696140478029631 + sage: d = continued_fraction([(0,1,2),(3,)]); d.n() + 0.697224362268005 + sage: a < b and a < c and a < d + True + sage: b < c and b < d and c < d + True + sage: b == c + False + sage: c > c + False + sage: b >= d + False + """ + if isinstance(other, ContinuedFraction_periodic): + n = max(len(self._x1) + 2*len(self._x2), + len(other._x1) + 2*len(other._x2)) + for i in xrange(n): + a = self.quotient(i) + b = other.quotient(i) + test = cmp(a,b) + if test == 1: + return -1 if i % 2 else 1 + if test == -1: + return 1 if i % 2 else -1 + return 0 + + return ContinuedFraction_base.__cmp__(self, other) + + def value(self): + r""" + Return the value of ``self`` as a quadratic number (with square free + discriminant). + + EXAMPLES: + + Some purely periodic examples:: + + sage: cf = continued_fraction([(),(2,)]); cf + [(2)*] + sage: v = cf.value(); v + sqrt2 + 1 + sage: v.continued_fraction() + [(2)*] + + sage: cf = continued_fraction([(),(1,2)]); cf + [(1, 2)*] + sage: v = cf.value(); v + 1/2*sqrt3 + 1/2 + sage: v.continued_fraction() + [(1, 2)*] + + The number ``sqrt3`` that appear above is actually internal to the + continued fraction. In order to be access it from the console:: + + sage: cf.value().parent().inject_variables() + Defining sqrt3 + sage: sqrt3 + sqrt3 + sage: ((sqrt3+1)/2).continued_fraction() + [(1, 2)*] + + Some ultimately periodic but non periodic examples:: + + sage: cf = continued_fraction([(1,),(2,)]); cf + [1; (2)*] + sage: v = cf.value(); v + sqrt2 + sage: v.continued_fraction() + [1; (2)*] + + sage: cf = continued_fraction([(1,3),(1,2)]); cf + [1; 3, (1, 2)*] + sage: v = cf.value(); v + -sqrt3 + 3 + sage: v.continued_fraction() + [1; 3, (1, 2)*] + + sage: cf = continued_fraction([(-5,18), (1,3,1,5)]) + sage: cf.value().continued_fraction() == cf + True + sage: cf = continued_fraction([(-1,),(1,)]) + sage: cf.value().continued_fraction() == cf + True + + TESTS:: + + sage: a1 = ((0,1),(2,3)) + sage: a2 = ((-12,1,1),(2,3,2,4)) + sage: a3 = ((1,),(1,2)) + sage: a4 = ((-2,2),(1,124,13)) + sage: a5 = ((0,),(1,)) + sage: for a in a1,a2,a3,a4,a5: + ....: cf = continued_fraction(a) + ....: assert cf.value().continued_fraction() == cf + """ + if self._x1 and self._x1[0] < 0: + return -(-self).value() + + if self._x2[0] is Infinity: + return self._rational_() + + # determine the equation for the purely periodic cont. frac. determined + # by self._x2 + p0,q0,p1,q1 = last_two_convergents(self._x2) + + # now x is one of the root of the equation + # q1 x^2 + (q0 - p1) x - p0 = 0 + from sage.rings.number_field.number_field import QuadraticField + from sage.misc.functional import squarefree_part + D = (q0-p1)**2 + 4*q1*p0 + DD = squarefree_part(D) + Q = QuadraticField(DD, 'sqrt%d' % DD) + x = ((p1 - q0) + (D/DD).sqrt() * Q.gen()) / (2*q1) + + # we add the preperiod + p0,q0,p1,q1 = last_two_convergents(self._x1) + return (p1*x + p0) / (q1*x + q0) + + def _repr_(self): + r""" + TESTS:: + + sage: a = continued_fraction(pi.n()); a + [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 3] + sage: a.rename('continued fraction of pi') + sage: a + continued fraction of pi + + sage: continued_fraction([(0,1),(2,)]) + [0; 1, (2)*] + sage: continued_fraction([(),(1,3)]) + [(1, 3)*] + """ + if self._x2[0] is Infinity: # rational case + if len(self._x1) == 1: + return '[%d]' % self._x1[0] + return '[%d; ' % self._x1[0] + ', '.join(str(a) for a in self._x1[1:]) + ']' + + period = '(' + ', '.join(str(a) for a in self._x2) + ')*' + if not self._x1: # purely periodic case + return '[' + period + ']' + + if len(self._x1) == 1: + return '[%d; ' % self._x1[0] + period + ']' + return '[%d; ' % self._x1[0] + ', '.join(str(a) for a in self._x1[1:]) + ', ' + period + ']' + +# def __reduce__(self): +# r""" +# Pickling support. +# +# EXAMPLES:: +# +# sage: a = CFF([1,2,3]) +# sage: loads(dumps(a)) == a +# True +# +# sage: a = CFF([(-1,2),(3,1,4)]) +# sage: loads(dumps(a)) == a +# True +# """ +# return self.parent(),((self._x1,self._x2),) + + def __len__(self): + """ + Return the number of terms in this continued fraction. + + EXAMPLES:: + + sage: len(continued_fraction([1,2,3,4,5]) ) + 5 + """ + if self._x2[0] is Infinity: # rational case + return len(self._x1) + raise ValueError("the length is infinite") + + def _rational_(self): + """ + EXAMPLES:: + + sage: a = continued_fraction(-17/389); a + [-1; 1, 21, 1, 7, 2] + sage: a._rational_() + -17/389 + sage: QQ(a) + -17/389 + """ + if self._x2[0] is not Infinity: + raise ValueError("this is not a rational!") + n = len(self) + return self.numerator(n-1) / self.denominator(n-1) + + def _latex_(self): + """ + EXAMPLES:: + + sage: a = continued_fraction(-17/389) + sage: latex(a) + -1+ \frac{\displaystyle 1}{\displaystyle 1+ \frac{\displaystyle 1}{\displaystyle 21+ \frac{\displaystyle 1}{\displaystyle 1+ \frac{\displaystyle 1}{\displaystyle 7+ \frac{\displaystyle 1}{\displaystyle 2}}}}} + """ + if self._x2[0] is not Infinity: + raise NotImplementedError("latex not implemented for non rational continued fractions") + v = self._x1 + if len(v) == 0: + return '0' + s = str(v[0]) + for i in range(1,len(v)): + s += '+ \\frac{\\displaystyle 1}{\\displaystyle %s' % v[i] + s += '}'*(len(v)-1) + return s + + def __invert__(self): + """ + Return the multiplicative inverse of self. + + EXAMPLES:: + + sage: a = continued_fraction(13/25) + sage: ~a == continued_fraction(25/13) + True + sage: a.value() * (~a).value() + 1 + + sage: a = continued_fraction(-17/253) + sage: ~a == continued_fraction(-253/17) + True + sage: a.value() * (~a).value() + 1 + + sage: K. = QuadraticField(5) + sage: a1 = (sqrt5+1)/2 + sage: c1 = a1.continued_fraction(); c1 + [(1)*] + sage: ~c1 + [0; (1)*] + sage: c1.value() * (~c1).value() + 1 + + sage: c2 = (sqrt5/3 + 1/7).continued_fraction(); c2 + [0; 1, (7, 1, 17, ..., 1, 2)*] + sage: c2.value() * (~c2).value() + 1 + """ + if not self: + raise ZeroDivisionError("Rational division by 0") + if self._x1: + if self._x1[0] < 0: + return -(-self).__invert__() + if self._x1[0] == 0: + return self.__class__(self._x1[1:], self._x2) + return self.__class__((0,) + self._x1, self._x2) + + def __neg__(self): + """ + Return additive inverse of self. + + TESTS:: + + sage: quots1 = [(0,),(1,),(2,),(0,1),(1,1),(2,1),(1,2),(0,1,1),(1,1,1),(1,1,1,1),(1,2)] + sage: for q in quots1: + ....: cf = continued_fraction(q) + ....: ncf = -cf + ....: nncf = -ncf + ....: assert cf == nncf + ....: assert ncf.value() == -cf.value() + ....: assert cf.length() < 2 or cf.quotients()[-1] != 1 + ....: assert ncf.length() < 2 or ncf.quotients()[-1] != 1 + ....: assert nncf.length() < 2 or nncf.quotients()[-1] != 1 + + sage: quots2 = [((),(1,)), ((), (1,2)), ((0,),(1,)), ((),(2,1)), ((3,),(2,1))] + sage: for q in quots2: + ....: cf = continued_fraction(q) + ....: ncf = -cf + ....: nncf = -ncf + ....: assert cf == nncf + ....: assert ncf.value() == -cf.value() + """ + x1 = self._x1 + x2 = self._x2 + + if x2[0] is Infinity: + if len(x1) == 1: + xx1 =(-x1[0],) + + elif x1[1] == 1: + xx1 = (-x1[0]-1, x1[2]+1) + x1[3:] + + elif len(x1) == 2 and x1[1] == 2: + xx1 = (-x1[0] -1, ZZ_2) + + else: + xx1 = (-x1[0]-1, ZZ_1, x1[1]-1) + x1[2:] + + return self.__class__(xx1, x2) + + # to make the quadratic case work, we need 3 elements in x1 + if len(x1) < 3: + x1 += x2 + if len(x1) < 3: + x1 += x2 + if len(x1) < 3: + x1 += x2 + + if x1[1] == 1: + xx1 = (-x1[0]-1, x1[2]+1) + x1[3:] + else: + xx1 = (-x1[0]-1, ZZ_1, x1[1]-1) + x1[2:] + xx1,xx2 = check_and_reduce_pair(xx1,x2) + return self.__class__(xx1,xx2) + +class ContinuedFraction_real(ContinuedFraction_base): + r""" + Continued fraction of a real (exact) number. + + This class simply wraps a real number into an attribute (that can be + accessed through the method :meth:`value`). The number is assumed to be + irrational. + + EXAMPLES:: + + sage: cf = continued_fraction(pi) + sage: cf + [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, ...] + sage: cf.value() + pi + + sage: cf = continued_fraction(e) + sage: cf + [2; 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1, ...] + sage: cf.value() + e + """ + def __init__(self, x): + r""" + INPUT: + + - ``x`` -- the real number from which we want the continued fraction + + TESTS:: + + sage: TestSuite(continued_fraction(pi)).run() + """ + ContinuedFraction_base.__init__(self) + self._x0 = x + + + from real_mpfi import RealIntervalField + self._xa = RealIntervalField(53)(self._x0) # an approximation of the + # last element of the orbit + # under the Gauss map + self._quotients = [] + + def length(self): + r""" + Return infinity + + EXAMPLES:: + + sage: continued_fraction(pi).length() + +Infinity + """ + return Infinity + + def __len__(self): + r""" + TESTS:: + + sage: len(continued_fraction(pi)) + Traceback (most recent call last): + ... + ValueError: the length is infinite! + """ + raise ValueError("the length is infinite!") + +# def __reduce__(self): +# r""" +# Pickling support. +# +# TESTS:: +# +# sage: cf = continued_fraction(pi) +# sage: loads(dumps(cf)) == cf +# True +# """ +# return self.parent(),(self.value(),) + + def __cmp__(self, other): + r""" + Comparison. + + EXAMPLES:: + + sage: continued_fraction(pi) > continued_fraction(e) + True + sage: continued_fraction(pi) > continued_fraction(e+4) + False + """ + try: + # The following is crazy and prevent us from using cmp(self.value(), + # other.value()). On sage-5.10.beta2: + # sage: cmp(pi, 4) + # -1 + # sage: cmp(pi, pi+4) + # 1 + if self.value() == other.value(): + return 0 + if self.value() - other.value() > 0: + return 1 + return -1 + except StandardError: + return ContinuedFraction_base.__cmp__(self, other) + + def _repr_(self): + r""" + String representation. + + EXAMPLES:: + + sage: continued_fraction(pi) # indirect doctest + [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, ...] + """ + return '[%d; ' % self.quotient(0) + ', '.join(str(self.quotient(i)) for i in xrange(1,20)) + ", ...]" + + def quotient(self, n): + r""" + Returns the ``n``-th quotient of ``self``. + + EXAMPLES:: + + sage: cf = continued_fraction(pi) + sage: cf.quotient(27) + 13 + sage: cf.quotient(2552) + 152 + sage: cf.quotient(10000) # long time + 5 + + The algorithm is not efficient with element of the symbolic ring and, + if possible, one can always prefer number fields elements. The reason is + that, given a symbolic element ``x``, there is no automatic way to + evaluate in ``RIF`` an expression of the form ``(a*x+b)/(c*x+d)`` where + both the numerator and the denominator are extremely small:: + + sage: a1 = pi + sage: c1 = continued_fraction(a1) + sage: p0 = c1.numerator(12); q0 = c1.denominator(12) + sage: p1 = c1.numerator(13); q1 = c1.denominator(13) + sage: num = (q0*a1 - p0); num.n() + 1.49011611938477e-8 + sage: den = (q1*a1 - p1); den.n() + -2.98023223876953e-8 + sage: a1 = -num/den + sage: RIF(a1) + [-infinity .. +infinity] + + The same computation with an element of a number field instead of + ``pi`` gives a very satisfactory answer:: + + sage: K. = NumberField(x^3 - 2, embedding=1.25) + sage: c2 = continued_fraction(a2) + sage: p0 = c2.numerator(111); q0 = c2.denominator(111) + sage: p1 = c2.numerator(112); q1 = c2.denominator(112) + sage: num = (q0*a2 - p0); num.n() + -4.56719261665907e46 + sage: den = (q1*a2 - p1); den.n() + -3.65375409332726e47 + sage: a2 = -num/den + sage: b2 = RIF(a2); b2 + 1.002685823312715? + sage: b2.absolute_diameter() + 8.88178419700125e-16 + + The consequence is that the precision needed with ``c1`` grows when we + compute larger and larger partial quotients:: + + sage: c1.quotient(100) + 2 + sage: c1._xa.parent() + Real Interval Field with 353 bits of precision + sage: c1.quotient(200) + 3 + sage: c1._xa.parent() + Real Interval Field with 753 bits of precision + sage: c1.quotient(300) + 5 + sage: c1._xa.parent() + Real Interval Field with 1053 bits of precision + + sage: c2.quotient(200) + 6 + sage: c2._xa.parent() + Real Interval Field with 53 bits of precision + sage: c2.quotient(500) + 1 + sage: c2._xa.parent() + Real Interval Field with 53 bits of precision + sage: c2.quotient(1000) + 1 + sage: c2._xa.parent() + Real Interval Field with 53 bits of precision + """ + x = self._xa + + if len(self._quotients) > 1 and n >= len(self._quotients) and self._quotients[-1] == 0: + return ZZ_0 + + for k in xrange(len(self._quotients), n+1): + if x.lower().is_infinity() or x.upper().is_infinity() or x.lower().floor() != x.upper().floor(): + orbit = lambda z: -(self.denominator(k-2)*z-self.numerator(k-2))/(self.denominator(k-1)*z-self.numerator(k-1)) + x = x.parent()(orbit(self._x0)) + + # It may happen that the above line fails to give an + # approximation with the expected number of digits (see the + # examples). In that case, we augment the precision. + while x.lower().is_infinity() or x.upper().is_infinity() or x.lower().floor() != x.upper().floor(): + from real_mpfi import RealIntervalField + self._prec = x.parent().prec() + 100 + x = RealIntervalField(self._prec)(orbit(self._x0)) + + self._quotients.append(x.unique_floor()) + x = (x-x.unique_floor()) + if not x: + self._quotients.append(ZZ_0) + return ZZ_0 + x = ~x + + self._xa = x + return self._quotients[n] + + def value(self): + r""" + Return the value of ``self`` (the number from which it was built). + + EXAMPLES:: + + sage: cf = continued_fraction(e) + sage: cf.value() + e + """ + return self._x0 + + +class ContinuedFraction_infinite(ContinuedFraction_base): + r""" + A continued fraction defined by an infinite sequence of partial quotients. + + EXAMPLES:: + + sage: t = continued_fraction(words.ThueMorseWord([1,2])); t + [1; 2, 2, 1, 2, 1, 1, 2, 2, 1...] + sage: t.n(digits=100) + 1.422388736882785488341547116024565825306879108991711829311892452916456747272565883312455412962072042 + + We check that comparisons work well:: + + sage: t > continued_fraction(1) and t < continued_fraction(3/2) + True + sage: t < continued_fraction(1) or t > continued_fraction(2) + False + + Can also be called with a ``value`` option:: + + sage: def f(n): + ....: if n % 3 == 2: return 2*(n+1)//3 + ....: return 1 + sage: w = Word(f, alphabet=NN) + sage: w + word: 1,1,2,1,1,4,1,1,6,1,1,8,1,1,10,1,1,12,1,1,14,1,1,16,1,1,18,1,1,20,1,1,22,1,1,24,1,1,26,1,... + sage: cf = continued_fraction(w, value=e-1) + sage: cf + [1; 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1...] + + In that case a small check is done on the input:: + + sage: cf = continued_fraction(w, value=pi) + Traceback (most recent call last): + ... + ValueError: value evaluates to 3.141592653589794? while the continued fraction evaluates to 1.718281828459046? in Real Interval Field with 53 bits of precision. + + """ + def __init__(self, w, value=None, check=True): + r""" + INPUT: + + - ``parent`` - a parent + + - ``w`` - an infinite list + + - ``value`` - an optional known value + + - ``check`` - whether the constructor checks the input (default is + ``True``) + + TESTS:: + + sage: w = words.FibonacciWord(['a','b']) + sage: continued_fraction(w) + Traceback (most recent call last): + ... + ValueError: the sequence must consist of integers + + sage: from itertools import count + sage: w = Word(count()) + sage: continued_fraction(w) + [0; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19...] + + sage: continued_fraction(words.FibonacciWord([0,1])) + Traceback (most recent call last): + ... + ValueError: only the first partial quotient can be null + + sage: w = words.ThueMorseWord([int(1), int(2)]) + sage: t = continued_fraction(w) + sage: type(t.quotient(1)) + + """ + ContinuedFraction_base.__init__(self) + self._w = w + + if check: + for i in xrange(10): + k = w[i] + if not isinstance(k, Integer): + try: + k = Integer(w[i]) + except (TypeError,ValueError): + raise ValueError("the sequence must consist of integers") + self.quotient = self._Integer_quotient + + if not k and i: + raise ValueError("only the first partial quotient can be null") + + if check and value is not None: + from sage.rings.real_mpfi import RealIntervalField + R = RealIntervalField(53) + x = R(value) + y = R(self) + if x.lower() > y.lower() or x.upper() < y.upper(): + raise ValueError("value evaluates to %s while the continued fraction evaluates to %s in %s."%(x,y,R)) + + self._value = value + + def _repr_(self): + r""" + String representation. + + EXAMPLES:: + + sage: # TODO + """ + return "[" + str(self._w[0]) + "; " + ", ".join(map(str,self._w[1:20])) + "...]" + + def length(self): + r""" + Returns infinity. + + EXAMPLES:: + + sage: w = words.FibonacciWord([3,13]) + sage: cf = continued_fraction(w) + sage: cf.length() + +Infinity + """ + return Infinity + + def quotient(self, n): + r""" + The ``n``-th partial quotient of ``self``. + + EXAMPLES:: + + sage: w = words.FibonacciWord([1,3]) + sage: cf = continued_fraction(w) + sage: cf.quotient(0) + 1 + sage: cf.quotient(1) + 3 + sage: cf.quotient(2) + 1 + """ + return self._w[n] + + def quotients(self): + r""" + Return the infinite list from which this continued fraction was built. + + EXAMPLES:: + + sage: w = words.FibonacciWord([1,5]) + sage: cf = continued_fraction(w) + sage: cf.quotients() + word: 1511515115115151151511511515115115151151... + """ + return self._w + + def _Integer_quotient(self, n): + r""" + The ``n``-th partial quotient of ``self``. + + EXAMPLES:: + + sage: w = words.ThueMorseWord([int(1), int(2)]) + sage: t = continued_fraction(w) + sage: t.quotient(0) + 1 + sage: t.quotient(1) + 2 + sage: type(t.quotient(1)) # indirect doctest + + """ + return Integer(self._w[n]) + + def value(self): + r""" + The value of ``self``. + + The method only works if a value was provided in the constructor. + + EXAMPLES:: + + sage: def f(n): + ....: if n % 3 == 2: return 2*(n+1)//3 + ....: return 1 + sage: w = Word(f, alphabet=NN) + sage: w + word: 1,1,2,1,1,4,1,1,6,1,1,8,1,1,10,1,1,12,1,1,14,1,1,16,1,1,18,1,1,20,1,1,22,1,1,24,1,1,26,1,... + sage: cf = continued_fraction(w, value=e-1) + sage: cf + [1; 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1...] + sage: cf.value() + e - 1 + """ + if self._value is not None: + return self._value + raise NotImplementedError("Real numbers built from continued fractions are not yet implemented") + +def check_and_reduce_pair(x1,x2=None): + r""" + There are often two ways to represent a given continued fraction. This + function makes it canonical. + + In the very special case of the number `0` we return the pair + ``((0,),(0,))``. + + TESTS:: + + sage: from sage.rings.continued_fraction import check_and_reduce_pair + sage: check_and_reduce_pair([]) + ((0,), (+Infinity,)) + sage: check_and_reduce_pair([-1,1]) + ((0,), (+Infinity,)) + sage: check_and_reduce_pair([1,1,1]) + ((1, 2), (+Infinity,)) + sage: check_and_reduce_pair([1,3],[2,3]) + ((1,), (3, 2)) + sage: check_and_reduce_pair([1,2,3],[2,3,2,3,2,3]) + ((1,), (2, 3)) + sage: check_and_reduce_pair([1,2],[]) + ((1, 2), (+Infinity,)) + """ + y1 = map(Integer,x1) + + if x2 is None or not x2 or x2[0] is Infinity: + y2 = [Infinity] + if not y1: + y1 = [ZZ_0] + elif len(y1) > 1 and y1[-1] == 1: + y1.pop(-1) + y1[-1] += 1 + + else: + y2 = map(Integer,x2) + if any(b <= ZZ_0 for b in y2): + raise ValueError("the elements of the period can not be negative") + + # add possibly some element of x1 into the period + while y1 and y1[-1] == y2[-1]: + y1.pop(-1) + y2.insert(0,y2.pop(-1)) + + # some special cases to treat + if len(y2) == 1 and y2[0] == 0: + if not y1: + y1 = [ZZ_0] + elif len(y1) > 1 and y1[-1] == 1: + y1.pop(-1) + y1[-1] += 1 + + # check that y2 is not a pure power (in a very naive way!!) + n2 = len(y2) + for i in xrange(1,(n2+2)/2): + if n2 % i == 0 and y2[:-i] == y2[i:]: + y2 = y2[:i] + break + + # check that at then end y1 has no zeros in it + for i in xrange(1,len(y1)): + if y1[i] <= 0: + raise ValueError("all quotient except the first must be positive") + + return tuple(y1),tuple(y2) + + +def continued_fraction_list(x, type="std", partial_convergents=False, bits=None, nterms=None): + r""" + Returns the (finite) continued fraction of ``x`` as a list. + + The continued fraction expansion of ``x`` are the coefficients `a_i` in + + .. MATH:: + + x = a_0 + 1/(a_1 + 1/(...)) + + with `a_0` integer and `a_1`, `...` positive integers. The Hirzebruch-Jung + continued fraction is the one for which the `+` signs are replaced with `-` + signs + + .. MATH:: + + x = a_0 - 1/(a_1 - 1/(...)) + + .. SEEALSO:: + + :func:`continued_fraction` + + INPUT: + + - ``x`` -- exact rational or floating-point number. The number to + compute the continued fraction of. + + - ``type`` -- either "std" (default) for standard continued fractions or + "hj" for Hirzebruch-Jung ones. + + - ``partial_convergents`` -- boolean. Whether to return the partial convergents. + + - ``bits`` -- an optional integer that specify a precision for the real + interval field that is used internally. + + - ``nterms`` -- integer. The upper bound on the number of terms in + the continued fraction expansion to return. + + OUTPUT: + + A lits of integers, the coefficients in the continued fraction expansion of + ``x``. If ``partial_convergents`` is set to ``True``, then return a pair + containing the coefficient list and the partial convergents list is + returned. + + EXAMPLES:: + + sage: continued_fraction_list(45/19) + [2, 2, 1, 2, 2] + sage: 2 + 1/(2 + 1/(1 + 1/(2 + 1/2))) + 45/19 + + sage: continued_fraction_list(45/19,type="hj") + [3, 2, 3, 2, 3] + sage: 3 - 1/(2 - 1/(3 - 1/(2 - 1/3))) + 45/19 + + Specifying ``bits`` or ``nterms`` modify the length of the output:: + + sage: continued_fraction_list(e, bits=20) + [2, 1, 2, 1, 1, 4, 2] + sage: continued_fraction_list(sqrt(2)+sqrt(3), bits=30) + [3, 6, 1, 5, 7, 2] + sage: continued_fraction_list(pi, bits=53) + [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14] + + sage: continued_fraction_list(log(3/2), nterms=15) + [0, 2, 2, 6, 1, 11, 2, 1, 2, 2, 1, 4, 3, 1, 1] + sage: continued_fraction_list(tan(sqrt(pi)), nterms=20) + [-5, 9, 4, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, 1, 1, 2, 4, 3, 1, 63] + + When the continued fraction is infinite (ie ``x`` is an irrational number) + and the parameters ``bits`` and ``nterms`` are not specified then a warning + is raised:: + + sage: continued_fraction_list(sqrt(2)) + doctest:...: UserWarning: the continued fraction of sqrt(2) seems infinite, return only the first 20 terms + [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] + sage: continued_fraction_list(sqrt(4/19)) + doctest:...: UserWarning: the continued fraction of 2*sqrt(1/19) seems infinite, return only the first 20 terms + [0, 2, 5, 1, 1, 2, 1, 16, 1, 2, 1, 1, 5, 4, 5, 1, 1, 2, 1, 16] + + An examples with the list of partial convergents:: + + sage: continued_fraction_list(RR(pi), partial_convergents=True) + ([3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 3], + [(3, 1), + (22, 7), + (333, 106), + (355, 113), + (103993, 33102), + (104348, 33215), + (208341, 66317), + (312689, 99532), + (833719, 265381), + (1146408, 364913), + (4272943, 1360120), + (5419351, 1725033), + (80143857, 25510582), + (245850922, 78256779)]) + + TESTS:: + + sage: continued_fraction_list(1 + 10^-10, nterms=3) + [1, 10000000000] + sage: continued_fraction_list(1 + 10^-20 - e^-100, nterms=3) + [1, 100000000000000000000, 2688] + sage: continued_fraction_list(1 + 10^-20 - e^-100, nterms=5) + [1, 100000000000000000000, 2688, 8, 1] + sage: continued_fraction_list(1 + 10^-20 - e^-100, nterms=5) + [1, 100000000000000000000, 2688, 8, 1] + """ + from rational_field import QQ + + try: + return x.continued_fraction_list(type=type) + except AttributeError: + pass + + if bits is not None: + from real_mpfi import RealIntervalField + x = RealIntervalField(bits)(x) + + if type == "hj": + l = QQ(x).continued_fraction_list("hj") + ## The C-code in sage.rings.rational is much more faster than the pure + ## Python below + ## v = [] + ## while True: + ## div, mod = divmod(x.numerator(), x.denominator()) + ## if mod == 0: + ## v.append(div) + ## break + ## v.append(div+1) + ## if nterms is not None and len(v) >= nterms: + ## break + ## x = 1/(div+1-x) + ## return v + if nterms is None: + return l + return l[:nterms] + + if type != "std": + raise ValueError("type must be either \"std\" or \"hj\"") + + cf = None + + from sage.rings.real_mpfi import is_RealIntervalField + if is_RealIntervalField(x.parent()): + cf = continued_fraction(rat_interval_cf_list( + x.lower().exact_rational(), + x.upper().exact_rational())) + + if cf is None: + try: + cf = continued_fraction(x) + except ValueError: + pass + + if cf is None: + raise ValueError("does not know how to compute the continued fraction of %s"%x) + + if nterms: + limit = min(cf.length(), nterms) + elif cf.length() != Infinity: + limit = cf.length() + else: + import warnings + warnings.warn("the continued fraction of %s seems infinite, return only the first 20 terms" % x) + limit = 20 + if partial_convergents: + return [cf.quotient(i) for i in xrange(limit)], [(cf.numerator(i),cf.denominator(i)) for i in xrange(limit)] + return [cf.quotient(i) for i in xrange(limit)] + + + + +def continued_fraction(x, value=None): + r""" + Return the continued fraction of ``x``. + + INPUT: + + - `x` -- a number or a list of partial quotients (for finite + development) or two list of partial quotients (preperiod and period + for ultimately periodic development) + + EXAMPLES: + + A finite continued fraction may be initialized by a number or by its list of + partial quotients:: + + sage: continued_fraction(12/571) + [0; 47, 1, 1, 2, 2] + sage: continued_fraction([3,2,1,4]) + [3; 2, 1, 4] + + It can be called with elements defined from symbolic values, in which case + the partial quotients are evaluated in a lazy way:: + + sage: c = continued_fraction(golden_ratio); c + [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...] + sage: c.convergent(12) + 377/233 + sage: fibonacci(14)/fibonacci(13) + 377/233 + + sage: continued_fraction(pi) + [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, ...] + sage: c = continued_fraction(pi); c + [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, ...] + sage: a = c.convergent(3); a + 355/113 + sage: a.n() + 3.14159292035398 + sage: pi.n() + 3.14159265358979 + + sage: continued_fraction(sqrt(2)) + [1; 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ...] + sage: continued_fraction(tan(1)) + [1; 1, 1, 3, 1, 5, 1, 7, 1, 9, 1, 11, 1, 13, 1, 15, 1, 17, 1, 19, ...] + sage: continued_fraction(tanh(1)) + [0; 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, ...] + sage: continued_fraction(e) + [2; 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1, ...] + + If you want to play with quadratic numbers (such as ``golden_ratio`` and + ``sqrt(2)`` above), it is much more convenient to use number fields as + follows since preperiods and periods are computed:: + + sage: K. = NumberField(x^2-5, embedding=2.23) + sage: my_golden_ratio = (1 + sqrt5)/2 + sage: cf = continued_fraction((1+sqrt5)/2); cf + [(1)*] + sage: cf.convergent(12) + 377/233 + sage: cf.period() + (1,) + sage: cf = continued_fraction(2/3+sqrt5/5); cf + [1; 8, (1, 3, 1, 1, 3, 9)*] + sage: cf.preperiod() + (1, 8) + sage: cf.period() + (1, 3, 1, 1, 3, 9) + + sage: L. = NumberField(x^2-2, embedding=1.41) + sage: cf = continued_fraction(sqrt2); cf + [1; (2)*] + sage: cf.period() + (2,) + sage: cf = continued_fraction(sqrt2/3); cf + [0; 2, (8, 4)*] + sage: cf.period() + (8, 4) + + It is also possible to go the other way around, build a ultimately periodic + continued fraction from its preperiod and its period and get its value + back:: + + sage: cf = continued_fraction([(1,1),(2,8)]); cf + [1; 1, (2, 8)*] + sage: cf.value() + 2/11*sqrt5 + 14/11 + + It is possible to deal with higher degree number fields but in that case the + continued fraction expansion is known to be aperiodic:: + + sage: K. = NumberField(x^3-2, embedding=1.25) + sage: cf = continued_fraction(a); cf + [1; 3, 1, 5, 1, 1, 4, 1, 1, 8, 1, 14, 1, 10, 2, 1, 4, 12, 2, 3, ...] + + Note that initial rounding can result in incorrect trailing partial + quotients:: + + sage: continued_fraction(RealField(39)(e)) + [2; 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 2] + + Note the value returned for floating point number is the continued fraction + associated to the rational number you obtain with a conversion:: + + sage: for _ in xrange(10): + ....: x = RR.random_element() + ....: cff = continued_fraction(x) + ....: cfe = QQ(x).continued_fraction() + ....: assert cff == cfe, "%s %s %s"%(x,cff,cfe) + """ + + if isinstance(x, ContinuedFraction_base): + return x + + try: + return x.continued_fraction() + except AttributeError: + pass + + # input for finite or ultimately periodic partial quotient expansion + from sage.combinat.words.finite_word import FiniteWord_class + if isinstance(x, FiniteWord_class): + x = list(x) + + if isinstance(x, (list, tuple)): + if len(x) == 2 and isinstance(x[0], (list,tuple)) and isinstance(x[1], (list,tuple)): + x1 = tuple(Integer(a) for a in x[0]) + x2 = tuple(Integer(a) for a in x[1]) + x1, x2 = check_and_reduce_pair(x1, x2) + else: + x1, x2 = check_and_reduce_pair(x) + return ContinuedFraction_periodic(x1, x2) + + # input for infinite partial quotient expansion + from sage.misc.lazy_list import lazy_list + from sage.combinat.words.infinite_word import InfiniteWord_class + if isinstance(x, (lazy_list, InfiniteWord_class)): + return ContinuedFraction_infinite(x, value) + + # input for numbers + #TODO: the approach used below might be not what the user expects as we + # have currently in sage (version 6.2) + # sage: RR.random_element() in QQ + # True + from rational_field import QQ + if x in QQ: + return QQ(x).continued_fraction() + + is_real = False + try: + is_real = x.is_real() + except AttributeError: + pass + + if is_real is False: + # we can not rely on the answer of .is_real() for elements of the + # symbolic ring. The thing below is a dirty temporary hack. + from real_mpfi import RealIntervalField + RIF = RealIntervalField(53) + try: + RIF(x) + is_real = True + except (AttributeError,ValueError): + pass + + if is_real is False: + raise ValueError("the number %s does not seem to be a real number"%x) + + if x.parent().is_exact(): + return ContinuedFraction_real(x) + + # we treat separatly the symbolic ring that holds all constants and + # which is not exact + from sage.symbolic.ring import SR + if x.parent() == SR: + return ContinuedFraction_real(x) + + raise ValueError("does not know how to compute the continued fraction of %s, try the function continued_fraction_list instead"%x) + +def Hirzebruch_Jung_continued_fraction_list(x, bits=None, nterms=None): + r""" + Return the Hirzebruch-Jung continued fraction of ``x`` as a list. + + This function is deprecated since :trac:`14567`. See + :func:`continued_fraction_list` and the documentation therein. + + INPUT: + + - ``x`` -- exact rational or something that can be numerically + evaluated. The number to compute the continued fraction of. + + - ``bits`` -- integer (default: the precision of ``x``). the + precision of the real interval field that is used + internally. This is only used if ``x`` is not an exact fraction. + + - ``nterms`` -- integer (default: None). The upper bound on the + number of terms in the continued fraction expansion to return. + A lits of integers, the coefficients in the Hirzebruch-Jung continued + fraction expansion of ``x``. + + EXAMPLES:: + + sage: Hirzebruch_Jung_continued_fraction_list(17/11) + doctest:...: DeprecationWarning: Hirzebruch_Jung_continued_fraction_list(x) is replaced by + continued_fraction_list(x,type="hj") + or for rationals + x.continued_fraction_list(type="hj") + See http://trac.sagemath.org/14567 for details. + [2, 3, 2, 2, 2, 2] + """ + from sage.misc.superseded import deprecation + deprecation(14567, 'Hirzebruch_Jung_continued_fraction_list(x) is replaced by\n\tcontinued_fraction_list(x,type="hj")\nor for rationals\n\tx.continued_fraction_list(type="hj")') + return continued_fraction_list(x, type="hj", bits=bits, nterms=nterms) + +def convergents(x): + r""" + Return the (partial) convergents of the number ``x``. + + EXAMPLES:: + + sage: convergents(143/255) + [0, 1, 1/2, 4/7, 5/9, 9/16, 14/25, 23/41, 60/107, 143/255] + """ + return continued_fraction(x).convergents() + +def farey(v, lim): + """ + Return the Farey sequence associated to the floating point number + v. + + INPUT: + + + - ``v`` - float (automatically converted to a float) + + - ``lim`` - maximum denominator. + + + OUTPUT: Results are (numerator, denominator); (1, 0) is "infinity". + + EXAMPLES:: + + sage: farey(2.0, 100) + doctest:...: DeprecationWarning: farey is deprecated. + See http://trac.sagemath.org/14567 for details. + (2, 1) + sage: farey(2.0, 1000) + (2, 1) + sage: farey(2.1, 1000) + (21, 10) + sage: farey(2.1, 100000) + (21, 10) + sage: farey(pi, 100000) + (312689, 99532) + + AUTHORS: + + - Scott David Daniels: Python Cookbook, 2nd Ed., Recipe 18.13 + """ + from sage.misc.superseded import deprecation + deprecation(14567, 'farey is deprecated.') + + v = float(v) + if v < 0: + n, d = farey(-v, lim) + return -n, d + z = lim - lim # Get a "0 of the right type" for denominator + lower, upper = (z, z+1), (z+1, z) + while True: + mediant = (lower[0] + upper[0]), (lower[1] + upper[1]) + if v * mediant[1] > mediant[0]: + if lim < mediant[1]: + return upper + lower = mediant + elif v * mediant[1] == mediant[0]: + if lim >= mediant[1]: + return mediant + if lower[1] < upper[1]: + return lower + return upper + else: + if lim < mediant[1]: + return lower + upper = mediant + + diff --git a/src/sage/rings/number_field/number_field_element_quadratic.pyx b/src/sage/rings/number_field/number_field_element_quadratic.pyx index 156db9d2333..941958e1f68 100644 --- a/src/sage/rings/number_field/number_field_element_quadratic.pyx +++ b/src/sage/rings/number_field/number_field_element_quadratic.pyx @@ -896,6 +896,68 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): return 1 return -1 + def continued_fraction_list(self): + r""" + Return the preperiod and the period of the continued fraction expansion + of ``self``. + + EXAMPLES:: + + sage: K. = QuadraticField(2) + sage: sqrt2.continued_fraction_list() + ((1,), (2,)) + sage: (1/2+sqrt2/3).continued_fraction_list() + ((0, 1, 33), (1, 32)) + + For rational entries a pair of tuples is also returned but the second + one is empty:: + + sage: K(123/567).continued_fraction_list() + ((0, 4, 1, 1, 1, 1, 3, 2), ()) + """ + cdef NumberFieldElement_quadratic x + + if mpz_sgn(self.b) == 0: + return tuple(Rational(self).continued_fraction_list()),() + + if mpz_sgn(self.D.value) < 0: + raise ValueError("the method is only available for positive discriminant") + + x = self + orbit = [] + quots = [] + while x not in orbit: + quots.append(x.floor()) + orbit.append(x) + x = ~(x - quots[-1]) + + i = orbit.index(x) + + return tuple(quots[:i]), tuple(quots[i:]) + + def continued_fraction(self): + r""" + Return the (finite or ultimately periodic) continued fraction of ``self``. + + EXAMPLES:: + + sage: K. = QuadraticField(2) + sage: cf = sqrt2.continued_fraction(); cf + [1; (2)*] + sage: cf.n() + 1.41421356237310 + sage: sqrt2.n() + 1.41421356237310 + sage: cf.value() + sqrt2 + + sage: (sqrt2/3 + 1/4).continued_fraction() + [0; 1, (2, 1, 1, 2, 3, 2, 1, 1, 2, 5, 1, 1, 14, 1, 1, 5)*] + """ + t1,t2 = self.continued_fraction_list() + from sage.rings.continued_fraction import ContinuedFraction_periodic + return ContinuedFraction_periodic(t1,t2) + ######################################################### # Arithmetic ######################################################### diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index d4e65c8e58b..b31935e6397 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -24,6 +24,8 @@ AUTHORS: - Travis Scrimshaw (2012-10-18): Added doctests for full coverage. +- Vincent Delecroix (2013): continued fraction + TESTS:: sage: a = -2/3 @@ -575,6 +577,125 @@ cdef class Rational(sage.structure.element.FieldElement): """ return [ self ] + def continued_fraction_list(self, type="std"): + r""" + Return the list of partial quotients of this rational number. + + INPUT: + + - ``type`` - either "std" (the default) for the standard continued + fractions or "hj" for the Hirzebruch-Jung ones. + + EXAMPLES:: + + sage: (13/9).continued_fraction_list() + [1, 2, 4] + sage: 1 + 1/(2 + 1/4) + 13/9 + + sage: (225/157).continued_fraction_list() + [1, 2, 3, 4, 5] + sage: 1 + 1/(2 + 1/(3 + 1/(4 + 1/5))) + 225/157 + + sage: (fibonacci(20)/fibonacci(19)).continued_fraction_list() + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2] + + sage: (-1/3).continued_fraction_list() + [-1, 1, 2] + + Check that the partial quotients of an integer ``n`` is simply ``[n]``:: + + sage: QQ(1).continued_fraction_list() + [1] + sage: QQ(0).continued_fraction_list() + [0] + sage: QQ(-1).continued_fraction_list() + [-1] + + Hirzebruch-Jung continued fractions:: + + sage: (11/19).continued_fraction_list("hj") + [1, 3, 2, 3, 2] + sage: 1 - 1/(3 - 1/(2 - 1/(3 - 1/2))) + 11/19 + + sage: (225/137).continued_fraction_list("hj") + [2, 3, 5, 10] + sage: 2 - 1/(3 - 1/(5 - 1/10)) + 225/137 + + sage: (-23/19).continued_fraction_list("hj") + [-1, 5, 4] + sage: -1 - 1/(5 - 1/4) + -23/19 + """ + cdef Integer z + cdef mpz_t p,q,tmp + cdef list res = [] + + mpz_init(tmp) + mpz_init(p) + mpz_init(q) + mpz_set(p, mpq_numref(self.value)) + mpz_set(q, mpq_denref(self.value)) + + if type == "std": + while mpz_sgn(q) != 0: + z = PY_NEW(Integer) + mpz_fdiv_qr(z.value,tmp,p,q) + mpz_set(p,q) + mpz_set(q,tmp) + res.append(z) + elif type == "hj": + while mpz_sgn(q) != 0: + z = PY_NEW(Integer) + mpz_cdiv_qr(z.value,tmp,p,q) + mpz_set(p,q) + mpz_set(q,tmp) + res.append(z) + if mpz_sgn(q) == 0: + break + z = PY_NEW(Integer) + mpz_fdiv_qr(z.value,tmp,p,q) + mpz_set(p,q) + mpz_set(q,tmp) + mpz_neg(z.value,z.value) + res.append(z) + else: + mpz_clear(p) + mpz_clear(q) + mpz_clear(tmp) + raise ValueError("the type must be one of 'floor', 'hj'") + + mpz_clear(p) + mpz_clear(q) + mpz_clear(tmp) + + return res + + def continued_fraction(self): + r""" + Return the continued fraction of that rational. + + EXAMPLES:: + + sage: (641/472).continued_fraction() + [1; 2, 1, 3, 1, 4, 1, 5] + + sage: a = (355/113).continued_fraction(); a + [3; 7, 16] + sage: a.n(digits=10) + 3.141592920 + sage: pi.n(digits=10) + 3.141592654 + + It's almost pi! + """ + #TODO: do better + from sage.rings.continued_fraction import ContinuedFraction_periodic + l = self.continued_fraction_list() + return ContinuedFraction_periodic(l) def __richcmp__(left, right, int op): """ diff --git a/src/sage/tests/book_stein_ent.py b/src/sage/tests/book_stein_ent.py index 41d3e10e846..b933092410f 100644 --- a/src/sage/tests/book_stein_ent.py +++ b/src/sage/tests/book_stein_ent.py @@ -389,46 +389,42 @@ 86 # Several of the examples below had to be changed due to improved -# behavior of the continued_fraction function #8017. +# behavior of the continued_fraction function #8017 and #14567. sage: continued_fraction(17/23) -[0, 1, 2, 1, 5] +[0; 1, 2, 1, 5] sage: reset('e') sage: continued_fraction(e) -[2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1] -sage: continued_fraction(e, bits=21) +[2; 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1, ...] +sage: continued_fraction_list(e, bits=21) [2, 1, 2, 1, 1, 4, 1, 1, 6] -sage: continued_fraction(e, bits=30) +sage: continued_fraction_list(e, bits=30) [2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8] sage: a = continued_fraction(17/23); a -[0, 1, 2, 1, 5] +[0; 1, 2, 1, 5] sage: a.value() 17/23 sage: b = continued_fraction(6/23); b -[0, 3, 1, 5] -sage: a + b -[1] -sage: c = continued_fraction(pi,bits=35); c -[3, 7, 15, 1, 292, 1] -sage: c.convergents() -[3, 22/7, 333/106, 355/113, 103993/33102, 104348/33215] +[0; 3, 1, 5] sage: c = continued_fraction(pi); c -[3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14] -sage: for n in range(-1, len(c)): -... print c.pn(n)*c.qn(n-1) - c.qn(n)*c.pn(n-1), +[3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, ...] +sage: [c.convergent(i) for i in xrange(5)] +[3, 22/7, 333/106, 355/113, 103993/33102] +sage: for n in range(-1, 13): +... print c.p(n)*c.q(n-1) - c.q(n)*c.p(n-1), 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 -sage: for n in range(len(c)): -... print c.pn(n)*c.qn(n-2) - c.qn(n)*c.pn(n-2), +sage: for n in range(13): +... print c.p(n)*c.q(n-2) - c.q(n)*c.p(n-2), 3 -7 15 -1 292 -1 1 -1 2 -1 3 -1 14 sage: c = continued_fraction([1,2,3,4,5]) sage: c.convergents() [1, 3/2, 10/7, 43/30, 225/157] -sage: [c.pn(n) for n in range(len(c))] +sage: [c.p(n) for n in range(len(c))] [1, 3, 10, 43, 225] -sage: [c.qn(n) for n in range(len(c))] +sage: [c.q(n) for n in range(len(c))] [1, 2, 7, 30, 157] sage: c = continued_fraction([1,1,1,1,1,1,1,1]) -sage: v = [(i, c.pn(i)/c.qn(i)) for i in range(len(c))] +sage: v = [(i, c.p(i)/c.q(i)) for i in range(len(c))] sage: P = point(v, rgbcolor=(0,0,1), pointsize=40) sage: L = line(v, rgbcolor=(0.5,0.5,0.5)) sage: L2 = line([(0,c.value()),(len(c)-1,c.value())], \ @@ -438,18 +434,18 @@ ... x = (1 + sqrt(RealField(bits)(5))) / 2 ... return continued_fraction(x) sage: cf(10) -[1, 1, 1, 1, 1, 1, 1] +[1; 1, 1, 1, 1, 1, 1, 2] sage: cf(30) -[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] +[1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2] sage: cf(50) -[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2] sage: def cf_sqrt_d(d, bits): ... x = sqrt(RealField(bits)(d)) ... return continued_fraction(x) sage: cf_sqrt_d(389,50) -[19, 1, 2, 1, 1, 1, 1, 2, 1, 38, 1, 2, 1, 1, 1, 1, 2, 1, 38, 2] +[19; 1, 2, 1, 1, 1, 1, 2, 1, 38, 1, 2, 1, 1, 1, 1, 2, 1, 38] sage: cf_sqrt_d(389,100) -[19, 1, 2, 1, 1, 1, 1, 2, 1, 38, 1, 2, 1, 1, 1, 1, 2, 1, 38, 1, 2, 1, 1, 1, 1, 2, 1, 38, 1, 2, 1, 1, 1, 1, 2, 1, 38, 1, 2, 1, 1] +[19; 1, 2, 1, 1, 1, 1, 2, 1, 38, 1, 2, 1, 1, 1, 1, 2, 1, 38, 1, 2, 1, 1, 1, 1, 2, 1, 38, 1, 2, 1, 1, 1, 1, 2, 1, 38, 1, 2, 2] sage: def newton_root(f, iterates=2, x0=0, prec=53): ... x = RealField(prec)(x0) ... R = PolynomialRing(ZZ,'x') @@ -462,9 +458,9 @@ sage: a = newton_root(3847*x^2 - 14808904*x + 36527265); a 2.46815700480740 sage: cf = continued_fraction(a); cf -[2, 2, 7, 2, 1, 5, 1, 1, 1, 1, 1, 1, 103, 8, 1, 2, 3] +[2; 2, 7, 2, 1, 5, 1, 1, 1, 1, 1, 1, 103, 8, 1, 2, 3, 2] sage: c = cf[:12]; c -[2, 2, 7, 2, 1, 5, 1, 1, 1, 1, 1, 1] +[2; 2, 7, 2, 1, 5, 1, 1, 1, 1, 2] sage: c.value() 9495/3847 sage: def sum_of_two_squares_naive(n): diff --git a/src/sage/tests/book_stein_modform.py b/src/sage/tests/book_stein_modform.py index 6657aee1412..8969b2268c1 100644 --- a/src/sage/tests/book_stein_modform.py +++ b/src/sage/tests/book_stein_modform.py @@ -73,7 +73,7 @@ sage: S.integral_basis() # basis over ZZ. ({-1/8, 0}, {-1/9, 0}) sage: set_modsym_print_mode ('manin') # set it back -sage: convergents(4/7) +sage: continued_fraction(4/7).convergents() [0, 1, 1/2, 4/7] sage: M = ModularSymbols(2,2) sage: M From ff7add97f5fb868793643b725ba642bc24e15abe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Mon, 28 Apr 2014 11:11:39 +0200 Subject: [PATCH 018/698] Fixed cross references, add title to all.py files --- src/doc/en/reference/combinat/index.rst | 15 ------- src/sage/combinat/__init__.py | 3 +- src/sage/combinat/algebraic_combinatorics.py | 4 +- src/sage/combinat/all.py | 3 ++ .../combinat/cluster_algebra_quiver/all.py | 3 ++ src/sage/combinat/counting.py | 14 +++--- src/sage/combinat/crystals/all.py | 3 ++ src/sage/combinat/designs/__init__.py | 18 ++++---- src/sage/combinat/designs/all.py | 3 ++ src/sage/combinat/matrices/__init__.py | 3 ++ src/sage/combinat/matrices/all.py | 3 ++ src/sage/combinat/ncsf_qsym/all.py | 3 ++ src/sage/combinat/ncsym/all.py | 3 ++ src/sage/combinat/posets/__init__.py | 8 ++-- src/sage/combinat/posets/all.py | 3 ++ src/sage/combinat/quickref.py | 23 +++++----- .../combinat/rigged_configurations/all.py | 3 ++ src/sage/combinat/root_system/all.py | 3 ++ src/sage/combinat/sf/all.py | 7 ++- src/sage/combinat/species/__init__.py | 44 +++++++++---------- src/sage/combinat/species/all.py | 3 ++ src/sage/combinat/words/__init__.py | 4 +- src/sage/combinat/words/all.py | 3 ++ 23 files changed, 106 insertions(+), 73 deletions(-) diff --git a/src/doc/en/reference/combinat/index.rst b/src/doc/en/reference/combinat/index.rst index d2a3b397921..e2c2c7389a8 100644 --- a/src/doc/en/reference/combinat/index.rst +++ b/src/doc/en/reference/combinat/index.rst @@ -3,23 +3,8 @@ Combinatorics .. automodule:: sage.combinat -<<<<<<< HEAD .. toctree:: :maxdepth: 1 -======= - sage/combinat/kazhdan_lusztig - sage/combinat/knutson_tao_puzzles - - crystals - posets - rigged_configurations - designs - species - developer - sage/combinat/finite_state_machine - sage/combinat/finite_state_machine_generators - words ->>>>>>> develop module_list diff --git a/src/sage/combinat/__init__.py b/src/sage/combinat/__init__.py index f1df4876300..59516f03836 100644 --- a/src/sage/combinat/__init__.py +++ b/src/sage/combinat/__init__.py @@ -15,6 +15,7 @@ - :ref:`sage.combinat.enumerated_sets` - :ref:`sage.combinat.catalog_partitions` - :ref:`sage.combinat.species` +- :ref:`sage.combinat.designs` - :ref:`sage.combinat.algebraic_combinatorics` - :ref:`sage.combinat.posets` - :ref:`sage.combinat.words` @@ -24,7 +25,7 @@ .. TODO:: point instead to the main entry point for graphs -- :class:`Graph`, :class:`DiGraph`, :obj:`graphs`, :obj:`digraphs` +- :class:`Graph`, :class:`DiGraph`, :obj:`graphs `, :obj:`digraphs ` Dynamical systems ----------------- diff --git a/src/sage/combinat/algebraic_combinatorics.py b/src/sage/combinat/algebraic_combinatorics.py index fb2d1cd6706..fb05d23c7ec 100644 --- a/src/sage/combinat/algebraic_combinatorics.py +++ b/src/sage/combinat/algebraic_combinatorics.py @@ -34,7 +34,9 @@ Groups and Algebras ------------------- -- :obj:`groups`, :obj:`algebras` +.. TODO:: add link to the catalog of algebras when it exists + +- :ref:`groups ` - :class:`SymmetricGroup`, :class:`CoxeterGroup`, :class:`WeylGroup` - :class:`sage.combinat.diagram_algebras.PartitionAlgebra` - :class:`sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra` diff --git a/src/sage/combinat/all.py b/src/sage/combinat/all.py index 21f3ae52e9f..4293c73b305 100644 --- a/src/sage/combinat/all.py +++ b/src/sage/combinat/all.py @@ -1,3 +1,6 @@ +""" +Combinatorics features that are imported by default in the interpreter namespace +""" from combinat import bell_number, catalan_number, euler_number, fibonacci, \ lucas_number1, lucas_number2, stirling_number1, stirling_number2, \ CombinatorialObject, CombinatorialClass, FilteredCombinatorialClass, \ diff --git a/src/sage/combinat/cluster_algebra_quiver/all.py b/src/sage/combinat/cluster_algebra_quiver/all.py index 31fc8e6253b..44060e2b3cb 100644 --- a/src/sage/combinat/cluster_algebra_quiver/all.py +++ b/src/sage/combinat/cluster_algebra_quiver/all.py @@ -1,3 +1,6 @@ +""" +Cluster algebra and quivers features that are imported by default in the interpreter namespace +""" from sage.misc.lazy_import import lazy_import lazy_import("sage.combinat.cluster_algebra_quiver.quiver_mutation_type", "QuiverMutationType") lazy_import("sage.combinat.cluster_algebra_quiver.quiver", "ClusterQuiver") diff --git a/src/sage/combinat/counting.py b/src/sage/combinat/counting.py index cfcbad13716..7773e78c0e9 100644 --- a/src/sage/combinat/counting.py +++ b/src/sage/combinat/counting.py @@ -2,11 +2,11 @@ Counting ======== - :mod:`sage/databases/oeis` - :mod:`sage/combinat/sloane_functions` - :mod:`sage/combinat/expnums` - :mod:`sage/combinat/q_analogues` - :mod:`sage/combinat/q_bernoulli` - :mod:`sage/combinat/binary_recurrence_sequences` - :mod:`sage/combinat/combinat` +- :ref:`sage.databases.oeis` +- :ref:`sage.combinat.sloane_functions` +- :ref:`sage.combinat.expnums` +- :ref:`sage.combinat.q_analogues` +- :ref:`sage.combinat.q_bernoulli` +- :ref:`sage.combinat.binary_recurrence_sequences` +- :ref:`sage.combinat.combinat` """ diff --git a/src/sage/combinat/crystals/all.py b/src/sage/combinat/crystals/all.py index eb4c093d8be..a644325a7e0 100644 --- a/src/sage/combinat/crystals/all.py +++ b/src/sage/combinat/crystals/all.py @@ -1,3 +1,6 @@ +""" +Crystal features that are imported by default in the interpreter namespace +""" import catalog as crystals from sage.misc.lazy_import import lazy_import diff --git a/src/sage/combinat/designs/__init__.py b/src/sage/combinat/designs/__init__.py index a8d677a6803..5386be74d3c 100644 --- a/src/sage/combinat/designs/__init__.py +++ b/src/sage/combinat/designs/__init__.py @@ -4,17 +4,17 @@ .. TODO:: Proofread / point to the main classes rather than the modules? -- :mod:`sage.combinat.designs.covering_design` -- :mod:`sage.combinat.designs.ext_rep` -- :mod:`sage.combinat.designs.incidence_structures` -- :mod:`sage.combinat.designs.design_catalog` +- :ref:`sage.combinat.designs.covering_design` +- :ref:`sage.combinat.designs.ext_rep` +- :ref:`sage.combinat.designs.incidence_structures` +- :ref:`sage.combinat.designs.design_catalog` Constructions ------------- -- :mod:`sage.combinat.designs.block_design` -- :mod:`sage.combinat.designs.bibd` -- :mod:`sage.combinat.designs.steiner_quadruple_systems` -- :mod:`sage.combinat.designs.latin_squares` -- :mod:`sage.combinat.designs.orthogonal_arrays` +- :ref:`sage.combinat.designs.block_design` +- :ref:`sage.combinat.designs.bibd` +- :ref:`sage.combinat.designs.steiner_quadruple_systems` +- :ref:`sage.combinat.designs.latin_squares` +- :ref:`sage.combinat.designs.orthogonal_arrays` """ diff --git a/src/sage/combinat/designs/all.py b/src/sage/combinat/designs/all.py index c6a04de444d..c738892c295 100644 --- a/src/sage/combinat/designs/all.py +++ b/src/sage/combinat/designs/all.py @@ -1,3 +1,6 @@ +""" +Combinatorial design features that are imported by default in the interpreter namespace +""" from block_design import (BlockDesign) from ext_rep import (designs_from_XML, designs_from_XML_url) diff --git a/src/sage/combinat/matrices/__init__.py b/src/sage/combinat/matrices/__init__.py index c9fecacd721..366b73d9231 100644 --- a/src/sage/combinat/matrices/__init__.py +++ b/src/sage/combinat/matrices/__init__.py @@ -1 +1,4 @@ +r""" +Combinatorics on matrices +""" import all diff --git a/src/sage/combinat/matrices/all.py b/src/sage/combinat/matrices/all.py index 84407df0159..bfbd88c7738 100644 --- a/src/sage/combinat/matrices/all.py +++ b/src/sage/combinat/matrices/all.py @@ -1,3 +1,6 @@ +r""" +Combinatorics on matrix features that are imported by default in the interpreter namespace +""" from latin import LatinSquare, LatinSquare_generator from dlxcpp import DLXCPP from dancing_links import make_dlxwrapper diff --git a/src/sage/combinat/ncsf_qsym/all.py b/src/sage/combinat/ncsf_qsym/all.py index 83c5e5b8524..835a4624e2f 100644 --- a/src/sage/combinat/ncsf_qsym/all.py +++ b/src/sage/combinat/ncsf_qsym/all.py @@ -1,2 +1,5 @@ +r""" +Features that are imported by default in the interpreter namespace +""" from qsym import QuasiSymmetricFunctions from ncsf import NonCommutativeSymmetricFunctions diff --git a/src/sage/combinat/ncsym/all.py b/src/sage/combinat/ncsym/all.py index c3bcfed76d8..e4bd21e1839 100644 --- a/src/sage/combinat/ncsym/all.py +++ b/src/sage/combinat/ncsym/all.py @@ -1,3 +1,6 @@ +""" +Features that are imported by default in the interpreter namespace +""" from ncsym import SymmetricFunctionsNonCommutingVariables from dual import SymmetricFunctionsNonCommutingVariablesDual diff --git a/src/sage/combinat/posets/__init__.py b/src/sage/combinat/posets/__init__.py index 40777857262..2a348d108b8 100644 --- a/src/sage/combinat/posets/__init__.py +++ b/src/sage/combinat/posets/__init__.py @@ -2,11 +2,11 @@ Posets ====== -- :mod:`sage.combinat.posets` -- :func:`Poset`, :func:`MeetSemiLattice`, :func:`JoinSemiLattice`, :func:`LatticePoset` -- :class:`sage.categories.posets.Posets`, :class:`sage.categories.lattices.Lattices` +- :ref:`sage.combinat.posets.posets` +- :func:`Poset`, :func:`MeetSemilattice`, :func:`JoinSemilattice`, :func:`LatticePoset` +- :class:`sage.categories.posets.Posets`, :class:`sage.categories.lattice_posets.LatticePosets` - :obj:`Posets` -- :func:`TamariLattice` +- :ref:`sage.combinat.tamari_lattices` - :class:`sage.combinat.posets.linear_extensions.LinearExtensionOfPoset`, :class:`sage.combinat.posets.linear_extensions.LinearExtensionsOfPoset` """ diff --git a/src/sage/combinat/posets/all.py b/src/sage/combinat/posets/all.py index 545c68dd4fc..673095e7c19 100644 --- a/src/sage/combinat/posets/all.py +++ b/src/sage/combinat/posets/all.py @@ -1,3 +1,6 @@ +r""" +Poset features that are imported by default in the interpreter namespace +""" from posets import Poset from lattices import LatticePoset diff --git a/src/sage/combinat/quickref.py b/src/sage/combinat/quickref.py index 258d795fe82..efb9a2a4873 100644 --- a/src/sage/combinat/quickref.py +++ b/src/sage/combinat/quickref.py @@ -4,7 +4,7 @@ Integer Sequences:: - sage: oeis([1,3,19,211]) + sage: s = oeis([1,3,19,211]); s 0: A000275: Coefficients of a Bessel function (reciprocal of J_0(z)); also pairs of permutations with rise/rise forbidden. sage: s.programs() 0: (PARI) a(n)=if(n<0,0,n!^2*4^n*polcoeff(1/besselj(0,x+x*O(x^(2*n))),2*n)) /* Michael Somos May 17 2004 */ @@ -22,24 +22,27 @@ Words:: - sage: W=Words('abc') + sage: Words('abc') sage: Word('aabca').some_flashy_feature() Polytopes:: - sage: L = LatticePolytope(random_matrix(ZZ, 3,6, x=7)) + sage: points = random_matrix(ZZ, 6, 3, x=7).rows() + sage: L = LatticePolytope(points) sage: L.npoints(); L.plot3d() -Root systems, Coxeter and Weyl groups (:mod:`sage.combinat.root_system`):: +:ref:`Root systems, Coxeter and Weyl groups `:: -Crystals (:mod:`sage.combinat.crystals`):: + sage: CoxeterGroup(["B",3]).some_flashy_feature() - sage: CrystalOfTableaux(["A",3], shape = [3,2]) +:ref:`Crystals `:: -Symmetric functions and combinatorial Hopf algebras (:mod:`sage.combinat.algebraic_combinatorics`):: + sage: CrystalOfTableaux(["A",3], shape = [3,2]).some_flashy_feature() + +:mod:`Symmetric functions and combinatorial Hopf algebras `:: sage: Sym = SymmetricFunctions(QQ); Sym.inject_shorthands() - sage: s[3] * h[2] ... + sage: m( ( h[2,1] * (1 + 3 * p[2,1]) ) + s[2](s[3]) ) Discrete groups, Permutation groups (:mod:`sage.groups`):: @@ -47,7 +50,7 @@ sage: M = MultivariatePolynomials('x0,x1,x2,x3') sage: M(...).action??? S. -Graph theory, posets, lattices (:class:`Graph`, :class:`Digraph`, :mod:`sage.combinat.posets`):: +Graph theory, posets, lattices (:class:`Graph`, :class:`DiGraph`, :mod:`sage.combinat.posets`):: - sage: Poset({1: [2,3], 2: [4], 3: [4]}).some_snappy_feature() + sage: Poset({1: [2,3], 2: [4], 3: [4]}).some_flashy_feature() """ diff --git a/src/sage/combinat/rigged_configurations/all.py b/src/sage/combinat/rigged_configurations/all.py index a8c1facb606..ee4b3ad6fa8 100644 --- a/src/sage/combinat/rigged_configurations/all.py +++ b/src/sage/combinat/rigged_configurations/all.py @@ -1,3 +1,6 @@ +r""" +Features that are imported by default in the interpreter namespace +""" from rigged_configurations import RiggedConfigurations # Deprecated classes diff --git a/src/sage/combinat/root_system/all.py b/src/sage/combinat/root_system/all.py index 17e0277841b..4c3b331342f 100644 --- a/src/sage/combinat/root_system/all.py +++ b/src/sage/combinat/root_system/all.py @@ -1,3 +1,6 @@ +r""" +Root system features that are imported by default in the interpreter namespace +""" from sage.misc.lazy_import import lazy_import lazy_import('sage.combinat.root_system.associahedron', 'Associahedron') diff --git a/src/sage/combinat/sf/all.py b/src/sage/combinat/sf/all.py index c7c11c81ebe..d382806733e 100644 --- a/src/sage/combinat/sf/all.py +++ b/src/sage/combinat/sf/all.py @@ -1,7 +1,10 @@ -# In the long run, this will be the single entry point -# Nothing else will be exported +r""" +Symmetric function features that are imported by default in the interpreter namespace +""" from sage.misc.lazy_import import lazy_import +# In the long run, this will be the single entry point +# Nothing else will be exported from sf import SymmetricFunctions # This is deprecated: diff --git a/src/sage/combinat/species/__init__.py b/src/sage/combinat/species/__init__.py index be08cb20da1..36e2c2d5a5e 100644 --- a/src/sage/combinat/species/__init__.py +++ b/src/sage/combinat/species/__init__.py @@ -15,40 +15,40 @@ Lazy Power Series ----------------- -- :mod:`sage/combinat/species/stream` -- :mod:`sage/combinat/species/series_order` -- :mod:`sage/combinat/species/series` -- :mod:`sage/combinat/species/generating_series` +- :ref:`sage.combinat.species.stream` +- :ref:`sage.combinat.species.series_order` +- :ref:`sage.combinat.species.series` +- :ref:`sage.combinat.species.generating_series` Basic Species ------------- -- :mod:`sage/combinat/species/species` -- :mod:`sage/combinat/species/empty_species` -- :mod:`sage/combinat/species/recursive_species` -- :mod:`sage/combinat/species/characteristic_species` -- :mod:`sage/combinat/species/cycle_species` -- :mod:`sage/combinat/species/partition_species` -- :mod:`sage/combinat/species/permutation_species` -- :mod:`sage/combinat/species/linear_order_species` -- :mod:`sage/combinat/species/set_species` -- :mod:`sage/combinat/species/subset_species` -- :mod:`sage/combinat/species/library` +- :ref:`sage.combinat.species.species` +- :ref:`sage.combinat.species.empty_species` +- :ref:`sage.combinat.species.recursive_species` +- :ref:`sage.combinat.species.characteristic_species` +- :ref:`sage.combinat.species.cycle_species` +- :ref:`sage.combinat.species.partition_species` +- :ref:`sage.combinat.species.permutation_species` +- :ref:`sage.combinat.species.linear_order_species` +- :ref:`sage.combinat.species.set_species` +- :ref:`sage.combinat.species.subset_species` +- :ref:`sage.combinat.species.library` Operations on Species --------------------- -- :mod:`sage/combinat/species/sum_species` -- :mod:`sage/combinat/species/product_species` -- :mod:`sage/combinat/species/composition_species` -- :mod:`sage/combinat/species/functorial_composition_species` +- :ref:`sage.combinat.species.sum_species` +- :ref:`sage.combinat.species.product_species` +- :ref:`sage.combinat.species.composition_species` +- :ref:`sage.combinat.species.functorial_composition_species` Miscellaneous ------------- -- :mod:`sage/combinat/species/structure` -- :mod:`sage/combinat/species/misc` -- :mod:`sage/combinat/species/combinatorial_logarithm` +- :ref:`sage.combinat.species.structure` +- :ref:`sage.combinat.species.misc` +- :ref:`sage.combinat.species.combinatorial_logarithm` """ import all diff --git a/src/sage/combinat/species/all.py b/src/sage/combinat/species/all.py index 7ead1cce8b7..a8de646c206 100644 --- a/src/sage/combinat/species/all.py +++ b/src/sage/combinat/species/all.py @@ -1,3 +1,6 @@ +r""" +Combinatorial species features that are imported by default in the interpreter namespace +""" from series import LazyPowerSeriesRing from recursive_species import CombinatorialSpecies import library as species diff --git a/src/sage/combinat/words/__init__.py b/src/sage/combinat/words/__init__.py index ab290aad8c6..03c960588b6 100644 --- a/src/sage/combinat/words/__init__.py +++ b/src/sage/combinat/words/__init__.py @@ -8,8 +8,8 @@ - Add links from the module documentation to the important classes/functions - :func:`sage.combinat.words.alphabet.build_alphabet` -- :func:`sage.combinat.word.Word` -- :func:`sage.combinat.words.Words` +- :func:`sage.combinat.words.word.Word` +- :func:`sage.combinat.words.words.Words` - :ref:`sage.combinat.words.word_generators` - :class:`sage.combinat.words.shuffle_product.ShuffleProduct`, :class:`sage.combinat.words.shuffle_product.ShuffleProduct` ??? - :ref:`sage.combinat.words.suffix_trees` diff --git a/src/sage/combinat/words/all.py b/src/sage/combinat/words/all.py index 119377da22e..f53f3619013 100644 --- a/src/sage/combinat/words/all.py +++ b/src/sage/combinat/words/all.py @@ -1,3 +1,6 @@ +r""" +Word features that are imported by default in the interpreter namespace +""" from alphabet import Alphabet, build_alphabet from morphism import WordMorphism from paths import WordPaths From d3284073bb560acb669287ef1c7208e8b384cbdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Mon, 28 Apr 2014 15:17:19 +0200 Subject: [PATCH 019/698] Trac 16256: fixed some cross references and doc compilation issues --- src/doc/en/reference/combinat/module_list.rst | 3 --- src/sage/combinat/__init__.py | 2 +- src/sage/combinat/algebraic_combinatorics.py | 2 +- src/sage/combinat/quickref.py | 2 +- src/sage/combinat/root_system/cartan_type.py | 11 +++++------ 5 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/doc/en/reference/combinat/module_list.rst b/src/doc/en/reference/combinat/module_list.rst index 9ef704aef74..e90a0957270 100644 --- a/src/doc/en/reference/combinat/module_list.rst +++ b/src/doc/en/reference/combinat/module_list.rst @@ -303,6 +303,3 @@ Alphabetical module list sage/combinat/words/word sage/combinat/words/words sage/combinat/yang_baxter_graph - - -.. include:: ../footer.txt diff --git a/src/sage/combinat/__init__.py b/src/sage/combinat/__init__.py index 066901dfe6e..df039ae109e 100644 --- a/src/sage/combinat/__init__.py +++ b/src/sage/combinat/__init__.py @@ -25,7 +25,7 @@ Graphs ------ -.. TODO:: point instead to the main entry point for graphs +.. TODO:: are those the best entry points for graphs? - :class:`Graph`, :class:`DiGraph`, :obj:`graphs `, :obj:`digraphs ` diff --git a/src/sage/combinat/algebraic_combinatorics.py b/src/sage/combinat/algebraic_combinatorics.py index 61877838270..f4234521611 100644 --- a/src/sage/combinat/algebraic_combinatorics.py +++ b/src/sage/combinat/algebraic_combinatorics.py @@ -36,7 +36,7 @@ .. TODO:: add link to the catalog of algebras when it exists -- :ref:`groups ` +- :ref:`Groups ` - :class:`SymmetricGroup`, :class:`CoxeterGroup`, :class:`WeylGroup` - :class:`sage.combinat.diagram_algebras.PartitionAlgebra` - :class:`sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra` diff --git a/src/sage/combinat/quickref.py b/src/sage/combinat/quickref.py index ce11a6c59b0..87803f4c024 100644 --- a/src/sage/combinat/quickref.py +++ b/src/sage/combinat/quickref.py @@ -44,7 +44,7 @@ sage: Sym = SymmetricFunctions(QQ); Sym.inject_shorthands() sage: m( ( h[2,1] * (1 + 3 * p[2,1]) ) + s[2](s[3]) ) -:ref:`Discrete groups, Permutation groups `:: +:ref:`Discrete groups, Permutation groups `:: sage: S = SymmetricGroup(4) sage: M = MultivariatePolynomials('x0,x1,x2,x3') diff --git a/src/sage/combinat/root_system/cartan_type.py b/src/sage/combinat/root_system/cartan_type.py index b986cc4f57b..7b9bb85e9b7 100644 --- a/src/sage/combinat/root_system/cartan_type.py +++ b/src/sage/combinat/root_system/cartan_type.py @@ -1,10 +1,11 @@ r""" Cartan types -.. contents:: +.. TODO:: + + Why does sphinx complain if I use sections here? Introduction ------------- Loosely speaking, Dynkin diagrams (or equivalently Cartan matrices) are graphs which are used to classify root systems, Coxeter and Weyl @@ -391,9 +392,9 @@ E6^2 sage: CartanType.global_options['notation'] = 'BC' +.. TODO:: Should those indexes come before the introduction? Abstract classes for cartan types ---------------------------------- - :class:`CartanType_abstract` - :class:`CartanType_crystallographic` @@ -401,19 +402,17 @@ - :class:`CartanType_simple` - :class:`CartanType_finite` - :class:`CartanType_affine` (see also :ref:`sage.combinat.root_system.type_affine`) -- :ref:`sage.combinat.root_system.cartan_type.CartanType` +- :obj:`sage.combinat.root_system.cartan_type.CartanType` - :ref:`sage.combinat.root_system.type_dual` - :ref:`sage.combinat.root_system.type_reducible` - :ref:`sage.combinat.root_system.type_relabel` Concrete classes for cartan types ---------------------------------- - :class:`CartanType_standard_affine` - :class:`CartanType_standard_untwisted_affine` Type specific data ------------------- The data essentially consists of a description of the Dynkin/Coxeter diagram and, when relevant, of the natural embedding of the root From 0e48aa939db26a4f51ea831dc9c542e9fe0c5feb Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Tue, 22 Apr 2014 23:35:04 +0100 Subject: [PATCH 020/698] make DefaultConvertMap a morphism in SetsWithPartialMaps() --- src/sage/structure/coerce_maps.pyx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/structure/coerce_maps.pyx b/src/sage/structure/coerce_maps.pyx index 4598b717a7a..6591c94b191 100644 --- a/src/sage/structure/coerce_maps.pyx +++ b/src/sage/structure/coerce_maps.pyx @@ -24,7 +24,9 @@ cdef class DefaultConvertMap(Map): def __init__(self, domain, codomain, force_use=False): if not PY_TYPE_CHECK(domain, Parent): domain = Set_PythonType(domain) - Map.__init__(self, domain, codomain) + from sage.categories.sets_with_partial_maps import SetsWithPartialMaps + parent = domain.Hom(codomain, category=SetsWithPartialMaps()) + Map.__init__(self, parent) self._coerce_cost = 100 self._force_use = force_use if (codomain)._element_constructor is None: From d92ec909915dd2014000c5dc0c3828320aad557d Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Fri, 9 May 2014 01:07:46 +0100 Subject: [PATCH 021/698] add Map._category_for and Map._set_parent() --- src/sage/categories/map.pxd | 1 + src/sage/categories/map.pyx | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/sage/categories/map.pxd b/src/sage/categories/map.pxd index bd4fb61f7a0..907c9c6bacd 100644 --- a/src/sage/categories/map.pxd +++ b/src/sage/categories/map.pxd @@ -15,6 +15,7 @@ cdef class Map(Element): cdef public domain # will be either a weakref or a constant map cdef public codomain # will be a constant map cdef Parent _codomain # for accessing the codomain directly + cdef object _category_for # category in which this is a morphism cdef public _repr_type_str diff --git a/src/sage/categories/map.pyx b/src/sage/categories/map.pyx index 59161366e62..4e3591ad0ae 100644 --- a/src/sage/categories/map.pyx +++ b/src/sage/categories/map.pyx @@ -129,6 +129,7 @@ cdef class Map(Element): Element.__init__(self, parent) D = parent.domain() C = parent.codomain() + self._category_for = parent.homset_category() self._codomain = C self.domain = ConstantFunction(D) self.codomain = ConstantFunction(C) @@ -137,6 +138,10 @@ cdef class Map(Element): else: self._coerce_cost = 10000 # inexact morphisms are bad. + def _set_parent(self, parent): + super(Map, self)._set_parent(parent) + self._category_for = parent.homset_category() + def __copy__(self): """ Return copy, with strong references to domain and codomain. @@ -176,7 +181,7 @@ cdef class Map(Element): cdef Map out = Element.__copy__(self) # Element.__copy__ updates the __dict__, but not the slots. # Let's do this now, but with strong references. - out._parent = self.parent() # self._parent might be None + out._set_parent(self.parent()) # self._parent might be None out._update_slots(self._extra_slots({})) return out @@ -229,7 +234,7 @@ cdef class Map(Element): C = self._codomain if C is None or D is None: raise ValueError("This map is in an invalid state, the domain has been garbage collected") - return homset.Hom(D, C) + return homset.Hom(D, C, self._category_for) return self._parent def _make_weak_references(self): @@ -361,7 +366,7 @@ cdef class Map(Element): if D is None or C is None: raise RuntimeError("The domain of this map became garbage collected") self.domain = ConstantFunction(D) - self._parent = homset.Hom(D, C) + self._parent = homset.Hom(D, C, self._category_for) cdef _update_slots(self, dict _slots): """ @@ -615,7 +620,7 @@ cdef class Map(Element): FIXME: find a better name for this method """ - return self.parent().homset_category() + return self._category_for def __call__(self, x, *args, **kwds): """ From d0e43bc8bedb2ea6877001c49abb4a56a6b1e145 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Fri, 9 May 2014 11:59:03 +0100 Subject: [PATCH 022/698] Trac 15618: fix category of the Q_to_Z morphism --- src/sage/rings/rational.pyx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index d4e65c8e58b..1233c0744f5 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -3766,7 +3766,8 @@ cdef class Z_to_Q(Morphism): From: Rational Field To: Integer Ring """ - return Q_to_Z(self._codomain, self.domain()) + from sage.categories.sets_with_partial_maps import SetsWithPartialMaps + return Q_to_Z(self._codomain.Hom(self.domain(), category=SetsWithPartialMaps())) cdef class Q_to_Z(Map): r""" From d96f19ef8b9b418ed974d130de22f73e7e7979e0 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Fri, 9 May 2014 20:31:03 +0100 Subject: [PATCH 023/698] Trac 15618: do not change category in FiniteDimensionalAlgebra._Hom_() --- .../finite_dimensional_algebras/finite_dimensional_algebra.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py index 9acc8cba623..f49f221b8a8 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py @@ -169,8 +169,7 @@ def _Hom_(self, B, category): sage: A._Hom_(B, A.category()) Set of Homomorphisms from Finite-dimensional algebra of degree 1 over Rational Field to Finite-dimensional algebra of degree 2 over Rational Field """ - if isinstance(B, FiniteDimensionalAlgebra): - category = FiniteDimensionalAlgebrasWithBasis(self.base_ring()).or_subcategory(category) + if category.is_subcategory(FiniteDimensionalAlgebrasWithBasis(self.base_ring())): from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra_morphism import FiniteDimensionalAlgebraHomset return FiniteDimensionalAlgebraHomset(self, B, category=category) return super(FiniteDimensionalAlgebra, self)._Hom_(B, category) From da8a52b074d80e5de286e9923fbdb780e14ce347 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Wed, 14 May 2014 16:12:14 +0200 Subject: [PATCH 024/698] trac #14567: fix code in words, plot and rational Several part of Sage use continued fraction. Because of the changes, some of it had to be adapted. --- src/sage/combinat/words/word_generators.py | 17 ++++++++++++----- src/sage/plot/misc.py | 3 ++- src/sage/rings/rational.pyx | 6 +++--- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index e1c283b2968..3f971e19939 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -838,9 +838,11 @@ def CharacteristicSturmianWord(self, slope, alphabet=(0, 1), bits=None): :: sage: words.CharacteristicSturmianWord(1/golden_ratio^2, bits=30) + doctest:...: DeprecationWarning: the argument 'bits' is deprecated + See http://trac.sagemath.org/14567 for details. word: 0100101001001010010100100101001001010010... sage: _.length() - 6765 + +Infinity :: @@ -867,14 +869,19 @@ def CharacteristicSturmianWord(self, slope, alphabet=(0, 1), bits=None): sage: u[1:-1] == v[:-2] True """ + if bits is not None: + from sage.misc.superseded import deprecation + deprecation(14567, "the argument 'bits' is deprecated") + if len(set(alphabet)) != 2: raise TypeError("alphabet does not contain two distinct elements") + if slope in RR: if not 0 < slope < 1: msg = "The argument slope (=%s) must be in ]0,1[."%slope raise ValueError(msg) - from sage.rings.all import CFF - cf = CFF(slope, bits=bits) + from sage.rings.continued_fraction import continued_fraction + cf = continued_fraction(slope) if cf.length() == Infinity: length = Infinity else: @@ -916,7 +923,7 @@ def _CharacteristicSturmianWord_LetterIterator(self, cf, alphabet=(0,1)): EXAMPLES:: - sage: CFF(1/golden_ratio^2)[:8] + sage: continued_fraction(1/golden_ratio^2)[:8] [0; 2, 1, 1, 1, 1, 2] sage: cf = iter(_) sage: Word(words._CharacteristicSturmianWord_LetterIterator(cf)) @@ -925,7 +932,7 @@ def _CharacteristicSturmianWord_LetterIterator(self, cf, alphabet=(0,1)): :: sage: alpha = (sqrt(3)-1)/2 - sage: CFF(alpha)[:10] + sage: continued_fraction(alpha)[:10] [0; 2, 1, 2, 1, 2, 1, 2, 1, 2] sage: cf = iter(_) sage: Word(words._CharacteristicSturmianWord_LetterIterator(cf)) diff --git a/src/sage/plot/misc.py b/src/sage/plot/misc.py index 0c4dbd56bf6..9671dcd1d99 100644 --- a/src/sage/plot/misc.py +++ b/src/sage/plot/misc.py @@ -234,9 +234,10 @@ def _multiple_of_constant(n,pos,const): """ from sage.misc.latex import latex from sage.rings.continued_fraction import continued_fraction + from sage.rings.infinity import Infinity cf = continued_fraction(n/const) k = 1 - while cf.quotient(k) and cf.denominator(k) < 12: + while cf.quotient(k) != Infinity and cf.denominator(k) < 12: k += 1 return '$%s$'%latex(cf.convergent(k-1)*const) diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index b31935e6397..9f863934f44 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -2087,15 +2087,15 @@ cdef class Rational(sage.structure.element.FieldElement): Test larger rationals:: - sage: Q = continued_fraction(pi, bits=3000).convergents() - sage: all([RDF(q) == RR(q) for q in Q]) + sage: Q = continued_fraction(pi).convergents()[:100] + sage: all([RDF(q) == RR(q) for q in Q]) True At some point, the continued fraction and direct conversion to ``RDF`` should agree:: sage: RDFpi = RDF(pi) - sage: all([RDF(q) == RDFpi for q in Q[20:]]) + sage: all([RDF(q) == RDFpi for q in Q[20:]]) True """ return mpq_get_d_nearest(self.value) From d261a37914aec9a0b7949fd526881003d3214f62 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Tue, 27 May 2014 02:12:33 +0100 Subject: [PATCH 025/698] Trac 15618: delay setting _category_for to avoid unpickling trouble --- src/sage/categories/map.pyx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/sage/categories/map.pyx b/src/sage/categories/map.pyx index 4e3591ad0ae..54dc46f5fc8 100644 --- a/src/sage/categories/map.pyx +++ b/src/sage/categories/map.pyx @@ -138,10 +138,6 @@ cdef class Map(Element): else: self._coerce_cost = 10000 # inexact morphisms are bad. - def _set_parent(self, parent): - super(Map, self)._set_parent(parent) - self._category_for = parent.homset_category() - def __copy__(self): """ Return copy, with strong references to domain and codomain. @@ -181,7 +177,7 @@ cdef class Map(Element): cdef Map out = Element.__copy__(self) # Element.__copy__ updates the __dict__, but not the slots. # Let's do this now, but with strong references. - out._set_parent(self.parent()) # self._parent might be None + out._parent = self.parent() # self._parent might be None out._update_slots(self._extra_slots({})) return out @@ -294,6 +290,8 @@ cdef class Map(Element): if not isinstance(self.domain, ConstantFunction): return self.domain = weakref.ref(self.domain()) + # Save the category before clearing the parent. + self._category_for = self._parent.homset_category() self._parent = None def _make_strong_references(self): @@ -620,6 +618,13 @@ cdef class Map(Element): FIXME: find a better name for this method """ + if self._category_for is None: + # This can happen if the map is the result of unpickling. + # We have initialised self._parent, but could not set + # self._category_for at that moment, because it could + # happen that the parent was not fully constructed and + # did not know its category yet. + self._category_for = self._parent.homset_category() return self._category_for def __call__(self, x, *args, **kwds): From 54a6ecae11f902b11ad651c67af021af6ed2da21 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Tue, 27 May 2014 13:11:34 +0100 Subject: [PATCH 026/698] Trac 15618: add doctests --- src/sage/rings/finite_rings/integer_mod.pyx | 19 +++++++++++++++++++ src/sage/rings/rational.pyx | 8 +++++++- src/sage/structure/coerce_maps.pyx | 13 +++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index c11ff1ece08..b0f88efb721 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -4276,7 +4276,26 @@ cdef class Integer_to_IntegerMod(IntegerMod_hom): return IntegerMod_to_Integer(self._codomain) cdef class IntegerMod_to_Integer(Map): + """ + Map to lift elements to :class:`~sage.rings.integer.Integer`. + + EXAMPLES:: + + sage: ZZ.convert_map_from(GF(2)) + Lifting map: + From: Finite Field of size 2 + To: Integer Ring + """ def __init__(self, R): + """ + TESTS: + + Lifting maps are morphisms in the category of sets (see + :trac:`15618`):: + + sage: ZZ.convert_map_from(GF(2)).parent() + Set of Morphisms from Finite Field of size 2 to Integer Ring in Category of sets + """ import sage.categories.homset from sage.categories.all import Sets Morphism.__init__(self, sage.categories.homset.Hom(R, integer_ring.ZZ, Sets())) diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index 1233c0744f5..bffdab17dad 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -3761,10 +3761,16 @@ cdef class Z_to_Q(Morphism): EXAMPLES:: - sage: QQ.coerce_map_from(ZZ).section() + sage: f = QQ.coerce_map_from(ZZ).section(); f Generic map: From: Rational Field To: Integer Ring + + This map is a morphism in the category of sets with partial + maps (see :trac:`15618`):: + + sage: f.parent() + Set of Morphisms from Rational Field to Integer Ring in Category of sets with partial maps """ from sage.categories.sets_with_partial_maps import SetsWithPartialMaps return Q_to_Z(self._codomain.Hom(self.domain(), category=SetsWithPartialMaps())) diff --git a/src/sage/structure/coerce_maps.pyx b/src/sage/structure/coerce_maps.pyx index 6591c94b191..7789bb72176 100644 --- a/src/sage/structure/coerce_maps.pyx +++ b/src/sage/structure/coerce_maps.pyx @@ -22,6 +22,19 @@ cdef class DefaultConvertMap(Map): passing in the codomain as the first argument. """ def __init__(self, domain, codomain, force_use=False): + """ + TESTS: + + Maps of this type are morphisms in the category of sets with + partial maps (see :trac:`15618`):: + + sage: f = GF(11).convert_map_from(GF(7)); f + Conversion map: + From: Finite Field of size 7 + To: Finite Field of size 11 + sage: f.parent() + Set of Morphisms from Finite Field of size 7 to Finite Field of size 11 in Category of sets with partial maps + """ if not PY_TYPE_CHECK(domain, Parent): domain = Set_PythonType(domain) from sage.categories.sets_with_partial_maps import SetsWithPartialMaps From 8f1ad732bd60a20b70626aaeb3f566a31214581e Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Tue, 27 May 2014 15:15:25 +0200 Subject: [PATCH 027/698] trac #12797: The cut returned by edge_cut of undirected weighted graphs is sometimes incorrect --- src/sage/graphs/generic_graph.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 07d04f02545..f76cecdd077 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -5217,6 +5217,15 @@ def edge_cut(self, s, t, value_only=True, use_edge_labels=False, vertices=False, sage: g = graphs.PappusGraph() sage: g.edge_cut(1, 2, value_only=True, method = "LP") 3 + + :trac:`12797`:: + + sage: G = Graph([(0, 3, 1), (0, 4, 1), (1, 2, 1), (2, 3, 1), (2, 4, 1)]) + sage: G.edge_cut(0,1,value_only=False,use_edge_labels=True) + [1, [(1, 2, 1)]] + sage: G = DiGraph([(0, 3, 1), (0, 4, 1), (2, 1, 1), (3, 2, 1), (4, 2, 1)]) + sage: G.edge_cut(0,1,value_only=False,use_edge_labels=True) + [1, [(2, 1, 1)]] """ self._scream_if_not_simple(allow_loops=True) if vertices: @@ -5231,9 +5240,12 @@ def edge_cut(self, s, t, value_only=True, use_edge_labels=False, vertices=False, if value_only: return self.flow(s,t,value_only=value_only,use_edge_labels=use_edge_labels, method=method) + from sage.graphs.digraph import DiGraph + g = DiGraph(self) + flow_value, flow_graph = self.flow(s,t,value_only=value_only,use_edge_labels=use_edge_labels, method=method) - g = self.copy() for u,v,l in flow_graph.edge_iterator(): + g.add_edge(v,u) if (not use_edge_labels or (weight(g.edge_label(u,v)) == weight(l))): g.delete_edge(u,v) From 5dc78c5f5f647bf95b98da916d7086fae539ffb8 Mon Sep 17 00:00:00 2001 From: Simon King Date: Mon, 26 May 2014 22:15:11 +0200 Subject: [PATCH 028/698] Implement sequences of bounded integers --- src/doc/en/reference/structure/index.rst | 1 + src/module_list.py | 3 + .../structure/bounded_integer_sequences.pxd | 54 + .../structure/bounded_integer_sequences.pyx | 924 ++++++++++++++++++ 4 files changed, 982 insertions(+) create mode 100644 src/sage/structure/bounded_integer_sequences.pxd create mode 100644 src/sage/structure/bounded_integer_sequences.pyx diff --git a/src/doc/en/reference/structure/index.rst b/src/doc/en/reference/structure/index.rst index 4c448524942..2f5ebfbd727 100644 --- a/src/doc/en/reference/structure/index.rst +++ b/src/doc/en/reference/structure/index.rst @@ -16,6 +16,7 @@ Basic Structures sage/structure/unique_representation sage/structure/factory sage/structure/dynamic_class + sage/structure/bounded_integer_sequences sage/structure/list_clone sage/structure/list_clone_demo sage/structure/mutability diff --git a/src/module_list.py b/src/module_list.py index fa460be87b5..319b6a4ad82 100755 --- a/src/module_list.py +++ b/src/module_list.py @@ -1959,6 +1959,9 @@ def uname_specific(name, value, alternative): ## ################################ + Extension('sage.structure.bounded_integer_sequences', + sources = ['sage/structure/bounded_integer_sequences.pyx']), + Extension('sage.structure.category_object', sources = ['sage/structure/category_object.pyx']), diff --git a/src/sage/structure/bounded_integer_sequences.pxd b/src/sage/structure/bounded_integer_sequences.pxd new file mode 100644 index 00000000000..14d3d0da2fc --- /dev/null +++ b/src/sage/structure/bounded_integer_sequences.pxd @@ -0,0 +1,54 @@ +include "sage/libs/ntl/decl.pxi" + +ctypedef struct biseq_t: # bounded integer sequence type + mpz_t data # Use GMP integers as bitarrays + unsigned long int bitsize # Bitsize of "data" + unsigned int itembitsize # Bitsize of one element of this sequence. + # Note: We do not store the exact bound for the + # items of this sequence, but store the + # bitlength that is sufficient to store one + # item. + size_t length # Number of items in this sequence. + # bitsize=length*itembitsize, but we do not want + # to repeat this multiplication and thus store + # the result. + +cdef biseq_t* allocate_biseq(size_t l, unsigned long int itemsize) except NULL + +#cdef inline void dealloc_biseq(biseq_t S) + +cdef biseq_t* list2biseq(biseq_t S, list data) except NULL + # Assumes that S is allocated + +cdef list biseq2list(biseq_t S) + +cdef str biseq2str(biseq_t S) + +cdef biseq_t* concat_biseq(biseq_t S1, biseq_t S2) except NULL + # Does not test whether the sequences have the same bound! + +#cdef inline int cmp_biseq(biseq_t S1, biseq_t S2) + +cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2) + # Is S1=S2+something? Does not check whether the sequences have the same + # bound! + +cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start) + # Returns the position *in S1* of S2 as a subsequence of S1[start:], or -1 + # if S2 is not a subsequence. Does not check whether the sequences have the + # same bound! + +cdef int index_biseq(biseq_t S, int item, size_t start) + # Returns the position *in S* of the item in S[start:], or -1 if S does not + # contain the item. + +cdef int getitem_biseq(biseq_t S, unsigned long int index) + # Returns S[index], without checking margins + +cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL + # Returns the biseq S[start:stop:step] + +cdef class BoundedIntegerSequence: + cdef biseq_t data + cdef str str(self) + cpdef bint startswith(self, BoundedIntegerSequence other) diff --git a/src/sage/structure/bounded_integer_sequences.pyx b/src/sage/structure/bounded_integer_sequences.pyx new file mode 100644 index 00000000000..5750aa8ee47 --- /dev/null +++ b/src/sage/structure/bounded_integer_sequences.pyx @@ -0,0 +1,924 @@ +r""" +Sequences of bounded integers + +AUTHORS: + +- Simon King (2014): initial version + +""" +#***************************************************************************** +# Copyright (C) 2014 Simon King +# +# 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/ +#***************************************************************************** + +include "sage/ext/cdefs.pxi" +include "sage/ext/interrupt.pxi" +include "sage/ext/stdsage.pxi" +include "sage/ext/python.pxi" + +cdef extern from "mpz_pylong.h": + cdef long mpz_pythonhash(mpz_t src) + +cdef extern from "Python.h": + bint PySlice_Check(PyObject* ob) + +cdef tuple ZeroNone = (0,None) +cdef PyObject* zeroNone = ZeroNone +cdef dict EmptyDict = {} +cdef PyObject* emptyDict = EmptyDict + +from cython.operator import dereference as deref + +################### +# Boilerplate +# cdef functions +################### + +# +# (De)allocation, copying +# + +cdef biseq_t* allocate_biseq(size_t l, unsigned long int itemsize) except NULL: + cdef biseq_t out + out.bitsize = l*itemsize + out.length = l + out.itembitsize = itemsize + sig_on() + mpz_init2(out.data, out.bitsize+64) + sig_off() + return &out + +#cdef inline void dealloc_biseq(biseq_t S): +# mpz_clear(S.data) + +# +# Conversion +# + +cdef biseq_t* list2biseq(biseq_t S, list data) except NULL: + # S is supposed to be initialised to zero + cdef unsigned long int item + cdef mpz_t tmp + cdef unsigned long int shift = 0 + mpz_init(tmp) + try: + sig_on() + for item in data: + mpz_set_ui(tmp, item) + mpz_fdiv_r_2exp(tmp, tmp, S.itembitsize) + mpz_mul_2exp(tmp, tmp, shift) + mpz_ior(S.data, S.data, tmp) + shift += S.itembitsize + sig_off() + except (TypeError, OverflowError): + sig_off() + S.itembitsize=0 # this is the error value + mpz_clear(tmp) + return &S + +cdef list biseq2list(biseq_t S): + cdef mpz_t tmp, item + sig_on() + mpz_init_set(tmp, S.data) + mpz_init(item) + + cdef list L = [] + cdef size_t i + for i from S.length > i > 0: + mpz_fdiv_r_2exp(item, tmp, S.itembitsize) + L.append(mpz_get_ui(item)) + mpz_fdiv_q_2exp(tmp, tmp, S.itembitsize) + L.append(mpz_get_ui(tmp)) + sig_off() + mpz_clear(tmp) + mpz_clear(item) + return L + +cdef str biseq2str(biseq_t S): + cdef mpz_t tmp, item + if S.length==0: + return "" + sig_on() + mpz_init_set(tmp, S.data) + cdef char* s_item + # allocate enough memory to s_item + mpz_init_set_ui(item,1) + mpz_mul_2exp(item, item, S.itembitsize) + cdef size_t item10len = mpz_sizeinbase(item, 10)+2 + s_item = PyMem_Malloc(item10len) + sig_off() + if s_item == NULL: + raise MemoryError, "Unable to allocate enough memory for the string representation of bounded integer sequence." + cdef list L = [] + cdef size_t i + for i from S.length > i > 0: + mpz_fdiv_r_2exp(item, tmp, S.itembitsize) + L.append(PyString_FromString(mpz_get_str(s_item, 10, item))) + mpz_fdiv_q_2exp(tmp, tmp, S.itembitsize) + L.append(PyString_FromString(mpz_get_str(s_item, 10, tmp))) + mpz_clear(tmp) + mpz_clear(item) + PyMem_Free(s_item) + return ', '.join(L) + +# +# Arithmetics +# + +cdef biseq_t *concat_biseq(biseq_t S1, biseq_t S2) except NULL: + cdef biseq_t out + out.bitsize = S1.bitsize+S2.bitsize + out.length = S1.length+S2.length + out.itembitsize = S1.itembitsize # do not test == S2.itembitsize + sig_on() + mpz_init2(out.data, out.bitsize+64) + sig_off() + mpz_mul_2exp(out.data, S2.data, S1.bitsize) + mpz_ior(out.data, out.data, S1.data) + return &out + +#cdef inline int cmp_biseq(biseq_t S1, biseq_t S2): +# return mpz_cmp(S1.data, S2.data) + +cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2): + return mpz_congruent_2exp_p(S1.data, S2.data, S2.bitsize) + +cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start): + if S1.length=S.length: + return -1 + cdef mpz_t tmp, mpz_item + sig_on() + mpz_init_set(tmp, S.data) + sig_off() + mpz_fdiv_q_2exp(tmp, tmp, start*S.itembitsize) + mpz_init_set_ui(mpz_item, item) + cdef size_t i + for i from start<=i0: + if stop>start: + length = ((stop-start-1)//step)+1 + else: + length = 0 + else: + if stop>=start: + length = 0 + else: + length = ((stop-start+1)//step)+1 + cdef biseq_t out + out = deref(allocate_biseq(length, S.itembitsize)) + cdef mpz_t tmp + if step==1: + sig_on() + mpz_init_set(tmp, S.data) + sig_off() + mpz_fdiv_q_2exp(tmp, tmp, start*S.itembitsize) + mpz_fdiv_r_2exp(out.data, tmp, out.bitsize) + mpz_clear(tmp) + return &out + cdef mpz_t item + sig_on() + mpz_init_set(tmp, S.data) + mpz_init2(item, S.itembitsize) + sig_off() + cdef unsigned long int bitstep + if step>0: + mpz_fdiv_q_2exp(tmp, tmp, start*S.itembitsize) + bitstep = out.itembitsize*step + for i from 0<=i + + Each bounded integer sequence has a bound that is a power of two, such + that all its item are less than this bound (they are in fact truncated):: + + sage: S.bound() + 32 + sage: BoundedIntegerSequence(16, [2, 7, 20]) + <2, 7, 4> + + Bounded integer sequences are iterable, and we see that we can recover the + originally given list, modulo the bound:: + + sage: L = [randint(0,31) for i in range(5000)] + sage: S = BoundedIntegerSequence(32, L) + sage: list(L) == L + True + sage: S16 = BoundedIntegerSequence(16, L) + sage: list(S16) == [x%S16.bound() for x in L] + True + + Getting items and slicing works in the same way as for lists. Note, + however, that slicing is an operation that is relatively slow for bounded + integer sequences. :: + + sage: n = randint(0,4999) + sage: S[n] == L[n] + True + sage: m = randint(0,1000) + sage: n = randint(3000,4500) + sage: s = randint(1, 7) + sage: list(S[m:n:s]) == L[m:n:s] + True + sage: list(S[n:m:-s]) == L[n:m:-s] + True + + The :meth:`index` method works different for bounded integer sequences and + tuples or lists. If one asks for the index of an item, the behaviour is + the same. But we can also ask for the index of a sub-sequence:: + + sage: L.index(L[200]) == S.index(L[200]) + True + sage: S.index(S[100:2000]) # random + 100 + + Similarly, containment tests work for both items and sub-sequences:: + + sage: S[200] in S + True + sage: S[200:400] in S + True + + Note, however, that containment of items will test for congruence modulo + the bound of the sequence. Thus, we have:: + + sage: S[200]+S.bound() in S + True + sage: L[200]+S.bound() in L + False + + Bounded integer sequences are immutable, and thus copies are + identical. This is the same for tuples, but of course not for lists:: + + sage: T = tuple(S) + sage: copy(T) is T + True + sage: copy(S) is S + True + sage: copy(L) is L + False + + Concatenation works in the same way for list, tuples and bounded integer + sequences:: + + sage: M = [randint(0,31) for i in range(5000)] + sage: T = BoundedIntegerSequence(32, M) + sage: list(S+T)==L+M + True + sage: list(T+S)==M+L + True + sage: (T+S == S+T) == (M+L == L+M) + True + + However, comparison works different for lists and bounded integer + sequences. Bounded integer sequences are first compared by bound, then by + length, and eventually by *reverse* lexicographical ordering:: + + sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) + sage: T = BoundedIntegerSequence(51, [4,1,6,2,7,20]) + sage: S < T # compare by bound, not length + True + sage: T < S + False + sage: S.bound() < T.bound() + True + sage: len(S) > len(T) + True + + :: + + sage: T = BoundedIntegerSequence(21, [0,0,0,0,0,0,0,0]) + sage: S < T # compare by length, not lexicographically + True + sage: T < S + False + sage: list(T) < list(S) + True + sage: len(T) > len(S) + True + + :: + + sage: T = BoundedIntegerSequence(21, [4,1,5,2,8,20,9]) + sage: T > S # compare by reverse lexicographic ordering... + True + sage: S > T + False + sage: len(S) == len(T) + True + sage: list(S)> list(T) # direct lexicographic ordering is different + True + + TESTS: + + We test against various corner cases:: + + sage: BoundedIntegerSequence(16, [2, 7, -20]) + Traceback (most recent call last): + ... + ValueError: List of non-negative integers expected + sage: BoundedIntegerSequence(1, [2, 7, 0]) + <0, 1, 0> + sage: BoundedIntegerSequence(0, [2, 7, 0]) + Traceback (most recent call last): + ... + ValueError: Positive bound expected + sage: BoundedIntegerSequence(2, []) + <> + sage: BoundedIntegerSequence(2, []) == BoundedIntegerSequence(4, []) # The bounds differ + False + sage: BoundedIntegerSequence(16, [2, 7, 20])[1:1] + <> + + """ + def __cinit__(self, unsigned long int bound, list data): + """ + Allocate memory for underlying data + + INPUT: + + - ``bound``, non-negative integer + - ``data``, ignored + + .. WARNING:: + + If ``bound=0`` then no allocation is done. Hence, this should + only be done internally, when calling :meth:`__new__` without :meth:`__init__`. + + EXAMPLES:: + + sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) # indirect doctest + <4, 1, 6, 2, 7, 20, 9> + + """ + # In __init__, we'll raise an error if the bound is 0. + cdef mpz_t tmp + if bound!=0: + mpz_init_set_ui(tmp, bound-1) + self.data = deref(allocate_biseq(len(data), mpz_sizeinbase(tmp, 2))) + mpz_clear(tmp) + + def __dealloc__(self): + """ + Free the memory from underlying data + + EXAMPLES:: + + sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) + sage: del S # indirect doctest + + """ + mpz_clear(self.data.data) + + def __init__(self, unsigned long int bound, list data): + """ + INPUT: + + - ``bound``, non-negative integer. When zero, a :class:`ValueError` + will be raised. Otherwise, the given bound is replaced by the next + power of two that is greater than the given bound. + - ``data``, a list of integers. The given integers will be truncated + to be less than the bound. + + EXAMPLES:: + + sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: L = [randint(0,26) for i in range(5000)] + sage: S = BoundedIntegerSequence(57, L) # indirect doctest + sage: list(S) == L + True + + The given data are truncated according to the bound:: + + sage: S = BoundedIntegerSequence(11, [4,1,6,2,7,20,9]); S + <4, 1, 6, 2, 7, 4, 9> + sage: S.bound() + 16 + sage: S = BoundedIntegerSequence(11, L) + sage: [x%S.bound() for x in L] == list(S) + True + + Non-positive bounds result in errors:: + + sage: BoundedIntegerSequence(-1, L) + Traceback (most recent call last): + ... + OverflowError: can't convert negative value to unsigned long + sage: BoundedIntegerSequence(0, L) + Traceback (most recent call last): + ... + ValueError: Positive bound expected + + """ + if bound==0: + raise ValueError("Positive bound expected") + self.data = deref(list2biseq(self.data, data)) + if not self.data.itembitsize: + raise ValueError("List of non-negative integers expected") + + def __copy__(self): + """ + :class:`BoundedIntegerSequence` is immutable, copying returns ``self``. + + EXAMPLES:: + + sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: S = BoundedIntegerSequence(11, [4,1,6,2,7,20,9]) + sage: copy(S) is S + True + + """ + return self + + def __len__(self): + """ + EXAMPLES:: + + sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: L = [randint(0,26) for i in range(5000)] + sage: S = BoundedIntegerSequence(57, L) # indirect doctest + sage: len(S) == len(L) + True + + """ + return self.data.length + + def __repr__(self): + """ + String representation. + + To distinguish it from Python tuples or lists, we use pointed brackets + as delimiters. + + EXAMPLES:: + + sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) # indirect doctest + <4, 1, 6, 2, 7, 20, 9> + + """ + return '<'+self.str()+'>' + + cdef str str(self): + """ + A cdef helper function, returns the string representation without the brackets. + + Used in :meth:`__repr__`. + + EXAMPLES:: + + sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) # indirect doctest + <4, 1, 6, 2, 7, 20, 9> + + """ + return biseq2str(self.data) + + def bound(self): + """ + The bound of this bounded integer sequence + + All items of this sequence are non-negative integers less than the + returned bound. The bound is a power of two. + + EXAMPLES:: + + sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) + sage: T = BoundedIntegerSequence(51, [4,1,6,2,7,20,9]) + sage: S.bound() + 32 + sage: T.bound() + 64 + + """ + cdef long b = 1 + return (b<0: + sig_on() + mpz_init_set(tmp, self.data.data) + mpz_init2(item, self.data.itembitsize) + sig_off() + for i from self.data.length>i>0: + mpz_fdiv_r_2exp(item, tmp, self.data.itembitsize) + yield mpz_get_si(item) + mpz_fdiv_q_2exp(tmp, tmp, self.data.itembitsize) + yield mpz_get_si(tmp) + mpz_clear(tmp) + mpz_clear(item) + + def __getitem__(self, index): + """ + Get single items or slices. + + EXAMPLES:: + + sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) + sage: S[2] + 6 + sage: S[1::2] + <1, 2, 20> + sage: S[-1::-2] + <9, 7, 6, 4> + + TESTS:: + + sage: L = [randint(0,26) for i in range(5000)] + sage: S = BoundedIntegerSequence(27, L) + sage: S[1234] == L[1234] + True + sage: list(S[100:2000:3]) == L[100:2000:3] + True + sage: list(S[3000:10:-7]) == L[3000:10:-7] + True + sage: S[:] == S + True + sage: S[:] is S + True + + """ + cdef BoundedIntegerSequence out + cdef int start,stop,step + if PySlice_Check(index): + start,stop,step = index.indices(self.data.length) + if start==0 and stop==self.data.length and step==1: + return self + out = BoundedIntegerSequence.__new__(BoundedIntegerSequence, 0, None) + out.data = deref(slice_biseq(self.data, start, stop, step)) + return out + cdef long Index + try: + Index = index + except TypeError: + raise TypeError("Sequence index must be integer or slice") + if Index<0: + Index = (self.data.length)+Index + if Index<0 or Index>=self.data.length: + raise IndexError("Index out of range") + return getitem_biseq(self.data, Index) + + def __contains__(self, other): + """ + Tells whether this bounded integer sequence contains an item or a sub-sequence + + EXAMPLES:: + + sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) + sage: 6 in S + True + sage: BoundedIntegerSequence(21, [2, 7, 20]) in S + True + + The bound of the sequences matters:: + + sage: BoundedIntegerSequence(51, [2, 7, 20]) in S + False + + Note that the items are compared up to congruence modulo the bound of + the sequence. Thus we have:: + + sage: 6+S.bound() in S + True + sage: S.index(6) == S.index(6+S.bound()) + True + + """ + if not isinstance(other, BoundedIntegerSequence): + return index_biseq(self.data, other, 0)>=0 + cdef BoundedIntegerSequence right = other + if self.data.itembitsize!=right.data.itembitsize: + return False + return contains_biseq(self.data, right.data, 0)>=0 + + cpdef bint startswith(self, BoundedIntegerSequence other): + """ + Tells whether ``self`` starts with a given bounded integer sequence + + EXAMPLES:: + + sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: L = [randint(0,26) for i in range(5000)] + sage: S = BoundedIntegerSequence(27, L) + sage: L0 = L[:1000] + sage: T = BoundedIntegerSequence(27, L0) + sage: S.startswith(T) + True + sage: L0[-1] += 1 + sage: T = BoundedIntegerSequence(27, L0) + sage: S.startswith(T) + False + sage: L0[-1] -= 1 + sage: L0[0] += 1 + sage: T = BoundedIntegerSequence(27, L0) + sage: S.startswith(T) + False + sage: L0[0] -= 1 + + The bounds of the sequences must be compatible, or :meth:`startswith` + returns ``False``:: + + sage: T = BoundedIntegerSequence(51, L0) + sage: S.startswith(T) + False + + """ + if self.data.itembitsize!=other.data.itembitsize: + return False + return startswith_biseq(self.data, other.data) + + def index(self, other): + """ + The index of a given item or sub-sequence of ``self`` + + EXAMPLES:: + + sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: S = BoundedIntegerSequence(21, [4,1,6,2,6,20,9]) + sage: S.index(6) + 2 + sage: S.index(5) + Traceback (most recent call last): + ... + ValueError: BoundedIntegerSequence.index(x): x(=5) not in sequence + sage: S.index(-3) + Traceback (most recent call last): + ... + ValueError: BoundedIntegerSequence.index(x): x(=-3) not in sequence + sage: S.index(BoundedIntegerSequence(21, [6, 2, 6])) + 2 + sage: S.index(BoundedIntegerSequence(21, [6, 2, 7])) + Traceback (most recent call last): + ... + ValueError: Not a sub-sequence + + The bound of (sub-)sequences matters:: + + sage: S.index(BoundedIntegerSequence(51, [6, 2, 6])) + Traceback (most recent call last): + ... + ValueError: Not a sub-sequence + + Note that items are compared up to congruence modulo the bound of the + sequence:: + + sage: S.index(6) == S.index(6+S.bound()) + True + + """ + cdef int out + if not isinstance(other, BoundedIntegerSequence): + if other<0: + raise ValueError("BoundedIntegerSequence.index(x): x(={}) not in sequence".format(other)) + try: + out = index_biseq(self.data, other, 0) + except TypeError: + raise ValueError("BoundedIntegerSequence.index(x): x(={}) not in sequence".format(other)) + if out>=0: + return out + raise ValueError("BoundedIntegerSequence.index(x): x(={}) not in sequence".format(other)) + cdef BoundedIntegerSequence right = other + if self.data.itembitsize!=right.data.itembitsize: + raise ValueError("Not a sub-sequence") + out = contains_biseq(self.data, right.data, 0) + if out>=0: + return out + raise ValueError("Not a sub-sequence") + + def __add__(self, other): + """ + Concatenation of bounded integer sequences. + + NOTE: + + There is no coercion happening, as bounded integer sequences are not + considered to be elements of an object. + + EXAMPLES:: + + sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) + sage: T = BoundedIntegerSequence(21, [4,1,6,2,8,15]) + sage: S+T + <4, 1, 6, 2, 7, 20, 9, 4, 1, 6, 2, 8, 15> + sage: T+S + <4, 1, 6, 2, 8, 15, 4, 1, 6, 2, 7, 20, 9> + sage: S in S+T + True + sage: T in S+T + True + sage: T+list(S) + Traceback (most recent call last): + ... + TypeError: Cannot convert list to sage.structure.bounded_integer_sequences.BoundedIntegerSequence + sage: T+None + Traceback (most recent call last): + ... + TypeError: Can not concatenate bounded integer sequence and None + + """ + cdef BoundedIntegerSequence myself, right, out + if other is None or self is None: + raise TypeError('Can not concatenate bounded integer sequence and None') + myself = self # may result in a type error + right = other # --"-- + if right.data.itembitsize!=myself.data.itembitsize: + raise ValueError("can only concatenate bounded integer sequences of compatible bounds") + out = BoundedIntegerSequence.__new__(BoundedIntegerSequence, 0, None) + out.data = deref(concat_biseq(myself.data, right.data)) + return out + + def __cmp__(self, other): + """ + Comparison of bounded integer sequences + + We compare, in this order: + + - The bound of ``self`` and ``other`` + + - The length of ``self`` and ``other`` + + - Reverse lexicographical ordering, i.e., the sequences' items + are compared starting with the last item. + + EXAMPLES: + + Comparison by bound:: + + sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) + sage: T = BoundedIntegerSequence(51, [4,1,6,2,7,20,9]) + sage: S < T + True + sage: T < S + False + sage: list(T) == list(S) + True + + Comparison by length:: + + sage: T = BoundedIntegerSequence(21, [0,0,0,0,0,0,0,0]) + sage: S < T + True + sage: T < S + False + sage: list(T) < list(S) + True + sage: len(T) > len(S) + True + + Comparison by *reverse* lexicographical ordering:: + + sage: T = BoundedIntegerSequence(21, [4,1,5,2,8,20,9]) + sage: T > S + True + sage: S > T + False + sage: list(S)> list(T) + True + + """ + cdef BoundedIntegerSequence right + if other is None: + return 1 + try: + right = other + except TypeError: + return -1 + cdef int c = cmp(self.data.itembitsize, right.data.itembitsize) + if c: + return c + c = cmp(self.data.length, right.data.length) + if c: + return c + return mpz_cmp(self.data.data, right.data.data) + + def __hash__(self): + """ + The hash takes into account the content and the bound of the sequence. + + EXAMPLES:: + + sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) + sage: T = BoundedIntegerSequence(51, [4,1,6,2,7,20,9]) + sage: S == T + False + sage: list(S) == list(T) + True + sage: S.bound() == T.bound() + False + sage: hash(S) == hash(T) + False + sage: T = BoundedIntegerSequence(31, [4,1,6,2,7,20,9]) + sage: T.bound() == S.bound() + True + sage: hash(S) == hash(T) + True + + """ + return mpz_pythonhash(self.data.data) From 2e30025298097a2c280629135f3f76d973c0b4a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 27 May 2014 20:44:14 +0200 Subject: [PATCH 029/698] trac #10779 corrected 3 doctests --- src/sage/structure/element.pyx | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index ed2ae24089e..1dc1fd1bb77 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -1934,11 +1934,8 @@ def is_CommutativeRingElement(x): TESTS:: + sage: from sage.rings.commutative_ring_element import is_CommutativeRingElement sage: is_CommutativeRingElement(oo) - doctest:...: DeprecationWarning: - Using is_CommutativeRingElement from the top level is deprecated since it was designed to be used by developers rather than end users. - It most likely does not do what you would expect it to do. If you really need to use it, import it from the module that it is defined in. - See http://trac.sagemath.org/10107 for details. False sage: is_CommutativeRingElement(1) @@ -2978,12 +2975,9 @@ def is_AlgebraElement(x): TESTS:: + sage: from sage.structure.element import is_AlgebraElement sage: R. = FreeAlgebra(QQ,2) sage: is_AlgebraElement(x*y) - doctest:...: DeprecationWarning: - Using is_AlgebraElement from the top level is deprecated since it was designed to be used by developers rather than end users. - It most likely does not do what you would expect it to do. If you really need to use it, import it from the module that it is defined in. - See http://trac.sagemath.org/10107 for details. True sage: is_AlgebraElement(1) @@ -3009,11 +3003,8 @@ def is_InfinityElement(x): TESTS:: + sage: from sage.structure.element import is_InfinityElement sage: is_InfinityElement(1) - doctest:...: DeprecationWarning: - Using is_InfinityElement from the top level is deprecated since it was designed to be used by developers rather than end users. - It most likely does not do what you would expect it to do. If you really need to use it, import it from the module that it is defined in. - See http://trac.sagemath.org/10107 for details. False sage: is_InfinityElement(oo) From efef80bea22840f618335b7dd6f5d3e9a64fa301 Mon Sep 17 00:00:00 2001 From: Simon King Date: Fri, 30 May 2014 14:51:59 +0200 Subject: [PATCH 030/698] Relocate bounded integer sequences (sage.misc, not sage.structure) --- src/doc/en/reference/misc/index.rst | 1 + src/doc/en/reference/structure/index.rst | 1 - src/module_list.py | 6 ++-- .../bounded_integer_sequences.pxd | 0 .../bounded_integer_sequences.pyx | 36 +++++++++---------- 5 files changed, 22 insertions(+), 22 deletions(-) rename src/sage/{structure => misc}/bounded_integer_sequences.pxd (100%) rename src/sage/{structure => misc}/bounded_integer_sequences.pyx (94%) diff --git a/src/doc/en/reference/misc/index.rst b/src/doc/en/reference/misc/index.rst index ecbdce90a40..bdb04e0bc07 100644 --- a/src/doc/en/reference/misc/index.rst +++ b/src/doc/en/reference/misc/index.rst @@ -7,6 +7,7 @@ Miscellaneous sage/misc/abstract_method sage/misc/ascii_art sage/misc/bindable_class + sage/misc/bounded_integer_sequences sage/misc/cachefunc sage/misc/weak_dict sage/misc/c3 diff --git a/src/doc/en/reference/structure/index.rst b/src/doc/en/reference/structure/index.rst index 7426fbf81e1..bd6d4d32be7 100644 --- a/src/doc/en/reference/structure/index.rst +++ b/src/doc/en/reference/structure/index.rst @@ -16,7 +16,6 @@ Basic Structures sage/structure/unique_representation sage/structure/factory sage/structure/dynamic_class - sage/structure/bounded_integer_sequences sage/structure/list_clone sage/structure/list_clone_demo sage/structure/mutability diff --git a/src/module_list.py b/src/module_list.py index 0bfb7dc1659..5463bc8722f 100755 --- a/src/module_list.py +++ b/src/module_list.py @@ -1191,6 +1191,9 @@ def uname_specific(name, value, alternative): sources = ['sage/misc/bitset.pyx'], libraries = ['gmp']), + Extension('sage.misc.bounded_integer_sequences', + sources = ['sage/misc/bounded_integer_sequences.pyx']), + Extension('sage.misc.cachefunc', sources = ['sage/misc/cachefunc.pyx']), @@ -1964,9 +1967,6 @@ def uname_specific(name, value, alternative): ## ################################ - Extension('sage.structure.bounded_integer_sequences', - sources = ['sage/structure/bounded_integer_sequences.pyx']), - Extension('sage.structure.category_object', sources = ['sage/structure/category_object.pyx']), diff --git a/src/sage/structure/bounded_integer_sequences.pxd b/src/sage/misc/bounded_integer_sequences.pxd similarity index 100% rename from src/sage/structure/bounded_integer_sequences.pxd rename to src/sage/misc/bounded_integer_sequences.pxd diff --git a/src/sage/structure/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx similarity index 94% rename from src/sage/structure/bounded_integer_sequences.pyx rename to src/sage/misc/bounded_integer_sequences.pyx index 5750aa8ee47..437f2e658de 100644 --- a/src/sage/structure/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -272,7 +272,7 @@ cdef class BoundedIntegerSequence: To distinguish from tuples or lists, we use pointed brackets for the string representation of bounded integer sequences:: - sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [2, 7, 20]); S <2, 7, 20> @@ -434,7 +434,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) # indirect doctest <4, 1, 6, 2, 7, 20, 9> @@ -452,7 +452,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: del S # indirect doctest @@ -471,7 +471,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: L = [randint(0,26) for i in range(5000)] sage: S = BoundedIntegerSequence(57, L) # indirect doctest sage: list(S) == L @@ -511,7 +511,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(11, [4,1,6,2,7,20,9]) sage: copy(S) is S True @@ -523,7 +523,7 @@ cdef class BoundedIntegerSequence: """ EXAMPLES:: - sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: L = [randint(0,26) for i in range(5000)] sage: S = BoundedIntegerSequence(57, L) # indirect doctest sage: len(S) == len(L) @@ -541,7 +541,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) # indirect doctest <4, 1, 6, 2, 7, 20, 9> @@ -556,7 +556,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) # indirect doctest <4, 1, 6, 2, 7, 20, 9> @@ -572,7 +572,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: T = BoundedIntegerSequence(51, [4,1,6,2,7,20,9]) sage: S.bound() @@ -588,7 +588,7 @@ cdef class BoundedIntegerSequence: """ EXAMPLES:: - sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: L = [randint(0,26) for i in range(5000)] sage: S = BoundedIntegerSequence(27, L) sage: list(S) == L # indirect doctest @@ -616,7 +616,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: S[2] 6 @@ -667,7 +667,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: 6 in S True @@ -701,7 +701,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: L = [randint(0,26) for i in range(5000)] sage: S = BoundedIntegerSequence(27, L) sage: L0 = L[:1000] @@ -737,7 +737,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,6,20,9]) sage: S.index(6) 2 @@ -800,7 +800,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: T = BoundedIntegerSequence(21, [4,1,6,2,8,15]) sage: S+T @@ -814,7 +814,7 @@ cdef class BoundedIntegerSequence: sage: T+list(S) Traceback (most recent call last): ... - TypeError: Cannot convert list to sage.structure.bounded_integer_sequences.BoundedIntegerSequence + TypeError: Cannot convert list to sage.misc.bounded_integer_sequences.BoundedIntegerSequence sage: T+None Traceback (most recent call last): ... @@ -849,7 +849,7 @@ cdef class BoundedIntegerSequence: Comparison by bound:: - sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: T = BoundedIntegerSequence(51, [4,1,6,2,7,20,9]) sage: S < T @@ -903,7 +903,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.structure.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: T = BoundedIntegerSequence(51, [4,1,6,2,7,20,9]) sage: S == T From 64ac7bab9d4c85136e9845878d69d82be7c300f8 Mon Sep 17 00:00:00 2001 From: Simon King Date: Fri, 30 May 2014 23:42:21 +0200 Subject: [PATCH 031/698] Pickling of bounded integer sequence. Documentation of cdef functions --- src/sage/misc/bounded_integer_sequences.pxd | 21 +-- src/sage/misc/bounded_integer_sequences.pyx | 141 ++++++++++++++++++-- 2 files changed, 141 insertions(+), 21 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pxd b/src/sage/misc/bounded_integer_sequences.pxd index 14d3d0da2fc..cb8f4002559 100644 --- a/src/sage/misc/bounded_integer_sequences.pxd +++ b/src/sage/misc/bounded_integer_sequences.pxd @@ -14,21 +14,22 @@ ctypedef struct biseq_t: # bounded integer sequence type # the result. cdef biseq_t* allocate_biseq(size_t l, unsigned long int itemsize) except NULL + # Allocate memory (filled with zero) for a bounded integer sequence + # of length l with items fitting in itemsize bits. -#cdef inline void dealloc_biseq(biseq_t S) - -cdef biseq_t* list2biseq(biseq_t S, list data) except NULL +cdef biseq_t* list_to_biseq(biseq_t S, list data) except NULL # Assumes that S is allocated -cdef list biseq2list(biseq_t S) +cdef list biseq_to_list(biseq_t S) + # Convert a bounded integer sequence to a list -cdef str biseq2str(biseq_t S) +cdef str biseq_to_str(biseq_t S) + # String representation of bounded integer sequence as comma + # separated list cdef biseq_t* concat_biseq(biseq_t S1, biseq_t S2) except NULL # Does not test whether the sequences have the same bound! -#cdef inline int cmp_biseq(biseq_t S1, biseq_t S2) - cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2) # Is S1=S2+something? Does not check whether the sequences have the same # bound! @@ -39,8 +40,8 @@ cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start) # same bound! cdef int index_biseq(biseq_t S, int item, size_t start) - # Returns the position *in S* of the item in S[start:], or -1 if S does not - # contain the item. + # Returns the position *in S* of the item in S[start:], or -1 if S[start:] + # does not contain the item. cdef int getitem_biseq(biseq_t S, unsigned long int index) # Returns S[index], without checking margins @@ -52,3 +53,5 @@ cdef class BoundedIntegerSequence: cdef biseq_t data cdef str str(self) cpdef bint startswith(self, BoundedIntegerSequence other) + +cpdef BoundedIntegerSequence NewBISEQ(data, unsigned long int bitsize, unsigned int itembitsize, size_t length) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index 437f2e658de..a4fadc16d9e 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -43,6 +43,11 @@ from cython.operator import dereference as deref # cdef biseq_t* allocate_biseq(size_t l, unsigned long int itemsize) except NULL: + """ + Allocate memory (filled with zero) for a bounded integer sequence of + length l with items fitting in itemsize bits. Returns a pointer to the + bounded integer sequence, or NULL on error. + """ cdef biseq_t out out.bitsize = l*itemsize out.length = l @@ -52,15 +57,19 @@ cdef biseq_t* allocate_biseq(size_t l, unsigned long int itemsize) except NULL: sig_off() return &out -#cdef inline void dealloc_biseq(biseq_t S): -# mpz_clear(S.data) - # # Conversion # -cdef biseq_t* list2biseq(biseq_t S, list data) except NULL: - # S is supposed to be initialised to zero +cdef biseq_t* list_to_biseq(biseq_t S, list data) except NULL: + """ + Fill the content of a list into a bounded integer sequence. + + The bounded integer sequence is supposed to have enough memory allocated + and initialised to zero. This function returns a pointer to the originally + given bounded integer sequence, or NULL on error. + + """ cdef unsigned long int item cdef mpz_t tmp cdef unsigned long int shift = 0 @@ -80,7 +89,10 @@ cdef biseq_t* list2biseq(biseq_t S, list data) except NULL: mpz_clear(tmp) return &S -cdef list biseq2list(biseq_t S): +cdef list biseq_to_list(biseq_t S): + """ + Convert a bounded integer sequence to a list of integers. + """ cdef mpz_t tmp, item sig_on() mpz_init_set(tmp, S.data) @@ -98,7 +110,11 @@ cdef list biseq2list(biseq_t S): mpz_clear(item) return L -cdef str biseq2str(biseq_t S): +cdef str biseq_to_str(biseq_t S): + """ + String representation of bounded integer sequence as comma + separated list of integers + """ cdef mpz_t tmp, item if S.length==0: return "" @@ -130,6 +146,20 @@ cdef str biseq2str(biseq_t S): # cdef biseq_t *concat_biseq(biseq_t S1, biseq_t S2) except NULL: + """ + Concatenate two bounded integer sequences. + + ASSUMPTION: + + - The two sequences must have equivalent bounds, i.e., the items on the + sequences must fit into the same number of bits. This condition is not + tested. + + OUTPUT: + + - A pointer to the concatenated sequence, or NULL on error. + + """ cdef biseq_t out out.bitsize = S1.bitsize+S2.bitsize out.length = S1.length+S2.length @@ -141,13 +171,35 @@ cdef biseq_t *concat_biseq(biseq_t S1, biseq_t S2) except NULL: mpz_ior(out.data, out.data, S1.data) return &out -#cdef inline int cmp_biseq(biseq_t S1, biseq_t S2): -# return mpz_cmp(S1.data, S2.data) - cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2): + """ + Tests if bounded integer sequence S1 starts with bounded integer sequence S2 + + ASSUMPTION: + + - The two sequences must have equivalent bounds, i.e., the items on the + sequences must fit into the same number of bits. This condition is not + tested. + + """ return mpz_congruent_2exp_p(S1.data, S2.data, S2.bitsize) cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start): + """ + Tests if bounded integer sequence S1[start:] contains a sub-sequence S2 + + INPUT: + + - ``S1``, ``S2`` -- two bounded integer sequences + - ``start`` -- integer, start index + + ASSUMPTION: + + - The two sequences must have equivalent bounds, i.e., the items on the + sequences must fit into the same number of bits. This condition is not + tested. + + """ if S1.length=S.length: return -1 cdef mpz_t tmp, mpz_item @@ -185,6 +242,10 @@ cdef int index_biseq(biseq_t S, int item, size_t start): return -1 cdef int getitem_biseq(biseq_t S, unsigned long int index): + """ + Get item S[index], without checking margins. + + """ cdef mpz_t tmp, item sig_on() mpz_init_set(tmp, S.data) @@ -198,6 +259,14 @@ cdef int getitem_biseq(biseq_t S, unsigned long int index): return out cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL: + """ + Create the slice S[start:stop:step] as bounded integer sequence. + + Return: + + - A pointer to the resulting bounded integer sequence, or NULL on error. + + """ cdef unsigned long int length, length1 if step>0: if stop>start: @@ -501,7 +570,7 @@ cdef class BoundedIntegerSequence: """ if bound==0: raise ValueError("Positive bound expected") - self.data = deref(list2biseq(self.data, data)) + self.data = deref(list_to_biseq(self.data, data)) if not self.data.itembitsize: raise ValueError("List of non-negative integers expected") @@ -519,6 +588,33 @@ cdef class BoundedIntegerSequence: """ return self + def __reduce__(self): + """ + Pickling of :class:`BoundedIntegerSequence` + + + EXAMPLES:: + + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: L = [randint(0,26) for i in range(5000)] + sage: S = BoundedIntegerSequence(32, L) + sage: loads(dumps(S)) == S # indirect doctest + True + + """ + cdef size_t n + cdef char *s + n = mpz_sizeinbase(self.data.data, 32) + 2 + s = PyMem_Malloc(n) + if s == NULL: + raise MemoryError, "Unable to allocate enough memory for the string defining a bounded integer sequence." + sig_on() + mpz_get_str(s, 32, self.data.data) + sig_off() + data_str = PyString_FromString(s) + PyMem_Free(s) + return NewBISEQ, (data_str, self.data.bitsize, self.data.itembitsize, self.data.length) + def __len__(self): """ EXAMPLES:: @@ -561,7 +657,7 @@ cdef class BoundedIntegerSequence: <4, 1, 6, 2, 7, 20, 9> """ - return biseq2str(self.data) + return biseq_to_str(self.data) def bound(self): """ @@ -922,3 +1018,24 @@ cdef class BoundedIntegerSequence: """ return mpz_pythonhash(self.data.data) + +cpdef BoundedIntegerSequence NewBISEQ(data, unsigned long int bitsize, unsigned int itembitsize, size_t length): + """ + Helper function for unpickling of :class:`BoundedIntegerSequence`. + + EXAMPLES:: + + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: L = [randint(0,26) for i in range(5000)] + sage: S = BoundedIntegerSequence(32, L) + sage: loads(dumps(S)) == S # indirect doctest + True + + """ + cdef BoundedIntegerSequence out = BoundedIntegerSequence.__new__(BoundedIntegerSequence, 0, None) + mpz_init2(out.data.data, bitsize+64) + out.data.bitsize = bitsize + out.data.itembitsize = itembitsize + out.data.length = length + mpz_set_str(out.data.data, data, 32) + return out From 050b118c9ce92b3c640ad4ea66b5c02dce87a172 Mon Sep 17 00:00:00 2001 From: Simon King Date: Sat, 31 May 2014 22:33:37 +0200 Subject: [PATCH 032/698] Improve access to items of bounded integer sequences --- src/sage/misc/bounded_integer_sequences.pxd | 3 +- src/sage/misc/bounded_integer_sequences.pyx | 44 +++++++++++++++------ 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pxd b/src/sage/misc/bounded_integer_sequences.pxd index cb8f4002559..55e90fdb0e6 100644 --- a/src/sage/misc/bounded_integer_sequences.pxd +++ b/src/sage/misc/bounded_integer_sequences.pxd @@ -8,6 +8,7 @@ ctypedef struct biseq_t: # bounded integer sequence type # items of this sequence, but store the # bitlength that is sufficient to store one # item. + unsigned int mask_item # "bla&mask_item" greps onethe item bla starts with size_t length # Number of items in this sequence. # bitsize=length*itembitsize, but we do not want # to repeat this multiplication and thus store @@ -43,7 +44,7 @@ cdef int index_biseq(biseq_t S, int item, size_t start) # Returns the position *in S* of the item in S[start:], or -1 if S[start:] # does not contain the item. -cdef int getitem_biseq(biseq_t S, unsigned long int index) +cdef int getitem_biseq(biseq_t S, unsigned long int index) except -1 # Returns S[index], without checking margins cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index a4fadc16d9e..44ab72ffa9e 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -23,9 +23,18 @@ include "sage/ext/python.pxi" cdef extern from "mpz_pylong.h": cdef long mpz_pythonhash(mpz_t src) +cdef extern from "gmp.h": + cdef int mp_bits_per_limb + mp_limb_t mpn_rshift(mp_ptr res, mp_ptr src, mp_size_t n, unsigned int count) + void mpn_copyi(mp_ptr res, mp_ptr src, mp_size_t n) + cdef extern from "Python.h": bint PySlice_Check(PyObject* ob) +cdef size_t times_size_of_limb = [1,2,4,8,16,32,64].index(sizeof(mp_limb_t)) +cdef size_t times_mp_bits_per_limb = [1,2,4,8,16,32,64,128,256].index(mp_bits_per_limb) +cdef size_t mod_mp_bits_per_limb = ((1)<ZeroNone cdef dict EmptyDict = {} @@ -52,6 +61,7 @@ cdef biseq_t* allocate_biseq(size_t l, unsigned long int itemsize) except NULL: out.bitsize = l*itemsize out.length = l out.itembitsize = itemsize + out.mask_item = ((1)<S.data) + cdef unsigned long int limb_index, bit_index, limb_size + index *= S.itembitsize + limb_index = index>>times_mp_bits_per_limb + bit_index = index&mod_mp_bits_per_limb + limb_size = ((bit_index+S.itembitsize-1)>>times_mp_bits_per_limb)+1 + cdef mp_limb_t* tmp_limb + cdef unsigned int out + if bit_index: + tmp_limb = sage_malloc(limb_size<deref(tmp_limb) + sage_free(tmp_limb) + else: + out = deref(seq._mp_d+limb_index) + return out&S.mask_item cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL: """ @@ -1036,6 +1055,7 @@ cpdef BoundedIntegerSequence NewBISEQ(data, unsigned long int bitsize, unsigned mpz_init2(out.data.data, bitsize+64) out.data.bitsize = bitsize out.data.itembitsize = itembitsize + out.data.mask_item = ((1)< Date: Sun, 1 Jun 2014 03:51:45 +0200 Subject: [PATCH 033/698] Improve conversion "list->bounded integer sequence" --- src/sage/misc/bounded_integer_sequences.pyx | 65 ++++++++++++--------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index 44ab72ffa9e..0355ac35a67 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -26,7 +26,11 @@ cdef extern from "mpz_pylong.h": cdef extern from "gmp.h": cdef int mp_bits_per_limb mp_limb_t mpn_rshift(mp_ptr res, mp_ptr src, mp_size_t n, unsigned int count) + mp_limb_t mpn_lshift(mp_ptr res, mp_ptr src, mp_size_t n, unsigned int count) void mpn_copyi(mp_ptr res, mp_ptr src, mp_size_t n) + void mpn_ior_n (mp_limb_t *rp, mp_limb_t *s1p, mp_limb_t *s2p, mp_size_t n) + void mpn_zero (mp_limb_t *rp, mp_size_t n) + void mpn_copyd (mp_limb_t *rp, mp_limb_t *s1p, mp_size_t n) cdef extern from "Python.h": bint PySlice_Check(PyObject* ob) @@ -40,7 +44,7 @@ cdef PyObject* zeroNone = ZeroNone cdef dict EmptyDict = {} cdef PyObject* emptyDict = EmptyDict -from cython.operator import dereference as deref +from cython.operator import dereference as deref, preincrement as preinc ################### # Boilerplate @@ -53,9 +57,9 @@ from cython.operator import dereference as deref cdef biseq_t* allocate_biseq(size_t l, unsigned long int itemsize) except NULL: """ - Allocate memory (filled with zero) for a bounded integer sequence of - length l with items fitting in itemsize bits. Returns a pointer to the - bounded integer sequence, or NULL on error. + Allocate memory for a bounded integer sequence of length l with items + fitting in itemsize bits. Returns a pointer to the bounded integer + sequence, or NULL on error. """ cdef biseq_t out out.bitsize = l*itemsize @@ -63,7 +67,7 @@ cdef biseq_t* allocate_biseq(size_t l, unsigned long int itemsize) except NULL: out.itembitsize = itemsize out.mask_item = ((1)<S.data + cdef mp_limb_t item_limb, *tmp_limb + S_boil._mp_size = (((len(data)*S.itembitsize)-1)>>times_mp_bits_per_limb)+1 + tmp_limb = sage_malloc(2<(item&S.mask_item) + offset_mod = offset&mod_mp_bits_per_limb + offset_div = offset>>times_mp_bits_per_limb + if offset_mod: + tmp_limb[1] = mpn_lshift(tmp_limb, &item_limb, 1, offset_mod) + if offset_div < S_boil._mp_size: + S_boil._mp_d[offset_div] |= tmp_limb[0] + S_boil._mp_d[offset_div+1] = tmp_limb[1] + else: + S_boil._mp_d[offset_div] |= tmp_limb[0] + else: + tmp_limb[0] = item_limb + S_boil._mp_d[offset_div] = tmp_limb[0] + offset += S.itembitsize + sage_free(tmp_limb) return &S cdef list biseq_to_list(biseq_t S): @@ -176,7 +191,7 @@ cdef biseq_t *concat_biseq(biseq_t S1, biseq_t S2) except NULL: out.itembitsize = S1.itembitsize # do not test == S2.itembitsize out.mask_item = S1.mask_item sig_on() - mpz_init2(out.data, out.bitsize+64) + mpz_init2(out.data, out.bitsize+mp_bits_per_limb) sig_off() mpz_mul_2exp(out.data, S2.data, S1.bitsize) mpz_ior(out.data, out.data, S1.data) @@ -491,7 +506,7 @@ cdef class BoundedIntegerSequence: sage: BoundedIntegerSequence(16, [2, 7, -20]) Traceback (most recent call last): ... - ValueError: List of non-negative integers expected + OverflowError: can't convert negative value to unsigned long sage: BoundedIntegerSequence(1, [2, 7, 0]) <0, 1, 0> sage: BoundedIntegerSequence(0, [2, 7, 0]) @@ -590,8 +605,6 @@ cdef class BoundedIntegerSequence: if bound==0: raise ValueError("Positive bound expected") self.data = deref(list_to_biseq(self.data, data)) - if not self.data.itembitsize: - raise ValueError("List of non-negative integers expected") def __copy__(self): """ @@ -1052,7 +1065,7 @@ cpdef BoundedIntegerSequence NewBISEQ(data, unsigned long int bitsize, unsigned """ cdef BoundedIntegerSequence out = BoundedIntegerSequence.__new__(BoundedIntegerSequence, 0, None) - mpz_init2(out.data.data, bitsize+64) + mpz_init2(out.data.data, bitsize+mp_bits_per_limb) out.data.bitsize = bitsize out.data.itembitsize = itembitsize out.data.mask_item = ((1)< Date: Sun, 1 Jun 2014 13:58:51 +0200 Subject: [PATCH 034/698] Improve iteration and list/string conversion of bounded integer sequences --- src/sage/misc/bounded_integer_sequences.pxd | 1 + src/sage/misc/bounded_integer_sequences.pyx | 145 +++++++++++--------- 2 files changed, 84 insertions(+), 62 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pxd b/src/sage/misc/bounded_integer_sequences.pxd index 55e90fdb0e6..274e2f2e8a0 100644 --- a/src/sage/misc/bounded_integer_sequences.pxd +++ b/src/sage/misc/bounded_integer_sequences.pxd @@ -54,5 +54,6 @@ cdef class BoundedIntegerSequence: cdef biseq_t data cdef str str(self) cpdef bint startswith(self, BoundedIntegerSequence other) + cpdef list list(self) cpdef BoundedIntegerSequence NewBISEQ(data, unsigned long int bitsize, unsigned int itembitsize, size_t length) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index 0355ac35a67..e1e1d89f621 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -118,21 +118,29 @@ cdef list biseq_to_list(biseq_t S): """ Convert a bounded integer sequence to a list of integers. """ - cdef mpz_t tmp, item - sig_on() - mpz_init_set(tmp, S.data) - mpz_init(item) - + cdef __mpz_struct seq + seq = deref(<__mpz_struct*>S.data) + cdef unsigned int index, limb_index, bit_index + index = 0 + cdef mp_limb_t *tmp_limb + tmp_limb = sage_malloc(2< i > 0: - mpz_fdiv_r_2exp(item, tmp, S.itembitsize) - L.append(mpz_get_ui(item)) - mpz_fdiv_q_2exp(tmp, tmp, S.itembitsize) - L.append(mpz_get_ui(tmp)) - sig_off() - mpz_clear(tmp) - mpz_clear(item) + cdef size_t n + for n from S.length>=n>0: + limb_index = index>>times_mp_bits_per_limb + bit_index = index&mod_mp_bits_per_limb + if bit_index: + if bit_index+S.itembitsize >= mp_bits_per_limb: + mpn_rshift(tmp_limb, seq._mp_d+limb_index, 2, bit_index) + L.append(tmp_limb[0]&S.mask_item) + else: + L.append(((seq._mp_d[limb_index])>>bit_index)&S.mask_item) + else: + L.append(seq._mp_d[limb_index]&S.mask_item) + index += S.itembitsize + sage_free(tmp_limb) return L cdef str biseq_to_str(biseq_t S): @@ -140,30 +148,29 @@ cdef str biseq_to_str(biseq_t S): String representation of bounded integer sequence as comma separated list of integers """ - cdef mpz_t tmp, item - if S.length==0: - return "" - sig_on() - mpz_init_set(tmp, S.data) - cdef char* s_item - # allocate enough memory to s_item - mpz_init_set_ui(item,1) - mpz_mul_2exp(item, item, S.itembitsize) - cdef size_t item10len = mpz_sizeinbase(item, 10)+2 - s_item = PyMem_Malloc(item10len) - sig_off() - if s_item == NULL: - raise MemoryError, "Unable to allocate enough memory for the string representation of bounded integer sequence." + cdef __mpz_struct seq + seq = deref(<__mpz_struct*>S.data) + cdef unsigned int index, limb_index, bit_index + index = 0 + cdef mp_limb_t *tmp_limb + tmp_limb = sage_malloc(2< i > 0: - mpz_fdiv_r_2exp(item, tmp, S.itembitsize) - L.append(PyString_FromString(mpz_get_str(s_item, 10, item))) - mpz_fdiv_q_2exp(tmp, tmp, S.itembitsize) - L.append(PyString_FromString(mpz_get_str(s_item, 10, tmp))) - mpz_clear(tmp) - mpz_clear(item) - PyMem_Free(s_item) + cdef size_t n + for n from S.length>=n>0: + limb_index = index>>times_mp_bits_per_limb + bit_index = index&mod_mp_bits_per_limb + if bit_index: + if bit_index+S.itembitsize >= mp_bits_per_limb: + mpn_rshift(tmp_limb, seq._mp_d+limb_index, 2, bit_index) + L.append(repr((tmp_limb[0]&S.mask_item))) + else: + L.append(repr((((seq._mp_d[limb_index])>>bit_index)&S.mask_item))) + else: + L.append(repr((seq._mp_d[limb_index]&S.mask_item))) + index += S.itembitsize + sage_free(tmp_limb) return ', '.join(L) # @@ -278,18 +285,21 @@ cdef int getitem_biseq(biseq_t S, unsigned long int index) except -1: index *= S.itembitsize limb_index = index>>times_mp_bits_per_limb bit_index = index&mod_mp_bits_per_limb - limb_size = ((bit_index+S.itembitsize-1)>>times_mp_bits_per_limb)+1 cdef mp_limb_t* tmp_limb - cdef unsigned int out + cdef int out if bit_index: - tmp_limb = sage_malloc(limb_size<deref(tmp_limb) - sage_free(tmp_limb) + limb_size = ((bit_index+S.itembitsize-1)>>times_mp_bits_per_limb)+1 + if limb_size!=1: + tmp_limb = sage_malloc(limb_size<deref(tmp_limb) + sage_free(tmp_limb) + else: + out = ((seq._mp_d[limb_index]))>>bit_index else: - out = deref(seq._mp_d+limb_index) + out = (seq._mp_d[limb_index]) return out&S.mask_item cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL: @@ -723,20 +733,28 @@ cdef class BoundedIntegerSequence: True """ - cdef size_t i - cdef mpz_t tmp,item - if self.data.length>0: - sig_on() - mpz_init_set(tmp, self.data.data) - mpz_init2(item, self.data.itembitsize) - sig_off() - for i from self.data.length>i>0: - mpz_fdiv_r_2exp(item, tmp, self.data.itembitsize) - yield mpz_get_si(item) - mpz_fdiv_q_2exp(tmp, tmp, self.data.itembitsize) - yield mpz_get_si(tmp) - mpz_clear(tmp) - mpz_clear(item) + cdef __mpz_struct seq + seq = deref(<__mpz_struct*>self.data.data) + cdef unsigned int index, limb_index, bit_index + index = 0 + cdef mp_limb_t *tmp_limb + tmp_limb = sage_malloc(2<=n>0: + limb_index = index>>times_mp_bits_per_limb + bit_index = index&mod_mp_bits_per_limb + if bit_index: + if bit_index+self.data.itembitsize >= mp_bits_per_limb: + mpn_rshift(tmp_limb, seq._mp_d+limb_index, 2, bit_index) + yield (tmp_limb[0]&self.data.mask_item) + else: + yield (((seq._mp_d[limb_index])>>bit_index)&self.data.mask_item) + else: + yield (seq._mp_d[limb_index]&self.data.mask_item) + index += self.data.itembitsize + sage_free(tmp_limb) def __getitem__(self, index): """ @@ -823,6 +841,9 @@ cdef class BoundedIntegerSequence: return False return contains_biseq(self.data, right.data, 0)>=0 + cpdef list list(self): + return biseq_to_list(self.data) + cpdef bint startswith(self, BoundedIntegerSequence other): """ Tells whether ``self`` starts with a given bounded integer sequence @@ -946,12 +967,12 @@ cdef class BoundedIntegerSequence: sage: T+None Traceback (most recent call last): ... - TypeError: Can not concatenate bounded integer sequence and None + TypeError: Cannot concatenate bounded integer sequence and None """ cdef BoundedIntegerSequence myself, right, out if other is None or self is None: - raise TypeError('Can not concatenate bounded integer sequence and None') + raise TypeError('Cannot concatenate bounded integer sequence and None') myself = self # may result in a type error right = other # --"-- if right.data.itembitsize!=myself.data.itembitsize: From c8a299ba54fa05d6851fd492019d9996e7e31515 Mon Sep 17 00:00:00 2001 From: Simon King Date: Sun, 1 Jun 2014 14:36:21 +0200 Subject: [PATCH 035/698] More documentation of bounded integer sequences --- src/sage/misc/bounded_integer_sequences.pyx | 60 +++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index e1e1d89f621..3c4cc18d718 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -5,6 +5,49 @@ AUTHORS: - Simon King (2014): initial version +This module provides :class:`BoundedIntegerSequence`, which implements +sequences of bounded integers and is for many (but not all) operations faster +than representing the same sequence as a Python :class:`tuple`. + +It also provides some boilerplate functions that can be cimported in Cython +modules:: + + cdef biseq_t* allocate_biseq(size_t l, unsigned long int itemsize) except NULL + # Allocate memory (filled with zero) for a bounded integer sequence + # of length l with items fitting in itemsize bits. + + cdef biseq_t* list_to_biseq(biseq_t S, list data) except NULL + # Assumes that S is allocated + + cdef list biseq_to_list(biseq_t S) + # Convert a bounded integer sequence to a list + + cdef str biseq_to_str(biseq_t S) + # String representation of bounded integer sequence as comma + # separated list + + cdef biseq_t* concat_biseq(biseq_t S1, biseq_t S2) except NULL + # Does not test whether the sequences have the same bound! + + cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2) + # Is S1=S2+something? Does not check whether the sequences have the same + # bound! + + cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start) + # Returns the position *in S1* of S2 as a subsequence of S1[start:], or -1 + # if S2 is not a subsequence. Does not check whether the sequences have the + # same bound! + + cdef int index_biseq(biseq_t S, int item, size_t start) + # Returns the position *in S* of the item in S[start:], or -1 if S[start:] + # does not contain the item. + + cdef int getitem_biseq(biseq_t S, unsigned long int index) except -1 + # Returns S[index], without checking margins + + cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL + # Returns the biseq S[start:stop:step] + """ #***************************************************************************** # Copyright (C) 2014 Simon King @@ -842,6 +885,23 @@ cdef class BoundedIntegerSequence: return contains_biseq(self.data, right.data, 0)>=0 cpdef list list(self): + """ + Converts this bounded integer sequence to a list + + NOTE: + + A conversion to a list is also possible by iterating over the + sequence, which actually is faster. + + EXAMPLES:: + + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: L = [randint(0,26) for i in range(5000)] + sage: S = BoundedIntegerSequence(32, L) + sage: S.list() == list(S) == L + True + + """ return biseq_to_list(self.data) cpdef bint startswith(self, BoundedIntegerSequence other): From 775d7955c67cb27af3ec8877491a3d7478fa8579 Mon Sep 17 00:00:00 2001 From: Simon King Date: Sun, 1 Jun 2014 19:08:03 +0200 Subject: [PATCH 036/698] Improve index computation for bounded integer sequences --- src/sage/misc/bounded_integer_sequences.pxd | 2 +- src/sage/misc/bounded_integer_sequences.pyx | 46 +++++++++++++-------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pxd b/src/sage/misc/bounded_integer_sequences.pxd index 274e2f2e8a0..9464b89cdbd 100644 --- a/src/sage/misc/bounded_integer_sequences.pxd +++ b/src/sage/misc/bounded_integer_sequences.pxd @@ -40,7 +40,7 @@ cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start) # if S2 is not a subsequence. Does not check whether the sequences have the # same bound! -cdef int index_biseq(biseq_t S, int item, size_t start) +cdef int index_biseq(biseq_t S, int item, size_t start) except -2 # Returns the position *in S* of the item in S[start:], or -1 if S[start:] # does not contain the item. diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index 3c4cc18d718..666b12cc84b 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -292,29 +292,39 @@ cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start): mpz_clear(tmp) return -1 -cdef int index_biseq(biseq_t S, int item, size_t start): +cdef int index_biseq(biseq_t S, int item, size_t start) except -2: """ Returns the position in S of an item in S[start:], or -1 if S[start:] does not contain the item. """ - if start>=S.length: - return -1 - cdef mpz_t tmp, mpz_item - sig_on() - mpz_init_set(tmp, S.data) - sig_off() - mpz_fdiv_q_2exp(tmp, tmp, start*S.itembitsize) - mpz_init_set_ui(mpz_item, item) - cdef size_t i - for i from start<=iS.data) + + cdef unsigned int n, limb_index, bit_index + cdef mp_limb_t *tmp_limb + tmp_limb = sage_malloc(2<>times_mp_bits_per_limb + bit_index = n&mod_mp_bits_per_limb + if bit_index: + if bit_index+S.itembitsize >= mp_bits_per_limb: + mpn_rshift(tmp_limb, seq._mp_d+limb_index, 2, bit_index) + if item==(tmp_limb[0]&S.mask_item): + sage_free(tmp_limb) + return index + elif item==(((seq._mp_d[limb_index])>>bit_index)&S.mask_item): + sage_free(tmp_limb) + return index + elif item==(seq._mp_d[limb_index]&S.mask_item): + return index + n += S.itembitsize + sage_free(tmp_limb) return -1 cdef int getitem_biseq(biseq_t S, unsigned long int index) except -1: From 391a102f2b5623979c214a725092eeb3dbe180f6 Mon Sep 17 00:00:00 2001 From: Simon King Date: Sun, 1 Jun 2014 20:02:07 +0200 Subject: [PATCH 037/698] Improve bounded integer subsequent containment test --- src/sage/misc/bounded_integer_sequences.pyx | 27 ++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index 666b12cc84b..7941afa7965 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -278,17 +278,32 @@ cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start): """ if S1.lengthS2.data) + limb_size = seq._mp_size+1 cdef mpz_t tmp + # Idea: We shift-copy enough limbs from S1 to tmp and then compare with + # S2, for each shift. sig_on() - mpz_init_set(tmp, S1.data) + mpz_init2(tmp, S2.bitsize+mp_bits_per_limb) sig_off() - mpz_fdiv_q_2exp(tmp, tmp, start*S1.itembitsize) - cdef size_t i - for i from start<=i<=S1.length-S2.length: + (<__mpz_struct*>tmp)._mp_size = seq._mp_size + seq = deref(<__mpz_struct*>S1.data) + cdef unsigned int n, limb_index, bit_index + n = 0 + cdef int index = 0 + for index from 0<=index<=S1.length-S2.length: + limb_index = n>>times_mp_bits_per_limb + bit_index = n&mod_mp_bits_per_limb + if bit_index: + mpn_rshift((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, limb_size, bit_index) + else: + mpn_copyi((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, limb_size) if mpz_congruent_2exp_p(tmp, S2.data, S2.bitsize): mpz_clear(tmp) - return i - mpz_fdiv_q_2exp(tmp, tmp, S1.itembitsize) + return index + n += S1.itembitsize mpz_clear(tmp) return -1 From 735939e593c9c302ff42c4973cbfe2e48eb22644 Mon Sep 17 00:00:00 2001 From: Simon King Date: Tue, 3 Jun 2014 08:39:59 +0200 Subject: [PATCH 038/698] Improve slicing of bounded integer sequences --- src/sage/misc/bounded_integer_sequences.pyx | 107 ++++++++++++-------- 1 file changed, 63 insertions(+), 44 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index 7941afa7965..9a59463491b 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -131,10 +131,9 @@ cdef biseq_t* list_to_biseq(biseq_t S, list data) except NULL: cdef __mpz_struct *S_boil S_boil = <__mpz_struct*>S.data cdef mp_limb_t item_limb, *tmp_limb - S_boil._mp_size = (((len(data)*S.itembitsize)-1)>>times_mp_bits_per_limb)+1 - tmp_limb = sage_malloc(2<sage_malloc(sizeof(mp_limb_t)) if tmp_limb==NULL: - raise MemoryError("Cannot even allocate two long integers") + raise MemoryError("Cannot even allocate one long integer") cdef int offset_mod, offset_div cdef int offset = 0 if not data: @@ -144,16 +143,15 @@ cdef biseq_t* list_to_biseq(biseq_t S, list data) except NULL: offset_mod = offset&mod_mp_bits_per_limb offset_div = offset>>times_mp_bits_per_limb if offset_mod: - tmp_limb[1] = mpn_lshift(tmp_limb, &item_limb, 1, offset_mod) - if offset_div < S_boil._mp_size: - S_boil._mp_d[offset_div] |= tmp_limb[0] - S_boil._mp_d[offset_div+1] = tmp_limb[1] - else: - S_boil._mp_d[offset_div] |= tmp_limb[0] + S_boil._mp_d[offset_div+1] = mpn_lshift(tmp_limb, &item_limb, 1, offset_mod) + S_boil._mp_d[offset_div] |= tmp_limb[0] else: - tmp_limb[0] = item_limb - S_boil._mp_d[offset_div] = tmp_limb[0] + S_boil._mp_d[offset_div] = item_limb offset += S.itembitsize + if offset_mod and S_boil._mp_d[offset_div+1]: + S_boil._mp_size = offset_div+2 + else: + S_boil._mp_size = offset_div+1 sage_free(tmp_limb) return &S @@ -379,7 +377,7 @@ cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL: - A pointer to the resulting bounded integer sequence, or NULL on error. """ - cdef unsigned long int length, length1 + cdef unsigned long int length, total_shift, n if step>0: if stop>start: length = ((stop-start-1)//step)+1 @@ -392,40 +390,61 @@ cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL: length = ((stop-start+1)//step)+1 cdef biseq_t out out = deref(allocate_biseq(length, S.itembitsize)) - cdef mpz_t tmp + cdef unsigned int offset_mod, offset_div, limb_size + total_shift = start*S.itembitsize if step==1: - sig_on() - mpz_init_set(tmp, S.data) - sig_off() - mpz_fdiv_q_2exp(tmp, tmp, start*S.itembitsize) - mpz_fdiv_r_2exp(out.data, tmp, out.bitsize) - mpz_clear(tmp) + # allocate_biseq allocates one limb more than strictly needed. This is + # enough to shift a limb* array directly to its ._mp_d field. + offset_mod = total_shift&mod_mp_bits_per_limb + offset_div = total_shift>>times_mp_bits_per_limb + limb_size = ((offset_mod+out.bitsize-1)>>times_mp_bits_per_limb)+1 + mpn_rshift((<__mpz_struct*>(out.data))._mp_d, (<__mpz_struct*>(S.data))._mp_d+offset_div, limb_size, offset_mod) + (<__mpz_struct*>(out.data))._mp_size = limb_size + mpz_fdiv_r_2exp(out.data, out.data, out.bitsize) return &out - cdef mpz_t item - sig_on() - mpz_init_set(tmp, S.data) - mpz_init2(item, S.itembitsize) - sig_off() - cdef unsigned long int bitstep - if step>0: - mpz_fdiv_q_2exp(tmp, tmp, start*S.itembitsize) - bitstep = out.itembitsize*step - for i from 0<=isage_malloc(2<S.data + cdef int bitstep = step*S.itembitsize + cdef int offset_mod_tgt, offset_div_tgt + cdef int offset_tgt = 0 + cdef __mpz_struct *seq_tgt + seq_tgt = <__mpz_struct*>out.data + for n from length>=n>0: + offset_div_src = offset_src>>times_mp_bits_per_limb + offset_mod_src = offset_src&mod_mp_bits_per_limb + offset_div_tgt = offset_tgt>>times_mp_bits_per_limb + offset_mod_tgt = offset_tgt&mod_mp_bits_per_limb + # put data from src to tmp_limb[0] + if offset_mod_src: + if offset_mod_src+S.itembitsize >= mp_bits_per_limb: + mpn_rshift(tmp_limb, seq_src._mp_d+offset_div_src, 2, offset_mod_src) + else: + tmp_limb[0] = (seq_src._mp_d[offset_div_src])>>offset_mod_src + else: + tmp_limb[0] = seq_src._mp_d[offset_div_src] + tmp_limb[0] &= S.mask_item + # put data from tmp_limb[0] to tgt + if offset_mod_tgt: + seq_tgt._mp_d[offset_div_tgt+1] = mpn_lshift(tmp_limb, tmp_limb, 1, offset_mod_tgt) + seq_tgt._mp_d[offset_div_tgt] |= tmp_limb[0] + else: + seq_tgt._mp_d[offset_div_tgt] = tmp_limb[0] + offset_tgt += S.itembitsize + offset_src += bitstep + if offset_mod_tgt and seq_tgt._mp_d[offset_div_tgt+1]: + seq_tgt._mp_size = offset_div_tgt+2 else: - bitstep = out.itembitsize*(-step) - length1 = length-1 - mpz_fdiv_q_2exp(tmp, tmp, (start+length1*step)*S.itembitsize) - for i from 0<=i list(T) # direct lexicographic ordering is different + sage: list(S) > list(T) # direct lexicographic ordering is different True TESTS: From c900a2cd4045aa3463be31d76c9f047b05571958 Mon Sep 17 00:00:00 2001 From: Simon King Date: Thu, 5 Jun 2014 23:09:20 +0200 Subject: [PATCH 039/698] Take care of GMP's removal of trailing zeroes --- src/sage/misc/bounded_integer_sequences.pyx | 287 ++++++++++++++++---- 1 file changed, 236 insertions(+), 51 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index 9a59463491b..ca43286d52c 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -74,6 +74,7 @@ cdef extern from "gmp.h": void mpn_ior_n (mp_limb_t *rp, mp_limb_t *s1p, mp_limb_t *s2p, mp_size_t n) void mpn_zero (mp_limb_t *rp, mp_size_t n) void mpn_copyd (mp_limb_t *rp, mp_limb_t *s1p, mp_size_t n) + int mpn_cmp (mp_limb_t *s1p, mp_limb_t *s2p, mp_size_t n) cdef extern from "Python.h": bint PySlice_Check(PyObject* ob) @@ -130,7 +131,8 @@ cdef biseq_t* list_to_biseq(biseq_t S, list data) except NULL: cdef unsigned long int item cdef __mpz_struct *S_boil S_boil = <__mpz_struct*>S.data - cdef mp_limb_t item_limb, *tmp_limb + cdef mp_limb_t item_limb + cdef mp_limb_t *tmp_limb tmp_limb = sage_malloc(sizeof(mp_limb_t)) if tmp_limb==NULL: raise MemoryError("Cannot even allocate one long integer") @@ -148,10 +150,11 @@ cdef biseq_t* list_to_biseq(biseq_t S, list data) except NULL: else: S_boil._mp_d[offset_div] = item_limb offset += S.itembitsize - if offset_mod and S_boil._mp_d[offset_div+1]: - S_boil._mp_size = offset_div+2 - else: - S_boil._mp_size = offset_div+1 + cdef unsigned long int i + for i from offset_div+(1 if offset_mod else 0)>=i>=0: + if S_boil._mp_d[i]: + break + S_boil._mp_size = i+1 sage_free(tmp_limb) return &S @@ -161,7 +164,7 @@ cdef list biseq_to_list(biseq_t S): """ cdef __mpz_struct seq seq = deref(<__mpz_struct*>S.data) - cdef unsigned int index, limb_index, bit_index + cdef unsigned int index, limb_index, bit_index, max_limb index = 0 cdef mp_limb_t *tmp_limb tmp_limb = sage_malloc(2<=n>0: limb_index = index>>times_mp_bits_per_limb bit_index = index&mod_mp_bits_per_limb - if bit_index: - if bit_index+S.itembitsize >= mp_bits_per_limb: - mpn_rshift(tmp_limb, seq._mp_d+limb_index, 2, bit_index) - L.append(tmp_limb[0]&S.mask_item) + # Problem: GMP tries to be clever, and sometimes removes trailing + # zeroes. Hence, we must take care to not read bits from non-allocated + # memory. + if limb_index < max_limb: + if bit_index: + if bit_index+S.itembitsize >= mp_bits_per_limb: + mpn_rshift(tmp_limb, seq._mp_d+limb_index, 2, bit_index) + L.append((tmp_limb[0]&S.mask_item)) + else: + L.append((((seq._mp_d[limb_index])>>bit_index)&S.mask_item)) + else: + L.append((seq._mp_d[limb_index]&S.mask_item)) + elif limb_index == max_limb: + if bit_index: + L.append((((seq._mp_d[limb_index])>>bit_index)&S.mask_item)) else: - L.append(((seq._mp_d[limb_index])>>bit_index)&S.mask_item) + L.append((seq._mp_d[limb_index]&S.mask_item)) else: - L.append(seq._mp_d[limb_index]&S.mask_item) + break index += S.itembitsize + if n: + L.extend([int(0)]*n) sage_free(tmp_limb) return L @@ -191,7 +211,7 @@ cdef str biseq_to_str(biseq_t S): """ cdef __mpz_struct seq seq = deref(<__mpz_struct*>S.data) - cdef unsigned int index, limb_index, bit_index + cdef unsigned int index, limb_index, bit_index, max_limb index = 0 cdef mp_limb_t *tmp_limb tmp_limb = sage_malloc(2<=n>0: limb_index = index>>times_mp_bits_per_limb bit_index = index&mod_mp_bits_per_limb - if bit_index: - if bit_index+S.itembitsize >= mp_bits_per_limb: - mpn_rshift(tmp_limb, seq._mp_d+limb_index, 2, bit_index) - L.append(repr((tmp_limb[0]&S.mask_item))) + if limb_index < max_limb: + if bit_index: + if bit_index+S.itembitsize >= mp_bits_per_limb: + mpn_rshift(tmp_limb, seq._mp_d+limb_index, 2, bit_index) + L.append(repr((tmp_limb[0]&S.mask_item))) + else: + L.append(repr((((seq._mp_d[limb_index])>>bit_index)&S.mask_item))) else: + L.append(repr((seq._mp_d[limb_index]&S.mask_item))) + elif limb_index == max_limb: + if bit_index: L.append(repr((((seq._mp_d[limb_index])>>bit_index)&S.mask_item))) + else: + L.append(repr((seq._mp_d[limb_index]&S.mask_item))) else: - L.append(repr((seq._mp_d[limb_index]&S.mask_item))) + break index += S.itembitsize + if n: + L.extend(["0"]*n) sage_free(tmp_limb) return ', '.join(L) @@ -239,7 +273,7 @@ cdef biseq_t *concat_biseq(biseq_t S1, biseq_t S2) except NULL: out.itembitsize = S1.itembitsize # do not test == S2.itembitsize out.mask_item = S1.mask_item sig_on() - mpz_init2(out.data, out.bitsize+mp_bits_per_limb) + mpz_init2(out.data, out.bitsize) sig_off() mpz_mul_2exp(out.data, S2.data, S1.bitsize) mpz_ior(out.data, out.data, S1.data) @@ -277,15 +311,41 @@ cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start): if S1.lengthS2.data) limb_size = seq._mp_size+1 + limb_size_orig = seq._mp_size # not "+1", because we only need to do + # something special if we move strictly + # less limbs than fitting into S2. cdef mpz_t tmp # Idea: We shift-copy enough limbs from S1 to tmp and then compare with # S2, for each shift. sig_on() mpz_init2(tmp, S2.bitsize+mp_bits_per_limb) sig_off() + # We will use tmp to store enough bits to be able to compare with S2. + # Hence, we say that its _mp_size is equal to that of S2. This may not be + # correct, as we move bits from S1 (hence, there might be different + # trailing zeroes), but this is not critical for the mpz_* functions we + # are using here: _mp_size must be big enough, but can be bigger than + # needed. + # + # Problem: When bitshifting data of S1, it may happen that S1 has some + # cut-off trailing zeroes. In this case, the bit-shift will not fill all + # allocated memory, and thus the highest limbs of tmp may still be + # non-zero from previous bitshifts. If the highest limb of S2 happens to + # be equal to this non-zero artifact of previous bitshift operations on + # S1, then the congruence tests will give the wrong result (telling that + # S2 in S1 even though the last items of S2 are non-zero and the + # corresponding items of S1 are zero. + # + # Solution: We only shift the limbs of S1 that are guaranteed to be + # correct. Then, we compare S2 with the shifted version of S1 at most up + # to the number of valid limbs. If S2's _mp_size is not larger than that, + # then it is a sub-sequence; otherwise (provided that we are keeping track + # of _mp_size correctly!!!) it has non-zero bits where S1 has (cut-off) + # trailing zeroes, and can thus be no sub-sequence (also not for higher + # index). (<__mpz_struct*>tmp)._mp_size = seq._mp_size seq = deref(<__mpz_struct*>S1.data) cdef unsigned int n, limb_index, bit_index @@ -293,12 +353,25 @@ cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start): cdef int index = 0 for index from 0<=index<=S1.length-S2.length: limb_index = n>>times_mp_bits_per_limb + # Adjust the number of limbs we are shifting + limb_size = min(limb_size, seq._mp_size-limb_index) bit_index = n&mod_mp_bits_per_limb if bit_index: mpn_rshift((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, limb_size, bit_index) else: mpn_copyi((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, limb_size) - if mpz_congruent_2exp_p(tmp, S2.data, S2.bitsize): + # If limb_size is now smaller than limb_size_orig, then we were + # running into trailing zeroes of S1. Hence, as explained above, we + # can decide now whether S2 is a sub-sequence of S1 in the case that + # the non-cutoff bits match. + if limb_sizetmp)._mp_d, (<__mpz_struct*>(S2.data))._mp_d, limb_size)==0: + mpz_clear(tmp) + if (<__mpz_struct*>(S2.data))._mp_size > limb_size: + return -1 + return index + elif mpz_congruent_2exp_p(tmp, S2.data, S2.bitsize): mpz_clear(tmp) return index n += S1.itembitsize @@ -314,28 +387,46 @@ cdef int index_biseq(biseq_t S, int item, size_t start) except -2: cdef __mpz_struct seq seq = deref(<__mpz_struct*>S.data) - cdef unsigned int n, limb_index, bit_index + cdef unsigned int n, limb_index, bit_index, max_limb cdef mp_limb_t *tmp_limb tmp_limb = sage_malloc(2<>times_mp_bits_per_limb bit_index = n&mod_mp_bits_per_limb - if bit_index: - if bit_index+S.itembitsize >= mp_bits_per_limb: - mpn_rshift(tmp_limb, seq._mp_d+limb_index, 2, bit_index) - if item==(tmp_limb[0]&S.mask_item): + if limb_index < max_limb: + if bit_index: + if bit_index+S.itembitsize >= mp_bits_per_limb: + mpn_rshift(tmp_limb, seq._mp_d+limb_index, 2, bit_index) + if item==(tmp_limb[0]&S.mask_item): + sage_free(tmp_limb) + return index + elif item==(((seq._mp_d[limb_index])>>bit_index)&S.mask_item): sage_free(tmp_limb) return index - elif item==(((seq._mp_d[limb_index])>>bit_index)&S.mask_item): - sage_free(tmp_limb) + elif item==(seq._mp_d[limb_index]&S.mask_item): return index - elif item==(seq._mp_d[limb_index]&S.mask_item): - return index + elif limb_index == max_limb: + if bit_index: + if item==(((seq._mp_d[limb_index])>>bit_index)&S.mask_item): + sage_free(tmp_limb) + return index + elif item==(seq._mp_d[limb_index]&S.mask_item): + return index + else: + sage_free(tmp_limb) + if item==0 and index=seq._mp_size: + return 0 if bit_index: + # limb_size is 1 or 2 limb_size = ((bit_index+S.itembitsize-1)>>times_mp_bits_per_limb)+1 + if limb_index+limb_size>=seq._mp_size: + limb_size = 1 # the second limb may be non-allocated memory and + # should be treated as zero. if limb_size!=1: tmp_limb = sage_malloc(limb_size<deref(tmp_limb) sage_free(tmp_limb) else: - out = ((seq._mp_d[limb_index]))>>bit_index + out = ((seq._mp_d[limb_index])>>bit_index) else: out = (seq._mp_d[limb_index]) return out&S.mask_item @@ -398,8 +495,15 @@ cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL: offset_mod = total_shift&mod_mp_bits_per_limb offset_div = total_shift>>times_mp_bits_per_limb limb_size = ((offset_mod+out.bitsize-1)>>times_mp_bits_per_limb)+1 + # GMP tries to be clever and thus may cut trailing zeroes. Hence, + # limb_size may be so large that it would access non-allocated + # memory. We adjust this now: + limb_size = min(limb_size, (<__mpz_struct*>(S.data))._mp_size-offset_div) mpn_rshift((<__mpz_struct*>(out.data))._mp_d, (<__mpz_struct*>(S.data))._mp_d+offset_div, limb_size, offset_mod) - (<__mpz_struct*>(out.data))._mp_size = limb_size + for n from limb_size>n>=0: + if (<__mpz_struct*>(out.data))._mp_d[n]: + break + (<__mpz_struct*>(out.data))._mp_size = n+1 mpz_fdiv_r_2exp(out.data, out.data, out.bitsize) return &out @@ -409,10 +513,13 @@ cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL: tmp_limb = sage_malloc(2<S.data + # We need to take into account that GMP tries to be clever, and removes + # trailing zeroes from the allocated memory. + max_limb = seq_src._mp_size - 1 cdef int bitstep = step*S.itembitsize cdef int offset_mod_tgt, offset_div_tgt cdef int offset_tgt = 0 @@ -423,15 +530,23 @@ cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL: offset_mod_src = offset_src&mod_mp_bits_per_limb offset_div_tgt = offset_tgt>>times_mp_bits_per_limb offset_mod_tgt = offset_tgt&mod_mp_bits_per_limb - # put data from src to tmp_limb[0] - if offset_mod_src: - if offset_mod_src+S.itembitsize >= mp_bits_per_limb: - mpn_rshift(tmp_limb, seq_src._mp_d+offset_div_src, 2, offset_mod_src) + # put data from src to tmp_limb[0]. + if offset_div_src < max_limb: + if offset_mod_src: + if (offset_mod_src+S.itembitsize >= mp_bits_per_limb): + mpn_rshift(tmp_limb, seq_src._mp_d+offset_div_src, 2, offset_mod_src) + else: + tmp_limb[0] = (seq_src._mp_d[offset_div_src])>>offset_mod_src else: + tmp_limb[0] = seq_src._mp_d[offset_div_src] + tmp_limb[0] &= S.mask_item + elif offset_div_src == max_limb: + if offset_mod_src: tmp_limb[0] = (seq_src._mp_d[offset_div_src])>>offset_mod_src + else: + tmp_limb[0] = seq_src._mp_d[offset_div_src] else: - tmp_limb[0] = seq_src._mp_d[offset_div_src] - tmp_limb[0] &= S.mask_item + tmp_limb[0] = 0 # put data from tmp_limb[0] to tgt if offset_mod_tgt: seq_tgt._mp_d[offset_div_tgt+1] = mpn_lshift(tmp_limb, tmp_limb, 1, offset_mod_tgt) @@ -440,10 +555,10 @@ cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL: seq_tgt._mp_d[offset_div_tgt] = tmp_limb[0] offset_tgt += S.itembitsize offset_src += bitstep - if offset_mod_tgt and seq_tgt._mp_d[offset_div_tgt+1]: - seq_tgt._mp_size = offset_div_tgt+2 - else: - seq_tgt._mp_size = offset_div_tgt+1 + for n from offset_div_tgt+(1 if offset_mod_tgt else 0)>=n>=0: + if seq_tgt._mp_d[n]: + break + seq_tgt._mp_size = n+1 sage_free(tmp_limb) return &out @@ -730,6 +845,24 @@ cdef class BoundedIntegerSequence: sage: loads(dumps(S)) == S # indirect doctest True + TESTS: + + The discussion at :trac:`15820` explains why the following is a good test:: + + sage: X = BoundedIntegerSequence(21, [4,1,6,2,7,2,3]) + sage: S = BoundedIntegerSequence(21, [0,0,0,0,0,0,0]) + sage: loads(dumps(X+S)) + <4, 1, 6, 2, 7, 2, 3, 0, 0, 0, 0, 0, 0, 0> + sage: loads(dumps(X+S)) == X+S + True + sage: T = BoundedIntegerSequence(21, [0,4,0,1,0,6,0,2,0,7,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) + sage: T[1::2] + <4, 1, 6, 2, 7, 2, 3, 0, 0, 0, 0, 0, 0, 0> + sage: T[1::2] == X+S + True + sage: loads(dumps(X[1::2])) == X[1::2] + True + """ cdef size_t n cdef char *s @@ -819,27 +952,49 @@ cdef class BoundedIntegerSequence: sage: list(S) == L # indirect doctest True + TESTS: + + The discussion at :trac:`15820` explains why this is a good test:: + + sage: S = BoundedIntegerSequence(21, [0,0,0,0,0,0,0]) + sage: X = BoundedIntegerSequence(21, [4,1,6,2,7,2,3]) + sage: list(X) + [4, 1, 6, 2, 7, 2, 3] + sage: list(X+S) + [4, 1, 6, 2, 7, 2, 3, 0, 0, 0, 0, 0, 0, 0] + """ cdef __mpz_struct seq seq = deref(<__mpz_struct*>self.data.data) - cdef unsigned int index, limb_index, bit_index + cdef unsigned int index, limb_index, bit_index, max_limb index = 0 cdef mp_limb_t *tmp_limb tmp_limb = sage_malloc(2<=n>0: limb_index = index>>times_mp_bits_per_limb bit_index = index&mod_mp_bits_per_limb - if bit_index: - if bit_index+self.data.itembitsize >= mp_bits_per_limb: - mpn_rshift(tmp_limb, seq._mp_d+limb_index, 2, bit_index) - yield (tmp_limb[0]&self.data.mask_item) + if limb_index < max_limb: + if bit_index: + if bit_index+self.data.itembitsize >= mp_bits_per_limb: + mpn_rshift(tmp_limb, seq._mp_d+limb_index, 2, bit_index) + yield (tmp_limb[0]&self.data.mask_item) + else: + yield (((seq._mp_d[limb_index])>>bit_index)&self.data.mask_item) else: - yield (((seq._mp_d[limb_index])>>bit_index)&self.data.mask_item) + yield (seq._mp_d[limb_index]&self.data.mask_item) + elif limb_index == max_limb: + yield (((seq._mp_d[limb_index])>>bit_index)&self.data.mask_item) else: - yield (seq._mp_d[limb_index]&self.data.mask_item) + for n2 from n>=n2>0: + yield 0 + break index += self.data.itembitsize sage_free(tmp_limb) @@ -873,6 +1028,15 @@ cdef class BoundedIntegerSequence: sage: S[:] is S True + :: + + sage: S = BoundedIntegerSequence(21, [0,0,0,0,0,0,0]) + sage: X = BoundedIntegerSequence(21, [4,1,6,2,7,2,3]) + sage: (X+S)[6] + 3 + sage: (X+S)[10] + 0 + """ cdef BoundedIntegerSequence out cdef int start,stop,step @@ -920,6 +1084,25 @@ cdef class BoundedIntegerSequence: sage: S.index(6) == S.index(6+S.bound()) True + TESTS: + + The discussion at :trac:`15820` explains why the following is a good test:: + + sage: X = BoundedIntegerSequence(21, [4,1,6,2,7,2,3]) + sage: S = BoundedIntegerSequence(21, [0,0,0,0,0,0,0]) + sage: loads(dumps(X+S)) + <4, 1, 6, 2, 7, 2, 3, 0, 0, 0, 0, 0, 0, 0> + sage: loads(dumps(X+S)) == X+S + True + sage: T = BoundedIntegerSequence(21, [0,4,0,1,0,6,0,2,0,7,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) + sage: T[3::2]==(X+S)[1:] + True + sage: T[3::2] in X+S + True + sage: T = BoundedIntegerSequence(21, [0,4,0,1,0,6,0,2,0,7,0,2,0,3,0,0,0,16,0,0,0,0,0,0,0,0,0,0]) + sage: T[3::2] in (X+S) + False + """ if not isinstance(other, BoundedIntegerSequence): return index_biseq(self.data, other, 0)>=0 @@ -1064,6 +1247,8 @@ cdef class BoundedIntegerSequence: True sage: T in S+T True + sage: BoundedIntegerSequence(21, [4,1,6,2,7,20,9,4]) in S+T + True sage: T+list(S) Traceback (most recent call last): ... From 1192c211965ea1dcf1fdbaeaec7e68bf61ba265e Mon Sep 17 00:00:00 2001 From: Simon King Date: Mon, 9 Jun 2014 09:25:30 +0200 Subject: [PATCH 040/698] Allow empty slices; bounded integer sequence -> bool --- src/sage/misc/bounded_integer_sequences.pyx | 25 +++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index ca43286d52c..d2353bc282b 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -479,10 +479,10 @@ cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL: if stop>start: length = ((stop-start-1)//step)+1 else: - length = 0 + return allocate_biseq(0, S.itembitsize) else: if stop>=start: - length = 0 + return allocate_biseq(0, S.itembitsize) else: length = ((stop-start+1)//step)+1 cdef biseq_t out @@ -890,6 +890,22 @@ cdef class BoundedIntegerSequence: """ return self.data.length + def __nonzero__(self): + """ + A bounded integer sequence is nonzero if and only if its length is nonzero. + + EXAMPLES:: + + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: S = BoundedIntegerSequence(13, [0,0,0]) + sage: bool(S) + True + sage: bool(S[1:1]) + False + + """ + return self.data.length!=0 + def __repr__(self): """ String representation. @@ -1037,6 +1053,11 @@ cdef class BoundedIntegerSequence: sage: (X+S)[10] 0 + :: + + sage: S[2:2] == X[4:2] + True + """ cdef BoundedIntegerSequence out cdef int start,stop,step From ff4477a1600b44031c2fb962ff3c5ab24c110410 Mon Sep 17 00:00:00 2001 From: Simon King Date: Wed, 11 Jun 2014 17:12:33 +0200 Subject: [PATCH 041/698] Remove biseq_to_str. Add max_overlap. Fix boundary violations --- src/sage/misc/bounded_integer_sequences.pxd | 9 +- src/sage/misc/bounded_integer_sequences.pyx | 177 ++++++++++++++------ 2 files changed, 130 insertions(+), 56 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pxd b/src/sage/misc/bounded_integer_sequences.pxd index 9464b89cdbd..b80d95d3a56 100644 --- a/src/sage/misc/bounded_integer_sequences.pxd +++ b/src/sage/misc/bounded_integer_sequences.pxd @@ -24,10 +24,6 @@ cdef biseq_t* list_to_biseq(biseq_t S, list data) except NULL cdef list biseq_to_list(biseq_t S) # Convert a bounded integer sequence to a list -cdef str biseq_to_str(biseq_t S) - # String representation of bounded integer sequence as comma - # separated list - cdef biseq_t* concat_biseq(biseq_t S1, biseq_t S2) except NULL # Does not test whether the sequences have the same bound! @@ -40,6 +36,10 @@ cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start) # if S2 is not a subsequence. Does not check whether the sequences have the # same bound! +cdef int max_overlap_biseq(biseq_t S1, biseq_t S2) except 0 + # Returns the minimal *positive* integer i such that S2 starts with S1[i:]. + # This function will *not* test whether S2 starts with S1! + cdef int index_biseq(biseq_t S, int item, size_t start) except -2 # Returns the position *in S* of the item in S[start:], or -1 if S[start:] # does not contain the item. @@ -55,5 +55,6 @@ cdef class BoundedIntegerSequence: cdef str str(self) cpdef bint startswith(self, BoundedIntegerSequence other) cpdef list list(self) + cpdef BoundedIntegerSequence maximal_overlap(self, BoundedIntegerSequence other) cpdef BoundedIntegerSequence NewBISEQ(data, unsigned long int bitsize, unsigned int itembitsize, size_t length) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index d2353bc282b..5cbf1916c1d 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -22,10 +22,6 @@ modules:: cdef list biseq_to_list(biseq_t S) # Convert a bounded integer sequence to a list - cdef str biseq_to_str(biseq_t S) - # String representation of bounded integer sequence as comma - # separated list - cdef biseq_t* concat_biseq(biseq_t S1, biseq_t S2) except NULL # Does not test whether the sequences have the same bound! @@ -38,6 +34,10 @@ modules:: # if S2 is not a subsequence. Does not check whether the sequences have the # same bound! + cdef int max_overlap_biseq(biseq_t S1, biseq_t S2) except 0 + # Returns the minimal *positive* integer i such that S2 starts with S1[i:]. + # This function will *not* test whether S2 starts with S1! + cdef int index_biseq(biseq_t S, int item, size_t start) # Returns the position *in S* of the item in S[start:], or -1 if S[start:] # does not contain the item. @@ -164,7 +164,8 @@ cdef list biseq_to_list(biseq_t S): """ cdef __mpz_struct seq seq = deref(<__mpz_struct*>S.data) - cdef unsigned int index, limb_index, bit_index, max_limb + cdef unsigned int index, limb_index, bit_index + cdef int max_limb index = 0 cdef mp_limb_t *tmp_limb tmp_limb = sage_malloc(2<=n>0: limb_index = index>>times_mp_bits_per_limb bit_index = index&mod_mp_bits_per_limb @@ -204,50 +207,6 @@ cdef list biseq_to_list(biseq_t S): sage_free(tmp_limb) return L -cdef str biseq_to_str(biseq_t S): - """ - String representation of bounded integer sequence as comma - separated list of integers - """ - cdef __mpz_struct seq - seq = deref(<__mpz_struct*>S.data) - cdef unsigned int index, limb_index, bit_index, max_limb - index = 0 - cdef mp_limb_t *tmp_limb - tmp_limb = sage_malloc(2<=n>0: - limb_index = index>>times_mp_bits_per_limb - bit_index = index&mod_mp_bits_per_limb - if limb_index < max_limb: - if bit_index: - if bit_index+S.itembitsize >= mp_bits_per_limb: - mpn_rshift(tmp_limb, seq._mp_d+limb_index, 2, bit_index) - L.append(repr((tmp_limb[0]&S.mask_item))) - else: - L.append(repr((((seq._mp_d[limb_index])>>bit_index)&S.mask_item))) - else: - L.append(repr((seq._mp_d[limb_index]&S.mask_item))) - elif limb_index == max_limb: - if bit_index: - L.append(repr((((seq._mp_d[limb_index])>>bit_index)&S.mask_item))) - else: - L.append(repr((seq._mp_d[limb_index]&S.mask_item))) - else: - break - index += S.itembitsize - if n: - L.extend(["0"]*n) - sage_free(tmp_limb) - return ', '.join(L) - # # Arithmetics # @@ -378,6 +337,66 @@ cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start): mpz_clear(tmp) return -1 +cdef int max_overlap_biseq(biseq_t S1, biseq_t S2) except 0: + """ + Returns the smallest **positive** integer ``i`` such that ``S2`` starts with ``S1[i:]``. + + Returns ``-1`` if there is no overlap. Note that ``i==0`` will not be considered! + + INPUT: + + - ``S1``, ``S2`` -- two bounded integer sequences + + ASSUMPTION: + + - The two sequences must have equivalent bounds, i.e., the items on the + sequences must fit into the same number of bits. This condition is not + tested. + + """ + cdef __mpz_struct seq + seq = deref(<__mpz_struct*>S1.data) + cdef mpz_t tmp + # Idea: We shift-copy enough limbs from S1 to tmp and then compare with + # the initial part of S2, for each shift. + sig_on() + mpz_init2(tmp, S1.bitsize+mp_bits_per_limb) + sig_off() + # We will use tmp to store enough bits to be able to compare with the tail + # of S1. + cdef unsigned int n, limb_index, bit_index + cdef int index, i, start_index + if S2.length>=S1.length: + start_index = 1 + else: + start_index = S1.length-S2.length + n = S1.itembitsize*start_index + for index from start_index<=index>times_mp_bits_per_limb + if limb_index>=seq._mp_size: + break + bit_index = n&mod_mp_bits_per_limb + if bit_index: + mpn_rshift((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, seq._mp_size-limb_index, bit_index) + else: + mpn_copyi((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, seq._mp_size-limb_index) + (<__mpz_struct*>tmp)._mp_size = seq._mp_size-limb_index + if mpz_congruent_2exp_p(tmp, S2.data, S1.bitsize-n): + mpz_clear(tmp) + return index + n += S1.itembitsize + # now, it could be that we have to check for leading zeroes on S2. + if index(S.data))._mp_size-offset_div) + if limb_size<=0: + (<__mpz_struct*>(out.data))._mp_size = 0 + return &out mpn_rshift((<__mpz_struct*>(out.data))._mp_d, (<__mpz_struct*>(S.data))._mp_d+offset_div, limb_size, offset_mod) for n from limb_size>n>=0: if (<__mpz_struct*>(out.data))._mp_d[n]: @@ -918,6 +941,8 @@ cdef class BoundedIntegerSequence: sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence sage: BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) # indirect doctest <4, 1, 6, 2, 7, 20, 9> + sage: BoundedIntegerSequence(21, [0,0]) + BoundedIntegerSequence(21, [0,0]) + <0, 0, 0, 0> """ return '<'+self.str()+'>' @@ -935,7 +960,7 @@ cdef class BoundedIntegerSequence: <4, 1, 6, 2, 7, 20, 9> """ - return biseq_to_str(self.data) + return ', '.join([repr(n) for n in biseq_to_list(self.data)]) def bound(self): """ @@ -978,11 +1003,14 @@ cdef class BoundedIntegerSequence: [4, 1, 6, 2, 7, 2, 3] sage: list(X+S) [4, 1, 6, 2, 7, 2, 3, 0, 0, 0, 0, 0, 0, 0] + sage: list(BoundedIntegerSequence(21, [0,0]) + BoundedIntegerSequence(21, [0,0])) + [0, 0, 0, 0] """ cdef __mpz_struct seq seq = deref(<__mpz_struct*>self.data.data) - cdef unsigned int index, limb_index, bit_index, max_limb + cdef unsigned int index, limb_index, bit_index + cdef int max_limb index = 0 cdef mp_limb_t *tmp_limb tmp_limb = sage_malloc(2<=n>0: + yield 0 + return for n from self.data.length>=n>0: limb_index = index>>times_mp_bits_per_limb bit_index = index&mod_mp_bits_per_limb @@ -1052,6 +1084,8 @@ cdef class BoundedIntegerSequence: 3 sage: (X+S)[10] 0 + sage: (X+S)[12:] + <0, 0> :: @@ -1149,6 +1183,11 @@ cdef class BoundedIntegerSequence: sage: S.list() == list(S) == L True + The discussion at :trac:`15820` explains why the following is a good test:: + + sage: (BoundedIntegerSequence(21, [0,0]) + BoundedIntegerSequence(21, [0,0])).list() + [0, 0, 0, 0] + """ return biseq_to_list(self.data) @@ -1279,6 +1318,13 @@ cdef class BoundedIntegerSequence: ... TypeError: Cannot concatenate bounded integer sequence and None + TESTS: + + The discussion at :trac:`15820` explains why the following is a good test:: + + sage: BoundedIntegerSequence(21, [0,0]) + BoundedIntegerSequence(21, [0,0]) + <0, 0, 0, 0> + """ cdef BoundedIntegerSequence myself, right, out if other is None or self is None: @@ -1291,6 +1337,33 @@ cdef class BoundedIntegerSequence: out.data = deref(concat_biseq(myself.data, right.data)) return out + cpdef BoundedIntegerSequence maximal_overlap(self, BoundedIntegerSequence other): + """ + Returns ``self``'s maximal trailing sub-sequence that ``other`` starts with. + + Returns ``None`` if there is no overlap + + EXAMPLES:: + + sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: X = BoundedIntegerSequence(21, [4,1,6,2,7,2,3]) + sage: S = BoundedIntegerSequence(21, [0,0,0,0,0,0,0]) + sage: T = BoundedIntegerSequence(21, [2,7,2,3,0,0,0,0,0,0,0,1]) + sage: (X+S).maximal_overlap(T) + <2, 7, 2, 3, 0, 0, 0, 0, 0, 0, 0> + sage: print (X+S).maximal_overlap(BoundedIntegerSequence(21, [2,7,2,3,0,0,0,0,0,1])) + None + sage: (X+S).maximal_overlap(BoundedIntegerSequence(21, [0,0])) + <0, 0> + + """ + if other.startswith(self): + return self + cdef int i = max_overlap_biseq(self.data, other.data) + if i==-1: + return None + return self[i:] + def __cmp__(self, other): """ Comparison of bounded integer sequences From 1e75320fbe3cbc7d0b639f789aa0c0ef71cad746 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Sat, 21 Jun 2014 01:22:05 +0100 Subject: [PATCH 042/698] Trac 16507: better handling of subspace construction in pushout --- src/sage/categories/pushout.py | 43 ++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/src/sage/categories/pushout.py b/src/sage/categories/pushout.py index 4798fb47438..fbc7bbad7c5 100644 --- a/src/sage/categories/pushout.py +++ b/src/sage/categories/pushout.py @@ -286,6 +286,13 @@ def expand(self): """ return [self] + # The pushout function below assumes that if F is a construction + # applied to an object X, then F(X) admits a coercion map from X. + # In derived classes, the following attribute should be set to + # True if F(X) has a coercion map _to_ X instead. This is + # currently used for the subspace construction. + coercion_reversed = False + class CompositeConstructionFunctor(ConstructionFunctor): """ @@ -1719,6 +1726,10 @@ class SubspaceFunctor(ConstructionFunctor): """ rank = 11 # ranking of functor, not rank of module + # The subspace construction returns an object admitting a coercion + # map into the original, not vice versa. + coercion_reversed = True + def __init__(self, basis): """ INPUT: @@ -3141,6 +3152,22 @@ def pushout(R, S): sage: pushout(Frac(ZZ['x']), QQ[['x']]) Laurent Series Ring in x over Rational Field + A construction with ``coercion_reversed = True`` (currently only + the :class:`SubspaceFunctor` construction) is only applied if an + instance of it appears on each side, in which case the two + instances are correctly combined by their ``merge`` methods:: + + sage: V = (QQ^3).span([[1, 2, 3/4]]) + sage: A = ZZ^3 + sage: pushout(A, V) + Vector space of dimension 3 over Rational Field + sage: B = A.span([[0, 0, 2/3]]) + sage: pushout(B, V) + Vector space of degree 3 and dimension 2 over Rational Field + User basis matrix: + [1 2 0] + [0 0 1] + AUTHORS: -- Robert Bradshaw @@ -3211,14 +3238,22 @@ def pushout(R, S): # print Z # if we are out of functors in either tower, there is no ambiguity if len(Sc) == 0: - all = Rc.pop() * all + c = Rc.pop() + if not c.coercion_reversed: + all = c * all elif len(Rc) == 0: - all = Sc.pop() * all + c = Sc.pop() + if not c.coercion_reversed: + all = c * all # if one of the functors has lower rank, do it first elif Rc[-1].rank < Sc[-1].rank: - all = Rc.pop() * all + c = Rc.pop() + if not c.coercion_reversed: + all = c * all elif Sc[-1].rank < Rc[-1].rank: - all = Sc.pop() * all + c = Sc.pop() + if not c.coercion_reversed: + all = c * all else: # the ranks are the same, so things are a bit subtler if Rc[-1] == Sc[-1]: From 88ad7deca2fadbb8b70ed82baf43f61e748d78d1 Mon Sep 17 00:00:00 2001 From: Ben Hutz Date: Wed, 25 Jun 2014 12:19:32 -0400 Subject: [PATCH 043/698] trac 15393: imported patch to branch --- .../projective/endPN_automorphism_group.py | 1876 +++++++++++++++++ .../schemes/projective/projective_morphism.py | 178 ++ 2 files changed, 2054 insertions(+) create mode 100644 src/sage/schemes/projective/endPN_automorphism_group.py diff --git a/src/sage/schemes/projective/endPN_automorphism_group.py b/src/sage/schemes/projective/endPN_automorphism_group.py new file mode 100644 index 00000000000..f862ddfd24d --- /dev/null +++ b/src/sage/schemes/projective/endPN_automorphism_group.py @@ -0,0 +1,1876 @@ +r""" +Automorphism groups of endomorphisms of the projective line + +AUTHORS: + +- Xander Faber, Michelle Manes, Bianca Viray: algorithm and original code + "Computing Conjugating Sets and Automorphism Groups of Rational Functions" + by Xander Faber, Michelle Manes, and Bianca Viray + +- Joao de Faria, Ben Hutz, Bianca Thompson (11-2013): adaption for inclusion in Sage + +""" + +#***************************************************************************** +# Copyright (C) 2012 +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +from sage.combinat.subset import Subsets +from sage.functions.all import sqrt +from itertools import permutations, combinations +from sage.matrix.constructor import matrix +from sage.matrix.matrix import is_Matrix +from sage.misc.functional import squarefree_part +from sage.misc.misc_c import prod +from sage.rings.arith import is_square, divisors +from sage.rings.finite_rings.constructor import GF +from sage.rings.fraction_field import FractionField +from sage.rings.integer_ring import ZZ +from sage.rings.number_field.number_field import NumberField +from sage.rings.arith import gcd, lcm +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.rational_field import QQ +from sage.sets.primes import Primes + +def automorphism_group_QQ_fixedpoints(rational_function, return_functions = False, iso_type=False): + r""" + + This function will compute the automorphism group for ``rational_function`` via the method of fixed points + + ALGORITHM: + + See Algorithm 3 in "Computing Conjugating Sets and Automorphism Groups of Rational Functions" + by Xander Faber, Michelle Manes, and Bianca Viray + + INPUT: + + - ``rational_function`` - Rational Function defined over `\mathbb{Z}` or `\mathbb{Q}` + + - ``return_functions`` - Boolean Value, True will return elements in the automorphism group + as linear fractional transformations. False will return elements as `PGL2` matrices. + + - ``iso_type`` - Boolean - True will cause the classification of the finite automorphism + group to also be returned + + OUTPUT: + + - List of automorphisms that make up the Automorphism Group + of ``rational_function``. + + EXAMPLES:: + + sage: F. = PolynomialRing(QQ) + sage: rational_function = (z^2 - 2*z - 2)/(-2*z^2 - 2*z + 1) + sage: from sage.schemes.projective.endPN_automorphism_group import automorphism_group_QQ_fixedpoints + sage: automorphism_group_QQ_fixedpoints(rational_function, True) + [z, 2/(2*z), -z - 1, -2*z/(2*z + 2), (-z - 1)/z, -1/(z + 1)] + + :: + + sage: F. = PolynomialRing(QQ) + sage: rational_function = (z^2 + 2*z)/(-2*z - 1) + sage: from sage.schemes.projective.endPN_automorphism_group import automorphism_group_QQ_fixedpoints + sage: automorphism_group_QQ_fixedpoints(rational_function) + [ + [1 0] [-1 -1] [-2 0] [0 2] [-1 -1] [ 0 -1] + [0 1], [ 0 1], [ 2 2], [2 0], [ 1 0], [ 1 1] + ] + + :: + + sage: F. = PolynomialRing(QQ) + sage: rational_function = (z^2 - 4*z -3)/(-3*z^2 - 2*z + 2) + sage: from sage.schemes.projective.endPN_automorphism_group import automorphism_group_QQ_fixedpoints + sage: automorphism_group_QQ_fixedpoints(rational_function, True) + [z, (-z - 1)/z, -1/(z + 1)] + """ + + if rational_function.parent().is_field(): + K = rational_function.parent() + R = K.ring() + else: + R = rational_function.parent() + K = R.fraction_field() + + F = R.base_ring() + + if F != QQ and F!= ZZ: + raise TypeError("Coefficient ring is not the rational numbers or the integers") + + z = R.gen(0) + phi = R.fraction_field()(rational_function) + + f = phi.numerator() + g = phi.denominator() + + #scale f,g so both have integer coefficients + N = lcm(f.denominator(),g.denominator()) + f = f*N + g = g*N + N = gcd(gcd(f.coefficients()), gcd(g.coefficients())) + f = f/N + g = g/N + + d = max(f.degree(), g.degree()) + + h = f - g*z + + if return_functions: + elements = [z] + else: + elements = [matrix(ZZ, 2, [1,0,0,1])] + + rational_roots = h.roots(multiplicities = False) + + min_poly = 1 + + #check if infinity is a fixed point + if g.degree() < d: #then infinity is a fixed point + for T in g.roots(multiplicities = False):#find elements in W of the form + alpha = T #(infinty, y) + zeta = -1 + s = (zeta*z + alpha*(1 - zeta)) + if s(phi(z)) == phi(s(z)): + if return_functions: + elements.append(s) + else: + elements.append(matrix(F, 2, [zeta, alpha*(1-zeta), 0, 1])) + + for S in h.roots(): + min_poly = min_poly*(z - S[0])**(S[1]) + + if g.degree() < d: #then infinity is a fixed point so (infinity, S[0]) + alpha = S[0] # is in Z_(1,1)**2 + zeta = -1 + s = (zeta*z + alpha*(1 - zeta)) + if s(phi(z)) == phi(s(z)): + if return_functions: + elements.append(s) + else: + elements.append(matrix(F, 2, [zeta, alpha*(1-zeta), 0, 1])) + + #now compute points in W + preimage = f - g*S[0] + if preimage.degree() < d: #infinity is in W + zeta = -1 + alpha = S[0] + s = (zeta*z + alpha*(1 - zeta)) + if s(phi(z)) == phi(s(z)): + if return_functions: + elements.append(s) + else: + elements.append(matrix(F, 2, [zeta, alpha*(1-zeta), 0, 1])) + for T in preimage.roots(multiplicities = False): + if T != S[0]: + zeta = -1 + alpha = S[0] + beta = T + s = ( (alpha - zeta*beta)*z - (alpha*beta)*(1 - zeta))/((1 - zeta)*z + (alpha*zeta - beta)) + if s(phi(z)) == phi(s(z)): + if return_functions: + elements.append(s) + else: + elements.append(matrix(F, 2, + [(alpha - zeta*beta), - (alpha*beta)*(1 - zeta), + (1 - zeta), (alpha*zeta - beta)])) + + #first look at rational fixed points + for S in Subsets(rational_roots, 2): + zeta = -1 + alpha = S[0] + beta = S[1] + s = ( (alpha - zeta*beta)*z - (alpha*beta)*(1 - zeta))/((1 - zeta)*z + (alpha*zeta - beta)) + if s(phi(z)) == phi(s(z)): + if return_functions: + elements.append(s) + else: + elements.append(matrix(F, 2, + [(alpha - zeta*beta), - (alpha*beta)*(1 - zeta), + (1 - zeta), (alpha*zeta - beta)])) + + + #now consider 2-periodic points + psi = phi(phi(z)) + f2 = psi.numerator() + g2 = psi.denominator() + period2_points = [x for x in (f2 - z*g2).roots(multiplicities = False) if not x in rational_roots] + for S in Subsets(period2_points, 2): + zeta = -1 + alpha = S[0] + beta = S[1] + s = ( (alpha - zeta*beta)*z - (alpha*beta)*(1 - zeta))/((1 - zeta)*z + (alpha*zeta - beta)) + if s(phi(z)) == phi(s(z)): + if return_functions: + elements.append(s) + else: + elements.append(matrix(F, 2, + [(alpha - zeta*beta), - (alpha*beta)*(1 - zeta), + (1 - zeta), (alpha*zeta - beta)])) + if g2.degree() < f2.degree() and g.degree() == d: #infinity has period 2 + for alpha in period2_points: + zeta = -1 + s = (zeta*z + alpha*(1 - zeta)) + if s(phi(z)) == phi(s(z)): + if return_functions: + elements.append(s) + else: + elements.append(matrix(F, 2, [zeta, alpha*(1-zeta), 0, 1])) + factors = (f2 - z*g2).factor() + L1 = NumberField(z**2 + 1,'i') + i=L1.gen(0) + L2 = NumberField(z**2 + 3,'isqrt3') + isqrt3 = L2.gen(0) + for psi in factors: + if psi[0].degree() == 2: + a = psi[0][2] + b = psi[0][1] + c = psi[0][0] + disc = b**2 - 4*a*c + s = (-b*z - 2*c)/(2*a*z + b) + if s(phi(z)) == phi(s(z)): + if return_functions: + elements.append(K(s)) + else: + elements.append(matrix(F, 2, [-b,-2*c, 2*a, b])) + if is_square(-disc): #psi[0] generates Q(i) + alpha = psi[0].change_ring(L1).roots()[0][0] + beta = alpha.trace() - alpha + for zeta in [i, -i]: + a = (alpha - zeta*beta)/(1 - zeta) + d = (alpha*zeta - beta)/(1 - zeta) + if a in F and d in F: + a = F(a) + d = F(d) + b = F(-alpha*beta) + s = ( a*z + b)/(z + d) + if s(phi(z)) == phi(s(z)): + if return_functions: + elements.append(K(s)) + else: + elements.append(matrix(F, 2, [a,b, 1, d])) + elif is_square(-3*disc): #psi[0] generates Q(zeta_3) + alpha = psi[0].change_ring(L2).roots()[0][0] + beta = alpha.trace() - alpha + for zeta in [ZZ(1)/ZZ(2)*(1 + isqrt3), ZZ(1)/ZZ(2)*(1 - isqrt3),ZZ(1)/ZZ(2)*(-1 + isqrt3), ZZ(1)/ZZ(2)*(-1 - isqrt3)]: + a = (alpha - zeta*beta)/(1 - zeta) + d = (alpha*zeta - beta)/(1 - zeta) + if a in F and d in F: + a = F(a) + d = F(d) + b = F(-alpha*beta) + s = ( a*z + b)/(z + d) + if s(phi(z)) == phi(s(z)): + if return_functions: + elements.append(K(s)) + else: + elements.append(matrix(F, 2, [a,b, 1, d])) + + if iso_type: + return(elements, which_group(elements)) + return(elements) + +def height_bound(polynomial): + r""" + Compute the maximum height of the coefficients of an automorphism. This + sets the termination criteria for the Chinese Remainder Theorem step. + + Let `f` be a square-free polynomial with coefficients in `K` + Let `F` be an automorphism of `\mathbb{P}^1_{Frac(R)}` that permutes the roots of `f` + This function returns a bound on the height of `F`, + when viewed as an element of `\mathbb{P}^3` + + We have proved that `ht(F) <= 6^{[K:Q]}*M`, where `M` is the Mahler measure of `f` + M is bounded above by `H(f)`, so we return the floor of `6*H(f)` + (since `ht(F)` is an integer) + + INPUT: + + - ``polynomial`` -- a univariate polynomial + + OUTPUT: + + - a positive integer + + EXAMPLES:: + + sage: R. = PolynomialRing(QQ) + sage: f = (z^3+2*z+6) + sage: from sage.schemes.projective.endPN_automorphism_group import height_bound + sage: height_bound(f) + 413526 + """ + # first check that polynomial is over QQ or ZZ + K=polynomial.parent() + + if K.is_field(): + R = K.ring() + else: + R = K + F = R.base_ring() + + if F != QQ and F!= ZZ: + raise TypeError("coefficient ring is not the rational numbers or the integers!") + + # scale polynomial so that it has integer coefficients with gcd 1 + # this ensures that H(f) = H_infinity(f) + f = R(polynomial) + f = f*f.denominator() + f = f/(gcd(f.coefficients())) + + # compute the infinite height + L2norm_sq = sum([a**2 for a in f.coefficients()]) + + return (6*(L2norm_sq)**3) + +def PGL_repn(rational_function): + r""" + Take a linear fraction transformation (an automorphism of `\mathbb{P}^1`) + and represent it as a 2x2 matrix (an element of `GL_2`). + + INPUT: + + - ``rational_function`` -- a linear fraction transformation + + OUTPUT: + + - a 2x2 matrix representing ``rational_function`` + + EXAMPLES:: + + sage: R. = PolynomialRing(QQ) + sage: f = ((2*z-1)/(3-z)) + sage: from sage.schemes.projective.endPN_automorphism_group import PGL_repn + sage: PGL_repn(f) + [ 2 -1] + [-1 3] + """ + if is_Matrix(rational_function): + return rational_function + K = rational_function.parent() + F = K.base_ring() + if not K.is_field(): + return matrix(F, 2, [rational_function[1], rational_function[0], 0, 1]) + else: + f = rational_function.numerator() + g = rational_function.denominator() + return matrix(F, 2, [f[1], f[0], g[1], g[0]]) + +def PGL_order(A): + r""" + Find the multiplicative order of an element ``A`` of `GL_2(R)` that + has a finite order as an element of `PGL_2(R)`. + + INPUT: + + - ``A`` -- an element of `GL_2(R)` + + OUTPUT: + + - a positive integer + + EXAMPLES:: + + sage: M = matrix([[0,2],[2,0]]) + sage: from sage.schemes.projective.endPN_automorphism_group import PGL_order + sage: PGL_order(M) + 2 + """ + + n = 1 + B = A + while B[0][0] != B[1][1] or B[0][1] != 0 or B[1][0] != 0: + n = n + 1 + B = A*B + + return n + +def get_orders(L): + r""" + Find the multiplicative orders of a list of linear fractional transformations + that have a finite order + + INPUT: + + - ``L`` -- a list of degree 1 rational functions over `R` with finite order + + OUTPUT: + + - a list of positive integers and list of the `GL_2` representation of the + elements of `L` + + EXAMPLES:: + + sage: R. = PolynomialRing(QQ) + sage: L = [x, -x, 1/x, -1/x, (-x + 1)/(x + 1), (x + 1)/(x - 1), (x - 1)/(x + 1),(-x - 1)/(x - 1)] + sage: from sage.schemes.projective.endPN_automorphism_group import get_orders + sage: get_orders(L) + ([1, 2, 2, 2, 2, 2, 4, 4], [[1 0] + [0 1], [-1 0] + [ 0 1], [0 1] + [1 0], [ 0 -1] + [ 1 0], [-1 1] + [ 1 1], [ 1 1] + [ 1 -1], [ 1 -1] + [ 1 1], [-1 -1] + [ 1 -1]]) + """ + auts = [PGL_repn(A) for A in L] + auts.sort(key = PGL_order) + orders = [PGL_order(A) for A in auts] + return orders, auts + +def CRT_helper(automorphisms, moduli): + r""" + Given a list of automorphisms over various `Zmod(p^k)` find a list + of automorphisms over `Zmod(M)` where `M=\prod p^k` that surjects + onto every tuple of automorphisms from the various `Zmod(p^k)`. + + INPUT: + + - ``automorphisms`` -- a list of lists of automorphisms over various `Zmod(p^k)` + + - ``moduli`` -- list of the various `p^k` + + OUTPUT: + + - a list of automorphisms over `Zmod(M)`. + + EXAMPLES:: + + sage: from sage.schemes.projective.endPN_automorphism_group import CRT_helper + sage: CRT_helper([[matrix([[4,0],[0,1]]), matrix([[0,1],[1,0]])]],[5]) + ([[4 0] + [0 1], [0 1] + [1 0]], 5) + """ + if len(automorphisms) > 2: + temp, modulus = CRT_helper( + [automorphisms[i] for i in range(len(automorphisms)) if i != 0], + [moduli[i] for i in range(len(moduli)) if i != 0]) + elif len(automorphisms) == 2: + temp = automorphisms[1] + modulus = moduli[1] + else: + return automorphisms[0], moduli[0] + + autos = [] + for B in temp: + for C in automorphisms[0]: + A = matrix(Integers(modulus*moduli[0]), 2, + [CRT(B[0][0].lift(), C[0][0].lift(), modulus, moduli[0]), + CRT(B[0][1].lift(), C[0][1].lift(), modulus, moduli[0]), + CRT(B[1][0].lift(), C[1][0].lift(), modulus, moduli[0]), + CRT(B[1][1].lift(), C[1][1].lift(), modulus, moduli[0])]) + autos.append(A) + + return autos, modulus*moduli[0] + +def CRT_automorphisms(automorphisms, order_elts, degree, moduli): + r""" + Given a list of automorphisms over various `Zmod(p^k)`, a list of the + elements orders, an integer degree, and a list of the `p^k` values compute + a maximal list of automorphisms over `Zmod(M)`, such that for every `j` in `len(moduli)`, + each element reduces mod ``moduli[j]`` to one of the elements in `automorphisms[j]` that + has order = ``degree`` + + INPUT: + + - ``automorphisms`` -- a list of lists of automorphisms over various `Zmod(p^k)` + + - ``order_elts`` -- a list of lists of the orders of the elements of ``automorphisms`` + + - ``degree`` - a positive integer + + - ``moduli`` -- list of the various `p^k` + + OUTPUT: + + - a list of automorphisms over `Zmod(M)`. + + EXAMPLES:: + + sage: aut = [[matrix([[1,0],[0,1]]),matrix([[0,1],[1,0]])]] + sage: ords = [[1,2]] + sage: degree = 2 + sage: mods = [5] + sage: from sage.schemes.projective.endPN_automorphism_group import CRT_automorphisms + sage: CRT_automorphisms(aut,ords,degree,mods) + ([[0 1] + [1 0]], 5) + """ + # restrict to automorphisms of degree d + d = degree + degree_d_autos = [] + for j in range(len(automorphisms)): + L = automorphisms[j] + degree_d_autos.append( + [L[i] for i in range(len(L)) if order_elts[j][i] == d]) + + # get list of CRT'ed automorphisms + return CRT_helper(degree_d_autos, moduli) + +def valid_automorphisms(automorphisms_CRT, rational_function, ht_bound, M, + return_functions = False): + r""" + Checks whether an element that is an automorphism of ``rational_function`` modulo `p^k` for various + `p`s and `k`s can be lifted to an automorphim over `ZZ`. It uses the fact that every + automorphism has height at most ``ht_bound`` + + INPUT: + + - ``automorphisms`` -- a list of lists of automorphisms over various `Zmod(p^k)` + + - ``rational_function`` -- A one variable rational function + + - ``ht_bound`` - a positive integer + + - ``M`` -- a list of prime powers + + - ``return_functions`` -- Boolean, + + OUTPUT: + + - a list of automorphisms over `ZZ`. + + EXAMPLES:: + + sage: R. = PolynomialRing(QQ) + sage: F = z^2 + sage: from sage.schemes.projective.endPN_automorphism_group import valid_automorphisms + sage: valid_automorphisms([matrix(GF(5),[[0,1],[1,0]])], F, 48, 5, True) + [1/z] + """ +# if rational_function.parent().is_field(): +# K = rational_function.parent() +# R = K.ring() +# else: +# R = rational_function.parent() +# K = R.fraction_field() + + z = rational_function.parent().gen(0) + valid_auto = [] + for A in automorphisms_CRT: + a = A[0][0].lift() + b = A[0][1].lift() + c = A[1][0].lift() + d = A[1][1].lift() + for scalar in range(1, M-1): + aa = scalar*a - (scalar*a/M).round()*M + bb = scalar*b - (scalar*b/M).round()*M + cc = scalar*c - (scalar*c/M).round()*M + dd = scalar*d - (scalar*d/M).round()*M + g = gcd([aa,bb,cc,dd]) + if gcd(scalar, M) == 1 and abs(aa) <= ht_bound*g and\ + abs(bb) <= ht_bound*g and abs(cc) <= ht_bound*g and\ + abs(dd) <= ht_bound*g: + f = ((aa/g)*z + bb/g)/(cc/g*z + dd/g) + if rational_function(f(z)) == f(rational_function(z)): + if return_functions: + valid_auto.append(f) + else: + valid_auto.append(matrix(ZZ,[[aa/g,bb/g],[cc/g,dd/g]])) + break + + return valid_auto + +def remove_redundant_automorphisms(automorphisms, order_elts, moduli,integral_autos): + r""" + if an element of Aut_{F_p} has been lifted to `QQ` + remove that element from `Aut_{F_p}` so we don't + attempt to lift that element again unecessarily + + INPUT: + + - ``automorphisms`` -- a list of lists of automorphisms + + - ``order_elts`` -- a list of lists of the orders of the elements of ``automorphisms`` + + - ``moduli`` -- a list of prime powers + + - ``integral_autos`` -- list of known automorphisms + + OUTPUT: + + - a list of automorphisms. + + EXAMPLES:: + + sage: auts = [[matrix([[1,0],[0,1]]), matrix([[6,0],[0,1]]), matrix([[0,1],[1,0]]), + ....: matrix([[6,1],[1,1]]), matrix([[1,1],[1,6]]), matrix([[0,6],[1,0]]), + ....: matrix([[1,6],[1,1]]), matrix([[6,6],[1,6]])]] + sage: ord_elts = [[1, 2, 2, 2, 2, 2, 4, 4]] + sage: mods = [7] + sage: R. = PolynomialRing(QQ) + sage: int_auts = [-1/x] + sage: from sage.schemes.projective.endPN_automorphism_group import remove_redundant_automorphisms + sage: remove_redundant_automorphisms(auts, ord_elts, mods, int_auts) + [[[1 0] + [0 1], [6 0] + [0 1], [0 1] + [1 0], [6 1] + [1 1], [1 1] + [1 6], [1 6] + [1 1], [6 6] + [1 6]]] + """ + to_del = [] + + for i in range(len(automorphisms)): + p = moduli[i] + to_del_temp = [] + for psi in integral_autos: + #The return_functions boolean determines if the automorphisms + #are matricies or linear fractional transformations + if is_Matrix(psi): + ppsi=psi.change_ring(GF(p)) + B=[ppsi[0,0],ppsi[0,1],ppsi[1,0],psi[1,1]] + else: + ff = psi.numerator().change_ring(GF(p)) + gg = psi.denominator().change_ring(GF(p)) + B = [ff[1],ff[0],gg[1],gg[0]] + for j in range(len(automorphisms[i])): + A = automorphisms[i][j] + M = matrix(GF(p), [B, [A[0][0], A[0][1], A[1][0], A[1][1]]]) + if M.rank() == 1: + to_del_temp.append(j) + break + to_del.append(to_del_temp) + + for i in range(len(to_del)): + to_del[i].sort() + to_del[i].reverse() + for j in to_del[i]: + del automorphisms[i][j] + del order_elts[i][j] + + return(automorphisms) + +def automorphism_group_QQ_CRT(rational_function, prime_lower_bound = 4, return_functions = True, iso_type=False): + r""" + Determines the complete group of rational automorphisms (under the conjugation action + of `PGL(2,QQ)`) for a rational function of one variable. + + INPUT: + + - ``rational_function`` - a rational function of a univariate polynomial ring over `QQ` + + - prime_lower_bound`` -- a positive integer - a lower bound for the primes to use for + the Chinese Remainder Theorem step. (optional) + + - ``return_functions`` -- Boolean - True returns linear fractional transformations + False returns elements of `PGL(2,QQ)` (optional). + + - ``iso_type`` -- Boolean - True returns the isomorphism type of the automorphism group. + default: False (optional) + + OUTPUT: + + - a complete list of automorphisms of `rational_function` as linear fractional transformations + + EXAMPLES:: + + sage: R. = PolynomialRing(QQ) + sage: f = (3*z^2 - 1)/(z^3 - 3*z) + sage: from sage.schemes.projective.endPN_automorphism_group import automorphism_group_QQ_CRT + sage: automorphism_group_QQ_CRT(f, 4,True) + [z, -z, 1/z, -1/z, (-z + 1)/(z + 1), (z + 1)/(z - 1), (z - 1)/(z + 1), + (-z - 1)/(z - 1)] + + :: + + sage: R. = PolynomialRing(QQ) + sage: f = (3*z^2 - 1)/(z^3 - 3*z) + sage: from sage.schemes.projective.endPN_automorphism_group import automorphism_group_QQ_CRT + sage: automorphism_group_QQ_CRT(f, 4,False) + [ + [1 0] [-1 0] [0 1] [ 0 -1] [-1 1] [ 1 1] [ 1 -1] [-1 -1] + [0 1], [ 0 1], [1 0], [ 1 0], [ 1 1], [ 1 -1], [ 1 1], [ 1 -1] + ] + """ + if rational_function.parent().is_field(): + K = rational_function.parent() + R = K.ring() + else: + R = rational_function.parent() + K = R.fraction_field() + + F = R.base_ring() + + if F != QQ and F!= ZZ: + raise TypeError("coefficient ring is not the rational numbers or the integers!") + + z = R.gen(0) + phi = K(rational_function) + + f = phi.numerator() + g = phi.denominator() + + #scale f,g so both have integer coefficients + N = lcm(f.denominator(),g.denominator()) + f = f*N + g = g*N + N = gcd(gcd(f.coefficients()), gcd(g.coefficients())) + f = f/N + g = g/N + + d = max(f.degree(), g.degree()) + + if d == 1: + raise ValueError("rational function has degree 1") + + #badprimes is an integer divisible by every prime p such that either + # 1) phi has bad reduction at p or + # 2) the reduction map fails to be injective + badprimes = (gcd(f[d],g[d])*f.resultant(g)*6) + #6 is because over Q, Aut(phi) has order dividing 12 + #when generalizing to a number field K, 6 should be replaced with + # 2*gcd(2*[K:Q] + 1, d^3 - d) + + #Determining the set that is used to obtain the height bound + h = squarefree_part(f - g*z) # take minimal polynomial of fixed points + if h.degree() == 2: #if there are only 2 finite fixed points, take preimage of fixed points + h = h[2]*f**2 + h[1]*f*g + h[0]*g**2 + elif h.degree() == 1: #if there is just 1 finite fixed points, take preimages under phi^2 + psi = phi(phi(z)) + f2 = psi.numerator() + g2 = psi.denominator() + N = lcm(f2.denominator(),g2.denominator()) + f2 = f2*N + g2 = g2*N + N = gcd(gcd(f2.coefficients()), gcd(g2.coefficients())) + f2 = f2/N + g2 = g2/N + h = h[1]*f2 + h[0]*g2 + + MaxH = height_bound(h) + congruence = 1 + primes = Primes(); + p = primes.next(ZZ(prime_lower_bound)) + primepowers = [] + automorphisms = [] + orderaut = [] + orderelts = [] + + if return_functions: + elements = [z] + else: + elements = [matrix(ZZ, 2, [1,0,0,1])] + + badorders = [1, 12]# order 12 not possible over Q, even though 4 and 6 are + + #over Q, elts of PGL_2 of finite order can only have order dividing 6 or 4, + # and the finite subgroups can only be cyclic or dihedral (Beauville) so + # the only possible groups are C_n, D_2n for n|6 or n|4 + # all of these groups have order dividing 24 + while (congruence < (2*MaxH**2)) and len(elements) < gcd(orderaut + [24]): + if badprimes%p != 0: #prime of good reduction + #hp = h.change_ring(GF(p)) + # compute automorphisms mod p + phi_p = f.change_ring(GF(p))/g.change_ring(GF(p)) + orders, sorted_automorphisms = get_orders(automorphism_group_FF(phi_p)) + + automorphisms.append(sorted_automorphisms) + orderaut.append(len(automorphisms[-1])) + orderelts.append(orders) + + k = 1 + primepowers.append(p**k) + + # check if we already found 8 or 12 automorphisms + # and the gcd of orders over Fp and 24 is 24 + # or if the gcd is equal to the the number of automorphisms we have + if (len(elements) == gcd(orderaut + [24])) or \ + (gcd(orderaut + [24]) == 24 and \ + (len(elements) == 12 or len(elements) == 8)): + if iso_type: + return(elements, which_group(elements)) + return elements + else: + N = gcd(orderaut + [12]) #all orders of elements divide N + for order in [O for O in divisors(N) \ + if not O in badorders]: #range over all orders + # that are possible over Q such that we haven't already + # found all elements of that order + + # First count number of elements of particular order + numeltsoffixedorder = [] + for L in orderelts: + numeltsoffixedorder.append(L.count(order)) + numelts = min(numeltsoffixedorder) + # + # Have some elts of fixed order mod p for each p + if numelts != 0: + #CRT order d elements together and check if + # they are an automorphism + autos, M = CRT_automorphisms(automorphisms, + orderelts, order, primepowers) + temp = valid_automorphisms(autos, phi, MaxH, M, + return_functions) + elements.extend(temp) + # + # + if (len(elements) == gcd(orderaut + [24])): + #found enough automorphisms + if iso_type: + return(elements, which_group(elements)) + return elements + elif numelts <= (len(temp)): + badorders.append(order) + # found all elements of order 'order; + elif len(temp) != 0: + # found some elements of order 'order' + # if an element of Aut_{F_p} has been lifted to Q + # remove that element from Aut_{F_p} so we don't + # attempt to lift that element again unecessarily + automorphisms=remove_redundant_automorphisms(automorphisms, + orderelts, primepowers, temp) + if order == 4: #have some elements of order 4 + # so possible aut group is Z/4 or D_4 + badorders.extend([3, 6]) + elif order == 3 or order == 6:#have some elements of + # order 3 or 6 so possible aut groups are Z/3, + # D_3, Z/6, or D_6 + badorders.append(4) + else: #no elements of order d in some F_v + for m in divisors(N): + if m%order == 0: + badorders.append(m) + #no elements of that order or any order that + # is a multiple of it + if len([order for order in divisors(N) \ + if not order in badorders]) == 0: + #found all elements of every possible order + if iso_type: + return(elements, which_group(elements)) + return elements + else: + k = 0 + + congruence = congruence*p**k + p = primes.next(p) + + if iso_type: + return(elements, which_group(elements)) + return(elements) + +def automorphism_group_FF(rational_function, absolute=False, iso_type=False, return_functions=False): + r""" + This function computes automorphism groups over finite fields. + + AUTHORS: + + - Algorithm developed by X. Faber, M. Manes, B. Viray + - Last updated June 29, 2012 + + ALGORITHM: + + See Algorithm 4 in Computing Conjugating Sets and Automorphism Groups of Rational Functions + by Xander Faber, Michelle Manes, and Bianca Viray + + INPUT: + + - ``rational_function`` -- a rational function defined over the fraction field + of a polynomial ring in one variable with finite field coefficients. + + - ``absolute``-- Boolean - True returns the absolute automorphism group and a field of definition. + default: False (optional) + + - ``iso_type`` -- Boolean - True returns the isomorphism type of the automorphism group. + default: False (optional) + + - ``return_functions`` -- Boolean, True returns linear fractional transformations + False returns elements of `PGL(2)`. (optional) + + OUTPUT: + + - List of automorphisms of ``rational_function`` + + EXAMPLES:: + + sage: R. = PolynomialRing(GF(5^2,'t')) + sage: from sage.schemes.projective.endPN_automorphism_group import automorphism_group_FF + sage: automorphism_group_FF((x^2+x+1)/(x+1)) + [ + [1 0] [4 3] + [0 1], [0 1] + ] + + :: + + sage: R. = PolynomialRing(GF(2^5,'t')) + sage: from sage.schemes.projective.endPN_automorphism_group import automorphism_group_FF + sage: automorphism_group_FF(x^(5),True,False,True) + [Univariate Polynomial Ring in w over Finite Field in b of size 2^5, [w, 1/w]] + + :: + + sage: R. = PolynomialRing(GF(2^5,'t')) + sage: from sage.schemes.projective.endPN_automorphism_group import automorphism_group_FF + sage: automorphism_group_FF(x^(5),False,False,True) + [x, 1/x] + """ + + if absolute==False: + G = automorphism_group_FF_alg3(rational_function) + + else: + G = automorphism_group_FF_alg2(rational_function) + + if not return_functions: + if absolute: + R=G[1][0].parent() + if R.is_field(): + R = R.ring() + G[1] = [matrix(R.base_ring(),[[R(g.numerator())[1],R(g.numerator())[0]],[R(g.denominator())[1],R(g.denominator())[0]]]) for g in G[1]] + else: + R=G[0].parent() + if R.is_field(): + R = R.ring() + G = [matrix(R.base_ring(),[[R(g.numerator())[1],R(g.numerator())[0]],[R(g.denominator())[1],R(g.denominator())[0]]]) for g in G] + + if iso_type == False: + return G + + elif absolute == False: + return G, which_group(G) + + else: + return G, which_group(G[1]) + +def field_descent(sigma, yy): + r""" + Function for descending an element in a field E to a subfield F. + Here F, E must be finite fields or number fields. This function determine + the unique image of subfield which is ``yy` by the embedding ``sigma`` if it exists. + Otherwise returns ``None``. + This functionality is necessary because Sage does not keep track of subfields. + + INPUT: + + - ``sigma``-- an embedding sigma: `F` -> `E` of fields. + + - ``yy`` --an element of the field `E` + + OUTPUT: + + - the unique element of the subfield if it exists, otherwise ``None`` + + EXAMPLE:: + + sage: R = GF(11^2,'b') + sage: RR = GF(11) + sage: s = RR.Hom(R)[0] + sage: from sage.schemes.projective.endPN_automorphism_group import field_descent + sage: field_descent(s, R(1)) + 1 + """ + y = yy + F = sigma.domain() + a = F.gen() + + p = F.characteristic() + r = F.degree() + if p != 0 and y**(p**r) != y: + return + + K = F.prime_subfield() + R = PolynomialRing(K,'X') + X = R.gen(0) + f = R(sigma(a).polynomial().coeffs()) + g = R(y.polynomial().coeffs()) + + x = F(0) + quotient, remainder = g.quo_rem(f) + if not remainder.is_constant(): + return + else: + x = x+ F(remainder) + + steps = 1 + while not quotient.is_constant(): + quotient, remainder = quotient.quo_rem(f) + if not remainder.is_constant(): + return + else: + x = x+ F(remainder)*a**(steps) + steps += 1 + + return x + F(quotient)*a**(steps) + +def rational_function_coefficient_descent(rational_function, ssigma, poly_ring): + r""" + Function for descending the coefficients of a rational function from field `E` + to a subfield `F`. Here `F`, `E` must be finite fields or number fields. + It determines the unique rational function in fraction field of + ``poly_ring`` which is the image of ``rational_function`` by ``ssigma``, + if it exists, and otherwise returns ``None``. + + INPUT: + + - ``rational_function``--a rational function with coefficients in a field `E`, + + - ``ssigma``-- a field embedding sigma: `F` -> `E`. + + - ``poly_ring``-- a polynomial ring `R` with coefficients in `F`. + + OUTPUT: + + - a rational function with coefficients in the fraction field of ``poly_ring`` + if it exists, and otherwise ``None``. + + EXAMPLES:: + + sage: T. = PolynomialRing(GF(11^2,'b')) + sage: S. = PolynomialRing(GF(11)) + sage: s = S.base_ring().hom(T.base_ring()) + sage: f = (3*z^3 - z^2)/(z-1) + sage: from sage.schemes.projective.endPN_automorphism_group import rational_function_coefficient_descent + sage: rational_function_coefficient_descent(f,s,S) + (3*y^3 + 10*y^2)/(y + 10) + """ + + if rational_function.parent().is_field(): + S = rational_function.parent().ring() + else: + S = rational_function.parent() + + if rational_function == S(0): + return poly_ring(0) + + sigma = ssigma + num=S(rational_function.numerator()) + denom=S(rational_function.denominator()) + f = num.coefficients() + fe = num.exponents() + g = denom.coefficients() + ge = denom.exponents() + ff = [ field_descent(sigma, x/f[-1]) for x in f] + gg = [ field_descent(sigma, x/f[-1]) for x in g] + if None in ff or None in gg: + return + + R = poly_ring + z = R.gen(0) + numer = sum( R(ff[i])*z**fe[i] for i in range(len(ff)) ) + denom = sum( R(gg[i])*z**ge[i] for i in range(len(gg)) ) + return numer / denom + +def rational_function_coerce(rational_function, sigma, S_polys): + r""" + Function for coercing a rational function defined over a ring `R` to have + coefficients in a second ring ``S_polys``. The fraction field of polynomial ring + ``S_polys`` will contain the new rational function. + + INPUT: + + - ``rational_funtion``-- rational function with coefficients in `R`. + + - ``sigma`` -- a ring homomorphism sigma: `R` -> ``S_polys``. + + - ``S_polys`` -- a polynomial ring. + + OUTPUT: + + - a rational function with coefficients in ``S_polys``. + + EXAMPLES:: + + sage: R. = PolynomialRing(QQ) + sage: S. = PolynomialRing(ZZ) + sage: s = S.hom([z],R) + sage: f = (3*z^2 + 1)/(z^3-1) + sage: from sage.schemes.projective.endPN_automorphism_group import rational_function_coerce + sage: rational_function_coerce(f,s,R) + (3*y^2 + 1)/(y^3 - 1) + """ + if rational_function.parent().is_field(): + R = rational_function.parent().ring() + else: + R = rational_function.parent() + + f = R(rational_function.numerator()).coeffs() + g = R(rational_function.denominator()).coeffs() + + if g == [R(1)]: + return S_polys([sigma(a) for a in f]) # allows for coercion of polynomials + else: + return S_polys([sigma(a) for a in f]) / S_polys([sigma(b) for b in g]) + +def rational_function_reduce(rational_function): + r""" + Force Sage to divide out common factors in numerator and denominator + of rational function. + + INPUT: + + - ``rational_function``--rational function `= F/G` in univariate polynomial ring. + + OUTPUT: + + - `(F/gcd(F,G) ) / (G/gcd(F,G))`. + + EXAMPLES:: + + sage: R. = PolynomialRing(GF(7)) + sage: f = ((z-1)*(z^2+z+1))/((z-1)*(z^3+1)) + sage: from sage.schemes.projective.endPN_automorphism_group import rational_function_reduce + sage: rational_function_reduce(f) + (z^2 + z + 1)/(z^3 + 1) + """ + phi = rational_function + F = phi.numerator() + G = phi.denominator() + comm_factor = gcd(F,G) + return (F.quo_rem(comm_factor)[0]) / (G.quo_rem(comm_factor)[0]) + +def three_stable_points(rational_function, invariant_list): + r""" + Implementation of Algorithm 1 for automorphism groups from "Computing + Conjugating Sets and Automorphism Groups of Rational Functions" by Xander + Faber, Michelle Manes, and Bianca Viray. + + INPUT: + + - ``rational_function``--rational function phi defined over finite + field `E`. + + - ``invariant_list``-- a list of at least `3` points of `\mathbb{P}^1(E)` that + is stable under `Aut_phi(E)`. + + OUTPUT: + + - list of automorphisms + + EXAMPLES:: + + sage: R. = PolynomialRing(GF(5^2,'t')) + sage: f = z^3 + sage: L = [[0,1],[4,1],[1,1],[1,0]] + sage: from sage.schemes.projective.endPN_automorphism_group import three_stable_points + sage: three_stable_points(f,L) + [z, 4*z, 2/(2*z), 3/(2*z)] + """ + # define ground field and ambient function field + if rational_function.parent().is_field(): + K = rational_function.parent() + R = K.ring() + else: + R = rational_function.parent() + K = R.fraction_field() + + z = R.gen(0) + phi = K(rational_function) + + T = invariant_list + + automorphisms = [] + for t in permutations(range(len(T)),3): + a = (T[0][0]*T[1][1]*T[2][1]*T[t[0]][0]*T[t[1]][0]*T[t[2]][1] - + T[0][0]*T[1][1]*T[2][1]*T[t[0]][0]*T[t[1]][1]*T[t[2]][0] - + T[0][1]*T[1][0]*T[2][1]*T[t[0]][0]*T[t[1]][0]*T[t[2]][1] + + T[0][1]*T[1][0]*T[2][1]*T[t[0]][1]*T[t[1]][0]*T[t[2]][0] + + T[0][1]*T[1][1]*T[2][0]*T[t[0]][0]*T[t[1]][1]*T[t[2]][0] - + T[0][1]*T[1][1]*T[2][0]*T[t[0]][1]*T[t[1]][0]*T[t[2]][0]) + + b = (T[0][0]*T[1][0]*T[2][1]*T[t[0]][0]*T[t[1]][1]*T[t[2]][0] - + T[0][0]*T[1][0]*T[2][1]*T[t[0]][1]*T[t[1]][0]*T[t[2]][0] - + T[0][0]*T[1][1]*T[2][0]*T[t[0]][0]*T[t[1]][0] *T[t[2]][1] + + T[0][0]*T[1][1]*T[2][0]*T[t[0]][1]*T[t[1]][0]*T[t[2]][0] + + T[0][1]*T[1][0]*T[2][0]*T[t[0]][0]*T[t[1]][0]*T[t[2]][1] - + T[0][1]*T[1][0]*T[2][0]*T[t[0]][0]*T[t[1]][1]*T[t[2]][0]) + + c = (T[0][0]*T[1][1]*T[2][1]*T[t[0]][1]*T[t[1]][0] *T[t[2]][1]- + T[0][0]*T[1][1]*T[2][1]*T[t[0]][1]*T[t[1]][1]*T[t[2]][0] - + T[0][1]*T[1][0]*T[2][1]*T[t[0]][0]*T[t[1]][1]*T[t[2]][1] + + T[0][1]*T[1][0]*T[2][1]*T[t[0]][1]*T[t[1]][1]*T[t[2]][0] + + T[0][1]*T[1][1]*T[2][0]*T[t[0]][0]*T[t[1]][1]*T[t[2]][1] - + T[0][1]*T[1][1]*T[2][0]*T[t[0]][1]*T[t[1]][0]*T[t[2]][1]) + + d = (T[0][0]*T[1][0]*T[2][1]*T[t[0]][0]*T[t[1]][1]*T[t[2]][1] - + T[0][0]*T[1][0]*T[2][1]*T[t[0]][1]*T[t[1]][0] *T[t[2]][1]- + T[0][0]*T[1][1]*T[2][0]*T[t[0]][0]*T[t[1]][1]*T[t[2]][1] + + T[0][0]*T[1][1]*T[2][0]*T[t[0]][1]*T[t[1]][1]*T[t[2]][0] + + T[0][1]*T[1][0]*T[2][0]*T[t[0]][1]*T[t[1]][0] *T[t[2]][1]- + T[0][1]*T[1][0]*T[2][0]*T[t[0]][1]*T[t[1]][1]*T[t[2]][0]) + + if a*d - b*c != 0: + s = K(a*z + b) / K(c*z + d) + if s(phi(z)) == phi(s(z)) and s not in automorphisms: + automorphisms.append(s) + + return automorphisms + +def automorphism_group_FF_alg2(rational_function): + r""" + Implementation of algorithm for determining the absolute automorphism + group over a finite field, given an invariant set. + + INPUT: + + - ``rational_function``--a rational function defined over a finite field `F`. + + OUTPUT: + + - absolute automorphism group of ``rational_function`` and a ring of definition. + + EXAMPLES:: + + sage: R. = PolynomialRing(GF(7^2,'t')) + sage: f = (3*z^3 - z^2)/(z-1) + sage: from sage.schemes.projective.endPN_automorphism_group import automorphism_group_FF_alg2 + sage: automorphism_group_FF_alg2(f) + [Univariate Polynomial Ring in w over Finite Field in b of size 7^2, [w, (3*b + 2)/((2*b + 6)*w)]] + + :: + + sage: R. = PolynomialRing(GF(5^3,'t')) + sage: f = (3456*z^(4)) + sage: from sage.schemes.projective.endPN_automorphism_group import automorphism_group_FF_alg2 + sage: automorphism_group_FF_alg2(f) + [Univariate Polynomial Ring in w over Finite Field in b of size 5^6, [w, + (3*b^5 + 4*b^4 + 3*b^2 + 2*b + 1)*w, (2*b^5 + b^4 + 2*b^2 + 3*b + 3)*w, + (3*b^5 + 4*b^4 + 3*b^2 + 2*b)/((3*b^5 + 4*b^4 + 3*b^2 + 2*b)*w), (4*b^5 + + 2*b^4 + 4*b^2 + b + 2)/((3*b^5 + 4*b^4 + 3*b^2 + 2*b)*w), (3*b^5 + + 4*b^4 + 3*b^2 + 2*b + 3)/((3*b^5 + 4*b^4 + 3*b^2 + 2*b)*w)]] + """ + # define ground field and ambient function field + if rational_function.parent().is_field(): + K = rational_function.parent() + R = K.ring() + else: + R = rational_function.parent() + K = R.fraction_field() + + F = R.base_ring() + if not F.is_finite() or not F.is_field(): + raise TypeError("Coefficient ring is not a finite field.") + p = F.characteristic() + z = R.gen(0) + phi = K(rational_function) + f = phi.numerator() + g = phi.denominator() + D = max(f.degree(), g.degree()) + + # Build an invariant set for phi + fix = f(z) - z*g(z) + factor_list = fix.factor() + minimal_fix_poly = R(prod(x[0] for x in factor_list)) + n = sum(x[0].degree() for x in factor_list) + bool(fix.degree() < D+1) + + if n >= 3: + T_poly = minimal_fix_poly + infinity_check = bool(fix.degree() < D+1) + + elif n == 2: + # Infinity is a fixed point + if bool(fix.degree() < D+1): + y = fix.roots(multiplicities=False)[0] + preimage = g*(f(z) - y*g(z)) + infinity_check = 1 + + # Infinity is not a fixed point + else: + C = minimal_fix_poly.coeffs() + preimage = C[2]*f(z)**2 + C[1]*f(z)*g(z) + C[0]*g(z)**2 + infinity_check = bool(preimage.degree() < 2*D) + + T_poly = R(prod(x[0] for x in preimage.factor())) + + else: #case n=1 + # Infinity is the fixed point + if bool(fix.degree() < D+1): + minimal_preimage = R(prod(x[0] for x in g.factor())) + if minimal_preimage.degree() + 1 >= 3: + T_poly = minimal_preimage + infinity_check = 1 + else: + T_poly = R(prod(x[0] for x in phi(phi(z)).denominator().factor() ) ) + infinity_check = 1 + + # Infinity is not a fixed point + else: + y = fix.roots(multiplicities=False)[0] + preimage = f(z) - y*g(z) + minimal_preimage = R(prod(x[0] for x in preimage.factor())) + if minimal_preimage.degree() + bool(preimage.degree()= 3: + T_poly = minimal_preimage + infinity_check = bool(preimage.degree() = PolynomialRing(GF(11)) + sage: f = x^11 + sage: L = [[[0, 1], [], 1], [[10, 1], [], 1], [[9, 1], [], 1], + ....: [[8, 1], [],1], [[7, 1], [], 1], [[6, 1], [], 1], [[5, 1], [], 1], + ....: [[4, 1], [], 1],[[3, 1], [], 1], [[2, 1], [], 1], [[1, 1], [], 1], + ....: [[1, 0], [], 1]] + sage: from sage.schemes.projective.endPN_automorphism_group import order_p_automorphisms + sage: order_p_automorphisms(f,L) + [x/(x + 1), 6*x/(x + 6), 3*x/(x + 3), 7*x/(x + 7), 9*x/(x + 9), 10*x/(x + + 10), 5*x/(x + 5), 8*x/(x + 8), 4*x/(x + 4), 2*x/(x + 2), 10/(x + 2), + (5*x + 10)/(x + 7), (2*x + 10)/(x + 4), (6*x + 10)/(x + 8), (8*x + + 10)/(x + 10), (9*x + 10)/x, (4*x + 10)/(x + 6), (7*x + 10)/(x + 9), (3*x + + 10)/(x + 5), (x + 10)/(x + 3), (10*x + 7)/(x + 3), (4*x + 7)/(x + 8), + (x + 7)/(x + 5), (5*x + 7)/(x + 9), (7*x + 7)/x, (8*x + 7)/(x + 1), (3*x + + 7)/(x + 7), (6*x + 7)/(x + 10), (2*x + 7)/(x + 6), 7/(x + 4), (9*x + + 2)/(x + 4), (3*x + 2)/(x + 9), 2/(x + 6), (4*x + 2)/(x + 10), (6*x + + 2)/(x + 1), (7*x + 2)/(x + 2), (2*x + 2)/(x + 8), (5*x + 2)/x, (x + + 2)/(x + 7), (10*x + 2)/(x + 5), (8*x + 6)/(x + 5), (2*x + 6)/(x + 10), + (10*x + 6)/(x + 7), (3*x + 6)/x, (5*x + 6)/(x + 2), (6*x + 6)/(x + 3), + (x + 6)/(x + 9), (4*x + 6)/(x + 1), 6/(x + 8), (9*x + 6)/(x + 6), (7*x + + 8)/(x + 6), (x + 8)/x, (9*x + 8)/(x + 8), (2*x + 8)/(x + 1), (4*x + + 8)/(x + 3), (5*x + 8)/(x + 4), 8/(x + 10), (3*x + 8)/(x + 2), (10*x + + 8)/(x + 9), (8*x + 8)/(x + 7), (6*x + 8)/(x + 7), 8/(x + 1), (8*x + + 8)/(x + 9), (x + 8)/(x + 2), (3*x + 8)/(x + 4), (4*x + 8)/(x + 5), (10*x + + 8)/x, (2*x + 8)/(x + 3), (9*x + 8)/(x + 10), (7*x + 8)/(x + 8), (5*x + + 6)/(x + 8), (10*x + 6)/(x + 2), (7*x + 6)/(x + 10), 6/(x + 3), (2*x + + 6)/(x + 5), (3*x + 6)/(x + 6), (9*x + 6)/(x + 1), (x + 6)/(x + 4), (8*x + + 6)/x, (6*x + 6)/(x + 9), (4*x + 2)/(x + 9), (9*x + 2)/(x + 3), (6*x + + 2)/x, (10*x + 2)/(x + 4), (x + 2)/(x + 6), (2*x + 2)/(x + 7), (8*x + + 2)/(x + 2), 2/(x + 5), (7*x + 2)/(x + 1), (5*x + 2)/(x + 10), (3*x + + 7)/(x + 10), (8*x + 7)/(x + 4), (5*x + 7)/(x + 1), (9*x + 7)/(x + 5), + 7/(x + 7), (x + 7)/(x + 8), (7*x + 7)/(x + 3), (10*x + 7)/(x + 6), (6*x + + 7)/(x + 2), (4*x + 7)/x, (2*x + 10)/x, (7*x + 10)/(x + 5), (4*x + + 10)/(x + 2), (8*x + 10)/(x + 6), (10*x + 10)/(x + 8), 10/(x + 9), (6*x + + 10)/(x + 4), (9*x + 10)/(x + 7), (5*x + 10)/(x + 3), (3*x + 10)/(x + 1), + x + 1, x + 2, x + 4, x + 8, x + 5, x + 10, x + 9, x + 7, x + 3, x + 6] + """ + # define ground field and ambient function field + if rational_function.parent().is_field(): + K = rational_function.parent() + R = K.ring() + else: + R = rational_function.parent() + K = R.fraction_field() + + z = R.gen(0) + phi = K(rational_function) + F = R.base_ring() + q = F.cardinality() + p = F.characteristic() + r = (q-1) / (p-1) # index of F_p^\times inside F^\times + pre_image = pre_data + + # Compute the threshold r2 for determining which algorithm to use + if len(pre_image) > 1: + r2 = len(pre_image) + case = 'fix' + elif len(pre_image[0][1]) > 0: + r2 = len(pre_image[0][1]) + case = 'F-pre_images' + else: + factor_list = pre_image[0][2].factor() + minimal_fix_poly = R(prod(x[0] for x in factor_list)) + r2 = sum(x[0].degree() for x in factor_list) + # Note that infinity is F-rational, so covered by preceding case + case = 'all pre_images' + + automorphisms_p = [] + + if r2 >= r or r2 == 0: + # Note that r2 == 0 corresponds to having a unique F-rational fixed point + # that is totally ramified + + for guy in pre_image: + pt = guy[0] + zeta = F.multiplicative_generator() + alpha = zeta**r + + if pt == [F(1),F(0)]: + for j in range(r): + s = z + zeta**j + if s(phi(z)) == phi(s(z)): + for i in range(p-1): + automorphisms_p.append(z+alpha**i*zeta**j) + + else: + u = F(1) / (z - pt[0]) + u_inv = pt[0] + F(1)/z + for j in range(r): + s = u_inv( u(z) + zeta**j ) + if s(phi(z)) == phi(s(z)): + for i in range(p-1): + automorphisms_p.append(u_inv( u(z) + alpha**i*zeta**j) ) + + elif r2 < r: + + if case=='fix': + T = [x[0] for x in pre_image] + elif case == 'F-pre_images': + T = [x for x in pre_image[0][1]] + else: + T = [] + + # loop over all F-rational pre-images + for guy in pre_image: + pt = guy[0] + + # treat case of multiple F-rational fixed points or + # 1 F-rational fixed point with F-rational pre-images + if T != []: + M = [t for t in T if t != pt] + m = len(M) + if pt == [F(1),F(0)]: + for i in range(1, m): + s = z + M[i][0] - M[0][0] + if s(phi(z)) == phi(s(z)): + automorphisms_p.append(s) + + else: + u = F(1) / (z - pt[0]) + u_inv = pt[0] + F(1)/z + for i in range(1,m): + if M[0] == [F(1),F(0)]: uy1 = 0 + else: uy1 = u(M[0][0]) + if M[i] == [F(1),F(0)]: uy2 = 0 + else: uy2 = u(M[i][0]) + s = u_inv( u(z) + uy2 - uy1 ) + if s(phi(z)) == phi(s(z)): + automorphisms_p.append(s) + + elif T==[]: + # create the extension field generated by pre-images of the unique fixed point + T_poly = pre_image[0][2] + e = lcm([x[0].degree() for x in T_poly.factor()])*F.degree() + E = GF(p**e, 'b') + b = E.gen(0) + sigma = F.Hom(E)[0] + S = PolynomialRing(E,'w') + w = S.gen(0) + E_poly = rational_function_coerce(T_poly, sigma, S) + + # List of roots permuted by elements of order p + # Since infinity is F-rational, it won't appear in this list + T = [ [alpha, E(1)] for alpha in E_poly.roots(ring=E, multiplicities=False)] + + + # coerce the rational function and fixed point into E + Phi = rational_function_coerce(phi, sigma, S) + Pt = [sigma(pt[0]), sigma(pt[1])] + + m = len(T) + if Pt == [E(1),E(0)]: + for i in range(1, m): + s = w + T[i][0] - T[0][0] + if s(Phi(w)) == Phi(s(w)): + automorphisms_p.append(rational_function_coefficient_descent(s, sigma, R)) + + else: + u = E(1) / (w - Pt[0]) + u_inv = Pt[0] + E(1)/w + for i in range(1,m): + uy1 = u(T[0][0]) + uy2 = u(T[i][0]) + s = u_inv( u(w) + uy2 - uy1 ) + if s(Phi(w)) == Phi(s(w)): + s = rational_function_reduce(s) + automorphisms_p.append(rational_function_coefficient_descent(s,sigma,R)) + + return automorphisms_p + +def automorphisms_fixing_pair(rational_function, pair, quad): + r""" + INPUT: + + - ``rational_function``-- rational function defined over finite field `E`. + + - ``pair``-- a pair of points of `\mathbb{P}^1(E)`. + + - ``quad``-- an indicator if this is a quadratic pair of points + + OUTPUT: + + - set of automorphisms defined over `E` that fix the pair, excluding the identity. + + EXAMPLES:: + + sage: R. = PolynomialRing(GF(7^2,'t')) + sage: f = (z^2 + 5*z + 5)/(5*z^2 + 5*z + 1) + sage: L = [[4, 1], [2, 1]] + sage: from sage.schemes.projective.endPN_automorphism_group import automorphisms_fixing_pair + sage: automorphisms_fixing_pair(f,L,False) + [(6*z + 6)/z, 4/(3*z + 3)] + """ + # define ground field and ambient function field + if rational_function.parent().is_field(): + K = rational_function.parent() + R = K.ring() + else: + R = rational_function.parent() + K = R.fraction_field() + + z = R.gen(0) + phi = K(rational_function) + E = R.base_ring() + T = pair + f = phi.numerator() + g = phi.denominator() + D = max(f.degree(), g.degree()) + + if T[0] == [1,0]: + u = K(z - T[1][0]) + u_inv = K(z + T[1][0]) + elif T[1] == [1,0]: + u = K(E(1) / (z - T[0][0])) + u_inv = K( (T[0][0]*z + 1) / z ) + else: + u = K( (z - T[1][0]) / (z - T[0][0]) ) + u_inv = K( (T[0][0]*z - T[1][0] ) / (z - 1) ) + + automorphisms_prime_to_p = [] + + # Quadratic automorphisms have order dividing q+1 and D, D-1, or D+1 + if quad==True: + q = sqrt(E.cardinality()) + zeta = (E.multiplicative_generator())**(q-1) + for j in [-1,0,1]: + g = gcd(q+1, D + j) + xi = zeta**( (q+1) / g ) + for i in range(1,g): + s = u_inv(xi**i*u(z)) + if s(phi(z)) == phi(s(z)): + automorphisms_prime_to_p.append(rational_function_reduce(s)) + + # rational automorphisms have order dividing q-1 and D, D-1, or D+1 + else: + q = E.cardinality() + zeta = E.multiplicative_generator() + for j in [-1,0,1]: + g = gcd(q-1, D + j) + xi = zeta**( (q-1) / g ) + for i in range(1,g): + s = u_inv(xi**i*u(z)) + if s(phi(z)) == phi(s(z)): + automorphisms_prime_to_p.append(rational_function_reduce(s)) + + return list(set(automorphisms_prime_to_p)) + +def automorphism_group_FF_alg3(rational_function): + r""" + Implementation of Algorithm 3 in the paper by Faber/Manes/Viray + for computing the automorphism group over a finite field. + + INPUT: + + - ``rational_function``--a rational function defined over a finite field `F`. + + OUTPUT: + + - list of `F`-rational automorphisms of ``rational_function``. + + EXAMPLES:: + + sage: R. = PolynomialRing(GF(5^3,'t')) + sage: f = (3456*z^4) + sage: from sage.schemes.projective.endPN_automorphism_group import automorphism_group_FF_alg3 + sage: automorphism_group_FF_alg3(f) + [z, 3/(3*z)] + """ + # define ground field and ambient function field + if rational_function.parent().is_field(): + K = rational_function.parent() + R = K.ring() + else: + R = rational_function.parent() + K = R.fraction_field() + + F = R.base_ring() + if not F.is_finite() or not F.is_field(): + raise TypeError("Coefficient ring is not a finite field.") + p = F.characteristic() + q = F.cardinality() + z = R.gen(0) + phi = K(rational_function) + f = phi.numerator() + g = phi.denominator() + D = max(f.degree(), g.degree()) + + # For use in the quadratic extension parts of the algorithm + E = GF(p**(2*F.degree()),'b') + b = E.gen(0) + sigma = F.Hom(E)[0] + S = PolynomialRing(E, 'w') + w = S.gen(0) + Phi = rational_function_coerce(phi, sigma, S) + + # Compute the set of distinct F-rational and F-quadratic + # factors of the fixed point polynomial + fix = f(z) - z*g(z) + linear_fix = gcd(fix, z**q - z); + quad_temp = fix.quo_rem(linear_fix)[0] + residual = gcd(quad_temp, z**q - z) + while residual.degree() > 0: + quad_temp = quad_temp.quo_rem(residual)[0] + residual = gcd(quad_temp, z**q - z) + quadratic_fix = gcd(quad_temp, z**(q**2) - z).factor() + + # Compute the set of distinct F-rational fixed points + linear_fix_pts = [[ x, F(1)] for x in linear_fix.roots(multiplicities=False)] + if bool(fix.degree() < D+1): + linear_fix_pts.append( [F(1),F(0)] ) + n1 = len(linear_fix_pts) + + # Coerce quadratic factors into a quadratic extension + quad_fix_factors = [ rational_function_coerce(poly[0], sigma, S) for poly in quadratic_fix] + n2 = 2*len(quad_fix_factors) + + # Collect pre-image data as a list L with entries in the form + # [fixed point y, F-rational pre-images z != y, polynomial defining the pre-images] + # Note that we remove the fixed point from its pre-image set and its polynomial + pre_images = [] + for y in linear_fix_pts: + if y == [F(1),F(0)]: + Fpre = [ [x,F(1)] for x in g.roots(multiplicities=False) ] + pre_images.append([y, Fpre, g]) + else: + Fpre = [ [x,F(1)] for x in (f - y[0]*g).roots(multiplicities=False) if x != y[0]] + if y[0] == 0 and f.degree() < g.degree(): + Fpre.append([F(1), F(0)]) # infinity is a pre-image of 0 + elif f.degree() == g.degree() and f.leading_coefficient() == y[0]*g.leading_coefficient(): + Fpre.append([F(1), F(0)]) # infinity is a pre-image of y[0] + # remove y[0] as a root of pre-image polynomial ??? + h = (f - y[0]*g).quo_rem(z-y[0])[0] + h_common = gcd(h, z-y[0]) + while h_common.degree() > 0: + h = h.quo_rem(z-y[0])[0] + h_common = gcd(h,z-y[0]) + pre_images.append([y, Fpre, h]) + + # Initialize the set of automorphisms to contain the identity + automorphisms = [R(z)] + automorphisms_quad = [] + + # order p elements + # An F-rational fixed point has orbit length 1 or p under the action of an element of + # order p. An F-quadratic fixed point has orbit length p. The set of F-rational + # pre-images of fixed points decomposes as a union of orbits of length p. + if n1%p == 1 and n2%p == 0 and sum(len(x[1]) for x in pre_images)%p == 0: + # Compute total number of distinct fixed points as a final check for order p auts + factor_list = fix.factor() + minimal_fix_poly = R(prod(x[0] for x in factor_list)) + n = sum(x[0].degree() for x in factor_list) + bool(fix.degree() < D+1) + if n%p == 1: + automorphisms = automorphisms + order_p_automorphisms(phi, pre_images) + + ## nontrivial elements with order prime to p ## + # case of 2 F-rational fixed points + for pt_pair in combinations(linear_fix_pts, 2): + x = pt_pair[0] + y = pt_pair[1] + automorphisms = automorphisms + automorphisms_fixing_pair(phi, [x,y], False) + + # case of 1 F-rational fixed point and an F-rational pre-image + for y in pre_images: + for x in y[1]: + automorphisms = automorphisms + automorphisms_fixing_pair(phi, [x,y[0]], False) + + # case of a pair of quadratic fixed points + for h in quad_fix_factors: + quad_fix_pts = [ [x,E(1)] for x in h.roots(multiplicities=False)] + automorphisms_quad = automorphisms_quad + automorphisms_fixing_pair(Phi, quad_fix_pts, True) + + phi_2 = phi(phi(z)) + f_2 = phi_2.numerator() + g_2 = phi_2.denominator() + + period_2 = (f_2(z) - z*g_2(z)).quo_rem(fix)[0] + factor_list_2 = period_2.factor() + linear_period_2_pts = [[ x, F(1)] for x in period_2.roots(multiplicities=False)] + if bool(period_2.degree() < D**2-D): + linear_period_2_pts.append( [F(1),F(0)] ) + quad_period_2_factors = [rational_function_coerce(poly[0], sigma, S) for poly in factor_list_2 if poly[0].degree() == 2] + # n2 = n1 + 2*len(quad_fix_factors) + + # case of a pair of F-rational period 2 points + linear_period_2_pairs = [] + while len(linear_period_2_pts) > 0: + x = linear_period_2_pts.pop(-1) + if x[1] == 1 and g(x[0]) != 0: + y = [phi(x[0]), F(1)] + elif x[1] == 1 or f.degree() > g.degree(): + y = [F(1), F(0)] + elif f.degree() == g.degree(): + y = [f.leading_coefficient() / g.leading_coefficient(), F(1)] + else: + y = [F(0), F(1)] + + if x != y: + linear_period_2_pts.remove(y) + linear_period_2_pairs.append([x,y]) + + for pt_pair in linear_period_2_pairs: + automorphisms = automorphisms + automorphisms_fixing_pair(phi, pt_pair, False) + + # case of a pair of quadratic period 2 points + for h in quad_period_2_factors: + pt_pair = [ [x,E(1)] for x in h.roots(multiplicities=False)] + if Phi(pt_pair[0][0]) == pt_pair[1][0]: + automorphisms_quad = automorphisms_quad + automorphisms_fixing_pair(Phi, pt_pair, True) + + # Descend coefficients of the quadratic guys back to the base field + for s in automorphisms_quad: + automorphisms.append(rational_function_coefficient_descent(s, sigma, R)) + + return automorphisms + +################################################################################ + + +# Input: a finite list of elements of PGL(2,K) that we know a priori form a group +# Output: the isomorphism type of the group +# This function makes heavy use of the classification of finite subgroups of PGL(2,K) +def which_group(list_of_elements): + r""" + Given a finite subgroup of `PGL2` determine its isomorphism class. + INPUT: + + - ``list_of_elements``-- a finite list of elements of `PGL(2,K)` + that we know a priori form a group + + OUTPUT: + + - String -- the isomorphism type of the group. + + EXAMPLES:: + + sage: R. = PolynomialRing(GF(7,'t')) + sage: G = [x, 6*x/(x + 1), 6*x + 6, 1/x, (6*x + 6)/x, 6/(x + 1)] + sage: from sage.schemes.projective.endPN_automorphism_group import which_group + sage: which_group(G) + 'Dihedral of order 6' + """ + if is_Matrix(list_of_elements[-1]): + R = PolynomialRing(list_of_elements[-1].base_ring(),'z') + z = R.gen(0) + G=[(t[0,0]*z+t[0,1])/(t[1,0]*z+t[1,1]) for t in list_of_elements] + else: + G = list_of_elements + + n = ZZ(len(G)) + + # invalid input + if n == 0: + return + + # define ground field and ambient function field + rational_function = G[-1] + + if rational_function.parent().is_field(): + K = rational_function.parent() + R = K.ring() + else: + R = rational_function.parent() + K = R.fraction_field() + + z = R.gen(0) + p = K.characteristic() + + # factor n = mp^e; set e = 0 and m = n if p = 0 (Sage sets 0^0 = 1) + if p > 0: + m = n.prime_to_m_part(p) + e = ZZ(n/m).exact_log(p) + else: + m = n + e = 0 + + # Determine if G is cyclic or dihedral. + # This determines the maximal cyclic subgroup and the maximal cyclic + # p-regular subgroup. Algorithm terminates if the order of this subgroup agrees with + # the order of the group. + max_reg_cyclic = [1, z, [z]] # initialize order of cyclic p-regular subgroup and generator + discard = [] # list of elements already considered + + for g in G: + if g not in discard: + H = [g] + for i in range(n-1): + h = g(H[-1]) + H.append(h) + H = list(set(H)) + if len(H) == n: + # return ['Cyclic of order {0}'.format(n), g] + return 'Cyclic of order {0}'.format(n) + if len(H) > max_reg_cyclic[0] and gcd(len(H), p) != p: + max_reg_cyclic = [len(H), g, H] + discard = list(set(discard +H)) # adjoin all new elements to discard + + n_reg = max_reg_cyclic[0] + + # Test for dihedral subgroup. A subgroup of index 2 is always normal, so the + # presence of a cyclic subgroup H of index 2 indicates the group is either + # H x Z/2Z or dihedral. The former occurs only if H has order 1 or 2, both of + # which are dihedral. + if 2*n_reg == n: + for g in G: + if g not in max_reg_cyclic[2]: + # return ['Dihedral of order {0}'.format(n), [max_reg_cyclic[1],g]] + return 'Dihedral of order {0}'.format(n) + + # Check the p-irregular cases. There is overlap in these cases when p^e = 2, + # which is dihedral and so already dealt with above. By the classification theorem, + # these are either p-semi-elementary, PGL(2,q), PSL(2,q), or A_5 when p=3. The latter + # case is already covered by the remaining sporadic cases below. + if e > 0: + if n_reg == m: # p-semi-elementary + # return ['{0}-semi-elementary of order {1}'.format(p, n), 'No generator support'] + return '{0}-semi-elementary of order {1}'.format(p, n) + if n_reg == m / (p**e - 1) and m == p**(2*e) - 1: # PGL(2) + return 'PGL(2,{0})'.format(p**e) + if n_reg == m / (p**e - 1) and m == (1/2)*(p**(2*e) - 1): # PSL(2) + return 'PSL(2,{0})'.format(p**e) + + # Treat sporadic cases + if n == 12: + return ['A_4'] + + elif n == 24: + return ['S_4'] + + else: + return ['A_5'] + + return \ No newline at end of file diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 006e8cc7bda..f17c4fda242 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -2133,6 +2133,99 @@ def minimal_model(self, return_transformation=False, prime_list=None): from endPN_minimal_model import affine_minimal return(affine_minimal(self, return_transformation, prime_list, False)) + def automorphism_group(self, **kwds): + r""" + Given a homogenous rational function, this calculates the subsgroup of `PGL2` that is + the automorphism group of ``self``. + + INPUT: + + keywords: + + - ``starting_prime`` -- The first prime to use for CRT. default: 5.(optional) + + - ``algorithm``-- Choose ``CRT``-Chinese Remainder Theorem- or ``fixed_points`` algorithm. + default: depends on ``self``. (optional) + + - ``return_functions``-- Boolean - True returns elements as linear fractional transformations. + False returns elements as `PGL2` matrices. default: False. (optional) + + - ``iso_type`` -- Boolean - True returns the isomorphism type of the automorphism group. + default: False (optional) + + OUTPUT: + + - list - elements of automorphism group. + + AUTHORS: + + - Original algorithm written by Xander Faber, Michelle Manes, Bianca Viray + - Modified by Joao Alberto de Faria, Ben Hutz, Bianca Thompson + + REFERENCES: + ..[FMV] - "Computing Conjugating Sets and Automorphism Groups of Rational Functions" + by Xander Faber, Michelle Manes, and Bianca Viray + + EXAMPLES:: + + sage: R. = ProjectiveSpace(QQ,1) + sage: H = End(R) + sage: f = H([x^2-y^2,x*y]) + sage: f.automorphism_group(return_functions=True) + [x, -x] + + :: + + sage: R. = ProjectiveSpace(QQ,1) + sage: H = End(R) + sage: f = H([x^2 + 5*x*y + 5*y^2,5*x^2 + 5*x*y + y^2]) + sage: f.automorphism_group() + [ + [1 0] [0 2] + [0 1], [2 0] + ] + + :: + + sage: R. = ProjectiveSpace(QQ,1) + sage: H = End(R) + sage: f=H([x^2-2*x*y-2*y^2,-2*x^2-2*x*y+y^2]) + sage: f.automorphism_group(return_functions=True) + [x, 2/(2*x), -x - 1, -2*x/(2*x + 2), (-x - 1)/x, -1/(x + 1)] + + :: + + sage: R. = ProjectiveSpace(QQ,1) + sage: H = End(R) + sage: f = H([3*x^2*y - y^3,x^3 - 3*x*y^2]) + sage: f.automorphism_group(algorithm='CRT',return_functions=True,iso_type=True) + ([x, (x + 1)/(x - 1), (-x + 1)/(x + 1), -x, 1/x, -1/x, (x - 1)/(x + 1), (-x - 1)/(x - 1)], 'Dihedral of order 8') + """ + + alg=kwds.get('algorithm',None) + p=kwds.get('starting_prime', 5) + return_functions=kwds.get('return_functions', False) + iso_type=kwds.get('iso_type',False) + + if self.domain().dimension_relative()!=1: + raise NotImplementedError, "Must be dimension 1" + else: + f=self.dehomogenize(1) + z=f[0].parent().gen() + if f[0].denominator()!=1: + F=(f[0].numerator().polynomial(z))/f[0].denominator().polynomial(z) + else: + F=f[0].numerator().polynomial(z) + from endPN_automorphism_group import automorphism_group_QQ_CRT, automorphism_group_QQ_fixedpoints + if alg is None: + if self.degree() <= 12: + return(automorphism_group_QQ_fixedpoints(F, return_functions, iso_type)) + return(automorphism_group_QQ_CRT(F, p, return_functions, iso_type)) + elif alg == 'CRT': + return(automorphism_group_QQ_CRT(F, p, return_functions, iso_type)) + + return(automorphism_group_QQ_fixedpoints(F, return_functions, iso_type)) + class SchemeMorphism_polynomial_projective_space_field(SchemeMorphism_polynomial_projective_space): def lift_to_rational_periodic(self, points_modp, B=None): @@ -2963,3 +3056,88 @@ def possible_periods(self, return_points=False): """ return _fast_possible_periods(self,return_points) + def automorphism_group(self, **kwds): + r""" + Given a homogenous rational function, this calculates the subsgroup of `PGL2` that is + the automorphism group of ``self``. + + INPUT: + + keywords: + + - ``absolute``-- Boolean - True returns the absolute automorphism group and a field of definition. default: False (optional) + + - ``iso_type`` -- Boolean - True returns the isomorphism type of the automorphism group. default: False (optional) + + - ``return_functions``-- Boolean - True returns elements as linear fractional transformations. + False returns elements as `PGL2` matrices. default: False. (optional) + + OUTPUT: + + - list - elements of automorphism group. + + AUTHORS: + + - Original algorithm written by Xander Faber, Michelle Manes, Bianca Viray + - Modified by Joao Alberto de Faria, Ben Hutz, Bianca Thompson + + REFERENCES: + ..[FMV] - "Computing Conjugating Sets and Automorphism Groups of Rational Functions" + by Xander Faber, Michelle Manes, and Bianca Viray + + EXAMPLES:: + + sage: R. = ProjectiveSpace(GF(7^3,'t'),1) + sage: H = End(R) + sage: f = H([x^2-y^2,x*y]) + sage: f.automorphism_group() + [ + [1 0] [6 0] + [0 1], [0 1] + ] + + :: + + sage: R. = ProjectiveSpace(GF(3^2,'t'),1) + sage: H = End(R) + sage: f = H([x^3,y^3]) + sage: f.automorphism_group(return_functions=True,iso_type=True) # long time + ([x, x/(x + 1), x/(2*x + 1), 2/(x + 2), (2*x + 1)/(2*x), (2*x + 2)/x, + 1/(2*x + 2), x + 1, x + 2, x/(x + 2), 2*x/(x + 1), 2*x, 1/x, 2*x + 1, + 2*x + 2, ((t + 2)*x + t + 2)/((2*t + 1)*x + t + 2), (t*x + 2*t)/(t*x + + t), 2/x, (x + 1)/(x + 2), (2*t*x + t)/(t*x), (2*t + 1)/((2*t + 1)*x + + 2*t + 1), ((2*t + 1)*x + 2*t + 1)/((2*t + 1)*x), t/(t*x + 2*t), (2*x + + 1)/(x + 1)], 'PGL(2,3)') + + :: + + sage: R. = ProjectiveSpace(GF(2^5,'t'),1) + sage: H = End(R) + sage: f=H([x^5,y^5]) + sage: f.automorphism_group(return_functions=True,iso_type=True) + ([x, 1/x], 'Cyclic of order 2') + + :: + + sage: R. = ProjectiveSpace(GF(3^4,'t'),1) + sage: H = End(R) + sage: f=H([x^2+25*x*y+y^2,x*y+3*y^2]) + sage: f.automorphism_group(absolute=True) + [Univariate Polynomial Ring in w over Finite Field in b of size 3^4, [[1 0] + [0 1]]] + """ + absolute=kwds.get('absolute',False) + iso_type=kwds.get('iso_type',False) + return_functions=kwds.get('return_functions',False) + + if self.domain().dimension_relative()!=1: + raise NotImplementedError, "Must be dimension 1" + else: + f=self.dehomogenize(1) + z=f[0].parent().gen() + if f[0].denominator()!=1: + F=(f[0].numerator().polynomial(z))/f[0].denominator().polynomial(z) + else: + F=f[0].numerator().polynomial(z) + from endPN_automorphism_group import automorphism_group_FF + return(automorphism_group_FF(F, absolute, iso_type, return_functions)) From 2947606572e5421301eb408d26066def13b267d4 Mon Sep 17 00:00:00 2001 From: Julian Rueth Date: Wed, 25 Jun 2014 19:03:00 +0200 Subject: [PATCH 044/698] Improved docstring of polynomial gcd. --- src/sage/rings/polynomial/polynomial_element.pyx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index d36bea278e5..35023fa5d98 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -3692,17 +3692,17 @@ cdef class Polynomial(CommutativeAlgebraElement): @coerce_binop def gcd(self, other): """ - Compute a greatest common divisor of ``self`` and ``other``. + Compute a greatest common divisor of this polynomial and ``other``. INPUT: - - ``other`` -- a polynomial in the same ring as ``self`` + - ``other`` -- a polynomial in the same ring as this polynomial OUTPUT: - A greatest common divisor of ``self`` and ``other`` as a polynomial - in the same ring as ``self``. Over a field, the return value will - be a monic polynomial. + A greatest common divisor as a polynomial in the same ring as this + polynomial. Over a field, the return value will be a monic + polynomial. .. NOTE:: From 62fdcda1159d16bbb4b4a72b94b3c9c555ad9238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 25 Jun 2014 21:01:06 +0200 Subject: [PATCH 045/698] trac #14567 taking care of doctest continuation --- src/sage/geometry/cone.py | 22 +++++++++++----------- src/sage/tests/book_stein_ent.py | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index 1c7775b91a6..518c5b924c9 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -1058,17 +1058,17 @@ def classify_cone_2d(ray0, ray1, check=True): sage: from sage.geometry.cone import normalize_rays sage: for i in range(10): - ... ray0 = random_vector(ZZ, 3) - ... ray1 = random_vector(ZZ, 3) - ... if ray0.is_zero() or ray1.is_zero(): continue - ... ray0, ray1 = normalize_rays([ray0, ray1], ZZ^3) - ... d, k = classify_cone_2d(ray0, ray1, check=True) - ... assert (d,k) == classify_cone_2d(ray1, ray0) - ... if d == 0: continue - ... frac = (k/d).continued_fraction_list("hj") - ... if len(frac)>100: continue # avoid expensive computation - ... hilb = Cone([ray0, ray1]).Hilbert_basis() - ... assert len(hilb) == len(frac) + 1 + ....: ray0 = random_vector(ZZ, 3) + ....: ray1 = random_vector(ZZ, 3) + ....: if ray0.is_zero() or ray1.is_zero(): continue + ....: ray0, ray1 = normalize_rays([ray0, ray1], ZZ^3) + ....: d, k = classify_cone_2d(ray0, ray1, check=True) + ....: assert (d,k) == classify_cone_2d(ray1, ray0) + ....: if d == 0: continue + ....: frac = (k/d).continued_fraction_list("hj") + ....: if len(frac)>100: continue # avoid expensive computation + ....: hilb = Cone([ray0, ray1]).Hilbert_basis() + ....: assert len(hilb) == len(frac) + 1 """ if check: assert ray0.parent() is ray1.parent() diff --git a/src/sage/tests/book_stein_ent.py b/src/sage/tests/book_stein_ent.py index b933092410f..8a9a252ad6d 100644 --- a/src/sage/tests/book_stein_ent.py +++ b/src/sage/tests/book_stein_ent.py @@ -411,10 +411,10 @@ sage: [c.convergent(i) for i in xrange(5)] [3, 22/7, 333/106, 355/113, 103993/33102] sage: for n in range(-1, 13): -... print c.p(n)*c.q(n-1) - c.q(n)*c.p(n-1), +....: print c.p(n)*c.q(n-1) - c.q(n)*c.p(n-1), 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 sage: for n in range(13): -... print c.p(n)*c.q(n-2) - c.q(n)*c.p(n-2), +....: print c.p(n)*c.q(n-2) - c.q(n)*c.p(n-2), 3 -7 15 -1 292 -1 1 -1 2 -1 3 -1 14 sage: c = continued_fraction([1,2,3,4,5]) sage: c.convergents() From f40215a7eb8b673d7abae3b2f4dab73eadf22ce2 Mon Sep 17 00:00:00 2001 From: Mario Pernici Date: Tue, 1 Jul 2014 19:24:45 +0200 Subject: [PATCH 046/698] added function `permanental_minor_vector`; used in `rook_vector` --- src/sage/matrix/matrix2.pyx | 8 +-- src/sage/matrix/matrix_misc.py | 128 +++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 4 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index a76cb42622f..ba50c01e1dc 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -49,6 +49,7 @@ import sage.modules.free_module import matrix_space import berlekamp_massey from sage.modules.free_module_element import is_FreeModuleElement +from sage.matrix.matrix_misc import permanental_minor_vector cdef class Matrix(matrix1.Matrix): def _backslash_(self, B): @@ -946,6 +947,7 @@ cdef class Matrix(matrix1.Matrix): AUTHORS: - Jaap Spies (2006-02-24) + - Mario Pernici (2014-07-01) """ m = self._nrows n = self._ncols @@ -960,10 +962,8 @@ cdef class Matrix(matrix1.Matrix): if not (x == 0 or x == 1): raise ValueError, "must have zero or one, but we have (=%s)"%x - tmp = [] - for k in range(m+1): - tmp.append(self.permanental_minor(k)) - return tmp + p = permanental_minor_vector(self) + return p def minors(self,k): r""" diff --git a/src/sage/matrix/matrix_misc.py b/src/sage/matrix/matrix_misc.py index 7a5069cb7af..9870c7b4082 100644 --- a/src/sage/matrix/matrix_misc.py +++ b/src/sage/matrix/matrix_misc.py @@ -19,6 +19,7 @@ #***************************************************************************** from sage.categories.fields import Fields +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing _Fields = Fields() def row_iterator(A): @@ -199,3 +200,130 @@ def weak_popov_form(M,ascend=True): # return reduced matrix and operations matrix return (matrix(r)/den, matrix(N), d) + +def _prm_mul(p1, p2, free_vars_indices, K): + p = {} + mask_free = 0 + one = int(1) + for i in free_vars_indices: + mask_free += one << i + if not p2: + return p + get = p.get + for exp1, v1 in p1.iteritems(): + for exp2, v2 in p2.items(): + if exp1 & exp2: + continue + exp = exp1 | exp2 + v = v1*v2 + if exp & mask_free: + for i in free_vars_indices: + #print 'DB14 exp=%s i=%s' %(exp, i) + if exp & (one << i): + exp = exp.__xor__(one << i) + #print 'DB14b exp=%s' % exp + p[exp] = get(exp, K.zero()) + v + return p + + +def _is_free_var(i, k, m): + """ + i current row + k index of the variable + m matrix as a list of lists + returns true if the variable `k` does not occur from row `i` on + """ + for j in range(i, len(m)): + if m[j][k] != 0: + return False + return True + +def permanental_minor_vector(m, permanent_only=False): + """ + Return the polynomial of the sums of permanental minors of a matrix `m` + in array form. + + The polynomial of the sums of permanental minors is + + .. MATH:: + + \sum_0^{min(nrows, ncols)} p_i(m) x^i + + where `p_i(m) = m.permanental_minor(i)` + + + INPUT: + + - `m` - matrix + + - `permanent_only` if True, only the permanent is computed + + OUTPUT: + + polynomial in array form; the last element of the array is the permanent. + + EXAMPLES:: + + sage: from sage.matrix.matrix_misc import permanental_minor_vector + sage: m = matrix([[1,1],[1,2]]) + sage: permanental_minor_vector(m) + [1, 5, 3] + sage: permanental_minor_vector(m, permanent_only=1) + 3 + + :: + + sage: M = MatrixSpace(QQ,2,2) + sage: A = M([1/5,2/7,3/2,4/5]) + sage: permanental_minor_vector(A, 1) + 103/175 + + :: + + sage: R. = PolynomialRing(ZZ) + sage: A = MatrixSpace(R,2)([[a,1], [a,a+1]]) + sage: permanental_minor_vector(A, 1) + a^2 + 2*a + + REFERENCES: + + P. Butera and M. Pernici + ``Sums of permanental minors using Grassmann algebra'' + http://arxiv.org/abs/1406.5337 + """ + K = PolynomialRing(m.base_ring(), 'K') + m = list(m) + nrows = len(m) + ncols = len(m[0]) + p = {int(0):K.one()} + t = K.gen() + done_vars = set() + one = int(1) + for i in range(nrows): + if permanent_only: + p1 = {} + else: + p1 = {int(0): K.one()} + a = m[i] + for j in range(len(a)): + if a[j]: + p1[one< Date: Tue, 1 Jul 2014 22:26:49 +0200 Subject: [PATCH 047/698] fixed bug in `permanental_minor_vector` in case of vanishing permanent --- src/sage/matrix/matrix_misc.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_misc.py b/src/sage/matrix/matrix_misc.py index 9870c7b4082..774acc85227 100644 --- a/src/sage/matrix/matrix_misc.py +++ b/src/sage/matrix/matrix_misc.py @@ -271,6 +271,14 @@ def permanental_minor_vector(m, permanent_only=False): sage: permanental_minor_vector(m, permanent_only=1) 3 + :: + + sage: from sage.matrix.matrix_misc import permanental_minor_vector + sage: M = MatrixSpace(ZZ,4,4) + sage: A = M([1,0,1,0,1,0,1,0,1,0,10,10,1,0,1,1]) + sage: permanental_minor_vector(A) + [1, 28, 114, 84, 0] + :: sage: M = MatrixSpace(QQ,2,2) @@ -321,7 +329,7 @@ def permanental_minor_vector(m, permanent_only=False): return K.zero() assert len(p) == 1 a = p[0].coeffs() - len_a = min(nrows, ncols) + len_a = min(nrows, ncols) + 1 if len(a) < len_a: a += [0]*(len_a - len(a)) if permanent_only: From 0190e4d1140c1f6c892b16f49e4670071a41a0b7 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Wed, 2 Jul 2014 11:32:43 -0500 Subject: [PATCH 048/698] Some review changes to set.py. --- src/sage/sets/set.py | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/sage/sets/set.py b/src/sage/sets/set.py index b412ec81f9b..ce18854de0b 100644 --- a/src/sage/sets/set.py +++ b/src/sage/sets/set.py @@ -15,7 +15,8 @@ - Nicolas M. Thiery (2011-03-15) - Added subset and superset methods -- Julian Rueth (2013-04-09) - Collected common code in Set_object_binary, fixed __hash__. +- Julian Rueth (2013-04-09) - Collected common code in + :class:`Set_object_binary`, fixed ``__hash__``. """ @@ -990,10 +991,11 @@ def symmetric_difference(self, other): return Set_object_enumerated(self.set().symmetric_difference(other.set())) class Set_object_binary(Set_object): - """ - An abstract common base class for :class:`Set_object_union`, - :class:`Set_object_intersection`, :class:`Set_object_difference`, and - :class:`Set_object_symmetric_difference`. + r""" + An abstract common base class for sets defined by a binary operators (ex. + :class:`Set_object_union`, :class:`Set_object_intersection`, + :class:`Set_object_difference`, and + :class:`Set_object_symmetric_difference`). INPUT: @@ -1008,23 +1010,22 @@ class Set_object_binary(Set_object): sage: X = Set(QQ^2) sage: Y = Set(ZZ) sage: from sage.sets.set import Set_object_binary - sage: S = Set_object_binary(X,Y,"union","\\cup"); S - Set-theoretic union of Set of elements of Vector space of dimension 2 over Rational Field and Set of elements of Integer Ring - + sage: S = Set_object_binary(X, Y, "union", "\\cup"); S + Set-theoretic union of Set of elements of Vector space of dimension 2 + over Rational Field and Set of elements of Integer Ring """ def __init__(self, X, Y, op, latex_op): - """ + r""" Initialization. TESTS:: - sage: from sage.sets.set import Set_object_binary - sage: X = Set(QQ^2) - sage: Y = Set(ZZ) - sage: S = Set_object_binary(X,Y,"union","\\cup") - sage: type(S) - - + sage: from sage.sets.set import Set_object_binary + sage: X = Set(QQ^2) + sage: Y = Set(ZZ) + sage: S = Set_object_binary(X, Y, "union", "\\cup") + sage: type(S) + """ self._X = X self._Y = Y @@ -1040,9 +1041,8 @@ def _repr_(self): sage: Set(ZZ).union(Set(GF(5))) Set-theoretic union of Set of elements of Integer Ring and {0, 1, 2, 3, 4} - """ - return "Set-theoretic %s of %s and %s"%(self._op, self._X, self._Y) + return "Set-theoretic {} of {} and {}".format(self._op, self._X, self._Y) def _latex_(self): r""" @@ -1052,9 +1052,8 @@ def _latex_(self): sage: latex(Set(ZZ).union(Set(GF(5)))) \Bold{Z} \cup \left\{0, 1, 2, 3, 4\right\} - """ - return '%s %s %s'%(latex(self._X), self._latex_op, latex(self._Y)) + return latex(self._X) + self._latex_op + latex(self._Y) def cardinality(self): """ @@ -1075,7 +1074,6 @@ def __hash__(self): """ The hash value of this set. - EXAMPLES: The hash values of equal sets are in general not equal since it is not @@ -1094,9 +1092,8 @@ def __hash__(self): sage: T = Set(ZZ).union(Set([infinity])) sage: hash(S) == hash(T) True - """ - return hash((self._X,self._Y,self._op)) + return hash((self._X, self._Y, self._op)) class Set_object_union(Set_object_binary): """ From 05ed0370f6a08b0e181f1f520b7df7ec6312a15c Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Wed, 2 Jul 2014 11:35:09 -0500 Subject: [PATCH 049/698] Fix typo. --- src/sage/sets/set.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/sets/set.py b/src/sage/sets/set.py index ce18854de0b..6451e166af8 100644 --- a/src/sage/sets/set.py +++ b/src/sage/sets/set.py @@ -992,7 +992,7 @@ def symmetric_difference(self, other): class Set_object_binary(Set_object): r""" - An abstract common base class for sets defined by a binary operators (ex. + An abstract common base class for sets defined by a binary operation (ex. :class:`Set_object_union`, :class:`Set_object_intersection`, :class:`Set_object_difference`, and :class:`Set_object_symmetric_difference`). From 93546db866564a80d80df30de48934697e2b0d1d Mon Sep 17 00:00:00 2001 From: Simon King Date: Tue, 22 Jul 2014 13:36:25 +0200 Subject: [PATCH 050/698] Fix subsequence containment test. --- src/sage/misc/bounded_integer_sequences.pyx | 72 +++++++++++++++------ 1 file changed, 53 insertions(+), 19 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index 5cbf1916c1d..fb6a91d3fc1 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -88,7 +88,7 @@ cdef PyObject* zeroNone = ZeroNone cdef dict EmptyDict = {} cdef PyObject* emptyDict = EmptyDict -from cython.operator import dereference as deref, preincrement as preinc +from cython.operator import dereference as deref, preincrement as preinc, predecrement as predec ################### # Boilerplate @@ -271,11 +271,6 @@ cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start): return -1 cdef __mpz_struct seq cdef unsigned int limb_size, limb_size_orig - seq = deref(<__mpz_struct*>S2.data) - limb_size = seq._mp_size+1 - limb_size_orig = seq._mp_size # not "+1", because we only need to do - # something special if we move strictly - # less limbs than fitting into S2. cdef mpz_t tmp # Idea: We shift-copy enough limbs from S1 to tmp and then compare with # S2, for each shift. @@ -305,34 +300,66 @@ cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start): # of _mp_size correctly!!!) it has non-zero bits where S1 has (cut-off) # trailing zeroes, and can thus be no sub-sequence (also not for higher # index). - (<__mpz_struct*>tmp)._mp_size = seq._mp_size + seq = deref(<__mpz_struct*>S2.data) + # The number of limbs required to store data of S2's bitsize (including + # trailing zeroes) + limb_size = (S2.bitsize>>times_mp_bits_per_limb)+1 + # Size of S2 without trailing zeroes: + limb_size_orig = seq._mp_size + seq = deref(<__mpz_struct*>S1.data) cdef unsigned int n, limb_index, bit_index + # The maximal number of limbs of S1 that is safe to use after the current + # position. + cdef unsigned int max_limb_size = seq._mp_size-((start*S1.itembitsize)>>times_mp_bits_per_limb) + if ((start*S1.itembitsize)&mod_mp_bits_per_limb)==0: + # We increase it, since in the loop it is decreased when the index is + # zero modulo bits per limb + preinc(max_limb_size) n = 0 cdef int index = 0 + # tmp may have trailing zeroes, and GMP can NOT cope with that! + # Hence, we need to adjust the size later. + (<__mpz_struct*>tmp)._mp_size = limb_size for index from 0<=index<=S1.length-S2.length: limb_index = n>>times_mp_bits_per_limb # Adjust the number of limbs we are shifting - limb_size = min(limb_size, seq._mp_size-limb_index) bit_index = n&mod_mp_bits_per_limb if bit_index: - mpn_rshift((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, limb_size, bit_index) + if limb_size < max_limb_size: + mpn_rshift((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, limb_size+1, bit_index) + else: + (<__mpz_struct*>tmp)._mp_size = max_limb_size + mpn_rshift((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, max_limb_size, bit_index) else: - mpn_copyi((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, limb_size) - # If limb_size is now smaller than limb_size_orig, then we were + # The bit_index is zero, and hence one limb less is remaining. We + # thus decrement max_limb_size. + if limb_size < predec(max_limb_size): + mpn_copyi((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, limb_size) + else: + (<__mpz_struct*>tmp)._mp_size = max_limb_size + mpn_copyi((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, max_limb_size) + # Now, the first min(limb_size,max_limb_size) limbs of tmp are + # guaranteed to be valid. The rest may be junk. + + # If the number of valid limbs of tmp is smaller than limb_size_orig + # (this can only happen if max_limb_size became small), then we were # running into trailing zeroes of S1. Hence, as explained above, we # can decide now whether S2 is a sub-sequence of S1 in the case that # the non-cutoff bits match. - if limb_sizetmp)._mp_d, (<__mpz_struct*>(S2.data))._mp_d, limb_size)==0: + if max_limb_sizetmp)._mp_d, (<__mpz_struct*>(S2.data))._mp_d, max_limb_size)==0: mpz_clear(tmp) - if (<__mpz_struct*>(S2.data))._mp_size > limb_size: + if limb_size_orig > max_limb_size: + # S2 has further non-zero entries return -1 + # Both S2 and S1 have enough trailing zeroes + return index + else: + if mpz_congruent_2exp_p(S2.data, tmp, S2.bitsize): + mpz_clear(tmp) return index - elif mpz_congruent_2exp_p(tmp, S2.data, S2.bitsize): - mpz_clear(tmp) - return index n += S1.itembitsize mpz_clear(tmp) return -1 @@ -1141,7 +1168,7 @@ cdef class BoundedIntegerSequence: TESTS: - The discussion at :trac:`15820` explains why the following is a good test:: + The discussion at :trac:`15820` explains why the following are good tests:: sage: X = BoundedIntegerSequence(21, [4,1,6,2,7,2,3]) sage: S = BoundedIntegerSequence(21, [0,0,0,0,0,0,0]) @@ -1158,6 +1185,13 @@ cdef class BoundedIntegerSequence: sage: T[3::2] in (X+S) False + :: + + sage: S1 = BoundedIntegerSequence(3,[1,3]) + sage: S2 = BoundedIntegerSequence(3,[0]) + sage: S2 in S1 + False + """ if not isinstance(other, BoundedIntegerSequence): return index_biseq(self.data, other, 0)>=0 From 7b1807808cb638a2f064b78a71ad01f74303bddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 27 Jul 2014 10:05:10 +0200 Subject: [PATCH 051/698] trac #16399 first naive try --- src/sage/matrix/matrix_integer_dense.pyx | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx index 2cec8c7f833..e076db65fb0 100644 --- a/src/sage/matrix/matrix_integer_dense.pyx +++ b/src/sage/matrix/matrix_integer_dense.pyx @@ -4388,12 +4388,15 @@ cdef class Matrix_integer_dense(matrix_dense.Matrix_dense): # dense or sparse return res - ##################################################################################### + ################################################################# # operations with matrices - ##################################################################################### + ################################################################# def stack(self, bottom, subdivide=False): r""" - Return the matrix self on top of bottom: [ self ] [ bottom ] + Return the matrix ``self`` on top of ``bottom``: + + [ self ] + [ bottom ] EXAMPLES:: @@ -4451,8 +4454,18 @@ cdef class Matrix_integer_dense(matrix_dense.Matrix_dense): # dense or sparse bottom = bottom.row() if self._ncols != bottom.ncols(): raise TypeError("number of columns must be the same") - if not (self._base_ring is bottom.base_ring()): - bottom = bottom.change_ring(self._base_ring) + top_ring = self._base_ring + bottom_ring = bottom.base_ring() + if not (top_ring is bottom_ring): + if top_ring_has_coerce_map_from(bottom_ring): + bottom = bottom.change_ring(top_ring) + elif bottom_ring_has_coerce_map_from(top_ring): + new_top = self.change_ring(bottom_ring) + return new_top.stack(bottom, subdivide=subdivide): + else: + # what to do ? + # how to find a common parent ? + raise TypeError('damn') cdef Matrix_integer_dense other = bottom.dense_matrix() cdef Matrix_integer_dense M M = self.new_matrix(nrows = self._nrows + other._nrows, ncols = self.ncols()) From 098d574aa98441e4067178a4b8913c88ebc0f6b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 27 Jul 2014 10:20:02 +0200 Subject: [PATCH 052/698] trac #16399 now for sparse matrices --- src/sage/matrix/matrix_sparse.pyx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/sage/matrix/matrix_sparse.pyx b/src/sage/matrix/matrix_sparse.pyx index d30923e8caa..40d04337017 100644 --- a/src/sage/matrix/matrix_sparse.pyx +++ b/src/sage/matrix/matrix_sparse.pyx @@ -905,8 +905,17 @@ cdef class Matrix_sparse(matrix.Matrix): if self._ncols != other._ncols: raise TypeError, "number of columns must be the same" - if not (self._base_ring is other.base_ring()): - other = other.change_ring(self._base_ring) + top_ring = self._base_ring + bottom_ring = other.base_ring() + if not (top_ring is bottom_ring): + if top_ring_has_coerce_map_from(bottom_ring): + other = other.change_ring(top_ring) + elif bottom_ring_has_coerce_map_from(top_ring): + self = self.change_ring(bottom_ring) # allowed ? + else: + # what to do ? + # how to find a common parent ? + raise TypeError('damn') cdef Matrix_sparse Z Z = self.new_matrix(nrows = self._nrows + other.nrows()) From bee1968a7bfc534ac1ce216562b8f66df770483e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 30 Jul 2014 16:10:35 +0200 Subject: [PATCH 053/698] trac #16399 trying to use coercion model --- src/sage/matrix/matrix_sparse.pyx | 32 +++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/sage/matrix/matrix_sparse.pyx b/src/sage/matrix/matrix_sparse.pyx index 40d04337017..d4b69da9c7e 100644 --- a/src/sage/matrix/matrix_sparse.pyx +++ b/src/sage/matrix/matrix_sparse.pyx @@ -4,7 +4,7 @@ Base class for sparse matrices cimport matrix cimport matrix0 -from sage.structure.element cimport Element, RingElement, ModuleElement, Vector +from sage.structure.element cimport (Element, RingElement, ModuleElement, Vector, CoercionModel) from sage.rings.ring import is_Ring from sage.misc.misc import verbose @@ -894,16 +894,33 @@ cdef class Matrix_sparse(matrix.Matrix): [-----------] [ 0 1 2 3] [ 4 5 6 7] + + TESTS:: + + One can stack matrices over different rings (:trac:`16399`). :: + + sage: M = Matrix(ZZ, 2, 3, range(6), sparse=True) + sage: N = Matrix(QQ, 1, 3, [10,11,12], sparse=True) + sage: M.stack(N) + [0 1 2 3 4] + [5 6 7 8 9] + [0 1 2 3 4] + sage: N.stack(M) + ? + sage: M2 = Matrix(ZZ['x'], 2, 3, range(6), sparse=True) + sage: N.stack(M2) + ? """ if hasattr(bottom, '_vector_'): bottom = bottom.row() if not isinstance(bottom, matrix.Matrix): - raise TypeError, "other must be a matrix" + raise TypeError("other must be a matrix") cdef Matrix_sparse other = bottom.sparse_matrix() + cdef CoercionModel coercion_model if self._ncols != other._ncols: - raise TypeError, "number of columns must be the same" + raise TypeError("number of columns must be the same") top_ring = self._base_ring bottom_ring = other.base_ring() @@ -913,9 +930,12 @@ cdef class Matrix_sparse(matrix.Matrix): elif bottom_ring_has_coerce_map_from(top_ring): self = self.change_ring(bottom_ring) # allowed ? else: - # what to do ? - # how to find a common parent ? - raise TypeError('damn') + from sage.structure.element import get_coercion_model + coercion_model = get_coercion_model() + com_ring = coercion_model.common_parent(top_ring, bottom_ring) + self = self.change_ring(com_ring) # allowed ? + other = other.change_ring(com_ring) + cdef Matrix_sparse Z Z = self.new_matrix(nrows = self._nrows + other.nrows()) From 9986c476c78510e1b98d46890a5b9506f3b62613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 30 Jul 2014 16:18:12 +0200 Subject: [PATCH 054/698] trac #16399 fixing some obvious errors. --- src/sage/matrix/matrix_integer_dense.pyx | 31 +++++++++++++++++++----- src/sage/matrix/matrix_sparse.pyx | 4 +-- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx index e076db65fb0..84998580f84 100644 --- a/src/sage/matrix/matrix_integer_dense.pyx +++ b/src/sage/matrix/matrix_integer_dense.pyx @@ -93,7 +93,7 @@ from sage.rings.integer_ring import ZZ, IntegerRing_class from sage.rings.integer_ring cimport IntegerRing_class from sage.rings.finite_rings.integer_mod_ring import IntegerModRing from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.structure.element cimport ModuleElement, RingElement, Element, Vector +from sage.structure.element cimport (ModuleElement, RingElement, Element, Vector, CoercionModel) from sage.structure.element import is_Vector from sage.structure.sequence import Sequence @@ -4449,23 +4449,42 @@ cdef class Matrix_integer_dense(matrix_dense.Matrix_dense): # dense or sparse [ 0 0 12] sage: P.is_sparse() False + + One can stack matrices over different rings (:trac:`16399`). :: + + sage: M = Matrix(ZZ, 2, 3, range(6)) + sage: N = Matrix(QQ, 1, 3, [10,11,12]) + sage: M.stack(N) + [0 1 2 3 4] + [5 6 7 8 9] + [0 1 2 3 4] + sage: N.stack(M) + ? + sage: M2 = Matrix(ZZ['x'], 2, 3, range(6)) + sage: N.stack(M2) + ? """ if hasattr(bottom, '_vector_'): bottom = bottom.row() if self._ncols != bottom.ncols(): raise TypeError("number of columns must be the same") + cdef CoercionModel coercion_model + top_ring = self._base_ring bottom_ring = bottom.base_ring() if not (top_ring is bottom_ring): - if top_ring_has_coerce_map_from(bottom_ring): + if top_ring.has_coerce_map_from(bottom_ring): bottom = bottom.change_ring(top_ring) - elif bottom_ring_has_coerce_map_from(top_ring): + elif bottom_ring.has_coerce_map_from(top_ring): new_top = self.change_ring(bottom_ring) return new_top.stack(bottom, subdivide=subdivide): else: - # what to do ? - # how to find a common parent ? - raise TypeError('damn') + from sage.structure.element import get_coercion_model + coercion_model = get_coercion_model() + com_ring = coercion_model.common_parent(top_ring, bottom_ring) + self = self.change_ring(com_ring) # allowed ? + bottom = other.change_ring(com_ring) + cdef Matrix_integer_dense other = bottom.dense_matrix() cdef Matrix_integer_dense M M = self.new_matrix(nrows = self._nrows + other._nrows, ncols = self.ncols()) diff --git a/src/sage/matrix/matrix_sparse.pyx b/src/sage/matrix/matrix_sparse.pyx index d4b69da9c7e..ed5ee0747a6 100644 --- a/src/sage/matrix/matrix_sparse.pyx +++ b/src/sage/matrix/matrix_sparse.pyx @@ -925,9 +925,9 @@ cdef class Matrix_sparse(matrix.Matrix): top_ring = self._base_ring bottom_ring = other.base_ring() if not (top_ring is bottom_ring): - if top_ring_has_coerce_map_from(bottom_ring): + if top_ring.has_coerce_map_from(bottom_ring): other = other.change_ring(top_ring) - elif bottom_ring_has_coerce_map_from(top_ring): + elif bottom_ring.has_coerce_map_from(top_ring): self = self.change_ring(bottom_ring) # allowed ? else: from sage.structure.element import get_coercion_model From dfc59bf1dd299aff360ff9d1e6171639c29f3947 Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Wed, 6 Aug 2014 10:56:52 +0200 Subject: [PATCH 055/698] trac #16770: fixed type of falling_factorial with zero factors --- src/sage/rings/arith.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/arith.py b/src/sage/rings/arith.py index 004690b649f..8f693cbf6bb 100644 --- a/src/sage/rings/arith.py +++ b/src/sage/rings/arith.py @@ -4757,11 +4757,19 @@ def falling_factorial(x, a): sage: falling_factorial(x, 4) x^4 - 6*x^3 + 11*x^2 - 6*x + TESTS: + Check that :trac:`14858` is fixed:: sage: falling_factorial(-4, SR(2)) 20 + Check that :trac:`16770` is fixed:: + + sage: d = var('d') + sage: type(falling_factorial(d, 0)) + + AUTHORS: - Jaap Spies (2006-03-05) @@ -4769,7 +4777,7 @@ def falling_factorial(x, a): if (isinstance(a, (integer.Integer, int, long)) or (isinstance(a, sage.symbolic.expression.Expression) and a.is_integer())) and a >= 0: - return misc.prod([(x - i) for i in range(a)]) + return misc.prod([(x - i) for i in range(a)], z=x.parent()(1)) from sage.functions.all import gamma return gamma(x+1) / gamma(x-a+1) @@ -4835,6 +4843,8 @@ def rising_factorial(x, a): sage: rising_factorial(x, 4) x^4 + 6*x^3 + 11*x^2 + 6*x + TESTS: + Check that :trac:`14858` is fixed:: sage: bool(rising_factorial(-4, 2) == @@ -4842,6 +4852,12 @@ def rising_factorial(x, a): ....: rising_factorial(SR(-4), SR(2))) True + Check that :trac:`16770` is fixed:: + + sage: d = var('d') + sage: type(rising_factorial(d, 0)) + + AUTHORS: - Jaap Spies (2006-03-05) @@ -4849,7 +4865,7 @@ def rising_factorial(x, a): if (isinstance(a, (integer.Integer, int, long)) or (isinstance(a, sage.symbolic.expression.Expression) and a.is_integer())) and a >= 0: - return misc.prod([(x + i) for i in range(a)]) + return misc.prod([(x + i) for i in range(a)], z=x.parent()(1)) from sage.functions.all import gamma return gamma(x+a) / gamma(x) From 95319371cc13f9512521043bfe53cfe806df244e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 20 Aug 2014 11:31:34 +0200 Subject: [PATCH 056/698] trac #10779 correct failing doctest + more doc changes --- src/sage/structure/element.pyx | 142 ++++++++++++++++----------------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index 0fbece59d06..c66a922b608 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -109,12 +109,12 @@ and classes are similar. There are four relevant functions. This is the function you should override to implement addition in a python subclass of RingElement. - .. warning:: + .. WARNING:: - if you override this in a *Cython* class, it won't get called. - You should override _add_ instead. It is especially important to - keep this in mind whenever you move a class down from Python to - Cython. + if you override this in a *Cython* class, it won't get called. + You should override _add_ instead. It is especially important to + keep this in mind whenever you move a class down from Python to + Cython. The two arguments to this function are guaranteed to have the SAME PARENT. Its return value MUST have the SAME PARENT as its @@ -282,11 +282,11 @@ cdef class Element(sage_object.SageObject): and ``cat.element_class``, in that order, for attribute lookup. - NOTE: + .. NOTE:: - Attributes beginning with two underscores but not ending with - an unnderscore are considered private and are thus exempted - from the lookup in ``cat.element_class``. + Attributes beginning with two underscores but not ending + with an underscore are considered private and are thus + exempted from the lookup in ``cat.element_class``. EXAMPLES: @@ -369,7 +369,7 @@ cdef class Element(sage_object.SageObject): def __getstate__(self): """ - Returns a tuple describing the state of your object. + Return a tuple describing the state of your object. This should return all information that will be required to unpickle the object. The functionality for unpickling is implemented in @@ -406,7 +406,7 @@ cdef class Element(sage_object.SageObject): def __copy__(self): """ - Returns a copy of ``self``. + Return a copy of ``self``. OUTPUT: @@ -474,7 +474,7 @@ cdef class Element(sage_object.SageObject): def base_ring(self): """ - Returns the base ring of this element's parent (if that makes sense). + Return the base ring of this element's parent (if that makes sense). TESTS:: @@ -504,8 +504,8 @@ cdef class Element(sage_object.SageObject): sage: from sage.categories.examples.sets_cat import PrimeNumbers sage: class CCls(PrimeNumbers): - ... def an_element(self): - ... return 18 + ....: def an_element(self): + ....: return 18 sage: CC = CCls() sage: CC._test_an_element() Traceback (most recent call last): @@ -541,8 +541,8 @@ cdef class Element(sage_object.SageObject): Let us now write a broken class method:: sage: class CCls(Element): - ... def __eq__(self, other): - ... return True + ....: def __eq__(self, other): + ....: return True sage: CCls(Parent())._test_eq() Traceback (most recent call last): ... @@ -551,8 +551,8 @@ cdef class Element(sage_object.SageObject): Let us now break inequality:: sage: class CCls(Element): - ... def __ne__(self, other): - ... return True + ....: def __ne__(self, other): + ....: return True sage: CCls(Parent())._test_eq() Traceback (most recent call last): ... @@ -573,7 +573,7 @@ cdef class Element(sage_object.SageObject): def parent(self, x=None): """ - Returns parent of this element; or, if the optional argument x is + Return the parent of this element; or, if the optional argument x is supplied, the result of coercing x into the parent of this element. """ if x is None: @@ -672,9 +672,9 @@ cdef class Element(sage_object.SageObject): Evaluates numerically and returns an mpmath number. Used as fallback for conversion by mpmath.mpmathify(). - .. note:: + .. NOTE:: - Currently, the rounding mode is ignored. + Currently, the rounding mode is ignored. EXAMPLES:: @@ -813,13 +813,15 @@ cdef class Element(sage_object.SageObject): def is_zero(self): """ - Return ``True`` if ``self`` equals self.parent()(0). The default - implementation is to fall back to 'not self.__nonzero__'. + Return ``True`` if ``self`` equals self.parent()(0). - .. warning:: + The default implementation is to fall back to 'not + self.__nonzero__'. - Do not re-implement this method in your subclass but - implement __nonzero__ instead. + .. WARNING:: + + Do not re-implement this method in your subclass but + implement __nonzero__ instead. """ return not self @@ -1151,10 +1153,11 @@ cdef class ElementWithCachedMethod(Element): This getattr method ensures that cached methods and lazy attributes can be inherited from the element class of a category. - NOTE: + .. NOTE:: - The use of cached methods is demonstrated in the main doc string of - this class. Here, we demonstrate lazy attributes. + The use of cached methods is demonstrated in the main doc + string of this class. Here, we demonstrate lazy + attributes. EXAMPLE:: @@ -1868,14 +1871,14 @@ cdef class RingElement(ModuleElement): def additive_order(self): """ - Return the additive order of self. + Return the additive order of ``self``. """ raise NotImplementedError def multiplicative_order(self): r""" - Return the multiplicative order of self, if ``self`` is a unit, or raise - ``ArithmeticError`` otherwise. + Return the multiplicative order of ``self``, if ``self`` is a unit, + or raise ``ArithmeticError`` otherwise. """ if not self.is_unit(): raise ArithmeticError("self (=%s) must be a unit to have a multiplicative order.") @@ -1883,22 +1886,22 @@ cdef class RingElement(ModuleElement): def is_nilpotent(self): """ - Return ``True`` if ``self`` is nilpotent, i.e., some power of self + Return ``True`` if ``self`` is nilpotent, i.e., some power of ``self`` is 0. TESTS:: - sage: a=QQ(2) + sage: a = QQ(2) sage: a.is_nilpotent() False - sage: a=QQ(0) + sage: a = QQ(0) sage: a.is_nilpotent() True - sage: m=matrix(RR,3,[[3,2,3],[9,0,3],[-9,0,-3]]) + sage: m = matrix(QQ,3,[[3,2,3],[9,0,3],[-9,0,-3]]) sage: m.is_nilpotent() Traceback (most recent call last): ... - NotImplementedError + AttributeError: ... object has no attribute 'is_nilpotent' """ if self.is_unit(): return False @@ -2090,15 +2093,15 @@ cdef class CommutativeRingElement(RingElement): sage: f.mod(x + 1) -1 - When little is implemented about a given ring, then mod may - return simply return `f`. For example, reduction is not - implemented for `\ZZ[x]` yet. (TODO!) + Reduction for `\ZZ[x]`:: sage: R. = PolynomialRing(ZZ) sage: f = x^3 + x + 1 sage: f.mod(x + 1) -1 + When little is implemented about a given ring, then mod may + return simply return `f`. EXAMPLE: Multivariate polynomials We reduce a polynomial in two variables modulo a polynomial @@ -2135,25 +2138,22 @@ cdef class CommutativeRingElement(RingElement): def is_square(self, root=False): """ - Returns whether or not ring element is a square. If the optional - argument root is ``True``, then also returns the square root (or None, - if the it is not a square). - - INPUT: + Return whether or not the ring element ``self`` is a square. + If the optional argument root is ``True``, then also return + the square root (or ``None``, if it is not a square). - - ``root`` - whether or not to also return a square - root (default: False) + INPUT: + - ``root`` - whether or not to also return a square + root (default: ``False``) OUTPUT: + - ``bool`` -- whether or not a square - - ``bool`` - whether or not a square - - - ``object`` - (optional) an actual square root if - found, and None otherwise. - + - ``object`` -- (optional) an actual square root if + found, and ``None`` otherwise. EXAMPLES:: @@ -2169,17 +2169,17 @@ cdef class CommutativeRingElement(RingElement): sage: h.is_square(root=True) (True, 2*x^2 + 8*x + 6) - .. NOTE: + .. NOTE:: - This is the is_square implementation for general commutative ring - elements. It's implementation is to raise a NotImplementedError. - The function definition is here to show what functionality is expected and - provide a general framework. + This is the is_square implementation for general + commutative ring elements. It's implementation is to raise + a NotImplementedError. The function definition is here to + show what functionality is expected and provide a general + framework. """ - raise NotImplementedError("is_square() not implemented for elements of %s" %self.parent()) + raise NotImplementedError("is_square() not implemented for elements of %s" % self.parent()) - - def sqrt(self, extend = True, all = False, name=None ): + def sqrt(self, extend=True, all=False, name=None): """ It computes the square root. @@ -2329,10 +2329,10 @@ cdef class Vector(ModuleElement): - Gonzalo Tornaria (2007-06-21) - write test cases and fix them - .. note:: + .. NOTE:: - scalar * vector is implemented (and tested) in class RingElement - matrix * vector is implemented (and tested) in class Matrix + scalar * vector is implemented (and tested) in class RingElement + matrix * vector is implemented (and tested) in class Matrix TESTS: @@ -2576,10 +2576,10 @@ cdef class Matrix(ModuleElement): - Gonzalo Tornaria (2007-06-25) - write test cases and fix them - .. note:: + .. NOTE:: - scalar * matrix is implemented (and tested) in class RingElement - vector * matrix is implemented (and tested) in class Vector + scalar * matrix is implemented (and tested) in class RingElement + vector * matrix is implemented (and tested) in class Vector TESTS: @@ -2817,7 +2817,7 @@ def is_PrincipalIdealDomainElement(x): cdef class PrincipalIdealDomainElement(DedekindDomainElement): def lcm(self, right): """ - Returns the least common multiple of ``self`` and right. + Return the least common multiple of ``self`` and right. """ if not PY_TYPE_CHECK(right, Element) or not ((right)._parent is self._parent): return coercion_model.bin_op(self, right, lcm) @@ -2900,7 +2900,7 @@ cdef class FieldElement(CommutativeRingElement): return self / other def is_unit(self): - """ + r""" Return ``True`` if ``self`` is a unit in its parent ring. EXAMPLES:: @@ -2908,7 +2908,7 @@ cdef class FieldElement(CommutativeRingElement): sage: a = 2/3; a.is_unit() True - On the other hand, 2 is not a unit, since its parent is ZZ. + On the other hand, 2 is not a unit, since its parent is `\ZZ`. :: @@ -3288,7 +3288,7 @@ cdef class NamedBinopMethod: def _sage_src_(self): """ - Returns the source of the wrapped object for introspection. + Return the source of the wrapped object for introspection. EXAMPLES:: @@ -3301,7 +3301,7 @@ cdef class NamedBinopMethod: def _sage_argspec_(self): """ - Returns the argspec of the wrapped object for introspection. + Return the argspec of the wrapped object for introspection. EXAMPLES:: From 839e0bfb78fa8a06e7ef064f531376a873067d30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Tue, 26 Aug 2014 01:19:04 +0200 Subject: [PATCH 057/698] Trac #9927: set character of BrandtModule to trivial This is needed so that direct computation of hecke ops for non-squarefree level works, as the inherited methods from AmbientHeckeModule need to know the character. --- src/sage/modular/quatalg/brandt.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/sage/modular/quatalg/brandt.py b/src/sage/modular/quatalg/brandt.py index 1c47fc24b15..45b43c1da0d 100644 --- a/src/sage/modular/quatalg/brandt.py +++ b/src/sage/modular/quatalg/brandt.py @@ -226,6 +226,7 @@ class if `I=aJ` for some `a \in A^*`. (Left `\mathcal{O}`-ideals are from sage.rings.arith import gcd, factor, kronecker_symbol from sage.modular.hecke.all import (AmbientHeckeModule, HeckeSubmodule, HeckeModuleElement) +from sage.modular.dirichlet import TrivialCharacter from sage.matrix.all import MatrixSpace, matrix from sage.rings.rational_field import is_RationalField from sage.misc.mrange import cartesian_product_iterator @@ -535,6 +536,17 @@ def M(self): """ return self.__M + def character(self): + r""" + The character of this space. Always trivial. + + EXAMPLE:: + + sage: BrandtModule(11,5).character() + Dirichlet character modulo 55 of conductor 1 mapping 12 |--> 1, 46 |--> 1 + """ + return TrivialCharacter(self.__N*self.__M) + def _repr_(self): """ Return string representation of this Brandt module. From c69c67ccf3093a3c947ebbe83d5224daf695c3f9 Mon Sep 17 00:00:00 2001 From: Simon King Date: Tue, 26 Aug 2014 22:25:20 +0200 Subject: [PATCH 058/698] Use a bitmask when slicing bounded integer sequences --- src/sage/misc/bounded_integer_sequences.pyx | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index fb6a91d3fc1..b1e109c5428 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -585,16 +585,16 @@ cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL: if offset_mod_src: if (offset_mod_src+S.itembitsize >= mp_bits_per_limb): mpn_rshift(tmp_limb, seq_src._mp_d+offset_div_src, 2, offset_mod_src) + tmp_limb[0] &= S.mask_item else: - tmp_limb[0] = (seq_src._mp_d[offset_div_src])>>offset_mod_src + tmp_limb[0] = ((seq_src._mp_d[offset_div_src])>>offset_mod_src) & S.mask_item else: - tmp_limb[0] = seq_src._mp_d[offset_div_src] - tmp_limb[0] &= S.mask_item + tmp_limb[0] = seq_src._mp_d[offset_div_src] & S.mask_item elif offset_div_src == max_limb: if offset_mod_src: - tmp_limb[0] = (seq_src._mp_d[offset_div_src])>>offset_mod_src + tmp_limb[0] = ((seq_src._mp_d[offset_div_src])>>offset_mod_src) & S.mask_item else: - tmp_limb[0] = seq_src._mp_d[offset_div_src] + tmp_limb[0] = seq_src._mp_d[offset_div_src] & S.mask_item else: tmp_limb[0] = 0 # put data from tmp_limb[0] to tgt @@ -1090,6 +1090,14 @@ cdef class BoundedIntegerSequence: TESTS:: + sage: S = BoundedIntegerSequence(8, [4,1,6,2,7,2,5,5,2]) + sage: S[-1::-2] + <2, 5, 7, 6, 4> + sage: S[1::2] + <1, 2, 2, 5> + + :: + sage: L = [randint(0,26) for i in range(5000)] sage: S = BoundedIntegerSequence(27, L) sage: S[1234] == L[1234] From dfe42c7f14c430d5aa7b110fe6ab495c07d24ebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Thu, 28 Aug 2014 12:22:17 +0200 Subject: [PATCH 059/698] Trac #16895: fix 'names' parameter for Order.residue_field() --- src/sage/rings/number_field/order.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/number_field/order.py b/src/sage/rings/number_field/order.py index 99fe0158f10..fb3cc82da0f 100644 --- a/src/sage/rings/number_field/order.py +++ b/src/sage/rings/number_field/order.py @@ -683,7 +683,7 @@ def ambient(self): """ return self._K - def residue_field(self, prime, name = None, check = False): + def residue_field(self, prime, names=None, check=False): """ Return the residue field of this order at a given prime, ie `O/pO`. @@ -705,9 +705,12 @@ def residue_field(self, prime, name = None, check = False): sage: OK = K.maximal_order() sage: OK.residue_field(P) Residue field in abar of Fractional ideal (61, a^2 + 30) + sage: Fp. = OK.residue_field(P) + sage: Fp + Residue field in b of Fractional ideal (61, a^2 + 30) """ if self.is_maximal(): - return self.number_field().residue_field(prime, name, check) + return self.number_field().residue_field(prime, names, check) else: raise NotImplementedError("Residue fields of non-maximal orders are not yet supported.") From 77251224787d5140af17a32e7cb3059effe22670 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 28 Aug 2014 12:32:22 +0200 Subject: [PATCH 060/698] Cosmetic changes --- build/pkgs/mpir/SPKG.txt | 346 ---------------------------- build/pkgs/mpir/checksums.ini | 6 +- build/pkgs/mpir/package-version.txt | 2 +- build/pkgs/mpir/spkg-install | 9 +- 4 files changed, 9 insertions(+), 354 deletions(-) diff --git a/build/pkgs/mpir/SPKG.txt b/build/pkgs/mpir/SPKG.txt index fda48fef5b8..47384145420 100644 --- a/build/pkgs/mpir/SPKG.txt +++ b/build/pkgs/mpir/SPKG.txt @@ -27,353 +27,7 @@ See http://www.mpir.org - Perhaps also modify CXXFLAGS (and/or CPPFLAGS). - We currently don't use anything of GMP's/MPIR's CC setting, and matching with the current compiler (`$CC`) is perhaps suboptimal. - * Make sure the patches still apply. * Remove some files / directories not needed for Sage from upstream: rm -rf src/build.vc* # Microsoft Visual C build files rm -rf src/yasm/Mkfiles/{dj,vc*} # DJGPP, Microsoft Visual C (Saves 13 of 40 MB uncompressed.) - -=== Patches === - * gmp-h.in.patch: a trivial patch adding some #includes such that MPIR - would compile on SunOS with Sun CC. The changes in this patch only - take effect if the preprocessor variable `__SUNPRO_CC` is defined. - * quote_asm.patch: replace things of the form "define(OPERATION_foo,1)" by - "define(`OPERATION_foo',1)". This gives proper quoting for use with m4, - otherwise the define might expand to "define(,1)". Some versions of m4 - bail out with an error when encountering "define(,1)". - These files were patched using - find mpn -name '*.asm' -exec sed -i 's/define(\(OPERATION[^,]*\),/define(\`\1'"'"',/' {} \; - * configure-cxx.patch: remove libtool C++ hack to let MPIR build correctly - on Cygwin when C++ support is disabled. - * configure.patch: add some extra run-time configure tests, remove - mentions of Fortran. Re-generated configure (using the same versions - of autoconf, automake and libtool as the original files). - * core-prescott-configure.patch: fix upstream bug breaking support for - core-*-* and prescott-*-*, at least on non-MacOS-X systems. (The bug - results in requiring `ABI=standard` on these platforms, and only using the - generic C implementation when configured that way.) - Patches `configure`, `acinclude.m4` and `configure.in`; to be applied - *after* `patches/configure.patch` (which its name should currently make - sure). Submitted upstream (against MPIR 2.6.0; 26.02.2013). - * clang-config.patch: remove one broken configure test and fix one test - for Clang, see http://trac.sagemath.org/ticket/13948 - * mpz__t-scan-bugfix.patch: fix trivial bug in `tests/mpz/t-scan.c` leading - to a segfault (during the test suite) with newer GCC versions. - Submitted upstream (against MPIR 2.6.0; 02.04.2013). - * apple.patch: make sure 32 bits Apple Darwin use the correct asm directories. - -== Changelog == - -=== mpir-2.6.0.p4 (Jean-Pierre Flori, 6 November 2013) === - * #15364: remove libtool hack for C++ support. - * Taken from upstream commit 2320c7d965e3277fddaf2390fdf7032d34954c8c. - -=== mpir-2.6.0.p3 (Jeroen Demeyer, 2 October 2013) === - * #13948: clang-config.patch: fix configure script for Clang. - -=== mpir-2.6.0.p2 (Leif Leonhardy, April 3rd 2013) === - * #14399: MPIR 2.6.0's test suite fails with GCC 4.8.0 - Rather surprisingly, this bug, now causing a segfault in MPIR's test suite, - apparently never showed up before. - Add patch (`mpz__t-scan-bugfix.patch`) fixing an invalid array access in - the test code. - Patch has been submitted upstream. - -=== mpir-2.6.0.p1 (Leif Leonhardy, February 27th 2013) === - * #14172: MPIR 2.6.0 (but also older versions) fails to configure on Intel - "Core" CPUs (expecting ABI to be "standard" rather than "32", which is - just one symptom). (Similar for Pentium4 Prescott.) - Add patch (`core-prescott-configure.patch`) fixing `acinclude.m4`, - `configure.in`, and the generated `configure`, rebased to the patches we - apply in advance. - Patch(es) have been submitted upstream. - -=== mpir-2.6.0.p0 (Jean-Pierre Flori, 12 January 2013) === - * Trac #13137: Update to MPIR 2.6.0. - * Modify spkg-install to rename *,asm files to *.asm files. - * Remove -Wl,-z,noexecstack fix which has been integrated upstream. - * Remove old code about 32 bits Apple Darwin and use slightly modified upstream fix. - -=== mpir-2.5.2.p0 (John Palmieri, 3 October 2012) === - * Trac #13137: Update to MPIR 2.5.2. - * Remove the patch 'patches/yasm__tools__re2c__code.c.patch'. - * Do not use clang, which fails to compile MPIR, on OS X. - -=== mpir-2.4.0.p7 (Karl-Dieter Crisman, Jean-Pierre Flori, 1 August 2012) === - * Trac #12115: let MPIR build on Cygwin. - * Only build the shared version of the library on Cygwin. - * Export ABI=32 on Cygwin. - -=== mpir-2.4.0.p6 (Jeroen Demeyer, 28 May 2012) === - * Trac #12751: Apply the ia64 workaround for gcc-4.7.0 *only* on - gcc-4.7.0 and not on other gcc-4.7.x versions. - -=== mpir-2.4.0.p5 (Jeroen Demeyer, 27 May 2012) === - * Trac #12970: configure.patch: add some configure tests to check that - certain code compiles and runs. In particular, add a runtime test - for unsigned long/double division. - * Additionally, remove all mentions of Fortran in the configure file. - Supposedly, it was there to work around a libtool bug. - -=== mpir-2.4.0.p4 (Jeroen Demeyer, 26 May 2012) === - * Trac #12954: when SAGE_FAT_BINARY=yes on systems which don't support - --enable-fat, compile a generic binary (not assuming any particular - CPU) by passing the output of configfsf.guess to the --build option - of ./configure. - * Disable SAGE_FAT_BINARY when bootstrapping GCC. - * Rename MPIR_EXTRA_OPTS to MPIR_CONFIGURE. - * Add configure options directly to MPIR_CONFIGURE, no longer use - SAGE_CONF_OPTS for this. - * When user specifies CFLAGS, append them to MPIR's flags instead of - completely replacing MPIR's flags. - * Remove $default_cflags and get_processor_specific_cflags(). - -=== mpir-2.4.0.p3 (Jeroen Demeyer, April 26th, 2012) === - Trac #11616, reviewer fixes: - * When the first configure run (with CFLAGS unset) of MPIR fails, bail - out with an error. I am not aware of any system where MPIR fails - to configure with CFLAGS unset but succeeds with CFLAGS set. - This implies the following simplifications: - - We no longer read CC and CFLAGS from /usr/include/gmp.h or - /usr/local/include/gmp.h - - We no longer try to add -march=native, we simply use MPIR's flags. - * Extract $CC and $CFLAGS from Makefile instead of mpir.h, which is - simpler and more reliable. - * Added `quote_asm.patch` to add proper quoting to the m4 in .asm files. - * Use `patch` to patch gmp-h.in instead of copying the file. - * In get_processor_specific_cflags() in spkg-install, also check for - -mpower* and -mno-power* flags, as MPIR adds -mpower on 32-bit - PowerPC systems. - -=== mpir-2.4.0.p2 (Leif Leonhardy, April 4th, 2012) === - #11616 (upgrading MPIR), further fixes: - * Before enabling `-march=native`, minimalistically check whether the - system's assembler also understands the instructions the compiler emits - with that option. (Work-around for e.g. GCC 4.6.3 on MacOS X 10.x and - Intel Core i7-family CPUs with AVX.) - * Do not unconditionally unset `PYTHON`, since Sage (>=5.0.beta10) no longer - pollutes the environment with its package version variables, which previous- - ly confused yasm's `configure`. - * Fix extraction of `__GMP_CC` and `__GMP_CFLAGS` from `gmp.h`, since MPIR - meanwhile defines these to preprocessor variables (rather than literals). - Also don't use `\+` in `sed` patterns, as this is less portable. - * Work around GCC 4.7.0 bug (compilation error) on Linux ia64 (Itanium) by - almost completely disabling optimization on that platform if GCC 4.7.x - is detected. This doesn't hurt much if we later rebuild MPIR with a (non- - broken) GCC from the new GCC spkg. Cf. #12765. - * Do not build the C++ interface and static libraries when bootstrapping the - GCC spkg, i.e. if `SAGE_BUILD_TOOLCHAIN=yes`. (GMP/MPIR is a prerequisite - for it, and MPIR will later get rebuilt with both enabled, with the newly - built GCC.) Cf. #12782. - * Fix a potential race condition in yasm's build by patching the re2c source. - Cf. #11844. - * Add "`patch` loop" to apply any patches (`*.patch`) located in `patches/`. - Currently only the re2c patch matches that; the prepatched header to support - Sun's C compiler is still copied over (and only on SunOS, although it doesn't - do any harm on other platforms). - * Minor clean-up; e.g. redirect error messages and warnings to `stderr`, - quote parameter to `--libdir`, add some comments and messages, also save - user's setting of `LDFLAGS` and `ABI`. - -=== mpir-2.4.0.p1 (Leif Leonhardy, March 21st, 2012) === - * Upstream upgrade to MPIR 2.4.0 (#11616). - The 2.4.0.p0 spkg isn't in this history, as it was based - on the 2.1.3.p4 spkg, i.e., is "on another branch", - and never got merged into Sage. - * Remove forcing a sequential `make install` again, since - the potential race condition was fixed in MPIR 2.1.4. - * Fix `.hgtags`, which contained duplicate entries, and - was missing others. - -=== mpir-2.1.3.p9 (Simon King, 11 December 2011) === - * #12131: Use --libdir, so that the package works on openSUSE - -=== mpir-2.1.3.p8 (Jeroen Demeyer, 10 December 2011) === - * #12139: Disable parallel "make install". - -=== mpir-2.1.3.p7 (Leif Leonhardy, October 30th, 2011) === - * #11964: Use ABI=mode64 instead of ABI=64 on Linux PPC64. - -=== mpir-2.1.3.p6 (Jeroen Demeyer, October 11th, 2011) === - * #11896: Do not set ABI at all when the compiler does not support - $CFLAG32 nor $CFLAG64 (by default set to '-m32' resp. '-m64'). - -=== mpir-2.1.3.p5 (Leif Leonhardy, October 5th, 2011) === - * #11896: Set ABI=32 on 32-bit (Linux) systems that run on 64-bit - processors since otherwise the build might fail with a bunch of - assembler errors when MPIR selects the wrong (64-bit) ABI. - (Reported upstream, but no response yet.) - -=== mpir-2.1.3.p4 (Leif Leonhardy, July 19th, 2011) === - * #8664: Upgrade Sage's MPIR spkg to version 2.1.3 - * Do not delete old GMP/MPIR shared libraries as Sage's versions of libraries - used by GCC might still refer to them, such that their deletion would break - GCC inside Sage. (PPL e.g. refers to libgmpxx; MPFR and MPC are equally - dangerous, since they're [also] used by recent versions of GCC.) - * Some more messages (e.g on rebuilding the Sage library and other packages - after installation) and comments added. - * "Patches" section added. - * Also refreshed the patched gmp-h.in for SunOS. ;-) - -=== mpir-2.1.3.p3 (Leif Leonhardy, July 18th, 2011) === - * #8664: Upgrade Sage's MPIR spkg to version 2.1.3 - * Support MacOS 10.7 (Darwin 11) and later. - * Add warning if SAGE_DEBUG=yes since we then disable optimization. - -=== mpir-2.1.3.p2 (Leif Leonhardy, November 24th, 2010) === - * #8664: Upgrade Sage's MPIR spkg to version 2.1.3 - * Further improvements: - - Let MPIR select CPU-specific code generation parameters (for CFLAGS) even - if we (also) pass our own (or user-specified) CC and CFLAGS; these might - be used by MPFR and GMP-ECM later, too, since MPIR's settings are recorded - in 'gmp.h' / 'mpir.h'. - Don't override user-settings (and respect SAGE_FAT_BINARY, SAGE_DEBUG - etc.) though. Add '-march-native' if appropriate and supported. - * Recognize also lower-case 'power*' arch (from 'uname -m'). - * Major restructuring / reformatting; more comments and messages added. - -=== mpir-2.1.3.p1 (Leif Leonhardy, November 5th, 2010) === - * #8664: Upgrade Sage's MPIR spkg to version 2.1.3 - * Fix Darwin assembler errors on PPC by passing the option to allow - use of extended instruction set to it. (See also #5847.) - * Enable the build of a static MPIR library, to be e.g. used by ECM. - * Support additional 'configure' options given by MPIR_EXTRA_OPTS, - and print messages how we configure. - * Print various environment variable settings (CC, CFLAGS et al.). - * Move hint to rerun 'make' on *install* errors to correct place. - * Further comments added. - -=== mpir-2.1.3.p0 (Leif Leonhardy, November 3rd, 2010) === - * #8664: Upgrade Sage's MPIR spkg to version 2.1.3 - * Dependencies corrected (might be even more, depending on the configuration). - * Work around executable stack issue on Fedora 14 (and other SELinux- - enabled systems). - * If 'make install' fails, this might be due to a rare race condition; - give a hint that rerunning 'make' might be sufficient. - * Support SAGE_DEBUG (disabling optimzation), but add debug symbols by - default and enable optimization (-O3) if SAGE_DEBUG!="yes". - * spkg-install clean-up: - - Use $UNAME instead of `uname`. - - Support "fat" binaries on Linux i486 and i586 as well, - give warning if not supported (e.g. ia64 [?]). - - Remove dead code; more or less cosmetic changes. - * spkg-check: - - Use $MAKE instead of 'make'. - - Print messages on success and error. - -=== mpir-1.2.2.p2 (Volker Braun, Oct 28, 2010) === - * Clear the execstack (executable stack) flag from the shared libraries. - NOTE: Obsoleted by the 2.1.3 spkg(s), not in the Mercurial repository. - -=== mpir-2.1.1 (Mike Hansen, August 16th, 2010) === - * #8664: Upgrade Sage's MPIR spkg to version 2.1.1 - -=== mpir-1.2.2.p1 (Georg S. Weber, May 18th 2010) === - * Update the License information (e.g. above), as kindly requested - on the MPIR project homepage (see "http://www.mpir.org/past.html"): - "... Note MPIR 1.2.2 is overall LGPL v3+ due to us accidentally including - an LGPL v3 file (mpf/set_str.c). Please distribute this version of the - library under the terms of this license! ..." - (According to "http://trac.mpir.org/mpir_trac/ticket/71", this LGPL v3 file - stems from (patches for) GMP 4.2.4 in the year 2008.) - Also copied two new files "gpl-3.0.txt" and "lgpl-3.0.txt" under src/, taken - from the updated mpir-1.2.2 "vanilla" tarball downloaded under the link: - http://www.mpir.org/mpir-1.2.2.tar.gz - According to private communication with Bill Hart (MPIR upstream), this - addition of two files was the only change done to the tarball itself. - -=== mpir-1.2.2.p0 (David Kirkby, January 5th 2010) === - * 7849. Included two header files so MPIR builds with Sun - studio if configured with --enable-cxx and the newer - Sun C++ library is used (library=stlport4). This is between - #ifdefine __SUNPRO_CC and #endif, so will have no effect - except if Sun Studio is used. - -=== mpir-1.2.2 (William Stein, Nov 18, 2009) === - * Upgraded to MPIR-1.2.2. - -=== mpir-1.2.p9 (William Stein, Nov 12, 2009) === - * Also enable --enable-fat for i686. - -=== mpir-1.2.p8 (William Stein, Nov 10, 2009) === - * Put ABI=32 back except on OS X 10.6 (all versions) - -=== mpir-1.2.p6 (William Stein, Sept 25, 2009) === - * Put ABI=32 back except on OS X 10.6 - -=== mpir-1.2.p5 (William Stein, Sept 24, 2009) === - * Remove explicit ABI=32 for OS X; instead let the OS decide. This is needed - for 10.6 where the default is 64-bit instead of 32-bit. - -=== mpir-1.2.p3 (Nick Alexander, June 9, 2009) === - * Update to latest MPIR 1.2 final release. - -=== mpir-1.2.p2 (William Stein, June 4, 2009) === - * Update to latest MPIR 1.2 pre-release - -=== mpir-1.2.p1 (William Stein, June 2, 2009) === - * Update to latest MPIR 1.2 pre-release - -=== mpir-1.2.p0 (William Stein, May 31, 2009) === - * add support for SAGE_FAT_BINARY flag - -=== mpir-1.2 (William Stein, May 31, 2009) === - * Update to the latest MPIR 1.2 pre-release - * Change "GMP" --> "MPIR" in various places. - -=== gmp-mpir-1.1.2 (William Stein, May 28, 2009) === - * Update to the latest MPIR 1.1.2 release - -=== gmp-mpir-1.1.1 (Michael Abshoff, April 29th, 2009) === - * Update to the latest MPIR 1.1.1 release - -=== gmp-mpir-1.1 (Michael Abshoff, April 17th, 2009) === - * Update to the latest MPIR 1.1 release - -=== gmp-mpir-1.0.rc8 (Michael Abshoff, April 10th, 2009) === - * Update to the latest MPIR 1.0 release candidate - * fix --enable-gmplink flag that was changed - * remove 1.0.rc7 non-Darwin workaround that was fixed in 1.0.rc8 - -=== gmp-mpir-1.0.rc7 (Michael Abshoff, April 5th, 2009) === - * Update to the latest MPIR 1.0 release candidate - -=== gmp-mpir-1.0.rc4 (Michael Abshoff, April 1st, 2009) === - * Update to the latest MPIR 1.0 release candidate - * remove some 1.0.rc4 workaround again since it was fixed upstream - -=== gmp-mpir-1.0.rc4 (Michael Abshoff, April 1st, 2009) - * Update to the latest MPIR 1.0 release candidate - * turn on the gmp link option - -=== gmp-mpir-0.9 (Michael Abshoff, February 20th, 2009) === - * 0.9.rc4 become the official 0.9 release - * delete more OSX MacIntel specific assembly faile due to PIC issue (#5315) - -=== gmp-mpir-0.9.rc4 (Michael Abshoff, February 10th, 2009) === - * update to latest upstream 0.9.rc4 release (fixes #5210) - -=== gmp-mpir-0.9.rc3 (Michael Abshoff, February 7th, 2009) === - * update to latest upstream 0.9.rc3 release - * clean out no longer used patches from the patches directory - * turn on test suite per default - * fix some typos and small bugs in spkg-install - -=== gmp-mpir-svn1555.p0 (Michael Abshoff, January 19th, 2008) === - * unset PYTHON since it confuses yasm during configure time - -=== gmp-mpir-svn1555 (Michael Abshoff, January 19th, 2008) === - * Switch to MPIR - -=== gmp-4.2.1.p13 (Michael Abshoff, March 28th, 2008) === - * Fix OSX 10.5 detection code to handle 10.5.2 and higher (#2672) - * Make sure SAGE_ROOT is defined (#633) - * clean spkg-check - -=== gmp-4.2.1.p12 and previous === - -Work by - * William Stein - * Joe Weening - * David Harvey - * Wilson Cheung diff --git a/build/pkgs/mpir/checksums.ini b/build/pkgs/mpir/checksums.ini index 173e594f5a3..a757f978179 100644 --- a/build/pkgs/mpir/checksums.ini +++ b/build/pkgs/mpir/checksums.ini @@ -1,4 +1,4 @@ tarball=mpir-VERSION.tar.bz2 -sha1=e677ffb80ef7a04d99c017fcc365cff2a212b7aa -md5=f606b224589aee316d9f902b8973bf68 -cksum=3791195729 +sha1=815fee928c9ba5f444457144dd037300cb8f4ca4 +md5=c57ab6a7dbf59a32b7feb714ccc068f4 +cksum=3594042083 diff --git a/build/pkgs/mpir/package-version.txt b/build/pkgs/mpir/package-version.txt index 3e703e0948f..24ba9a38de6 100644 --- a/build/pkgs/mpir/package-version.txt +++ b/build/pkgs/mpir/package-version.txt @@ -1 +1 @@ -2.7.0.alpha4 +2.7.0 diff --git a/build/pkgs/mpir/spkg-install b/build/pkgs/mpir/spkg-install index 6157f605992..853e06a681b 100755 --- a/build/pkgs/mpir/spkg-install +++ b/build/pkgs/mpir/spkg-install @@ -233,11 +233,10 @@ fi # Pre-configure MPIR to get the settings it would use if CFLAGS were empty: -echo "Checking what CFLAGS MPIR would use if they were empty..." -(unset CFLAGS CPPFLAGS CXXFLAGS && ./configure $MPIR_CONFIGURE) &>configure-empty.log +echo "------------------------------------------------------------------------" +echo "Configuring MPIR with empty CFLAGS to determine the defaults:" +(unset CFLAGS CPPFLAGS CXXFLAGS && ./configure $MPIR_CONFIGURE) if [ $? -ne 0 ]; then - # Output the log of the failed configure run - cat configure-empty.log echo >&2 "Error configuring MPIR (with CFLAGS unset)." echo >&2 "Consult `pwd`/config.log for for details." exit 1 @@ -252,6 +251,7 @@ if [ -z "$mpir_cc" ]; then echo >&2 "Please report this to " exit 1 fi +echo "------------------------------------------------------------------------" echo "Settings chosen by MPIR when configuring with CFLAGS unset:" echo " CC: $mpir_cc" echo " CFLAGS: $mpir_cflags" @@ -289,6 +289,7 @@ echo "(These settings may still get overridden by 'configure' or Makefiles.)" # We also add '--libdir="$SAGE_LOCAL/lib"' below, since newer autotools may # otherwise put the libraries into .../lib64 on 64-bit systems (cf. #12131). +echo "------------------------------------------------------------------------" echo "Configuring MPIR with the following options:" echo " --prefix=\"$SAGE_LOCAL\" --libdir=\"$SAGE_LOCAL/lib\" $MPIR_CONFIGURE" echo "You can set MPIR_CONFIGURE to pass additional parameters." From af1680b8e6fd32fc7b32cb37872061e8bf546890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Fri, 29 Aug 2014 06:55:28 +0200 Subject: [PATCH 061/698] 16256: Merge branch 'develop=6.4 beta2' into combinat/reorganize_the_documentation_indexes_into_src_sage_combinat-16256 (cont) --- src/sage/combinat/designs/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/combinat/designs/__init__.py b/src/sage/combinat/designs/__init__.py index b85584d4d7f..65270359a66 100644 --- a/src/sage/combinat/designs/__init__.py +++ b/src/sage/combinat/designs/__init__.py @@ -21,7 +21,8 @@ - :ref:`sage.combinat.designs.latin_squares` - :ref:`sage.combinat.designs.orthogonal_arrays` - :ref:`sage.combinat.designs.orthogonal_arrays_recursive` -- :ref:`sage.combinat.designs.difference_family +- :ref:`sage.combinat.designs.difference_family` +- :ref:`sage.combinat.designs.difference_matrices` - :ref:`sage.combinat.designs.steiner_quadruple_systems` - :ref:`sage.combinat.designs.database` From a23c12fafb58d03e371d47102bc490a7142ab7ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Fri, 29 Aug 2014 06:55:36 +0200 Subject: [PATCH 062/698] 16256: updated sage/combinat/module_list.rst --- src/doc/en/reference/combinat/module_list.rst | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/doc/en/reference/combinat/module_list.rst b/src/doc/en/reference/combinat/module_list.rst index e90a0957270..b883ee043de 100644 --- a/src/doc/en/reference/combinat/module_list.rst +++ b/src/doc/en/reference/combinat/module_list.rst @@ -3,9 +3,11 @@ Alphabetical module list .. NOTE:: - This is built automatically by running in src/sage/combinat:: + This can be updated semi-automatically by running in src/sage/combinat:: - for x in **/*.py*; do echo " sage/combinat/"`echo $x | sed 's/\.py.?$//'`; done >! /tmp/module_list + for x in **/*.py*; do echo " sage/combinat/$x"; done | perl -pe 's/\.pyx?$//' >! /tmp/module_list.rst + + and copy pasting the result back there. .. TODO:: @@ -74,12 +76,17 @@ Alphabetical module list sage/combinat/designs/bibd sage/combinat/designs/block_design sage/combinat/designs/covering_design + sage/combinat/designs/database sage/combinat/designs/design_catalog + sage/combinat/designs/designs_pyx + sage/combinat/designs/difference_family + sage/combinat/designs/difference_matrices sage/combinat/designs/ext_rep sage/combinat/designs/incidence_structures sage/combinat/designs/__init__ sage/combinat/designs/latin_squares sage/combinat/designs/orthogonal_arrays + sage/combinat/designs/orthogonal_arrays_recursive sage/combinat/designs/steiner_quadruple_systems sage/combinat/diagram_algebras sage/combinat/dict_addition @@ -91,11 +98,12 @@ Alphabetical module list sage/combinat/expnums sage/combinat/family sage/combinat/finite_class - sage/combinat/finite_state_machine sage/combinat/finite_state_machine_generators + sage/combinat/finite_state_machine sage/combinat/free_module sage/combinat/gelfand_tsetlin_patterns sage/combinat/graph_path + sage/combinat/gray_codes sage/combinat/hall_polynomial sage/combinat/__init__ sage/combinat/integer_list @@ -103,6 +111,7 @@ Alphabetical module list sage/combinat/integer_vector sage/combinat/integer_vectors_mod_permgroup sage/combinat/integer_vector_weighted + sage/combinat/interval_posets sage/combinat/kazhdan_lusztig sage/combinat/knutson_tao_puzzles sage/combinat/k_tableau @@ -170,6 +179,8 @@ Alphabetical module list sage/combinat/rigged_configurations/__init__ sage/combinat/rigged_configurations/kleber_tree sage/combinat/rigged_configurations/kr_tableaux + sage/combinat/rigged_configurations/rc_crystal + sage/combinat/rigged_configurations/rc_infinity sage/combinat/rigged_configurations/rigged_configuration_element sage/combinat/rigged_configurations/rigged_configurations sage/combinat/rigged_configurations/rigged_partition @@ -184,9 +195,12 @@ Alphabetical module list sage/combinat/root_system/coxeter_group sage/combinat/root_system/coxeter_matrix sage/combinat/root_system/dynkin_diagram + sage/combinat/root_system/hecke_algebra_representation sage/combinat/root_system/__init__ + sage/combinat/root_system/non_symmetric_macdonald_polynomials sage/combinat/root_system/pieri_factors sage/combinat/root_system/plot + sage/combinat/root_system/root_lattice_realization_algebras sage/combinat/root_system/root_lattice_realizations sage/combinat/root_system/root_space sage/combinat/root_system/root_system @@ -242,6 +256,7 @@ Alphabetical module list sage/combinat/sf/sfa sage/combinat/sf/sf sage/combinat/sf/witt + sage/combinat/shuffle sage/combinat/sidon_sets sage/combinat/similarity_class_type sage/combinat/six_vertex_model From 87f6298d9c0b02a78aa65d4307002ae74cf0d4b0 Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Sat, 30 Aug 2014 00:49:03 -0700 Subject: [PATCH 063/698] Check coercions when applying coercion reversed construction functors. --- src/sage/categories/pushout.py | 122 +++++++++++++++++++++++++++------ 1 file changed, 100 insertions(+), 22 deletions(-) diff --git a/src/sage/categories/pushout.py b/src/sage/categories/pushout.py index fbc7bbad7c5..9188b1d5066 100644 --- a/src/sage/categories/pushout.py +++ b/src/sage/categories/pushout.py @@ -3153,9 +3153,8 @@ def pushout(R, S): Laurent Series Ring in x over Rational Field A construction with ``coercion_reversed = True`` (currently only - the :class:`SubspaceFunctor` construction) is only applied if an - instance of it appears on each side, in which case the two - instances are correctly combined by their ``merge`` methods:: + the :class:`SubspaceFunctor` construction) is only applied if it + leads to a valid coercion:: sage: V = (QQ^3).span([[1, 2, 3/4]]) sage: A = ZZ^3 @@ -3168,6 +3167,45 @@ def pushout(R, S): [1 2 0] [0 0 1] + sage: from sage.categories.pushout import ConstructionFunctor + sage: class EvenPolynomialRing(type(QQ['x'])): + ... def __init__(self, base, var): + ... super(EvenPolynomialRing, self).__init__(base, var) + ... self.register_embedding(base[var]) + ... def __repr__(self): + ... return "Even Power " + super(EvenPolynomialRing, self).__repr__() + ... def construction(self): + ... return EvenPolynomialFunctor(), self.base()[self.variable_name()] + ... def _coerce_map_from_(self, R): + ... return self.base().has_coerce_map_from(R) + ... + sage: class EvenPolynomialFunctor(ConstructionFunctor): + ... rank = 10 + ... coercion_reversed = True + ... def __init__(self): + ... ConstructionFunctor.__init__(self, Rings(), Rings()) + ... def __call__(self, R): + ... return EvenPolynomialRing(R.base(), R.variable_name()) + ... + sage: pushout(EvenPolynomialRing(QQ, 'x'), ZZ) + Even Power Univariate Polynomial Ring in x over Rational Field + sage: pushout(EvenPolynomialRing(QQ, 'x'), QQ) + Even Power Univariate Polynomial Ring in x over Rational Field + sage: pushout(EvenPolynomialRing(QQ, 'x'), RR) + Even Power Univariate Polynomial Ring in x over Real Field with 53 bits of precision + + sage: pushout(EvenPolynomialRing(QQ, 'x'), ZZ['x']) + Univariate Polynomial Ring in x over Rational Field + sage: pushout(EvenPolynomialRing(QQ, 'x'), QQ['x']) + Univariate Polynomial Ring in x over Rational Field + sage: pushout(EvenPolynomialRing(QQ, 'x'), RR['x']) + Univariate Polynomial Ring in x over Real Field with 53 bits of precision + + sage: pushout(EvenPolynomialRing(QQ, 'x'), EvenPolynomialRing(QQ, 'x')) + Even Power Univariate Polynomial Ring in x over Rational Field + sage: pushout(EvenPolynomialRing(QQ, 'x'), EvenPolynomialRing(RR, 'x')) + Even Power Univariate Polynomial Ring in x over Real Field with 53 bits of precision + AUTHORS: -- Robert Bradshaw @@ -3187,9 +3225,11 @@ def pushout(R, S): Ss = [c[1] for c in S_tower] if R in Ss: - return S + if not any(c[0].coercion_reversed for c in S_tower[1:]): + return S elif S in Rs: - return R + if not any(c[0].coercion_reversed for c in R_tower[1:]): + return R if Rs[-1] in Ss: Rs, Ss = Ss, Rs @@ -3224,36 +3264,37 @@ def pushout(R, S): raise CoercionException("No common base") # Rc is a list of functors from Z to R and Sc is a list of functors from Z to S - Rc = [c[0] for c in R_tower[1:len(Rs)+1]] - Sc = [c[0] for c in S_tower[1:len(Ss)+1]] - - Rc = sum([c.expand() for c in Rc], []) - Sc = sum([c.expand() for c in Sc], []) + R_tower = expand_tower(R_tower[:len(Rs)+1]) + S_tower = expand_tower(S_tower[:len(Ss)+1]) + Rc = [c[0] for c in R_tower[1:]] + Sc = [c[0] for c in S_tower[1:]] all = IdentityConstructionFunctor() + def apply_from(Xc): + c = Xc.pop() + if c.coercion_reversed: + Yc = Sc if Xc is Rc else Rc + Y_tower = S_tower if Xc is Rc else R_tower + Y_partial = Y_tower[len(Yc)][1] + if not (c * all)(Z).has_coerce_map_from(Y_partial): + return all + return c * all + try: while len(Rc) > 0 or len(Sc) > 0: # print Z # if we are out of functors in either tower, there is no ambiguity if len(Sc) == 0: - c = Rc.pop() - if not c.coercion_reversed: - all = c * all + all = apply_from(Rc) elif len(Rc) == 0: - c = Sc.pop() - if not c.coercion_reversed: - all = c * all + all = apply_from(Sc) # if one of the functors has lower rank, do it first elif Rc[-1].rank < Sc[-1].rank: - c = Rc.pop() - if not c.coercion_reversed: - all = c * all + all = apply_from(Rc) elif Sc[-1].rank < Rc[-1].rank: - c = Sc.pop() - if not c.coercion_reversed: - all = c * all + all = apply_from(Sc) else: # the ranks are the same, so things are a bit subtler if Rc[-1] == Sc[-1]: @@ -3301,6 +3342,7 @@ def pushout(R, S): # We do this because we may be trying all kinds of things that don't # make sense, and in this case simply want to return that a pushout # couldn't be found. + raise raise CoercionException(ex) @@ -3513,7 +3555,43 @@ def construction_tower(R): c = R.construction() return tower +def expand_tower(tower): + """ + An auxiliary function that is used in :func:`pushout`. + + INPUT: + + A construction tower as returned by :func:`construction_tower`. + + OUTPUT: + A new construction tower with all the construction functors expanded. + + EXAMPLE:: + + sage: from sage.categories.pushout import construction_tower, expand_tower + sage: construction_tower(QQ['x,y,z']) + [(None, Multivariate Polynomial Ring in x, y, z over Rational Field), + (MPoly[x,y,z], Rational Field), + (FractionField, Integer Ring)] + sage: expand_tower(construction_tower(QQ['x,y,z'])) + [(None, Multivariate Polynomial Ring in x, y, z over Rational Field), + (MPoly[z], Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field), + (MPoly[y], Univariate Polynomial Ring in x over Rational Field), + (MPoly[x], Rational Field), + (FractionField, Integer Ring)] + """ + new_tower = [] + for f, R in reversed(tower): + if f is None: + new_tower.append((f, R)) + else: + fs = f.expand() + for ff in reversed(fs[1:]): + new_tower.append((ff, R)) + R = ff(R) + new_tower.append((fs[0], R)) + return list(reversed(new_tower)) def type_to_parent(P): """ From e31574828e020c03ff883856868ee089e95c3ec3 Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Sat, 30 Aug 2014 16:46:54 -0700 Subject: [PATCH 064/698] More reverse coercion tests. --- src/sage/categories/pushout.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/sage/categories/pushout.py b/src/sage/categories/pushout.py index 9188b1d5066..f2fc0b644f2 100644 --- a/src/sage/categories/pushout.py +++ b/src/sage/categories/pushout.py @@ -3167,6 +3167,8 @@ def pushout(R, S): [1 2 0] [0 0 1] + Some more tests with ``coercion_reversed = True``:: + sage: from sage.categories.pushout import ConstructionFunctor sage: class EvenPolynomialRing(type(QQ['x'])): ... def __init__(self, base, var): @@ -3206,6 +3208,11 @@ def pushout(R, S): sage: pushout(EvenPolynomialRing(QQ, 'x'), EvenPolynomialRing(RR, 'x')) Even Power Univariate Polynomial Ring in x over Real Field with 53 bits of precision + sage: pushout(EvenPolynomialRing(QQ, 'x')^2, RR^2) + Ambient free module of rank 2 over the principal ideal domain Even Power Univariate Polynomial Ring in x over Real Field with 53 bits of precision + sage: pushout(EvenPolynomialRing(QQ, 'x')^2, RR['x']^2) + Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Real Field with 53 bits of precision + AUTHORS: -- Robert Bradshaw @@ -3317,9 +3324,9 @@ def apply_from(Xc): if Sc[-1] in Rc: raise CoercionException("Ambiguous Base Extension", R, S) else: - all = Sc.pop() * all + all = apply_from(Sc) elif Sc[-1] in Rc: - all = Rc.pop() * all + all = apply_from(Rc) # If, perchance, the two functors commute, then we may do them in any order. elif Rc[-1].commutes(Sc[-1]) or Sc[-1].commutes(Rc[-1]): all = Sc.pop() * Rc.pop() * all @@ -3342,7 +3349,6 @@ def apply_from(Xc): # We do this because we may be trying all kinds of things that don't # make sense, and in this case simply want to return that a pushout # couldn't be found. - raise raise CoercionException(ex) From eb78962f4978bd50629919ad3a88ee1549f4c380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Sun, 31 Aug 2014 15:35:51 +0200 Subject: [PATCH 065/698] 16256: reference graph theory, coding, and dynamics as 'related topics'; minor improvements --- src/doc/en/reference/coding/index.rst | 2 ++ src/doc/en/reference/combinat/index.rst | 4 ++++ src/doc/en/reference/dynamics/index.rst | 6 +++++ src/doc/en/reference/graphs/index.rst | 1 + src/sage/combinat/__init__.py | 30 +++++++++++-------------- src/sage/combinat/enumerated_sets.py | 2 +- 6 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/doc/en/reference/coding/index.rst b/src/doc/en/reference/coding/index.rst index 57ce7d93e3b..313fa839ab0 100644 --- a/src/doc/en/reference/coding/index.rst +++ b/src/doc/en/reference/coding/index.rst @@ -1,3 +1,5 @@ +.. _sage.coding: + Coding Theory ============= diff --git a/src/doc/en/reference/combinat/index.rst b/src/doc/en/reference/combinat/index.rst index c35b07f2e73..2511a04a459 100644 --- a/src/doc/en/reference/combinat/index.rst +++ b/src/doc/en/reference/combinat/index.rst @@ -3,6 +3,10 @@ Combinatorics .. automodule:: sage.combinat + +Alphabetical Module List +------------------------ + .. toctree:: :maxdepth: 1 diff --git a/src/doc/en/reference/dynamics/index.rst b/src/doc/en/reference/dynamics/index.rst index 002577d9be5..7bc1004aed2 100644 --- a/src/doc/en/reference/dynamics/index.rst +++ b/src/doc/en/reference/dynamics/index.rst @@ -1,3 +1,5 @@ +.. _sage.dynamics: + Discrete dynamics ================= @@ -7,4 +9,8 @@ Discrete dynamics interval_exchanges flat_surfaces +.. SEEALSO:: + + - :ref:`sage.combinat.e_one_star` + .. include:: ../footer.txt diff --git a/src/doc/en/reference/graphs/index.rst b/src/doc/en/reference/graphs/index.rst index a598f8c6fe0..0a6995e6147 100644 --- a/src/doc/en/reference/graphs/index.rst +++ b/src/doc/en/reference/graphs/index.rst @@ -1,3 +1,4 @@ +.. _sage.graphs: Graph Theory ============ diff --git a/src/sage/combinat/__init__.py b/src/sage/combinat/__init__.py index df039ae109e..512e0b2d3fb 100644 --- a/src/sage/combinat/__init__.py +++ b/src/sage/combinat/__init__.py @@ -11,37 +11,33 @@ Thematic indexes ---------------- +- :ref:`sage.combinat.algebraic_combinatorics` - :ref:`sage.combinat.counting` - :ref:`sage.combinat.enumerated_sets` - :ref:`sage.combinat.catalog_partitions` +- :ref:`sage.combinat.finite_state_machine` - :ref:`sage.combinat.species` - :ref:`sage.combinat.designs` -- :ref:`sage.combinat.algebraic_combinatorics` - :ref:`sage.combinat.posets` - :ref:`sage.combinat.words` .. TODO:: mention here the thematic indexes on root_systems, crystals, quivers, ...? -Graphs ------- - -.. TODO:: are those the best entry points for graphs? - -- :class:`Graph`, :class:`DiGraph`, :obj:`graphs `, :obj:`digraphs ` - -Dynamical systems ------------------ +Utilities +--------- -- :ref:`sage.combinat.e_one_star` - -Miscellaneous -------------- - -- :ref:`sage.combinat.finite_state_machine` (TODO: this deserves to be advertised more) - :ref:`sage.combinat.output` - :ref:`sage.combinat.ranker` +- :func:`Combinatorial maps ` - :ref:`sage.combinat.misc` -- :func:`sage.combinat.combinatorial_map.combinatorial_map` + +Related topics +-------------- + +- :ref:`sage.coding` +- :ref:`sage.dynamics` +- :ref:`sage.graphs` + """ #import demo #import demo_short diff --git a/src/sage/combinat/enumerated_sets.py b/src/sage/combinat/enumerated_sets.py index 14748228ff2..3ea7b8086cd 100644 --- a/src/sage/combinat/enumerated_sets.py +++ b/src/sage/combinat/enumerated_sets.py @@ -55,7 +55,7 @@ .. SEEALSO:: - - :class:`SymmetricGroup`, :class:`PermutationGroup`, :ref:`sage.groups.perm_gps.permutation_groups_catalog` + - :class:`SymmetricGroup`, :func:`PermutationGroup`, :ref:`sage.groups.perm_gps.permutation_groups_catalog` - :class:`FiniteSetMaps` - :ref:`sage.combinat.integer_vectors_mod_permgroup` - :ref:`sage.combinat.rsk` From b872e5754a9ea0b33363b1bb5ed2bb52573da400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Sun, 31 Aug 2014 16:28:48 +0200 Subject: [PATCH 066/698] 16256: use ~ when referencing classes and functions --- src/sage/combinat/algebraic_combinatorics.py | 33 ++++++++--------- src/sage/combinat/enumerated_sets.py | 38 ++++++++++---------- 2 files changed, 34 insertions(+), 37 deletions(-) diff --git a/src/sage/combinat/algebraic_combinatorics.py b/src/sage/combinat/algebraic_combinatorics.py index f4234521611..b3415e8a693 100644 --- a/src/sage/combinat/algebraic_combinatorics.py +++ b/src/sage/combinat/algebraic_combinatorics.py @@ -20,16 +20,16 @@ ---------------------------------------- - :ref:`sage.combinat.catalog_partitions` -- :class:`sage.combinat.gelfand_tsetlin_patterns.GelfandTsetlinPattern`, :class:`sage.combinat.gelfand_tsetlin_patterns.GelfandTsetlinPatterns` -- :class:`sage.combinat.knutson_tao_puzzles.KnutsonTaoPuzzleSolver` +- :class:`~sage.combinat.gelfand_tsetlin_patterns.GelfandTsetlinPattern`, :class:`~sage.combinat.gelfand_tsetlin_patterns.GelfandTsetlinPatterns` +- :class:`~sage.combinat.knutson_tao_puzzles.KnutsonTaoPuzzleSolver` Combinatorial Hopf Algebras --------------------------- -- :class:`Symmetric Functions ` +- :class:`~sage.combinat.sf.sf.SymmetricFunctions` - :ref:`sage.combinat.ncsf_qsym` - :ref:`sage.combinat.schubert_polynomial` -- :class:`sage.combinat.ncsym.ncsym.SymmetricFunctionsNonCommutingVariables` +- :class:`~sage.combinat.ncsym.ncsym.SymmetricFunctionsNonCommutingVariables` Groups and Algebras ------------------- @@ -38,11 +38,13 @@ - :ref:`Groups ` - :class:`SymmetricGroup`, :class:`CoxeterGroup`, :class:`WeylGroup` -- :class:`sage.combinat.diagram_algebras.PartitionAlgebra` -- :class:`sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra` -- :class:`sage.combinat.symmetric_group_algebra.SymmetricGroupAlgebra` -- :class:`sage.algebras.nil_coxeter_algebra.NilCoxeterAlgebra` -- :class:`sage.algebras.affine_nil_temperley_lieb.AffineNilTemperleyLiebTypeA` +- :class:`~sage.combinat.diagram_algebras.PartitionAlgebra` +- :class:`~sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra` +- :class:`~sage.combinat.symmetric_group_algebra.SymmetricGroupAlgebra` +- :class:`~sage.algebras.nil_coxeter_algebra.NilCoxeterAlgebra` +- :class:`~sage.algebras.affine_nil_temperley_lieb.AffineNilTemperleyLiebTypeA` +- :ref:`sage.combinat.descent_algebra` +- :ref:`sage.combinat.diagram_algebras` Combinatorial Representation Theory ----------------------------------- @@ -51,13 +53,8 @@ - :ref:`sage.combinat.crystals` - :ref:`sage.combinat.rigged_configurations` - :ref:`sage.combinat.cluster_algebra_quiver` -- :class:`sage.combinat.kazhdan_lusztig.KazhdanLusztigPolynomial` -- :class:`sage.combinat.symmetric_group_representations.SymmetricGroupRepresentation` - -.. TODO:: - - ../sage/combinat/descent_algebra - ../sage/combinat/diagram_algebras - ../sage/combinat/yang_baxter_graph - ../sage/combinat/hall_polynomial +- :class:`~sage.combinat.kazhdan_lusztig.KazhdanLusztigPolynomial` +- :class:`~sage.combinat.symmetric_group_representations.SymmetricGroupRepresentation` +- :ref:`sage.combinat.yang_baxter_graph` +- :ref:`sage.combinat.hall_polynomial` """ diff --git a/src/sage/combinat/enumerated_sets.py b/src/sage/combinat/enumerated_sets.py index 3ea7b8086cd..bf541137c1a 100644 --- a/src/sage/combinat/enumerated_sets.py +++ b/src/sage/combinat/enumerated_sets.py @@ -12,10 +12,10 @@ Basic enumerated sets --------------------- -- :class:`sage.combinat.subset.Subsets`, :class:`sage.combinat.combination.Combinations` -- :class:`sage.combinat.permutation.Arrangements`, :class:`sage.combinat.tuple.Tuples` -- :class:`sage.sets.finite_enumerated_set.FiniteEnumeratedSet` -- :class:`DisjointUnionEnumeratedSets`, :class:`CartesianProduct` +- :class:`~sage.combinat.subset.Subsets`, :class:`~sage.combinat.combination.Combinations` +- :class:`~sage.combinat.permutation.Arrangements`, :class:`~sage.combinat.tuple.Tuples` +- :class:`~sage.sets.finite_enumerated_set.FiniteEnumeratedSet` +- :class:`~DisjointUnionEnumeratedSets`, :class:`~CartesianProduct` Integer lists ------------- @@ -23,11 +23,11 @@ - :ref:`sage.combinat.partition` (see also: :ref:`sage.combinat.catalog_partitions`) - :ref:`sage.combinat.composition` -- :class:`sage.combinat.composition_signed.SignedCompositions` +- :class:`~sage.combinat.composition_signed.SignedCompositions` -- :class:`sage.combinat.integer_vector.IntegerVectors` -- :func:`sage.combinat.integer_vector_weighted.WeightedIntegerVectors` -- :class:`sage.combinat.integer_vectors_mod_permgroup.IntegerVectorsModPermutationGroup` +- :class:`~sage.combinat.integer_vector.IntegerVectors` +- :func:`~sage.combinat.integer_vector_weighted.WeightedIntegerVectors` +- :class:`~sage.combinat.integer_vectors_mod_permgroup.IntegerVectorsModPermutationGroup` - :ref:`sage.combinat.parking_functions` - :ref:`sage.combinat.non_decreasing_parking_function` @@ -50,7 +50,7 @@ - :ref:`sage.combinat.permutation` - :ref:`sage.combinat.affine_permutation` -- :class:`sage.combinat.permutation.Arrangements` +- :class:`~sage.combinat.permutation.Arrangements` - :ref:`sage.combinat.derangements` .. SEEALSO:: @@ -87,7 +87,7 @@ - :ref:`sage.combinat.set_partition_ordered` - :ref:`sage.combinat.set_partition` -- :class:`sage.combinat.subsets_pairwise.PairwiseCompatibleSubsets` +- :class:`~sage.combinat.subsets_pairwise.PairwiseCompatibleSubsets` Trees ----- @@ -111,17 +111,17 @@ Do we want a separate section, possibly more proeminent, for backtracking solvers? -- :class:`sage.combinat.backtrack.GenericBacktracker` -- :class:`sage.combinat.backtrack.TransitiveIdeal` -- :class:`sage.combinat.backtrack.TransitiveIdealGraded` -- :func:`sage.combinat.tools.transitive_ideal` -- :class:`sage.combinat.backtrack.SearchForest` +- :class:`~sage.combinat.backtrack.GenericBacktracker` +- :class:`~sage.combinat.backtrack.TransitiveIdeal` +- :class:`~sage.combinat.backtrack.TransitiveIdealGraded` +- :func:`~sage.combinat.tools.transitive_ideal` +- :class:`~sage.combinat.backtrack.SearchForest` - :ref:`sage.combinat.tiling` - :ref:`sage.combinat.dlx` - :ref:`sage.combinat.matrices.dlxcpp` - :ref:`sage.combinat.species` -- :class:`sage.combinat.integer_list.IntegerListsLex` -- :class:`sage.combinat.integer_vectors_mod_permgroup.IntegerVectorsModPermutationGroup` +- :class:`~sage.combinat.integer_list.IntegerListsLex` +- :class:`~sage.combinat.integer_vectors_mod_permgroup.IntegerVectorsModPermutationGroup` Low level enumerated sets ------------------------- @@ -135,7 +135,7 @@ Misc enumerated sets -------------------- -- :class:`sage.combinat.gelfand_tsetlin_patterns.GelfandTsetlinPattern`, :class:`sage.combinat.gelfand_tsetlin_patterns.GelfandTsetlinPatterns` -- :class:`sage.combinat.knutson_tao_puzzles.KnutsonTaoPuzzleSolver` +- :class:`~sage.combinat.gelfand_tsetlin_patterns.GelfandTsetlinPattern`, :class:`~sage.combinat.gelfand_tsetlin_patterns.GelfandTsetlinPatterns` +- :class:`~sage.combinat.knutson_tao_puzzles.KnutsonTaoPuzzleSolver` - :func:`LatticePolytope` """ From 4ea19e8e8c4b00e9c64247b49fa4ce55c55647b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Sun, 31 Aug 2014 16:29:19 +0200 Subject: [PATCH 067/698] 16256: added title to sage.combinat.perm_grps.permutation_groups_catalog --- src/sage/groups/perm_gps/permutation_groups_catalog.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/groups/perm_gps/permutation_groups_catalog.py b/src/sage/groups/perm_gps/permutation_groups_catalog.py index 8559abcda96..2151c2cea32 100644 --- a/src/sage/groups/perm_gps/permutation_groups_catalog.py +++ b/src/sage/groups/perm_gps/permutation_groups_catalog.py @@ -1,4 +1,6 @@ r""" +Catalog of permutation groups + Type ``groups.permutation.`` to access examples of groups implemented as permutation groups. """ From b331dc4f12e7291e9537f607ed155085cabc3fcd Mon Sep 17 00:00:00 2001 From: Simon King Date: Tue, 2 Sep 2014 14:48:41 +0200 Subject: [PATCH 068/698] Fix mem leak converting zero-valued biseq_t to list --- src/sage/misc/bounded_integer_sequences.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index b1e109c5428..07f66e2901a 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -168,9 +168,6 @@ cdef list biseq_to_list(biseq_t S): cdef int max_limb index = 0 cdef mp_limb_t *tmp_limb - tmp_limb = sage_malloc(2<sage_malloc(2<=n>0: limb_index = index>>times_mp_bits_per_limb bit_index = index&mod_mp_bits_per_limb From 7b53dc82d032d5a787e10731938f9048b620031b Mon Sep 17 00:00:00 2001 From: Simon King Date: Wed, 3 Sep 2014 15:43:57 +0200 Subject: [PATCH 069/698] Try to improve memory management for biseq_t, and add a stress test --- src/sage/misc/bounded_integer_sequences.pyx | 127 +++++++++++--------- 1 file changed, 71 insertions(+), 56 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index 07f66e2901a..cc0cc820bed 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -130,12 +130,8 @@ cdef biseq_t* list_to_biseq(biseq_t S, list data) except NULL: """ cdef unsigned long int item cdef __mpz_struct *S_boil - S_boil = <__mpz_struct*>S.data cdef mp_limb_t item_limb - cdef mp_limb_t *tmp_limb - tmp_limb = sage_malloc(sizeof(mp_limb_t)) - if tmp_limb==NULL: - raise MemoryError("Cannot even allocate one long integer") + cdef mp_limb_t tmp_limb cdef int offset_mod, offset_div cdef int offset = 0 if not data: @@ -145,40 +141,35 @@ cdef biseq_t* list_to_biseq(biseq_t S, list data) except NULL: offset_mod = offset&mod_mp_bits_per_limb offset_div = offset>>times_mp_bits_per_limb if offset_mod: - S_boil._mp_d[offset_div+1] = mpn_lshift(tmp_limb, &item_limb, 1, offset_mod) - S_boil._mp_d[offset_div] |= tmp_limb[0] + (<__mpz_struct*>S.data)._mp_d[offset_div+1] = mpn_lshift(&tmp_limb, &item_limb, 1, offset_mod) + (<__mpz_struct*>S.data)._mp_d[offset_div] |= tmp_limb + if (<__mpz_struct*>S.data)._mp_d[offset_div+1]!=0 and offset_div+1>=(<__mpz_struct*>S.data)._mp_size: + (<__mpz_struct*>S.data)._mp_size = offset_div+2 + elif tmp_limb!=0 and offset_div>=(<__mpz_struct*>S.data)._mp_size: + (<__mpz_struct*>S.data)._mp_size = offset_div+1 else: - S_boil._mp_d[offset_div] = item_limb + (<__mpz_struct*>S.data)._mp_d[offset_div] = item_limb + if item_limb!=0 and offset_div>=(<__mpz_struct*>S.data)._mp_size: + (<__mpz_struct*>S.data)._mp_size = offset_div+1 offset += S.itembitsize - cdef unsigned long int i - for i from offset_div+(1 if offset_mod else 0)>=i>=0: - if S_boil._mp_d[i]: - break - S_boil._mp_size = i+1 - sage_free(tmp_limb) return &S cdef list biseq_to_list(biseq_t S): """ Convert a bounded integer sequence to a list of integers. """ - cdef __mpz_struct seq - seq = deref(<__mpz_struct*>S.data) cdef unsigned int index, limb_index, bit_index cdef int max_limb index = 0 - cdef mp_limb_t *tmp_limb cdef list L = [] cdef size_t n # If limb_indexS.data)._mp_size - 1 if max_limb<0: return [int(0)]*S.length - tmp_limb = sage_malloc(2<=n>0: limb_index = index>>times_mp_bits_per_limb bit_index = index&mod_mp_bits_per_limb @@ -188,23 +179,22 @@ cdef list biseq_to_list(biseq_t S): if limb_index < max_limb: if bit_index: if bit_index+S.itembitsize >= mp_bits_per_limb: - mpn_rshift(tmp_limb, seq._mp_d+limb_index, 2, bit_index) + mpn_rshift(tmp_limb, (<__mpz_struct*>S.data)._mp_d+limb_index, 2, bit_index) L.append((tmp_limb[0]&S.mask_item)) else: - L.append((((seq._mp_d[limb_index])>>bit_index)&S.mask_item)) + L.append(((((<__mpz_struct*>S.data)._mp_d[limb_index])>>bit_index)&S.mask_item)) else: - L.append((seq._mp_d[limb_index]&S.mask_item)) + L.append(((<__mpz_struct*>S.data)._mp_d[limb_index]&S.mask_item)) elif limb_index == max_limb: if bit_index: - L.append((((seq._mp_d[limb_index])>>bit_index)&S.mask_item)) + L.append(((((<__mpz_struct*>S.data)._mp_d[limb_index])>>bit_index)&S.mask_item)) else: - L.append((seq._mp_d[limb_index]&S.mask_item)) + L.append(((<__mpz_struct*>S.data)._mp_d[limb_index]&S.mask_item)) else: break index += S.itembitsize if n: L.extend([int(0)]*n) - sage_free(tmp_limb) return L # @@ -434,10 +424,7 @@ cdef int index_biseq(biseq_t S, int item, size_t start) except -2: seq = deref(<__mpz_struct*>S.data) cdef unsigned int n, limb_index, bit_index, max_limb - cdef mp_limb_t *tmp_limb - tmp_limb = sage_malloc(2<= mp_bits_per_limb: mpn_rshift(tmp_limb, seq._mp_d+limb_index, 2, bit_index) if item==(tmp_limb[0]&S.mask_item): - sage_free(tmp_limb) return index elif item==(((seq._mp_d[limb_index])>>bit_index)&S.mask_item): - sage_free(tmp_limb) return index elif item==(seq._mp_d[limb_index]&S.mask_item): return index elif limb_index == max_limb: if bit_index: if item==(((seq._mp_d[limb_index])>>bit_index)&S.mask_item): - sage_free(tmp_limb) return index elif item==(seq._mp_d[limb_index]&S.mask_item): return index else: - sage_free(tmp_limb) if item==0 and index>times_mp_bits_per_limb bit_index = index&mod_mp_bits_per_limb - cdef mp_limb_t* tmp_limb + cdef mp_limb_t tmp_limb[2] cdef int out if limb_index>=seq._mp_size: return 0 @@ -499,12 +481,8 @@ cdef int getitem_biseq(biseq_t S, unsigned long int index) except -1: limb_size = 1 # the second limb may be non-allocated memory and # should be treated as zero. if limb_size!=1: - tmp_limb = sage_malloc(limb_size<deref(tmp_limb) - sage_free(tmp_limb) + out = (tmp_limb[0]) else: out = ((seq._mp_d[limb_index])>>bit_index) else: @@ -559,10 +537,7 @@ cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL: # Convention for variable names: We move data from *_src to *_tgt # tmp_limb is used to temporarily store the data that we move/shift - cdef mp_limb_t *tmp_limb - tmp_limb = sage_malloc(2<=seq_tgt._mp_size: + seq_tgt._mp_size = offset_div_tgt+2 + elif tmp_limb[0]!=0 and offset_div_tgt>=seq_tgt._mp_size: + seq_tgt._mp_size = offset_div_tgt+1 else: seq_tgt._mp_d[offset_div_tgt] = tmp_limb[0] + if tmp_limb[0]!=0: + seq_tgt._mp_size = offset_div_tgt+1 offset_tgt += S.itembitsize offset_src += bitstep - for n from offset_div_tgt+(1 if offset_mod_tgt else 0)>=n>=0: - if seq_tgt._mp_d[n]: - break - seq_tgt._mp_size = n+1 - sage_free(tmp_limb) return &out ########################################### @@ -1039,10 +1015,7 @@ cdef class BoundedIntegerSequence: cdef unsigned int index, limb_index, bit_index cdef int max_limb index = 0 - cdef mp_limb_t *tmp_limb - tmp_limb = sage_malloc(2<0 break index += self.data.itembitsize - sage_free(tmp_limb) def __getitem__(self, index): """ @@ -1518,3 +1490,46 @@ cpdef BoundedIntegerSequence NewBISEQ(data, unsigned long int bitsize, unsigned out.data.length = length mpz_set_str(out.data.data, data, 32) return out + +def _biseq_stresstest(): + cdef int i + from sage.misc.prandom import randint + cdef list L = [BoundedIntegerSequence(6, [randint(0,5) for x in range(randint(4,10))]) for y in range(100)] + cdef int branch + cdef BoundedIntegerSequence S, T + for i from 0<=i<10000: + if (i%1000) == 0: + print i + branch = randint(0,4) + if branch == 0: + L[randint(0,99)] = L[randint(0,99)]+L[randint(0,99)] + elif branch == 1: + x = randint(0,99) + if len(L[x]): + y = randint(0,len(L[x])-1) + z = randint(y,len(L[x])-1) + L[randint(0,99)] = L[x][y:z] + else: + L[x] = BoundedIntegerSequence(6, [randint(0,5) for x in range(randint(4,10))]) + elif branch == 2: + t = list(L[randint(0,99)]) + t = repr(L[randint(0,99)]) + t = L[randint(0,99)].list() + elif branch == 3: + x = randint(0,99) + if len(L[x]): + t = L[x][randint(0,len(L[x])-1)] + try: + t = L[x].index(t) + except ValueError: + print L[x] + print t + raise + else: + L[x] = BoundedIntegerSequence(6, [randint(0,5) for x in range(randint(4,10))]) + elif branch == 4: + S = L[randint(0,99)] + T = L[randint(0,99)] + startswith_biseq(S.data,T.data) + contains_biseq(S.data, T.data, 0) + max_overlap_biseq(S.data, T.data) From 7b6637585ad21de1f57ef086a989fdae93d1252a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Wed, 3 Sep 2014 15:58:48 +0200 Subject: [PATCH 070/698] 16256: temporarily hard coded html links to the thematic tutorials --- src/sage/combinat/algebraic_combinatorics.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/combinat/algebraic_combinatorics.py b/src/sage/combinat/algebraic_combinatorics.py index b3415e8a693..70b33bfe01b 100644 --- a/src/sage/combinat/algebraic_combinatorics.py +++ b/src/sage/combinat/algebraic_combinatorics.py @@ -10,11 +10,11 @@ Thematic tutorials ------------------ -.. TODO:: how to link to those? +.. TODO:: get Sphinx to create those cross links properly -- thematic_tutorials/algebraic_combinatorics -- thematic_tutorials/lie -- thematic_tutorials/MILP +- `Algebraic Combinatorics in Sage <../../../../thematic_tutorials/algebraic_combinatorics.html>`_ +- `Lie Methods and Related Combinatorics in Sage <../../../../thematic_tutorials/lie.html>`_ +- `Linear Programming (Mixed Integer) <../../../../thematic_tutorials/linear_programming.html>`_ Enumerated sets of combinatorial objects ---------------------------------------- From 29734cfb075a969fdc8885bf1c9d4797531cc2fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Wed, 3 Sep 2014 15:59:36 +0200 Subject: [PATCH 071/698] 16256: added direct links to the indexes on crystals, quiver algebras, root systems, ... --- src/sage/combinat/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/__init__.py b/src/sage/combinat/__init__.py index 512e0b2d3fb..4c79af7b9c2 100644 --- a/src/sage/combinat/__init__.py +++ b/src/sage/combinat/__init__.py @@ -12,6 +12,10 @@ ---------------- - :ref:`sage.combinat.algebraic_combinatorics` + - :ref:`sage.combinat.cluster_algebra_quiver` + - :ref:`sage.combinat.crystals` + - :ref:`sage.combinat.root_system` + - :class:`~sage.combinat.sf.sf.SymmetricFunctions` - :ref:`sage.combinat.counting` - :ref:`sage.combinat.enumerated_sets` - :ref:`sage.combinat.catalog_partitions` @@ -21,8 +25,6 @@ - :ref:`sage.combinat.posets` - :ref:`sage.combinat.words` -.. TODO:: mention here the thematic indexes on root_systems, crystals, quivers, ...? - Utilities --------- From 3f0ef5ab3c0bda2e5ee3730fd48f1186e56f0401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Wed, 3 Sep 2014 16:22:43 +0200 Subject: [PATCH 072/698] 16256: ReST typo fix on previous commit --- src/sage/combinat/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/combinat/__init__.py b/src/sage/combinat/__init__.py index 4c79af7b9c2..63bb315b443 100644 --- a/src/sage/combinat/__init__.py +++ b/src/sage/combinat/__init__.py @@ -12,10 +12,12 @@ ---------------- - :ref:`sage.combinat.algebraic_combinatorics` + - :ref:`sage.combinat.cluster_algebra_quiver` - :ref:`sage.combinat.crystals` - :ref:`sage.combinat.root_system` - :class:`~sage.combinat.sf.sf.SymmetricFunctions` + - :ref:`sage.combinat.counting` - :ref:`sage.combinat.enumerated_sets` - :ref:`sage.combinat.catalog_partitions` From 7c9f0f28529af66a5c0a00a8c0116ed02ac58f5a Mon Sep 17 00:00:00 2001 From: Simon King Date: Wed, 3 Sep 2014 20:19:08 +0200 Subject: [PATCH 073/698] Biseq refactored, so that only pointers are passed around. --- src/sage/misc/bounded_integer_sequences.pxd | 16 ++-- src/sage/misc/bounded_integer_sequences.pyx | 90 +++++++++++++-------- 2 files changed, 67 insertions(+), 39 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pxd b/src/sage/misc/bounded_integer_sequences.pxd index b80d95d3a56..de2094a3c09 100644 --- a/src/sage/misc/bounded_integer_sequences.pxd +++ b/src/sage/misc/bounded_integer_sequences.pxd @@ -1,6 +1,6 @@ include "sage/libs/ntl/decl.pxi" -ctypedef struct biseq_t: # bounded integer sequence type +ctypedef struct biseq: # bounded integer sequence mpz_t data # Use GMP integers as bitarrays unsigned long int bitsize # Bitsize of "data" unsigned int itembitsize # Bitsize of one element of this sequence. @@ -14,17 +14,21 @@ ctypedef struct biseq_t: # bounded integer sequence type # to repeat this multiplication and thus store # the result. -cdef biseq_t* allocate_biseq(size_t l, unsigned long int itemsize) except NULL +ctypedef biseq *biseq_t + +cdef biseq_t allocate_biseq(size_t l, unsigned long int itemsize) except NULL # Allocate memory (filled with zero) for a bounded integer sequence # of length l with items fitting in itemsize bits. -cdef biseq_t* list_to_biseq(biseq_t S, list data) except NULL - # Assumes that S is allocated +cdef void dealloc_biseq(biseq_t S) + +cdef biseq_t list_to_biseq(list data, unsigned int bound) except NULL + # Convert a list to a bounded integer sequence cdef list biseq_to_list(biseq_t S) # Convert a bounded integer sequence to a list -cdef biseq_t* concat_biseq(biseq_t S1, biseq_t S2) except NULL +cdef biseq_t concat_biseq(biseq_t S1, biseq_t S2) except NULL # Does not test whether the sequences have the same bound! cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2) @@ -47,7 +51,7 @@ cdef int index_biseq(biseq_t S, int item, size_t start) except -2 cdef int getitem_biseq(biseq_t S, unsigned long int index) except -1 # Returns S[index], without checking margins -cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL +cdef biseq_t slice_biseq(biseq_t S, int start, int stop, int step) except NULL # Returns the biseq S[start:stop:step] cdef class BoundedIntegerSequence: diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index cc0cc820bed..7f9ab021e62 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -16,7 +16,7 @@ modules:: # Allocate memory (filled with zero) for a bounded integer sequence # of length l with items fitting in itemsize bits. - cdef biseq_t* list_to_biseq(biseq_t S, list data) except NULL + cdef biseq_t* list_to_biseq(list data, unsigned int bound) except NULL # Assumes that S is allocated cdef list biseq_to_list(biseq_t S) @@ -99,13 +99,15 @@ from cython.operator import dereference as deref, preincrement as preinc, predec # (De)allocation, copying # -cdef biseq_t* allocate_biseq(size_t l, unsigned long int itemsize) except NULL: +cdef biseq_t allocate_biseq(size_t l, unsigned long int itemsize) except NULL: """ Allocate memory for a bounded integer sequence of length l with items fitting in itemsize bits. Returns a pointer to the bounded integer sequence, or NULL on error. """ - cdef biseq_t out + cdef biseq_t out = sage_malloc(sizeof(biseq)) + if out==NULL: + raise MemoryError("Can not allocate bounded integer sequence") out.bitsize = l*itemsize out.length = l out.itembitsize = itemsize @@ -113,29 +115,36 @@ cdef biseq_t* allocate_biseq(size_t l, unsigned long int itemsize) except NULL: sig_on() mpz_init2(out.data, out.bitsize+mp_bits_per_limb) sig_off() - return &out + return out + +cdef void dealloc_biseq(biseq_t S): + mpz_clear(S.data) + sage_free(S) # # Conversion # -cdef biseq_t* list_to_biseq(biseq_t S, list data) except NULL: +cdef biseq_t list_to_biseq(list data, unsigned int bound) except NULL: """ - Fill the content of a list into a bounded integer sequence. - - The bounded integer sequence is supposed to have enough memory allocated - and initialised to zero. This function returns a pointer to the originally - given bounded integer sequence, or NULL on error. + Convert a list into a bounded integer sequence. """ + cdef mpz_t tmp + cdef biseq_t S + if bound!=0: + mpz_init_set_ui(tmp, bound-1) + S = allocate_biseq(len(data), mpz_sizeinbase(tmp, 2)) + mpz_clear(tmp) + else: + raise ValueError("The bound for the items of bounded integer sequences must be positive") cdef unsigned long int item - cdef __mpz_struct *S_boil cdef mp_limb_t item_limb cdef mp_limb_t tmp_limb cdef int offset_mod, offset_div cdef int offset = 0 if not data: - return &S + return S for item in data: item_limb = (item&S.mask_item) offset_mod = offset&mod_mp_bits_per_limb @@ -152,7 +161,7 @@ cdef biseq_t* list_to_biseq(biseq_t S, list data) except NULL: if item_limb!=0 and offset_div>=(<__mpz_struct*>S.data)._mp_size: (<__mpz_struct*>S.data)._mp_size = offset_div+1 offset += S.itembitsize - return &S + return S cdef list biseq_to_list(biseq_t S): """ @@ -201,7 +210,7 @@ cdef list biseq_to_list(biseq_t S): # Arithmetics # -cdef biseq_t *concat_biseq(biseq_t S1, biseq_t S2) except NULL: +cdef biseq_t concat_biseq(biseq_t S1, biseq_t S2) except NULL: """ Concatenate two bounded integer sequences. @@ -216,7 +225,9 @@ cdef biseq_t *concat_biseq(biseq_t S1, biseq_t S2) except NULL: - A pointer to the concatenated sequence, or NULL on error. """ - cdef biseq_t out + cdef biseq_t out = sage_malloc(sizeof(biseq)) + if out==NULL: + raise MemoryError("Can not allocate bounded integer sequence") out.bitsize = S1.bitsize+S2.bitsize out.length = S1.length+S2.length out.itembitsize = S1.itembitsize # do not test == S2.itembitsize @@ -226,7 +237,7 @@ cdef biseq_t *concat_biseq(biseq_t S1, biseq_t S2) except NULL: sig_off() mpz_mul_2exp(out.data, S2.data, S1.bitsize) mpz_ior(out.data, out.data, S1.data) - return &out + return out cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2): """ @@ -489,7 +500,7 @@ cdef int getitem_biseq(biseq_t S, unsigned long int index) except -1: out = (seq._mp_d[limb_index]) return out&S.mask_item -cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL: +cdef biseq_t slice_biseq(biseq_t S, int start, int stop, int step) except NULL: """ Create the slice S[start:stop:step] as bounded integer sequence. @@ -509,8 +520,7 @@ cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL: return allocate_biseq(0, S.itembitsize) else: length = ((stop-start+1)//step)+1 - cdef biseq_t out - out = deref(allocate_biseq(length, S.itembitsize)) + cdef biseq_t out = allocate_biseq(length, S.itembitsize) cdef unsigned int offset_mod, offset_div cdef int limb_size total_shift = start*S.itembitsize @@ -526,14 +536,14 @@ cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL: limb_size = min(limb_size, (<__mpz_struct*>(S.data))._mp_size-offset_div) if limb_size<=0: (<__mpz_struct*>(out.data))._mp_size = 0 - return &out + return out mpn_rshift((<__mpz_struct*>(out.data))._mp_d, (<__mpz_struct*>(S.data))._mp_d+offset_div, limb_size, offset_mod) for n from limb_size>n>=0: if (<__mpz_struct*>(out.data))._mp_d[n]: break (<__mpz_struct*>(out.data))._mp_size = n+1 mpz_fdiv_r_2exp(out.data, out.data, out.bitsize) - return &out + return out # Convention for variable names: We move data from *_src to *_tgt # tmp_limb is used to temporarily store the data that we move/shift @@ -586,7 +596,7 @@ cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL: seq_tgt._mp_size = offset_div_tgt+1 offset_tgt += S.itembitsize offset_src += bitstep - return &out + return out ########################################### # A cdef class that wraps the above, and @@ -781,11 +791,7 @@ cdef class BoundedIntegerSequence: """ # In __init__, we'll raise an error if the bound is 0. - cdef mpz_t tmp - if bound!=0: - mpz_init_set_ui(tmp, bound-1) - self.data = deref(allocate_biseq(len(data), mpz_sizeinbase(tmp, 2))) - mpz_clear(tmp) + self.data = NULL def __dealloc__(self): """ @@ -798,7 +804,8 @@ cdef class BoundedIntegerSequence: sage: del S # indirect doctest """ - mpz_clear(self.data.data) + if self.data!=NULL: + dealloc_biseq(self.data) def __init__(self, unsigned long int bound, list data): """ @@ -842,7 +849,7 @@ cdef class BoundedIntegerSequence: """ if bound==0: raise ValueError("Positive bound expected") - self.data = deref(list_to_biseq(self.data, data)) + self.data = list_to_biseq(data, bound) def __copy__(self): """ @@ -1099,6 +1106,12 @@ cdef class BoundedIntegerSequence: sage: S[2:2] == X[4:2] True + :: + + sage: S = BoundedIntegerSequence(6, [3, 5, 3, 1, 5, 2, 2, 5, 3, 3, 4]) + sage: S[10] + 4 + """ cdef BoundedIntegerSequence out cdef int start,stop,step @@ -1107,7 +1120,7 @@ cdef class BoundedIntegerSequence: if start==0 and stop==self.data.length and step==1: return self out = BoundedIntegerSequence.__new__(BoundedIntegerSequence, 0, None) - out.data = deref(slice_biseq(self.data, start, stop, step)) + out.data = slice_biseq(self.data, start, stop, step) return out cdef long Index try: @@ -1348,7 +1361,7 @@ cdef class BoundedIntegerSequence: if right.data.itembitsize!=myself.data.itembitsize: raise ValueError("can only concatenate bounded integer sequences of compatible bounds") out = BoundedIntegerSequence.__new__(BoundedIntegerSequence, 0, None) - out.data = deref(concat_biseq(myself.data, right.data)) + out.data = concat_biseq(myself.data, right.data) return out cpdef BoundedIntegerSequence maximal_overlap(self, BoundedIntegerSequence other): @@ -1483,6 +1496,9 @@ cpdef BoundedIntegerSequence NewBISEQ(data, unsigned long int bitsize, unsigned """ cdef BoundedIntegerSequence out = BoundedIntegerSequence.__new__(BoundedIntegerSequence, 0, None) + out.data = sage_malloc(sizeof(biseq)) + if out.data==NULL: + raise MemoryError("Can not allocate bounded integer sequence") mpz_init2(out.data.data, bitsize+mp_bits_per_limb) out.data.bitsize = bitsize out.data.itembitsize = itembitsize @@ -1492,14 +1508,22 @@ cpdef BoundedIntegerSequence NewBISEQ(data, unsigned long int bitsize, unsigned return out def _biseq_stresstest(): + """ + This function creates many bounded integer sequences and manipulates them + in various ways, in order to try to detect random memory corruptions. + + TESTS:: + + sage: from sage.misc.bounded_integer_sequences import _biseq_stresstest + sage: _biseq_stresstest() + + """ cdef int i from sage.misc.prandom import randint cdef list L = [BoundedIntegerSequence(6, [randint(0,5) for x in range(randint(4,10))]) for y in range(100)] cdef int branch cdef BoundedIntegerSequence S, T for i from 0<=i<10000: - if (i%1000) == 0: - print i branch = randint(0,4) if branch == 0: L[randint(0,99)] = L[randint(0,99)]+L[randint(0,99)] From 0aa3cbcfb1be64154ad32a419f250a9c6e52dcf2 Mon Sep 17 00:00:00 2001 From: Simon King Date: Wed, 3 Sep 2014 22:16:24 +0200 Subject: [PATCH 074/698] Fix corner cases in item access for bounded integer sequences --- src/sage/misc/bounded_integer_sequences.pyx | 44 ++++++++++++--------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index 7f9ab021e62..e0d765b41be 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -167,8 +167,7 @@ cdef list biseq_to_list(biseq_t S): """ Convert a bounded integer sequence to a list of integers. """ - cdef unsigned int index, limb_index, bit_index - cdef int max_limb + cdef int index, limb_index, bit_index, max_limb index = 0 cdef list L = [] cdef size_t n @@ -271,7 +270,7 @@ cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start): if S1.lengthS1.data) - cdef unsigned int n, limb_index, bit_index + cdef int n, limb_index, bit_index # The maximal number of limbs of S1 that is safe to use after the current # position. - cdef unsigned int max_limb_size = seq._mp_size-((start*S1.itembitsize)>>times_mp_bits_per_limb) + cdef int max_limb_size = seq._mp_size-((start*S1.itembitsize)>>times_mp_bits_per_limb) if ((start*S1.itembitsize)&mod_mp_bits_per_limb)==0: # We increase it, since in the loop it is decreased when the index is # zero modulo bits per limb @@ -392,7 +391,7 @@ cdef int max_overlap_biseq(biseq_t S1, biseq_t S2) except 0: sig_off() # We will use tmp to store enough bits to be able to compare with the tail # of S1. - cdef unsigned int n, limb_index, bit_index + cdef int n, limb_index, bit_index cdef int index, i, start_index if S2.length>=S1.length: start_index = 1 @@ -434,7 +433,7 @@ cdef int index_biseq(biseq_t S, int item, size_t start) except -2: cdef __mpz_struct seq seq = deref(<__mpz_struct*>S.data) - cdef unsigned int n, limb_index, bit_index, max_limb + cdef int n, limb_index, bit_index, max_limb cdef mp_limb_t tmp_limb[2] item &= S.mask_item n = 0 @@ -463,8 +462,8 @@ cdef int index_biseq(biseq_t S, int item, size_t start) except -2: elif item==(seq._mp_d[limb_index]&S.mask_item): return index else: - if item==0 and indexS.data) - cdef unsigned long int limb_index, bit_index, limb_size + cdef long int limb_index, bit_index, limb_size index *= S.itembitsize limb_index = index>>times_mp_bits_per_limb bit_index = index&mod_mp_bits_per_limb @@ -488,7 +487,7 @@ cdef int getitem_biseq(biseq_t S, unsigned long int index) except -1: if bit_index: # limb_size is 1 or 2 limb_size = ((bit_index+S.itembitsize-1)>>times_mp_bits_per_limb)+1 - if limb_index+limb_size>=seq._mp_size: + if limb_index+limb_size>seq._mp_size: limb_size = 1 # the second limb may be non-allocated memory and # should be treated as zero. if limb_size!=1: @@ -509,7 +508,7 @@ cdef biseq_t slice_biseq(biseq_t S, int start, int stop, int step) except NULL: - A pointer to the resulting bounded integer sequence, or NULL on error. """ - cdef unsigned long int length, total_shift, n + cdef long int length, total_shift, n if step>0: if stop>start: length = ((stop-start-1)//step)+1 @@ -521,7 +520,7 @@ cdef biseq_t slice_biseq(biseq_t S, int start, int stop, int step) except NULL: else: length = ((stop-start+1)//step)+1 cdef biseq_t out = allocate_biseq(length, S.itembitsize) - cdef unsigned int offset_mod, offset_div + cdef int offset_mod, offset_div cdef int limb_size total_shift = start*S.itembitsize if step==1: @@ -1019,7 +1018,7 @@ cdef class BoundedIntegerSequence: """ cdef __mpz_struct seq seq = deref(<__mpz_struct*>self.data.data) - cdef unsigned int index, limb_index, bit_index + cdef int index, limb_index, bit_index cdef int max_limb index = 0 cdef mp_limb_t tmp_limb[2] @@ -1292,6 +1291,14 @@ cdef class BoundedIntegerSequence: sage: S.index(6) == S.index(6+S.bound()) True + TESTS:: + + sage: S = BoundedIntegerSequence(8, [2, 2, 2, 1, 2, 4, 3, 3, 3, 2, 2, 0]) + sage: S[11] + 0 + sage: S.index(0) + 11 + """ cdef int out if not isinstance(other, BoundedIntegerSequence): @@ -1515,7 +1522,7 @@ def _biseq_stresstest(): TESTS:: sage: from sage.misc.bounded_integer_sequences import _biseq_stresstest - sage: _biseq_stresstest() + sage: #_biseq_stresstest() """ cdef int i @@ -1542,13 +1549,12 @@ def _biseq_stresstest(): elif branch == 3: x = randint(0,99) if len(L[x]): - t = L[x][randint(0,len(L[x])-1)] + y = randint(0,len(L[x])-1) + t = L[x][y] try: t = L[x].index(t) except ValueError: - print L[x] - print t - raise + raise ValueError("{} should be in {} (bound {}) at position {}".format(t,L[x],L[x].bound(),y)) else: L[x] = BoundedIntegerSequence(6, [randint(0,5) for x in range(randint(4,10))]) elif branch == 4: From 8602a2d59d6578cde061ab94b76a47c63d127115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Wed, 3 Sep 2014 23:20:03 +0200 Subject: [PATCH 075/698] 16256: pass of proofreading on all combinat documentation indexes, handling a bunch of TODO's there. --- src/doc/en/reference/combinat/module_list.rst | 2 +- src/sage/combinat/__init__.py | 2 +- src/sage/combinat/algebraic_combinatorics.py | 4 +- .../cluster_algebra_quiver/__init__.py | 11 +- src/sage/combinat/designs/__init__.py | 2 - src/sage/combinat/matrices/__init__.py | 6 + src/sage/combinat/ncsf_qsym/__init__.py | 1 + src/sage/combinat/ncsym/__init__.py | 8 +- src/sage/combinat/posets/__init__.py | 9 +- src/sage/combinat/posets/posets.py | 2 +- .../rigged_configurations/__init__.py | 38 ++--- src/sage/combinat/root_system/__init__.py | 153 +++++++++++------- src/sage/combinat/root_system/root_system.py | 27 +--- src/sage/combinat/root_system/type_folded.py | 2 +- src/sage/combinat/sf/__init__.py | 44 +++-- 15 files changed, 165 insertions(+), 146 deletions(-) diff --git a/src/doc/en/reference/combinat/module_list.rst b/src/doc/en/reference/combinat/module_list.rst index b883ee043de..b869bf150d9 100644 --- a/src/doc/en/reference/combinat/module_list.rst +++ b/src/doc/en/reference/combinat/module_list.rst @@ -3,7 +3,7 @@ Alphabetical module list .. NOTE:: - This can be updated semi-automatically by running in src/sage/combinat:: + This can be updated semi-automatically by running in ``src/sage/combinat``:: for x in **/*.py*; do echo " sage/combinat/$x"; done | perl -pe 's/\.pyx?$//' >! /tmp/module_list.rst diff --git a/src/sage/combinat/__init__.py b/src/sage/combinat/__init__.py index 63bb315b443..ed3aaf07d74 100644 --- a/src/sage/combinat/__init__.py +++ b/src/sage/combinat/__init__.py @@ -16,7 +16,7 @@ - :ref:`sage.combinat.cluster_algebra_quiver` - :ref:`sage.combinat.crystals` - :ref:`sage.combinat.root_system` - - :class:`~sage.combinat.sf.sf.SymmetricFunctions` + - :ref:`sage.combinat.sf` - :ref:`sage.combinat.counting` - :ref:`sage.combinat.enumerated_sets` diff --git a/src/sage/combinat/algebraic_combinatorics.py b/src/sage/combinat/algebraic_combinatorics.py index 70b33bfe01b..152fe358b83 100644 --- a/src/sage/combinat/algebraic_combinatorics.py +++ b/src/sage/combinat/algebraic_combinatorics.py @@ -26,10 +26,10 @@ Combinatorial Hopf Algebras --------------------------- -- :class:`~sage.combinat.sf.sf.SymmetricFunctions` +- :ref:`sage.combinat.sf` - :ref:`sage.combinat.ncsf_qsym` - :ref:`sage.combinat.schubert_polynomial` -- :class:`~sage.combinat.ncsym.ncsym.SymmetricFunctionsNonCommutingVariables` +- :ref:`sage.combinat.ncsym` Groups and Algebras ------------------- diff --git a/src/sage/combinat/cluster_algebra_quiver/__init__.py b/src/sage/combinat/cluster_algebra_quiver/__init__.py index 6c1cfe5eb7e..0c697cb0f2f 100644 --- a/src/sage/combinat/cluster_algebra_quiver/__init__.py +++ b/src/sage/combinat/cluster_algebra_quiver/__init__.py @@ -2,12 +2,9 @@ Cluster Algebras and Quivers ============================ -.. TODO:: - - Populate - - ../sage/combinat/cluster_algebra_quiver/quiver_mutation_type - ../sage/combinat/cluster_algebra_quiver/quiver - ../sage/combinat/cluster_algebra_quiver/cluster_seed +- `A compendium on the cluster algebra and quiver package in Sage `_ arXiv:1102.4844 [math.CO] +- :ref:`sage.combinat.cluster_algebra_quiver.quiver_mutation_type` +- :ref:`sage.combinat.cluster_algebra_quiver.quiver` +- :ref:`sage.combinat.cluster_algebra_quiver.cluster_seed` """ diff --git a/src/sage/combinat/designs/__init__.py b/src/sage/combinat/designs/__init__.py index 65270359a66..7f7894cb57e 100644 --- a/src/sage/combinat/designs/__init__.py +++ b/src/sage/combinat/designs/__init__.py @@ -2,8 +2,6 @@ Designs and Incidence Structures ================================ -.. TODO:: Proofread / point to the main classes rather than the modules? - All designs can be accessed by ``designs.`` and are listed in the design catalog: diff --git a/src/sage/combinat/matrices/__init__.py b/src/sage/combinat/matrices/__init__.py index 366b73d9231..9e3d0a7d6bb 100644 --- a/src/sage/combinat/matrices/__init__.py +++ b/src/sage/combinat/matrices/__init__.py @@ -1,4 +1,10 @@ r""" Combinatorics on matrices +========================= + +- :ref:`sage.combinat.matrices.dancing_links` +- :ref:`sage.combinat.matrices.dlxcpp` +- :ref:`sage.combinat.matrices.hadamard_matrix` +- :ref:`sage.combinat.matrices.latin` """ import all diff --git a/src/sage/combinat/ncsf_qsym/__init__.py b/src/sage/combinat/ncsf_qsym/__init__.py index a69be87a569..7813801f5aa 100644 --- a/src/sage/combinat/ncsf_qsym/__init__.py +++ b/src/sage/combinat/ncsf_qsym/__init__.py @@ -3,6 +3,7 @@ ================================================================= - :ref:`sage.combinat.ncsf_qsym.tutorial` + - :class:`sage.combinat.ncsf_qsym.ncsf.NonCommutativeSymmetricFunctions` - :class:`sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions` diff --git a/src/sage/combinat/ncsym/__init__.py b/src/sage/combinat/ncsym/__init__.py index 9afdd274cad..7cac63e663c 100644 --- a/src/sage/combinat/ncsym/__init__.py +++ b/src/sage/combinat/ncsym/__init__.py @@ -2,9 +2,9 @@ Symmetric Functions in Non-Commuting Variables ============================================== -.. TODO:: Populate +- :class:`Introduction to Symmetric Functions in Non-Commuting Variables ` - ../sage/combinat/ncsym/bases - ../sage/combinat/ncsym/dual - ../sage/combinat/ncsym/ncsym +- :ref:`sage.combinat.ncsym.bases` +- :ref:`sage.combinat.ncsym.dual` +- :ref:`sage.combinat.ncsym.ncsym` """ diff --git a/src/sage/combinat/posets/__init__.py b/src/sage/combinat/posets/__init__.py index 2653ade17b7..8b8f7451e44 100644 --- a/src/sage/combinat/posets/__init__.py +++ b/src/sage/combinat/posets/__init__.py @@ -3,12 +3,13 @@ ====== - :ref:`sage.combinat.posets.posets` -- :func:`Poset`, :func:`MeetSemilattice`, :func:`JoinSemilattice`, :func:`LatticePoset` -- :class:`sage.categories.posets.Posets`, :class:`sage.categories.lattice_posets.LatticePosets` -- :obj:`Posets` +- Posets constructors: :func:`Poset`, :func:`MeetSemilattice`, :func:`JoinSemilattice`, :func:`LatticePoset` +- Posets categories: :class:`~sage.categories.posets.Posets` and :class:`~sage.categories.lattice_posets.LatticePosets` +- :class:`~sage.combinat.posets.linear_extensions.LinearExtensionOfPoset`, :class:`sage.combinat.posets.linear_extensions.LinearExtensionsOfPoset` + +- Catalog of posets: :obj:`Posets` - :ref:`sage.combinat.tamari_lattices` - :ref:`sage.combinat.interval_posets` -- :class:`sage.combinat.posets.linear_extensions.LinearExtensionOfPoset`, :class:`sage.combinat.posets.linear_extensions.LinearExtensionsOfPoset` """ import all diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 3a328f372e9..db5d2accf5b 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- r""" -Posets +Finite posets This module implements finite partially ordered sets. It defines: diff --git a/src/sage/combinat/rigged_configurations/__init__.py b/src/sage/combinat/rigged_configurations/__init__.py index 2f2770b49a1..0e857ab9a17 100644 --- a/src/sage/combinat/rigged_configurations/__init__.py +++ b/src/sage/combinat/rigged_configurations/__init__.py @@ -4,31 +4,31 @@ .. TODO:: Proofread / point to the main classes rather than the modules? -- :mod:`sage.combinat.rigged_configurations.rigged_configurations.rc_crystal` -- :mod:`sage.combinat.rigged_configurations.rigged_configurations.rc_infinity` +- :ref:`sage.combinat.rigged_configurations.rc_crystal` +- :ref:`sage.combinat.rigged_configurations.rc_infinity` -- :mod:`sage.combinat.rigged_configurations.rigged_configurations` -- :mod:`sage.combinat.rigged_configurations.rigged_configuration_element` +- :ref:`sage.combinat.rigged_configurations.rigged_configurations` +- :ref:`sage.combinat.rigged_configurations.rigged_configuration_element` -- :mod:`sage.combinat.rigged_configurations.tensor_product_kr_tableaux` -- :mod:`sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element` -- :mod:`sage.combinat.rigged_configurations.kr_tableaux` +- :ref:`sage.combinat.rigged_configurations.tensor_product_kr_tableaux` +- :ref:`sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element` +- :ref:`sage.combinat.rigged_configurations.kr_tableaux` -- :mod:`sage.combinat.rigged_configurations.kleber_tree` +- :ref:`sage.combinat.rigged_configurations.kleber_tree` -- :mod:`sage.combinat.rigged_configurations.rigged_partition` +- :ref:`sage.combinat.rigged_configurations.rigged_partition` Bijections ---------- -- :mod:`sage.combinat.rigged_configurations.bijection` -- :mod:`sage.combinat.rigged_configurations.bij_abstract_class` -- :mod:`sage.combinat.rigged_configurations.bij_type_A` -- :mod:`sage.combinat.rigged_configurations.bij_type_B` -- :mod:`sage.combinat.rigged_configurations.bij_type_C` -- :mod:`sage.combinat.rigged_configurations.bij_type_D` -- :mod:`sage.combinat.rigged_configurations.bij_type_A2_odd` -- :mod:`sage.combinat.rigged_configurations.bij_type_A2_even` -- :mod:`sage.combinat.rigged_configurations.bij_type_A2_dual` -- :mod:`sage.combinat.rigged_configurations.bij_type_D_twisted` +- :ref:`sage.combinat.rigged_configurations.bijection` +- :ref:`sage.combinat.rigged_configurations.bij_abstract_class` +- :ref:`sage.combinat.rigged_configurations.bij_type_A` +- :ref:`sage.combinat.rigged_configurations.bij_type_B` +- :ref:`sage.combinat.rigged_configurations.bij_type_C` +- :ref:`sage.combinat.rigged_configurations.bij_type_D` +- :ref:`sage.combinat.rigged_configurations.bij_type_A2_odd` +- :ref:`sage.combinat.rigged_configurations.bij_type_A2_even` +- :ref:`sage.combinat.rigged_configurations.bij_type_A2_dual` +- :ref:`sage.combinat.rigged_configurations.bij_type_D_twisted` """ diff --git a/src/sage/combinat/root_system/__init__.py b/src/sage/combinat/root_system/__init__.py index bcbebf8d4f7..4d0eadd76a9 100644 --- a/src/sage/combinat/root_system/__init__.py +++ b/src/sage/combinat/root_system/__init__.py @@ -1,5 +1,101 @@ -# Makes sage.combinat.root_system? equivalent to sage.combinat.root_system.root_system? -from root_system import __doc__ +__doc__=""" +Root Systems +============ + +Quickref +-------- + +- ``T = CartanType(["A", 3]), T.is_finite()`` -- Cartan types +- ``T.dynkin_diagram(), DynkinDiagram(["G",2])`` -- Dynkin diagrams +- ``T.cartan_matrix(), CartanMatrix(["F",4])`` -- Cartan matrices +- ``RootSystem(T).weight_lattice()`` -- Root systems +- ``WeylGroup(["B", 6, 1]).simple_reflections()`` -- Affine Weyl groups +- ``WeylCharacterRing(["D", 4])`` -- Weyl character rings + +Introductory material +--------------------- + +- :ref:`sage.combinat.root_system` -- This overview +- :class:`CartanType` -- An introduction to Cartan types +- :class:`RootSystem` -- An introduction to root systems +- :ref:`sage.combinat.root_system.plot` -- A root system visualization tutorial + +- The `Lie Methods and Related Combinatorics <../../../../thematic_tutorials/lie.html>`_ thematic tutorial + + +Related material +---------------- + +- :ref:`sage.combinat.crystals` -- Crystals + +Cartan datum +------------ + +- :ref:`sage.combinat.root_system.cartan_type` +- :ref:`sage.combinat.root_system.dynkin_diagram` +- :ref:`sage.combinat.root_system.cartan_matrix` +- :ref:`sage.combinat.root_system.coxeter_matrix` + +Root systems +------------ + +- :ref:`sage.combinat.root_system.root_system` +- :ref:`sage.combinat.root_system.plot` +- :ref:`sage.combinat.root_system.root_lattice_realizations` +- :ref:`sage.combinat.root_system.root_lattice_realization_algebras` +- :ref:`sage.combinat.root_system.weight_lattice_realizations` +- :ref:`sage.combinat.root_system.root_space` +- :ref:`sage.combinat.root_system.weight_space` +- :ref:`sage.combinat.root_system.ambient_space` + +Coxeter groups +-------------- + +- :ref:`sage.combinat.root_system.coxeter_group` +- :ref:`sage.combinat.root_system.weyl_group` + +.. SEEALSO:: + + The categories :class:`CoxeterGroups` and :class:`WeylGroups` + +Representation theory +--------------------- + +- :ref:`sage.combinat.root_system.weyl_characters` +- :ref:`sage.combinat.root_system.branching_rules` +- :ref:`sage.combinat.root_system.hecke_algebra_representation` +- :ref:`sage.combinat.root_system.non_symmetric_macdonald_polynomials` + +Root system data and code for specific families of Cartan types +--------------------------------------------------------------- + +- :ref:`sage.combinat.root_system.type_affine` +- :ref:`sage.combinat.root_system.type_dual` +- :ref:`sage.combinat.root_system.type_folded` +- :ref:`sage.combinat.root_system.type_reducible` +- :ref:`sage.combinat.root_system.type_relabel` + +Root system data and code for specific Cartan types +--------------------------------------------------- + +- :ref:`sage.combinat.root_system.type_A` +- :ref:`sage.combinat.root_system.type_B` +- :ref:`sage.combinat.root_system.type_C` +- :ref:`sage.combinat.root_system.type_D` +- :ref:`sage.combinat.root_system.type_E` +- :ref:`sage.combinat.root_system.type_F` +- :ref:`sage.combinat.root_system.type_G` +- :ref:`sage.combinat.root_system.type_H` +- :ref:`sage.combinat.root_system.type_I` +- :ref:`sage.combinat.root_system.type_A_affine` +- :ref:`sage.combinat.root_system.type_B_affine` +- :ref:`sage.combinat.root_system.type_C_affine` +- :ref:`sage.combinat.root_system.type_D_affine` +- :ref:`sage.combinat.root_system.type_E_affine` +- :ref:`sage.combinat.root_system.type_F_affine` +- :ref:`sage.combinat.root_system.type_G_affine` +- :ref:`sage.combinat.root_system.type_BC_affine` +""" # currently needed to activate the backward compatibility register_unpickle_override import type_A @@ -11,56 +107,3 @@ import type_G import all - -""" -Root Systems -============ - -.. toctree:: - :maxdepth: 2 - - ../sage/combinat/root_system/cartan_type - ../sage/combinat/root_system/dynkin_diagram - ../sage/combinat/root_system/cartan_matrix - ../sage/combinat/root_system/coxeter_matrix - ../sage/combinat/root_system/type_folded - - ../sage/combinat/root_system/root_system - ../sage/combinat/root_system/plot - ../sage/combinat/root_system/root_lattice_realizations - ../sage/combinat/root_system/root_lattice_realization_algebras - ../sage/combinat/root_system/weight_lattice_realizations - ../sage/combinat/root_system/root_space - ../sage/combinat/root_system/weight_space - ../sage/combinat/root_system/ambient_space - - ../sage/combinat/root_system/coxeter_group - ../sage/combinat/root_system/weyl_group - - ../sage/combinat/root_system/weyl_characters - ../sage/combinat/root_system/branching_rules - ../sage/combinat/root_system/hecke_algebra_representation - ../sage/combinat/root_system/non_symmetric_macdonald_polynomials - - ../sage/combinat/root_system/type_affine - ../sage/combinat/root_system/type_dual - ../sage/combinat/root_system/type_reducible - ../sage/combinat/root_system/type_relabel - ../sage/combinat/root_system/type_A - ../sage/combinat/root_system/type_B - ../sage/combinat/root_system/type_C - ../sage/combinat/root_system/type_D - ../sage/combinat/root_system/type_E - ../sage/combinat/root_system/type_F - ../sage/combinat/root_system/type_G - ../sage/combinat/root_system/type_H - ../sage/combinat/root_system/type_I - ../sage/combinat/root_system/type_A_affine - ../sage/combinat/root_system/type_B_affine - ../sage/combinat/root_system/type_C_affine - ../sage/combinat/root_system/type_D_affine - ../sage/combinat/root_system/type_E_affine - ../sage/combinat/root_system/type_F_affine - ../sage/combinat/root_system/type_G_affine - ../sage/combinat/root_system/type_BC_affine -""" diff --git a/src/sage/combinat/root_system/root_system.py b/src/sage/combinat/root_system/root_system.py index 1ca5d232ad8..5a1a46314db 100644 --- a/src/sage/combinat/root_system/root_system.py +++ b/src/sage/combinat/root_system/root_system.py @@ -2,32 +2,7 @@ Root systems ============ -Quickref --------- - -- ``T = CartanType(["A", 3]), T.is_finite()`` -- Cartan types -- ``T.dynkin_diagram(), DynkinDiagram(["G",2])`` -- Dynkin diagrams -- ``T.cartan_matrix(), CartanMatrix(["F",4])`` -- Cartan matrices -- ``RootSystem(T).weight_lattice()`` -- Root systems -- ``WeylGroup(["B", 6, 1]).simple_reflections()`` -- Affine Weyl groups -- ``WeylCharacterRing(["D", 4])`` -- Weyl character rings - -Documentation -------------- - -- :ref:`sage.combinat.root_system.root_system` -- This current overview -- :class:`CartanType` -- An introduction to Cartan types -- :class:`RootSystem` -- An introduction to root systems -- :ref:`sage.combinat.root_system.plot` -- A root system visualization tutorial -- The ``Lie Methods and Related Combinatorics`` thematic tutorial - -See also --------- - -- :class:`CoxeterGroups`, :class:`WeylGroups`, ...-- The categories of Coxeter and Weyl groups -- :ref:`sage.combinat.crystals` -- Crystals -- :mod:`.type_A`, :mod:`.type_B_affine`, ... -- Type specific root system data - +See :ref:`sage.combinat.root_system` for an overview. """ #***************************************************************************** # Copyright (C) 2007 Mike Hansen , diff --git a/src/sage/combinat/root_system/type_folded.py b/src/sage/combinat/root_system/type_folded.py index 7b3fbf21de6..28b388f7e2a 100644 --- a/src/sage/combinat/root_system/type_folded.py +++ b/src/sage/combinat/root_system/type_folded.py @@ -1,5 +1,5 @@ r""" -Folded Cartan Types +Root system data for folded Cartan types AUTHORS: diff --git a/src/sage/combinat/sf/__init__.py b/src/sage/combinat/sf/__init__.py index 7b1951ca3fe..9f8b1d56baf 100644 --- a/src/sage/combinat/sf/__init__.py +++ b/src/sage/combinat/sf/__init__.py @@ -2,28 +2,26 @@ Symmetric Functions =================== -.. TODO:: +- :class:`Introduction to Symmetric Functions ` - Populate - - sage/combinat/sf/sfa - sage/combinat/sf/sf - sage/combinat/sf/classical - sage/combinat/sf/schur - sage/combinat/sf/monomial - sage/combinat/sf/multiplicative - sage/combinat/sf/elementary - sage/combinat/sf/homogeneous - sage/combinat/sf/powersum - sage/combinat/sf/dual - sage/combinat/sf/orthotriang - sage/combinat/sf/kfpoly - sage/combinat/sf/hall_littlewood - sage/combinat/sf/jack - sage/combinat/sf/new_kschur - sage/combinat/sf/k_dual - sage/combinat/sf/llt - sage/combinat/sf/macdonald - sage/combinat/sf/ns_macdonald - sage/combinat/sf/witt +- :ref:`sage.combinat.sf.sfa` +- :ref:`sage.combinat.sf.sf` +- :ref:`sage.combinat.sf.classical` +- :ref:`sage.combinat.sf.schur` +- :ref:`sage.combinat.sf.monomial` +- :ref:`sage.combinat.sf.multiplicative` +- :ref:`sage.combinat.sf.elementary` +- :ref:`sage.combinat.sf.homogeneous` +- :ref:`sage.combinat.sf.powersum` +- :ref:`sage.combinat.sf.dual` +- :ref:`sage.combinat.sf.orthotriang` +- :ref:`sage.combinat.sf.kfpoly` +- :ref:`sage.combinat.sf.hall_littlewood` +- :ref:`sage.combinat.sf.jack` +- :ref:`sage.combinat.sf.new_kschur` +- :ref:`sage.combinat.sf.k_dual` +- :ref:`sage.combinat.sf.llt` +- :ref:`sage.combinat.sf.macdonald` +- :ref:`sage.combinat.sf.ns_macdonald` +- :ref:`sage.combinat.sf.witt` """ From f20dc096832f260edee2f28b3007bf42263f54ac Mon Sep 17 00:00:00 2001 From: Simon King Date: Thu, 4 Sep 2014 17:19:28 +0200 Subject: [PATCH 076/698] Fix writing out of bounds, and assert that the bounds are respected --- src/sage/misc/bounded_integer_sequences.pyx | 37 +++++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index e0d765b41be..c7bd00c7abf 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -150,6 +150,7 @@ cdef biseq_t list_to_biseq(list data, unsigned int bound) except NULL: offset_mod = offset&mod_mp_bits_per_limb offset_div = offset>>times_mp_bits_per_limb if offset_mod: + assert offset_div+1<(<__mpz_struct*>S.data)._mp_alloc (<__mpz_struct*>S.data)._mp_d[offset_div+1] = mpn_lshift(&tmp_limb, &item_limb, 1, offset_mod) (<__mpz_struct*>S.data)._mp_d[offset_div] |= tmp_limb if (<__mpz_struct*>S.data)._mp_d[offset_div+1]!=0 and offset_div+1>=(<__mpz_struct*>S.data)._mp_size: @@ -157,6 +158,7 @@ cdef biseq_t list_to_biseq(list data, unsigned int bound) except NULL: elif tmp_limb!=0 and offset_div>=(<__mpz_struct*>S.data)._mp_size: (<__mpz_struct*>S.data)._mp_size = offset_div+1 else: + assert offset_div<(<__mpz_struct*>S.data)._mp_alloc (<__mpz_struct*>S.data)._mp_d[offset_div] = item_limb if item_limb!=0 and offset_div>=(<__mpz_struct*>S.data)._mp_size: (<__mpz_struct*>S.data)._mp_size = offset_div+1 @@ -272,11 +274,6 @@ cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start): cdef __mpz_struct seq cdef int limb_size, limb_size_orig cdef mpz_t tmp - # Idea: We shift-copy enough limbs from S1 to tmp and then compare with - # S2, for each shift. - sig_on() - mpz_init2(tmp, S2.bitsize+mp_bits_per_limb) - sig_off() # We will use tmp to store enough bits to be able to compare with S2. # Hence, we say that its _mp_size is equal to that of S2. This may not be # correct, as we move bits from S1 (hence, there might be different @@ -309,13 +306,19 @@ cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start): seq = deref(<__mpz_struct*>S1.data) cdef int n, limb_index, bit_index + # Idea: We shift-copy enough limbs from S1 to tmp and then compare with + # S2, for each shift. + sig_on() + mpz_init2(tmp, S2.bitsize+mp_bits_per_limb) + sig_off() # The maximal number of limbs of S1 that is safe to use after the current - # position. - cdef int max_limb_size = seq._mp_size-((start*S1.itembitsize)>>times_mp_bits_per_limb) + # position, but not more than what fits into tmp: + cdef int max_S1_limbs = seq._mp_size-((start*S1.itembitsize)>>times_mp_bits_per_limb) + cdef int max_limb_size = min((<__mpz_struct*>tmp)._mp_alloc, max_S1_limbs) if ((start*S1.itembitsize)&mod_mp_bits_per_limb)==0: # We increase it, since in the loop it is decreased when the index is # zero modulo bits per limb - preinc(max_limb_size) + preinc(max_S1_limbs) n = 0 cdef int index = 0 # tmp may have trailing zeroes, and GMP can NOT cope with that! @@ -327,16 +330,22 @@ cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start): bit_index = n&mod_mp_bits_per_limb if bit_index: if limb_size < max_limb_size: + assert limb_size<(<__mpz_struct*>tmp)._mp_alloc mpn_rshift((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, limb_size+1, bit_index) else: + assert max_limb_size<=(<__mpz_struct*>tmp)._mp_alloc (<__mpz_struct*>tmp)._mp_size = max_limb_size mpn_rshift((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, max_limb_size, bit_index) else: # The bit_index is zero, and hence one limb less is remaining. We - # thus decrement max_limb_size. - if limb_size < predec(max_limb_size): + # thus decrement max_S1_limbs. + predec(max_S1_limbs) + max_limb_size = min((<__mpz_struct*>tmp)._mp_alloc, max_S1_limbs) + if limb_size < max_limb_size: + assert limb_size<=(<__mpz_struct*>tmp)._mp_alloc mpn_copyi((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, limb_size) else: + assert max_limb_size<=(<__mpz_struct*>tmp)._mp_alloc (<__mpz_struct*>tmp)._mp_size = max_limb_size mpn_copyi((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, max_limb_size) # Now, the first min(limb_size,max_limb_size) limbs of tmp are @@ -404,8 +413,10 @@ cdef int max_overlap_biseq(biseq_t S1, biseq_t S2) except 0: break bit_index = n&mod_mp_bits_per_limb if bit_index: + assert seq._mp_size-limb_index<=(<__mpz_struct*>tmp)._mp_alloc mpn_rshift((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, seq._mp_size-limb_index, bit_index) else: + assert seq._mp_size-limb_index<=(<__mpz_struct*>tmp)._mp_alloc mpn_copyi((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, seq._mp_size-limb_index) (<__mpz_struct*>tmp)._mp_size = seq._mp_size-limb_index if mpz_congruent_2exp_p(tmp, S2.data, S1.bitsize-n): @@ -491,6 +502,7 @@ cdef int getitem_biseq(biseq_t S, unsigned long int index) except -1: limb_size = 1 # the second limb may be non-allocated memory and # should be treated as zero. if limb_size!=1: + assert limb_size<=2 mpn_rshift(tmp_limb, seq._mp_d+limb_index, limb_size, bit_index) out = (tmp_limb[0]) else: @@ -536,6 +548,7 @@ cdef biseq_t slice_biseq(biseq_t S, int start, int stop, int step) except NULL: if limb_size<=0: (<__mpz_struct*>(out.data))._mp_size = 0 return out + assert limb_size<=(<__mpz_struct*>(out.data))._mp_alloc mpn_rshift((<__mpz_struct*>(out.data))._mp_d, (<__mpz_struct*>(S.data))._mp_d+offset_div, limb_size, offset_mod) for n from limb_size>n>=0: if (<__mpz_struct*>(out.data))._mp_d[n]: @@ -583,6 +596,7 @@ cdef biseq_t slice_biseq(biseq_t S, int start, int stop, int step) except NULL: tmp_limb[0] = 0 # put data from tmp_limb[0] to tgt if offset_mod_tgt: + assert offset_div_tgt+1<(<__mpz_struct*>(out.data))._mp_alloc seq_tgt._mp_d[offset_div_tgt+1] = mpn_lshift(tmp_limb, tmp_limb, 1, offset_mod_tgt) seq_tgt._mp_d[offset_div_tgt] |= tmp_limb[0] if seq_tgt._mp_d[offset_div_tgt+1]!=0 and offset_div_tgt+1>=seq_tgt._mp_size: @@ -590,6 +604,7 @@ cdef biseq_t slice_biseq(biseq_t S, int start, int stop, int step) except NULL: elif tmp_limb[0]!=0 and offset_div_tgt>=seq_tgt._mp_size: seq_tgt._mp_size = offset_div_tgt+1 else: + assert offset_div_tgt<(<__mpz_struct*>(out.data))._mp_alloc seq_tgt._mp_d[offset_div_tgt] = tmp_limb[0] if tmp_limb[0]!=0: seq_tgt._mp_size = offset_div_tgt+1 @@ -1522,7 +1537,7 @@ def _biseq_stresstest(): TESTS:: sage: from sage.misc.bounded_integer_sequences import _biseq_stresstest - sage: #_biseq_stresstest() + sage: _biseq_stresstest() """ cdef int i From cea38bb0a7d6f748cfc1feef357df5e22eb7b652 Mon Sep 17 00:00:00 2001 From: Simon King Date: Thu, 4 Sep 2014 18:05:45 +0200 Subject: [PATCH 077/698] Change doc according to the changed functionality of list_to_biseq --- src/sage/misc/bounded_integer_sequences.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index c7bd00c7abf..708b0ead3d1 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -17,7 +17,7 @@ modules:: # of length l with items fitting in itemsize bits. cdef biseq_t* list_to_biseq(list data, unsigned int bound) except NULL - # Assumes that S is allocated + # Convert a list to a bounded integer sequence cdef list biseq_to_list(biseq_t S) # Convert a bounded integer sequence to a list From 7af0a5d5d319ad00ba2700a7037c1e2664820aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Thu, 4 Sep 2014 18:43:35 +0200 Subject: [PATCH 078/698] 16256: improved sage.combinat.quickref --- src/sage/combinat/quickref.py | 52 +++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/src/sage/combinat/quickref.py b/src/sage/combinat/quickref.py index 87803f4c024..bb645b6487c 100644 --- a/src/sage/combinat/quickref.py +++ b/src/sage/combinat/quickref.py @@ -6,51 +6,73 @@ sage: s = oeis([1,3,19,211]); s 0: A000275: Coefficients of a Bessel function (reciprocal of J_0(z)); also pairs of permutations with rise/rise forbidden. - sage: s.programs() - 0: (PARI) a(n)=if(n<0,0,n!^2*4^n*polcoeff(1/besselj(0,x+x*O(x^(2*n))),2*n)) /* Michael Somos May 17 2004 */ + sage: s[0].programs() + 0: (PARI) a(n)=if(n<0,0,n!^2*4^n*polcoeff(1/besselj(0,x+x*O(x^(2*n))),2*n)) /* _Michael Somos_, May 17 2004 */ Combinatorial objects:: - sage: P = Partitions(10); P.cardinality(); P. - sage: C = Combinations([1,3,7]); C.list() + sage: S = Subsets([1,2,3,4]); S.list(); S. # not tested + sage: P = Partitions(10000); P.cardinality() + 3616...315650422081868605887952568754066420592310556052906916435144 + sage: Combinations([1,3,7]).random_element() # random sage: Compositions(5, max_part = 3).unrank(3) + [2, 2, 1] + + sage: DyckWord([1,0,1,0,1,1,0,0]).to_binary_tree() + [., [., [[., .], .]]] + sage: Permutation([3,1,4,2]).robinson_schensted() + [[[1, 2], [3, 4]], [[1, 3], [2, 4]]] + sage: StandardTableau([[1, 4], [2, 5], [3]]).schuetzenberger_involution() + [[1, 3], [2, 4], [5]] Constructions and Species:: - sage: for (p, c) in CartesianProduct(P, C): print p, c - sage: DisjointUnionEnumeratedSets(Family(lambda n: IntegerVectors(n, 3), NonNegativeIntegers)) + sage: for (p, s) in CartesianProduct(P, S): print p, s # not tested + sage: DisjointUnionEnumeratedSets(Family(lambda n: IntegerVectors(n, 3), NonNegativeIntegers)) # not tested Words:: - sage: Words('abc') - sage: Word('aabca').some_flashy_feature() + sage: Words('abc', 4).list() + [word: aaaa, ..., word: cccc] + + sage: Word('aabcacbaa').is_palindrome() + True + sage: WordMorphism('a->ab,b->a').fixed_point('a') + word: abaababaabaababaababaabaababaabaababaaba... Polytopes:: sage: points = random_matrix(ZZ, 6, 3, x=7).rows() sage: L = LatticePolytope(points) - sage: L.npoints(); L.plot3d() + sage: L.npoints(); L.plot3d() # random :ref:`Root systems, Coxeter and Weyl groups `:: - sage: CoxeterGroup(["B",3]).some_flashy_feature() + sage: WeylGroup(["B",3]).bruhat_poset() + Finite poset containing 48 elements + sage: RootSystem(["A",2,1]).weight_lattice().plot() # not tested :ref:`Crystals `:: - sage: CrystalOfTableaux(["A",3], shape = [3,2]).some_flashy_feature() + sage: CrystalOfTableaux(["A",3], shape = [3,2]).some_flashy_feature() # not tested :mod:`Symmetric functions and combinatorial Hopf algebras `:: sage: Sym = SymmetricFunctions(QQ); Sym.inject_shorthands() + doctest:...: RuntimeWarning: redefining global value `s` + doctest:...: RuntimeWarning: redefining global value `e` sage: m( ( h[2,1] * (1 + 3 * p[2,1]) ) + s[2](s[3]) ) + 3*m[1, 1, 1] + ... + 10*m[5, 1] + 4*m[6] :ref:`Discrete groups, Permutation groups `:: sage: S = SymmetricGroup(4) - sage: M = MultivariatePolynomials('x0,x1,x2,x3') - sage: M(...).action??? S. + sage: M = PolynomialRing(QQ, 'x0,x1,x2,x3') + sage: M.an_element() * S.an_element() + x1 -Graph theory, posets, lattices (:class:`Graph`, :class:`DiGraph`, :mod:`sage.combinat.posets`):: +Graph theory, posets, lattices (:ref:`sage.graphs`, :ref:`sage.combinat.posets`):: - sage: Poset({1: [2,3], 2: [4], 3: [4]}).some_flashy_feature() + sage: Poset({1: [2,3], 2: [4], 3: [4]}).linear_extensions().cardinality() + 2 """ From 2252c4453b5788a3c44fe05100fc0a9f93ea6919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Thu, 4 Sep 2014 18:59:42 +0200 Subject: [PATCH 079/698] 16256: improved sage.combinat.crystals's index --- src/sage/combinat/crystals/__init__.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/sage/combinat/crystals/__init__.py b/src/sage/combinat/crystals/__init__.py index affd1895d5b..c5e903c0a67 100644 --- a/src/sage/combinat/crystals/__init__.py +++ b/src/sage/combinat/crystals/__init__.py @@ -12,15 +12,12 @@ - :ref:`sage.combinat.crystals` -- This overview - :ref:`sage.combinat.crystals.crystals` -- The ``Lie Methods and Related Combinatorics`` thematic tutorial +- The `Lie Methods and Related Combinatorics <../../../../thematic_tutorials/lie.html>`_ thematic tutorial Catalogs of crystals -------------------- - :ref:`sage.combinat.crystals.catalog` -- :ref:`sage.combinat.crystals.catalog_elementary_crystals` -- :ref:`sage.combinat.crystals.catalog_infinity_crystals` -- :ref:`sage.combinat.crystals.catalog_kirillov_reshetikhin` See also -------- From 4611f8aa591616f118b50ebc2d2516c635e40318 Mon Sep 17 00:00:00 2001 From: Simon King Date: Fri, 5 Sep 2014 00:37:33 +0200 Subject: [PATCH 080/698] Minor changes in the docs --- src/sage/misc/bounded_integer_sequences.pyx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index 708b0ead3d1..e5acd8eda6d 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -12,17 +12,17 @@ than representing the same sequence as a Python :class:`tuple`. It also provides some boilerplate functions that can be cimported in Cython modules:: - cdef biseq_t* allocate_biseq(size_t l, unsigned long int itemsize) except NULL + cdef biseq_t allocate_biseq(size_t l, unsigned long int itemsize) except NULL # Allocate memory (filled with zero) for a bounded integer sequence # of length l with items fitting in itemsize bits. - cdef biseq_t* list_to_biseq(list data, unsigned int bound) except NULL + cdef biseq_t list_to_biseq(list data, unsigned int bound) except NULL # Convert a list to a bounded integer sequence cdef list biseq_to_list(biseq_t S) # Convert a bounded integer sequence to a list - cdef biseq_t* concat_biseq(biseq_t S1, biseq_t S2) except NULL + cdef biseq_t concat_biseq(biseq_t S1, biseq_t S2) except NULL # Does not test whether the sequences have the same bound! cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2) @@ -45,7 +45,7 @@ modules:: cdef int getitem_biseq(biseq_t S, unsigned long int index) except -1 # Returns S[index], without checking margins - cdef biseq_t* slice_biseq(biseq_t S, int start, int stop, int step) except NULL + cdef biseq_t slice_biseq(biseq_t S, int start, int stop, int step) except NULL # Returns the biseq S[start:stop:step] """ From 815d77c77f48605ea33b87a88120aaabadfb5f7f Mon Sep 17 00:00:00 2001 From: Simon King Date: Fri, 5 Sep 2014 12:57:41 +0200 Subject: [PATCH 081/698] mpn_r/lshift should only be used with strictly positive shift --- src/sage/misc/bounded_integer_sequences.pyx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index e5acd8eda6d..aac33237f9f 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -549,7 +549,10 @@ cdef biseq_t slice_biseq(biseq_t S, int start, int stop, int step) except NULL: (<__mpz_struct*>(out.data))._mp_size = 0 return out assert limb_size<=(<__mpz_struct*>(out.data))._mp_alloc - mpn_rshift((<__mpz_struct*>(out.data))._mp_d, (<__mpz_struct*>(S.data))._mp_d+offset_div, limb_size, offset_mod) + if offset_mod: + mpn_rshift((<__mpz_struct*>(out.data))._mp_d, (<__mpz_struct*>(S.data))._mp_d+offset_div, limb_size, offset_mod) + else: + mpn_copyi((<__mpz_struct*>(out.data))._mp_d, (<__mpz_struct*>(S.data))._mp_d+offset_div, limb_size) for n from limb_size>n>=0: if (<__mpz_struct*>(out.data))._mp_d[n]: break From d4b6d28935f08d2bbc4215ee7fb36bb0b1541369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Sat, 6 Sep 2014 10:41:20 +0200 Subject: [PATCH 082/698] 16256: merged the two introduction of crystals (in the catalog.py an crystals.py) and further little improvements --- src/sage/combinat/crystals/__init__.py | 6 +-- src/sage/combinat/crystals/catalog.py | 52 +++--------------- src/sage/combinat/crystals/crystals.py | 73 ++++++++++++++++++-------- 3 files changed, 60 insertions(+), 71 deletions(-) diff --git a/src/sage/combinat/crystals/__init__.py b/src/sage/combinat/crystals/__init__.py index c5e903c0a67..694eb1a519c 100644 --- a/src/sage/combinat/crystals/__init__.py +++ b/src/sage/combinat/crystals/__init__.py @@ -10,7 +10,6 @@ Introductory material --------------------- -- :ref:`sage.combinat.crystals` -- This overview - :ref:`sage.combinat.crystals.crystals` - The `Lie Methods and Related Combinatorics <../../../../thematic_tutorials/lie.html>`_ thematic tutorial @@ -22,9 +21,8 @@ See also -------- -- :class:`Crystals`, :class:`HighestWeightCrystals`, :class:`FiniteCrystals`, :class:`ClassicalCrystals`, :class:`RegularCrystals` -- The categories for crystals -- :ref:`sage.combinat.root_system` -- Root systems - +- The categories for crystals: :class:`Crystals`, :class:`HighestWeightCrystals`, :class:`FiniteCrystals`, :class:`ClassicalCrystals`, :class:`RegularCrystals` -- The categories for crystals +- :ref:`sage.combinat.root_system` """ import all diff --git a/src/sage/combinat/crystals/catalog.py b/src/sage/combinat/crystals/catalog.py index a834f6edba7..9e8a0204f46 100644 --- a/src/sage/combinat/crystals/catalog.py +++ b/src/sage/combinat/crystals/catalog.py @@ -1,44 +1,6 @@ r""" Catalog Of Crystals -Definition of a Crystal ------------------------ - -.. TODO:: This documentation duplicates that of sage.combinat.crystals.crystals - -Let `C` be a CartanType with index set `I`, and `P` be -the corresponding weight lattice of the type `C`. Let `\alpha_i` -and `\alpha^{\vee}_i` denote the corresponding simple roots -and coroots respectively. Let us give the axiomatic definition -of a crystal. - -A type `C` crystal `\mathcal{B}` is a non-empty set with maps -`\operatorname{wt} : \mathcal{B} \to P`, -`e_i, f_i : \mathcal{B} \to \mathcal{B} \cup \{0\}`, and -`\varepsilon_i, \varphi_i : \mathcal{B} \to \ZZ \cup \{-\infty\}` -for `i \in I` satisfying the following properties for all `i \in I`: - -- `\varphi_i(b) = \varepsilon_i(b) + \langle \alpha^{\vee}_i, - \operatorname{wt}(b) \rangle`, - -- if `e_i b \in \mathcal{B}`, then: - - * `\operatorname{wt}(e_i x) = \operatorname{wt}(b) + \alpha_i`, - * `\varepsilon_i(e_i b) = \varepsilon_i(b) - 1`, - * `\varphi_i(e_i b) = \varphi_i(b) + 1`, - -- if `f_i b \in \mathcal{B}`, then: - - * `\operatorname{wt}(f_i b) = \operatorname{wt}(b) - \alpha_i`, - * `\varepsilon_i(f_i b) = \varepsilon_i(b) + 1`, - * `\varphi_i(f_i b) = \varphi_i(b) - 1`, - -- `f_i b^{\prime} = b` if and only if `e_i b = b^{\prime}` - for `b, b^{\prime} \in \mathcal{B}`, - -- if `\varphi_i(b) = -\infty` for `b \in \mathcal{B}`, - then `e_i b = f_i b = 0`. - .. SEEALSO:: - :mod:`sage.categories.crystals` @@ -47,7 +9,7 @@ Catalog ------- -This is a catalog of crystals that are currently in Sage: +This is a catalog of crystals that are currently implemented in Sage: * :class:`~sage.combinat.crystals.affine.AffineCrystalFromClassical` * :class:`~sage.combinat.crystals.affine.AffineCrystalFromClassicalAndPromotion` @@ -71,16 +33,16 @@ * :class:`SpinsMinus ` * :class:`Tableaux ` +Subcatalogs: + +* :ref:`sage.combinat.crystals.catalog_infinity_crystals` +* :ref:`sage.combinat.crystals.catalog_elementary_crystals` +* :ref:`sage.combinat.crystals.catalog_kirillov_reshetikhin` + Functorial constructions: * :class:`DirectSum ` * :class:`TensorProduct ` - -Subcatalogs: - -* `B(\infty)` :mod:`(infinity) crystals ` -* :mod:`Elementary crystals ` -* :mod:`Kirillov-Reshetihkin crystals ` """ from letters import CrystalOfLetters as Letters from spins import CrystalOfSpins as Spins diff --git a/src/sage/combinat/crystals/crystals.py b/src/sage/combinat/crystals/crystals.py index 8bd32f5f04a..08855ef9a92 100644 --- a/src/sage/combinat/crystals/crystals.py +++ b/src/sage/combinat/crystals/crystals.py @@ -2,36 +2,68 @@ An introduction to crystals =========================== -Let `T` be a CartanType with index set `I`, and -`W` be a realization of the type `T` weight -lattice. +Informally, a crystal `\mathcal{B}` is an oriented graph with the +edges colored in some set `I` such that, for each `i\in I`, each node +`x` has: -A type `T` crystal `C` is a colored oriented graph -equipped with a weight function from the nodes to some realization -of the type `T` weight lattice such that: +- at most one `i`-successor, denoted `f_i x`; +- at most one `i`-predecessor, denoted `e_i x`. -- Each edge is colored with a label in `i \in I`. +and convention, one writes `f_i x=\emptyset` and `e_i x=\emptyset` +when `x` has no successor / predecessor. -- For each `i\in I`, each node `x` has: +One may think of `\mathcal{B}` as essentially a deterministic +automaton whose dual is also deterministic; in this context, the +`f_i` s and `e_i` s are respectively the transition functions of the +automaton and of its dual, and `\emptyset` is the sink. +A crystal comes further endowed with a weight function +`\operatorname{wt}: \mathcal{B}\mapsto L` which shall satisfies +appropriate conditions. - - at most one `i`-successor `f_i(x)`; +In combinatorial representation theory, Crystals are used as +combinatorial data to model representations of Lie algebra. - - at most one `i`-predecessor `e_i(x)`. +Axiomatic definition +-------------------- +Let `C` be a CartanType with index set `I`, and `L` be a realization +of the weight lattice of the type `C`. Let `\alpha_i` and +`\alpha^{\vee}_i` denote the simple roots and coroots +respectively. - Furthermore, when they exist, +A type `C` crystal `\mathcal{B}` is a non-empty set with maps +`\operatorname{wt} : \mathcal{B} \to L`, +`e_i, f_i : \mathcal{B} \to \mathcal{B} \cup \{\emptyset\}`, and +`\varepsilon_i, \varphi_i : \mathcal{B} \to \ZZ \cup \{-\infty\}` +for `i \in I` satisfying the following properties for all `i \in I`: +- `f_i b^{\prime} = b` if and only if `e_i b = b^{\prime}` + for `b, b^{\prime} \in \mathcal{B}`, - - `f_i(x)`.weight() = x.weight() - `\alpha_i`; +- `\varphi_i(b) = \varepsilon_i(b) + \langle \alpha^{\vee}_i, + \operatorname{wt}(b) \rangle`, - - `e_i(x)`.weight() = x.weight() + `\alpha_i`. +- if `e_i b \in \mathcal{B}`, then: + * `\operatorname{wt}(e_i x) = \operatorname{wt}(b) + \alpha_i`, + * `\varepsilon_i(e_i b) = \varepsilon_i(b) - 1`, + * `\varphi_i(e_i b) = \varphi_i(b) + 1`, +- if `f_i b \in \mathcal{B}`, then: -This crystal actually models a representation of a Lie algebra if -it satisfies some further local conditions due to Stembridge [St2003]_. + * `\operatorname{wt}(f_i b) = \operatorname{wt}(b) - \alpha_i`, + * `\varepsilon_i(f_i b) = \varepsilon_i(b) + 1`, + * `\varphi_i(f_i b) = \varphi_i(b) - 1`, + +- if `\varphi_i(b) = -\infty` for `b \in \mathcal{B}`, + then `e_i b = f_i b = 0`. + +Some further conditions are required to guarantee that this data +indeed models a representation of a Lie algebra. In finite simply +laced types a complete characterization is given by Stembridge's local +axioms [St2003]_. REFERENCES: @@ -91,11 +123,9 @@ sage: view(G, pdflatex=True, tightpage=True) #optional - dot2tex graphviz For rank two crystals, there is an alternative method of getting -metapost pictures. For more information see C.metapost? - -See also the categories :class:`Crystals`, :class:`ClassicalCrystals`, -:class:`FiniteCrystals`, :class:`HighestWeightCrystals`. +metapost pictures. For more information see ``C.metapost?``. +.. SEEALSO:: :ref:`The overview of crystal features in Sage` .. TODO:: @@ -111,9 +141,8 @@ - RestrictionOfCrystal -Most of the above features (except Littelmann/alcove paths) are in -MuPAD-Combinat (see lib/COMBINAT/crystals.mu), which could provide -inspiration. +The crystals library in Sage grew up from an initial implementation in +MuPAD-Combinat (see /lib/COMBINAT/crystals.mu). """ #***************************************************************************** From 2872210a0f22f940a6b808514eb6ed0b27f1f9a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Sat, 6 Sep 2014 11:08:16 +0200 Subject: [PATCH 083/698] 16256: proofreading previous commit --- src/sage/combinat/crystals/crystals.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/sage/combinat/crystals/crystals.py b/src/sage/combinat/crystals/crystals.py index 08855ef9a92..4bc99aa8826 100644 --- a/src/sage/combinat/crystals/crystals.py +++ b/src/sage/combinat/crystals/crystals.py @@ -2,20 +2,20 @@ An introduction to crystals =========================== -Informally, a crystal `\mathcal{B}` is an oriented graph with the -edges colored in some set `I` such that, for each `i\in I`, each node -`x` has: +Informally, a crystal `\mathcal{B}` is an oriented graph with edges +colored in some set `I` such that, for each `i\in I`, each node `x` +has: - at most one `i`-successor, denoted `f_i x`; - at most one `i`-predecessor, denoted `e_i x`. -and convention, one writes `f_i x=\emptyset` and `e_i x=\emptyset` -when `x` has no successor / predecessor. +By convention, one writes `f_i x=\emptyset` and `e_i x=\emptyset` when +`x` has no successor resp. predecessor. One may think of `\mathcal{B}` as essentially a deterministic automaton whose dual is also deterministic; in this context, the -`f_i` s and `e_i` s are respectively the transition functions of the +`f_i`'s and `e_i`'s are respectively the transition functions of the automaton and of its dual, and `\emptyset` is the sink. A crystal comes further endowed with a weight function @@ -33,17 +33,14 @@ `\alpha^{\vee}_i` denote the simple roots and coroots respectively. -A type `C` crystal `\mathcal{B}` is a non-empty set with maps +A type `C` crystal is a non-empty set `\mathcal{B}` endowed with maps `\operatorname{wt} : \mathcal{B} \to L`, `e_i, f_i : \mathcal{B} \to \mathcal{B} \cup \{\emptyset\}`, and `\varepsilon_i, \varphi_i : \mathcal{B} \to \ZZ \cup \{-\infty\}` for `i \in I` satisfying the following properties for all `i \in I`: -- `f_i b^{\prime} = b` if and only if `e_i b = b^{\prime}` - for `b, b^{\prime} \in \mathcal{B}`, +- for `b, b^{\prime} \in \mathcal{B}`, `f_i b^{\prime} = b` if and only if `e_i b = b^{\prime}`; -- `\varphi_i(b) = \varepsilon_i(b) + \langle \alpha^{\vee}_i, - \operatorname{wt}(b) \rangle`, - if `e_i b \in \mathcal{B}`, then: @@ -57,11 +54,14 @@ * `\varepsilon_i(f_i b) = \varepsilon_i(b) + 1`, * `\varphi_i(f_i b) = \varphi_i(b) - 1`, +- `\varphi_i(b) = \varepsilon_i(b) + \langle \alpha^{\vee}_i, + \operatorname{wt}(b) \rangle`, + - if `\varphi_i(b) = -\infty` for `b \in \mathcal{B}`, - then `e_i b = f_i b = 0`. + then `e_i b = f_i b = \emptyset`. Some further conditions are required to guarantee that this data -indeed models a representation of a Lie algebra. In finite simply +indeed models a representation of a Lie algebra. For finite simply laced types a complete characterization is given by Stembridge's local axioms [St2003]_. From dacaa247ad080a725d44f07f857c9e0ec1d5b1a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 7 Sep 2014 14:50:22 +0200 Subject: [PATCH 084/698] trac #16895 doc correction --- src/sage/rings/number_field/order.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/number_field/order.py b/src/sage/rings/number_field/order.py index a8d405ced94..f9e58262a94 100644 --- a/src/sage/rings/number_field/order.py +++ b/src/sage/rings/number_field/order.py @@ -690,7 +690,7 @@ def residue_field(self, prime, names=None, check=False): INPUT: - ``prime`` -- a prime ideal of the maximal order in this number field. - - ``name`` -- the name of the variable in the residue field + - ``names`` -- the name of the variable in the residue field - ``check`` -- whether or not to check the primality of prime. OUTPUT: @@ -711,8 +711,9 @@ def residue_field(self, prime, names=None, check=False): """ if self.is_maximal(): return self.number_field().residue_field(prime, names, check) - else: - raise NotImplementedError("Residue fields of non-maximal orders are not yet supported.") + + raise NotImplementedError("Residue fields of non-maximal orders " + "are not yet supported.") def fraction_field(self): """ From 14061a1d40e8a27d86eac6dd91559b0131f9fe55 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Wed, 10 Sep 2014 15:05:47 +0100 Subject: [PATCH 085/698] Fix mem leak when polynomial evaluates to constant --- src/sage/rings/polynomial/multi_polynomial_libsingular.pyx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 3b6cbdbe84c..9f52411be43 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -2102,7 +2102,7 @@ cdef class MPolynomial_libsingular(sage.rings.polynomial.multi_polynomial.MPolyn y += c*mul([ x[i]**m[i] for i in m.nonzero_positions()]) return y - cdef poly *res + cdef poly *res # ownership will be transferred to us in the next line singular_polynomial_call(&res, self._poly, _ring, coerced_x, MPolynomial_libsingular_get_element) res_parent = get_coercion_model().common_parent(parent._base, *x) @@ -2110,8 +2110,10 @@ cdef class MPolynomial_libsingular(sage.rings.polynomial.multi_polynomial.MPolyn return res_parent(0) if p_LmIsConstant(res, _ring): sage_res = si2sa( p_GetCoeff(res, _ring), _ring, parent._base ) + p_Delete(&res, _ring) # sage_res contains copy else: - sage_res = new_MP(parent, res) + sage_res = new_MP(parent, res) # pass on ownership of res to sage_res + if parent(sage_res) is not res_parent: sage_res = res_parent(sage_res) return sage_res From 083af08c1bd19eefd46092cb16720d8f1d1b88e4 Mon Sep 17 00:00:00 2001 From: Chris Wuthrich Date: Wed, 10 Sep 2014 16:18:28 +0100 Subject: [PATCH 086/698] corrections in sha_tate --- .../schemes/elliptic_curves/padic_lseries.py | 13 +- src/sage/schemes/elliptic_curves/sha_tate.py | 216 ++++++++++-------- 2 files changed, 129 insertions(+), 100 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/padic_lseries.py b/src/sage/schemes/elliptic_curves/padic_lseries.py index 4011736c51f..34635b8e104 100644 --- a/src/sage/schemes/elliptic_curves/padic_lseries.py +++ b/src/sage/schemes/elliptic_curves/padic_lseries.py @@ -48,8 +48,9 @@ - [Po] Robert Pollack, On the `p`-adic L-function of a modular form at supersingular prime, Duke Math. J. 118 (2003), no 3, 523-558. -- [SW] William Stein and Christian Wuthrich, Computations About Tate-Shafarevich Groups - using Iwasawa theory, preprint 2009. +- [SW] William Stein and Christian Wuthrich, Algorithms + for the Arithmetic of Elliptic Curves using Iwasawa Theory + Mathematics of Computation 82 (2013), 1757-1792. AUTHORS: @@ -892,12 +893,10 @@ def series(self, n=2, quadratic_twist=+1, prec=5, eta=0): K = Qp(p, 20, print_mode='series') R = PowerSeriesRing(K,'T',1) L = self.modular_symbol(0, sign=+1, quadratic_twist= D) - if self._E.has_nonsplit_multiplicative_reduction(p): - L *= 2 - if self._E.has_split_multiplicative_reduction(p): - L *= 0 + chip = kronecker_symbol(D,p) + if self._E.conductor() % p == 0: + L *= 1 - chip/self.alpha() else: - chip = kronecker_symbol(D,p) L *= (1-chip/self.alpha())**2 L /= self._quotient_of_periods_to_twist(D)*self._E.real_components() L = R(L, 1) diff --git a/src/sage/schemes/elliptic_curves/sha_tate.py b/src/sage/schemes/elliptic_curves/sha_tate.py index 826a520ec99..8cf9e25aefe 100644 --- a/src/sage/schemes/elliptic_curves/sha_tate.py +++ b/src/sage/schemes/elliptic_curves/sha_tate.py @@ -2,37 +2,43 @@ r""" Tate-Shafarevich group -If `E` is an elliptic curve over a global field `K`, the Tate-Shafarevich group -is the subgroup of elements in `H^1(K,E)` which map to zero under every global-to-local -restriction map `H^1(K,E) \to H^1(K_v,E)`, one for each place `v` -of `K`. +If `E` is an elliptic curve over a global field `K`, the Tate-Shafarevich +group is the subgroup of elements in `H^1(K,E)` which map to zero under every +global-to-local restriction map `H^1(K,E) \to H^1(K_v,E)`, one for each place +`v` of `K`. -The group is usually denoted by the Russian letter Sha (Ш), in this document it will be denoted by `Sha`. +The group is usually denoted by the Russian letter Sha (Ш), in this document +it will be denoted by `Sha`. -`Sha` is known to be an abelian torsion group. It is conjectured that the Tate-Shafarevich group is finite for any elliptic curve over a global field. But it is not known in general. +`Sha` is known to be an abelian torsion group. It is conjectured that the +Tate-Shafarevich group is finite for any elliptic curve over a global field. +But it is not known in general. -A theorem of Kolyvagin and Gross-Zagier using Heegner points shows that if the L-series of an elliptic curve `E/\QQ` does not -vanish at 1 or has a simple zero there, then `Sha` is finite. +A theorem of Kolyvagin and Gross-Zagier using Heegner points shows that if the +L-series of an elliptic curve `E/\QQ` does not vanish at 1 or has a simple +zero there, then `Sha` is finite. -A theorem of Kato, together with theorems from Iwasawa theory, allow for certain primes `p` to show that the `p`-primary part of `Sha` is finite and gives an effective upper bound for it. +A theorem of Kato, together with theorems from Iwasawa theory, allows for +certain primes `p` to show that the `p`-primary part of `Sha` is finite and +gives an effective upper bound for it. -The (`p`-adic) conjecture of Birch and Swinnerton-Dyer predicts the order of `Sha` from the leading term of the (`p`-adic) L-series of the elliptic curve. +The (`p`-adic) conjecture of Birch and Swinnerton-Dyer predicts the order of +`Sha` from the leading term of the (`p`-adic) L-series of the elliptic curve. Sage can compute a few things about `Sha`. The commands ``an``, -``an_numerical`` and ``an_padic`` compute the conjectural order of `Sha` -as a real or `p`-adic number. With ``p_primary_bound`` one can find an -upper bound of the size of the `p`-primary part of `Sha`. Finally, if -the analytic rank is at most 1, then ``bound_kato`` and -``bound_kolyvagin`` find all primes for which the theorems of Kato -and Kolyvagin respectively do not prove the triviality the `p`-primary -part of `Sha`. +``an_numerical`` and ``an_padic`` compute the conjectural order of `Sha` as a +real or `p`-adic number. With ``p_primary_bound`` one can find an upper bound +of the size of the `p`-primary part of `Sha`. Finally, if the analytic rank is +at most 1, then ``bound_kato`` and ``bound_kolyvagin`` find all primes for +which the theorems of Kato and Kolyvagin respectively do not prove the +triviality the `p`-primary part of `Sha`. EXAMPLES:: sage: E = EllipticCurve('11a1') sage: S = E.sha() sage: S.bound_kato() - [2, 3, 5] + [2] sage: S.bound_kolyvagin() ([2, 5], 1) sage: S.an_padic(7,3) @@ -92,18 +98,18 @@ class Sha(SageObject): r""" The Tate-Shafarevich group associated to an elliptic curve. - If `E` is an elliptic curve over a global field `K`, the Tate-Shafarevich group - is the subgroup of elements in `H^1(K,E)` which map to zero under every global-to-local - restriction map `H^1(K,E) \to H^1(K_v,E)`, one for each place `v` - of `K`. + If `E` is an elliptic curve over a global field `K`, the Tate-Shafarevich + group is the subgroup of elements in `H^1(K,E)` which map to zero under + every global-to-local restriction map `H^1(K,E) \to H^1(K_v,E)`, one for + each place `v` of `K`. EXAMPLES:: sage: E = EllipticCurve('571a1') - sage: E._set_gens([]) + sage: E._set_gens([]) # curve has rank 0, but non-trivial Sha[2] sage: S = E.sha() sage: S.bound_kato() - [2, 3] + [2] sage: S.bound_kolyvagin() ([2], 1) sage: S.an_padic(7,3) @@ -120,9 +126,9 @@ class Sha(SageObject): 1.00000000000000 sage: S.p_primary_bound(5) # long time 0 - sage: S.an_padic(5) # long time + sage: S.an_padic(5) # long time 1 + O(5) - sage: S.an_padic(5,prec=4) # long time + sage: S.an_padic(5,prec=4) # very long time 1 + O(5^3) """ def __init__(self, E): @@ -279,9 +285,10 @@ def an(self, use_database=False, descent_second_limit=12): INPUT: - - ``use_database`` -- bool (default: ``False``); if ``True``, try to use any - databases installed to lookup the analytic order of `Sha`, if - possible. The order of `Sha` is computed if it cannot be looked up. + - ``use_database`` -- bool (default: ``False``); if ``True``, try + to use any databases installed to lookup the analytic order of + `Sha`, if possible. The order of `Sha` is computed if it cannot + be looked up. - ``descent_second_limit`` -- int (default: 12); limit to use on point searching for the quartic twist in the hard case @@ -352,8 +359,8 @@ def an(self, use_database=False, descent_second_limit=12): sage: E.sha().an() 1.00000000000000 - The following are examples that require computation of the Mordell-Weil - group and regulator:: + The following are examples that require computation of the Mordell- + Weil group and regulator:: sage: E = EllipticCurve([0, 0, 1, -1, 0]) # 37A (rank 1) sage: E.sha().an() @@ -363,8 +370,8 @@ def an(self, use_database=False, descent_second_limit=12): sage: E.sha().an() 4 - In this case the input curve is not minimal, and if this function did not - transform it to be minimal, it would give nonsense:: + In this case the input curve is not minimal, and if this function did + not transform it to be minimal, it would give nonsense:: sage: E = EllipticCurve([0,-432*6^2]) sage: E.sha().an() @@ -447,18 +454,15 @@ def an_padic(self, p, prec=0, use_twists=True): C. R. Acad. Sci. Paris, Ser I. Math, 317 (1993), no 3, 227-232. - .. [SW] William Stein and Christian Wuthrich, Algorithms - for the Arithmetic of Elliptic Curves using Iwasawa Theory - Mathematics of Computation 82 (2013), 1757-1792. - INPUT: - ``p`` - a prime > 3 - - ``prec`` (optional) - the precision used in the computation of the `p`-adic L-Series + - ``prec`` (optional) - the precision used in the computation of the + `p`-adic L-Series - - ``use_twists`` (default = ``True``) - If ``True`` the algorithm may change - to a quadratic twist with minimal conductor to do the modular + - ``use_twists`` (default = ``True``) - If ``True`` the algorithm may + change to a quadratic twist with minimal conductor to do the modular symbol computations rather than using the modular symbols of the curve itself. If ``False`` it forces the computation using the modular symbols of the curve itself. @@ -612,10 +616,10 @@ def an_padic(self, p, prec=0, use_twists=True): v = bsdp.valuation() if v > 0: - verbose("the prime is irregular.") + verbose("the prime is irregular for this curve.") - # determine how much prec we need to prove at least the triviality of - # the p-primary part of Sha + # determine how much prec we need to prove at least the + # triviality of the p-primary part of Sha if prec == 0: n = max(v,2) @@ -701,33 +705,40 @@ def an_padic(self, p, prec=0, use_twists=True): def p_primary_bound(self, p): r""" - Returns a provable upper bound for the order of `Sha(E)(p)`. In particular, - if this algorithm does not fail, then it proves that the `p`-primary - part of `Sha` is finite. + Returns a provable upper bound for the order of the `p`-primary part + `Sha(E)(p)` of the Tate-Shafarevich group. In particular, if this + algorithm does not fail, then it proves that the `p`-primary part of `Sha` is finite. This works also for curves of rank > 1. INPUT: ``p`` -- a prime > 2 - OUTPUT: integer -- power of `p` that bounds the order of `Sha(E)(p)` from above + OUTPUT: integer -- power of `p` that bounds the order of `Sha(E)(p)` + from above - The result is a proven upper bound on the order of `Sha(E)(p)`. - So in particular it proves it finiteness even if the rank of - the curve is larger than 1. Note also that this bound is sharp - if one assumes the main conjecture of Iwasawa theory of - elliptic curves (and this is known in certain cases). + Note also that this bound is sharp if one assumes the main conjecture + of Iwasawa theory of elliptic curves (and this is known in certain cases). - Currently the algorithm is only implemented when certain conditions are verified. + Currently the algorithm is only implemented when certain conditions + are verified. - - The mod `p` Galois representation must be surjective. + - The `p`-adic Galois representation must be surjective or must have + its image contained in a Borel subgroup. - The reduction at `p` is not allowed to be additive. - - If the reduction at `p` is non-split multiplicative, then the rank has to be 0. - - If `p=3` then the reduction at 3 must be good ordinary or split multiplicative and the rank must be 0. + - If the reduction at `p` is non-split multiplicative, then the rank + has to be 0. + - If `p=3` then the reduction at 3 must be good ordinary or split + multiplicative and the rank must be 0. + The algorithm is described in [SW]_. The results for the reducible + case can be found in [Wu]_. The main ingredient is Kato's result on + the main conjecture in Iwasawa theory. EXAMPLES:: sage: e = EllipticCurve('11a3') sage: e.sha().p_primary_bound(3) 0 + sage: e.sha().p_primary_bound(5) + 0 sage: e.sha().p_primary_bound(7) 0 sage: e.sha().p_primary_bound(11) @@ -752,33 +763,41 @@ def p_primary_bound(self, p): OverflowError: Python int too large to convert to C long # 32-bit 0 # 64-bit - Some checks for :trac:`6406`:: + Some checks for :trac:`6406` and :trac:`123456`:: sage: e.sha().p_primary_bound(7) - Traceback (most recent call last): - ... - ValueError: The mod-p Galois representation is not surjective. Current knowledge about Euler systems does not provide an upper bound in this case. Try an_padic for a conjectural bound. - - sage: e.sha().an_padic(7) # long time (depends on "e.sha().p_primary_bound(3)" above) - Traceback (most recent call last): # 32-bit - ... # 32-bit - OverflowError: Python int too large to convert to C long # 32-bit - 7^2 + O(7^24) # 64-bit + 2 - sage: e = EllipticCurve('11a3') - sage: e.sha().p_primary_bound(5) + sage: E = EllipticCurve('608b1') + sage: E.sha().p_primary_bound(5) Traceback (most recent call last): ... - ValueError: The mod-p Galois representation is not surjective. Current knowledge about Euler systems does not provide an upper bound in this case. Try an_padic for a conjectural bound. - sage: e.sha().an_padic(5) + ValueError: The p-adic Galois representation is not surjective or reducible. Current knowledge about Euler systems does not provide an upper bound in this case. Try an_padic for a conjectural bound. + + sage: E.sha().an_padic(5) 1 + O(5^22) + + REFERENCES: + + .. [SW] William Stein and Christian Wuthrich, Algorithms + for the Arithmetic of Elliptic Curves using Iwasawa Theory + Mathematics of Computation 82 (2013), 1757-1792. + + .. [Wu] Christian Wuthrich, On the integrality of modular symbols and + Kato's Euler system for elliptic curves. Doc. Math. 19 (2014), + 381–402. + """ p = Integer(p) + if p == 2: + raise ValueError("The prime p must be odd.") E = self.Emin if E.is_ordinary(p) or E.is_good(p): - su = E.galois_representation().is_surjective(p) - if not su : - raise ValueError("The mod-p Galois representation is not surjective. Current knowledge about Euler systems does not provide an upper bound in this case. Try an_padic for a conjectural bound.") + rho = E.galois_representation() + su = rho.is_surjective(p) + re = rho.is_reducible(p) + if not su and not re : + raise ValueError("The p-adic Galois representation is not surjective or reducible. Current knowledge about Euler systems does not provide an upper bound in this case. Try an_padic for a conjectural bound.") shan = self.an_padic(p,prec = 0,use_twists=True) if shan == 0: raise RuntimeError("There is a bug in an_padic.") @@ -833,8 +852,8 @@ def bound_kolyvagin(self, D=0, regulator=None, INPUT: - - ``D`` - (optional) a fundamental discriminant < -4 that satisfies the - Heegner hypothesis for `E`; if not given, use the first such `D` + - ``D`` - (optional) a fundamental discriminant < -4 that satisfies + the Heegner hypothesis for `E`; if not given, use the first such `D` - ``regulator`` -- (optional) regulator of `E(K)`; if not given, will be computed (which could take a long time) - ``ignore_nonsurj_hypothesis`` (optional: default ``False``) -- @@ -984,38 +1003,42 @@ def bound_kolyvagin(self, D=0, regulator=None, def bound_kato(self): r""" - Returns a list `p` of primes such that the theorems of Kato's [Ka]_ - and others (e.g., as explained in a paper/thesis of Grigor - Grigorov [Gri]_) imply that if `p` divides the order of `Sha(E/\QQ)` then `p` is in + Returns a list of primes `p` such that the theorems of Kato's [Ka]_ + and others (e.g., as explained in a thesis of Grigor Grigorov [Gri]_) + imply that if `p` divides the order of `Sha(E/\QQ)` then `p` is in the list. If `L(E,1) = 0`, then this function gives no information, so it returns ``False``. - THEOREM (Kato): Suppose `L(E,1) \neq 0` and `p \neq 2, 3` is a prime such that + THEOREM: Suppose `L(E,1) \neq 0` and `p \neq 2` is a prime such + that - `E` does not have additive reduction at `p`, - - the mod-`p` representation is surjective. + - either the `p`-adic representation is surjective or has its + image contained in a Borel subgroup. - Then `{ord}_p(\#Sha(E))` divides `{ord}_p(L(E,1)\cdot\#E(\QQ)_{tor}^2/(\Omega_E \cdot \prod c_q))`. + Then `{ord}_p(\#Sha(E))` is bounded from above by the `p`-adic valuation of `L(E,1)\cdot\#E(\QQ)_{tor}^2 / (\Omega_E \cdot \prod c_v)`. + + If the L-series vanishes, the method ``p_primary_bound`` can be used instead. EXAMPLES:: sage: E = EllipticCurve([0, -1, 1, -10, -20]) # 11A = X_0(11) sage: E.sha().bound_kato() - [2, 3, 5] + [2] sage: E = EllipticCurve([0, -1, 1, 0, 0]) # X_1(11) sage: E.sha().bound_kato() - [2, 3, 5] + [2] sage: E = EllipticCurve([1,1,1,-352,-2689]) # 66B3 sage: E.sha().bound_kato() - [2, 3] + [2] For the following curve one really has that 25 divides the order of `Sha` (by Grigorov-Stein paper [GS]_):: sage: E = EllipticCurve([1, -1, 0, -332311, -73733731]) # 1058D1 sage: E.sha().bound_kato() # long time (about 1 second) - [2, 3, 5, 23] + [2, 5, 23] sage: E.galois_representation().non_surjective() # long time (about 1 second) [] @@ -1023,7 +1046,7 @@ def bound_kato(self): sage: E = EllipticCurve([0, 0, 0, -4062871, -3152083138]) # 3364C1 sage: E.sha().bound_kato() # long time (< 10 seconds) - [2, 3, 7, 29] + [2, 7, 29] No information about curves of rank > 0:: @@ -1038,18 +1061,24 @@ def bound_kato(self): applications arithmétiques III, Astérisque vol 295, SMF, Paris, 2004. - .. [Gri] + .. [Gri] G. Grigorov, Kato's Euler System and the Main Conjecture, + Harvard Ph.D. Thesis (2005). + + .. [GS] G. Grigorov, A. Jorza, S. Patrikis, C. Tarnita, and W. Stein, + Computational verification of the Birch and Swinnerton-Dyer + conjecture for individual elliptic curves, Math. Comp. 78 (2009), + 2397-2425. - .. [GS] """ E = self.Emin if E.has_cm(): return False if E.lseries().L1_vanishes(): return False - B = [2, 3] - for p in E.galois_representation().non_surjective(): - if p > 3: + B = [2] + rho = E.galois_representation() + for p in rho.non_surjective(): + if p > 2 and p not in rho.reducible_primes(): B.append(p) for p in E.conductor().prime_divisors(): if E.has_additive_reduction(p) and p not in B: @@ -1069,8 +1098,9 @@ def bound_kato(self): def bound(self): r""" Compute a provably correct bound on the order of the Tate-Shafarevich - group of this curve. The bound is either ``False`` (no bound) or a list - ``B`` of primes such that any divisor of `Sha` is in this list. + group of this curve. The bound is either ``False`` (no bound) or a + list ``B`` of primes such that any prime divisor of the order of `Sha` + is in this list. EXAMPLES:: From e20fe2691428bf33958cdc3a716a9f2248dde789 Mon Sep 17 00:00:00 2001 From: Chris Wuthrich Date: Wed, 10 Sep 2014 16:34:19 +0100 Subject: [PATCH 087/698] trac #16959: doctests for corrections in sha_tate --- src/sage/schemes/elliptic_curves/sha_tate.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sage/schemes/elliptic_curves/sha_tate.py b/src/sage/schemes/elliptic_curves/sha_tate.py index 8cf9e25aefe..45fe0d6e656 100644 --- a/src/sage/schemes/elliptic_curves/sha_tate.py +++ b/src/sage/schemes/elliptic_curves/sha_tate.py @@ -763,7 +763,7 @@ def p_primary_bound(self, p): OverflowError: Python int too large to convert to C long # 32-bit 0 # 64-bit - Some checks for :trac:`6406` and :trac:`123456`:: + Some checks for :trac:`6406` and :trac:`16959`:: sage: e.sha().p_primary_bound(7) 2 @@ -777,6 +777,10 @@ def p_primary_bound(self, p): sage: E.sha().an_padic(5) 1 + O(5^22) + sage: E = EllipticCurve("5040bi1") + sage: E.sha().p_primary_bound(5) # long time + 0 + REFERENCES: .. [SW] William Stein and Christian Wuthrich, Algorithms From 45eca3df3203644db640072e6aae8bc9d2592c93 Mon Sep 17 00:00:00 2001 From: Chris Wuthrich Date: Wed, 10 Sep 2014 22:34:25 +0100 Subject: [PATCH 088/698] trac #16959: adjusting doctests --- src/doc/en/bordeaux_2008/elliptic_curves.rst | 4 +-- src/sage/schemes/elliptic_curves/BSD.py | 33 +++++++++++++------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/doc/en/bordeaux_2008/elliptic_curves.rst b/src/doc/en/bordeaux_2008/elliptic_curves.rst index eec9bb6715f..880abd1446e 100644 --- a/src/doc/en/bordeaux_2008/elliptic_curves.rst +++ b/src/doc/en/bordeaux_2008/elliptic_curves.rst @@ -193,8 +193,8 @@ unpublished papers of Wuthrich and me. :: sage: E = EllipticCurve('11a1') - sage: E.sha().bound() # so only 2,3,5 could divide sha - [2, 3, 5] + sage: E.sha().bound() # so only 2 could divide sha + [2] sage: E = EllipticCurve('37a1') # so only 2 could divide sha sage: E.sha().bound() ([2], 1) diff --git a/src/sage/schemes/elliptic_curves/BSD.py b/src/sage/schemes/elliptic_curves/BSD.py index 0b26f34d59d..f496ccbd7b5 100644 --- a/src/sage/schemes/elliptic_curves/BSD.py +++ b/src/sage/schemes/elliptic_curves/BSD.py @@ -290,9 +290,9 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, Hautes Études Sci. Publ. Math. No. 47 (1977), 33--186 (1978). .. [Rubin] K. Rubin. The "main conjectures" of Iwasawa theory for imaginary quadratic fields. Invent. Math. 103 (1991), no. 1, 25--68. - .. [SteinWuthrich] W. Stein and C. Wuthrich. Computations about - Tate-Shafarevich groups using Iwasawa theory. - http://wstein.org/papers/shark, February 2008. + .. [SteinWuthrich] W Stein and C Wuthrich, Algorithms + for the Arithmetic of Elliptic Curves using Iwasawa Theory + Mathematics of Computation 82 (2013), 1757-1792. .. [SteinEtAl] G. Grigorov, A. Jorza, S. Patrikis, W. Stein, C. Tarniţǎ. Computational verification of the Birch and Swinnerton-Dyer conjecture for individual elliptic curves. @@ -302,21 +302,30 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, EXAMPLES:: sage: EllipticCurve('11a').prove_BSD(verbosity=2) - p = 2: True by 2-descent... + p = 2: True by 2-descent True for p not in {2, 5} by Kolyvagin. - True for p=5 by Mazur + Kato further implies that #Sha[5] is trivial. [] sage: EllipticCurve('14a').prove_BSD(verbosity=2) p = 2: True by 2-descent True for p not in {2, 3} by Kolyvagin. + Kato further implies that #Sha[3] is trivial. + [] + + sage: E = EllipticCurve("50b1") + sage: E.prove_BSD(verbosity=2) + p = 2: True by 2-descent + True for p not in {2, 3, 5} by Kolyvagin. + Kolyvagin's bound for p = 3 applies by Stein et al. + True for p = 3 by Kolyvagin bound Remaining primes: - p = 3: reducible, not surjective, good ordinary, divides a Tamagawa number + p = 5: reducible, not surjective, additive, divides a Tamagawa number (no bounds found) ord_p(#Sha_an) = 0 - [3] - sage: EllipticCurve('14a').prove_BSD(two_desc='simon') - [3] + [5] + sage: E.prove_BSD(two_desc='simon') + [5] A rank two curve:: @@ -336,9 +345,9 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, sage: E = EllipticCurve('19a') sage: E.prove_BSD(verbosity=2) - p = 2: True by 2-descent... + p = 2: True by 2-descent True for p not in {2, 3} by Kolyvagin. - True for p=3 by Mazur + Kato further implies that #Sha[3] is trivial. [] sage: E = EllipticCurve('37a') @@ -409,7 +418,7 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, sage: B.gens [] sage: B.primes - [7] + [] sage: B.heegner_indexes {-23: 2} From 93d45724d5f8451cf3320e1bde08eaf7fae71e67 Mon Sep 17 00:00:00 2001 From: Chris Wuthrich Date: Fri, 12 Sep 2014 14:01:23 +0100 Subject: [PATCH 089/698] trac #16959: change doctest for 32 bit --- src/sage/schemes/elliptic_curves/BSD.py | 2 +- src/sage/schemes/elliptic_curves/sha_tate.py | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/BSD.py b/src/sage/schemes/elliptic_curves/BSD.py index f496ccbd7b5..4106d138474 100644 --- a/src/sage/schemes/elliptic_curves/BSD.py +++ b/src/sage/schemes/elliptic_curves/BSD.py @@ -290,7 +290,7 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, Hautes Études Sci. Publ. Math. No. 47 (1977), 33--186 (1978). .. [Rubin] K. Rubin. The "main conjectures" of Iwasawa theory for imaginary quadratic fields. Invent. Math. 103 (1991), no. 1, 25--68. - .. [SteinWuthrich] W Stein and C Wuthrich, Algorithms + .. [SteinWuthrich] W. Stein and C. Wuthrich, Algorithms for the Arithmetic of Elliptic Curves using Iwasawa Theory Mathematics of Computation 82 (2013), 1757-1792. .. [SteinEtAl] G. Grigorov, A. Jorza, S. Patrikis, W. Stein, diff --git a/src/sage/schemes/elliptic_curves/sha_tate.py b/src/sage/schemes/elliptic_curves/sha_tate.py index 45fe0d6e656..e5b3de7701c 100644 --- a/src/sage/schemes/elliptic_curves/sha_tate.py +++ b/src/sage/schemes/elliptic_curves/sha_tate.py @@ -765,8 +765,11 @@ def p_primary_bound(self, p): Some checks for :trac:`6406` and :trac:`16959`:: - sage: e.sha().p_primary_bound(7) - 2 + sage: e.sha().p_primary_bound(7) # long time + Traceback (most recent call last): # 32-bit + ... # 32-bit + OverflowError: Python int too large to convert to C long # 32-bit + 2 # 64-bit sage: E = EllipticCurve('608b1') sage: E.sha().p_primary_bound(5) @@ -774,7 +777,7 @@ def p_primary_bound(self, p): ... ValueError: The p-adic Galois representation is not surjective or reducible. Current knowledge about Euler systems does not provide an upper bound in this case. Try an_padic for a conjectural bound. - sage: E.sha().an_padic(5) + sage: E.sha().an_padic(5) # long time 1 + O(5^22) sage: E = EllipticCurve("5040bi1") From 6b5a4c4f5b675fd2e42561c9ed7c145215ae17d8 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Sun, 14 Sep 2014 13:26:58 +0100 Subject: [PATCH 090/698] Normalize polynomials after fast_map to avoid segfault --- src/sage/libs/singular/polynomial.pyx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sage/libs/singular/polynomial.pyx b/src/sage/libs/singular/polynomial.pyx index 5d4319639f7..e2912b1ec5e 100644 --- a/src/sage/libs/singular/polynomial.pyx +++ b/src/sage/libs/singular/polynomial.pyx @@ -27,6 +27,7 @@ from sage.libs.singular.decl cimport n_Delete, idInit, fast_map, id_Delete from sage.libs.singular.decl cimport omAlloc0, omStrDup, omFree from sage.libs.singular.decl cimport p_GetComp, p_SetComp from sage.libs.singular.decl cimport pSubst +from sage.libs.singular.decl cimport p_Normalize from sage.libs.singular.singular cimport sa2si, si2sa, overflow_check @@ -157,6 +158,9 @@ cdef int singular_polynomial_call(poly **ret, poly *p, ring *r, list args, poly cdef ideal *res_id = fast_map(from_id, r, to_id, r) ret[0] = res_id.m[0] + # Unsure why we have to normalize here. See #16958 + p_Normalize(ret[0], r) + from_id.m[0] = NULL res_id.m[0] = NULL From 377220e947cf36ab019af2d243db89441a64ee7e Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Sun, 14 Sep 2014 13:58:44 +0100 Subject: [PATCH 091/698] Doctest that the memory leak is gone --- src/sage/libs/singular/polynomial.pyx | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/sage/libs/singular/polynomial.pyx b/src/sage/libs/singular/polynomial.pyx index e2912b1ec5e..4851919a944 100644 --- a/src/sage/libs/singular/polynomial.pyx +++ b/src/sage/libs/singular/polynomial.pyx @@ -145,6 +145,26 @@ cdef int singular_polynomial_call(poly **ret, poly *p, ring *r, list args, poly sage: (3*x*z)(x,x,x) 3*x^2 + + Test that there is no memory leak in evaluating polynomials. Note + that (lib)Singular has pre-allocated buckets, so we have to run a + lot of iterations to fill those up first:: + + sage: import resource + sage: import gc + sage: F. = GF(7^2) + sage: R. = F[] + sage: p = x+2*y + sage: def leak(N): + ....: before = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss + ....: gc.collect() + ....: for i in range(N): + ....: _ = p(a, a) + ....: after = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss + ....: return (after - before) * 1024 # ru_maxrss is in kilobytes + sage: _ = leak(50000) # warmup and fill up pre-allocated buckets + sage: leak(10000) + 0 """ cdef long l = len(args) cdef ideal *to_id = idInit(l,1) From 431acb6362656c099dfa262fb5ee7d06cb310e64 Mon Sep 17 00:00:00 2001 From: kcrisman Date: Mon, 15 Sep 2014 12:31:49 -0400 Subject: [PATCH 092/698] Trivial fix for typesetting line_graph.py Missing colon. --- src/sage/graphs/line_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/line_graph.py b/src/sage/graphs/line_graph.py index c9de934d4bf..3b0af720827 100644 --- a/src/sage/graphs/line_graph.py +++ b/src/sage/graphs/line_graph.py @@ -190,7 +190,7 @@ def is_line_graph(g, certificate = False): True The Petersen Graph not being claw-free, it is not a line - graph: + graph:: sage: graphs.PetersenGraph().is_line_graph() False From 27b4e34ac45bf1d847bf947e2183841dcb8e71a1 Mon Sep 17 00:00:00 2001 From: kcrisman Date: Mon, 15 Sep 2014 14:22:11 -0400 Subject: [PATCH 093/698] Minor typesetting issue in graph.py Code should have two backticks, not one. --- src/sage/graphs/graph.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index a946bcb5557..51585edea5d 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -6340,11 +6340,11 @@ def is_prime(self): r""" Tests whether the current graph is prime. A graph is prime if all its modules are trivial (i.e. empty, all of the graph or - singletons)-- see `self.modular_decomposition?`. + singletons)-- see ``self.modular_decomposition?``. EXAMPLE: - The Petersen Graph and the Bull Graph are both prime :: + The Petersen Graph and the Bull Graph are both prime:: sage: graphs.PetersenGraph().is_prime() True From d93512419089b35d11d0c05a3533a80eb41a5790 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sat, 20 Sep 2014 17:30:52 -0700 Subject: [PATCH 094/698] Expanded coercions between quotient rings. --- src/sage/rings/quotient_ring.py | 49 +++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/quotient_ring.py b/src/sage/rings/quotient_ring.py index 915ed18d8d4..9c487ff3b30 100644 --- a/src/sage/rings/quotient_ring.py +++ b/src/sage/rings/quotient_ring.py @@ -994,7 +994,7 @@ def _element_constructor_(self, x, coerce=True): def _coerce_map_from_(self, R): """ - Returns ``True`` if there is a coercion map from ``R`` to ``self``. + Return ``True`` if there is a coercion map from ``R`` to ``self``. EXAMPLES:: @@ -1009,8 +1009,53 @@ def _coerce_map_from_(self, R): False sage: T.has_coerce_map_from(R) True + + TESTS: + + We check that :trac:`13682` is fixed:: + + sage: R. = PolynomialRing(QQ) + sage: I = R.ideal(x^2+y^2) + sage: J = R.ideal(x^2+y^2, x^3 - y) + sage: I < J + True + sage: S = R.quotient(I) + sage: T = R.quotient(J) + sage: T.has_coerce_map_from(S) + True + sage: S.quotient_ring(x^4-x*y+1).has_coerce_map_from(S) + True + sage: S.has_coerce_map_from(T) + False + + We also allow coercions with the cover rings:: + + sage: Rp. = PolynomialRing(ZZ) + sage: Ip = Rp.ideal(x^2+y^2) + sage: Jp = Rp.ideal(x^2+y^2, x^3 - y) + sage: Sp = Rp.quotient(Ip) + sage: Tp = Rp.quotient(Jp) + sage: R.has_coerce_map_from(Rp) + True + sage: Sp.has_coerce_map_from(Sp) + True + sage: T.has_coerce_map_from(Sp) + True + sage: Sp.has_coerce_map_from(T) + False """ - return self.cover_ring().has_coerce_map_from(R) + C = self.cover_ring() + if isinstance(R, QuotientRing_nc): + if C == R.cover_ring(): + if R.defining_ideal() <= self.defining_ideal(): + return True + elif C.has_coerce_map_from(R.cover_ring()): + try: + if R.defining_ideal().change_ring(C) <= self.defining_ideal(): + return True + except AttributeError: # Not all ideals have a change_ring + pass + return C.has_coerce_map_from(R) def __cmp__(self, other): r""" From bc111997c874e67e09dfbfe29e71118924fe4f9b Mon Sep 17 00:00:00 2001 From: Ben Hutz Date: Mon, 29 Sep 2014 20:29:52 -0400 Subject: [PATCH 095/698] implement canonical heights over number fields --- .../schemes/projective/projective_morphism.py | 27 +- .../schemes/projective/projective_point.py | 230 ++++++++++++------ 2 files changed, 170 insertions(+), 87 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 37b0a4e275c..cdf548559f8 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -1455,9 +1455,12 @@ def conjugate(self, M): def green_function(self, P, v, **kwds): r""" Evaluates the local Green's function at the place ``v`` for ``P`` with ``N`` terms of the - series or, in dimension 1, to within a given error bound. + series or, in dimension 1, to within a given error bound. Must be over a number field + or order of a number field. Note that this is abosolute local greens function + so is scaled by the degree of the base field. - Use ``v=0`` for the archimedean place. Must be over `\ZZ` or `\QQ`. + Use ``v=0`` for the archimedean place over `\QQ` or field embedding. Local places are prime ideals + for number fields or primes over `\QQ`. ALGORITHM: @@ -1493,20 +1496,18 @@ def green_function(self, P, v, **kwds): sage: f.green_function(P.point([1,1],False),0,N=30) 0.43288629610862338612700146098 """ - if self.base_ring() != ZZ and self.base_ring() != QQ: - raise TypeError("Must be ZZ or QQ") return(P.green_function(self, v, **kwds)) def canonical_height(self, P, **kwds): r""" - Evaluates the canonical height of ``P`` with respect to ``self``. Must be over `\ZZ` or `\QQ`. - + Evaluates the (absolute) canonical height of ``self`` with respect to ``F``. Must be over number field + or order of a number field. Specify either the number of terms of the series to evaluate or, in dimension 1, the error bound required. ALGORITHM: - The sum of the Green's function at the archimedean place and the places of bad reduction. + The sum of the Green's function at the archimedean places and the places of bad reduction. INPUT: @@ -1531,9 +1532,9 @@ def canonical_height(self, P, **kwds): sage: P. = ProjectiveSpace(ZZ,1) sage: H = Hom(P,P) sage: f = H([x^2+y^2,2*x*y]); - sage: f.canonical_height(P.point([5,4]),error_bound=0.001) + sage: f.canonical_height(P.point([5,4]), error_bound=0.001) 2.1970553519503404898926835324 - sage: f.canonical_height(P.point([2,1]),error_bound=0.001) + sage: f.canonical_height(P.point([2,1]), error_bound=0.001) 1.0984430632822307984974382955 Notice that preperiodic points may not be exactly 0:: @@ -1541,8 +1542,8 @@ def canonical_height(self, P, **kwds): sage: P. = ProjectiveSpace(QQ,1) sage: H = Hom(P,P) sage: f = H([x^2-29/16*y^2,y^2]); - sage: f.canonical_height(P.point([1,4]),N=60) - 1.2024186864216154694752186858e-18 + sage: f.canonical_height(P.point([1,4]), error_bound=0.000001) + 3.5711911601471793573322582827e-7 :: @@ -1551,11 +1552,9 @@ def canonical_height(self, P, **kwds): sage: H = Hom(X,X) sage: f = H([x^2,y^2,4*z^2]); sage: Q = X([4,4,1]) - sage: f.canonical_height(Q,badprimes=[2]) + sage: f.canonical_height(Q, badprimes=[2]) 0.0013538030870311431824555314882 """ - if self.base_ring() != ZZ and self.base_ring() != QQ: - raise TypeError("Must be ZZ or QQ") return(P.canonical_height(self, **kwds)) def global_height(self, prec=None): diff --git a/src/sage/schemes/projective/projective_point.py b/src/sage/schemes/projective/projective_point.py index 4c54016a6ad..236d9e32240 100644 --- a/src/sage/schemes/projective/projective_point.py +++ b/src/sage/schemes/projective/projective_point.py @@ -40,11 +40,16 @@ from sage.rings.infinity import infinity from sage.rings.arith import gcd, lcm, is_prime from sage.rings.integer_ring import ZZ +from sage.rings.fraction_field import FractionField +from sage.rings.morphism import RingHomomorphism_im_gens from sage.rings.number_field.order import is_NumberFieldOrder +from sage.rings.number_field.number_field_ideal import NumberFieldFractionalIdeal from sage.rings.padics.all import Qp from sage.rings.quotient_ring import QuotientRing_generic from sage.rings.rational_field import QQ -from sage.rings.real_mpfr import RealField, RR +from sage.rings.real_double import RDF +from sage.rings.real_mpfr import RealField, RR, is_RealField + from copy import copy from sage.schemes.generic.morphism import (SchemeMorphism, is_SchemeMorphism, @@ -698,12 +703,15 @@ def orbit(self,f,N,**kwds): Orb.append(Q) return(Orb) - def green_function(self, G,v, **kwds): + def green_function(self, G, v, **kwds): r""" Evaluates the local Green's function at the place ``v`` for ``self`` with ``N`` terms of the series - or, in dimension 1, to within the specified error bound. Defaults to ``N=10`` if no kwds provided + or, in dimension 1, to within the specified error bound. Defaults to ``N=10`` if no kwds provided. + Must be over a number field or order of a number field. Note that this is abosolute local greens function + so is scaled by the degree of the base field. - Use ``v=0`` for the archimedean place. Must be over `\ZZ` or `\QQ`. + Use ``v=0`` for the archimedean place over `\QQ` or field embedding. Local places are prime ideals + for number fields or primes over `\QQ`. ALGORITHM: @@ -713,7 +721,8 @@ def green_function(self, G,v, **kwds): - ``G`` - an endomorphism of self.codomain() - - ``v`` - non-negative integer. a place, use v=0 for the archimedean place + - ``v`` - a number field place or prime ideal. + Over `\QQ` v=0 (archimedean place) or a prime number kwds: @@ -729,22 +738,43 @@ def green_function(self, G,v, **kwds): Examples:: - sage: P.=ProjectiveSpace(QQ,1) - sage: H=Hom(P,P) - sage: f=H([x^2+y^2,x*y]); - sage: Q=P(5,1) + sage: P. = ProjectiveSpace(QQ,1) + sage: H = Hom(P,P) + sage: f = H([x^2+y^2,x*y]); + sage: Q = P(5,1) sage: f.green_function(Q,0,N=30) 1.6460930159932946233759277576 :: - sage: P.=ProjectiveSpace(QQ,1) - sage: H=Hom(P,P) - sage: f=H([x^2+y^2,x*y]); - sage: Q=P(5,1) + sage: P. = ProjectiveSpace(QQ,1) + sage: H = Hom(P,P) + sage: f = H([x^2+y^2,x*y]); + sage: Q = P(5,1) sage: Q.green_function(f,0,N=200,prec=200) 1.6460930160038721802875250367738355497198064992657997569827 + :: + + z = var('z') + K. = NumberField(z^3-z+2); + PS. = ProjectiveSpace(K,1) + H = Hom(PS,PS) + f = H([9*x^3-x*y^2+2*y^3,70*y^3]) + Q = PS.point([a/3,1]) + Q.canonical_height(f) + 4.8429437927327375677926472074 + + :: + + sage: K.=QuadraticField(2) + sage: PS. = ProjectiveSpace(QuadraticField(2),1) + sage: H = Hom(PS,PS) + sage: f = H([3*x^2+y^2,7*y^2]) + sage: Q = PS.point([w,1]) + sage: Q.canonical_height(f, error_bound=0.001) + 0.97271753666766452112216113784 + .. TODO:: error bounds for dimension > 1 @@ -752,19 +782,29 @@ def green_function(self, G,v, **kwds): N = kwds.get('N', None) #Get number of iterates (if entered) err = kwds.get('error_bound', None) #Get error bound (if entered) prec = kwds.get('prec', 100) #Get precision (if entered) - R=RealField(prec) + R = RealField(prec) + localht = R(0) + BR = FractionField(self.codomain().base_ring()) - if not (v == 0 or is_prime(v)): - raise ValueError("Invalid valuation (=%s) entered."%v) - if v == 0: + if not BR in _NumberFields: + raise NotImplementedError("Must be over a NumberField or a NumberField Order") + + #For QQ the 'flip-trick' works better over RR or Qp + if isinstance(v, (NumberFieldFractionalIdeal, RingHomomorphism_im_gens)): + K = BR + elif is_prime(v): + K = Qp(v, prec) + elif v == 0: K = R + v = BR.places(prec=prec)[0] else: - K = Qp(v, prec) + raise ValueError("Invalid valuation (=%s) entered."%v) #Coerce all polynomials in F into polynomials with coefficients in K - F=G.change_ring(K,False) + F = G.change_ring(K, False) d = F.degree() - D=F.codomain().ambient_space().dimension_relative() + D = F.codomain().ambient_space().dimension_relative() + P = self.change_ring(K, False) if err is not None: if D!=1: @@ -779,56 +819,73 @@ def green_function(self, G,v, **kwds): #compute maximum coefficient of polynomials of F C = R(G.global_height(prec)) - if v == 0: + if isinstance(v, RingHomomorphism_im_gens): log_fact = R(0) for i in range(2*d+1): log_fact += R(i+1).log() - B = max((R(res.abs()) - R(2*d).log() - (2*d-1)*C - log_fact).log().abs(), (C + R(d+1).log()).abs()) + B = max((R(v(res).abs()) - R(2*d).log() - (2*d-1)*C - log_fact).log().abs(), (C + R(d+1).log()).abs()) + elif BR == QQ: + B = max(R(v**(-(res.valuation(v)))).log() - ((2*d-1)*C).abs(), C.abs()) else: - B = max(R(res.abs()).log() - ((2*d-1)*C).abs(), C.abs()) + B = max(R(res.abs_non_arch(v)).log() - ((2*d-1)*C).abs(), C.abs()) N = R(B/(err*(d-1))).log(d).abs().ceil() elif N is None: - N=10 #default is to do 10 iterations - - #Coerce the coordinates into Q_v - self.normalize_coordinates() - if self.codomain().base_ring()==QQ: - self.clear_denominators() - P=self.change_ring(K,False) + N = 10 #default is to do 10 iterations #START GREEN FUNCTION CALCULATION - - g = R(0) - + if isinstance(v, RingHomomorphism_im_gens): #embedding for archimedean local height + # :: WARNING: If places is fed the default Sage precision of 53 bits, + # it uses Real or Complex Double Field in place of RealField(prec) or ComplexField(prec) + # the function is_RealField does not identify RDF as real, so we test for that ourselves. + for i in range(N+1): + Pv = [ (v(t).abs()) for t in P ] + m = -1 + + #compute the maximum absolute value of entries of a, and where it occurs + for n in range(D+1): + if Pv[n] > m: + j = n + m = Pv[n] + # add to sum for the Green's function + localht += ((1/R(d))**R(i))*(R(m).log()) + #get the next iterate + if i < N: + P.scale_by(1/P[j]) + P = F(P, False) + return (1/BR.absolute_degree())*localht + + #else - prime or prime ideal for non-archimedean for i in range(N+1): + if BR == QQ: + Pv = [ R(v**(-(t.valuation(v)))) for t in P ] + else: + Pv = [ R(t.abs_non_arch(v)) for t in P ] m = -1 #compute the maximum absolute value of entries of a, and where it occurs for n in range(D+1): - a_v = R(P[n].abs()) - if a_v > m: + if Pv[n] > m: j = n - m = a_v - - #add to Greens function - g += (1/R(d))**(i)*R(m).log() - - #normalize coordinates and evaluate - P.scale_by(1/P[j]) - P = F(P, check=False) - - return g - - def canonical_height(self,F, **kwds): + m = Pv[n] + # add to sum for the Green's function + localht += ((1/R(d))**R(i))*(R(m).log()) + #get the next iterate + if i < N: + P.scale_by(1/P[j]) + P = F(P, False) + return (1/BR.absolute_degree())*localht + + def canonical_height(self, F, **kwds): r""" - Evaluates the canonical height of ``self`` with respect to ``F``. Must be over `\ZZ` or `\QQ`. + Evaluates the (absolute) canonical height of ``self`` with respect to ``F``. Must be over number field + or order of a number field. Specify either the number of terms of the series to evaluate or, in dimension 1, the error bound required. ALGORITHM: - The sum of the Green's function at the archimedean place and the places of bad reduction. + The sum of the Green's function at the archimedean places and the places of bad reduction. INPUT: @@ -850,10 +907,10 @@ def canonical_height(self,F, **kwds): EXAMPLES:: - sage: P.=ProjectiveSpace(ZZ,1) - sage: H=Hom(P,P) - sage: f=H([x^2+y^2,2*x*y]); - sage: Q=P(2,1) + sage: P. = ProjectiveSpace(ZZ,1) + sage: H = Hom(P,P) + sage: f = H([x^2+y^2,2*x*y]); + sage: Q = P(2,1) sage: f.canonical_height(f(Q)) 2.1965476757927038111992627081 sage: f.canonical_height(Q) @@ -861,33 +918,60 @@ def canonical_height(self,F, **kwds): Notice that preperiodic points may not be exactly 0. :: - sage: P.=ProjectiveSpace(QQ,1) - sage: H=Hom(P,P) - sage: f=H([x^2-29/16*y^2,y^2]); - sage: Q=P(5,4) - sage: f.canonical_height(Q,N=30) - 1.4989058602918874235863427216e-9 + sage: P. = ProjectiveSpace(QQ,1) + sage: H = Hom(P,P) + sage: f = H([x^2-29/16*y^2,y^2]); + sage: Q = P(5,4) + sage: f.canonical_height(Q, N=30) + 1.4989058602918874235833076226e-9 :: - sage: P.=ProjectiveSpace(QQ,2) - sage: X=P.subscheme(x^2-y^2); - sage: H=Hom(X,X) - sage: f=H([x^2,y^2,30*z^2]); - sage: Q=X([4,4,1]) - sage: f.canonical_height(Q,badprimes=[2,3,5],prec=200) + sage: P. = ProjectiveSpace(QQ,2) + sage: X = P.subscheme(x^2-y^2); + sage: H = Hom(X,X) + sage: f = H([x^2,y^2,30*z^2]); + sage: Q = X([4,4,1]) + sage: f.canonical_height(Q, badprimes=[2,3,5], prec=200) 2.7054056208276961889784303469356774912979228770208655455481 """ - badprimes = kwds.pop("badprimes",None) - - if badprimes is None: - badprimes=F.primes_of_bad_reduction(0) - - h=self.green_function(F,0,**kwds) #arch Green function - for v in badprimes: - h+=self.green_function(F,v,**kwds) #non-arch Green functions + bad_primes = kwds.pop("badprimes", None) + prec = kwds.get("prec", 100) + K = FractionField(self.codomain().base_ring()) + + if not K in _NumberFields: + raise NotImplementedError("Must be over a NumberField or a NumberField Order") + + if bad_primes is None: + bad_primes = [] + for b in self: + if K == QQ: + bad_primes += b.denominator().prime_factors() + else: + bad_primes += b.denominator_ideal().prime_factors() + bad_primes += K(F.resultant()).support() + bad_primes = list(set(bad_primes)) + + R = RealField(prec) + h = R(0) + # Archimedean local heights + + emb = K.places(prec=prec) + for v in emb: + if is_RealField(v.codomain()) or v.codomain() is RDF: + dv = R(1) + else: + dv = R(2) + h += dv*self.green_function(F, v, **kwds) #arch Green function + # Non-Archimedean local heights + for v in bad_primes: + if K == QQ: + dv = R(1) + else: + dv = R(v.residue_class_degree() * v.absolute_ramification_index()) + h += dv * self.green_function(F, v, **kwds) #non-arch Green functions return h def global_height(self, prec=None): From aca71cb72ef80895a6228efde9965367152dba4f Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 1 Oct 2014 16:37:02 +0200 Subject: [PATCH 096/698] Upgrade to mpir-2.7.0-alpha12 --- build/pkgs/mpir/checksums.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/pkgs/mpir/checksums.ini b/build/pkgs/mpir/checksums.ini index a757f978179..e529988e9a6 100644 --- a/build/pkgs/mpir/checksums.ini +++ b/build/pkgs/mpir/checksums.ini @@ -1,4 +1,4 @@ tarball=mpir-VERSION.tar.bz2 -sha1=815fee928c9ba5f444457144dd037300cb8f4ca4 -md5=c57ab6a7dbf59a32b7feb714ccc068f4 -cksum=3594042083 +sha1=6a46071d007a5284dbb67c4db70306deeb3e6513 +md5=3e681b1e9401db089c956cd97c34d77b +cksum=1170656757 From 67babebcf82ac594043c634b8e63d4036c7818c6 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 1 Oct 2014 20:23:13 +0200 Subject: [PATCH 097/698] Fix doctests due to changed xgcd results --- src/sage/modular/modsym/manin_symbols.py | 30 ++++++++++++------------ src/sage/rings/integer.pyx | 8 +++---- src/sage/tests/book_stein_modform.py | 2 +- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/sage/modular/modsym/manin_symbols.py b/src/sage/modular/modsym/manin_symbols.py index 7e861b1be1f..710b84233ab 100644 --- a/src/sage/modular/modsym/manin_symbols.py +++ b/src/sage/modular/modsym/manin_symbols.py @@ -58,9 +58,9 @@ class ManinSymbolList_character(ManinSymbolList) import sage.modular.modsym.p1list as p1list import sage.modular.modsym.g1list as g1list import sage.modular.modsym.ghlist as ghlist -import sage.modular.modsym.modular_symbols -import sage.rings.arith as arith -import sage.rings.all as rings +from sage.rings.arith import xgcd, gcd +from sage.rings.all import Infinity +from sage.rings.all import ZZ, Integer from sage.structure.sage_object import SageObject @@ -609,7 +609,7 @@ def apply_T(self, j): else: s = -1 z = [] - a = rings.ZZ(k-2-i) + a = Integer(k-2-i) for j in range(k-2-i+1): m = self.index((j, u, v)) z.append((m, s * a.binomial(j))) @@ -652,7 +652,7 @@ def apply_TT(self, j): else: s = -1 z = [] - a = rings.ZZ(i) + a = Integer(i) for j in range(i+1): m = self.index((k-2-i+j, u, v)) z.append((m, s * a.binomial(j))) @@ -1164,7 +1164,7 @@ def apply_T(self, j): else: s = -r z = [] - a = rings.ZZ(k-2-i) + a = Integer(k-2-i) for j in range(k-2-i+1): m, r = self.index((j, u, v)) z.append((m, s * r * a.binomial(j))) @@ -1206,7 +1206,7 @@ def apply_TT(self, j): else: s = -r z = [] - a = rings.ZZ(i) + a = Integer(i) for j in range(i+1): m, r = self.index((k-2-i+j, u, v)) z.append((m, s * r * a.binomial(j))) @@ -1761,10 +1761,10 @@ def lift_to_sl2z(self, N=None): if N is None: N = self.level() if N == 1: - return [1,0,0,1] - c = self.u - d = self.v - g, z1, z2 = arith.XGCD(c,d) + return [ZZ.one(), ZZ.zero(), ZZ.zero(), ZZ.one()] + c = Integer(self.u) + d = Integer(self.v) + g, z1, z2 = xgcd(c,d) # We're lucky: z1*c + z2*d = 1. if g==1: @@ -1779,19 +1779,19 @@ def lift_to_sl2z(self, N=None): # compute prime-to-d part of m. while True: - g = arith.GCD(m,d) + g = gcd(m,d) if g == 1: break m //= g # compute prime-to-N part of m. while True: - g = arith.GCD(m,N); + g = gcd(m,N); if g == 1: break m //= g d += N*m - g, z1, z2 = arith.XGCD(c,d) + g, z1, z2 = xgcd(c,d) assert g==1 return [z2, -z1, c, d] @@ -1882,7 +1882,7 @@ def modular_symbol_rep(self): """ # TODO: It would likely be much better to do this slightly more directly from sage.modular.modsym.modular_symbols import ModularSymbol - x = ModularSymbol(self.__parent, self.i, 0, rings.infinity) + x = ModularSymbol(self.__parent, self.i, 0, Infinity) a,b,c,d = self.lift_to_sl2z() return x.apply([a,b,c,d]) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index c85ba09de39..058702ba172 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -5441,10 +5441,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): Output may differ with and without the ``minimal`` option:: - sage: 2._xgcd(-2) - (2, 1, 0) - sage: 2._xgcd(-2, minimal=True) - (2, 0, -1) + sage: 5._xgcd(6) + (1, -1, 1) + sage: 5._xgcd(6, minimal=True) + (1, 5, -4) Exhaustive tests, checking minimality conditions:: diff --git a/src/sage/tests/book_stein_modform.py b/src/sage/tests/book_stein_modform.py index 6657aee1412..e9a49f1f0df 100644 --- a/src/sage/tests/book_stein_modform.py +++ b/src/sage/tests/book_stein_modform.py @@ -92,7 +92,7 @@ (2,3), (2,5), (3,1), (3,2)] sage: M = ModularSymbols(2,2) sage: [x.lift_to_sl2z(2) for x in M.manin_generators()] -[[1, 0, 0, 1], [0, -1, 1, 0], [0, -1, 1, 1]] +[[1, 0, 0, 1], [0, -1, 1, 0], [1, 0, 1, 1]] sage: M = ModularSymbols(6,2) sage: x = M.manin_generators()[9] sage: x From 8c7fbbd95d470a15e3e57b4e2573685bd726a7bd Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 1 Oct 2014 20:29:00 +0200 Subject: [PATCH 098/698] Re-enable "not tested" test from #4357 --- src/sage/tests/book_stein_modform.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/sage/tests/book_stein_modform.py b/src/sage/tests/book_stein_modform.py index e9a49f1f0df..4aec68ada6f 100644 --- a/src/sage/tests/book_stein_modform.py +++ b/src/sage/tests/book_stein_modform.py @@ -2,12 +2,6 @@ This file contains a bunch of tests extracted from the published book 'Modular Forms: a Computational Approach' by William Stein, AMS 2007. -One doctest is commented out below, because it does not work in -Sage currently. The original answer in the book is wrong, but the -correct answer has been put in below. This is trac #4357. -""" - -""" sage: G = SL(2,ZZ); G Special Linear Group of degree 2 over Integer Ring sage: S, T = G.gens() @@ -549,9 +543,10 @@ q^2 - q^5 - 3*q^8 + 4*q^11 + O(q^14), q^3 - q^6 - q^9 - q^12 + O(q^14) ] - -sage: S.new_subspace().basis() # not tested -(q + q^2 - q^4 -q^5 - 3*q^8 - q^10 + 4*q^11 - 2*q^13 + O(q^14),) +sage: S.new_subspace().basis() +[ +q + q^2 - q^4 - q^5 - 3*q^8 - q^10 + 4*q^11 - 2*q^13 + O(q^14) +] sage: CuspForms(Gamma0(9),2) Cuspidal subspace of dimension 0 of Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(9) of From fa40d41412f940b81cbdef0e94d6f33be1913c4e Mon Sep 17 00:00:00 2001 From: Ben Hutz Date: Fri, 3 Oct 2014 10:30:57 -0400 Subject: [PATCH 099/698] errors bounds and local heights --- .../schemes/projective/projective_morphism.py | 59 +++++- .../schemes/projective/projective_point.py | 195 ++++++++---------- 2 files changed, 145 insertions(+), 109 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index cdf548559f8..c2c7ff0f91e 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -54,6 +54,7 @@ from sage.rings.finite_rings.integer_mod_ring import Zmod from sage.rings.fraction_field import FractionField from sage.rings.integer_ring import ZZ +from sage.rings.number_field.order import is_NumberFieldOrder from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.quotient_ring import QuotientRing_generic from sage.rings.rational_field import QQ @@ -67,6 +68,8 @@ from sage.misc.lazy_attribute import lazy_attribute from sage.schemes.projective.projective_morphism_helper import _fast_possible_periods import sys +from sage.categories.number_fields import NumberFields +_NumberFields = NumberFields() class SchemeMorphism_polynomial_projective_space(SchemeMorphism_polynomial): """ @@ -1533,9 +1536,9 @@ def canonical_height(self, P, **kwds): sage: H = Hom(P,P) sage: f = H([x^2+y^2,2*x*y]); sage: f.canonical_height(P.point([5,4]), error_bound=0.001) - 2.1970553519503404898926835324 + 2.1968861265644615969948765910 sage: f.canonical_height(P.point([2,1]), error_bound=0.001) - 1.0984430632822307984974382955 + 1.0982738378963519055996313540 Notice that preperiodic points may not be exactly 0:: @@ -1602,6 +1605,8 @@ def global_height(self, prec=None): .. TODO:: add heights to integer.pyx and remove special case """ + if self.domain().base_ring() not in _NumberFields and not is_NumberFieldOrder(self.domain().base_ring()): + raise TypeError("Must be over a Numberfield or a Numberfield Order") if self.domain().base_ring() == ZZ: if prec is None: R = RealField() @@ -1620,6 +1625,56 @@ def global_height(self, prec=None): H = max(H, h) return(H) + def local_height(self, v, prec=None): + r""" + Returns the maximum of the local heights of the coefficients in any + of the coordinate functions of ``self``. + + INPUT: + + - ``v`` -- a prime or prime ideal of the base ring + + - ``prec`` -- desired floating point precision (default: + default RealField precision). + + OUTPUT: + + - a real number + + EXAMPLES:: + + sage: P. = ProjectiveSpace(QQ,1) + sage: H = Hom(P,P) + sage: f = H([1/1331*x^2+1/4000*y^2,210*x*y]); + sage: f.local_height(1331) + 7.19368581839511 + + This function does not automatically normalize:: + + sage: P. = ProjectiveSpace(QQ,2) + sage: H = Hom(P,P) + sage: f = H([4*x^2+3/100*y^2,8/210*x*y,1/10000*z^2]); + sage: f.local_height(2) + 2.77258872223978 + sage: f.normalize_coordinates() + sage: f.local_height(2) + 0.000000000000000 + + :: + + sage: R. = PolynomialRing(QQ) + sage: K. = NumberField(z^2-2) + sage: P. = ProjectiveSpace(K,1) + sage: H = Hom(P,P) + sage: f = H([2*x^2 + w/3*y^2,1/w*y^2]) + sage: f.local_height(K.ideal(3)) + 1.09861228866811 + """ + K = FractionField(self.domain().base_ring()) + if K not in _NumberFields: + raise TypeError("Must be over a Numberfield or a Numberfield Order") + return max([K(c).local_height(v, prec) for f in self for c in f.coefficients()]) + def height_difference_bound(self, prec=None): r""" Returns an upper bound on the different bewtween the canonical height of a point with diff --git a/src/sage/schemes/projective/projective_point.py b/src/sage/schemes/projective/projective_point.py index 236d9e32240..a072e34c113 100644 --- a/src/sage/schemes/projective/projective_point.py +++ b/src/sage/schemes/projective/projective_point.py @@ -38,7 +38,7 @@ from sage.categories.number_fields import NumberFields _NumberFields = NumberFields() from sage.rings.infinity import infinity -from sage.rings.arith import gcd, lcm, is_prime +from sage.rings.arith import gcd, lcm, is_prime, binomial from sage.rings.integer_ring import ZZ from sage.rings.fraction_field import FractionField from sage.rings.morphism import RingHomomorphism_im_gens @@ -704,89 +704,15 @@ def orbit(self,f,N,**kwds): return(Orb) def green_function(self, G, v, **kwds): - r""" - Evaluates the local Green's function at the place ``v`` for ``self`` with ``N`` terms of the series - or, in dimension 1, to within the specified error bound. Defaults to ``N=10`` if no kwds provided. - Must be over a number field or order of a number field. Note that this is abosolute local greens function - so is scaled by the degree of the base field. - - Use ``v=0`` for the archimedean place over `\QQ` or field embedding. Local places are prime ideals - for number fields or primes over `\QQ`. - - ALGORITHM: - - See Exercise 5.29 and Figure 5.6 of ``The Arithmetic of Dynamics Systems``, Joseph H. Silverman, Springer, GTM 241, 2007. - - INPUT: - - - ``G`` - an endomorphism of self.codomain() - - - ``v`` - a number field place or prime ideal. - Over `\QQ` v=0 (archimedean place) or a prime number - - kwds: - - - ``N`` - positive integer. number of terms of the series to use - - - ``prec`` - positive integer, float point or p-adic precision, default: 100 - - - ``error_bound`` - a positive real number - - OUTPUT: - - - a real number - - Examples:: - - sage: P. = ProjectiveSpace(QQ,1) - sage: H = Hom(P,P) - sage: f = H([x^2+y^2,x*y]); - sage: Q = P(5,1) - sage: f.green_function(Q,0,N=30) - 1.6460930159932946233759277576 - - :: - - sage: P. = ProjectiveSpace(QQ,1) - sage: H = Hom(P,P) - sage: f = H([x^2+y^2,x*y]); - sage: Q = P(5,1) - sage: Q.green_function(f,0,N=200,prec=200) - 1.6460930160038721802875250367738355497198064992657997569827 - - :: - - z = var('z') - K. = NumberField(z^3-z+2); - PS. = ProjectiveSpace(K,1) - H = Hom(PS,PS) - f = H([9*x^3-x*y^2+2*y^3,70*y^3]) - Q = PS.point([a/3,1]) - Q.canonical_height(f) - 4.8429437927327375677926472074 - - :: - - sage: K.=QuadraticField(2) - sage: PS. = ProjectiveSpace(QuadraticField(2),1) - sage: H = Hom(PS,PS) - sage: f = H([3*x^2+y^2,7*y^2]) - sage: Q = PS.point([w,1]) - sage: Q.canonical_height(f, error_bound=0.001) - 0.97271753666766452112216113784 - - .. TODO:: - - error bounds for dimension > 1 - """ N = kwds.get('N', None) #Get number of iterates (if entered) err = kwds.get('error_bound', None) #Get error bound (if entered) prec = kwds.get('prec', 100) #Get precision (if entered) R = RealField(prec) localht = R(0) BR = FractionField(self.codomain().base_ring()) + GBR = G.change_ring(BR) #so the heights work - if not BR in _NumberFields: + if not BR in NumberFields(): raise NotImplementedError("Must be over a NumberField or a NumberField Order") #For QQ the 'flip-trick' works better over RR or Qp @@ -803,36 +729,54 @@ def green_function(self, G, v, **kwds): #Coerce all polynomials in F into polynomials with coefficients in K F = G.change_ring(K, False) d = F.degree() - D = F.codomain().ambient_space().dimension_relative() + dim = F.codomain().ambient_space().dimension_relative() P = self.change_ring(K, False) if err is not None: - if D!=1: - raise NotImplementedError("error bounds only for dimension 1") err = R(err) if not err>0: raise ValueError("Error bound (=%s) must be positive."%err) + if G.is_endomorphism() == False: + raise NotImplementedError("Error bounds only for endomorphisms") #if doing error estimates, compute needed number of iterates - res = F.resultant() - - #compute maximum coefficient of polynomials of F - C = R(G.global_height(prec)) - - if isinstance(v, RingHomomorphism_im_gens): - log_fact = R(0) - for i in range(2*d+1): - log_fact += R(i+1).log() - B = max((R(v(res).abs()) - R(2*d).log() - (2*d-1)*C - log_fact).log().abs(), (C + R(d+1).log()).abs()) - elif BR == QQ: - B = max(R(v**(-(res.valuation(v)))).log() - ((2*d-1)*C).abs(), C.abs()) + D = (dim + 1) * (d - 1) + 1 + #compute upper bound + if isinstance(v, RingHomomorphism_im_gens): #archimedean + ################do we need the image of v here #################################### + U = GBR.global_height(prec) + R(binomial(dim + d, d)).log() + else: #non-archimedean + U = GBR.local_height(v, prec) + + #compute lower bound - from explicit polynomials of Nullstellensatz + CR = G.codomain().ambient_space().coordinate_ring() + CR = CR.change_ring(BR) #.lift() only works over fields + I = CR.ideal(G.defining_polynomials()) + maxh=0 + for k in range(dim + 1): + CoeffPolys = (CR.gen(k) ** D).lift(I) + Res = 1 + h = 1 + for j in range(len(CoeffPolys)): + if CoeffPolys[j] != 0: + if isinstance(v, RingHomomorphism_im_gens): #archimedean + h = max([c.global_height(prec) for c in CoeffPolys[j].coefficients()]) + else: #non-archimedean + h = max([c.local_height(v, prec) for c in CoeffPolys[j].coefficients()]) + if h > maxh: + maxh=h + if isinstance(v, RingHomomorphism_im_gens): #archimedean + L = R(1 / ((dim + 1) * binomial(dim + D - d, D - d) * maxh)).abs().log() + else: #non-archimedean + L = abs(R(1 / maxh).log()) + C = max([U, L]) + if C != 0: + N = R(C/(err)).log(d).abs().ceil() else: - B = max(R(res.abs_non_arch(v)).log() - ((2*d-1)*C).abs(), C.abs()) - N = R(B/(err*(d-1))).log(d).abs().ceil() - + #############can we just return 0 ############################3 + N=5 elif N is None: N = 10 #default is to do 10 iterations - #START GREEN FUNCTION CALCULATION if isinstance(v, RingHomomorphism_im_gens): #embedding for archimedean local height # :: WARNING: If places is fed the default Sage precision of 53 bits, @@ -841,9 +785,9 @@ def green_function(self, G, v, **kwds): for i in range(N+1): Pv = [ (v(t).abs()) for t in P ] m = -1 - + #compute the maximum absolute value of entries of a, and where it occurs - for n in range(D+1): + for n in range(dim + 1): if Pv[n] > m: j = n m = Pv[n] @@ -856,15 +800,15 @@ def green_function(self, G, v, **kwds): return (1/BR.absolute_degree())*localht #else - prime or prime ideal for non-archimedean - for i in range(N+1): + for i in range(N + 1): if BR == QQ: - Pv = [ R(v**(-(t.valuation(v)))) for t in P ] + Pv = [ R(K(t).abs()) for t in P ] else: Pv = [ R(t.abs_non_arch(v)) for t in P ] m = -1 #compute the maximum absolute value of entries of a, and where it occurs - for n in range(D+1): + for n in range(dim + 1): if Pv[n] > m: j = n m = Pv[n] @@ -938,6 +882,7 @@ def canonical_height(self, F, **kwds): bad_primes = kwds.pop("badprimes", None) prec = kwds.get("prec", 100) + error_bound = kwds.get("error_bound", None) K = FractionField(self.codomain().base_ring()) if not K in _NumberFields: @@ -953,11 +898,14 @@ def canonical_height(self, F, **kwds): bad_primes += K(F.resultant()).support() bad_primes = list(set(bad_primes)) + emb = K.places(prec=prec) + num_places = len(emb) + len(bad_primes) + if not error_bound is None: + error_bound /= num_places R = RealField(prec) h = R(0) # Archimedean local heights - emb = K.places(prec=prec) for v in emb: if is_RealField(v.codomain()) or v.codomain() is RDF: dv = R(1) @@ -1009,16 +957,49 @@ def global_height(self, prec=None): sage: A([3,5*w+1,1]).global_height(prec=100) 2.4181409534757389986565376694 - .. TODO:: - - p-adic heights - """ if self.domain().base_ring() in _NumberFields or is_NumberFieldOrder(self.domain().base_ring()): return(max([self[i].global_height(prec) for i in range(self.codomain().ambient_space().dimension_relative()+1)])) else: - raise NotImplementedError("Must be over a Numberfield or a Numberfield Order") + raise TypeError("Must be over a Numberfield or a Numberfield Order") + + def local_height(self, v, prec=None): + r""" + Returns the maximum of the local heights of the coefficients in any + of the coordinate functions of ``self``. + + INPUT: + + - ``v`` -- a prime or prime ideal of the base ring + + - ``prec`` -- desired floating point precision (default: + default RealField precision). + + OUTPUT: + + - a real number + + EXAMPLES:: + + EXAMPLES:: + sage: P.=ProjectiveSpace(QQ,2) + sage: Q=P.point([4,4,1/150],False) + sage: Q.local_height(5) + 3.21887582486820 + + :: + + sage: P.=ProjectiveSpace(QQ,2) + sage: Q=P([4,1,30]) + sage: Q.local_height(2) + 0.693147180559945 + + """ + K = FractionField(self.domain().base_ring()) + if K not in _NumberFields: + raise("Must be over a Numberfield or a Numberfield Order") + return max([K(c).local_height(v, prec) for c in self]) def multiplier(self,f,n,check=True): r""" From 59af0821faaa86dd385cfd8f20715852bc8d04ff Mon Sep 17 00:00:00 2001 From: Ben Hutz Date: Sat, 4 Oct 2014 12:21:25 -0400 Subject: [PATCH 100/698] added local_heights to use in error_bounds --- .../schemes/projective/projective_morphism.py | 62 +++++-- .../schemes/projective/projective_point.py | 161 +++++++++++++----- 2 files changed, 171 insertions(+), 52 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index c2c7ff0f91e..24797955d74 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -1458,12 +1458,12 @@ def conjugate(self, M): def green_function(self, P, v, **kwds): r""" Evaluates the local Green's function at the place ``v`` for ``P`` with ``N`` terms of the - series or, in dimension 1, to within a given error bound. Must be over a number field - or order of a number field. Note that this is abosolute local greens function + series or to within a given error bound. Must be over a number field + or order of a number field. Note that this is absolute local greens function so is scaled by the degree of the base field. - Use ``v=0`` for the archimedean place over `\QQ` or field embedding. Local places are prime ideals - for number fields or primes over `\QQ`. + Use ``v=0`` for the archimedean place over `\QQ` or field embedding. Non-archimedean + places are prime ideals for number fields or primes over `\QQ`. ALGORITHM: @@ -1477,7 +1477,7 @@ def green_function(self, P, v, **kwds): kwds: - - ``N`` - positive integer. number of terms of the series to use + - ``N`` - positive integer. number of terms of the series to use, default: 10 - ``prec`` - positive integer, float point or p-adic precision, default: 100 @@ -1504,9 +1504,8 @@ def green_function(self, P, v, **kwds): def canonical_height(self, P, **kwds): r""" Evaluates the (absolute) canonical height of ``self`` with respect to ``F``. Must be over number field - or order of a number field. - Specify either the number of terms of the series to evaluate - or, in dimension 1, the error bound required. + or order of a number field. Specify either the number of terms of the series to evaluate or + the error bound required. ALGORITHM: @@ -1546,7 +1545,7 @@ def canonical_height(self, P, **kwds): sage: H = Hom(P,P) sage: f = H([x^2-29/16*y^2,y^2]); sage: f.canonical_height(P.point([1,4]), error_bound=0.000001) - 3.5711911601471793573322582827e-7 + 4.6394113279707749011644196028e-7 :: @@ -1627,7 +1626,7 @@ def global_height(self, prec=None): def local_height(self, v, prec=None): r""" - Returns the maximum of the local heights of the coefficients in any + Returns the maximum of the local height of the coefficients in any of the coordinate functions of ``self``. INPUT: @@ -1675,6 +1674,49 @@ def local_height(self, v, prec=None): raise TypeError("Must be over a Numberfield or a Numberfield Order") return max([K(c).local_height(v, prec) for f in self for c in f.coefficients()]) + def local_height_arch(self, i, prec=None): + r""" + Returns the maximum of the local height at the ``i``-th infinite place of the coefficients in any + of the coordinate functions of ``self``. + + INPUT: + + - ``i`` -- an integer + + - ``prec`` -- desired floating point precision (default: + default RealField precision). + + OUTPUT: + + - a real number + + EXAMPLES:: + + sage: P. = ProjectiveSpace(QQ,1) + sage: H = Hom(P,P) + sage: f = H([1/1331*x^2+1/4000*y^2,210*x*y]); + sage: f.local_height_arch(0) + 5.34710753071747 + + :: + + sage: R. = PolynomialRing(QQ) + sage: K. = NumberField(z^2-2) + sage: P. = ProjectiveSpace(K,1) + sage: H = Hom(P,P) + sage: f = H([2*x^2 + w/3*y^2,1/w*y^2]) + sage: f.local_height_arch(1) + 0.6931471805599453094172321214582 + """ + K = FractionField(self.domain().base_ring()) + if K not in _NumberFields: + raise TypeError("Must be over a Numberfield or a Numberfield Order") + if K == QQ: + return max([K(c).local_height_arch(prec=prec) for f in self for c in f.coefficients()]) + else: + return max([K(c).local_height_arch(i, prec=prec) for f in self for c in f.coefficients()]) + + def height_difference_bound(self, prec=None): r""" Returns an upper bound on the different bewtween the canonical height of a point with diff --git a/src/sage/schemes/projective/projective_point.py b/src/sage/schemes/projective/projective_point.py index a072e34c113..8435d996cf8 100644 --- a/src/sage/schemes/projective/projective_point.py +++ b/src/sage/schemes/projective/projective_point.py @@ -704,7 +704,51 @@ def orbit(self,f,N,**kwds): return(Orb) def green_function(self, G, v, **kwds): - N = kwds.get('N', None) #Get number of iterates (if entered) + r""" + Evaluates the local Green's function at the place ``v`` for ``P`` with ``N`` terms of the + series or to within a given error bound. Must be over a number field + or order of a number field. Note that this is absolute local greens function + so is scaled by the degree of the base field. + + Use ``v=0`` for the archimedean place over `\QQ` or field embedding. Non-archimedean + places are prime ideals for number fields or primes over `\QQ`. + + ALGORITHM: + + See Exercise 5.29 and Figure 5.6 of ``The Arithmetic of Dynamics Systems``, Joseph H. Silverman, Springer, GTM 241, 2007. + + INPUT: + + - ``P`` - a projective point + + - ``v`` - non-negative integer. a place, use v=0 for the archimedean place + + kwds: + + - ``N`` - positive integer. number of terms of the series to use, default: 10 + + - ``prec`` - positive integer, float point or p-adic precision, default: 100 + + - ``error_bound`` - a positive real number + + OUTPUT: + + - a real number + + EXAMPLES:: + + sage: K. = QuadraticField(3) + sage: P. = ProjectiveSpace(K,1) + sage: H = Hom(P,P) + sage: f = H([17*x^2+1/7*y^2,17*w*x*y]) + sage: f.green_function(P.point([w,2],False), K.places()[1]) + 1.7236334013785676107373093775 + sage: print f.green_function(P([2,1]), K.ideal(7), N=7) + 0.48647753726382832627633818586 + sage: print f.green_function(P([w,1]), K.ideal(17), error_bound=0.001) + -0.70761163353747779889947530309 + """ + N = kwds.get('N', 10) #Get number of iterates (if entered) err = kwds.get('error_bound', None) #Get error bound (if entered) prec = kwds.get('prec', 100) #Get precision (if entered) R = RealField(prec) @@ -743,61 +787,61 @@ def green_function(self, G, v, **kwds): D = (dim + 1) * (d - 1) + 1 #compute upper bound if isinstance(v, RingHomomorphism_im_gens): #archimedean - ################do we need the image of v here #################################### - U = GBR.global_height(prec) + R(binomial(dim + d, d)).log() + vindex = BR.places(prec=prec).index(v) + U = GBR.local_height_arch(vindex, prec=prec) + R(binomial(dim + d, d)).log() else: #non-archimedean - U = GBR.local_height(v, prec) + U = GBR.local_height(v, prec=prec) #compute lower bound - from explicit polynomials of Nullstellensatz - CR = G.codomain().ambient_space().coordinate_ring() - CR = CR.change_ring(BR) #.lift() only works over fields - I = CR.ideal(G.defining_polynomials()) - maxh=0 + CR = GBR.codomain().ambient_space().coordinate_ring() #.lift() only works over fields + I = CR.ideal(GBR.defining_polynomials()) + maxh = 0 for k in range(dim + 1): CoeffPolys = (CR.gen(k) ** D).lift(I) Res = 1 h = 1 - for j in range(len(CoeffPolys)): - if CoeffPolys[j] != 0: + for poly in CoeffPolys: + if poly != 0: + for c in poly.coefficients(): + Res = lcm(Res, c.denominator()) + for poly in CoeffPolys: + if poly != 0: if isinstance(v, RingHomomorphism_im_gens): #archimedean - h = max([c.global_height(prec) for c in CoeffPolys[j].coefficients()]) + if BR == QQ: + h = max([(Res*c).local_height_arch(prec=prec) for c in poly.coefficients()]) + else: + h = max([(Res*c).local_height_arch(vindex, prec=prec) for c in poly.coefficients()]) else: #non-archimedean - h = max([c.local_height(v, prec) for c in CoeffPolys[j].coefficients()]) - if h > maxh: - maxh=h + h = max([c.local_height(v, prec=prec) for c in poly.coefficients()]) + if h > maxh: + maxh=h if isinstance(v, RingHomomorphism_im_gens): #archimedean - L = R(1 / ((dim + 1) * binomial(dim + D - d, D - d) * maxh)).abs().log() + L = R(Res / ((dim + 1) * binomial(dim + D - d, D - d) * maxh)).log().abs() else: #non-archimedean - L = abs(R(1 / maxh).log()) + L = R(1 / maxh).log().abs() C = max([U, L]) if C != 0: N = R(C/(err)).log(d).abs().ceil() - else: - #############can we just return 0 ############################3 - N=5 - elif N is None: - N = 10 #default is to do 10 iterations + else: #we just need log||P||_v + N=1 + #START GREEN FUNCTION CALCULATION if isinstance(v, RingHomomorphism_im_gens): #embedding for archimedean local height - # :: WARNING: If places is fed the default Sage precision of 53 bits, - # it uses Real or Complex Double Field in place of RealField(prec) or ComplexField(prec) - # the function is_RealField does not identify RDF as real, so we test for that ourselves. for i in range(N+1): Pv = [ (v(t).abs()) for t in P ] m = -1 - #compute the maximum absolute value of entries of a, and where it occurs for n in range(dim + 1): if Pv[n] > m: j = n m = Pv[n] # add to sum for the Green's function - localht += ((1/R(d))**R(i))*(R(m).log()) + localht += ((1/R(d))**R(i)) * (R(m).log()) #get the next iterate if i < N: P.scale_by(1/P[j]) P = F(P, False) - return (1/BR.absolute_degree())*localht + return (1/BR.absolute_degree()) * localht #else - prime or prime ideal for non-archimedean for i in range(N + 1): @@ -806,26 +850,24 @@ def green_function(self, G, v, **kwds): else: Pv = [ R(t.abs_non_arch(v)) for t in P ] m = -1 - #compute the maximum absolute value of entries of a, and where it occurs for n in range(dim + 1): if Pv[n] > m: j = n m = Pv[n] # add to sum for the Green's function - localht += ((1/R(d))**R(i))*(R(m).log()) + localht += ((1/R(d))**R(i)) * (R(m).log()) #get the next iterate if i < N: P.scale_by(1/P[j]) P = F(P, False) - return (1/BR.absolute_degree())*localht + return (1/BR.absolute_degree()) * localht def canonical_height(self, F, **kwds): r""" Evaluates the (absolute) canonical height of ``self`` with respect to ``F``. Must be over number field - or order of a number field. - Specify either the number of terms of the series to evaluate or, in dimension 1, the error bound - required. + or order of a number field. Specify either the number of terms of the series to evaluate or + the error bound required. ALGORITHM: @@ -879,7 +921,6 @@ def canonical_height(self, F, **kwds): sage: f.canonical_height(Q, badprimes=[2,3,5], prec=200) 2.7054056208276961889784303469356774912979228770208655455481 """ - bad_primes = kwds.pop("badprimes", None) prec = kwds.get("prec", 100) error_bound = kwds.get("error_bound", None) @@ -904,8 +945,11 @@ def canonical_height(self, F, **kwds): error_bound /= num_places R = RealField(prec) h = R(0) - # Archimedean local heights + # Archimedean local heights + # :: WARNING: If places is fed the default Sage precision of 53 bits, + # it uses Real or Complex Double Field in place of RealField(prec) or ComplexField(prec) + # the function is_RealField does not identify RDF as real, so we test for that ourselves. for v in emb: if is_RealField(v.codomain()) or v.codomain() is RDF: dv = R(1) @@ -924,7 +968,7 @@ def canonical_height(self, F, **kwds): def global_height(self, prec=None): r""" - Returns the logarithmic height of the points. Must be over `\ZZ` or `\QQ`. + Returns the logarithmic height of the points. INPUT: @@ -959,14 +1003,13 @@ def global_height(self, prec=None): """ if self.domain().base_ring() in _NumberFields or is_NumberFieldOrder(self.domain().base_ring()): - return(max([self[i].global_height(prec) for i in range(self.codomain().ambient_space().dimension_relative()+1)])) + return(max([self[i].global_height(prec=prec) for i in range(self.codomain().ambient_space().dimension_relative()+1)])) else: raise TypeError("Must be over a Numberfield or a Numberfield Order") def local_height(self, v, prec=None): r""" - Returns the maximum of the local heights of the coefficients in any - of the coordinate functions of ``self``. + Returns the maximum of the local height of the coordinates of ``self``. INPUT: @@ -979,8 +1022,6 @@ def local_height(self, v, prec=None): - a real number - EXAMPLES:: - EXAMPLES:: sage: P.=ProjectiveSpace(QQ,2) @@ -994,12 +1035,48 @@ def local_height(self, v, prec=None): sage: Q=P([4,1,30]) sage: Q.local_height(2) 0.693147180559945 + """ + K = FractionField(self.domain().base_ring()) + if K not in _NumberFields: + raise("Must be over a Numberfield or a Numberfield Order") + return max([K(c).local_height(v, prec=prec) for c in self]) + + def local_height_arch(self, i, prec=None): + r""" + Returns the maximum of the local heights at the ``i``-th infinite place of ``self``. + + INPUT: + - ``i`` -- an integer + + - ``prec`` -- desired floating point precision (default: + default RealField precision). + + OUTPUT: + + - a real number + + EXAMPLES:: + + sage: P.=ProjectiveSpace(QQ,2) + sage: Q = P.point([4,4,1/150], False) + sage: Q.local_height_arch(0) + 1.38629436111989 + + :: + + sage: P.=ProjectiveSpace(QuadraticField(5, 'w'),2) + sage: Q = P.point([4,1,30], False) + sage: Q.local_height_arch(1) + 3.401197381662155375413236691607 """ K = FractionField(self.domain().base_ring()) if K not in _NumberFields: raise("Must be over a Numberfield or a Numberfield Order") - return max([K(c).local_height(v, prec) for c in self]) + if K == QQ: + return max([K(c).local_height_arch(prec=prec) for c in self]) + else: + return max([K(c).local_height_arch(i, prec=prec) for c in self]) def multiplier(self,f,n,check=True): r""" From 6dfb1cb1c6dc5704e2a8918cf2aeabdd8dbef69a Mon Sep 17 00:00:00 2001 From: Simon King Date: Sat, 4 Oct 2014 20:40:24 +0200 Subject: [PATCH 101/698] Make contains_biseq interruptible and add to its doc --- src/sage/misc/bounded_integer_sequences.pxd | 2 +- src/sage/misc/bounded_integer_sequences.pyx | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pxd b/src/sage/misc/bounded_integer_sequences.pxd index de2094a3c09..eb3debf23bf 100644 --- a/src/sage/misc/bounded_integer_sequences.pxd +++ b/src/sage/misc/bounded_integer_sequences.pxd @@ -35,7 +35,7 @@ cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2) # Is S1=S2+something? Does not check whether the sequences have the same # bound! -cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start) +cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start) except -2 # Returns the position *in S1* of S2 as a subsequence of S1[start:], or -1 # if S2 is not a subsequence. Does not check whether the sequences have the # same bound! diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index aac33237f9f..0445a9b3f78 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -253,15 +253,20 @@ cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2): """ return mpz_congruent_2exp_p(S1.data, S2.data, S2.bitsize) -cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start): +cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start) except -2: """ - Tests if bounded integer sequence S1[start:] contains a sub-sequence S2 + Tests if bounded integer sequence ``S1[start:]`` contains a sub-sequence ``S2`` INPUT: - ``S1``, ``S2`` -- two bounded integer sequences - ``start`` -- integer, start index + OUTPUT: + + Index ``i>=start`` such that ``S1[i:]`` starts with ``S2``, or ``-1`` if + ``S1`` does not contain ``S2``. + ASSUMPTION: - The two sequences must have equivalent bounds, i.e., the items on the @@ -324,7 +329,7 @@ cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start): # tmp may have trailing zeroes, and GMP can NOT cope with that! # Hence, we need to adjust the size later. (<__mpz_struct*>tmp)._mp_size = limb_size - for index from 0<=index<=S1.length-S2.length: + for index from start<=index<=S1.length-S2.length: limb_index = n>>times_mp_bits_per_limb # Adjust the number of limbs we are shifting bit_index = n&mod_mp_bits_per_limb From c5363e3cabdfb6515f9fc011662b6850eab0947a Mon Sep 17 00:00:00 2001 From: Ben Hutz Date: Mon, 6 Oct 2014 14:15:25 -0400 Subject: [PATCH 102/698] added todo block --- src/sage/schemes/projective/projective_point.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sage/schemes/projective/projective_point.py b/src/sage/schemes/projective/projective_point.py index 8435d996cf8..f7fbc9e2122 100644 --- a/src/sage/schemes/projective/projective_point.py +++ b/src/sage/schemes/projective/projective_point.py @@ -747,6 +747,9 @@ def green_function(self, G, v, **kwds): 0.48647753726382832627633818586 sage: print f.green_function(P([w,1]), K.ideal(17), error_bound=0.001) -0.70761163353747779889947530309 + + .. TODO:: Implement general p-adic extensions so that the flip trick can be used + for number fields. """ N = kwds.get('N', 10) #Get number of iterates (if entered) err = kwds.get('error_bound', None) #Get error bound (if entered) From c84dfb480fcd1e3517ec79dd48e7ecbe560eae22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 9 Oct 2014 21:50:39 +0200 Subject: [PATCH 103/698] trac #14786 lattice of flats of a matroid --- src/sage/matroids/matroid.pyx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 1818ea20983..e2abae893a2 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -2714,6 +2714,21 @@ cdef class Matroid(SageObject): """ return self.dual().flats(r) + def lattice_of_flats(self): + """ + Return the lattice of flats of the matroid. + + EXAMPLES:: + + sage: M = matroids.named_matroids.Fano() + sage: M.lattice_of_flats() + Finite lattice containing 16 elements + """ + from sage.combinat.posets.lattices import LatticePoset + F = [X for i in range(self.rank() + 1) + for X in self.flats(i)] + return LatticePoset((F, lambda x, y: x <= y)) + cpdef hyperplanes(self): """ Return the set of hyperplanes of the matroid. From b8eb28c0e7ddc26155d1c69d84c8f4de66ab4731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Sat, 11 Oct 2014 14:33:07 +0200 Subject: [PATCH 104/698] remove code deprecated in 6992, 9337, 11634, 11763, 12806, 13249 --- src/sage/functions/all.py | 2 +- src/sage/functions/special.py | 20 -- src/sage/geometry/polyhedron/base.py | 370 --------------------------- src/sage/graphs/generic_graph.py | 73 +----- src/sage/rings/real_mpfr.pyx | 17 -- src/sage/schemes/generic/divisor.py | 23 -- src/sage/symbolic/expression.pyx | 18 -- 7 files changed, 5 insertions(+), 518 deletions(-) diff --git a/src/sage/functions/all.py b/src/sage/functions/all.py index dd2650ad4a3..1534c6bcc19 100644 --- a/src/sage/functions/all.py +++ b/src/sage/functions/all.py @@ -33,7 +33,7 @@ spherical_bessel_J, spherical_bessel_Y, spherical_hankel1, spherical_hankel2, spherical_harmonic, - lngamma, error_fcn, elliptic_e, + error_fcn, elliptic_e, elliptic_f, elliptic_ec, elliptic_eu, elliptic_kc, elliptic_pi, elliptic_j, airy_ai, airy_bi) diff --git a/src/sage/functions/special.py b/src/sage/functions/special.py index 5190dcfb6f3..92016648717 100644 --- a/src/sage/functions/special.py +++ b/src/sage/functions/special.py @@ -1008,26 +1008,6 @@ def __init__(self): elliptic_pi = EllipticPi() - -def lngamma(t): - r""" - This method is deprecated, please use - :meth:`~sage.functions.other.log_gamma` instead. - - See the :meth:`~sage.functions.other.log_gamma` function for ' - documentation and examples. - - EXAMPLES:: - - sage: lngamma(RR(6)) - doctest:...: DeprecationWarning: The method lngamma() is deprecated. Use log_gamma() instead. - See http://trac.sagemath.org/6992 for details. - 4.78749174278205 - """ - from sage.misc.superseded import deprecation - deprecation(6992, "The method lngamma() is deprecated. Use log_gamma() instead.") - return log_gamma(t) - def error_fcn(t): r""" The complementary error function diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index 48f86e50fec..4089a6763dc 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -1014,188 +1014,6 @@ def Vrep_generator(self): for V in self.Vrepresentation(): yield V - def facial_adjacencies(self): - r""" - Return the list of face indices (i.e. indices of - H-representation objects) and the indices of faces adjacent to - them. - - .. NOTE:: - - Instead of working with face indices, it is recommended - that you use the H-representation objects directly (see - example). - - EXAMPLES:: - - sage: p = polytopes.permutahedron(4) - sage: p.facial_adjacencies()[0:3] - doctest:...: DeprecationWarning: - This method is deprecated. - Use self.Hrepresentation(i).neighbors() instead. - See http://trac.sagemath.org/11763 for details. - [[0, [1, 2, 5, 10, 12, 13]], [1, [0, 2, 5, 7, 9, 11]], [2, [0, 1, 10, 11]]] - sage: f0 = p.Hrepresentation(0) - sage: f0.index() == 0 - True - sage: f0_adjacencies = [f0.index(), [n.index() for n in f0.neighbors()]] - sage: p.facial_adjacencies()[0] == f0_adjacencies - True - """ - from sage.misc.superseded import deprecation - deprecation(11763, 'This method is deprecated. Use self.Hrepresentation(i).neighbors() instead.') - try: - return self._facial_adjacencies - except AttributeError: - self._facial_adjacencies = \ - [ [ h.index(), - [n.index() for n in h.neighbors()] - ] for h in self.Hrepresentation() ] - return self._facial_adjacencies - - def facial_incidences(self): - """ - Return the face-vertex incidences in the form `[f_i, [v_{i_0}, v_{i_1},\dots ,v_{i_2}]]`. - - .. NOTE:: - - Instead of working with face/vertex indices, it is - recommended that you use the - H-representation/V-representation objects directly (see - examples). Or use :meth:`incidence_matrix`. - - OUTPUT: - - The face indices are the indices of the H-representation - objects, and the vertex indices are the indices of the - V-representation objects. - - EXAMPLES:: - - sage: p = Polyhedron(vertices = [[5,0,0],[0,5,0],[5,5,0],[0,0,0],[2,2,5]]) - sage: p.facial_incidences() - doctest:...: DeprecationWarning: - This method is deprecated. Use self.Hrepresentation(i).incident() instead. - See http://trac.sagemath.org/11763 for details. - [[0, [0, 1, 3, 4]], - [1, [0, 1, 2]], - [2, [0, 2, 3]], - [3, [2, 3, 4]], - [4, [1, 2, 4]]] - - sage: f0 = p.Hrepresentation(0) - sage: f0.index() == 0 - True - sage: f0_incidences = [f0.index(), [v.index() for v in f0.incident()]] - sage: p.facial_incidences()[0] == f0_incidences - True - - sage: p.incidence_matrix().column(0) - (1, 1, 0, 1, 1) - sage: p.incidence_matrix().column(1) - (1, 1, 1, 0, 0) - sage: p.incidence_matrix().column(2) - (1, 0, 1, 1, 0) - sage: p.incidence_matrix().column(3) - (0, 0, 1, 1, 1) - sage: p.incidence_matrix().column(4) - (0, 1, 1, 0, 1) - """ - from sage.misc.superseded import deprecation - deprecation(11763, 'This method is deprecated. Use self.Hrepresentation(i).incident() instead.') - try: - return self._facial_incidences - except AttributeError: - self._facial_incidences = \ - [ [ h.index(), - [v.index() for v in h.incident()] - ] for h in self.Hrepresentation() ] - return self._facial_incidences - - def vertex_adjacencies(self): - """ - Return a list of vertex indices and their adjacent vertices. - - .. NOTE:: - - Instead of working with vertex indices, you can use the - V-representation objects directly (see examples). - - Two V-representation objects are adjacent if they generate a - (1-dimensional) face of the polyhedron. Examples are two - vertices of a polytope that bound an edge, or a vertex and a - ray of a polyhedron that generate a bounding half-line of the - polyhedron. See :meth:`vertex_adjacency_matrix` for a more - detailed discussion. - - OUTPUT: - - The vertex indices are the indices of the V-representation - objects. - - EXAMPLES:: - - sage: permuta3 = Polyhedron(vertices = Permutations([1,2,3,4])) - sage: permuta3.vertex_adjacencies()[0:3] - doctest:...: DeprecationWarning: - This method is deprecated. Use self.Vrepresentation(i).neighbors() instead. - See http://trac.sagemath.org/11763 for details. - [[0, [1, 2, 6]], [1, [0, 3, 7]], [2, [0, 4, 8]]] - sage: v0 = permuta3.Vrepresentation(0) - sage: v0.index() == 0 - True - sage: list( v0.neighbors() ) - [A vertex at (1, 2, 4, 3), A vertex at (1, 3, 2, 4), A vertex at (2, 1, 3, 4)] - sage: v0_adjacencies = [v0.index(), [v.index() for v in v0.neighbors()]] - sage: permuta3.vertex_adjacencies()[0] == v0_adjacencies - True - """ - from sage.misc.superseded import deprecation - deprecation(11763, 'This method is deprecated. Use self.Vrepresentation(i).neighbors() instead.') - try: - return self._vertex_adjacencies - except AttributeError: - self._vertex_adjacencies = \ - [ [ v.index(), - [n.index() for n in v.neighbors()] - ] for v in self.Vrepresentation() ] - return self._vertex_adjacencies - - def vertex_incidences(self): - """ - Return the vertex-face incidences in the form `[v_i, [f_{i_0}, f_{i_1},\dots ,f_{i_2}]]`. - - .. NOTE:: - - Instead of working with face/vertex indices, you can use - the H-representation/V-representation objects directly - (see examples). - - EXAMPLES:: - - sage: p = polytopes.n_simplex(3) - sage: p.vertex_incidences() - doctest:...: DeprecationWarning: - This method is deprecated. Use self.Vrepresentation(i).incident() instead. - See http://trac.sagemath.org/11763 for details. - [[0, [0, 1, 2]], [1, [0, 1, 3]], [2, [0, 2, 3]], [3, [1, 2, 3]]] - sage: v0 = p.Vrepresentation(0) - sage: v0.index() == 0 - True - sage: p.vertex_incidences()[0] == [ v0.index(), [h.index() for h in v0.incident()] ] - True - """ - from sage.misc.superseded import deprecation - deprecation(11763, 'This method is deprecated. Use self.Vrepresentation(i).incident() instead.') - try: - return self._vertex_incidences - except AttributeError: - self._vertex_incidences = \ - [ [ v.index(), - [h.index() for h in v.incident()] - ] for v in self.Vrepresentation() ] - return self._vertex_incidences - def inequality_generator(self): """ Return a generator for the defining inequalities of the @@ -1274,23 +1092,6 @@ def inequalities_list(self): """ return [list(x) for x in self.inequality_generator()] - def ieqs(self): - """ - Deprecated. Alias for inequalities() - - EXAMPLES:: - - sage: p3 = Polyhedron(vertices = Permutations([1,2,3,4])) - sage: p3.ieqs() == p3.inequalities() - doctest:...: DeprecationWarning: - This method is deprecated. Use inequalities() instead. - See http://trac.sagemath.org/11763 for details. - True - """ - from sage.misc.superseded import deprecation - deprecation(11763, 'This method is deprecated. Use inequalities() instead.') - return self.inequalities() - def equation_generator(self): """ Return a generator for the linear equations satisfied by the @@ -1347,29 +1148,6 @@ def equations_list(self): """ return [list(eq) for eq in self.equation_generator()] - def linearities(self): - """ - Deprecated. Use equations() instead. - Returns the linear constraints of the polyhedron. As with - inequalities, each constraint is given as [b -a1 -a2 ... an] - where for variables x1, x2,..., xn, the polyhedron satisfies - the equation b = a1*x1 + a2*x2 + ... + an*xn. - - EXAMPLES:: - - sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]]) - sage: test_p.linearities() - doctest:...: DeprecationWarning: - This method is deprecated. Use equations_list() instead. - See http://trac.sagemath.org/11763 for details. - [[-10, 1, 1, 1, 1]] - sage: test_p.linearities() == test_p.equations_list() - True - """ - from sage.misc.superseded import deprecation - deprecation(11763, 'This method is deprecated. Use equations_list() instead.') - return self.equations_list() - def vertices_list(self): """ Return a list of vertices of the polyhedron. @@ -2263,126 +2041,6 @@ def triangulate(self, engine='auto', connected=True, fine=False, regular=None, s pc.set_engine(engine) return pc.triangulate() - def triangulated_facial_incidences(self): - """ - Return a list of the form [face_index, [v_i_0, - v_i_1,...,v_i_{n-1}]] where the face_index refers to the - original defining inequality. For a given face, the - collection of triangles formed by each list of v_i should - triangulate that face. - - In dimensions greater than 3, this is computed by randomly - lifting each face up a dimension; this does not always work! - This should eventually be fixed by using lrs or another - program that computes triangulations. - - EXAMPLES: - - If the figure is already composed of triangles, then all is well:: - - sage: Polyhedron(vertices = [[5,0,0],[0,5,0],[5,5,0],[2,2,5]] - ... ).triangulated_facial_incidences() - doctest:...: DeprecationWarning: - This method is deprecated. Use triangulate() instead. - See http://trac.sagemath.org/11634 for details. - doctest:...: DeprecationWarning: - This method is deprecated. Use self.Hrepresentation(i).incident() instead. - See http://trac.sagemath.org/11763 for details. - [[0, [0, 1, 2]], [1, [0, 1, 3]], [2, [0, 2, 3]], [3, [1, 2, 3]]] - - Otherwise some faces get split up to triangles:: - - sage: Polyhedron(vertices = [[2,0,0],[4,1,0],[0,5,0],[5,5,0], - ... [1,1,0],[0,0,1]]).triangulated_facial_incidences() - doctest:...: DeprecationWarning: - This method is deprecated. Use triangulate() instead. - See http://trac.sagemath.org/11634 for details. - doctest:...: DeprecationWarning: - This method is deprecated. Use self.Vrepresentation(i).neighbors() instead. - See http://trac.sagemath.org/11763 for details. - [[0, [1, 2, 5]], [0, [2, 5, 3]], [0, [5, 3, 4]], [1, [0, 1, 2]], - [2, [0, 2, 3]], [3, [0, 3, 4]], [4, [0, 4, 5]], [5, [0, 1, 5]]] - """ - from sage.misc.superseded import deprecation - deprecation(11634, 'This method is deprecated. Use triangulate() instead.') - try: - return self._triangulated_facial_incidences - except AttributeError: - t_fac_incs = [] - for a_face in self.facial_incidences(): - vert_number = len(a_face[1]) - if vert_number == self.dim(): - t_fac_incs.append(a_face) - elif self.dim() >= 4: - lifted_verts = [] - for vert_index in a_face[1]: - lifted_verts.append(self.vertices()[vert_index] + - [randint(-vert_index,5000+vert_index + vert_number**2)]) - temp_poly = Polyhedron(vertices = lifted_verts) - for t_face in temp_poly.facial_incidences(): - if len(t_face[1]) != self.dim(): - print 'Failed for face: ' + str(a_face) - print 'Attempted simplicial face: ' + str(t_face) - print 'Attempted lifted vertices: ' + str(lifted_verts) - raise RuntimeError("triangulation failed") - normal_fdir = temp_poly.ieqs()[t_face[0]][-1] - if normal_fdir >= 0: - t_fac_verts = [temp_poly.vertices()[i] for i in t_face[1]] - proj_verts = [q[0:self.dim()] for q in t_fac_verts] - t_fac_incs.append([a_face[0], - [self.vertices().index(q) for q in proj_verts]]) - else: - vs = a_face[1][:] - adj = dict( (a[0], [p for p in a[1] if p in a_face[1]]) - for a in self.vertex_adjacencies() if a[0] in a_face[1]) - t = vs[0] - vs.remove(t) - ts = adj[t] - for v in ts: - vs.remove(v) - t_fac_incs.append([a_face[0], [t] + ts]) - while vs: - t = ts[0] - ts = ts[1:] - for v in adj[t]: - if v in vs: - vs.remove(v) - ts.append(v) - t_fac_incs.append([a_face[0], [t] + ts]) - break - self._triangulated_facial_incidences = t_fac_incs - return t_fac_incs - - def simplicial_complex(self): - """ - Return a simplicial complex from a triangulation of the polytope. - - Warning: This first triangulates the polytope using - ``triangulated_facial_incidences``, and this function may fail - in dimensions greater than 3, although it usually doesn't. - - OUTPUT: - - A simplicial complex. - - EXAMPLES:: - - sage: p = polytopes.cuboctahedron() - sage: sc = p.simplicial_complex() - doctest:...: DeprecationWarning: - This method is deprecated. Use triangulate().simplicial_complex() instead. - See http://trac.sagemath.org/11634 for details. - doctest:...: DeprecationWarning: - This method is deprecated. Use triangulate() instead. - See http://trac.sagemath.org/11634 for details. - sage: sc - Simplicial complex with 12 vertices and 20 facets - """ - from sage.misc.superseded import deprecation - deprecation(11634, 'This method is deprecated. Use triangulate().simplicial_complex() instead.') - from sage.homology.simplicial_complex import SimplicialComplex - return SimplicialComplex([x[1] for x in self.triangulated_facial_incidences()]) - @coerce_binop def Minkowski_sum(self, other): """ @@ -3545,34 +3203,6 @@ def _volume_lrs(self, verbose=False): raise ValueError("lrs did not return a volume") - def lrs_volume(self, verbose=False): - """ - Computes the volume of a polytope using lrs. - - OUTPUT: - - The volume, cast to RDF (although lrs seems to output a - rational value this must be an approximation in some cases). - - EXAMPLES:: - - sage: polytopes.n_cube(3).lrs_volume() #optional - lrs - doctest:...: DeprecationWarning: use volume(engine='lrs') instead - See http://trac.sagemath.org/13249 for details. - 8.0 - sage: (polytopes.n_cube(3)*2).lrs_volume() #optional - lrs - 64.0 - sage: polytopes.twenty_four_cell().lrs_volume() #optional - lrs - 2.0 - - REFERENCES: - - David Avis's lrs program. - """ - from sage.misc.superseded import deprecation - deprecation(13249, "use volume(engine='lrs') instead") - return self._volume_lrs(verbose=verbose) - @cached_method def volume(self, engine='auto', **kwds): """ diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 9697e52ad0d..d125fcdd48e 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -2003,8 +2003,6 @@ def loops(self, labels=True): INPUT: - - ``new`` -- deprecated - - ``labels`` -- whether returned edges have labels ((u,v,l)) or not ((u,v)). EXAMPLES:: @@ -2293,7 +2291,6 @@ def multiple_edges(self, to_undirected=False, labels=True): sage: G.multiple_edges(to_undirected=True) [(1, 2, 'h'), (2, 1, 'g')] """ - from sage.misc.superseded import deprecation multi_edges = [] if self._directed and not to_undirected: for v in self: @@ -11910,7 +11907,7 @@ def clustering_average(self): import networkx return networkx.average_clustering(self.networkx_graph(copy=False)) - def clustering_coeff(self, nodes=None, weight=False, return_vertex_weights=True): + def clustering_coeff(self, nodes=None, weight=False): r""" Returns the clustering coefficient for each vertex in ``nodes`` as a dictionary keyed by vertex. @@ -11938,10 +11935,6 @@ def clustering_coeff(self, nodes=None, weight=False, return_vertex_weights=True) a string it used the indicated edge property as weight. ``weight = True`` is equivalent to ``weight = 'weight'`` - - ``return_vertex_weights`` is a boolean ensuring backwards - compatibility with deprecated features of NetworkX 1.2. It - should be set to ``False`` for all production code. - EXAMPLES:: sage: (graphs.FruchtGraph()).clustering_coeff().values() @@ -11956,8 +11949,7 @@ def clustering_coeff(self, nodes=None, weight=False, return_vertex_weights=True) 7: 0.3333333333333333, 8: 0.0, 9: 0.3333333333333333, 10: 0.3333333333333333, 11: 0.0} - sage: (graphs.FruchtGraph()).clustering_coeff(weight=True, - ... return_vertex_weights=False) + sage: (graphs.FruchtGraph()).clustering_coeff(weight=True) {0: 0.3333333333333333, 1: 0.3333333333333333, 2: 0.0, 3: 0.3333333333333333, 4: 0.3333333333333333, 5: 0.3333333333333333, 6: 0.3333333333333333, @@ -11967,68 +11959,11 @@ def clustering_coeff(self, nodes=None, weight=False, return_vertex_weights=True) {0: 0.3333333333333333, 1: 0.3333333333333333, 2: 0.0} sage: (graphs.FruchtGraph()).clustering_coeff(nodes=[0,1,2], - ... weight=True, return_vertex_weights=False) + ... weight=True) {0: 0.3333333333333333, 1: 0.3333333333333333, 2: 0.0} - - TESTS: - - Doctests that demonstrate the deprecation of the two-dictionary - return value due to the NetworkX API change after 1.2. The - return_vertex_weights keyword is provided with a default value - of True for backwards compatibility with older versions of Sage. - When the deprecation period has expired and the keyword is - removed, these doctests should be removed as well. :: - - sage: (graphs.FruchtGraph()).clustering_coeff(weight=True, - ... return_vertex_weights=True) - doctest:...: DeprecationWarning: The option 'return_vertex_weights' - has been deprecated. Only offered for backwards compatibility with - NetworkX 1.2. - See http://trac.sagemath.org/12806 for details. - ({0: 0.3333333333333333, 1: 0.3333333333333333, 2: 0.0, - 3: 0.3333333333333333, 4: 0.3333333333333333, - 5: 0.3333333333333333, 6: 0.3333333333333333, - 7: 0.3333333333333333, 8: 0.0, 9: 0.3333333333333333, - 10: 0.3333333333333333, 11: 0.0}, {0: 0.08333333333333333, - 1: 0.08333333333333333, 2: 0.08333333333333333, - 3: 0.08333333333333333, 4: 0.08333333333333333, - 5: 0.08333333333333333, 6: 0.08333333333333333, - 7: 0.08333333333333333, 8: 0.08333333333333333, - 9: 0.08333333333333333, 10: 0.08333333333333333, - 11: 0.08333333333333333}) - - sage: (graphs.FruchtGraph()).clustering_coeff(nodes=[0, 1, 2], - ... weight=True, return_vertex_weights=True) - ({0: 0.3333333333333333, 1: 0.3333333333333333, 2: 0.0}, - {0: 0.3333333333333333, 1: 0.3333333333333333, - 2: 0.3333333333333333}) """ import networkx - if weight and return_vertex_weights: - # Running in compatibility mode with deprecated NetworkX 1.2 features - # All this code should be removed when the deprecation warning expires - from sage.misc.superseded import deprecation - deprecation(12806, "The option 'return_vertex_weights' has been " +\ - "deprecated. Only offered for backwards" +\ - " compatibility with NetworkX 1.2.") - G = self.networkx_graph(copy=False) - if G.is_directed(): - raise NetworkXError("Clustering algorithms are not defined for directed graphs.") - clusterc={} - weights={} - for v,d,t in networkx.cluster._triangles_and_degree_iter(G,nodes): - weights[v]=float(d*(d-1)) - if t==0: - clusterc[v]=0.0 - else: - clusterc[v]=t/float(d*(d-1)) - scale=1./sum(weights.itervalues()) - for v,w in weights.iteritems(): - weights[v]=w*scale - return clusterc,weights - - else: - return networkx.clustering(self.networkx_graph(copy=False), nodes, weight=weight) + return networkx.clustering(self.networkx_graph(copy=False), nodes, weight=weight) def cluster_transitivity(self): r""" diff --git a/src/sage/rings/real_mpfr.pyx b/src/sage/rings/real_mpfr.pyx index 92618c0e2ce..b334d1ca18b 100644 --- a/src/sage/rings/real_mpfr.pyx +++ b/src/sage/rings/real_mpfr.pyx @@ -4989,23 +4989,6 @@ cdef class RealNumber(sage.structure.element.RingElement): if (self._parent).__prec > SIG_PREC_THRESHOLD: sig_off() return x - def lngamma(self): - r""" - This method is deprecated, please use :meth:`.log_gamma` instead. - - See the :meth:`.log_gamma` method for documentation and examples. - - EXAMPLES:: - - sage: RR(6).lngamma() - doctest:...: DeprecationWarning: The method lngamma() is deprecated. Use log_gamma() instead. - See http://trac.sagemath.org/6992 for details. - 4.78749174278205 - """ - from sage.misc.superseded import deprecation - deprecation(6992, "The method lngamma() is deprecated. Use log_gamma() instead.") - return self.log_gamma() - def log_gamma(self): """ Return the logarithm of gamma of ``self``. diff --git a/src/sage/schemes/generic/divisor.py b/src/sage/schemes/generic/divisor.py index 90bec235a77..6457dcde5a5 100644 --- a/src/sage/schemes/generic/divisor.py +++ b/src/sage/schemes/generic/divisor.py @@ -442,26 +442,3 @@ def coefficient(self, P): except AttributeError: raise NotImplementedError - def coef(self,P): - r""" - Synonym for :meth:`coefficient` - - .. WARNING:: - - This method is deprecated. It will be removed in a future - release of Sage. Please use the ``coefficient(P)`` method - instead. - - EXAMPLES:: - - sage: x,y = AffineSpace(2, GF(5), names='xy').gens() - sage: C = Curve(y^2 - x^9 - x) - sage: pts = C.rational_points(); pts - [(0, 0), (2, 2), (2, 3), (3, 1), (3, 4)] - sage: D = C.divisor(pts[0]) - sage: D.coefficient(pts[0]) - 1 - """ - from sage.misc.superseded import deprecation - deprecation(9337, "This method is deprecated. It will be removed in a future release of Sage. Please use the coefficient() method instead.") - return self.coefficient(P) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 6325ba9e518..a09493cf0a3 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -148,7 +148,6 @@ from sage.rings.rational import Rational # Used for sqrt. from sage.misc.derivative import multi_derivative from sage.rings.infinity import AnInfinity, infinity, minus_infinity, unsigned_infinity from sage.misc.decorators import rename_keyword -from sage.misc.superseded import deprecated_function_alias from sage.structure.dynamic_class import dynamic_class # a small overestimate of log(10,2) @@ -7430,23 +7429,6 @@ cdef class Expression(CommutativeRingElement): sig_off() return new_Expression_from_GEx(self._parent, x) - def lgamma(self, hold=False): - """ - This method is deprecated, please use the ``.log_gamma()`` function instead. - - Log gamma function evaluated at self. - - EXAMPLES:: - - sage: x.lgamma() - doctest:...: DeprecationWarning: The lgamma() function is deprecated. Use log_gamma() instead. - See http://trac.sagemath.org/6992 for details. - log_gamma(x) - """ - from sage.misc.superseded import deprecation - deprecation(6992, "The lgamma() function is deprecated. Use log_gamma() instead.") - return self.log_gamma(hold=hold) - def log_gamma(self, hold=False): """ Return the log gamma function evaluated at self. From eba41f927de314879031785cb59cc74b4397a1f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Sat, 11 Oct 2014 18:35:01 +0200 Subject: [PATCH 105/698] remove code deprecated in 14101, 14261 --- src/sage/algebras/all.py | 2 +- src/sage/algebras/iwahori_hecke_algebra.py | 19 +---- src/sage/combinat/all.py | 3 - src/sage/combinat/ribbon.py | 82 ---------------------- src/sage/combinat/ribbon_shaped_tableau.py | 3 +- src/sage/combinat/ribbon_tableau.py | 41 ----------- src/sage/combinat/skew_tableau.py | 51 -------------- src/sage/modules/free_module_element.pyx | 57 --------------- 8 files changed, 4 insertions(+), 254 deletions(-) diff --git a/src/sage/algebras/all.py b/src/sage/algebras/all.py index d57f2461623..85fbff1b880 100644 --- a/src/sage/algebras/all.py +++ b/src/sage/algebras/all.py @@ -36,7 +36,7 @@ from group_algebra_new import GroupAlgebra -from iwahori_hecke_algebra import IwahoriHeckeAlgebra, IwahoriHeckeAlgebraT +from iwahori_hecke_algebra import IwahoriHeckeAlgebra from affine_nil_temperley_lieb import AffineNilTemperleyLiebTypeA lazy_import('sage.algebras.nil_coxeter_algebra', 'NilCoxeterAlgebra') diff --git a/src/sage/algebras/iwahori_hecke_algebra.py b/src/sage/algebras/iwahori_hecke_algebra.py index d826ae4f228..3bd17b63960 100644 --- a/src/sage/algebras/iwahori_hecke_algebra.py +++ b/src/sage/algebras/iwahori_hecke_algebra.py @@ -2270,23 +2270,6 @@ def to_T_basis(self, w): # \tau is the Hecke involution. return (-1)**w.length()*self.realization_of().Cp().to_T_basis(w).hash_involution() -def IwahoriHeckeAlgebraT(W, q1, q2=-1, base_ring=None, prefix="T"): - """ - TESTS:: - - sage: H = IwahoriHeckeAlgebraT("A2", 1) - doctest:...: DeprecationWarning: this class is deprecated. Use IwahoriHeckeAlgebra().T instead - See http://trac.sagemath.org/14261 for details. - """ - from sage.misc.superseded import deprecation - deprecation(14261,'this class is deprecated. Use IwahoriHeckeAlgebra().T instead') - if W not in CoxeterGroups(): - W = WeylGroup(W) - if base_ring is None: - base_ring = q1.parent() - q2 = base_ring(q2) - return IwahoriHeckeAlgebra(W, q1=q1, q2=q2, base_ring=base_ring).T(prefix=prefix) - from sage.structure.sage_object import register_unpickle_override register_unpickle_override('sage.algebras.iwahori_hecke_algebra', - 'IwahoriHeckeAlgebraT', IwahoriHeckeAlgebraT) + 'IwahoriHeckeAlgebraT', IwahoriHeckeAlgebra) diff --git a/src/sage/combinat/all.py b/src/sage/combinat/all.py index c71456a3985..8c3399c6ca4 100644 --- a/src/sage/combinat/all.py +++ b/src/sage/combinat/all.py @@ -85,9 +85,6 @@ from ribbon_shaped_tableau import RibbonShapedTableau, StandardRibbonShapedTableaux from ribbon_tableau import RibbonTableaux, RibbonTableau, MultiSkewTableaux, MultiSkewTableau, SemistandardMultiSkewTableaux from composition_tableau import CompositionTableau, CompositionTableaux -#deprecated -from ribbon import Ribbon, StandardRibbons - from sage.combinat.tableau_tuple import TableauTuple, StandardTableauTuple, TableauTuples, StandardTableauTuples from k_tableau import WeakTableau, WeakTableaux, StrongTableau, StrongTableaux diff --git a/src/sage/combinat/ribbon.py b/src/sage/combinat/ribbon.py index 39bc0a1f250..dcfc834a8b5 100644 --- a/src/sage/combinat/ribbon.py +++ b/src/sage/combinat/ribbon.py @@ -17,85 +17,3 @@ #***************************************************************************** from ribbon_shaped_tableau import RibbonShapedTableau, StandardRibbonShapedTableaux -def Ribbon(r): - """ - Deprecated in :trac:`14101`. Use :class:`RibbonShapedTableau` instead. - - EXAMPLES:: - - sage: sage.combinat.ribbon.Ribbon([[2,3],[1,4,5]]) - doctest:...: DeprecationWarning: this class is deprecated. Use RibbonShapedTableau instead - See http://trac.sagemath.org/14101 for details. - [[None, None, 2, 3], [1, 4, 5]] - """ - from sage.misc.superseded import deprecation - deprecation(14101, 'this class is deprecated. Use RibbonShapedTableau instead') - return RibbonShapedTableau(r) - -def StandardRibbons(shape=None): - """ - Deprecated in :trac:`14101`. Use :class:`RibbonShapedTableaux` instead. - - EXAMPLES:: - - sage: sage.combinat.ribbon.StandardRibbons([3,3,1]) - doctest:...: DeprecationWarning: this class is deprecated. Use StandardRibbonShapedTableaux instead - See http://trac.sagemath.org/14101 for details. - Standard ribbon tableaux of shape [3, 3, 1] - """ - from sage.misc.superseded import deprecation - deprecation(14101, 'this class is deprecated. Use StandardRibbonShapedTableaux instead') - return StandardRibbonShapedTableaux(shape) - -def from_shape_and_word(shape, word): - """ - This is deprecated in :trac:`14101`. Use instead - :meth:`StandardRibbonShapedTableaux.from_shape_and_word()`. - - EXAMPLES:: - - sage: sage.combinat.ribbon.from_shape_and_word([2,3],[1,2,3,4,5]) - doctest:...: DeprecationWarning: this function is deprecated. Use StandardRibbonShapedTableaux().from_shape_and_word instead - See http://trac.sagemath.org/14101 for details. - [[None, None, 1, 2], [3, 4, 5]] - """ - from sage.misc.superseded import deprecation - deprecation(14101,'this function is deprecated. Use StandardRibbonShapedTableaux().from_shape_and_word instead') - return StandardRibbonShapedTableaux().from_shape_and_word(shape, word) - -def from_permutation(p): - """ - This is deprecated in :trac:`14101`. Use instead - :meth:`StandardRibbonShapedTableaux.from_shape_and_word()`. - - EXAMPLES:: - - sage: sage.combinat.ribbon.from_permutation(Permutation([1, 2, 3])) - doctest:...: DeprecationWarning: this function is deprecated. Use StandardRibbonShapedTableaux().from_permutation instead - See http://trac.sagemath.org/14101 for details. - [[1, 2, 3]] - """ - from sage.misc.superseded import deprecation - deprecation(14101,'this function is deprecated. Use StandardRibbonShapedTableaux().from_permutation instead') - return StandardRibbonShapedTableaux().from_permutation(p) - -def StandardRibbons_shape(shape): - """ - This is deprecated in :trac:`14101`. Use instead - :class:`StandardRibbonShapedTableaux`. - - EXAMPLES:: - - sage: sage.combinat.ribbon.StandardRibbons_shape([3,3,1]) - doctest:...: DeprecationWarning: this class is deprecated. Use StandardRibbonShapedTableaux instead - See http://trac.sagemath.org/14101 for details. - Standard ribbon tableaux of shape [3, 3, 1] - """ - from sage.misc.superseded import deprecation - deprecation(14101,'this class is deprecated. Use StandardRibbonShapedTableaux instead') - return StandardRibbonShapedTableaux(shape) - -from sage.structure.sage_object import register_unpickle_override -register_unpickle_override('sage.combinat.ribbon', 'Ribbon_class', RibbonShapedTableau) -register_unpickle_override('sage.combinat.ribbon', 'StandardRibbons_shape', StandardRibbonShapedTableaux) - diff --git a/src/sage/combinat/ribbon_shaped_tableau.py b/src/sage/combinat/ribbon_shaped_tableau.py index 56c33fe5a3e..310c3251df5 100644 --- a/src/sage/combinat/ribbon_shaped_tableau.py +++ b/src/sage/combinat/ribbon_shaped_tableau.py @@ -18,7 +18,7 @@ from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation -from sage.combinat.skew_tableau import SkewTableau, StandardSkewTableaux, from_expr +from sage.combinat.skew_tableau import SkewTableau, StandardSkewTableaux from sage.combinat.tableau import TableauOptions from sage.combinat.permutation import Permutation, descents_composition_first, descents_composition_list, descents_composition_last from sage.combinat.skew_partition import SkewPartition @@ -416,4 +416,5 @@ def __iter__(self): from sage.structure.sage_object import register_unpickle_override register_unpickle_override('sage.combinat.ribbon', 'Ribbon_class', RibbonShapedTableau) +register_unpickle_override('sage.combinat.ribbon', 'StandardRibbons_shape', StandardRibbonShapedTableaux) diff --git a/src/sage/combinat/ribbon_tableau.py b/src/sage/combinat/ribbon_tableau.py index 9549c8e3629..5e0bf915858 100644 --- a/src/sage/combinat/ribbon_tableau.py +++ b/src/sage/combinat/ribbon_tableau.py @@ -1161,47 +1161,6 @@ def __iter__(self): restmp.append( S.from_shape_and_word(parts[i], w) ) yield self.element_class(self, restmp) -def from_expr(l): - """ - Deprecated in :trac:`14101`. Use instead :meth:`RibbonTableaux.from_expr()`. - - EXAMPLES:: - - sage: sage.combinat.ribbon_tableau.from_expr([[1,1],[[5],[3,4],[1,2]]]) - doctest:...: DeprecationWarning: from_expr is deprecated. Use RibbonTableaux().from_expr instead - See http://trac.sagemath.org/14101 for details. - [[None, 1, 2], [None, 3, 4], [5]] - """ - from sage.misc.superseded import deprecation - deprecation(14101, 'from_expr is deprecated. Use RibbonTableaux().from_expr instead') - return RibbonTableaux().from_expr(l) - -def RibbonTableaux_shapeweightlength(shape, weight, length): - """ - EXAMPLES:: - - sage: sage.combinat.ribbon_tableau.RibbonTableaux_shapeweightlength([[2,1],[]], [1,1,1], 1) - doctest:...: DeprecationWarning: this class is deprecated. Use RibbonTableaux instead - See http://trac.sagemath.org/14101 for details. - Ribbon tableaux of shape [2, 1] / [] and weight [1, 1, 1] with 1-ribbons - """ - from sage.misc.superseded import deprecation - deprecation(14101, 'this class is deprecated. Use RibbonTableaux instead') - return RibbonTableaux(shape, weight, length) - -def SemistandardMultiSkewTtableaux_shapeweight(shape, weight): - """ - EXAMPLES:: - - sage: sage.combinat.ribbon_tableau.SemistandardMultiSkewTtableaux_shapeweight([ [[2,1],[]], [[2,2],[1]] ], [2,2,2]) - doctest:...: DeprecationWarning: this class is deprecated. Use SemistandardMultiSkewTableaux instead - See http://trac.sagemath.org/14101 for details. - Semistandard multi skew tableaux of shape [[2, 1] / [], [2, 2] / [1]] and weight [2, 2, 2] - """ - from sage.misc.superseded import deprecation - deprecation(14101, 'this class is deprecated. Use SemistandardMultiSkewTableaux instead') - return SemistandardMultiSkewTableaux(shape, weight) - from sage.structure.sage_object import register_unpickle_override register_unpickle_override('sage.combinat.ribbon_tableau', 'RibbonTableau_class', RibbonTableau) register_unpickle_override('sage.combinat.ribbon_tableau', 'RibbonTableaux_shapeweightlength', RibbonTableaux) diff --git a/src/sage/combinat/skew_tableau.py b/src/sage/combinat/skew_tableau.py index eb92129c4b6..998c70b170a 100644 --- a/src/sage/combinat/skew_tableau.py +++ b/src/sage/combinat/skew_tableau.py @@ -2128,57 +2128,6 @@ def __iter__(self): for x in RibbonTableaux_shape_weight_length(self.p, self.mu, 1): yield self.element_class(self, x._list) -################ -# Deprecations # -################ - -def from_expr(expr): - """ - Deprecated in :trac:`14101`. Use instead :meth:`SkewTableaux.from_expr()`. - - EXAMPLES:: - - sage: sage.combinat.skew_tableau.from_expr([[1,1],[[5],[3,4],[1,2]]]) - doctest:...: DeprecationWarning: from_expr is deprecated. Use SkewTableaux().from_expr instead - See http://trac.sagemath.org/14101 for details. - [[None, 1, 2], [None, 3, 4], [5]] - """ - from sage.misc.superseded import deprecation - deprecation(14101, 'from_expr is deprecated. Use SkewTableaux().from_expr instead') - return SkewTableaux().from_expr(expr) - -def from_shape_and_word(shape, word): - """ - Deprecated in :trac:`14101`. Use instead - :meth:`SkewTableaux.from_shape_and_word()`. - - EXAMPLES:: - - sage: t = SkewTableau([[None, 1, 3], [None, 2], [4]]) - sage: shape = t.shape() - sage: word = t.to_word() - sage: sage.combinat.skew_tableau.from_shape_and_word(shape, word) - doctest:...: DeprecationWarning: from_shape_and_word is deprecated. Use SkewTableaux().from_shape_and_word instead - See http://trac.sagemath.org/14101 for details. - [[None, 1, 3], [None, 2], [4]] - """ - from sage.misc.superseded import deprecation - deprecation(14101, 'from_shape_and_word is deprecated. Use SkewTableaux().from_shape_and_word instead') - return SkewTableaux().from_shape_and_word(shape, word) - -def StandardSkewTableaux_skewpartition(skp): - """ - EXAMPLES:: - - sage: sage.combinat.skew_tableau.StandardSkewTableaux_skewpartition([[1],[]]) - doctest:...: DeprecationWarning: this class is deprecated. Use StandardSkewTableaux_shape instead - See http://trac.sagemath.org/14101 for details. - Standard skew tableaux of shape [1] / [] - """ - from sage.misc.superseded import deprecation - deprecation(14101,'this class is deprecated. Use StandardSkewTableaux_shape instead') - return StandardSkewTableaux(skp) - # October 2012: fixing outdated pickles which use the classes being deprecated from sage.structure.sage_object import register_unpickle_override register_unpickle_override('sage.combinat.skew_tableau', 'StandardSkewTableaux_n', StandardSkewTableaux_size) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 9433759c8de..d26036d1efb 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -1116,44 +1116,6 @@ cdef class FreeModuleElement(element_Vector): # abstract base class """ return vector([e.n(prec, digits, algorithm) for e in self]) - def transpose(self): - r""" - Return self as a column matrix. - - .. note:: - - The ``transpose()`` method has been deprecated as of Sage 4.6.2, - in favor of the :meth:`column` method which is functionally identical. - - EXAMPLES:: - - sage: v = vector(ZZ, [2, 12, 22]) - sage: transpose(vector(v)) - doctest:...: DeprecationWarning: The transpose() method for vectors has been deprecated, use column() instead - (or check to see if you have a vector when you really want a matrix) - See http://trac.sagemath.org/10541 for details. - [ 2] - [12] - [22] - - :: - - sage: transpose(vector(GF(7), v)) - [2] - [5] - [1] - - :: - - sage: transpose(vector(v, ZZ['x', 'y'])) - [ 2] - [12] - [22] - """ - from sage.misc.superseded import deprecation - deprecation(10541, 'The transpose() method for vectors has been deprecated, use column() instead\n(or check to see if you have a vector when you really want a matrix)') - return self._matrix_().transpose() - def row(self): r""" Return a matrix with a single row and the same entries as the vector ``self``. @@ -2541,25 +2503,6 @@ cdef class FreeModuleElement(element_Vector): # abstract base class return (~self[i]) * self return self - def normalize(self): - """ - This function is deprecated. For division by the p-norm use - 'normalized', and for division by the first nonzero entry use - 'monic' (previously the purpose of this function). - - EXAMPLES:: - - sage: v = vector(QQ, [0, 4/3, 5, 1, 2]) - sage: v.normalize() - doctest:...: DeprecationWarning: 'normalize' is deprecated... - (0, 1, 15/4, 3/4, 3/2) - """ - from sage.misc.superseded import deprecation - deprecation(13393, "'normalize' is deprecated. For division by the \ -p-norm use 'normalized', and for division by the first nonzero entry use \ -'monic'.") - return self.monic() - def normalized(self, p=sage.rings.integer.Integer(2)): """ Return the input vector divided by the p-norm. From 429b5e3e2b04c0801a21162b6588aa2099bc01c1 Mon Sep 17 00:00:00 2001 From: Joao de Faria Date: Wed, 15 Oct 2014 21:33:48 -0400 Subject: [PATCH 106/698] Fixed logic to check for number fields --- src/sage/schemes/projective/projective_morphism.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 5506481b7d2..105804d2157 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -39,6 +39,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** +from sage.categories.number_fields import NumberFields from sage.categories.homset import Hom from sage.functions.all import sqrt from sage.libs.pari.gen import PariError @@ -1657,8 +1658,9 @@ def height_difference_bound(self, prec=None): sage: f.height_difference_bound() 10.7632079329219 """ - if self.domain().base_ring() != ZZ and self.domain().base_ring() != QQ: - raise NotImplementedError("Must be over ZZ or QQ") + BR = self.domain().base_ring() + if not BR in NumberFields: + raise NotImplemenetedError("Must be a number field") if not self.is_endomorphism(): raise NotImplementedError("Must be an endomorphism of projective space") if prec is None: @@ -1672,8 +1674,11 @@ def height_difference_bound(self, prec=None): U = self.global_height(prec) + R(binomial(N + d, d)).log() #compute lower bound - from explicit polynomials of Nullstellensatz CR = self.domain().coordinate_ring() - CR = CR.change_ring(QQ) #.lift() only works over fields - I = CR.ideal(self.defining_polynomials()) + try: + Def_polys = BR.defining_polynomial() + except AttributeError: + Def_polys = [] + I = CR.ideal(self.defining_polynomials(), Def_polys) MCP = [] for k in range(N + 1): CoeffPolys = (CR.gen(k) ** D).lift(I) From d4bdfcab040c79a63125695de8835e875ca9c236 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 16 Oct 2014 20:17:29 +0200 Subject: [PATCH 107/698] Calling the .n() method on reals shouldn't increase precision --- src/sage/functions/exp_integral.py | 12 ++-- src/sage/interfaces/tides.py | 14 ++--- src/sage/misc/functional.py | 75 +++++++++++++++++++----- src/sage/modules/free_module_element.pyx | 9 --- src/sage/rings/complex_number.pyx | 3 +- src/sage/rings/real_mpfr.pyx | 43 +++++++++++++- 6 files changed, 117 insertions(+), 39 deletions(-) diff --git a/src/sage/functions/exp_integral.py b/src/sage/functions/exp_integral.py index 521bd36a515..c5d6e76e692 100644 --- a/src/sage/functions/exp_integral.py +++ b/src/sage/functions/exp_integral.py @@ -996,8 +996,8 @@ def _evalf_(self, z, parent=None, algorithm=None): sage: N(cos_integral(1e23)) < 1e-20 True - sage: N(cos_integral(1e-10), digits=30) - -22.4486352650389235918737540487 + sage: N(cos_integral(10^-10), digits=30) + -22.4486352650389239795759024568 sage: cos_integral(ComplexField(100)(I)) 0.83786694098020824089467857943 + 1.5707963267948966192313216916*I @@ -1152,8 +1152,8 @@ def _evalf_(self, z, parent=None, algorithm=None): """ EXAMPLES:: - sage: N(sinh_integral(1e-10), digits=30) - 1.00000000000000003643219731550e-10 + sage: N(sinh_integral(10^-10), digits=30) + 1.00000000000000000000055555556e-10 sage: sinh_integral(ComplexField(100)(I)) 0.94608307036718301494135331382*I @@ -1289,8 +1289,8 @@ def _evalf_(self, z, parent=None, algorithm=None): """ EXAMPLES:: - sage: N(cosh_integral(1e-10), digits=30) - -22.4486352650389235918737540487 + sage: N(cosh_integral(10^-10), digits=30) + -22.4486352650389239795709024568 sage: cosh_integral(ComplexField(100)(I)) 0.33740392290096813466264620389 + 1.5707963267948966192313216916*I diff --git a/src/sage/interfaces/tides.py b/src/sage/interfaces/tides.py index 87451c8f031..6b97ca3e8e9 100644 --- a/src/sage/interfaces/tides.py +++ b/src/sage/interfaces/tides.py @@ -680,7 +680,7 @@ def genfiles_mpfr(integrator, driver, f, ics, initial, final, delta, sage: l[16] ' int nfun = 0;\n' sage: l[26] - '\tmpfr_set_str(v[2], "0.00000000000000000000000000000000000000000000000000", 10, TIDES_RND);\n' + '\tmpfr_set_str(v[2], "0", 10, TIDES_RND);\n' sage: l[30] '\tmpfr_init2(tolabs, TIDES_PREC); \n' sage: l[34] @@ -868,24 +868,24 @@ def genfiles_mpfr(integrator, driver, f, ics, initial, final, delta, outfile.write('\tfor(i=0; i 53 and CDF.has_coerce_map_from(B): + # If we can coerce to CDF, assume input precision was 53 bits + inprec = 53 + else: + # Otherwise, assume precision wasn't the issue + inprec = prec + + if prec > inprec: + raise TypeError("cannot approximate to a precision of %s bits, use at most %s bits" % (prec, inprec)) + + # The issue is not precision, try conversion instead + try: + return RR(x) + except (TypeError, ValueError): + pass + return CC(x) + n = numerical_approx N = numerical_approx diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 842263266cb..bf6f4f4541e 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -1067,20 +1067,11 @@ cdef class FreeModuleElement(element_Vector): # abstract base class (1.00000000000000, 2.00000000000000, 3.00000000000000) sage: _.parent() Vector space of dimension 3 over Real Field with 53 bits of precision - sage: v.n(prec=75) - (1.000000000000000000000, 2.000000000000000000000, 3.000000000000000000000) - sage: _.parent() - Vector space of dimension 3 over Real Field with 75 bits of precision - sage: v = vector(CDF, [1,2,3]) sage: v.n() (1.00000000000000, 2.00000000000000, 3.00000000000000) sage: _.parent() Vector space of dimension 3 over Complex Field with 53 bits of precision - sage: v.n(prec=75) - (1.000000000000000000000, 2.000000000000000000000, 3.000000000000000000000) - sage: _.parent() - Vector space of dimension 3 over Complex Field with 75 bits of precision sage: v = vector(Integers(8), [1,2,3]) sage: v.n() diff --git a/src/sage/rings/complex_number.pyx b/src/sage/rings/complex_number.pyx index 378b2dc0a3b..597bed321a9 100644 --- a/src/sage/rings/complex_number.pyx +++ b/src/sage/rings/complex_number.pyx @@ -590,7 +590,8 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): mpc(real='1.0', imag='2.0') """ if prec is not None: - return self.n(prec=prec)._mpmath_() + from complex_field import ComplexField + return ComplexField(prec)(self)._mpmath_() from sage.libs.mpmath.all import make_mpc re = mpfr_to_mpfval(self.__re) im = mpfr_to_mpfval(self.__im) diff --git a/src/sage/rings/real_mpfr.pyx b/src/sage/rings/real_mpfr.pyx index 14c6f809e5a..374f235ec25 100644 --- a/src/sage/rings/real_mpfr.pyx +++ b/src/sage/rings/real_mpfr.pyx @@ -3156,7 +3156,7 @@ cdef class RealNumber(sage.structure.element.RingElement): mpf('-1.5') """ if prec is not None: - return self.n(prec=prec)._mpmath_() + return RealField(prec)(self)._mpmath_() from sage.libs.mpmath.all import make_mpf return make_mpf(mpfr_to_mpfval(self.value)) @@ -5414,6 +5414,47 @@ cdef class RealLiteral(RealNumber): else: return RealLiteral(self._parent, '-'+self.literal, self.base) + def _numerical_approx(self, prec=53, algorithm=None): + """ + Convert ``self`` to a ``RealField`` with ``prec`` bits of + precision. + + INPUT: + + - ``prec`` -- (default: 53) a precision in bits + + - ``algorithm`` -- ignored + + OUTPUT: + + A ``RealNumber`` with ``prec`` bits of precision. + + EXAMPLES:: + + sage: (1.3)._numerical_approx() + 1.30000000000000 + sage: n(1.3, 120) + 1.3000000000000000000000000000000000 + + Compare with:: + + sage: RealField(120)(RR(13/10)) + 1.3000000000000000444089209850062616 + sage: n(RR(13/10), 120) + Traceback (most recent call last): + ... + TypeError: cannot approximate to a precision of 120 bits, use at most 53 bits + + The result is a non-literal:: + + sage: type(1.3) + + sage: type(n(1.3)) + + """ + return RealField(prec)(self.literal) + + RR = RealField() RR_min_prec = RealField(MPFR_PREC_MIN) From 47c639d55d3c07670b8b52a629f7cf86a8beb7ce Mon Sep 17 00:00:00 2001 From: Simon King Date: Sat, 18 Oct 2014 11:41:35 +0200 Subject: [PATCH 108/698] Rewrite bounded integer sequences using sage.misc.bitset --- src/sage/misc/bounded_integer_sequences.pxd | 63 +- src/sage/misc/bounded_integer_sequences.pyx | 903 ++++++++++---------- 2 files changed, 472 insertions(+), 494 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pxd b/src/sage/misc/bounded_integer_sequences.pxd index eb3debf23bf..a917f38cb17 100644 --- a/src/sage/misc/bounded_integer_sequences.pxd +++ b/src/sage/misc/bounded_integer_sequences.pxd @@ -1,41 +1,48 @@ -include "sage/libs/ntl/decl.pxi" - -ctypedef struct biseq: # bounded integer sequence - mpz_t data # Use GMP integers as bitarrays - unsigned long int bitsize # Bitsize of "data" - unsigned int itembitsize # Bitsize of one element of this sequence. - # Note: We do not store the exact bound for the - # items of this sequence, but store the - # bitlength that is sufficient to store one - # item. - unsigned int mask_item # "bla&mask_item" greps onethe item bla starts with - size_t length # Number of items in this sequence. - # bitsize=length*itembitsize, but we do not want - # to repeat this multiplication and thus store - # the result. - -ctypedef biseq *biseq_t - -cdef biseq_t allocate_biseq(size_t l, unsigned long int itemsize) except NULL +from sage.libs.gmp.types cimport * +from sage.misc.bitset cimport * + +ctypedef struct biseq: # bounded integer sequence + bitset_t data # Use GMP integers as bitarrays + mp_bitcnt_t itembitsize # Bitsize of one element of this sequence. Note: + # We do not store the exact bound for the items + # of this sequence, but store the bitlength that + # is sufficient to store one item. + mp_limb_t mask_item # "bla&mask_item" greps onethe item bla starts with + mp_size_t length # Number of items in this sequence. + # bitsize=length*itembitsize, but we do not want + # to repeat this multiplication and thus store + # the result. + +ctypedef biseq biseq_t[1] + +cdef bint allocate_biseq(biseq_t R, mp_size_t l, mp_size_t itemsize) except -1 # Allocate memory (filled with zero) for a bounded integer sequence # of length l with items fitting in itemsize bits. cdef void dealloc_biseq(biseq_t S) + # Free the data stored in S. -cdef biseq_t list_to_biseq(list data, unsigned int bound) except NULL +cdef bint copy_biseq(biseq_t R, biseq_t S) except -1 + # Replace the content of R by a copy of S + +cdef bint list_to_biseq(biseq_t R, list data, unsigned int bound) except -1 # Convert a list to a bounded integer sequence cdef list biseq_to_list(biseq_t S) # Convert a bounded integer sequence to a list -cdef biseq_t concat_biseq(biseq_t S1, biseq_t S2) except NULL +cdef bint concat_biseq(biseq_t R, biseq_t S1, biseq_t S2) except -1 # Does not test whether the sequences have the same bound! -cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2) +cdef bint first_bits_equal(mp_limb_t* b1, mp_limb_t* b2, mp_bitcnt_t d) except -1 + # Boilerplate function for comparison of the first bits of two gmp bitsets, + # mimmicking mpz_congruent_2exp_p + +cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2) except -1 # Is S1=S2+something? Does not check whether the sequences have the same # bound! -cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start) except -2 +cdef int contains_biseq(biseq_t S1, biseq_t S2, mp_size_t start) except -2 # Returns the position *in S1* of S2 as a subsequence of S1[start:], or -1 # if S2 is not a subsequence. Does not check whether the sequences have the # same bound! @@ -44,15 +51,15 @@ cdef int max_overlap_biseq(biseq_t S1, biseq_t S2) except 0 # Returns the minimal *positive* integer i such that S2 starts with S1[i:]. # This function will *not* test whether S2 starts with S1! -cdef int index_biseq(biseq_t S, int item, size_t start) except -2 +cdef int index_biseq(biseq_t S, mp_limb_t item, mp_size_t start) except -2 # Returns the position *in S* of the item in S[start:], or -1 if S[start:] # does not contain the item. -cdef int getitem_biseq(biseq_t S, unsigned long int index) except -1 +cdef int getitem_biseq(biseq_t S, mp_size_t index) except -1 # Returns S[index], without checking margins -cdef biseq_t slice_biseq(biseq_t S, int start, int stop, int step) except NULL - # Returns the biseq S[start:stop:step] +cdef bint slice_biseq(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1 + # Fills R with S[start:stop:step] cdef class BoundedIntegerSequence: cdef biseq_t data @@ -61,4 +68,4 @@ cdef class BoundedIntegerSequence: cpdef list list(self) cpdef BoundedIntegerSequence maximal_overlap(self, BoundedIntegerSequence other) -cpdef BoundedIntegerSequence NewBISEQ(data, unsigned long int bitsize, unsigned int itembitsize, size_t length) +cpdef BoundedIntegerSequence NewBISEQ(tuple data, mp_bitcnt_t itembitsize, mp_size_t length) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index 0445a9b3f78..028657b7f97 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -9,44 +9,56 @@ This module provides :class:`BoundedIntegerSequence`, which implements sequences of bounded integers and is for many (but not all) operations faster than representing the same sequence as a Python :class:`tuple`. -It also provides some boilerplate functions that can be cimported in Cython -modules:: +The underlying data structure is similar to :class:`~sage.misc.bitset.Bitset`, +which means that certain operations are implemented by using fast shift +operations from GMP. The following boilerplate functions can be cimported in +Cython modules:: - cdef biseq_t allocate_biseq(size_t l, unsigned long int itemsize) except NULL - # Allocate memory (filled with zero) for a bounded integer sequence - # of length l with items fitting in itemsize bits. +cdef bint allocate_biseq(biseq_t R, mp_size_t l, mp_size_t itemsize) except -1 + # Allocate memory (filled with zero) for a bounded integer sequence + # of length l with items fitting in itemsize bits. - cdef biseq_t list_to_biseq(list data, unsigned int bound) except NULL - # Convert a list to a bounded integer sequence +cdef void dealloc_biseq(biseq_t S) + # Free the data stored in S. - cdef list biseq_to_list(biseq_t S) - # Convert a bounded integer sequence to a list +cdef bint copy_biseq(biseq_t R, biseq_t S) + # Replace the content of R by a copy of S - cdef biseq_t concat_biseq(biseq_t S1, biseq_t S2) except NULL - # Does not test whether the sequences have the same bound! +cdef bint list_to_biseq(biseq_t R, list data, unsigned int bound) except -1 + # Convert a list to a bounded integer sequence - cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2) - # Is S1=S2+something? Does not check whether the sequences have the same - # bound! +cdef list biseq_to_list(biseq_t S) + # Convert a bounded integer sequence to a list - cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start) - # Returns the position *in S1* of S2 as a subsequence of S1[start:], or -1 - # if S2 is not a subsequence. Does not check whether the sequences have the - # same bound! +cdef bint concat_biseq(biseq_t R, biseq_t S1, biseq_t S2) except -1 + # Does not test whether the sequences have the same bound! - cdef int max_overlap_biseq(biseq_t S1, biseq_t S2) except 0 - # Returns the minimal *positive* integer i such that S2 starts with S1[i:]. - # This function will *not* test whether S2 starts with S1! +cdef bint first_bits_equal(mp_limb_t* b1, mp_limb_t* b2, mp_bitcnt_t d) except -1 + # Boilerplate function for comparison of the first bits of two gmp bitsets, + # mimmicking mpz_congruent_2exp_p - cdef int index_biseq(biseq_t S, int item, size_t start) - # Returns the position *in S* of the item in S[start:], or -1 if S[start:] - # does not contain the item. +cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2) + # Is S1=S2+something? Does not check whether the sequences have the same + # bound! - cdef int getitem_biseq(biseq_t S, unsigned long int index) except -1 - # Returns S[index], without checking margins +cdef int contains_biseq(biseq_t S1, biseq_t S2, mp_size_t start) except -2 + # Returns the position *in S1* of S2 as a subsequence of S1[start:], or -1 + # if S2 is not a subsequence. Does not check whether the sequences have the + # same bound! - cdef biseq_t slice_biseq(biseq_t S, int start, int stop, int step) except NULL - # Returns the biseq S[start:stop:step] +cdef int max_overlap_biseq(biseq_t S1, biseq_t S2) except 0 + # Returns the minimal *positive* integer i such that S2 starts with S1[i:]. + # This function will *not* test whether S2 starts with S1! + +cdef int index_biseq(biseq_t S, mp_limb_t item, mp_size_t start) except -2 + # Returns the position *in S* of the item in S[start:], or -1 if S[start:] + # does not contain the item. + +cdef int getitem_biseq(biseq_t S, mp_size_t index) except -1 + # Returns S[index], without checking margins + +cdef bint slice_biseq(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1 + # Fills R with S[start:stop:step] """ #***************************************************************************** @@ -62,9 +74,11 @@ include "sage/ext/cdefs.pxi" include "sage/ext/interrupt.pxi" include "sage/ext/stdsage.pxi" include "sage/ext/python.pxi" +include "sage/libs/ntl/decl.pxi" +include 'sage/misc/bitset.pxi' -cdef extern from "mpz_pylong.h": - cdef long mpz_pythonhash(mpz_t src) +#cdef extern from "mpz_pylong.h": +# cdef long mpz_pythonhash(mpz_t src) cdef extern from "gmp.h": cdef int mp_bits_per_limb @@ -79,16 +93,16 @@ cdef extern from "gmp.h": cdef extern from "Python.h": bint PySlice_Check(PyObject* ob) -cdef size_t times_size_of_limb = [1,2,4,8,16,32,64].index(sizeof(mp_limb_t)) -cdef size_t times_mp_bits_per_limb = [1,2,4,8,16,32,64,128,256].index(mp_bits_per_limb) -cdef size_t mod_mp_bits_per_limb = ((1)<1)<ZeroNone cdef dict EmptyDict = {} cdef PyObject* emptyDict = EmptyDict -from cython.operator import dereference as deref, preincrement as preinc, predecrement as predec +from cython.operator import dereference as deref, preincrement as preinc, predecrement as predec, postincrement as postinc ################### # Boilerplate @@ -99,121 +113,129 @@ from cython.operator import dereference as deref, preincrement as preinc, predec # (De)allocation, copying # -cdef biseq_t allocate_biseq(size_t l, unsigned long int itemsize) except NULL: +cdef bint allocate_biseq(biseq_t R, mp_size_t l, mp_size_t itemsize) except -1: """ Allocate memory for a bounded integer sequence of length l with items - fitting in itemsize bits. Returns a pointer to the bounded integer - sequence, or NULL on error. + fitting in itemsize bits. """ - cdef biseq_t out = sage_malloc(sizeof(biseq)) - if out==NULL: - raise MemoryError("Can not allocate bounded integer sequence") - out.bitsize = l*itemsize - out.length = l - out.itembitsize = itemsize - out.mask_item = ((1)<1)<mp_bits_per_limb: + raise ValueError("The integer bound {} does not fit into {}".format(bound, mp_bits_per_limb)) + allocate_biseq(R, len(data), ln) mpz_clear(tmp) else: raise ValueError("The bound for the items of bounded integer sequences must be positive") cdef unsigned long int item cdef mp_limb_t item_limb - cdef mp_limb_t tmp_limb + cdef mp_limb_t tmp_limb1, tmp_limb2 cdef int offset_mod, offset_div cdef int offset = 0 if not data: - return S + return True for item in data: - item_limb = (item&S.mask_item) + item_limb = (item&R.mask_item) offset_mod = offset&mod_mp_bits_per_limb offset_div = offset>>times_mp_bits_per_limb if offset_mod: - assert offset_div+1<(<__mpz_struct*>S.data)._mp_alloc - (<__mpz_struct*>S.data)._mp_d[offset_div+1] = mpn_lshift(&tmp_limb, &item_limb, 1, offset_mod) - (<__mpz_struct*>S.data)._mp_d[offset_div] |= tmp_limb - if (<__mpz_struct*>S.data)._mp_d[offset_div+1]!=0 and offset_div+1>=(<__mpz_struct*>S.data)._mp_size: - (<__mpz_struct*>S.data)._mp_size = offset_div+2 - elif tmp_limb!=0 and offset_div>=(<__mpz_struct*>S.data)._mp_size: - (<__mpz_struct*>S.data)._mp_size = offset_div+1 + tmp_limb2 = mpn_lshift(&tmp_limb1, &item_limb, 1, offset_mod) + if tmp_limb2: + # This can only happen, if offset_div is small enough to not + # write out of bounds, since initially we have allocated + # enough memory. + R.data.bits[offset_div+1] = tmp_limb2 + R.data.bits[offset_div] |= tmp_limb1 else: - assert offset_div<(<__mpz_struct*>S.data)._mp_alloc - (<__mpz_struct*>S.data)._mp_d[offset_div] = item_limb - if item_limb!=0 and offset_div>=(<__mpz_struct*>S.data)._mp_size: - (<__mpz_struct*>S.data)._mp_size = offset_div+1 - offset += S.itembitsize - return S + R.data.bits[offset_div] = item_limb + offset += R.itembitsize cdef list biseq_to_list(biseq_t S): """ Convert a bounded integer sequence to a list of integers. """ - cdef int index, limb_index, bit_index, max_limb - index = 0 + cdef mp_size_t limb_index, max_limbs + cdef mp_bitcnt_t bit_index, local_index cdef list L = [] - cdef size_t n - # If limb_indexS.data)._mp_size - 1 - if max_limb<0: - return [int(0)]*S.length + if S.length==0: + return L + max_limbs = S.data.limbs + predec(max_limbs) + cdef mp_size_t n cdef mp_limb_t tmp_limb[2] + limb_index = 0 + bit_index = 0 # This is the index mod mp_bits_per_limb in S.data + local_index = 0 # This is the index in tmp_limb + tmp_limb[0] = S.data.bits[0] for n from S.length>=n>0: - limb_index = index>>times_mp_bits_per_limb - bit_index = index&mod_mp_bits_per_limb - # Problem: GMP tries to be clever, and sometimes removes trailing - # zeroes. Hence, we must take care to not read bits from non-allocated - # memory. - if limb_index < max_limb: - if bit_index: - if bit_index+S.itembitsize >= mp_bits_per_limb: - mpn_rshift(tmp_limb, (<__mpz_struct*>S.data)._mp_d+limb_index, 2, bit_index) - L.append((tmp_limb[0]&S.mask_item)) - else: - L.append(((((<__mpz_struct*>S.data)._mp_d[limb_index])>>bit_index)&S.mask_item)) - else: - L.append(((<__mpz_struct*>S.data)._mp_d[limb_index]&S.mask_item)) - elif limb_index == max_limb: - if bit_index: - L.append(((((<__mpz_struct*>S.data)._mp_d[limb_index])>>bit_index)&S.mask_item)) + #print local_index, limb_index, bit_index + if local_index+S.itembitsize > mp_bits_per_limb: + #print "need more stuff" + local_index = 0 + # tmp_limb[0] can not provide the next item, we need to get new stuff + if bit_index and limb_index < max_limbs: + # We move two limbs now, so that tmp_limb[0] will be completely full + #print "shifting two limbs" + mpn_rshift(tmp_limb, S.data.bits+limb_index, 2, bit_index) else: - L.append(((<__mpz_struct*>S.data)._mp_d[limb_index]&S.mask_item)) - else: - break - index += S.itembitsize - if n: - L.extend([int(0)]*n) + #print "one limb is enough" + # We shift within one limb + tmp_limb[0] = S.data.bits[limb_index]>>bit_index + #else: tmp_limb[0] provides the next item + local_index += S.itembitsize + #print "next item from",Integer(tmp_limb[0]).bits(),"is",(tmp_limb[0]&S.mask_item) + L.append((tmp_limb[0]&S.mask_item)) + tmp_limb[0]>>=S.itembitsize + bit_index += S.itembitsize + if bit_index>=mp_bits_per_limb: + bit_index -= mp_bits_per_limb + preinc(limb_index) return L # # Arithmetics # -cdef biseq_t concat_biseq(biseq_t S1, biseq_t S2) except NULL: +cdef bint concat_biseq(biseq_t R, biseq_t S1, biseq_t S2) except -1: """ - Concatenate two bounded integer sequences. + Concatenate two bounded integer sequences ``S1`` and ``S2``. ASSUMPTION: @@ -223,24 +245,57 @@ cdef biseq_t concat_biseq(biseq_t S1, biseq_t S2) except NULL: OUTPUT: - - A pointer to the concatenated sequence, or NULL on error. + The result is written into ``R``, which must not be initialised """ - cdef biseq_t out = sage_malloc(sizeof(biseq)) - if out==NULL: - raise MemoryError("Can not allocate bounded integer sequence") - out.bitsize = S1.bitsize+S2.bitsize - out.length = S1.length+S2.length - out.itembitsize = S1.itembitsize # do not test == S2.itembitsize - out.mask_item = S1.mask_item - sig_on() - mpz_init2(out.data, out.bitsize) - sig_off() - mpz_mul_2exp(out.data, S2.data, S1.bitsize) - mpz_ior(out.data, out.data, S1.data) - return out + R.itembitsize = S1.itembitsize # do not test == S2.itembitsize + R.mask_item = S1.mask_item + if S1.length==0: + if S2.length==0: + R.length = 0 + return True + else: + R.length = S2.length + bitset_init(R.data, S2.data.size) + mpn_copyi(R.data.bits, S2.data.bits, S2.data.limbs) + else: + if S2.length==0: + R.length = S1.length + bitset_init(R.data, S1.data.size) + mpn_copyi(R.data.bits, S1.data.bits, S1.data.limbs) + else: + R.length = S1.length+S2.length + bitset_init(R.data, S1.data.size+S2.data.size) + mpn_lshift(R.data.bits+(S1.data.size>>times_mp_bits_per_limb), S2.data.bits, + S2.data.limbs, S1.data.size&mod_mp_bits_per_limb) + mpn_ior_n(R.data.bits, R.data.bits, S1.data.bits, S1.data.limbs) -cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2): +cdef inline bint first_bits_equal(mp_limb_t* b1, mp_limb_t* b2, mp_bitcnt_t d) except -1: + """ + Compare the first bits of two gmp bitsets + + INPUT: + + - b1,b2: Pointers to bitsets + - d: The number of bits to be compared + + ASSUMPTION: + + d must not exceed the length of either bitset. + + """ + cdef mp_size_t i, dlimbs + cdef unsigned long dbits + dlimbs = d>>times_mp_bits_per_limb + if mpn_cmp(b1,b2,dlimbs)!=0: + return False + dbits = d&mod_mp_bits_per_limb + if dbits==0: + return True + return (((b1[dlimbs])^(b2[dlimbs]))&(((1)<S1.length: + return False + return first_bits_equal(S1.data.bits, S2.data.bits, S2.data.size) -cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start) except -2: +cdef int contains_biseq(biseq_t S1, biseq_t S2, mp_size_t start) except -2: """ - Tests if bounded integer sequence ``S1[start:]`` contains a sub-sequence ``S2`` + Tests if the bounded integer sequence ``S1[start:]`` contains a sub-sequence ``S2`` INPUT: @@ -265,7 +324,7 @@ cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start) except -2: OUTPUT: Index ``i>=start`` such that ``S1[i:]`` starts with ``S2``, or ``-1`` if - ``S1`` does not contain ``S2``. + ``S1[start:]`` does not contain ``S2``. ASSUMPTION: @@ -276,349 +335,244 @@ cdef int contains_biseq(biseq_t S1, biseq_t S2, size_t start) except -2: """ if S1.lengthS2.data) - # The number of limbs required to store data of S2's bitsize (including - # trailing zeroes) - limb_size = (S2.bitsize>>times_mp_bits_per_limb)+1 - # Size of S2 without trailing zeroes: - limb_size_orig = seq._mp_size - - seq = deref(<__mpz_struct*>S1.data) - cdef int n, limb_index, bit_index - # Idea: We shift-copy enough limbs from S1 to tmp and then compare with - # S2, for each shift. - sig_on() - mpz_init2(tmp, S2.bitsize+mp_bits_per_limb) - sig_off() - # The maximal number of limbs of S1 that is safe to use after the current - # position, but not more than what fits into tmp: - cdef int max_S1_limbs = seq._mp_size-((start*S1.itembitsize)>>times_mp_bits_per_limb) - cdef int max_limb_size = min((<__mpz_struct*>tmp)._mp_alloc, max_S1_limbs) - if ((start*S1.itembitsize)&mod_mp_bits_per_limb)==0: - # We increase it, since in the loop it is decreased when the index is - # zero modulo bits per limb - preinc(max_S1_limbs) - n = 0 - cdef int index = 0 - # tmp may have trailing zeroes, and GMP can NOT cope with that! - # Hence, we need to adjust the size later. - (<__mpz_struct*>tmp)._mp_size = limb_size - for index from start<=index<=S1.length-S2.length: + if S2.length==0: + return start + cdef bitset_t tmp + bitset_init(tmp, S2.data.size+mp_bits_per_limb) + cdef mp_size_t index = 0 + cdef mp_bitcnt_t n = 0 + cdef mp_size_t limb_index, bit_index + cdef mp_bitcnt_t offset = S2.data.size&mod_mp_bits_per_limb + for index from start <= index <= S1.length-S2.length: limb_index = n>>times_mp_bits_per_limb - # Adjust the number of limbs we are shifting - bit_index = n&mod_mp_bits_per_limb + bit_index = n&mod_mp_bits_per_limb + # We shift a part of S1 (with length S2) by bit_index, and compare + # with S2. if bit_index: - if limb_size < max_limb_size: - assert limb_size<(<__mpz_struct*>tmp)._mp_alloc - mpn_rshift((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, limb_size+1, bit_index) + if offset+bit_index>mp_bits_per_limb: + mpn_rshift(tmp.bits, S1.data.bits+limb_index, S2.data.limbs+1, bit_index) else: - assert max_limb_size<=(<__mpz_struct*>tmp)._mp_alloc - (<__mpz_struct*>tmp)._mp_size = max_limb_size - mpn_rshift((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, max_limb_size, bit_index) + mpn_rshift(tmp.bits, S1.data.bits+limb_index, S2.data.limbs, bit_index) else: - # The bit_index is zero, and hence one limb less is remaining. We - # thus decrement max_S1_limbs. - predec(max_S1_limbs) - max_limb_size = min((<__mpz_struct*>tmp)._mp_alloc, max_S1_limbs) - if limb_size < max_limb_size: - assert limb_size<=(<__mpz_struct*>tmp)._mp_alloc - mpn_copyi((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, limb_size) - else: - assert max_limb_size<=(<__mpz_struct*>tmp)._mp_alloc - (<__mpz_struct*>tmp)._mp_size = max_limb_size - mpn_copyi((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, max_limb_size) - # Now, the first min(limb_size,max_limb_size) limbs of tmp are - # guaranteed to be valid. The rest may be junk. - - # If the number of valid limbs of tmp is smaller than limb_size_orig - # (this can only happen if max_limb_size became small), then we were - # running into trailing zeroes of S1. Hence, as explained above, we - # can decide now whether S2 is a sub-sequence of S1 in the case that - # the non-cutoff bits match. - if max_limb_sizetmp)._mp_d, (<__mpz_struct*>(S2.data))._mp_d, max_limb_size)==0: - mpz_clear(tmp) - if limb_size_orig > max_limb_size: - # S2 has further non-zero entries - return -1 - # Both S2 and S1 have enough trailing zeroes - return index - else: - if mpz_congruent_2exp_p(S2.data, tmp, S2.bitsize): - mpz_clear(tmp) - return index - n += S1.itembitsize - mpz_clear(tmp) - return -1 - -cdef int max_overlap_biseq(biseq_t S1, biseq_t S2) except 0: - """ - Returns the smallest **positive** integer ``i`` such that ``S2`` starts with ``S1[i:]``. - - Returns ``-1`` if there is no overlap. Note that ``i==0`` will not be considered! - - INPUT: - - - ``S1``, ``S2`` -- two bounded integer sequences - - ASSUMPTION: - - - The two sequences must have equivalent bounds, i.e., the items on the - sequences must fit into the same number of bits. This condition is not - tested. - - """ - cdef __mpz_struct seq - seq = deref(<__mpz_struct*>S1.data) - cdef mpz_t tmp - # Idea: We shift-copy enough limbs from S1 to tmp and then compare with - # the initial part of S2, for each shift. - sig_on() - mpz_init2(tmp, S1.bitsize+mp_bits_per_limb) - sig_off() - # We will use tmp to store enough bits to be able to compare with the tail - # of S1. - cdef int n, limb_index, bit_index - cdef int index, i, start_index - if S2.length>=S1.length: - start_index = 1 - else: - start_index = S1.length-S2.length - n = S1.itembitsize*start_index - for index from start_index<=index>times_mp_bits_per_limb - if limb_index>=seq._mp_size: - break - bit_index = n&mod_mp_bits_per_limb - if bit_index: - assert seq._mp_size-limb_index<=(<__mpz_struct*>tmp)._mp_alloc - mpn_rshift((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, seq._mp_size-limb_index, bit_index) - else: - assert seq._mp_size-limb_index<=(<__mpz_struct*>tmp)._mp_alloc - mpn_copyi((<__mpz_struct*>tmp)._mp_d, seq._mp_d+limb_index, seq._mp_size-limb_index) - (<__mpz_struct*>tmp)._mp_size = seq._mp_size-limb_index - if mpz_congruent_2exp_p(tmp, S2.data, S1.bitsize-n): - mpz_clear(tmp) + mpn_copyi(tmp.bits, S1.data.bits+limb_index, S2.data.limbs) + if first_bits_equal(tmp.bits, S2.data.bits, S2.data.size): + bitset_free(tmp) return index n += S1.itembitsize - # now, it could be that we have to check for leading zeroes on S2. - if indexS.data) - - cdef int n, limb_index, bit_index, max_limb + cdef mp_size_t limb_index, max_limbs + cdef mp_bitcnt_t bit_index, local_index + if S.length==0: + return -1 + max_limbs = S.data.limbs + predec(max_limbs) + cdef mp_size_t n cdef mp_limb_t tmp_limb[2] + limb_index = 0 + bit_index = 0 # This is the index mod mp_bits_per_limb in S.data + local_index = 0 # This is the index in tmp_limb + tmp_limb[0] = S.data.bits[0] item &= S.mask_item - n = 0 - # If limb_index>times_mp_bits_per_limb - bit_index = n&mod_mp_bits_per_limb - if limb_index < max_limb: - if bit_index: - if bit_index+S.itembitsize >= mp_bits_per_limb: - mpn_rshift(tmp_limb, seq._mp_d+limb_index, 2, bit_index) - if item==(tmp_limb[0]&S.mask_item): - return index - elif item==(((seq._mp_d[limb_index])>>bit_index)&S.mask_item): - return index - elif item==(seq._mp_d[limb_index]&S.mask_item): - return index - elif limb_index == max_limb: - if bit_index: - if item==(((seq._mp_d[limb_index])>>bit_index)&S.mask_item): - return index - elif item==(seq._mp_d[limb_index]&S.mask_item): - return index - else: - if item==0 and index mp_bits_per_limb: + local_index = 0 + # tmp_limb[0] can not provide the next item, we need to get new stuff + if bit_index and limb_index < max_limbs: + # We move two limbs now, so that tmp_limb[0] will be completely full + mpn_rshift(tmp_limb, S.data.bits+limb_index, 2, bit_index) else: - return -1 - n += S.itembitsize + # We shift within one limb + tmp_limb[0] = S.data.bits[limb_index]>>bit_index + #else: tmp_limb[0] provides the next item + local_index += S.itembitsize + if item == tmp_limb[0]&S.mask_item: + return n + tmp_limb[0]>>=S.itembitsize + bit_index += S.itembitsize + if bit_index>=mp_bits_per_limb: + bit_index -= mp_bits_per_limb + preinc(limb_index) return -1 -cdef int getitem_biseq(biseq_t S, unsigned long int index) except -1: +cdef int getitem_biseq(biseq_t S, mp_size_t index) except -1: """ Get item S[index], without checking margins. """ - cdef __mpz_struct seq - seq = deref(<__mpz_struct*>S.data) - cdef long int limb_index, bit_index, limb_size + cdef mp_size_t limb_index, bit_index index *= S.itembitsize limb_index = index>>times_mp_bits_per_limb bit_index = index&mod_mp_bits_per_limb cdef mp_limb_t tmp_limb[2] cdef int out - if limb_index>=seq._mp_size: - return 0 if bit_index: # limb_size is 1 or 2 - limb_size = ((bit_index+S.itembitsize-1)>>times_mp_bits_per_limb)+1 - if limb_index+limb_size>seq._mp_size: - limb_size = 1 # the second limb may be non-allocated memory and - # should be treated as zero. - if limb_size!=1: - assert limb_size<=2 - mpn_rshift(tmp_limb, seq._mp_d+limb_index, limb_size, bit_index) + if bit_index+S.itembitsize>mp_bits_per_limb: + mpn_rshift(tmp_limb, S.data.bits+limb_index, 2, bit_index) out = (tmp_limb[0]) else: - out = ((seq._mp_d[limb_index])>>bit_index) + out = ((S.data.bits[limb_index])>>bit_index) else: - out = (seq._mp_d[limb_index]) + out = (S.data.bits[limb_index]) return out&S.mask_item -cdef biseq_t slice_biseq(biseq_t S, int start, int stop, int step) except NULL: +cdef bint slice_biseq(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1: """ Create the slice S[start:stop:step] as bounded integer sequence. - Return: - - - A pointer to the resulting bounded integer sequence, or NULL on error. - """ - cdef long int length, total_shift, n + cdef mp_size_t length, total_shift, n if step>0: if stop>start: length = ((stop-start-1)//step)+1 else: - return allocate_biseq(0, S.itembitsize) + allocate_biseq(R, 0, S.itembitsize) + return True else: if stop>=start: - return allocate_biseq(0, S.itembitsize) + allocate_biseq(R, 0, S.itembitsize) + return True else: length = ((stop-start+1)//step)+1 - cdef biseq_t out = allocate_biseq(length, S.itembitsize) - cdef int offset_mod, offset_div - cdef int limb_size + allocate_biseq(R, length, S.itembitsize) + cdef mp_size_t offset_mod, offset_div total_shift = start*S.itembitsize if step==1: - # allocate_biseq allocates one limb more than strictly needed. This is - # enough to shift a limb* array directly to its ._mp_d field. + # Slicing essentially boils down to a shift operation. offset_mod = total_shift&mod_mp_bits_per_limb offset_div = total_shift>>times_mp_bits_per_limb - limb_size = ((offset_mod+out.bitsize-1)>>times_mp_bits_per_limb)+1 - # GMP tries to be clever and thus may cut trailing zeroes. Hence, - # limb_size may be so large that it would access non-allocated - # memory. We adjust this now: - limb_size = min(limb_size, (<__mpz_struct*>(S.data))._mp_size-offset_div) - if limb_size<=0: - (<__mpz_struct*>(out.data))._mp_size = 0 - return out - assert limb_size<=(<__mpz_struct*>(out.data))._mp_alloc if offset_mod: - mpn_rshift((<__mpz_struct*>(out.data))._mp_d, (<__mpz_struct*>(S.data))._mp_d+offset_div, limb_size, offset_mod) + #print "mpn_rshift",R.data.limbs,"by",offset_mod,"bits" + mpn_rshift(R.data.bits, S.data.bits+offset_div, R.data.limbs, offset_mod) + # Perhaps the last to-be-moved item partially belongs to the next + # limb of S? + #print "->",bitset_string(R.data) + if (R.data.size&mod_mp_bits_per_limb)+offset_mod>mp_bits_per_limb: + #print "adjust the final limb" + R.data.bits[R.data.limbs-1] |= (S.data.bits[offset_div+R.data.limbs]<<(mp_bits_per_limb-offset_mod)) + #print "->", bitset_string(R.data) else: - mpn_copyi((<__mpz_struct*>(out.data))._mp_d, (<__mpz_struct*>(S.data))._mp_d+offset_div, limb_size) - for n from limb_size>n>=0: - if (<__mpz_struct*>(out.data))._mp_d[n]: - break - (<__mpz_struct*>(out.data))._mp_size = n+1 - mpz_fdiv_r_2exp(out.data, out.data, out.bitsize) - return out - + #print "just copying",R.data.limbs,"limbs" + mpn_copyi(R.data.bits, S.data.bits+offset_div, R.data.limbs) + #print "->", bitset_string(R.data) + # Perhaps the last few bits of the last limb have to be set to zero? + offset_mod = (length*S.itembitsize)&mod_mp_bits_per_limb + if offset_mod: + #print "focus on",offset_mod,"bits" + R.data.bits[R.data.limbs-1] &= ((1)<",bitset_string(R.data) + return True + # Now for the difficult case: + # # Convention for variable names: We move data from *_src to *_tgt # tmp_limb is used to temporarily store the data that we move/shift cdef mp_limb_t tmp_limb[2] - cdef int offset_mod_src, offset_div_src, max_limb - cdef int offset_src = total_shift - cdef __mpz_struct *seq_src - seq_src = <__mpz_struct*>S.data - # We need to take into account that GMP tries to be clever, and removes - # trailing zeroes from the allocated memory. - max_limb = seq_src._mp_size - 1 - cdef int bitstep = step*S.itembitsize - cdef int offset_mod_tgt, offset_div_tgt - cdef int offset_tgt = 0 - cdef __mpz_struct *seq_tgt - seq_tgt = <__mpz_struct*>out.data + cdef mp_limb_t tmp_limb2 + cdef mp_size_t offset_div_src, max_limb + cdef mp_bitcnt_t offset_mod_src + cdef mp_size_t offset_src = total_shift + cdef mp_bitcnt_t bitstep = step*S.itembitsize + cdef mp_bitcnt_t offset_mod_tgt + cdef mp_size_t offset_div_tgt + cdef mp_size_t offset_tgt = 0 for n from length>=n>0: offset_div_src = offset_src>>times_mp_bits_per_limb offset_mod_src = offset_src&mod_mp_bits_per_limb offset_div_tgt = offset_tgt>>times_mp_bits_per_limb offset_mod_tgt = offset_tgt&mod_mp_bits_per_limb # put data from src to tmp_limb[0]. - if offset_div_src < max_limb: - if offset_mod_src: - if (offset_mod_src+S.itembitsize >= mp_bits_per_limb): - mpn_rshift(tmp_limb, seq_src._mp_d+offset_div_src, 2, offset_mod_src) - tmp_limb[0] &= S.mask_item - else: - tmp_limb[0] = ((seq_src._mp_d[offset_div_src])>>offset_mod_src) & S.mask_item - else: - tmp_limb[0] = seq_src._mp_d[offset_div_src] & S.mask_item - elif offset_div_src == max_limb: - if offset_mod_src: - tmp_limb[0] = ((seq_src._mp_d[offset_div_src])>>offset_mod_src) & S.mask_item + if offset_mod_src: + if (offset_mod_src+S.itembitsize > mp_bits_per_limb): + mpn_rshift(tmp_limb, S.data.bits+offset_div_src, 2, offset_mod_src) + tmp_limb[0] &= S.mask_item else: - tmp_limb[0] = seq_src._mp_d[offset_div_src] & S.mask_item + tmp_limb[0] = ((S.data.bits[offset_div_src])>>offset_mod_src) & S.mask_item else: - tmp_limb[0] = 0 + tmp_limb[0] = S.data.bits[offset_div_src] & S.mask_item # put data from tmp_limb[0] to tgt if offset_mod_tgt: - assert offset_div_tgt+1<(<__mpz_struct*>(out.data))._mp_alloc - seq_tgt._mp_d[offset_div_tgt+1] = mpn_lshift(tmp_limb, tmp_limb, 1, offset_mod_tgt) - seq_tgt._mp_d[offset_div_tgt] |= tmp_limb[0] - if seq_tgt._mp_d[offset_div_tgt+1]!=0 and offset_div_tgt+1>=seq_tgt._mp_size: - seq_tgt._mp_size = offset_div_tgt+2 - elif tmp_limb[0]!=0 and offset_div_tgt>=seq_tgt._mp_size: - seq_tgt._mp_size = offset_div_tgt+1 + tmp_limb2 = mpn_lshift(tmp_limb, tmp_limb, 1, offset_mod_tgt) + if tmp_limb2: + R.data.bits[offset_div_tgt+1] = tmp_limb2 + R.data.bits[offset_div_tgt] |= tmp_limb[0] else: - assert offset_div_tgt<(<__mpz_struct*>(out.data))._mp_alloc - seq_tgt._mp_d[offset_div_tgt] = tmp_limb[0] - if tmp_limb[0]!=0: - seq_tgt._mp_size = offset_div_tgt+1 + R.data.bits[offset_div_tgt] = tmp_limb[0] offset_tgt += S.itembitsize offset_src += bitstep - return out + +cdef int max_overlap_biseq(biseq_t S1, biseq_t S2) except 0: + """ + Returns the smallest **positive** integer ``i`` such that ``S2`` starts with ``S1[i:]``. + + Returns ``-1`` if there is no overlap. Note that ``i==0`` (``S2`` starts with ``S1``) + will not be considered! + + INPUT: + + - ``S1``, ``S2`` -- two bounded integer sequences + + ASSUMPTION: + + The two sequences must have equivalent bounds, i.e., the items on the + sequences must fit into the same number of bits. This condition is not + tested. + + """ + # Idea: We store the maximal possible tail of S1 in a temporary bitset, + # and then rightshift it (taking care that the number of to-be-shifted + # limbs will decrease over time), comparing with the initial part of S2 + # after each step. + if S1.length == 0: + raise ValueError("First argument must be of positive length") + cdef bitset_t tmp + cdef mp_size_t limb_index + cdef mp_bitcnt_t bit_index, n + cdef mp_size_t index, i, start_index + if S2.length>=S1.length: + start_index = 1 + else: + start_index = S1.length-S2.length + if start_index == S1.length: + return -1 + n = S1.itembitsize*start_index + ## Initilise the temporary bitset + # Allocate an additional limb, to cope with shifting accross limb borders + bitset_init(tmp, (mp_bits_per_limb+S1.data.size)-n) + cdef mp_size_t nlimbs = tmp.limbs # number of to-be-shifted limbs + limb_index = n>>times_mp_bits_per_limb + bit_index = n&mod_mp_bits_per_limb + if bit_index==0: + mpn_copyi(tmp.bits, S1.data.bits+limb_index, predec(nlimbs)) + else: + if ((S1.data.size-n)&mod_mp_bits_per_limb)+bit_index>mp_bits_per_limb: + # Need to shift an additional limb + mpn_rshift(tmp.bits, S1.data.bits+limb_index, nlimbs, bit_index) + else: + mpn_rshift(tmp.bits, S1.data.bits+limb_index, predec(nlimbs), bit_index) + cdef mp_bitcnt_t remaining_size = S1.data.size - n + n = 0 # This now counts how many bits of the highest limb of tmp we have shifted. + for index from start_index<=index=mp_bits_per_limb: + mpn_rshift(tmp.bits, tmp.bits, predec(nlimbs), S1.itembitsize) + n = 0 + else: + mpn_rshift(tmp.bits, tmp.bits, nlimbs, S1.itembitsize) + n += S1.itembitsize + bitset_free(tmp) + return -1 + ########################################### # A cdef class that wraps the above, and @@ -791,7 +745,7 @@ cdef class BoundedIntegerSequence: <> """ - def __cinit__(self, unsigned long int bound, list data): + def __cinit__(self, *args, **kwds): """ Allocate memory for underlying data @@ -813,7 +767,7 @@ cdef class BoundedIntegerSequence: """ # In __init__, we'll raise an error if the bound is 0. - self.data = NULL + self.data.length = 0 def __dealloc__(self): """ @@ -826,8 +780,7 @@ cdef class BoundedIntegerSequence: sage: del S # indirect doctest """ - if self.data!=NULL: - dealloc_biseq(self.data) + dealloc_biseq(self.data) def __init__(self, unsigned long int bound, list data): """ @@ -871,7 +824,7 @@ cdef class BoundedIntegerSequence: """ if bound==0: raise ValueError("Positive bound expected") - self.data = list_to_biseq(data, bound) + list_to_biseq(self.data, data, bound) def __copy__(self): """ @@ -919,18 +872,7 @@ cdef class BoundedIntegerSequence: True """ - cdef size_t n - cdef char *s - n = mpz_sizeinbase(self.data.data, 32) + 2 - s = PyMem_Malloc(n) - if s == NULL: - raise MemoryError, "Unable to allocate enough memory for the string defining a bounded integer sequence." - sig_on() - mpz_get_str(s, 32, self.data.data) - sig_off() - data_str = PyString_FromString(s) - PyMem_Free(s) - return NewBISEQ, (data_str, self.data.bitsize, self.data.itembitsize, self.data.length) + return NewBISEQ, (bitset_pickle(self.data.data), self.data.itembitsize, self.data.length) def __len__(self): """ @@ -1012,8 +954,7 @@ cdef class BoundedIntegerSequence: 64 """ - cdef long b = 1 - return (b<self.data.data) - cdef int index, limb_index, bit_index - cdef int max_limb - index = 0 - cdef mp_limb_t tmp_limb[2] - cdef size_t n, n2 - # If limb_index=n>0: - yield 0 + if self.data.length==0: return + cdef mp_size_t limb_index, max_limbs + cdef mp_bitcnt_t bit_index, local_index + max_limbs = self.data.data.limbs + predec(max_limbs) + cdef mp_size_t n + cdef mp_limb_t tmp_limb[2] + limb_index = 0 + bit_index = 0 # This is the index mod mp_bits_per_limb in self.data.data + local_index = 0 # This is the index in tmp_limb + tmp_limb[0] = self.data.data.bits[0] for n from self.data.length>=n>0: - limb_index = index>>times_mp_bits_per_limb - bit_index = index&mod_mp_bits_per_limb - if limb_index < max_limb: - if bit_index: - if bit_index+self.data.itembitsize >= mp_bits_per_limb: - mpn_rshift(tmp_limb, seq._mp_d+limb_index, 2, bit_index) - yield (tmp_limb[0]&self.data.mask_item) - else: - yield (((seq._mp_d[limb_index])>>bit_index)&self.data.mask_item) + if local_index+self.data.itembitsize > mp_bits_per_limb: + local_index = 0 + # tmp_limb[0] can not provide the next item, we need to get new stuff + if bit_index and limb_index < max_limbs: + # We move two limbs now, so that tmp_limb[0] will be completely full + mpn_rshift(tmp_limb, self.data.data.bits+limb_index, 2, bit_index) else: - yield (seq._mp_d[limb_index]&self.data.mask_item) - elif limb_index == max_limb: - yield (((seq._mp_d[limb_index])>>bit_index)&self.data.mask_item) - else: - for n2 from n>=n2>0: - yield 0 - break - index += self.data.itembitsize + # We shift within one limb + tmp_limb[0] = self.data.data.bits[limb_index]>>bit_index + #else: tmp_limb[0] provides the next item + local_index += self.data.itembitsize + yield (tmp_limb[0]&self.data.mask_item) + tmp_limb[0]>>=self.data.itembitsize + bit_index += self.data.itembitsize + if bit_index>=mp_bits_per_limb: + bit_index -= mp_bits_per_limb + preinc(limb_index) + def __getitem__(self, index): """ @@ -1134,6 +1072,12 @@ cdef class BoundedIntegerSequence: sage: S[10] 4 + :: + + sage: B = BoundedIntegerSequence(27, [8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10]) + sage: B[8:] + <17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10> + """ cdef BoundedIntegerSequence out cdef int start,stop,step @@ -1142,7 +1086,7 @@ cdef class BoundedIntegerSequence: if start==0 and stop==self.data.length and step==1: return self out = BoundedIntegerSequence.__new__(BoundedIntegerSequence, 0, None) - out.data = slice_biseq(self.data, start, stop, step) + slice_biseq(out.data, self.data, start, stop, step) return out cdef long Index try: @@ -1153,7 +1097,7 @@ cdef class BoundedIntegerSequence: Index = (self.data.length)+Index if Index<0 or Index>=self.data.length: raise IndexError("Index out of range") - return getitem_biseq(self.data, Index) + return getitem_biseq(self.data, Index) def __contains__(self, other): """ @@ -1207,6 +1151,12 @@ cdef class BoundedIntegerSequence: sage: S2 in S1 False + :: + + sage: B = BoundedIntegerSequence(27, [8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10]) + sage: B.index(B[8:]) + 8 + """ if not isinstance(other, BoundedIntegerSequence): return index_biseq(self.data, other, 0)>=0 @@ -1328,7 +1278,7 @@ cdef class BoundedIntegerSequence: if other<0: raise ValueError("BoundedIntegerSequence.index(x): x(={}) not in sequence".format(other)) try: - out = index_biseq(self.data, other, 0) + out = index_biseq(self.data, other, 0) except TypeError: raise ValueError("BoundedIntegerSequence.index(x): x(={}) not in sequence".format(other)) if out>=0: @@ -1391,7 +1341,7 @@ cdef class BoundedIntegerSequence: if right.data.itembitsize!=myself.data.itembitsize: raise ValueError("can only concatenate bounded integer sequences of compatible bounds") out = BoundedIntegerSequence.__new__(BoundedIntegerSequence, 0, None) - out.data = concat_biseq(myself.data, right.data) + concat_biseq(out.data, myself.data, right.data) return out cpdef BoundedIntegerSequence maximal_overlap(self, BoundedIntegerSequence other): @@ -1472,19 +1422,26 @@ cdef class BoundedIntegerSequence: """ cdef BoundedIntegerSequence right + cdef BoundedIntegerSequence Self if other is None: return 1 + if self is None: + return -1 try: right = other except TypeError: return -1 - cdef int c = cmp(self.data.itembitsize, right.data.itembitsize) + try: + Self = self + except TypeError: + return 1 + cdef int c = cmp(Self.data.itembitsize, right.data.itembitsize) if c: return c - c = cmp(self.data.length, right.data.length) + c = cmp(Self.data.length, right.data.length) if c: return c - return mpz_cmp(self.data.data, right.data.data) + return mpn_cmp(Self.data.data.bits, right.data.data.bits, Self.data.data.limbs) def __hash__(self): """ @@ -1510,9 +1467,25 @@ cdef class BoundedIntegerSequence: True """ - return mpz_pythonhash(self.data.data) - -cpdef BoundedIntegerSequence NewBISEQ(data, unsigned long int bitsize, unsigned int itembitsize, size_t length): + # This is similar to mpz_pythonhash, which is a very bad additive hash: + cdef mp_limb_t h = 0 + cdef mp_limb_t h0 + cdef mp_size_t i + cdef mp_limb_t* p = self.data.data.bits + for i from self.data.data.limbs>i>=0: + h0 = h + h += deref(postinc(p)) + if hsage_malloc(sizeof(biseq)) - if out.data==NULL: - raise MemoryError("Can not allocate bounded integer sequence") - mpz_init2(out.data.data, bitsize+mp_bits_per_limb) - out.data.bitsize = bitsize + cdef BoundedIntegerSequence out = BoundedIntegerSequence.__new__(BoundedIntegerSequence) out.data.itembitsize = itembitsize - out.data.mask_item = ((1)<1)<0: + max_overlap_biseq(S.data, T.data) From e3260e2d9f5bf0483770cc5235c00cd24c4eb310 Mon Sep 17 00:00:00 2001 From: Simon King Date: Sat, 18 Oct 2014 17:27:35 +0200 Subject: [PATCH 109/698] Typographical improvements --- src/sage/misc/bounded_integer_sequences.pyx | 84 ++++++++++++--------- 1 file changed, 49 insertions(+), 35 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index 028657b7f97..e9355f3448b 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -12,53 +12,67 @@ than representing the same sequence as a Python :class:`tuple`. The underlying data structure is similar to :class:`~sage.misc.bitset.Bitset`, which means that certain operations are implemented by using fast shift operations from GMP. The following boilerplate functions can be cimported in -Cython modules:: +Cython modules: -cdef bint allocate_biseq(biseq_t R, mp_size_t l, mp_size_t itemsize) except -1 - # Allocate memory (filled with zero) for a bounded integer sequence - # of length l with items fitting in itemsize bits. +- ``cdef bint allocate_biseq(biseq_t R, mp_size_t l, mp_size_t itemsize) except -1`` -cdef void dealloc_biseq(biseq_t S) - # Free the data stored in S. + Allocate memory (filled with zero) for a bounded integer sequence + of length l with items fitting in itemsize bits. -cdef bint copy_biseq(biseq_t R, biseq_t S) - # Replace the content of R by a copy of S +- ``cdef void dealloc_biseq(biseq_t S)`` -cdef bint list_to_biseq(biseq_t R, list data, unsigned int bound) except -1 - # Convert a list to a bounded integer sequence + Free the data stored in ``S``. -cdef list biseq_to_list(biseq_t S) - # Convert a bounded integer sequence to a list +- ``cdef bint copy_biseq(biseq_t R, biseq_t S)`` -cdef bint concat_biseq(biseq_t R, biseq_t S1, biseq_t S2) except -1 - # Does not test whether the sequences have the same bound! + Replace the content of ``R`` by a copy of ``S``. -cdef bint first_bits_equal(mp_limb_t* b1, mp_limb_t* b2, mp_bitcnt_t d) except -1 - # Boilerplate function for comparison of the first bits of two gmp bitsets, - # mimmicking mpz_congruent_2exp_p +- ``cdef bint list_to_biseq(biseq_t R, list data, unsigned int bound) except -1`` -cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2) - # Is S1=S2+something? Does not check whether the sequences have the same - # bound! + Convert a list to a bounded integer sequence. -cdef int contains_biseq(biseq_t S1, biseq_t S2, mp_size_t start) except -2 - # Returns the position *in S1* of S2 as a subsequence of S1[start:], or -1 - # if S2 is not a subsequence. Does not check whether the sequences have the - # same bound! +- ``cdef list biseq_to_list(biseq_t S)`` -cdef int max_overlap_biseq(biseq_t S1, biseq_t S2) except 0 - # Returns the minimal *positive* integer i such that S2 starts with S1[i:]. - # This function will *not* test whether S2 starts with S1! + Convert a bounded integer sequence to a list. -cdef int index_biseq(biseq_t S, mp_limb_t item, mp_size_t start) except -2 - # Returns the position *in S* of the item in S[start:], or -1 if S[start:] - # does not contain the item. +- ``cdef bint concat_biseq(biseq_t R, biseq_t S1, biseq_t S2) except -1`` -cdef int getitem_biseq(biseq_t S, mp_size_t index) except -1 - # Returns S[index], without checking margins + Concatenate ``S1`` and ``S2`` and write the result to ``R``. Does not test + whether the sequences have the same bound! -cdef bint slice_biseq(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1 - # Fills R with S[start:stop:step] +- ``cdef bint first_bits_equal(mp_limb_t* b1, mp_limb_t* b2, mp_bitcnt_t d) except -1`` + + Boilerplate function for comparison of the first bits of two gmp bitsets, + mimmicking ``mpz_congruent_2exp_p``. + +- ``cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2)`` + + Is ``S1=S2+something``? Does not check whether the sequences have the same + bound! + +- ``cdef int contains_biseq(biseq_t S1, biseq_t S2, mp_size_t start) except -2`` + + Returns the position *in ``S1``* of ``S2`` as a subsequence of + ``S1[start:]``, or ``-1`` if ``S2`` is not a subsequence. Does not check + whether the sequences have the same bound! + +- ``cdef int max_overlap_biseq(biseq_t S1, biseq_t S2) except 0`` + + Returns the minimal *positive* integer ``i`` such that ``S2`` starts with + ``S1[i:]``. This function will *not* test whether ``S2`` starts with ``S1``! + +- ``cdef int index_biseq(biseq_t S, mp_limb_t item, mp_size_t start) except -2`` + + Returns the position *in S* of the item in ``S[start:]``, or ``-1`` if + ``S[start:]`` does not contain the item. + +- ``cdef int getitem_biseq(biseq_t S, mp_size_t index) except -1`` + + Returns ``S[index]``, without checking margins. + +- ``cdef bint slice_biseq(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1`` + + Fills ``R`` with ``S[start:stop:step]`` """ #***************************************************************************** @@ -581,7 +595,7 @@ cdef int max_overlap_biseq(biseq_t S1, biseq_t S2) except 0: from sage.rings.integer import Integer cdef class BoundedIntegerSequence: """ - A sequence of non-negative uniformely bounded integers + A sequence of non-negative uniformely bounded integers. INPUT: From c2ff01b24aa9bc150498acbb370af5fdcae347d0 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Sat, 18 Oct 2014 20:45:58 +0100 Subject: [PATCH 110/698] Adjust header location for setjmp --- build/pkgs/gdb/patches/yosemite-setjmp.patch | 13 +++++++++++++ build/pkgs/gdb/spkg-install | 10 ++++++++++ 2 files changed, 23 insertions(+) create mode 100644 build/pkgs/gdb/patches/yosemite-setjmp.patch diff --git a/build/pkgs/gdb/patches/yosemite-setjmp.patch b/build/pkgs/gdb/patches/yosemite-setjmp.patch new file mode 100644 index 00000000000..c36ae80585c --- /dev/null +++ b/build/pkgs/gdb/patches/yosemite-setjmp.patch @@ -0,0 +1,13 @@ +Patch for building on OSX 10.10 taken from https://trac.macports.org/ticket/43973 + +--- gdb-7.7.1/gdb/darwin-nat.c.orig 2014-06-15 10:49:39.000000000 -0700 ++++ gdb-7.7.1/gdb/darwin-nat.c 2014-06-15 10:51:23.000000000 -0700 +@@ -42,7 +42,7 @@ + + #include + #include +-#include ++#include + #include + #include + #include diff --git a/build/pkgs/gdb/spkg-install b/build/pkgs/gdb/spkg-install index 01f8c15d332..d874fb79809 100755 --- a/build/pkgs/gdb/spkg-install +++ b/build/pkgs/gdb/spkg-install @@ -8,6 +8,16 @@ fi cd src +# Apply patches. +for patch in ../patches/*.patch; do + [ -r "$patch" ] || continue # Skip non-existing or non-readable patches + patch -p1 <"$patch" + if [ $? -ne 0 ]; then + echo >&2 "Error applying '$patch'" + exit 1 + fi +done + LDFLAGS="${LDFLAGS} -L${SAGE_LOCAL}/lib" export LDFLAGS From aac3a049805ab29aea8a0d3439c1eadf6605eab1 Mon Sep 17 00:00:00 2001 From: Simon King Date: Sun, 19 Oct 2014 00:09:11 +0200 Subject: [PATCH 111/698] Fix cornercase in unpickling --- src/sage/misc/bounded_integer_sequences.pyx | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index e9355f3448b..dcdf6d35ec2 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -1511,14 +1511,25 @@ cpdef BoundedIntegerSequence NewBISEQ(tuple bitset_data, mp_bitcnt_t itembitsize sage: loads(dumps(S)) == S # indirect doctest True + TESTS: + + We test a corner case:: + + sage: S = BoundedIntegerSequence(8,[]) + sage: S + <> + sage: loads(dumps(S)) == S + True + """ cdef BoundedIntegerSequence out = BoundedIntegerSequence.__new__(BoundedIntegerSequence) out.data.itembitsize = itembitsize out.data.mask_item = ((1)<0: + # bitset_unpickle assumes that out.data.data is initialised. + bitset_init(out.data.data, mp_bits_per_limb) + bitset_unpickle(out.data.data, bitset_data) return out def _biseq_stresstest(): From b182ba27bdaeb0f066daf1b575db3588b3195f89 Mon Sep 17 00:00:00 2001 From: Simon King Date: Sun, 19 Oct 2014 10:58:29 +0200 Subject: [PATCH 112/698] Use mpn_l/rshift only with nonzero shift --- src/sage/misc/bounded_integer_sequences.pyx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index dcdf6d35ec2..dbb6a01bad8 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -264,6 +264,7 @@ cdef bint concat_biseq(biseq_t R, biseq_t S1, biseq_t S2) except -1: """ R.itembitsize = S1.itembitsize # do not test == S2.itembitsize R.mask_item = S1.mask_item + cdef mp_size_t S1size_mod if S1.length==0: if S2.length==0: R.length = 0 @@ -280,8 +281,13 @@ cdef bint concat_biseq(biseq_t R, biseq_t S1, biseq_t S2) except -1: else: R.length = S1.length+S2.length bitset_init(R.data, S1.data.size+S2.data.size) - mpn_lshift(R.data.bits+(S1.data.size>>times_mp_bits_per_limb), S2.data.bits, - S2.data.limbs, S1.data.size&mod_mp_bits_per_limb) + S1size_mod = S1.data.size&mod_mp_bits_per_limb + if S1size_mod > 0: + mpn_lshift(R.data.bits+(S1.data.size>>times_mp_bits_per_limb), S2.data.bits, + S2.data.limbs, S1size_mod) + else: + mpn_copyi(R.data.bits+(S1.data.size>>times_mp_bits_per_limb), S2.data.bits, + S2.data.limbs) mpn_ior_n(R.data.bits, R.data.bits, S1.data.bits, S1.data.limbs) cdef inline bint first_bits_equal(mp_limb_t* b1, mp_limb_t* b2, mp_bitcnt_t d) except -1: From 4a0f1277de964fc01b351b9f85e83998adcf80fb Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Mon, 20 Oct 2014 21:15:09 +0200 Subject: [PATCH 113/698] Remove gmp_globals.c, gmp_globals.h and gmp.pxi --- src/c_lib/SConstruct | 4 +- src/c_lib/include/gmp_globals.h | 24 --------- src/c_lib/src/gmp_globals.c | 50 ------------------- src/sage/all.py | 1 - src/sage/combinat/expnums.pyx | 1 - src/sage/ext/gmp.pxi | 47 ----------------- src/sage/ext/multi_modular.pyx | 1 - src/sage/matrix/matrix_cyclo_dense.pyx | 2 - src/sage/quadratic_forms/count_local_2.pyx | 1 - src/sage/rings/factorint.pyx | 1 - src/sage/rings/fast_arith.pyx | 1 - src/sage/rings/fraction_field_FpT.pyx | 1 - src/sage/rings/integer.pyx | 10 +--- src/sage/rings/integer_ring.pyx | 1 - .../rings/padics/padic_generic_element.pyx | 1 - src/sage/rings/padics/padic_printing.pyx | 1 - src/sage/rings/padics/pow_computer.pyx | 1 - src/sage/rings/padics/pow_computer_ext.pyx | 1 - .../polynomial_integer_dense_flint.pyx | 16 +++--- src/sage/rings/polynomial/real_roots.pyx | 1 - .../universal_cyclotomic_field_c.pyx | 1 - 21 files changed, 9 insertions(+), 158 deletions(-) delete mode 100644 src/c_lib/include/gmp_globals.h delete mode 100644 src/c_lib/src/gmp_globals.c delete mode 100644 src/sage/ext/gmp.pxi diff --git a/src/c_lib/SConstruct b/src/c_lib/SConstruct index 18092c8d9aa..29eef02fd81 100644 --- a/src/c_lib/SConstruct +++ b/src/c_lib/SConstruct @@ -129,10 +129,10 @@ env['PYV']=platform.python_version().rsplit('.', 1)[0] includes = ['$SAGE_LOCAL/include/', '$SAGE_LOCAL/include/python$PYV/', '$SAGE_LOCAL/include/NTL/', 'include'] cFiles = Split( "convert.c interrupt.c memory.c mpn_pylong.c mpz_pylong.c") + \ - Split( "mpz_longlong.c stdsage.c gmp_globals.c" ) + Split( "mpz_longlong.c stdsage.c" ) cppFiles = Split( "ZZ_pylong.cpp ntl_wrap.cpp" ) srcFiles = cFiles + cppFiles -incFiles = Split( "ccobject.h convert.h gmp_globals.h" ) + \ +incFiles = Split( "ccobject.h convert.h" ) + \ Split( "interrupt.h memory.h mpn_pylong.h mpz_longlong.h" ) + \ Split( "mpz_pylong.h ntl_wrap.h parisage.h stdsage.h ZZ_pylong.h" ) diff --git a/src/c_lib/include/gmp_globals.h b/src/c_lib/include/gmp_globals.h deleted file mode 100644 index c89583ba1d0..00000000000 --- a/src/c_lib/include/gmp_globals.h +++ /dev/null @@ -1,24 +0,0 @@ -#include - -#ifdef __cplusplus -#define EXTERN extern "C" -#else -#define EXTERN extern -#endif - -// these vars are all used in rational reconstruction; they're cached so we don't -// have to recreate them with every call. -EXTERN mpz_t u, v, q, u0, u1, u2, v0, v1, v2, t0, t1, t2, x, y, ssqr, m2; -EXTERN mpq_t tmp; - -EXTERN mpz_t a1, a2, mod1, sage_mod2, g, s, t, xx; - -EXTERN mpz_t crtrr_a, crtrr_mod; - -EXTERN mpz_t rand_val, rand_n, rand_n1; - -EXTERN gmp_randstate_t rand_state; - -EXTERN void init_mpz_globals(); -EXTERN void clear_mpz_globals(); - diff --git a/src/c_lib/src/gmp_globals.c b/src/c_lib/src/gmp_globals.c deleted file mode 100644 index d1283230c45..00000000000 --- a/src/c_lib/src/gmp_globals.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "gmp_globals.h" - -mpz_t u, v, q, u0, u1, u2, v0, v1, v2, t0, t1, t2, x, y, ssqr, m2; -//changed sqr to ssqr due to a collision with ntl -mpq_t tmp; - -mpz_t a1, a2, mod1, sage_mod2, g, s, t, xx; - -mpz_t crtrr_a, crtrr_mod; - -mpz_t rand_val, rand_n, rand_n1; - -gmp_randstate_t rand_state; - -void init_mpz_globals() { - mpz_init(u); mpz_init(v); mpz_init(q); - mpz_init(u0); mpz_init(u1); mpz_init(u2); - mpz_init(v0); mpz_init(v1); mpz_init(v2); - mpz_init(t0); mpz_init(t1); mpz_init(t2); - mpz_init(x); mpz_init(y); - mpz_init(ssqr); mpz_init(m2); - mpq_init(tmp); - - mpz_init(a1); mpz_init(a2); mpz_init(mod1); mpz_init(sage_mod2); - mpz_init(g); mpz_init(s); mpz_init(t); mpz_init(xx); - - mpz_init(crtrr_a); mpz_init(crtrr_mod); - - mpz_init(rand_val); mpz_init(rand_n); mpz_init(rand_n1); - - gmp_randinit_default(rand_state); -} - -void clear_mpz_globals() { - mpz_clear(u); mpz_clear(v); mpz_clear(q); - mpz_clear(u0); mpz_clear(u1); mpz_clear(u2); - mpz_clear(v0); mpz_clear(v1); mpz_clear(v2); - mpz_clear(t0); mpz_clear(t1); mpz_clear(t2); - mpz_clear(x); mpz_clear(y); - mpz_clear(ssqr); mpz_clear(m2); - mpq_clear(tmp); - - mpz_clear(a1); mpz_clear(a2); mpz_clear(mod1); mpz_clear(sage_mod2); - mpz_clear(g); mpz_clear(s); mpz_clear(t); mpz_clear(xx); - - mpz_clear(crtrr_a); mpz_clear(crtrr_mod); - - mpz_clear(rand_val); mpz_clear(rand_n); mpz_clear(rand_n1); -} - diff --git a/src/sage/all.py b/src/sage/all.py index 72b79d68955..a2447c8f568 100644 --- a/src/sage/all.py +++ b/src/sage/all.py @@ -264,7 +264,6 @@ def quit_sage(verbose=True): # Free globally allocated mpir integers. import sage.rings.integer sage.rings.integer.free_integer_pool() - sage.rings.integer.clear_mpz_globals() import sage.algebras.quatalg.quaternion_algebra_element sage.algebras.quatalg.quaternion_algebra_element._clear_globals() diff --git a/src/sage/combinat/expnums.pyx b/src/sage/combinat/expnums.pyx index 3a038e0bcb6..5320a694663 100644 --- a/src/sage/combinat/expnums.pyx +++ b/src/sage/combinat/expnums.pyx @@ -9,7 +9,6 @@ AUTHORS: include "sage/ext/interrupt.pxi" include "sage/ext/stdsage.pxi" include "sage/ext/cdefs.pxi" -include "sage/ext/gmp.pxi" from sage.rings.integer cimport Integer diff --git a/src/sage/ext/gmp.pxi b/src/sage/ext/gmp.pxi deleted file mode 100644 index d71f3f609a6..00000000000 --- a/src/sage/ext/gmp.pxi +++ /dev/null @@ -1,47 +0,0 @@ -# gmp.inc -- misc. useful GMP functions that don't depend on -# other things and can be included in other files -# USAGE -# -# Include the following at the top of client .pyx file. -# -# include "gmp.pxi" -# -# to include this in a file. - -include 'sage/ext/interrupt.pxi' - -cimport libc.stdlib - -############ The following is the "one global set of vars" -cdef extern from "gmp_globals.h": - cdef mpz_t u, v, q, u0, u1, u2, v0, v1, v2, t0, t1, t2, x, y, ssqr, m2 - # changed sqr to ssqr due to a collision with ntl - cdef mpq_t tmp - - cdef mpz_t a1, a2, mod1, sage_mod2, g, s, t, xx - - cdef mpz_t crtrr_a, crtrr_mod - - cdef mpz_t rand_val, rand_n, rand_n1 - - cdef gmp_randstate_t rand_state - - void init_mpz_globals_c "init_mpz_globals"() - void clear_mpz_globals_c "clear_mpz_globals"() - -######################################################## - -cdef object mpz_to_str(mpz_t x): - """ - Convert a GMP integer to a Python string. - """ - cdef char *s - sig_on() - s = mpz_get_str(NULL, 10, x) - t = str(s) - # Emulate sage_free() to avoid needing to include stdsage.pxi - sig_block() - libc.stdlib.free(s) - sig_unblock() - sig_off() - return t diff --git a/src/sage/ext/multi_modular.pyx b/src/sage/ext/multi_modular.pyx index bffd7f04051..9ccb34acad1 100644 --- a/src/sage/ext/multi_modular.pyx +++ b/src/sage/ext/multi_modular.pyx @@ -14,7 +14,6 @@ Utility classes for multi-modular algorithms. include "sage/ext/interrupt.pxi" include "sage/ext/stdsage.pxi" -include "sage/ext/gmp.pxi" from sage.rings.integer_ring import ZZ diff --git a/src/sage/matrix/matrix_cyclo_dense.pyx b/src/sage/matrix/matrix_cyclo_dense.pyx index 87ff0d8fbd6..b627dda2ce7 100644 --- a/src/sage/matrix/matrix_cyclo_dense.pyx +++ b/src/sage/matrix/matrix_cyclo_dense.pyx @@ -35,9 +35,7 @@ AUTHORS: ###################################################################### include "sage/ext/interrupt.pxi" -# include "sage/ext/stdsage.pxi" include "sage/ext/cdefs.pxi" -include "sage/ext/gmp.pxi" include "sage/ext/random.pxi" include "sage/libs/ntl/decl.pxi" diff --git a/src/sage/quadratic_forms/count_local_2.pyx b/src/sage/quadratic_forms/count_local_2.pyx index 19e1d5ebe3b..2bd7d4aa520 100644 --- a/src/sage/quadratic_forms/count_local_2.pyx +++ b/src/sage/quadratic_forms/count_local_2.pyx @@ -3,7 +3,6 @@ Optimised Cython code for counting congruence solutions """ include "sage/ext/cdefs.pxi" -include "sage/ext/gmp.pxi" from sage.rings.arith import valuation, kronecker_symbol, is_prime from sage.rings.finite_rings.integer_mod import IntegerMod, Mod diff --git a/src/sage/rings/factorint.pyx b/src/sage/rings/factorint.pyx index b3e6b71f7c4..3deee5473e4 100644 --- a/src/sage/rings/factorint.pyx +++ b/src/sage/rings/factorint.pyx @@ -18,7 +18,6 @@ AUTHORS: #***************************************************************************** include "sage/libs/pari/decl.pxi" -include "sage/ext/gmp.pxi" include "sage/ext/stdsage.pxi" from sage.rings.integer cimport Integer diff --git a/src/sage/rings/fast_arith.pyx b/src/sage/rings/fast_arith.pyx index fdc848e29b0..d9bf7d59b3b 100644 --- a/src/sage/rings/fast_arith.pyx +++ b/src/sage/rings/fast_arith.pyx @@ -41,7 +41,6 @@ Basic arithmetic with c-integers. # The int definitions -include "sage/ext/gmp.pxi" include "sage/ext/stdsage.pxi" include "sage/libs/pari/decl.pxi" diff --git a/src/sage/rings/fraction_field_FpT.pyx b/src/sage/rings/fraction_field_FpT.pyx index 65d63818d16..0289fe782da 100644 --- a/src/sage/rings/fraction_field_FpT.pyx +++ b/src/sage/rings/fraction_field_FpT.pyx @@ -3,7 +3,6 @@ import sys include "sage/ext/cdefs.pxi" -include "sage/ext/gmp.pxi" include "sage/ext/interrupt.pxi" include "sage/ext/stdsage.pxi" diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 0ac0ec56113..8d145f97d57 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -140,7 +140,6 @@ import operator import sys -include "sage/ext/gmp.pxi" include "sage/ext/interrupt.pxi" # ctrl-c interrupt block support include "sage/ext/stdsage.pxi" from cpython.list cimport * @@ -193,12 +192,6 @@ cdef object numpy_object_interface = {'typestr': '|O'} cdef mpz_t mpz_tmp mpz_init(mpz_tmp) -def init_mpz_globals(): - init_mpz_globals_c() - -def clear_mpz_globals(): - clear_mpz_globals_c() - cdef int set_mpz(Integer self, mpz_t value): mpz_set(self.value, value) @@ -3029,7 +3022,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): elif PY_TYPE_CHECK_EXACT(other, Integer): if mpz_sgn((other).value) == 0: raise ZeroDivisionError, "Integer division by zero" - if mpz_size((x).value) > 100000: + if mpz_size(self.value) > 100000: sig_on() mpz_fdiv_qr(q.value, r.value, self.value, (other).value) sig_off() @@ -6399,7 +6392,6 @@ cdef set_zero_one_elements(): if initialized: return the_integer_ring._zero_element = Integer(0) the_integer_ring._one_element = Integer(1) - init_mpz_globals() initialized = True set_zero_one_elements() diff --git a/src/sage/rings/integer_ring.pyx b/src/sage/rings/integer_ring.pyx index a12b0d45744..c488438749b 100644 --- a/src/sage/rings/integer_ring.pyx +++ b/src/sage/rings/integer_ring.pyx @@ -52,7 +52,6 @@ other types will also coerce to the integers, when it makes sense. ########################################################################### include "sage/ext/cdefs.pxi" -include "sage/ext/gmp.pxi" include "sage/ext/stdsage.pxi" include "sage/ext/interrupt.pxi" # ctrl-c interrupt block support include "sage/ext/random.pxi" diff --git a/src/sage/rings/padics/padic_generic_element.pyx b/src/sage/rings/padics/padic_generic_element.pyx index c4522bf7cb8..352f37f0e73 100644 --- a/src/sage/rings/padics/padic_generic_element.pyx +++ b/src/sage/rings/padics/padic_generic_element.pyx @@ -27,7 +27,6 @@ AUTHORS: # http://www.gnu.org/licenses/ #***************************************************************************** -include "sage/ext/gmp.pxi" include "sage/ext/interrupt.pxi" include "sage/ext/stdsage.pxi" diff --git a/src/sage/rings/padics/padic_printing.pyx b/src/sage/rings/padics/padic_printing.pyx index 55c808ee4bb..19be0b7ab28 100644 --- a/src/sage/rings/padics/padic_printing.pyx +++ b/src/sage/rings/padics/padic_printing.pyx @@ -23,7 +23,6 @@ AUTHORS: #***************************************************************************** include "sage/ext/stdsage.pxi" -include "sage/ext/gmp.pxi" from cpython.list cimport * diff --git a/src/sage/rings/padics/pow_computer.pyx b/src/sage/rings/padics/pow_computer.pyx index 329c5fb93a3..b75902f420f 100644 --- a/src/sage/rings/padics/pow_computer.pyx +++ b/src/sage/rings/padics/pow_computer.pyx @@ -35,7 +35,6 @@ AUTHORS: import weakref from sage.rings.infinity import infinity -include "sage/ext/gmp.pxi" include "sage/ext/interrupt.pxi" include "sage/ext/stdsage.pxi" diff --git a/src/sage/rings/padics/pow_computer_ext.pyx b/src/sage/rings/padics/pow_computer_ext.pyx index ae4983cd39a..079ea57976b 100644 --- a/src/sage/rings/padics/pow_computer_ext.pyx +++ b/src/sage/rings/padics/pow_computer_ext.pyx @@ -48,7 +48,6 @@ AUTHORS: # http://www.gnu.org/licenses/ #***************************************************************************** -include "sage/ext/gmp.pxi" include "sage/ext/interrupt.pxi" include "sage/ext/stdsage.pxi" from cpython.list cimport * diff --git a/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx b/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx index 22244760ecc..4aaa88dc0de 100644 --- a/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx @@ -21,7 +21,6 @@ AUTHORS: include "sage/ext/stdsage.pxi" include "sage/ext/interrupt.pxi" -include "sage/ext/gmp.pxi" include "sage/libs/ntl/decl.pxi" from sage.rings.polynomial.polynomial_element cimport Polynomial @@ -451,19 +450,17 @@ cdef class Polynomial_integer_dense_flint(Polynomial): if name is None: name = self.parent().variable_name() cdef long i - cdef mpz_t coef - mpz_init(coef) + cdef Integer coef = PY_NEW(Integer) all = [] for i from fmpz_poly_degree(self.__poly) >= i >= 0: - fmpz_poly_get_coeff_mpz(coef, self.__poly, i) - sign = mpz_sgn(coef) - if sign: - if sign > 0: + fmpz_poly_get_coeff_mpz(coef.value, self.__poly, i) + if coef: + if coef > 0: sign_str = '+' - coeff_str = mpz_to_str(coef) + coeff_str = str(coef) else: sign_str = '-' - coeff_str = mpz_to_str(coef)[1:] + coeff_str = str(coef)[1:] if i > 0: if coeff_str == '1': coeff_str = '' @@ -480,7 +477,6 @@ cdef class Polynomial_integer_dense_flint(Polynomial): PyList_Append(all, " %s %s%s" % (sign_str, coeff_str, name)) else: PyList_Append(all, " %s %s" % (sign_str, coeff_str)) - mpz_clear(coef) if len(all) == 0: return '0' leading = all[0] diff --git a/src/sage/rings/polynomial/real_roots.pyx b/src/sage/rings/polynomial/real_roots.pyx index edf1c14c1a8..3002f28a4b5 100644 --- a/src/sage/rings/polynomial/real_roots.pyx +++ b/src/sage/rings/polynomial/real_roots.pyx @@ -155,7 +155,6 @@ cimport numpy from math import fabs include "sage/ext/cdefs.pxi" -include "sage/ext/gmp.pxi" from sage.libs.mpfr cimport * diff --git a/src/sage/rings/universal_cyclotomic_field/universal_cyclotomic_field_c.pyx b/src/sage/rings/universal_cyclotomic_field/universal_cyclotomic_field_c.pyx index ebd31e0aca5..ad31cd33e50 100644 --- a/src/sage/rings/universal_cyclotomic_field/universal_cyclotomic_field_c.pyx +++ b/src/sage/rings/universal_cyclotomic_field/universal_cyclotomic_field_c.pyx @@ -17,7 +17,6 @@ AUTHORS: #***************************************************************************** include "sage/ext/stdsage.pxi" include "sage/ext/cdefs.pxi" -include "sage/ext/gmp.pxi" import sys import operator From 1f5a53e7b23e406c553d789f83604cd4a7f90655 Mon Sep 17 00:00:00 2001 From: Simon King Date: Tue, 21 Oct 2014 16:34:51 +0200 Subject: [PATCH 114/698] Change the naming schemes of functions according to conventions in gmp and bitset --- src/sage/misc/bounded_integer_sequences.pxd | 21 +++--- src/sage/misc/bounded_integer_sequences.pyx | 84 +++++++++------------ 2 files changed, 48 insertions(+), 57 deletions(-) diff --git a/src/sage/misc/bounded_integer_sequences.pxd b/src/sage/misc/bounded_integer_sequences.pxd index a917f38cb17..96a42689ba5 100644 --- a/src/sage/misc/bounded_integer_sequences.pxd +++ b/src/sage/misc/bounded_integer_sequences.pxd @@ -1,4 +1,5 @@ from sage.libs.gmp.types cimport * +from sage.libs.gmp.mpn cimport mpn_rshift, mpn_lshift, mpn_copyi, mpn_ior_n, mpn_zero, mpn_copyd, mpn_cmp from sage.misc.bitset cimport * ctypedef struct biseq: # bounded integer sequence @@ -15,14 +16,14 @@ ctypedef struct biseq: # bounded integer sequence ctypedef biseq biseq_t[1] -cdef bint allocate_biseq(biseq_t R, mp_size_t l, mp_size_t itemsize) except -1 +cdef bint biseq_init(biseq_t R, mp_size_t l, mp_size_t itemsize) except -1 # Allocate memory (filled with zero) for a bounded integer sequence # of length l with items fitting in itemsize bits. -cdef void dealloc_biseq(biseq_t S) +cdef void biseq_dealloc(biseq_t S) # Free the data stored in S. -cdef bint copy_biseq(biseq_t R, biseq_t S) except -1 +cdef bint biseq_copy(biseq_t R, biseq_t S) except -1 # Replace the content of R by a copy of S cdef bint list_to_biseq(biseq_t R, list data, unsigned int bound) except -1 @@ -31,34 +32,34 @@ cdef bint list_to_biseq(biseq_t R, list data, unsigned int bound) except -1 cdef list biseq_to_list(biseq_t S) # Convert a bounded integer sequence to a list -cdef bint concat_biseq(biseq_t R, biseq_t S1, biseq_t S2) except -1 +cdef bint biseq_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1 # Does not test whether the sequences have the same bound! cdef bint first_bits_equal(mp_limb_t* b1, mp_limb_t* b2, mp_bitcnt_t d) except -1 # Boilerplate function for comparison of the first bits of two gmp bitsets, # mimmicking mpz_congruent_2exp_p -cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2) except -1 +cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1 # Is S1=S2+something? Does not check whether the sequences have the same # bound! -cdef int contains_biseq(biseq_t S1, biseq_t S2, mp_size_t start) except -2 +cdef int biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2 # Returns the position *in S1* of S2 as a subsequence of S1[start:], or -1 # if S2 is not a subsequence. Does not check whether the sequences have the # same bound! -cdef int max_overlap_biseq(biseq_t S1, biseq_t S2) except 0 +cdef int biseq_max_overlap(biseq_t S1, biseq_t S2) except 0 # Returns the minimal *positive* integer i such that S2 starts with S1[i:]. # This function will *not* test whether S2 starts with S1! -cdef int index_biseq(biseq_t S, mp_limb_t item, mp_size_t start) except -2 +cdef int biseq_index(biseq_t S, mp_limb_t item, mp_size_t start) except -2 # Returns the position *in S* of the item in S[start:], or -1 if S[start:] # does not contain the item. -cdef int getitem_biseq(biseq_t S, mp_size_t index) except -1 +cdef int biseq_getitem(biseq_t S, mp_size_t index) except -1 # Returns S[index], without checking margins -cdef bint slice_biseq(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1 +cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1 # Fills R with S[start:stop:step] cdef class BoundedIntegerSequence: diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/misc/bounded_integer_sequences.pyx index dbb6a01bad8..b16119b45fb 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/misc/bounded_integer_sequences.pyx @@ -14,16 +14,16 @@ which means that certain operations are implemented by using fast shift operations from GMP. The following boilerplate functions can be cimported in Cython modules: -- ``cdef bint allocate_biseq(biseq_t R, mp_size_t l, mp_size_t itemsize) except -1`` +- ``cdef bint biseq_init(biseq_t R, mp_size_t l, mp_size_t itemsize) except -1`` Allocate memory (filled with zero) for a bounded integer sequence of length l with items fitting in itemsize bits. -- ``cdef void dealloc_biseq(biseq_t S)`` +- ``cdef void biseq_dealloc(biseq_t S)`` Free the data stored in ``S``. -- ``cdef bint copy_biseq(biseq_t R, biseq_t S)`` +- ``cdef bint biseq_copy(biseq_t R, biseq_t S)`` Replace the content of ``R`` by a copy of ``S``. @@ -35,7 +35,7 @@ Cython modules: Convert a bounded integer sequence to a list. -- ``cdef bint concat_biseq(biseq_t R, biseq_t S1, biseq_t S2) except -1`` +- ``cdef bint biseq_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1`` Concatenate ``S1`` and ``S2`` and write the result to ``R``. Does not test whether the sequences have the same bound! @@ -45,32 +45,32 @@ Cython modules: Boilerplate function for comparison of the first bits of two gmp bitsets, mimmicking ``mpz_congruent_2exp_p``. -- ``cdef inline bint startswith_biseq(biseq_t S1, biseq_t S2)`` +- ``cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2)`` Is ``S1=S2+something``? Does not check whether the sequences have the same bound! -- ``cdef int contains_biseq(biseq_t S1, biseq_t S2, mp_size_t start) except -2`` +- ``cdef int biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2`` Returns the position *in ``S1``* of ``S2`` as a subsequence of ``S1[start:]``, or ``-1`` if ``S2`` is not a subsequence. Does not check whether the sequences have the same bound! -- ``cdef int max_overlap_biseq(biseq_t S1, biseq_t S2) except 0`` +- ``cdef int biseq_max_overlap(biseq_t S1, biseq_t S2) except 0`` Returns the minimal *positive* integer ``i`` such that ``S2`` starts with ``S1[i:]``. This function will *not* test whether ``S2`` starts with ``S1``! -- ``cdef int index_biseq(biseq_t S, mp_limb_t item, mp_size_t start) except -2`` +- ``cdef int biseq_index(biseq_t S, mp_limb_t item, mp_size_t start) except -2`` Returns the position *in S* of the item in ``S[start:]``, or ``-1`` if ``S[start:]`` does not contain the item. -- ``cdef int getitem_biseq(biseq_t S, mp_size_t index) except -1`` +- ``cdef int biseq_getitem(biseq_t S, mp_size_t index) except -1`` Returns ``S[index]``, without checking margins. -- ``cdef bint slice_biseq(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1`` +- ``cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1`` Fills ``R`` with ``S[start:stop:step]`` @@ -91,18 +91,8 @@ include "sage/ext/python.pxi" include "sage/libs/ntl/decl.pxi" include 'sage/misc/bitset.pxi' -#cdef extern from "mpz_pylong.h": -# cdef long mpz_pythonhash(mpz_t src) - cdef extern from "gmp.h": cdef int mp_bits_per_limb - mp_limb_t mpn_rshift(mp_ptr res, mp_ptr src, mp_size_t n, unsigned int count) - mp_limb_t mpn_lshift(mp_ptr res, mp_ptr src, mp_size_t n, unsigned int count) - void mpn_copyi(mp_ptr res, mp_ptr src, mp_size_t n) - void mpn_ior_n (mp_limb_t *rp, mp_limb_t *s1p, mp_limb_t *s2p, mp_size_t n) - void mpn_zero (mp_limb_t *rp, mp_size_t n) - void mpn_copyd (mp_limb_t *rp, mp_limb_t *s1p, mp_size_t n) - int mpn_cmp (mp_limb_t *s1p, mp_limb_t *s2p, mp_size_t n) cdef extern from "Python.h": bint PySlice_Check(PyObject* ob) @@ -127,7 +117,7 @@ from cython.operator import dereference as deref, preincrement as preinc, predec # (De)allocation, copying # -cdef bint allocate_biseq(biseq_t R, mp_size_t l, mp_size_t itemsize) except -1: +cdef bint biseq_init(biseq_t R, mp_size_t l, mp_size_t itemsize) except -1: """ Allocate memory for a bounded integer sequence of length l with items fitting in itemsize bits. @@ -138,11 +128,11 @@ cdef bint allocate_biseq(biseq_t R, mp_size_t l, mp_size_t itemsize) except -1: if l: bitset_init(R.data, l*itemsize) -cdef void dealloc_biseq(biseq_t S): +cdef void biseq_dealloc(biseq_t S): if S.length: bitset_free(S.data) -cdef bint copy_biseq(biseq_t R, biseq_t S) except -1: +cdef bint biseq_copy(biseq_t R, biseq_t S) except -1: """ Create a copy of S and store it in R, overriding R's previous content. """ @@ -174,7 +164,7 @@ cdef bint list_to_biseq(biseq_t R, list data, unsigned int bound) except -1: ln = mpz_sizeinbase(tmp, 2) if ln>mp_bits_per_limb: raise ValueError("The integer bound {} does not fit into {}".format(bound, mp_bits_per_limb)) - allocate_biseq(R, len(data), ln) + biseq_init(R, len(data), ln) mpz_clear(tmp) else: raise ValueError("The bound for the items of bounded integer sequences must be positive") @@ -247,7 +237,7 @@ cdef list biseq_to_list(biseq_t S): # Arithmetics # -cdef bint concat_biseq(biseq_t R, biseq_t S1, biseq_t S2) except -1: +cdef bint biseq_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1: """ Concatenate two bounded integer sequences ``S1`` and ``S2``. @@ -315,7 +305,7 @@ cdef inline bint first_bits_equal(mp_limb_t* b1, mp_limb_t* b2, mp_bitcnt_t d) e return (((b1[dlimbs])^(b2[dlimbs]))&(((1)<(S.data.bits[limb_index]) return out&S.mask_item -cdef bint slice_biseq(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1: +cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1: """ Create the slice S[start:stop:step] as bounded integer sequence. @@ -454,15 +444,15 @@ cdef bint slice_biseq(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int if stop>start: length = ((stop-start-1)//step)+1 else: - allocate_biseq(R, 0, S.itembitsize) + biseq_init(R, 0, S.itembitsize) return True else: if stop>=start: - allocate_biseq(R, 0, S.itembitsize) + biseq_init(R, 0, S.itembitsize) return True else: length = ((stop-start+1)//step)+1 - allocate_biseq(R, length, S.itembitsize) + biseq_init(R, length, S.itembitsize) cdef mp_size_t offset_mod, offset_div total_shift = start*S.itembitsize if step==1: @@ -528,7 +518,7 @@ cdef bint slice_biseq(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int offset_tgt += S.itembitsize offset_src += bitstep -cdef int max_overlap_biseq(biseq_t S1, biseq_t S2) except 0: +cdef int biseq_max_overlap(biseq_t S1, biseq_t S2) except 0: """ Returns the smallest **positive** integer ``i`` such that ``S2`` starts with ``S1[i:]``. @@ -800,7 +790,7 @@ cdef class BoundedIntegerSequence: sage: del S # indirect doctest """ - dealloc_biseq(self.data) + biseq_dealloc(self.data) def __init__(self, unsigned long int bound, list data): """ @@ -1106,7 +1096,7 @@ cdef class BoundedIntegerSequence: if start==0 and stop==self.data.length and step==1: return self out = BoundedIntegerSequence.__new__(BoundedIntegerSequence, 0, None) - slice_biseq(out.data, self.data, start, stop, step) + biseq_slice(out.data, self.data, start, stop, step) return out cdef long Index try: @@ -1117,7 +1107,7 @@ cdef class BoundedIntegerSequence: Index = (self.data.length)+Index if Index<0 or Index>=self.data.length: raise IndexError("Index out of range") - return getitem_biseq(self.data, Index) + return biseq_getitem(self.data, Index) def __contains__(self, other): """ @@ -1179,11 +1169,11 @@ cdef class BoundedIntegerSequence: """ if not isinstance(other, BoundedIntegerSequence): - return index_biseq(self.data, other, 0)>=0 + return biseq_index(self.data, other, 0)>=0 cdef BoundedIntegerSequence right = other if self.data.itembitsize!=right.data.itembitsize: return False - return contains_biseq(self.data, right.data, 0)>=0 + return biseq_contains(self.data, right.data, 0)>=0 cpdef list list(self): """ @@ -1244,7 +1234,7 @@ cdef class BoundedIntegerSequence: """ if self.data.itembitsize!=other.data.itembitsize: return False - return startswith_biseq(self.data, other.data) + return biseq_startswith(self.data, other.data) def index(self, other): """ @@ -1298,7 +1288,7 @@ cdef class BoundedIntegerSequence: if other<0: raise ValueError("BoundedIntegerSequence.index(x): x(={}) not in sequence".format(other)) try: - out = index_biseq(self.data, other, 0) + out = biseq_index(self.data, other, 0) except TypeError: raise ValueError("BoundedIntegerSequence.index(x): x(={}) not in sequence".format(other)) if out>=0: @@ -1307,7 +1297,7 @@ cdef class BoundedIntegerSequence: cdef BoundedIntegerSequence right = other if self.data.itembitsize!=right.data.itembitsize: raise ValueError("Not a sub-sequence") - out = contains_biseq(self.data, right.data, 0) + out = biseq_contains(self.data, right.data, 0) if out>=0: return out raise ValueError("Not a sub-sequence") @@ -1361,7 +1351,7 @@ cdef class BoundedIntegerSequence: if right.data.itembitsize!=myself.data.itembitsize: raise ValueError("can only concatenate bounded integer sequences of compatible bounds") out = BoundedIntegerSequence.__new__(BoundedIntegerSequence, 0, None) - concat_biseq(out.data, myself.data, right.data) + biseq_concat(out.data, myself.data, right.data) return out cpdef BoundedIntegerSequence maximal_overlap(self, BoundedIntegerSequence other): @@ -1386,7 +1376,7 @@ cdef class BoundedIntegerSequence: """ if other.startswith(self): return self - cdef int i = max_overlap_biseq(self.data, other.data) + cdef int i = biseq_max_overlap(self.data, other.data) if i==-1: return None return self[i:] @@ -1584,7 +1574,7 @@ def _biseq_stresstest(): elif branch == 4: S = L[randint(0,99)] T = L[randint(0,99)] - startswith_biseq(S.data,T.data) - contains_biseq(S.data, T.data, 0) + biseq_startswith(S.data,T.data) + biseq_contains(S.data, T.data, 0) if S.data.length>0: - max_overlap_biseq(S.data, T.data) + biseq_max_overlap(S.data, T.data) From ef69d1e6eb30a9551bb45d1e91f6180454d78b86 Mon Sep 17 00:00:00 2001 From: Simon King Date: Tue, 21 Oct 2014 20:29:54 +0200 Subject: [PATCH 115/698] Create sage.data_structures, move biseq into it, and amend types in biseq --- src/doc/en/reference/data_structures/conf.py | 73 ++++++++++ .../en/reference/data_structures/index.rst | 10 ++ src/doc/en/reference/index.rst | 1 + src/doc/en/reference/misc/index.rst | 1 - src/module_list.py | 12 +- src/sage/data_structures/__init__.py | 0 .../bounded_integer_sequences.pxd | 35 ++--- .../bounded_integer_sequences.pyx | 127 ++++++++---------- src/sage/libs/gmp/types.pxd | 1 + 9 files changed, 170 insertions(+), 90 deletions(-) create mode 100644 src/doc/en/reference/data_structures/conf.py create mode 100644 src/doc/en/reference/data_structures/index.rst create mode 100644 src/sage/data_structures/__init__.py rename src/sage/{misc => data_structures}/bounded_integer_sequences.pxd (69%) rename src/sage/{misc => data_structures}/bounded_integer_sequences.pyx (91%) diff --git a/src/doc/en/reference/data_structures/conf.py b/src/doc/en/reference/data_structures/conf.py new file mode 100644 index 00000000000..ae3b7eaf67f --- /dev/null +++ b/src/doc/en/reference/data_structures/conf.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +# +# Sage documentation build configuration file, created by +# sphinx-quickstart on Thu Aug 21 20:15:55 2008. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# The contents of this file are pickled, so don't put values in the namespace +# that aren't pickleable (module imports are okay, they're removed automatically). +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os +sys.path.append(os.environ['SAGE_DOC']) +from common.conf import * + +# settings for the intersphinx extension: + +ref_src = os.path.join(SAGE_DOC, 'en', 'reference') +ref_out = os.path.join(SAGE_DOC, 'output', 'html', 'en', 'reference') +intersphinx_mapping[ref_out] = None + +for doc in os.listdir(ref_src): + if os.path.exists(os.path.join(ref_src, doc, 'index.rst')): + intersphinx_mapping[os.path.join(ref_out, doc)] = None + +# We use the main document's title, if we can find it. +rst_file = open('index.rst', 'r') +rst_lines = rst_file.read().splitlines() +rst_file.close() + +title = u'' +for i in xrange(len(rst_lines)): + if rst_lines[i].startswith('==') and i > 0: + title = rst_lines[i-1].strip() + break + +# Otherwise, we use this directory's name. +name = os.path.basename(os.path.abspath('.')) +if not title: + title = name.capitalize() +title = title.replace(u'`', u'$') + +# General information about the project. +project = u'Sage Reference Manual: ' + title + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +html_title = u'Sage Reference Manual v' + release + ': ' + title + +# A shorter title for the navigation bar. Default is the same as html_title. +html_short_title = title + +# HTML theme (e.g., 'default', 'sphinxdoc'). The pages for the +# reference manual use a custom theme, a slight variant on the 'sage' +# theme, to set the links in the top line. +html_theme = 'sageref' + +# Output file base name for HTML help builder. +htmlhelp_basename = name + +# Grouping the document tree into LaTeX files. List of tuples (source +# start file, target name, title, author, document class +# [howto/manual]). +latex_documents = [ +('index', name + '.tex', project, u'The Sage Development Team', 'manual') +] + +#Ignore all .rst in the _sage subdirectory +exclude_trees = exclude_trees + ['_sage'] + +multidocs_is_master = False diff --git a/src/doc/en/reference/data_structures/index.rst b/src/doc/en/reference/data_structures/index.rst new file mode 100644 index 00000000000..8ee5dfd2ff1 --- /dev/null +++ b/src/doc/en/reference/data_structures/index.rst @@ -0,0 +1,10 @@ +Data Structures +=============== + +.. toctree:: + :maxdepth: 2 + + sage/data_structures/bounded_integer_sequences + + +.. include:: ../footer.txt diff --git a/src/doc/en/reference/index.rst b/src/doc/en/reference/index.rst index 662a07944fe..ee1b110c055 100644 --- a/src/doc/en/reference/index.rst +++ b/src/doc/en/reference/index.rst @@ -35,6 +35,7 @@ Structures, Coercion, Categories -------------------------------- * :doc:`Basic Structures ` +* :doc:`Data Structures ` * :doc:`Coercion ` * :doc:`Category Theory and Categories ` diff --git a/src/doc/en/reference/misc/index.rst b/src/doc/en/reference/misc/index.rst index f643a7ea7c9..d87adb5ae53 100644 --- a/src/doc/en/reference/misc/index.rst +++ b/src/doc/en/reference/misc/index.rst @@ -7,7 +7,6 @@ Miscellaneous sage/misc/abstract_method sage/misc/ascii_art sage/misc/bindable_class - sage/misc/bounded_integer_sequences sage/misc/cachefunc sage/misc/weak_dict sage/misc/c3 diff --git a/src/module_list.py b/src/module_list.py index 091135f95bd..42cbc0e0832 100755 --- a/src/module_list.py +++ b/src/module_list.py @@ -276,6 +276,15 @@ def uname_specific(name, value, alternative): Extension('sage.crypto.boolean_function', sources = ['sage/crypto/boolean_function.pyx']), + ################################ + ## + ## sage.data_structures + ## + ################################ + + Extension('sage.data_structures.bounded_integer_sequences', + sources = ['sage/data_structures/bounded_integer_sequences.pyx']), + ################################ ## ## sage.ext @@ -1206,9 +1215,6 @@ def uname_specific(name, value, alternative): sources = ['sage/misc/bitset.pyx'], libraries = ['gmp']), - Extension('sage.misc.bounded_integer_sequences', - sources = ['sage/misc/bounded_integer_sequences.pyx']), - Extension('sage.misc.cachefunc', sources = ['sage/misc/cachefunc.pyx']), diff --git a/src/sage/data_structures/__init__.py b/src/sage/data_structures/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/sage/misc/bounded_integer_sequences.pxd b/src/sage/data_structures/bounded_integer_sequences.pxd similarity index 69% rename from src/sage/misc/bounded_integer_sequences.pxd rename to src/sage/data_structures/bounded_integer_sequences.pxd index 96a42689ba5..4e4d4f78855 100644 --- a/src/sage/misc/bounded_integer_sequences.pxd +++ b/src/sage/data_structures/bounded_integer_sequences.pxd @@ -1,20 +1,25 @@ from sage.libs.gmp.types cimport * +from sage.libs.gmp.types cimport mp_bits_per_limb from sage.libs.gmp.mpn cimport mpn_rshift, mpn_lshift, mpn_copyi, mpn_ior_n, mpn_zero, mpn_copyd, mpn_cmp from sage.misc.bitset cimport * -ctypedef struct biseq: # bounded integer sequence - bitset_t data # Use GMP integers as bitarrays - mp_bitcnt_t itembitsize # Bitsize of one element of this sequence. Note: - # We do not store the exact bound for the items - # of this sequence, but store the bitlength that - # is sufficient to store one item. - mp_limb_t mask_item # "bla&mask_item" greps onethe item bla starts with - mp_size_t length # Number of items in this sequence. - # bitsize=length*itembitsize, but we do not want - # to repeat this multiplication and thus store - # the result. +ctypedef struct biseq_s: # bounded integer sequence + # Use GMP integers as bitarrays + bitset_t data + # Bitsize of one element of this sequence. Note: We do not store the exact + # bound for the items of this sequence, but store the bitlength that is + # sufficient to store one item. + mp_bitcnt_t itembitsize + # If `L` is a limb, then `L&mask_item` extracts the first `itembitsize` + # bits of it, i.e., it extracts one item. + mp_limb_t mask_item + # Number of items in this sequence. bitsize=length*itembitsize, but we do + # not want to repeat this multiplication and thus store the result. + mp_size_t length -ctypedef biseq biseq_t[1] +ctypedef biseq_s biseq_t[1] + +ctypedef mp_limb_t biseq_item_t cdef bint biseq_init(biseq_t R, mp_size_t l, mp_size_t itemsize) except -1 # Allocate memory (filled with zero) for a bounded integer sequence @@ -26,7 +31,7 @@ cdef void biseq_dealloc(biseq_t S) cdef bint biseq_copy(biseq_t R, biseq_t S) except -1 # Replace the content of R by a copy of S -cdef bint list_to_biseq(biseq_t R, list data, unsigned int bound) except -1 +cdef bint list_to_biseq(biseq_t R, list data, mp_limb_t bound) except -1 # Convert a list to a bounded integer sequence cdef list biseq_to_list(biseq_t S) @@ -35,7 +40,7 @@ cdef list biseq_to_list(biseq_t S) cdef bint biseq_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1 # Does not test whether the sequences have the same bound! -cdef bint first_bits_equal(mp_limb_t* b1, mp_limb_t* b2, mp_bitcnt_t d) except -1 +cdef bint biseq_first_bits_equal(mp_limb_t* b1, mp_limb_t* b2, mp_bitcnt_t d) except -1 # Boilerplate function for comparison of the first bits of two gmp bitsets, # mimmicking mpz_congruent_2exp_p @@ -56,7 +61,7 @@ cdef int biseq_index(biseq_t S, mp_limb_t item, mp_size_t start) except -2 # Returns the position *in S* of the item in S[start:], or -1 if S[start:] # does not contain the item. -cdef int biseq_getitem(biseq_t S, mp_size_t index) except -1 +cdef biseq_item_t biseq_getitem(biseq_t S, mp_size_t index) except -1 # Returns S[index], without checking margins cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1 diff --git a/src/sage/misc/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx similarity index 91% rename from src/sage/misc/bounded_integer_sequences.pyx rename to src/sage/data_structures/bounded_integer_sequences.pyx index b16119b45fb..6a729c3a7c7 100644 --- a/src/sage/misc/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -29,7 +29,7 @@ Cython modules: - ``cdef bint list_to_biseq(biseq_t R, list data, unsigned int bound) except -1`` - Convert a list to a bounded integer sequence. + Convert a list to a bounded integer sequence, which must not be allocated. - ``cdef list biseq_to_list(biseq_t S)`` @@ -40,7 +40,7 @@ Cython modules: Concatenate ``S1`` and ``S2`` and write the result to ``R``. Does not test whether the sequences have the same bound! -- ``cdef bint first_bits_equal(mp_limb_t* b1, mp_limb_t* b2, mp_bitcnt_t d) except -1`` +- ``cdef bint biseq_first_bits_equal(mp_limb_t* b1, mp_limb_t* b2, mp_bitcnt_t d) except -1`` Boilerplate function for comparison of the first bits of two gmp bitsets, mimmicking ``mpz_congruent_2exp_p``. @@ -66,7 +66,7 @@ Cython modules: Returns the position *in S* of the item in ``S[start:]``, or ``-1`` if ``S[start:]`` does not contain the item. -- ``cdef int biseq_getitem(biseq_t S, mp_size_t index) except -1`` +- ``cdef biseq_item_t biseq_getitem(biseq_t S, mp_size_t index) except -1`` Returns ``S[index]``, without checking margins. @@ -91,9 +91,6 @@ include "sage/ext/python.pxi" include "sage/libs/ntl/decl.pxi" include 'sage/misc/bitset.pxi' -cdef extern from "gmp.h": - cdef int mp_bits_per_limb - cdef extern from "Python.h": bint PySlice_Check(PyObject* ob) @@ -152,9 +149,10 @@ cdef bint biseq_copy(biseq_t R, biseq_t S) except -1: # Conversion # -cdef bint list_to_biseq(biseq_t R, list data, unsigned int bound) except -1: +cdef bint list_to_biseq(biseq_t R, list data, mp_limb_t bound) except -1: """ - Convert a list into a bounded integer sequence. + Convert a list into a bounded integer sequence and write the result into + ``R``, which must not be initialised. """ cdef mpz_t tmp @@ -162,8 +160,6 @@ cdef bint list_to_biseq(biseq_t R, list data, unsigned int bound) except -1: if bound!=0: mpz_init_set_ui(tmp, bound-1) ln = mpz_sizeinbase(tmp, 2) - if ln>mp_bits_per_limb: - raise ValueError("The integer bound {} does not fit into {}".format(bound, mp_bits_per_limb)) biseq_init(R, len(data), ln) mpz_clear(tmp) else: @@ -171,8 +167,9 @@ cdef bint list_to_biseq(biseq_t R, list data, unsigned int bound) except -1: cdef unsigned long int item cdef mp_limb_t item_limb cdef mp_limb_t tmp_limb1, tmp_limb2 - cdef int offset_mod, offset_div - cdef int offset = 0 + cdef mp_bitcnt_t offset_mod + cdef mp_size_t offset_div + cdef mp_size_t offset = 0 if not data: return True for item in data: @@ -209,23 +206,18 @@ cdef list biseq_to_list(biseq_t S): local_index = 0 # This is the index in tmp_limb tmp_limb[0] = S.data.bits[0] for n from S.length>=n>0: - #print local_index, limb_index, bit_index if local_index+S.itembitsize > mp_bits_per_limb: - #print "need more stuff" local_index = 0 # tmp_limb[0] can not provide the next item, we need to get new stuff if bit_index and limb_index < max_limbs: # We move two limbs now, so that tmp_limb[0] will be completely full - #print "shifting two limbs" mpn_rshift(tmp_limb, S.data.bits+limb_index, 2, bit_index) else: - #print "one limb is enough" # We shift within one limb tmp_limb[0] = S.data.bits[limb_index]>>bit_index #else: tmp_limb[0] provides the next item local_index += S.itembitsize - #print "next item from",Integer(tmp_limb[0]).bits(),"is",(tmp_limb[0]&S.mask_item) - L.append((tmp_limb[0]&S.mask_item)) + L.append((tmp_limb[0]&S.mask_item)) tmp_limb[0]>>=S.itembitsize bit_index += S.itembitsize if bit_index>=mp_bits_per_limb: @@ -280,7 +272,7 @@ cdef bint biseq_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1: S2.data.limbs) mpn_ior_n(R.data.bits, R.data.bits, S1.data.bits, S1.data.limbs) -cdef inline bint first_bits_equal(mp_limb_t* b1, mp_limb_t* b2, mp_bitcnt_t d) except -1: +cdef inline bint biseq_first_bits_equal(mp_limb_t* b1, mp_limb_t* b2, mp_bitcnt_t d) except -1: """ Compare the first bits of two gmp bitsets @@ -320,7 +312,7 @@ cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1: return True if S2.length>S1.length: return False - return first_bits_equal(S1.data.bits, S2.data.bits, S2.data.size) + return biseq_first_bits_equal(S1.data.bits, S2.data.bits, S2.data.size) cdef int biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2: """ @@ -365,7 +357,7 @@ cdef int biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2: mpn_rshift(tmp.bits, S1.data.bits+limb_index, S2.data.limbs, bit_index) else: mpn_copyi(tmp.bits, S1.data.bits+limb_index, S2.data.limbs) - if first_bits_equal(tmp.bits, S2.data.bits, S2.data.size): + if biseq_first_bits_equal(tmp.bits, S2.data.bits, S2.data.size): bitset_free(tmp) return index n += S1.itembitsize @@ -412,7 +404,7 @@ cdef int biseq_index(biseq_t S, mp_limb_t item, mp_size_t start) except -2: preinc(limb_index) return -1 -cdef int biseq_getitem(biseq_t S, mp_size_t index) except -1: +cdef biseq_item_t biseq_getitem(biseq_t S, mp_size_t index) except -1: """ Get item S[index], without checking margins. @@ -422,16 +414,16 @@ cdef int biseq_getitem(biseq_t S, mp_size_t index) except -1: limb_index = index>>times_mp_bits_per_limb bit_index = index&mod_mp_bits_per_limb cdef mp_limb_t tmp_limb[2] - cdef int out + cdef biseq_item_t out if bit_index: # limb_size is 1 or 2 if bit_index+S.itembitsize>mp_bits_per_limb: mpn_rshift(tmp_limb, S.data.bits+limb_index, 2, bit_index) - out = (tmp_limb[0]) + out = (tmp_limb[0]) else: - out = ((S.data.bits[limb_index])>>bit_index) + out = ((S.data.bits[limb_index])>>bit_index) else: - out = (S.data.bits[limb_index]) + out = (S.data.bits[limb_index]) return out&S.mask_item cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1: @@ -460,25 +452,17 @@ cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int offset_mod = total_shift&mod_mp_bits_per_limb offset_div = total_shift>>times_mp_bits_per_limb if offset_mod: - #print "mpn_rshift",R.data.limbs,"by",offset_mod,"bits" mpn_rshift(R.data.bits, S.data.bits+offset_div, R.data.limbs, offset_mod) # Perhaps the last to-be-moved item partially belongs to the next # limb of S? - #print "->",bitset_string(R.data) if (R.data.size&mod_mp_bits_per_limb)+offset_mod>mp_bits_per_limb: - #print "adjust the final limb" R.data.bits[R.data.limbs-1] |= (S.data.bits[offset_div+R.data.limbs]<<(mp_bits_per_limb-offset_mod)) - #print "->", bitset_string(R.data) else: - #print "just copying",R.data.limbs,"limbs" mpn_copyi(R.data.bits, S.data.bits+offset_div, R.data.limbs) - #print "->", bitset_string(R.data) # Perhaps the last few bits of the last limb have to be set to zero? offset_mod = (length*S.itembitsize)&mod_mp_bits_per_limb if offset_mod: - #print "focus on",offset_mod,"bits" R.data.bits[R.data.limbs-1] &= ((1)<",bitset_string(R.data) return True # Now for the difficult case: # @@ -570,7 +554,7 @@ cdef int biseq_max_overlap(biseq_t S1, biseq_t S2) except 0: cdef mp_bitcnt_t remaining_size = S1.data.size - n n = 0 # This now counts how many bits of the highest limb of tmp we have shifted. for index from start_index<=index @@ -771,7 +755,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) # indirect doctest <4, 1, 6, 2, 7, 20, 9> @@ -785,7 +769,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: del S # indirect doctest @@ -804,7 +788,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: L = [randint(0,26) for i in range(5000)] sage: S = BoundedIntegerSequence(57, L) # indirect doctest sage: list(S) == L @@ -842,7 +826,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(11, [4,1,6,2,7,20,9]) sage: copy(S) is S True @@ -857,7 +841,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: L = [randint(0,26) for i in range(5000)] sage: S = BoundedIntegerSequence(32, L) sage: loads(dumps(S)) == S # indirect doctest @@ -888,7 +872,7 @@ cdef class BoundedIntegerSequence: """ EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: L = [randint(0,26) for i in range(5000)] sage: S = BoundedIntegerSequence(57, L) # indirect doctest sage: len(S) == len(L) @@ -903,7 +887,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(13, [0,0,0]) sage: bool(S) True @@ -922,7 +906,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) # indirect doctest <4, 1, 6, 2, 7, 20, 9> sage: BoundedIntegerSequence(21, [0,0]) + BoundedIntegerSequence(21, [0,0]) @@ -939,12 +923,14 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) # indirect doctest <4, 1, 6, 2, 7, 20, 9> """ - return ', '.join([repr(n) for n in biseq_to_list(self.data)]) + if self.data.length==0: + return '' + return ('{!s:}'+(self.data.length-1)*', {!s:}').format(*biseq_to_list(self.data)) def bound(self): """ @@ -955,7 +941,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: T = BoundedIntegerSequence(51, [4,1,6,2,7,20,9]) sage: S.bound() @@ -970,7 +956,7 @@ cdef class BoundedIntegerSequence: """ EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: L = [randint(0,26) for i in range(5000)] sage: S = BoundedIntegerSequence(27, L) sage: list(S) == L # indirect doctest @@ -983,11 +969,11 @@ cdef class BoundedIntegerSequence: sage: S = BoundedIntegerSequence(21, [0,0,0,0,0,0,0]) sage: X = BoundedIntegerSequence(21, [4,1,6,2,7,2,3]) sage: list(X) - [4, 1, 6, 2, 7, 2, 3] + [4L, 1L, 6L, 2L, 7L, 2L, 3L] sage: list(X+S) - [4, 1, 6, 2, 7, 2, 3, 0, 0, 0, 0, 0, 0, 0] + [4L, 1L, 6L, 2L, 7L, 2L, 3L, 0L, 0L, 0L, 0L, 0L, 0L, 0L] sage: list(BoundedIntegerSequence(21, [0,0]) + BoundedIntegerSequence(21, [0,0])) - [0, 0, 0, 0] + [0L, 0L, 0L, 0L] """ if self.data.length==0: @@ -1014,7 +1000,7 @@ cdef class BoundedIntegerSequence: tmp_limb[0] = self.data.data.bits[limb_index]>>bit_index #else: tmp_limb[0] provides the next item local_index += self.data.itembitsize - yield (tmp_limb[0]&self.data.mask_item) + yield (tmp_limb[0]&self.data.mask_item) tmp_limb[0]>>=self.data.itembitsize bit_index += self.data.itembitsize if bit_index>=mp_bits_per_limb: @@ -1028,10 +1014,10 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: S[2] - 6 + 6L sage: S[1::2] <1, 2, 20> sage: S[-1::-2] @@ -1065,9 +1051,9 @@ cdef class BoundedIntegerSequence: sage: S = BoundedIntegerSequence(21, [0,0,0,0,0,0,0]) sage: X = BoundedIntegerSequence(21, [4,1,6,2,7,2,3]) sage: (X+S)[6] - 3 + 3L sage: (X+S)[10] - 0 + 0L sage: (X+S)[12:] <0, 0> @@ -1080,7 +1066,7 @@ cdef class BoundedIntegerSequence: sage: S = BoundedIntegerSequence(6, [3, 5, 3, 1, 5, 2, 2, 5, 3, 3, 4]) sage: S[10] - 4 + 4L :: @@ -1115,7 +1101,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: 6 in S True @@ -1186,7 +1172,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: L = [randint(0,26) for i in range(5000)] sage: S = BoundedIntegerSequence(32, L) sage: S.list() == list(S) == L @@ -1195,7 +1181,7 @@ cdef class BoundedIntegerSequence: The discussion at :trac:`15820` explains why the following is a good test:: sage: (BoundedIntegerSequence(21, [0,0]) + BoundedIntegerSequence(21, [0,0])).list() - [0, 0, 0, 0] + [0L, 0L, 0L, 0L] """ return biseq_to_list(self.data) @@ -1206,7 +1192,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: L = [randint(0,26) for i in range(5000)] sage: S = BoundedIntegerSequence(27, L) sage: L0 = L[:1000] @@ -1242,7 +1228,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,6,20,9]) sage: S.index(6) 2 @@ -1278,7 +1264,7 @@ cdef class BoundedIntegerSequence: sage: S = BoundedIntegerSequence(8, [2, 2, 2, 1, 2, 4, 3, 3, 3, 2, 2, 0]) sage: S[11] - 0 + 0L sage: S.index(0) 11 @@ -1313,7 +1299,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: T = BoundedIntegerSequence(21, [4,1,6,2,8,15]) sage: S+T @@ -1329,7 +1315,7 @@ cdef class BoundedIntegerSequence: sage: T+list(S) Traceback (most recent call last): ... - TypeError: Cannot convert list to sage.misc.bounded_integer_sequences.BoundedIntegerSequence + TypeError: Cannot convert list to sage.data_structures.bounded_integer_sequences.BoundedIntegerSequence sage: T+None Traceback (most recent call last): ... @@ -1362,7 +1348,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: X = BoundedIntegerSequence(21, [4,1,6,2,7,2,3]) sage: S = BoundedIntegerSequence(21, [0,0,0,0,0,0,0]) sage: T = BoundedIntegerSequence(21, [2,7,2,3,0,0,0,0,0,0,0,1]) @@ -1398,7 +1384,7 @@ cdef class BoundedIntegerSequence: Comparison by bound:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: T = BoundedIntegerSequence(51, [4,1,6,2,7,20,9]) sage: S < T @@ -1459,7 +1445,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: T = BoundedIntegerSequence(51, [4,1,6,2,7,20,9]) sage: S == T @@ -1501,7 +1487,7 @@ cpdef BoundedIntegerSequence NewBISEQ(tuple bitset_data, mp_bitcnt_t itembitsize EXAMPLES:: - sage: from sage.misc.bounded_integer_sequences import BoundedIntegerSequence + sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: L = [randint(0,26) for i in range(5000)] sage: S = BoundedIntegerSequence(32, L) sage: loads(dumps(S)) == S # indirect doctest @@ -1535,14 +1521,13 @@ def _biseq_stresstest(): TESTS:: - sage: from sage.misc.bounded_integer_sequences import _biseq_stresstest + sage: from sage.data_structures.bounded_integer_sequences import _biseq_stresstest sage: _biseq_stresstest() """ cdef int i from sage.misc.prandom import randint cdef list L = [BoundedIntegerSequence(6, [randint(0,5) for x in range(randint(4,10))]) for y in range(100)] - cdef int branch cdef BoundedIntegerSequence S, T for i from 0<=i<10000: branch = randint(0,4) diff --git a/src/sage/libs/gmp/types.pxd b/src/sage/libs/gmp/types.pxd index ea52ed2cf7e..7d92704f6f7 100644 --- a/src/sage/libs/gmp/types.pxd +++ b/src/sage/libs/gmp/types.pxd @@ -3,6 +3,7 @@ from libc.stdio cimport FILE cdef extern from "gmp.h": # GMP's configuration of how many bits are stuffed into a limb cdef unsigned int GMP_LIMB_BITS + cdef int mp_bits_per_limb ### Type Declarations ### From 83be138062f619a237e86650807c44b38eec94e5 Mon Sep 17 00:00:00 2001 From: Simon King Date: Tue, 21 Oct 2014 23:49:32 +0200 Subject: [PATCH 116/698] Reword documentation of biseq_s --- src/sage/data_structures/bounded_integer_sequences.pxd | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pxd b/src/sage/data_structures/bounded_integer_sequences.pxd index 4e4d4f78855..c60db92e28f 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pxd +++ b/src/sage/data_structures/bounded_integer_sequences.pxd @@ -4,7 +4,7 @@ from sage.libs.gmp.mpn cimport mpn_rshift, mpn_lshift, mpn_copyi, mpn_ior_n, mpn from sage.misc.bitset cimport * ctypedef struct biseq_s: # bounded integer sequence - # Use GMP integers as bitarrays + # Use bitsets to store the data, which in turn is based on GMP integers bitset_t data # Bitsize of one element of this sequence. Note: We do not store the exact # bound for the items of this sequence, but store the bitlength that is @@ -13,8 +13,7 @@ ctypedef struct biseq_s: # bounded integer sequence # If `L` is a limb, then `L&mask_item` extracts the first `itembitsize` # bits of it, i.e., it extracts one item. mp_limb_t mask_item - # Number of items in this sequence. bitsize=length*itembitsize, but we do - # not want to repeat this multiplication and thus store the result. + # Number of items in this sequence. mp_size_t length ctypedef biseq_s biseq_t[1] From 1fb819cb133e2b94bfc9222585b8762ee5efad21 Mon Sep 17 00:00:00 2001 From: Simon King Date: Wed, 22 Oct 2014 11:36:23 +0200 Subject: [PATCH 117/698] Remove a needless cimport, clarify documentation of biseq_s --- .../data_structures/bounded_integer_sequences.pxd | 15 ++++++++++----- .../data_structures/bounded_integer_sequences.pyx | 1 - 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pxd b/src/sage/data_structures/bounded_integer_sequences.pxd index c60db92e28f..205219318dc 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pxd +++ b/src/sage/data_structures/bounded_integer_sequences.pxd @@ -4,17 +4,22 @@ from sage.libs.gmp.mpn cimport mpn_rshift, mpn_lshift, mpn_copyi, mpn_ior_n, mpn from sage.misc.bitset cimport * ctypedef struct biseq_s: # bounded integer sequence - # Use bitsets to store the data, which in turn is based on GMP integers - bitset_t data + # Number of items in this sequence. + mp_size_t length # Bitsize of one element of this sequence. Note: We do not store the exact - # bound for the items of this sequence, but store the bitlength that is + # bound for the items of this sequence, but store the bitsize that is # sufficient to store one item. mp_bitcnt_t itembitsize + # A bitset comprising `length*itembitsize` bits is used to store the items + # of this sequence. Note that `bitset_t` stores the data in a field + # `mp_limb_t *bits`, where `mp_limb_t` is defined in + # `sage.libs.gmp.types`. Functions from `sage.libs.gmp.mpn` are used on + # `data.bits` for operations such as shift, comparison, or copying of + # data. + bitset_t data # If `L` is a limb, then `L&mask_item` extracts the first `itembitsize` # bits of it, i.e., it extracts one item. mp_limb_t mask_item - # Number of items in this sequence. - mp_size_t length ctypedef biseq_s biseq_t[1] diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index 6a729c3a7c7..36d223598db 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -88,7 +88,6 @@ include "sage/ext/cdefs.pxi" include "sage/ext/interrupt.pxi" include "sage/ext/stdsage.pxi" include "sage/ext/python.pxi" -include "sage/libs/ntl/decl.pxi" include 'sage/misc/bitset.pxi' cdef extern from "Python.h": From e166d38d8be72453d42325c5f6a73592ddeb3827 Mon Sep 17 00:00:00 2001 From: Simon King Date: Wed, 22 Oct 2014 13:27:46 +0200 Subject: [PATCH 118/698] Further clarification of biseq_s doc. --- src/sage/data_structures/bounded_integer_sequences.pxd | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pxd b/src/sage/data_structures/bounded_integer_sequences.pxd index 205219318dc..9f1bf17fa34 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pxd +++ b/src/sage/data_structures/bounded_integer_sequences.pxd @@ -6,9 +6,11 @@ from sage.misc.bitset cimport * ctypedef struct biseq_s: # bounded integer sequence # Number of items in this sequence. mp_size_t length - # Bitsize of one element of this sequence. Note: We do not store the exact - # bound for the items of this sequence, but store the bitsize that is - # sufficient to store one item. + # Bitsize (ranging from 1 to mp_bits_per_limb) of one item of this + # sequence. Note: Each item is a non-negative integer, and all items of + # this sequence satisfy an upper bound. We do not store the exact bound + # for the items of this sequence, but store the bitsize that is sufficient + # to store one item. mp_bitcnt_t itembitsize # A bitset comprising `length*itembitsize` bits is used to store the items # of this sequence. Note that `bitset_t` stores the data in a field From 3d293b96fa5a584684efbaae8fe667b885618797 Mon Sep 17 00:00:00 2001 From: Simon King Date: Wed, 22 Oct 2014 13:49:31 +0200 Subject: [PATCH 119/698] Fixing a corner case --- .../bounded_integer_sequences.pxd | 2 +- .../bounded_integer_sequences.pyx | 31 +++++++++++++------ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pxd b/src/sage/data_structures/bounded_integer_sequences.pxd index 9f1bf17fa34..71f98eb8540 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pxd +++ b/src/sage/data_structures/bounded_integer_sequences.pxd @@ -27,7 +27,7 @@ ctypedef biseq_s biseq_t[1] ctypedef mp_limb_t biseq_item_t -cdef bint biseq_init(biseq_t R, mp_size_t l, mp_size_t itemsize) except -1 +cdef bint biseq_init(biseq_t R, mp_size_t l, mp_bitcnt_t itemsize) except -1 # Allocate memory (filled with zero) for a bounded integer sequence # of length l with items fitting in itemsize bits. diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index 36d223598db..ee3d93b1fe9 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -113,14 +113,14 @@ from cython.operator import dereference as deref, preincrement as preinc, predec # (De)allocation, copying # -cdef bint biseq_init(biseq_t R, mp_size_t l, mp_size_t itemsize) except -1: +cdef bint biseq_init(biseq_t R, mp_size_t l, mp_bitcnt_t itemsize) except -1: """ Allocate memory for a bounded integer sequence of length l with items fitting in itemsize bits. """ R.length = l R.itembitsize = itemsize - R.mask_item = ((1)<>times_mp_bits_per_limb if mpn_cmp(b1,b2,dlimbs)!=0: return False @@ -779,11 +779,12 @@ cdef class BoundedIntegerSequence: """ INPUT: - - ``bound``, non-negative integer. When zero, a :class:`ValueError` - will be raised. Otherwise, the given bound is replaced by the next - power of two that is greater than the given bound. - - ``data``, a list of integers. The given integers will be truncated - to be less than the bound. + - ``bound``, non-negative integer that can be interpreted by an + `mp_limb_t` (which normally is an unsigned int). When zero, a + :class:`ValueError` will be raised. Otherwise, the given bound is + replaced by the next power of two that is greater than the given + bound. - ``data``, a list of integers. The given integers will be + truncated to be less than the bound. EXAMPLES:: @@ -814,6 +815,12 @@ cdef class BoundedIntegerSequence: ... ValueError: Positive bound expected + We are testing the corner case of the maximal possible bound:: + + sage: S = BoundedIntegerSequence(2^32-1, [8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10]) + sage: S + <8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10> + """ if bound==0: raise ValueError("Positive bound expected") @@ -1502,10 +1509,16 @@ cpdef BoundedIntegerSequence NewBISEQ(tuple bitset_data, mp_bitcnt_t itembitsize sage: loads(dumps(S)) == S True + And another one:: + + sage: S = BoundedIntegerSequence(2^32-1, [8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10]) + sage: loads(dumps(S)) + <8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10> + """ cdef BoundedIntegerSequence out = BoundedIntegerSequence.__new__(BoundedIntegerSequence) out.data.itembitsize = itembitsize - out.data.mask_item = ((1)<0: # bitset_unpickle assumes that out.data.data is initialised. From d22c1ca23727402e376c7f772c2f51b8ed6af1f1 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 23 Oct 2014 11:32:35 +0200 Subject: [PATCH 120/698] Lots of fixes for bounded integer sequences --- src/sage/data_structures/bitset.pxi | 16 + .../bounded_integer_sequences.pxd | 93 ++-- .../bounded_integer_sequences.pyx | 420 +++++++----------- 3 files changed, 210 insertions(+), 319 deletions(-) diff --git a/src/sage/data_structures/bitset.pxi b/src/sage/data_structures/bitset.pxi index 8698274e8ea..2291ee848d4 100644 --- a/src/sage/data_structures/bitset.pxi +++ b/src/sage/data_structures/bitset.pxi @@ -147,6 +147,22 @@ cdef inline void bitset_copy(bitset_t dst, bitset_t src): # Bitset Comparison ############################################################################# +cdef inline bint mpn_equal_bits(mp_srcptr b1, mp_srcptr b2, mp_bitcnt_t n): + """ + Return ``True`` iff the first n bits of *b1 and *b2 agree. + """ + cdef mp_size_t nlimbs = n // GMP_LIMB_BITS + cdef mp_limb_t mask = limb_lower_bits_down(n) + if nlimbs > 0 and mpn_cmp(b1, b2, nlimbs) != 0: + return False + if mask == 0: + return True + + cdef mp_limb_t b1h = b1[nlimbs] + cdef mp_limb_t b2h = b2[nlimbs] + return (b1h ^ b2h) & mask == 0 + + cdef inline bint bitset_isempty(bitset_t bits): """ Test whether bits is empty. Return True (i.e., 1) if the set is diff --git a/src/sage/data_structures/bounded_integer_sequences.pxd b/src/sage/data_structures/bounded_integer_sequences.pxd index 71f98eb8540..19c6ccf8201 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pxd +++ b/src/sage/data_structures/bounded_integer_sequences.pxd @@ -1,77 +1,52 @@ from sage.libs.gmp.types cimport * -from sage.libs.gmp.types cimport mp_bits_per_limb -from sage.libs.gmp.mpn cimport mpn_rshift, mpn_lshift, mpn_copyi, mpn_ior_n, mpn_zero, mpn_copyd, mpn_cmp -from sage.misc.bitset cimport * +from sage.data_structures.bitset cimport * + +ctypedef size_t biseq_item_t + +# A biseq (bounded integer sequence) is a sequence of non-negative +# integers, each fitting in "itembitsize" bits. We store the sequence +# in a bitset of length at least length*itembitsize. +ctypedef struct biseq_s: + # A bitset comprising at least length*itembitsize bits is used to + # store the items of this sequence. Note that bitset_t stores the + # data in a field mp_limb_t *bits, where mp_limb_t is defined in + # sage.libs.gmp.types. + # + # Normally, the "at least" in the first sentence above will be + # an equality, but we need the "at least" for the special case + # where the length is zero: then we will use a bitset of length 1. + # All extra bits (not in the first length*itembitsize) should be + # zero. + bitset_t data -ctypedef struct biseq_s: # bounded integer sequence # Number of items in this sequence. mp_size_t length - # Bitsize (ranging from 1 to mp_bits_per_limb) of one item of this - # sequence. Note: Each item is a non-negative integer, and all items of - # this sequence satisfy an upper bound. We do not store the exact bound - # for the items of this sequence, but store the bitsize that is sufficient - # to store one item. + + # Bitsize (ranging from 1 to GMP_LIMB_BITS) of one item of this + # sequence. Note: Each item is a non-negative integer, and all + # items of this sequence satisfy an upper bound. We do not store + # the exact bound for the items of this sequence, but store the + # bitsize that is sufficient to store one item. mp_bitcnt_t itembitsize - # A bitset comprising `length*itembitsize` bits is used to store the items - # of this sequence. Note that `bitset_t` stores the data in a field - # `mp_limb_t *bits`, where `mp_limb_t` is defined in - # `sage.libs.gmp.types`. Functions from `sage.libs.gmp.mpn` are used on - # `data.bits` for operations such as shift, comparison, or copying of - # data. - bitset_t data - # If `L` is a limb, then `L&mask_item` extracts the first `itembitsize` - # bits of it, i.e., it extracts one item. - mp_limb_t mask_item -ctypedef biseq_s biseq_t[1] + # If L is a limb, then "L & mask_item" extracts the first + # itembitsize bits of it, i.e., it extracts one item. + biseq_item_t mask_item -ctypedef mp_limb_t biseq_item_t +ctypedef biseq_s biseq_t[1] cdef bint biseq_init(biseq_t R, mp_size_t l, mp_bitcnt_t itemsize) except -1 - # Allocate memory (filled with zero) for a bounded integer sequence - # of length l with items fitting in itemsize bits. - cdef void biseq_dealloc(biseq_t S) - # Free the data stored in S. - -cdef bint biseq_copy(biseq_t R, biseq_t S) except -1 - # Replace the content of R by a copy of S - -cdef bint list_to_biseq(biseq_t R, list data, mp_limb_t bound) except -1 - # Convert a list to a bounded integer sequence - -cdef list biseq_to_list(biseq_t S) - # Convert a bounded integer sequence to a list - -cdef bint biseq_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1 - # Does not test whether the sequences have the same bound! - -cdef bint biseq_first_bits_equal(mp_limb_t* b1, mp_limb_t* b2, mp_bitcnt_t d) except -1 - # Boilerplate function for comparison of the first bits of two gmp bitsets, - # mimmicking mpz_congruent_2exp_p - +cdef bint biseq_init_copy(biseq_t R, biseq_t S) except -1 +cdef bint biseq_init_list(biseq_t R, list data, mp_limb_t bound) except -1 +cdef bint biseq_init_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1 cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1 - # Is S1=S2+something? Does not check whether the sequences have the same - # bound! - cdef int biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2 - # Returns the position *in S1* of S2 as a subsequence of S1[start:], or -1 - # if S2 is not a subsequence. Does not check whether the sequences have the - # same bound! - cdef int biseq_max_overlap(biseq_t S1, biseq_t S2) except 0 - # Returns the minimal *positive* integer i such that S2 starts with S1[i:]. - # This function will *not* test whether S2 starts with S1! - cdef int biseq_index(biseq_t S, mp_limb_t item, mp_size_t start) except -2 - # Returns the position *in S* of the item in S[start:], or -1 if S[start:] - # does not contain the item. - -cdef biseq_item_t biseq_getitem(biseq_t S, mp_size_t index) except -1 - # Returns S[index], without checking margins - +cdef biseq_item_t biseq_getitem(biseq_t S, mp_size_t index) +cdef biseq_getitem_py(biseq_t S, mp_size_t index) cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1 - # Fills R with S[start:stop:step] cdef class BoundedIntegerSequence: cdef biseq_t data diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index ee3d93b1fe9..f9005663819 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -23,28 +23,19 @@ Cython modules: Free the data stored in ``S``. -- ``cdef bint biseq_copy(biseq_t R, biseq_t S)`` +- ``cdef bint biseq_init_copy(biseq_t R, biseq_t S)`` - Replace the content of ``R`` by a copy of ``S``. + Copy S to the unallocated bitset R. -- ``cdef bint list_to_biseq(biseq_t R, list data, unsigned int bound) except -1`` +- ``cdef bint biseq_init_list(biseq_t R, list data, unsigned int bound) except -1`` Convert a list to a bounded integer sequence, which must not be allocated. -- ``cdef list biseq_to_list(biseq_t S)`` - - Convert a bounded integer sequence to a list. - -- ``cdef bint biseq_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1`` +- ``cdef bint biseq_init_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1`` Concatenate ``S1`` and ``S2`` and write the result to ``R``. Does not test whether the sequences have the same bound! -- ``cdef bint biseq_first_bits_equal(mp_limb_t* b1, mp_limb_t* b2, mp_bitcnt_t d) except -1`` - - Boilerplate function for comparison of the first bits of two gmp bitsets, - mimmicking ``mpz_congruent_2exp_p``. - - ``cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2)`` Is ``S1=S2+something``? Does not check whether the sequences have the same @@ -66,10 +57,14 @@ Cython modules: Returns the position *in S* of the item in ``S[start:]``, or ``-1`` if ``S[start:]`` does not contain the item. -- ``cdef biseq_item_t biseq_getitem(biseq_t S, mp_size_t index) except -1`` +- ``cdef biseq_item_t biseq_getitem(biseq_t S, mp_size_t index)`` Returns ``S[index]``, without checking margins. +- ``cdef biseq_item_t biseq_getitem_py(biseq_t S, mp_size_t index)`` + + Returns ``S[index]`` as Python ``int`` or ``long``, without checking margins. + - ``cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1`` Fills ``R`` with ``S[start:stop:step]`` @@ -77,6 +72,7 @@ Cython modules: """ #***************************************************************************** # Copyright (C) 2014 Simon King +# Copyright (C) 2014 Jeroen Demeyer # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of @@ -87,21 +83,17 @@ Cython modules: include "sage/ext/cdefs.pxi" include "sage/ext/interrupt.pxi" include "sage/ext/stdsage.pxi" -include "sage/ext/python.pxi" -include 'sage/misc/bitset.pxi' +include 'sage/data_structures/bitset.pxi' -cdef extern from "Python.h": - bint PySlice_Check(PyObject* ob) - -cdef mp_size_t times_size_of_limb = [1,2,4,8,16,32,64].index(sizeof(mp_limb_t)) -cdef mp_size_t times_mp_bits_per_limb = [1,2,4,8,16,32,64,128,256].index(mp_bits_per_limb) -cdef mp_size_t mod_mp_bits_per_limb = ((1)<ZeroNone -cdef dict EmptyDict = {} -cdef PyObject* emptyDict = EmptyDict +cdef extern from "Python.h": + cdef PyInt_FromSize_t(size_t ival) +cimport cython from cython.operator import dereference as deref, preincrement as preinc, predecrement as predec, postincrement as postinc ################### @@ -113,68 +105,69 @@ from cython.operator import dereference as deref, preincrement as preinc, predec # (De)allocation, copying # +@cython.overflowcheck cdef bint biseq_init(biseq_t R, mp_size_t l, mp_bitcnt_t itemsize) except -1: """ Allocate memory for a bounded integer sequence of length l with items fitting in itemsize bits. """ + cdef mp_bitcnt_t totalbitsize + if l: + totalbitsize = l * itemsize + else: + totalbitsize = 1 + bitset_init(R.data, totalbitsize) R.length = l R.itembitsize = itemsize R.mask_item = limb_lower_bits_up(itemsize) - if l: - bitset_init(R.data, l*itemsize) cdef void biseq_dealloc(biseq_t S): - if S.length: - bitset_free(S.data) + """ + Deallocate the memory used by S. + """ + bitset_free(S.data) -cdef bint biseq_copy(biseq_t R, biseq_t S) except -1: +cdef bint biseq_init_copy(biseq_t R, biseq_t S) except -1: """ - Create a copy of S and store it in R, overriding R's previous content. + Initialize R as a copy of S. """ - if S.length: - if R.length: - bitset_realloc(R.data, S.data.size) - else: - bitset_init(R.data, S.data.size) - mpn_copyi(R.data.bits, S.data.bits, S.data.limbs) - elif R.length: - bitset_free(R.data) - R.length = S.length - R.itembitsize = S.itembitsize - R.mask_item = S.mask_item + biseq_init(R, S.length, S.itembitsize) + bitset_copy(R.data, S.data) # # Conversion # -cdef bint list_to_biseq(biseq_t R, list data, mp_limb_t bound) except -1: +cdef bint biseq_init_list(biseq_t R, list data, mp_limb_t bound) except -1: """ - Convert a list into a bounded integer sequence and write the result into - ``R``, which must not be initialised. + Convert a list into a bounded integer sequence and write the result + into ``R``, which must not be initialised. + + INPUT: + + - ``data`` -- a list of integers + - ``bound`` -- a number which is the maximal number which can be + represented """ - cdef mpz_t tmp - cdef mp_size_t ln - if bound!=0: - mpz_init_set_ui(tmp, bound-1) - ln = mpz_sizeinbase(tmp, 2) - biseq_init(R, len(data), ln) - mpz_clear(tmp) - else: - raise ValueError("The bound for the items of bounded integer sequences must be positive") - cdef unsigned long int item cdef mp_limb_t item_limb cdef mp_limb_t tmp_limb1, tmp_limb2 cdef mp_bitcnt_t offset_mod cdef mp_size_t offset_div cdef mp_size_t offset = 0 - if not data: - return True + + if not (bound <= SIZE_MAX): + raise OverflowError("bound can be at most %s" % SIZE_MAX) + bound |= 1 # A bound of 0 should become 1 + biseq_init(R, len(data), BIT_COUNT(bound)) + for item in data: - item_limb = (item&R.mask_item) - offset_mod = offset&mod_mp_bits_per_limb - offset_div = offset>>times_mp_bits_per_limb + item_limb = item + #if item_limb > bound: + # raise ValueError("list item %r larger than %s"%(item, bound) ) + item_limb &= R.mask_item + offset_mod = offset % GMP_LIMB_BITS + offset_div = offset // GMP_LIMB_BITS if offset_mod: tmp_limb2 = mpn_lshift(&tmp_limb1, &item_limb, 1, offset_mod) if tmp_limb2: @@ -187,113 +180,27 @@ cdef bint list_to_biseq(biseq_t R, list data, mp_limb_t bound) except -1: R.data.bits[offset_div] = item_limb offset += R.itembitsize -cdef list biseq_to_list(biseq_t S): - """ - Convert a bounded integer sequence to a list of integers. - """ - cdef mp_size_t limb_index, max_limbs - cdef mp_bitcnt_t bit_index, local_index - cdef list L = [] - if S.length==0: - return L - max_limbs = S.data.limbs - predec(max_limbs) - cdef mp_size_t n - cdef mp_limb_t tmp_limb[2] - limb_index = 0 - bit_index = 0 # This is the index mod mp_bits_per_limb in S.data - local_index = 0 # This is the index in tmp_limb - tmp_limb[0] = S.data.bits[0] - for n from S.length>=n>0: - if local_index+S.itembitsize > mp_bits_per_limb: - local_index = 0 - # tmp_limb[0] can not provide the next item, we need to get new stuff - if bit_index and limb_index < max_limbs: - # We move two limbs now, so that tmp_limb[0] will be completely full - mpn_rshift(tmp_limb, S.data.bits+limb_index, 2, bit_index) - else: - # We shift within one limb - tmp_limb[0] = S.data.bits[limb_index]>>bit_index - #else: tmp_limb[0] provides the next item - local_index += S.itembitsize - L.append((tmp_limb[0]&S.mask_item)) - tmp_limb[0]>>=S.itembitsize - bit_index += S.itembitsize - if bit_index>=mp_bits_per_limb: - bit_index -= mp_bits_per_limb - preinc(limb_index) - return L - # # Arithmetics # -cdef bint biseq_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1: +cdef bint biseq_init_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1: """ Concatenate two bounded integer sequences ``S1`` and ``S2``. ASSUMPTION: - The two sequences must have equivalent bounds, i.e., the items on the - sequences must fit into the same number of bits. This condition is not - tested. + sequences must fit into the same number of bits. OUTPUT: The result is written into ``R``, which must not be initialised - """ - R.itembitsize = S1.itembitsize # do not test == S2.itembitsize - R.mask_item = S1.mask_item - cdef mp_size_t S1size_mod - if S1.length==0: - if S2.length==0: - R.length = 0 - return True - else: - R.length = S2.length - bitset_init(R.data, S2.data.size) - mpn_copyi(R.data.bits, S2.data.bits, S2.data.limbs) - else: - if S2.length==0: - R.length = S1.length - bitset_init(R.data, S1.data.size) - mpn_copyi(R.data.bits, S1.data.bits, S1.data.limbs) - else: - R.length = S1.length+S2.length - bitset_init(R.data, S1.data.size+S2.data.size) - S1size_mod = S1.data.size&mod_mp_bits_per_limb - if S1size_mod > 0: - mpn_lshift(R.data.bits+(S1.data.size>>times_mp_bits_per_limb), S2.data.bits, - S2.data.limbs, S1size_mod) - else: - mpn_copyi(R.data.bits+(S1.data.size>>times_mp_bits_per_limb), S2.data.bits, - S2.data.limbs) - mpn_ior_n(R.data.bits, R.data.bits, S1.data.bits, S1.data.limbs) - -cdef inline bint biseq_first_bits_equal(mp_limb_t* b1, mp_limb_t* b2, mp_bitcnt_t d) except -1: - """ - Compare the first bits of two gmp bitsets - - INPUT: - - - b1,b2: Pointers to bitsets - - d: The number of bits to be compared - - ASSUMPTION: - - d must not exceed the length of either bitset. - - """ - cdef mp_size_t i, dlimbs - cdef mp_bitcnt_t dbits - dlimbs = d>>times_mp_bits_per_limb - if mpn_cmp(b1,b2,dlimbs)!=0: - return False - dbits = d&mod_mp_bits_per_limb - if dbits==0: - return True - return (((b1[dlimbs])^(b2[dlimbs]))&(((1)<S1.length: + if S2.length > S1.length: return False - return biseq_first_bits_equal(S1.data.bits, S2.data.bits, S2.data.size) + return mpn_equal_bits(S1.data.bits, S2.data.bits, S2.data.size) + cdef int biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2: """ @@ -339,24 +245,24 @@ cdef int biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2: if S2.length==0: return start cdef bitset_t tmp - bitset_init(tmp, S2.data.size+mp_bits_per_limb) + bitset_init(tmp, S2.data.size+GMP_LIMB_BITS) cdef mp_size_t index = 0 cdef mp_bitcnt_t n = 0 cdef mp_size_t limb_index, bit_index - cdef mp_bitcnt_t offset = S2.data.size&mod_mp_bits_per_limb + cdef mp_bitcnt_t offset = S2.data.size % GMP_LIMB_BITS for index from start <= index <= S1.length-S2.length: - limb_index = n>>times_mp_bits_per_limb - bit_index = n&mod_mp_bits_per_limb + limb_index = n // GMP_LIMB_BITS + bit_index = n % GMP_LIMB_BITS # We shift a part of S1 (with length S2) by bit_index, and compare # with S2. if bit_index: - if offset+bit_index>mp_bits_per_limb: + if offset+bit_index>GMP_LIMB_BITS: mpn_rshift(tmp.bits, S1.data.bits+limb_index, S2.data.limbs+1, bit_index) else: mpn_rshift(tmp.bits, S1.data.bits+limb_index, S2.data.limbs, bit_index) else: mpn_copyi(tmp.bits, S1.data.bits+limb_index, S2.data.limbs) - if biseq_first_bits_equal(tmp.bits, S2.data.bits, S2.data.size): + if mpn_equal_bits(tmp.bits, S2.data.bits, S2.data.size): bitset_free(tmp) return index n += S1.itembitsize @@ -378,12 +284,12 @@ cdef int biseq_index(biseq_t S, mp_limb_t item, mp_size_t start) except -2: cdef mp_size_t n cdef mp_limb_t tmp_limb[2] limb_index = 0 - bit_index = 0 # This is the index mod mp_bits_per_limb in S.data + bit_index = 0 # This is the index mod GMP_LIMB_BITS in S.data local_index = 0 # This is the index in tmp_limb tmp_limb[0] = S.data.bits[0] item &= S.mask_item for n from 0<=n mp_bits_per_limb: + if local_index+S.itembitsize > GMP_LIMB_BITS: local_index = 0 # tmp_limb[0] can not provide the next item, we need to get new stuff if bit_index and limb_index < max_limbs: @@ -398,32 +304,37 @@ cdef int biseq_index(biseq_t S, mp_limb_t item, mp_size_t start) except -2: return n tmp_limb[0]>>=S.itembitsize bit_index += S.itembitsize - if bit_index>=mp_bits_per_limb: - bit_index -= mp_bits_per_limb + if bit_index>=GMP_LIMB_BITS: + bit_index -= GMP_LIMB_BITS preinc(limb_index) return -1 -cdef biseq_item_t biseq_getitem(biseq_t S, mp_size_t index) except -1: + +cdef inline biseq_item_t biseq_getitem(biseq_t S, mp_size_t index): """ Get item S[index], without checking margins. """ - cdef mp_size_t limb_index, bit_index - index *= S.itembitsize - limb_index = index>>times_mp_bits_per_limb - bit_index = index&mod_mp_bits_per_limb - cdef mp_limb_t tmp_limb[2] - cdef biseq_item_t out - if bit_index: - # limb_size is 1 or 2 - if bit_index+S.itembitsize>mp_bits_per_limb: - mpn_rshift(tmp_limb, S.data.bits+limb_index, 2, bit_index) - out = (tmp_limb[0]) - else: - out = ((S.data.bits[limb_index])>>bit_index) - else: - out = (S.data.bits[limb_index]) - return out&S.mask_item + cdef mp_bitcnt_t limb_index, bit_index + bit_index = (index) * S.itembitsize + limb_index = bit_index // GMP_LIMB_BITS + bit_index %= GMP_LIMB_BITS + + cdef mp_limb_t out + out = (S.data.bits[limb_index]) >> bit_index + if bit_index + S.itembitsize > GMP_LIMB_BITS: + # Our item is stored using 2 limbs, add the part from the upper limb + out |= (S.data.bits[limb_index+1]) << (GMP_LIMB_BITS - bit_index) + return out & S.mask_item + +cdef biseq_getitem_py(biseq_t S, mp_size_t index): + """ + Get item S[index] as a Python ``int`` or ``long``, without checking margins. + + """ + cdef size_t out = biseq_getitem(S, index) + return PyInt_FromSize_t(out) + cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1: """ @@ -448,18 +359,18 @@ cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int total_shift = start*S.itembitsize if step==1: # Slicing essentially boils down to a shift operation. - offset_mod = total_shift&mod_mp_bits_per_limb - offset_div = total_shift>>times_mp_bits_per_limb + offset_mod = total_shift % GMP_LIMB_BITS + offset_div = total_shift // GMP_LIMB_BITS if offset_mod: mpn_rshift(R.data.bits, S.data.bits+offset_div, R.data.limbs, offset_mod) # Perhaps the last to-be-moved item partially belongs to the next # limb of S? - if (R.data.size&mod_mp_bits_per_limb)+offset_mod>mp_bits_per_limb: - R.data.bits[R.data.limbs-1] |= (S.data.bits[offset_div+R.data.limbs]<<(mp_bits_per_limb-offset_mod)) + if (R.data.size % GMP_LIMB_BITS)+offset_mod>GMP_LIMB_BITS: + R.data.bits[R.data.limbs-1] |= (S.data.bits[offset_div+R.data.limbs]<<(GMP_LIMB_BITS-offset_mod)) else: mpn_copyi(R.data.bits, S.data.bits+offset_div, R.data.limbs) # Perhaps the last few bits of the last limb have to be set to zero? - offset_mod = (length*S.itembitsize)&mod_mp_bits_per_limb + offset_mod = (length*S.itembitsize) % GMP_LIMB_BITS if offset_mod: R.data.bits[R.data.limbs-1] &= ((1)<=n>0: - offset_div_src = offset_src>>times_mp_bits_per_limb - offset_mod_src = offset_src&mod_mp_bits_per_limb - offset_div_tgt = offset_tgt>>times_mp_bits_per_limb - offset_mod_tgt = offset_tgt&mod_mp_bits_per_limb + offset_div_src = offset_src // GMP_LIMB_BITS + offset_mod_src = offset_src % GMP_LIMB_BITS + offset_div_tgt = offset_tgt // GMP_LIMB_BITS + offset_mod_tgt = offset_tgt % GMP_LIMB_BITS # put data from src to tmp_limb[0]. if offset_mod_src: - if (offset_mod_src+S.itembitsize > mp_bits_per_limb): + if (offset_mod_src+S.itembitsize > GMP_LIMB_BITS): mpn_rshift(tmp_limb, S.data.bits+offset_div_src, 2, offset_mod_src) tmp_limb[0] &= S.mask_item else: @@ -538,14 +449,14 @@ cdef int biseq_max_overlap(biseq_t S1, biseq_t S2) except 0: n = S1.itembitsize*start_index ## Initilise the temporary bitset # Allocate an additional limb, to cope with shifting accross limb borders - bitset_init(tmp, (mp_bits_per_limb+S1.data.size)-n) + bitset_init(tmp, (GMP_LIMB_BITS+S1.data.size)-n) cdef mp_size_t nlimbs = tmp.limbs # number of to-be-shifted limbs - limb_index = n>>times_mp_bits_per_limb - bit_index = n&mod_mp_bits_per_limb + limb_index = n // GMP_LIMB_BITS + bit_index = n % GMP_LIMB_BITS if bit_index==0: mpn_copyi(tmp.bits, S1.data.bits+limb_index, predec(nlimbs)) else: - if ((S1.data.size-n)&mod_mp_bits_per_limb)+bit_index>mp_bits_per_limb: + if ((S1.data.size-n) % GMP_LIMB_BITS)+bit_index>GMP_LIMB_BITS: # Need to shift an additional limb mpn_rshift(tmp.bits, S1.data.bits+limb_index, nlimbs, bit_index) else: @@ -553,11 +464,11 @@ cdef int biseq_max_overlap(biseq_t S1, biseq_t S2) except 0: cdef mp_bitcnt_t remaining_size = S1.data.size - n n = 0 # This now counts how many bits of the highest limb of tmp we have shifted. for index from start_index<=index=mp_bits_per_limb: + if n>=GMP_LIMB_BITS: mpn_rshift(tmp.bits, tmp.bits, predec(nlimbs), S1.itembitsize) n = 0 else: @@ -723,7 +634,7 @@ cdef class BoundedIntegerSequence: sage: BoundedIntegerSequence(16, [2, 7, -20]) Traceback (most recent call last): ... - OverflowError: can't convert negative value to unsigned long + OverflowError: can't convert negative value to mp_limb_t sage: BoundedIntegerSequence(1, [2, 7, 0]) <0, 1, 0> sage: BoundedIntegerSequence(0, [2, 7, 0]) @@ -775,15 +686,15 @@ cdef class BoundedIntegerSequence: """ biseq_dealloc(self.data) - def __init__(self, unsigned long int bound, list data): + def __init__(self, mp_limb_t bound, list data): """ INPUT: - - ``bound``, non-negative integer that can be interpreted by an - `mp_limb_t` (which normally is an unsigned int). When zero, a - :class:`ValueError` will be raised. Otherwise, the given bound is - replaced by the next power of two that is greater than the given - bound. - ``data``, a list of integers. The given integers will be + - ``bound`` -- non-negative. When zero, a :class:`ValueError` + will be raised. Otherwise, the given bound is replaced by the + next power of two that is greater than the given + bound. + - ``data`` -- a list of integers. The given integers will be truncated to be less than the bound. EXAMPLES:: @@ -809,7 +720,7 @@ cdef class BoundedIntegerSequence: sage: BoundedIntegerSequence(-1, L) Traceback (most recent call last): ... - OverflowError: can't convert negative value to unsigned long + OverflowError: can't convert negative value to mp_limb_t sage: BoundedIntegerSequence(0, L) Traceback (most recent call last): ... @@ -824,7 +735,7 @@ cdef class BoundedIntegerSequence: """ if bound==0: raise ValueError("Positive bound expected") - list_to_biseq(self.data, data, bound) + biseq_init_list(self.data, data, bound-1) def __copy__(self): """ @@ -936,7 +847,7 @@ cdef class BoundedIntegerSequence: """ if self.data.length==0: return '' - return ('{!s:}'+(self.data.length-1)*', {!s:}').format(*biseq_to_list(self.data)) + return ('{!s:}'+(self.data.length-1)*', {!s:}').format(*self.list()) def bound(self): """ @@ -975,11 +886,11 @@ cdef class BoundedIntegerSequence: sage: S = BoundedIntegerSequence(21, [0,0,0,0,0,0,0]) sage: X = BoundedIntegerSequence(21, [4,1,6,2,7,2,3]) sage: list(X) - [4L, 1L, 6L, 2L, 7L, 2L, 3L] + [4, 1, 6, 2, 7, 2, 3] sage: list(X+S) - [4L, 1L, 6L, 2L, 7L, 2L, 3L, 0L, 0L, 0L, 0L, 0L, 0L, 0L] + [4, 1, 6, 2, 7, 2, 3, 0, 0, 0, 0, 0, 0, 0] sage: list(BoundedIntegerSequence(21, [0,0]) + BoundedIntegerSequence(21, [0,0])) - [0L, 0L, 0L, 0L] + [0, 0, 0, 0] """ if self.data.length==0: @@ -991,11 +902,11 @@ cdef class BoundedIntegerSequence: cdef mp_size_t n cdef mp_limb_t tmp_limb[2] limb_index = 0 - bit_index = 0 # This is the index mod mp_bits_per_limb in self.data.data + bit_index = 0 # This is the index mod GMP_LIMB_BITS in self.data.data local_index = 0 # This is the index in tmp_limb tmp_limb[0] = self.data.data.bits[0] for n from self.data.length>=n>0: - if local_index+self.data.itembitsize > mp_bits_per_limb: + if local_index+self.data.itembitsize > GMP_LIMB_BITS: local_index = 0 # tmp_limb[0] can not provide the next item, we need to get new stuff if bit_index and limb_index < max_limbs: @@ -1009,8 +920,8 @@ cdef class BoundedIntegerSequence: yield (tmp_limb[0]&self.data.mask_item) tmp_limb[0]>>=self.data.itembitsize bit_index += self.data.itembitsize - if bit_index>=mp_bits_per_limb: - bit_index -= mp_bits_per_limb + if bit_index>=GMP_LIMB_BITS: + bit_index -= GMP_LIMB_BITS preinc(limb_index) @@ -1023,7 +934,7 @@ cdef class BoundedIntegerSequence: sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: S[2] - 6L + 6 sage: S[1::2] <1, 2, 20> sage: S[-1::-2] @@ -1057,9 +968,9 @@ cdef class BoundedIntegerSequence: sage: S = BoundedIntegerSequence(21, [0,0,0,0,0,0,0]) sage: X = BoundedIntegerSequence(21, [4,1,6,2,7,2,3]) sage: (X+S)[6] - 3L + 3 sage: (X+S)[10] - 0L + 0 sage: (X+S)[12:] <0, 0> @@ -1072,7 +983,7 @@ cdef class BoundedIntegerSequence: sage: S = BoundedIntegerSequence(6, [3, 5, 3, 1, 5, 2, 2, 5, 3, 3, 4]) sage: S[10] - 4L + 4 :: @@ -1082,24 +993,24 @@ cdef class BoundedIntegerSequence: """ cdef BoundedIntegerSequence out - cdef int start,stop,step - if PySlice_Check(index): - start,stop,step = index.indices(self.data.length) + cdef Py_ssize_t start, stop, step, slicelength + if PySlice_Check(index): + PySlice_GetIndicesEx(index, self.data.length, &start, &stop, &step, &slicelength) if start==0 and stop==self.data.length and step==1: return self out = BoundedIntegerSequence.__new__(BoundedIntegerSequence, 0, None) biseq_slice(out.data, self.data, start, stop, step) return out - cdef long Index + cdef Py_ssize_t ind try: - Index = index + ind = index except TypeError: raise TypeError("Sequence index must be integer or slice") - if Index<0: - Index = (self.data.length)+Index - if Index<0 or Index>=self.data.length: - raise IndexError("Index out of range") - return biseq_getitem(self.data, Index) + if ind < 0: + ind += self.data.length + if ind < 0 or ind >= self.data.length: + raise IndexError("ind out of range") + return biseq_getitem_py(self.data, ind) def __contains__(self, other): """ @@ -1187,10 +1098,11 @@ cdef class BoundedIntegerSequence: The discussion at :trac:`15820` explains why the following is a good test:: sage: (BoundedIntegerSequence(21, [0,0]) + BoundedIntegerSequence(21, [0,0])).list() - [0L, 0L, 0L, 0L] + [0, 0, 0, 0] """ - return biseq_to_list(self.data) + cdef mp_size_t i + return [biseq_getitem_py(self.data, i) for i in range(self.data.length)] cpdef bint startswith(self, BoundedIntegerSequence other): """ @@ -1224,7 +1136,7 @@ cdef class BoundedIntegerSequence: False """ - if self.data.itembitsize!=other.data.itembitsize: + if self.data.itembitsize != other.data.itembitsize: return False return biseq_startswith(self.data, other.data) @@ -1270,7 +1182,7 @@ cdef class BoundedIntegerSequence: sage: S = BoundedIntegerSequence(8, [2, 2, 2, 1, 2, 4, 3, 3, 3, 2, 2, 0]) sage: S[11] - 0L + 0 sage: S.index(0) 11 @@ -1329,10 +1241,14 @@ cdef class BoundedIntegerSequence: TESTS: - The discussion at :trac:`15820` explains why the following is a good test:: + The discussion at :trac:`15820` explains why the following are good tests:: sage: BoundedIntegerSequence(21, [0,0]) + BoundedIntegerSequence(21, [0,0]) <0, 0, 0, 0> + sage: B1 = BoundedIntegerSequence(2^30, [10^9+1, 10^9+2]) + sage: B2 = BoundedIntegerSequence(2^30, [10^9+3, 10^9+4]) + sage: B1 + B2 + <1000000001, 1000000002, 1000000003, 1000000004> """ cdef BoundedIntegerSequence myself, right, out @@ -1340,10 +1256,10 @@ cdef class BoundedIntegerSequence: raise TypeError('Cannot concatenate bounded integer sequence and None') myself = self # may result in a type error right = other # --"-- - if right.data.itembitsize!=myself.data.itembitsize: + if right.data.itembitsize != myself.data.itembitsize: raise ValueError("can only concatenate bounded integer sequences of compatible bounds") out = BoundedIntegerSequence.__new__(BoundedIntegerSequence, 0, None) - biseq_concat(out.data, myself.data, right.data) + biseq_init_concat(out.data, myself.data, right.data) return out cpdef BoundedIntegerSequence maximal_overlap(self, BoundedIntegerSequence other): @@ -1443,7 +1359,7 @@ cdef class BoundedIntegerSequence: c = cmp(Self.data.length, right.data.length) if c: return c - return mpn_cmp(Self.data.data.bits, right.data.data.bits, Self.data.data.limbs) + return bitset_cmp(Self.data.data, right.data.data) def __hash__(self): """ @@ -1469,23 +1385,7 @@ cdef class BoundedIntegerSequence: True """ - # This is similar to mpz_pythonhash, which is a very bad additive hash: - cdef mp_limb_t h = 0 - cdef mp_limb_t h0 - cdef mp_size_t i - cdef mp_limb_t* p = self.data.data.bits - for i from self.data.data.limbs>i>=0: - h0 = h - h += deref(postinc(p)) - if h0: - # bitset_unpickle assumes that out.data.data is initialised. - bitset_init(out.data.data, mp_bits_per_limb) - bitset_unpickle(out.data.data, bitset_data) + + # bitset_unpickle assumes that out.data.data is initialised. + bitset_init(out.data.data, GMP_LIMB_BITS) + bitset_unpickle(out.data.data, bitset_data) return out def _biseq_stresstest(): From 41c40cf2c59734e7e665ba9c2350da2930c9cc8e Mon Sep 17 00:00:00 2001 From: Simon King Date: Thu, 23 Oct 2014 14:48:32 +0200 Subject: [PATCH 121/698] Don't use mpn_rshift for shifting two limbs --- .../bounded_integer_sequences.pyx | 64 ++++++++----------- 1 file changed, 27 insertions(+), 37 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index f9005663819..f63905e166f 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -197,7 +197,6 @@ cdef bint biseq_init_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1: The result is written into ``R``, which must not be initialised """ - assert S1.itembitsize == S2.itembitsize biseq_init(R, S1.length + S2.length, S1.itembitsize) bitset_lshift(R.data, S2.data, S1.length * S1.itembitsize) bitset_or(R.data, R.data, S1.data) @@ -279,30 +278,26 @@ cdef int biseq_index(biseq_t S, mp_limb_t item, mp_size_t start) except -2: cdef mp_bitcnt_t bit_index, local_index if S.length==0: return -1 - max_limbs = S.data.limbs - predec(max_limbs) + max_limbs = S.data.limbs - 1 cdef mp_size_t n - cdef mp_limb_t tmp_limb[2] + cdef mp_limb_t tmp_limb limb_index = 0 bit_index = 0 # This is the index mod GMP_LIMB_BITS in S.data local_index = 0 # This is the index in tmp_limb - tmp_limb[0] = S.data.bits[0] + tmp_limb = S.data.bits[0] item &= S.mask_item for n from 0<=n GMP_LIMB_BITS: local_index = 0 # tmp_limb[0] can not provide the next item, we need to get new stuff + tmp_limb = S.data.bits[limb_index]>>bit_index if bit_index and limb_index < max_limbs: - # We move two limbs now, so that tmp_limb[0] will be completely full - mpn_rshift(tmp_limb, S.data.bits+limb_index, 2, bit_index) - else: - # We shift within one limb - tmp_limb[0] = S.data.bits[limb_index]>>bit_index - #else: tmp_limb[0] provides the next item + # We fill the rest of tmp_limb + tmp_limb |= (S.data.bits[limb_index+1]) << (GMP_LIMB_BITS - bit_index) local_index += S.itembitsize - if item == tmp_limb[0]&S.mask_item: + if item == tmp_limb&S.mask_item: return n - tmp_limb[0]>>=S.itembitsize + tmp_limb>>=S.itembitsize bit_index += S.itembitsize if bit_index>=GMP_LIMB_BITS: bit_index -= GMP_LIMB_BITS @@ -378,7 +373,7 @@ cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int # # Convention for variable names: We move data from *_src to *_tgt # tmp_limb is used to temporarily store the data that we move/shift - cdef mp_limb_t tmp_limb[2] + cdef mp_limb_t tmp_limb cdef mp_limb_t tmp_limb2 cdef mp_size_t offset_div_src, max_limb cdef mp_bitcnt_t offset_mod_src @@ -392,23 +387,22 @@ cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int offset_mod_src = offset_src % GMP_LIMB_BITS offset_div_tgt = offset_tgt // GMP_LIMB_BITS offset_mod_tgt = offset_tgt % GMP_LIMB_BITS - # put data from src to tmp_limb[0]. + # put data from src to tmp_limb. if offset_mod_src: + tmp_limb = ((S.data.bits[offset_div_src])>>offset_mod_src) if (offset_mod_src+S.itembitsize > GMP_LIMB_BITS): - mpn_rshift(tmp_limb, S.data.bits+offset_div_src, 2, offset_mod_src) - tmp_limb[0] &= S.mask_item - else: - tmp_limb[0] = ((S.data.bits[offset_div_src])>>offset_mod_src) & S.mask_item + tmp_limb |= (S.data.bits[offset_div_src+1]) << (GMP_LIMB_BITS - offset_mod_src) + tmp_limb &= S.mask_item else: - tmp_limb[0] = S.data.bits[offset_div_src] & S.mask_item - # put data from tmp_limb[0] to tgt + tmp_limb = S.data.bits[offset_div_src] & S.mask_item + # put data from tmp_limb to tgt if offset_mod_tgt: - tmp_limb2 = mpn_lshift(tmp_limb, tmp_limb, 1, offset_mod_tgt) + tmp_limb2 = mpn_lshift(&tmp_limb, &tmp_limb, 1, offset_mod_tgt) if tmp_limb2: R.data.bits[offset_div_tgt+1] = tmp_limb2 - R.data.bits[offset_div_tgt] |= tmp_limb[0] + R.data.bits[offset_div_tgt] |= tmp_limb else: - R.data.bits[offset_div_tgt] = tmp_limb[0] + R.data.bits[offset_div_tgt] = tmp_limb offset_tgt += S.itembitsize offset_src += bitstep @@ -897,28 +891,24 @@ cdef class BoundedIntegerSequence: return cdef mp_size_t limb_index, max_limbs cdef mp_bitcnt_t bit_index, local_index - max_limbs = self.data.data.limbs - predec(max_limbs) + max_limbs = self.data.data.limbs-1 cdef mp_size_t n - cdef mp_limb_t tmp_limb[2] + cdef mp_limb_t tmp_limb limb_index = 0 bit_index = 0 # This is the index mod GMP_LIMB_BITS in self.data.data local_index = 0 # This is the index in tmp_limb - tmp_limb[0] = self.data.data.bits[0] + tmp_limb = self.data.data.bits[0] for n from self.data.length>=n>0: if local_index+self.data.itembitsize > GMP_LIMB_BITS: local_index = 0 - # tmp_limb[0] can not provide the next item, we need to get new stuff + # tmp_limb can not provide the next item, we need to get new stuff + tmp_limb = self.data.data.bits[limb_index]>>bit_index if bit_index and limb_index < max_limbs: - # We move two limbs now, so that tmp_limb[0] will be completely full - mpn_rshift(tmp_limb, self.data.data.bits+limb_index, 2, bit_index) - else: - # We shift within one limb - tmp_limb[0] = self.data.data.bits[limb_index]>>bit_index - #else: tmp_limb[0] provides the next item + # We fill the rest of tmp_limb + tmp_limb |= self.data.data.bits[limb_index+1] << (GMP_LIMB_BITS - bit_index) local_index += self.data.itembitsize - yield (tmp_limb[0]&self.data.mask_item) - tmp_limb[0]>>=self.data.itembitsize + yield (tmp_limb&self.data.mask_item) + tmp_limb>>=self.data.itembitsize bit_index += self.data.itembitsize if bit_index>=GMP_LIMB_BITS: bit_index -= GMP_LIMB_BITS From 9056cf636b65d30c5c89bc151c7740c1ea1143d3 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 23 Oct 2014 16:11:04 +0200 Subject: [PATCH 122/698] Fix handling of bound in biseq_init_list --- .../bounded_integer_sequences.pxd | 2 +- .../bounded_integer_sequences.pyx | 82 +++++++++---------- 2 files changed, 40 insertions(+), 44 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pxd b/src/sage/data_structures/bounded_integer_sequences.pxd index 19c6ccf8201..edddc97051e 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pxd +++ b/src/sage/data_structures/bounded_integer_sequences.pxd @@ -38,7 +38,7 @@ ctypedef biseq_s biseq_t[1] cdef bint biseq_init(biseq_t R, mp_size_t l, mp_bitcnt_t itemsize) except -1 cdef void biseq_dealloc(biseq_t S) cdef bint biseq_init_copy(biseq_t R, biseq_t S) except -1 -cdef bint biseq_init_list(biseq_t R, list data, mp_limb_t bound) except -1 +cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1 cdef bint biseq_init_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1 cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1 cdef int biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2 diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index f63905e166f..4290166473e 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -27,7 +27,7 @@ Cython modules: Copy S to the unallocated bitset R. -- ``cdef bint biseq_init_list(biseq_t R, list data, unsigned int bound) except -1`` +- ``cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1`` Convert a list to a bounded integer sequence, which must not be allocated. @@ -85,7 +85,6 @@ include "sage/ext/interrupt.pxi" include "sage/ext/stdsage.pxi" include 'sage/data_structures/bitset.pxi' -from libc.stdint cimport SIZE_MAX from cpython.slice cimport PySlice_Check, PySlice_GetIndicesEx from sage.libs.gmp.mpn cimport mpn_rshift, mpn_lshift, mpn_copyi, mpn_ior_n, mpn_zero, mpn_copyd, mpn_cmp from sage.libs.flint.flint cimport FLINT_BIT_COUNT as BIT_COUNT @@ -138,7 +137,7 @@ cdef bint biseq_init_copy(biseq_t R, biseq_t S) except -1: # Conversion # -cdef bint biseq_init_list(biseq_t R, list data, mp_limb_t bound) except -1: +cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1: """ Convert a list into a bounded integer sequence and write the result into ``R``, which must not be initialised. @@ -156,16 +155,12 @@ cdef bint biseq_init_list(biseq_t R, list data, mp_limb_t bound) except -1: cdef mp_size_t offset_div cdef mp_size_t offset = 0 - if not (bound <= SIZE_MAX): - raise OverflowError("bound can be at most %s" % SIZE_MAX) - bound |= 1 # A bound of 0 should become 1 - biseq_init(R, len(data), BIT_COUNT(bound)) + biseq_init(R, len(data), BIT_COUNT(bound|1)) for item in data: item_limb = item - #if item_limb > bound: - # raise ValueError("list item %r larger than %s"%(item, bound) ) - item_limb &= R.mask_item + if item_limb > bound: + raise ValueError("list item %r larger than %s"%(item, bound) ) offset_mod = offset % GMP_LIMB_BITS offset_div = offset // GMP_LIMB_BITS if offset_mod: @@ -484,10 +479,9 @@ cdef class BoundedIntegerSequence: INPUT: - ``bound``, non-negative integer. When zero, a :class:`ValueError` - will be raised. Otherwise, the given bound is replaced by the next - power of two that is greater than the given bound. - - ``data``, a list of integers. The given integers will be truncated - to be less than the bound. + will be raised. Otherwise, the given bound is replaced by the + power of two that is at least the given bound. + - ``data``, a list of integers. EXAMPLES: @@ -502,23 +496,22 @@ cdef class BoundedIntegerSequence: <2, 7, 20> Each bounded integer sequence has a bound that is a power of two, such - that all its item are less than this bound (they are in fact truncated):: + that all its item are less than this bound:: sage: S.bound() 32 sage: BoundedIntegerSequence(16, [2, 7, 20]) - <2, 7, 4> + Traceback (most recent call last): + ... + ValueError: list item 20 larger than 15 Bounded integer sequences are iterable, and we see that we can recover the - originally given list, modulo the bound:: + originally given list:: sage: L = [randint(0,31) for i in range(5000)] sage: S = BoundedIntegerSequence(32, L) sage: list(L) == L True - sage: S16 = BoundedIntegerSequence(16, L) - sage: list(S16) == [x%S16.bound() for x in L] - True Getting items and slicing works in the same way as for lists. Note, however, that slicing is an operation that is relatively slow for bounded @@ -629,17 +622,21 @@ cdef class BoundedIntegerSequence: Traceback (most recent call last): ... OverflowError: can't convert negative value to mp_limb_t - sage: BoundedIntegerSequence(1, [2, 7, 0]) - <0, 1, 0> - sage: BoundedIntegerSequence(0, [2, 7, 0]) + sage: BoundedIntegerSequence(1, [0, 0, 0]) + <0, 0, 0> + sage: BoundedIntegerSequence(1, [0, 1, 0]) Traceback (most recent call last): ... - ValueError: Positive bound expected + ValueError: list item 1 larger than 0 + sage: BoundedIntegerSequence(0, [0, 1, 0]) + Traceback (most recent call last): + ... + ValueError: positive bound expected sage: BoundedIntegerSequence(2, []) <> sage: BoundedIntegerSequence(2, []) == BoundedIntegerSequence(4, []) # The bounds differ False - sage: BoundedIntegerSequence(16, [2, 7, 20])[1:1] + sage: BoundedIntegerSequence(16, [2, 7, 4])[1:1] <> """ @@ -680,7 +677,7 @@ cdef class BoundedIntegerSequence: """ biseq_dealloc(self.data) - def __init__(self, mp_limb_t bound, list data): + def __init__(self, bound, data): """ INPUT: @@ -698,37 +695,36 @@ cdef class BoundedIntegerSequence: sage: S = BoundedIntegerSequence(57, L) # indirect doctest sage: list(S) == L True - - The given data are truncated according to the bound:: - - sage: S = BoundedIntegerSequence(11, [4,1,6,2,7,20,9]); S + sage: S = BoundedIntegerSequence(11, [4,1,6,2,7,4,9]); S <4, 1, 6, 2, 7, 4, 9> sage: S.bound() 16 - sage: S = BoundedIntegerSequence(11, L) - sage: [x%S.bound() for x in L] == list(S) - True - Non-positive bounds result in errors:: + Non-positive bounds or bounds which are too large result in errors:: sage: BoundedIntegerSequence(-1, L) Traceback (most recent call last): ... - OverflowError: can't convert negative value to mp_limb_t + ValueError: positive bound expected sage: BoundedIntegerSequence(0, L) Traceback (most recent call last): ... - ValueError: Positive bound expected + ValueError: positive bound expected + sage: BoundedIntegerSequence(2^64+1, L) + Traceback (most recent call last): + ... + OverflowError: long int too large to convert - We are testing the corner case of the maximal possible bound:: + We are testing the corner case of the maximal possible bound + on a 32-bit system:: - sage: S = BoundedIntegerSequence(2^32-1, [8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10]) + sage: S = BoundedIntegerSequence(2^32, [8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10]) sage: S <8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10> """ - if bound==0: - raise ValueError("Positive bound expected") + if bound <= 0: + raise ValueError("positive bound expected") biseq_init_list(self.data, data, bound-1) def __copy__(self): @@ -738,7 +734,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence - sage: S = BoundedIntegerSequence(11, [4,1,6,2,7,20,9]) + sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) sage: copy(S) is S True @@ -1049,8 +1045,8 @@ cdef class BoundedIntegerSequence: :: - sage: S1 = BoundedIntegerSequence(3,[1,3]) - sage: S2 = BoundedIntegerSequence(3,[0]) + sage: S1 = BoundedIntegerSequence(4, [1,3]) + sage: S2 = BoundedIntegerSequence(4, [0]) sage: S2 in S1 False From e9c779ae629dbec356bb8546e3974e2a67050051 Mon Sep 17 00:00:00 2001 From: Simon King Date: Thu, 23 Oct 2014 19:39:42 +0200 Subject: [PATCH 123/698] Simplify code by using biseq_getitem/biseq_inititem --- .../bounded_integer_sequences.pxd | 1 + .../bounded_integer_sequences.pyx | 106 +++++++++--------- 2 files changed, 51 insertions(+), 56 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pxd b/src/sage/data_structures/bounded_integer_sequences.pxd index edddc97051e..23a1f1218e7 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pxd +++ b/src/sage/data_structures/bounded_integer_sequences.pxd @@ -46,6 +46,7 @@ cdef int biseq_max_overlap(biseq_t S1, biseq_t S2) except 0 cdef int biseq_index(biseq_t S, mp_limb_t item, mp_size_t start) except -2 cdef biseq_item_t biseq_getitem(biseq_t S, mp_size_t index) cdef biseq_getitem_py(biseq_t S, mp_size_t index) +cdef biseq_inititem(biseq_t S, mp_size_t index, biseq_item_t item) cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1 cdef class BoundedIntegerSequence: diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index 4290166473e..f3f0c1bebd2 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -3,7 +3,7 @@ Sequences of bounded integers AUTHORS: -- Simon King (2014): initial version +- Simon King, Jeroen Demeyer (2014-10): initial version This module provides :class:`BoundedIntegerSequence`, which implements sequences of bounded integers and is for many (but not all) operations faster @@ -65,6 +65,11 @@ Cython modules: Returns ``S[index]`` as Python ``int`` or ``long``, without checking margins. +- ``cdef biseq_inititem(biseq_t S, mp_size_t index, biseq_item_t item)`` + + Set ``S[index] = item``, without checking margins and assuming that ``S[index]`` + has previously been zero. + - ``cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1`` Fills ``R`` with ``S[start:stop:step]`` @@ -149,31 +154,16 @@ cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1: - ``bound`` -- a number which is the maximal number which can be represented """ + cdef mp_size_t index cdef mp_limb_t item_limb - cdef mp_limb_t tmp_limb1, tmp_limb2 - cdef mp_bitcnt_t offset_mod - cdef mp_size_t offset_div - cdef mp_size_t offset = 0 biseq_init(R, len(data), BIT_COUNT(bound|1)) - for item in data: - item_limb = item - if item_limb > bound: + for index, item in enumerate(data): + if item > bound: raise ValueError("list item %r larger than %s"%(item, bound) ) - offset_mod = offset % GMP_LIMB_BITS - offset_div = offset // GMP_LIMB_BITS - if offset_mod: - tmp_limb2 = mpn_lshift(&tmp_limb1, &item_limb, 1, offset_mod) - if tmp_limb2: - # This can only happen, if offset_div is small enough to not - # write out of bounds, since initially we have allocated - # enough memory. - R.data.bits[offset_div+1] = tmp_limb2 - R.data.bits[offset_div] |= tmp_limb1 - else: - R.data.bits[offset_div] = item_limb - offset += R.itembitsize + item_limb = item + biseq_inititem(R, index, item_limb) # # Arithmetics @@ -325,6 +315,40 @@ cdef biseq_getitem_py(biseq_t S, mp_size_t index): cdef size_t out = biseq_getitem(S, index) return PyInt_FromSize_t(out) +cdef biseq_inititem(biseq_t S, mp_size_t index, biseq_item_t item): + """ + Set ``S[index] = item``, without checking margins. + + Note that it is assumed that ``S[index] == 0`` before the assignment. + """ + cdef mp_bitcnt_t limb_index, bit_index + bit_index = (index) * S.itembitsize + limb_index = bit_index // GMP_LIMB_BITS + bit_index %= GMP_LIMB_BITS + + S.data.bits[limb_index] |= (item << bit_index) + # Have some bits been shifted out of bound? + if bit_index + S.itembitsize > GMP_LIMB_BITS: + # Our item is stored using 2 limbs, add the part from the upper limb + S.data.bits[limb_index+1] |= (item >> (GMP_LIMB_BITS - bit_index)) + +cdef biseq_clearitem(biseq_t S, mp_size_t index): + """ + Set ``S[index] = 0``, without checking margins. + + In contrast to ``biseq_inititem``, the previous content of ``S[index]`` + will be erased. + """ + cdef mp_bitcnt_t limb_index, bit_index + bit_index = (index) * S.itembitsize + limb_index = bit_index // GMP_LIMB_BITS + bit_index %= GMP_LIMB_BITS + + S.data.bits[limb_index] &= ~(S.mask_item << bit_index) + # Have some bits been shifted out of bound? + if bit_index + S.itembitsize > GMP_LIMB_BITS: + # Our item is stored using 2 limbs, add the part from the upper limb + S.data.bits[limb_index+1] &= ~(S.mask_item >> (GMP_LIMB_BITS - bit_index)) cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1: """ @@ -364,42 +388,12 @@ cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int if offset_mod: R.data.bits[R.data.limbs-1] &= ((1)<=n>0: - offset_div_src = offset_src // GMP_LIMB_BITS - offset_mod_src = offset_src % GMP_LIMB_BITS - offset_div_tgt = offset_tgt // GMP_LIMB_BITS - offset_mod_tgt = offset_tgt % GMP_LIMB_BITS - # put data from src to tmp_limb. - if offset_mod_src: - tmp_limb = ((S.data.bits[offset_div_src])>>offset_mod_src) - if (offset_mod_src+S.itembitsize > GMP_LIMB_BITS): - tmp_limb |= (S.data.bits[offset_div_src+1]) << (GMP_LIMB_BITS - offset_mod_src) - tmp_limb &= S.mask_item - else: - tmp_limb = S.data.bits[offset_div_src] & S.mask_item - # put data from tmp_limb to tgt - if offset_mod_tgt: - tmp_limb2 = mpn_lshift(&tmp_limb, &tmp_limb, 1, offset_mod_tgt) - if tmp_limb2: - R.data.bits[offset_div_tgt+1] = tmp_limb2 - R.data.bits[offset_div_tgt] |= tmp_limb - else: - R.data.bits[offset_div_tgt] = tmp_limb - offset_tgt += S.itembitsize - offset_src += bitstep + biseq_inititem(R, postinc(tgt_index), biseq_getitem(S, src_index)) + src_index += step cdef int biseq_max_overlap(biseq_t S1, biseq_t S2) except 0: """ From acf2a7552bb19d3a9692c8f23a487c50f9e5b4d8 Mon Sep 17 00:00:00 2001 From: Simon King Date: Thu, 23 Oct 2014 20:07:51 +0200 Subject: [PATCH 124/698] Declare some functions as 'cdef inline void' --- .../data_structures/bounded_integer_sequences.pxd | 2 +- .../data_structures/bounded_integer_sequences.pyx | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pxd b/src/sage/data_structures/bounded_integer_sequences.pxd index 23a1f1218e7..6547a05c803 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pxd +++ b/src/sage/data_structures/bounded_integer_sequences.pxd @@ -46,7 +46,7 @@ cdef int biseq_max_overlap(biseq_t S1, biseq_t S2) except 0 cdef int biseq_index(biseq_t S, mp_limb_t item, mp_size_t start) except -2 cdef biseq_item_t biseq_getitem(biseq_t S, mp_size_t index) cdef biseq_getitem_py(biseq_t S, mp_size_t index) -cdef biseq_inititem(biseq_t S, mp_size_t index, biseq_item_t item) +cdef inline void biseq_inititem(biseq_t S, mp_size_t index, biseq_item_t item) cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1 cdef class BoundedIntegerSequence: diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index f3f0c1bebd2..050f0f5ffc3 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -19,7 +19,7 @@ Cython modules: Allocate memory (filled with zero) for a bounded integer sequence of length l with items fitting in itemsize bits. -- ``cdef void biseq_dealloc(biseq_t S)`` +- ``cdef inline void biseq_dealloc(biseq_t S)`` Free the data stored in ``S``. @@ -125,7 +125,7 @@ cdef bint biseq_init(biseq_t R, mp_size_t l, mp_bitcnt_t itemsize) except -1: R.itembitsize = itemsize R.mask_item = limb_lower_bits_up(itemsize) -cdef void biseq_dealloc(biseq_t S): +cdef inline void biseq_dealloc(biseq_t S): """ Deallocate the memory used by S. """ @@ -159,7 +159,8 @@ cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1: biseq_init(R, len(data), BIT_COUNT(bound|1)) - for index, item in enumerate(data): + for index from 0<=index bound: raise ValueError("list item %r larger than %s"%(item, bound) ) item_limb = item @@ -315,7 +316,7 @@ cdef biseq_getitem_py(biseq_t S, mp_size_t index): cdef size_t out = biseq_getitem(S, index) return PyInt_FromSize_t(out) -cdef biseq_inititem(biseq_t S, mp_size_t index, biseq_item_t item): +cdef inline void biseq_inititem(biseq_t S, mp_size_t index, biseq_item_t item): """ Set ``S[index] = item``, without checking margins. @@ -332,7 +333,7 @@ cdef biseq_inititem(biseq_t S, mp_size_t index, biseq_item_t item): # Our item is stored using 2 limbs, add the part from the upper limb S.data.bits[limb_index+1] |= (item >> (GMP_LIMB_BITS - bit_index)) -cdef biseq_clearitem(biseq_t S, mp_size_t index): +cdef inline void biseq_clearitem(biseq_t S, mp_size_t index): """ Set ``S[index] = 0``, without checking margins. From 7d258591bab37466eb6392443ed2e84cf699102c Mon Sep 17 00:00:00 2001 From: Simon King Date: Thu, 23 Oct 2014 20:43:37 +0200 Subject: [PATCH 125/698] Speed-up for testing bounds --- .../bounded_integer_sequences.pyx | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index 050f0f5ffc3..252a89412a0 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -151,8 +151,7 @@ cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1: - ``data`` -- a list of integers - - ``bound`` -- a number which is the maximal number which can be - represented + - ``bound`` -- a number which is the maximal value of an item """ cdef mp_size_t index cdef mp_limb_t item_limb @@ -160,10 +159,9 @@ cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1: biseq_init(R, len(data), BIT_COUNT(bound|1)) for index from 0<=index bound: - raise ValueError("list item %r larger than %s"%(item, bound) ) - item_limb = item + item_limb = data[index] + if item_limb > bound: + raise ValueError("list item {!s:} larger than {!s:}".format(item_limb, bound) ) biseq_inititem(R, index, item_limb) # @@ -717,6 +715,24 @@ cdef class BoundedIntegerSequence: sage: S <8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10> + Items that are too large:: + + sage: BoundedIntegerSequence(100, [2^256]) + Traceback (most recent call last): + ... + OverflowError: long int too large to convert + sage: BoundedIntegerSequence(100, [200]) + Traceback (most recent call last): + ... + ValueError: list item 200 larger than 99 + + Bounds that are too large:: + + sage: BoundedIntegerSequence(2^256, [200]) + Traceback (most recent call last): + ... + OverflowError: long int too large to convert + """ if bound <= 0: raise ValueError("positive bound expected") From 8a10b734c7f81e44bb401c1fec2dc82bd0e98d5e Mon Sep 17 00:00:00 2001 From: Simon King Date: Fri, 24 Oct 2014 00:01:56 +0200 Subject: [PATCH 126/698] Use plain size_t, not biseq_item_t --- .../bounded_integer_sequences.pxd | 8 +++----- .../bounded_integer_sequences.pyx | 20 +++++++++---------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pxd b/src/sage/data_structures/bounded_integer_sequences.pxd index 6547a05c803..7c1baed7865 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pxd +++ b/src/sage/data_structures/bounded_integer_sequences.pxd @@ -1,8 +1,6 @@ from sage.libs.gmp.types cimport * from sage.data_structures.bitset cimport * -ctypedef size_t biseq_item_t - # A biseq (bounded integer sequence) is a sequence of non-negative # integers, each fitting in "itembitsize" bits. We store the sequence # in a bitset of length at least length*itembitsize. @@ -31,7 +29,7 @@ ctypedef struct biseq_s: # If L is a limb, then "L & mask_item" extracts the first # itembitsize bits of it, i.e., it extracts one item. - biseq_item_t mask_item + size_t mask_item ctypedef biseq_s biseq_t[1] @@ -44,9 +42,9 @@ cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1 cdef int biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2 cdef int biseq_max_overlap(biseq_t S1, biseq_t S2) except 0 cdef int biseq_index(biseq_t S, mp_limb_t item, mp_size_t start) except -2 -cdef biseq_item_t biseq_getitem(biseq_t S, mp_size_t index) +cdef size_t biseq_getitem(biseq_t S, mp_size_t index) cdef biseq_getitem_py(biseq_t S, mp_size_t index) -cdef inline void biseq_inititem(biseq_t S, mp_size_t index, biseq_item_t item) +cdef inline void biseq_inititem(biseq_t S, mp_size_t index, size_t item) cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1 cdef class BoundedIntegerSequence: diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index 252a89412a0..98dfcd506c7 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -57,15 +57,15 @@ Cython modules: Returns the position *in S* of the item in ``S[start:]``, or ``-1`` if ``S[start:]`` does not contain the item. -- ``cdef biseq_item_t biseq_getitem(biseq_t S, mp_size_t index)`` +- ``cdef size_t biseq_getitem(biseq_t S, mp_size_t index)`` Returns ``S[index]``, without checking margins. -- ``cdef biseq_item_t biseq_getitem_py(biseq_t S, mp_size_t index)`` +- ``cdef size_t biseq_getitem_py(biseq_t S, mp_size_t index)`` Returns ``S[index]`` as Python ``int`` or ``long``, without checking margins. -- ``cdef biseq_inititem(biseq_t S, mp_size_t index, biseq_item_t item)`` +- ``cdef biseq_inititem(biseq_t S, mp_size_t index, size_t item)`` Set ``S[index] = item``, without checking margins and assuming that ``S[index]`` has previously been zero. @@ -161,7 +161,7 @@ cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1: for index from 0<=index bound: - raise ValueError("list item {!s:} larger than {!s:}".format(item_limb, bound) ) + raise ValueError("list item {!r:} larger than {!r:}".format(item_limb, bound) ) biseq_inititem(R, index, item_limb) # @@ -289,7 +289,7 @@ cdef int biseq_index(biseq_t S, mp_limb_t item, mp_size_t start) except -2: return -1 -cdef inline biseq_item_t biseq_getitem(biseq_t S, mp_size_t index): +cdef inline size_t biseq_getitem(biseq_t S, mp_size_t index): """ Get item S[index], without checking margins. @@ -314,7 +314,7 @@ cdef biseq_getitem_py(biseq_t S, mp_size_t index): cdef size_t out = biseq_getitem(S, index) return PyInt_FromSize_t(out) -cdef inline void biseq_inititem(biseq_t S, mp_size_t index, biseq_item_t item): +cdef inline void biseq_inititem(biseq_t S, mp_size_t index, size_t item): """ Set ``S[index] = item``, without checking margins. @@ -496,7 +496,7 @@ cdef class BoundedIntegerSequence: sage: BoundedIntegerSequence(16, [2, 7, 20]) Traceback (most recent call last): ... - ValueError: list item 20 larger than 15 + ValueError: list item 20L larger than 15 Bounded integer sequences are iterable, and we see that we can recover the originally given list:: @@ -620,7 +620,7 @@ cdef class BoundedIntegerSequence: sage: BoundedIntegerSequence(1, [0, 1, 0]) Traceback (most recent call last): ... - ValueError: list item 1 larger than 0 + ValueError: list item 1L larger than 0 sage: BoundedIntegerSequence(0, [0, 1, 0]) Traceback (most recent call last): ... @@ -724,7 +724,7 @@ cdef class BoundedIntegerSequence: sage: BoundedIntegerSequence(100, [200]) Traceback (most recent call last): ... - ValueError: list item 200 larger than 99 + ValueError: list item 200L larger than 99 Bounds that are too large:: @@ -914,7 +914,7 @@ cdef class BoundedIntegerSequence: # We fill the rest of tmp_limb tmp_limb |= self.data.data.bits[limb_index+1] << (GMP_LIMB_BITS - bit_index) local_index += self.data.itembitsize - yield (tmp_limb&self.data.mask_item) + yield (tmp_limb&self.data.mask_item) tmp_limb>>=self.data.itembitsize bit_index += self.data.itembitsize if bit_index>=GMP_LIMB_BITS: From fa7cde09b93359371f236ce6da13bb8f5a947a08 Mon Sep 17 00:00:00 2001 From: Simon King Date: Fri, 24 Oct 2014 08:06:38 +0200 Subject: [PATCH 127/698] Use original data in error message --- src/sage/data_structures/bounded_integer_sequences.pyx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index 98dfcd506c7..1e9d50ddcc5 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -161,7 +161,7 @@ cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1: for index from 0<=index bound: - raise ValueError("list item {!r:} larger than {!r:}".format(item_limb, bound) ) + raise ValueError("list item {} larger than {}".format(data[index], bound) ) biseq_inititem(R, index, item_limb) # @@ -496,7 +496,7 @@ cdef class BoundedIntegerSequence: sage: BoundedIntegerSequence(16, [2, 7, 20]) Traceback (most recent call last): ... - ValueError: list item 20L larger than 15 + ValueError: list item 20 larger than 15 Bounded integer sequences are iterable, and we see that we can recover the originally given list:: @@ -620,7 +620,7 @@ cdef class BoundedIntegerSequence: sage: BoundedIntegerSequence(1, [0, 1, 0]) Traceback (most recent call last): ... - ValueError: list item 1L larger than 0 + ValueError: list item 1 larger than 0 sage: BoundedIntegerSequence(0, [0, 1, 0]) Traceback (most recent call last): ... @@ -724,7 +724,7 @@ cdef class BoundedIntegerSequence: sage: BoundedIntegerSequence(100, [200]) Traceback (most recent call last): ... - ValueError: list item 200L larger than 99 + ValueError: list item 200 larger than 99 Bounds that are too large:: From 6e03f19d4bc2379e44e0b8adc32c13ac6e0bcabb Mon Sep 17 00:00:00 2001 From: Simon King Date: Fri, 24 Oct 2014 13:14:30 +0200 Subject: [PATCH 128/698] Code and speed improvement for biseq containment test --- src/sage/data_structures/bitset.pxi | 31 ++++++++ .../bounded_integer_sequences.pyx | 77 +++++-------------- 2 files changed, 49 insertions(+), 59 deletions(-) diff --git a/src/sage/data_structures/bitset.pxi b/src/sage/data_structures/bitset.pxi index 2291ee848d4..6a5ca0d0779 100644 --- a/src/sage/data_structures/bitset.pxi +++ b/src/sage/data_structures/bitset.pxi @@ -27,6 +27,7 @@ include 'sage/ext/cdefs.pxi' include 'sage/ext/stdsage.pxi' from sage.libs.gmp.mpn cimport * from sage.data_structures.bitset cimport * +from cython.operator import preincrement as preinc # Doctests for the functions in this file are in sage/data_structures/bitset.pyx @@ -162,6 +163,36 @@ cdef inline bint mpn_equal_bits(mp_srcptr b1, mp_srcptr b2, mp_bitcnt_t n): cdef mp_limb_t b2h = b2[nlimbs] return (b1h ^ b2h) & mask == 0 +cdef inline bint mpn_equal_bits_shifted(mp_srcptr b1, mp_srcptr b2, mp_bitcnt_t n, mp_bitcnt_t offset): + """ + Return ``True`` iff the first n bits of *b1 and the bits ranging from + offset to offset+n of *b2 agree. + """ + cdef mp_bitcnt_t bit_offset = offset % GMP_LIMB_BITS + cdef mp_size_t i2 = offset//GMP_LIMB_BITS + if bit_offset==0: + return mpn_equal_bits(b1, b2 + i2, n) + cdef mp_size_t neg_bit_offset = GMP_LIMB_BITS-bit_offset + # limbs of b1 to be considered + cdef mp_size_t nlimbs = n // GMP_LIMB_BITS + # bits of an additional limb of b1 to be considered + cdef mp_limb_t tmp_limb + cdef mp_size_t i1 + for i1 from 0 <= i1 < nlimbs: + tmp_limb = (b2[i2] >> bit_offset) + tmp_limb |= (b2[preinc(i2)] << neg_bit_offset) + if tmp_limb != b1[i1]: + return False + cdef mp_limb_t mask = limb_lower_bits_down(n) + if mask == 0: + return True + + cdef mp_limb_t b1h = b1[nlimbs] + tmp_limb = (b2[i2] >> bit_offset) + if (n%GMP_LIMB_BITS)+bit_offset > GMP_LIMB_BITS: + # Need bits from the next limb of b2 + tmp_limb |= (b2[preinc(i2)] << neg_bit_offset) + return (b1h ^ tmp_limb) & mask == 0 cdef inline bint bitset_isempty(bitset_t bits): """ diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index 1e9d50ddcc5..5342538afb4 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -199,6 +199,8 @@ cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1: """ if S2.length > S1.length: return False + if S2.length == 0: + return True return mpn_equal_bits(S1.data.bits, S2.data.bits, S2.data.size) @@ -227,29 +229,14 @@ cdef int biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2: return -1 if S2.length==0: return start - cdef bitset_t tmp - bitset_init(tmp, S2.data.size+GMP_LIMB_BITS) - cdef mp_size_t index = 0 - cdef mp_bitcnt_t n = 0 - cdef mp_size_t limb_index, bit_index - cdef mp_bitcnt_t offset = S2.data.size % GMP_LIMB_BITS - for index from start <= index <= S1.length-S2.length: - limb_index = n // GMP_LIMB_BITS - bit_index = n % GMP_LIMB_BITS - # We shift a part of S1 (with length S2) by bit_index, and compare - # with S2. - if bit_index: - if offset+bit_index>GMP_LIMB_BITS: - mpn_rshift(tmp.bits, S1.data.bits+limb_index, S2.data.limbs+1, bit_index) - else: - mpn_rshift(tmp.bits, S1.data.bits+limb_index, S2.data.limbs, bit_index) - else: - mpn_copyi(tmp.bits, S1.data.bits+limb_index, S2.data.limbs) - if mpn_equal_bits(tmp.bits, S2.data.bits, S2.data.size): - bitset_free(tmp) + cdef mp_bitcnt_t offset = 0 + cdef mp_size_t index + for index from start <= index < S1.length-S2.length: + if mpn_equal_bits_shifted(S2.data.bits, S1.data.bits, S2.data.size, offset): return index - n += S1.itembitsize - bitset_free(tmp) + offset += S1.itembitsize + if mpn_equal_bits_shifted(S2.data.bits, S1.data.bits, S2.data.size, offset): + return index return -1 cdef int biseq_index(biseq_t S, mp_limb_t item, mp_size_t start) except -2: @@ -412,54 +399,26 @@ cdef int biseq_max_overlap(biseq_t S1, biseq_t S2) except 0: tested. """ - # Idea: We store the maximal possible tail of S1 in a temporary bitset, - # and then rightshift it (taking care that the number of to-be-shifted - # limbs will decrease over time), comparing with the initial part of S2 - # after each step. if S1.length == 0: raise ValueError("First argument must be of positive length") - cdef bitset_t tmp - cdef mp_size_t limb_index - cdef mp_bitcnt_t bit_index, n - cdef mp_size_t index, i, start_index + cdef mp_size_t index, start_index if S2.length>=S1.length: start_index = 1 else: start_index = S1.length-S2.length if start_index == S1.length: return -1 - n = S1.itembitsize*start_index - ## Initilise the temporary bitset - # Allocate an additional limb, to cope with shifting accross limb borders - bitset_init(tmp, (GMP_LIMB_BITS+S1.data.size)-n) - cdef mp_size_t nlimbs = tmp.limbs # number of to-be-shifted limbs - limb_index = n // GMP_LIMB_BITS - bit_index = n % GMP_LIMB_BITS - if bit_index==0: - mpn_copyi(tmp.bits, S1.data.bits+limb_index, predec(nlimbs)) - else: - if ((S1.data.size-n) % GMP_LIMB_BITS)+bit_index>GMP_LIMB_BITS: - # Need to shift an additional limb - mpn_rshift(tmp.bits, S1.data.bits+limb_index, nlimbs, bit_index) - else: - mpn_rshift(tmp.bits, S1.data.bits+limb_index, predec(nlimbs), bit_index) - cdef mp_bitcnt_t remaining_size = S1.data.size - n - n = 0 # This now counts how many bits of the highest limb of tmp we have shifted. - for index from start_index<=index=GMP_LIMB_BITS: - mpn_rshift(tmp.bits, tmp.bits, predec(nlimbs), S1.itembitsize) - n = 0 - else: - mpn_rshift(tmp.bits, tmp.bits, nlimbs, S1.itembitsize) - n += S1.itembitsize - bitset_free(tmp) + overlap -= S1.itembitsize + offset += S1.itembitsize + if mpn_equal_bits_shifted(S2.data.bits, S1.data.bits, overlap, offset): + return index return -1 - ########################################### # A cdef class that wraps the above, and # behaves like a tuple From cef0ee08f43e178766f6a737b2d4ea18ac8fd90c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Sat, 25 Oct 2014 09:41:46 +0200 Subject: [PATCH 129/698] 16256: fixed missing links from the previous merge --- src/sage/combinat/designs/__init__.py | 3 ++- src/sage/combinat/enumerated_sets.py | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/sage/combinat/designs/__init__.py b/src/sage/combinat/designs/__init__.py index 7f7894cb57e..3b46fba32e0 100644 --- a/src/sage/combinat/designs/__init__.py +++ b/src/sage/combinat/designs/__init__.py @@ -18,7 +18,8 @@ - :ref:`sage.combinat.designs.bibd` - :ref:`sage.combinat.designs.latin_squares` - :ref:`sage.combinat.designs.orthogonal_arrays` -- :ref:`sage.combinat.designs.orthogonal_arrays_recursive` +- :ref:`sage.combinat.designs.orthogonal_arrays_build_recursive` +- :ref:`sage.combinat.designs.orthogonal_arrays_find_recursive` - :ref:`sage.combinat.designs.difference_family` - :ref:`sage.combinat.designs.difference_matrices` - :ref:`sage.combinat.designs.steiner_quadruple_systems` diff --git a/src/sage/combinat/enumerated_sets.py b/src/sage/combinat/enumerated_sets.py index bf541137c1a..16d24e01253 100644 --- a/src/sage/combinat/enumerated_sets.py +++ b/src/sage/combinat/enumerated_sets.py @@ -82,12 +82,14 @@ - :class:`MatrixSpace` - :ref:`sage.groups.matrix_gps.catalog` -Set partitions, ... -------------------- +Subsets and set partitions +-------------------------- +- :class:`~sage.combinat.subset.Subsets`, :class:`~sage.combinat.combination.Combinations` +- :class:`~sage.combinat.subsets_pairwise.PairwiseCompatibleSubsets` +- :ref:`sage.combinat.subsets_hereditary` - :ref:`sage.combinat.set_partition_ordered` - :ref:`sage.combinat.set_partition` -- :class:`~sage.combinat.subsets_pairwise.PairwiseCompatibleSubsets` Trees ----- From e18094ab5b9ab65724d68df99352559e0f63eb83 Mon Sep 17 00:00:00 2001 From: Sergey Bykov Date: Sat, 25 Oct 2014 13:33:37 +0400 Subject: [PATCH 130/698] Fixed Latex representation for user-provided variables --- src/sage/symbolic/ring.pyx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sage/symbolic/ring.pyx b/src/sage/symbolic/ring.pyx index f87f6223657..ea4e44b3c9c 100644 --- a/src/sage/symbolic/ring.pyx +++ b/src/sage/symbolic/ring.pyx @@ -623,6 +623,11 @@ cdef class SymbolicRing(CommutativeRing): Traceback (most recent call last): ... ValueError: The name "x,y" is not a valid Python identifier. + + Check that :trac:`17206` is fixed:: + var1 = var('var1', latex_name=r'\sigma^2_1') + latex(var1) + {\sigma^2_1} """ if is_Expression(name): return name @@ -645,7 +650,10 @@ cdef class SymbolicRing(CommutativeRing): if len(names_list) == 0: raise ValueError('You need to specify the name of the new variable.') if len(names_list) == 1: - return self.symbol(name, latex_name=latex_name, domain=domain) + formatted_latex_name = None + if latex_name is not None: + formatted_latex_name = '{{{0}}}'.format(latex_name) + return self.symbol(name, latex_name=formatted_latex_name, domain=domain) if len(names_list) > 1: if latex_name: raise ValueError, "cannot specify latex_name for multiple symbol names" From b5b066dc218d7fb6e5e13eb19cce4720d4a2d057 Mon Sep 17 00:00:00 2001 From: Simon King Date: Tue, 28 Oct 2014 16:11:41 +0100 Subject: [PATCH 131/698] Code simplification for biseq_*, bound check for bitset shifts --- src/sage/data_structures/bitset.pxi | 40 +++-- .../bounded_integer_sequences.pxd | 7 +- .../bounded_integer_sequences.pyx | 142 ++++++------------ 3 files changed, 76 insertions(+), 113 deletions(-) diff --git a/src/sage/data_structures/bitset.pxi b/src/sage/data_structures/bitset.pxi index 6a5ca0d0779..cb75e8d2e1c 100644 --- a/src/sage/data_structures/bitset.pxi +++ b/src/sage/data_structures/bitset.pxi @@ -12,6 +12,8 @@ AUTHORS: pickle, unpickle - Jeroen Demeyer (2014-09-05): use mpn_* functions from MPIR in the implementation (:trac`13352` and :trac:`16937`) +- Simon King (2014-10-28): ``bitset_rshift`` and ``bitset_lshift`` respecting + the size of the given bitsets. """ #***************************************************************************** @@ -601,7 +603,8 @@ cdef void bitset_rshift(bitset_t r, bitset_t a, mp_bitcnt_t n): Shift the bitset ``a`` right by ``n`` bits and store the result in ``r``. - We assume ``a.size <= r.size + n``. + If the result of the shift would exceed the size of ``r``, then it + will be cut. """ if n >= a.size: mpn_zero(r.bits, r.limbs) @@ -609,21 +612,25 @@ cdef void bitset_rshift(bitset_t r, bitset_t a, mp_bitcnt_t n): # Number of limbs on the right of a which will totally be shifted out cdef mp_size_t nlimbs = n >> index_shift + # Number of limbs of a which will survive the shift + cdef mp_size_t shifted_limbs = a.limbs - nlimbs # Number of bits to shift additionally cdef mp_bitcnt_t nbits = n % GMP_LIMB_BITS if nbits: # mpn_rshift only does shifts less than a limb - if a.limbs - nlimbs <= r.limbs: - mpn_rshift(r.bits, a.bits + nlimbs, a.limbs - nlimbs, nbits) + if shifted_limbs <= r.limbs: + mpn_rshift(r.bits, a.bits + nlimbs, shifted_limbs, nbits) else: - # In this case, we must have a.limbs - nlimbs - 1 == r.limbs mpn_rshift(r.bits, a.bits + nlimbs, r.limbs, nbits) # Add the additional bits from top limb of a - r.bits[r.limbs-1] |= a.bits[a.limbs-1] << (GMP_LIMB_BITS - nbits) + r.bits[r.limbs-1] |= a.bits[r.limbs+nlimbs] << (GMP_LIMB_BITS - nbits) else: - mpn_copyi(r.bits, a.bits + nlimbs, a.limbs - nlimbs) - + if shifted_limbs <= r.limbs: + mpn_copyi(r.bits, a.bits + nlimbs, shifted_limbs) + else: + mpn_copyi(r.bits, a.bits + nlimbs, r.limbs) + bitset_fix(r) # Clear top limbs if r.limbs + nlimbs >= a.limbs + 1: mpn_zero(r.bits + (r.limbs - nlimbs), r.limbs + nlimbs - a.limbs) @@ -633,7 +640,8 @@ cdef void bitset_lshift(bitset_t r, bitset_t a, mp_bitcnt_t n): Shift the bitset ``a`` left by ``n`` bits and store the result in ``r``. - We assume ``r.size <= a.size + n``. + If the result of the shift would exceed the size of ``r``, then it + will be cut. """ if n >= r.size: mpn_zero(r.bits, r.limbs) @@ -641,26 +649,28 @@ cdef void bitset_lshift(bitset_t r, bitset_t a, mp_bitcnt_t n): # Number of limbs on the left of r which will totally be shifted out cdef mp_size_t nlimbs = n >> index_shift + # Number of limbs of a which would fit into r + cdef mp_size_t max_shifted_limbs = r.limbs - nlimbs # Number of bits to shift additionally cdef mp_bitcnt_t nbits = n % GMP_LIMB_BITS cdef mp_limb_t out if nbits: # mpn_lshift only does shifts less than a limb - if r.limbs - nlimbs <= a.limbs: - mpn_lshift(r.bits + nlimbs, a.bits, r.limbs - nlimbs, nbits) + if max_shifted_limbs <= a.limbs: + mpn_lshift(r.bits + nlimbs, a.bits, max_shifted_limbs, nbits) else: - # In this case, we must have r.limbs - nlimbs - 1 == a.limbs out = mpn_lshift(r.bits + nlimbs, a.bits, a.limbs, nbits) - r.bits[r.limbs-1] = out + r.bits[nlimbs+a.limbs] = out else: - mpn_copyd(r.bits + nlimbs, a.bits, r.limbs - nlimbs) + if max_shifted_limbs <= a.limbs: + mpn_copyd(r.bits + nlimbs, a.bits, max_shifted_limbs) + else: + mpn_copyd(r.bits + nlimbs, a.bits, a.limbs) bitset_fix(r) - # Clear bottom limbs mpn_zero(r.bits, nlimbs) - cdef inline void bitset_map(bitset_t r, bitset_t a, m): """ Fill bitset ``r`` so ``r == {m[i] for i in a}``. diff --git a/src/sage/data_structures/bounded_integer_sequences.pxd b/src/sage/data_structures/bounded_integer_sequences.pxd index 7c1baed7865..4eefe01c93e 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pxd +++ b/src/sage/data_structures/bounded_integer_sequences.pxd @@ -39,12 +39,13 @@ cdef bint biseq_init_copy(biseq_t R, biseq_t S) except -1 cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1 cdef bint biseq_init_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1 cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1 -cdef int biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2 -cdef int biseq_max_overlap(biseq_t S1, biseq_t S2) except 0 -cdef int biseq_index(biseq_t S, mp_limb_t item, mp_size_t start) except -2 +cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2 +cdef mp_size_t biseq_max_overlap(biseq_t S1, biseq_t S2) except 0 +cdef mp_size_t biseq_index(biseq_t S, size_t item, mp_size_t start) except -2 cdef size_t biseq_getitem(biseq_t S, mp_size_t index) cdef biseq_getitem_py(biseq_t S, mp_size_t index) cdef inline void biseq_inititem(biseq_t S, mp_size_t index, size_t item) +cdef inline void biseq_clearitem(biseq_t S, mp_size_t index) cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1 cdef class BoundedIntegerSequence: diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index 5342538afb4..b25ad3fc7db 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -41,18 +41,18 @@ Cython modules: Is ``S1=S2+something``? Does not check whether the sequences have the same bound! -- ``cdef int biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2`` +- ``cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2`` Returns the position *in ``S1``* of ``S2`` as a subsequence of ``S1[start:]``, or ``-1`` if ``S2`` is not a subsequence. Does not check whether the sequences have the same bound! -- ``cdef int biseq_max_overlap(biseq_t S1, biseq_t S2) except 0`` +- ``cdef mp_size_t biseq_max_overlap(biseq_t S1, biseq_t S2) except 0`` Returns the minimal *positive* integer ``i`` such that ``S2`` starts with ``S1[i:]``. This function will *not* test whether ``S2`` starts with ``S1``! -- ``cdef int biseq_index(biseq_t S, mp_limb_t item, mp_size_t start) except -2`` +- ``cdef mp_size_t biseq_index(biseq_t S, size_t item, mp_size_t start) except -2`` Returns the position *in S* of the item in ``S[start:]``, or ``-1`` if ``S[start:]`` does not contain the item. @@ -70,9 +70,13 @@ Cython modules: Set ``S[index] = item``, without checking margins and assuming that ``S[index]`` has previously been zero. +- ``cdef inline void biseq_clearitem(biseq_t S, mp_size_t index)`` + + Set ``S[index] = 0``, without checking margins. + - ``cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1`` - Fills ``R`` with ``S[start:stop:step]`` + Initialises ``R`` with ``S[start:stop:step]``. """ #***************************************************************************** @@ -153,16 +157,17 @@ cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1: - ``bound`` -- a number which is the maximal value of an item """ - cdef mp_size_t index + cdef mp_size_t index = 0 cdef mp_limb_t item_limb biseq_init(R, len(data), BIT_COUNT(bound|1)) - for index from 0<=index bound: raise ValueError("list item {} larger than {}".format(data[index], bound) ) biseq_inititem(R, index, item_limb) + index += 1 # # Arithmetics @@ -204,7 +209,7 @@ cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1: return mpn_equal_bits(S1.data.bits, S2.data.bits, S2.data.size) -cdef int biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2: +cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2: """ Tests if the bounded integer sequence ``S1[start:]`` contains a sub-sequence ``S2`` @@ -239,40 +244,16 @@ cdef int biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2: return index return -1 -cdef int biseq_index(biseq_t S, mp_limb_t item, mp_size_t start) except -2: +cdef mp_size_t biseq_index(biseq_t S, size_t item, mp_size_t start) except -2: """ Returns the position in S of an item in S[start:], or -1 if S[start:] does not contain the item. """ - cdef mp_size_t limb_index, max_limbs - cdef mp_bitcnt_t bit_index, local_index - if S.length==0: - return -1 - max_limbs = S.data.limbs - 1 - cdef mp_size_t n - cdef mp_limb_t tmp_limb - limb_index = 0 - bit_index = 0 # This is the index mod GMP_LIMB_BITS in S.data - local_index = 0 # This is the index in tmp_limb - tmp_limb = S.data.bits[0] - item &= S.mask_item - for n from 0<=n GMP_LIMB_BITS: - local_index = 0 - # tmp_limb[0] can not provide the next item, we need to get new stuff - tmp_limb = S.data.bits[limb_index]>>bit_index - if bit_index and limb_index < max_limbs: - # We fill the rest of tmp_limb - tmp_limb |= (S.data.bits[limb_index+1]) << (GMP_LIMB_BITS - bit_index) - local_index += S.itembitsize - if item == tmp_limb&S.mask_item: - return n - tmp_limb>>=S.itembitsize - bit_index += S.itembitsize - if bit_index>=GMP_LIMB_BITS: - bit_index -= GMP_LIMB_BITS - preinc(limb_index) + cdef mp_size_t index + for index from 0 <= index < S.length: + if biseq_getitem(S, index) == item: + return index return -1 @@ -338,7 +319,8 @@ cdef inline void biseq_clearitem(biseq_t S, mp_size_t index): cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1: """ - Create the slice S[start:stop:step] as bounded integer sequence. + Create the slice S[start:stop:step] as bounded integer sequence and write + the result to ``R``, which must not be initialised. """ cdef mp_size_t length, total_shift, n @@ -355,24 +337,10 @@ cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int else: length = ((stop-start+1)//step)+1 biseq_init(R, length, S.itembitsize) - cdef mp_size_t offset_mod, offset_div total_shift = start*S.itembitsize if step==1: # Slicing essentially boils down to a shift operation. - offset_mod = total_shift % GMP_LIMB_BITS - offset_div = total_shift // GMP_LIMB_BITS - if offset_mod: - mpn_rshift(R.data.bits, S.data.bits+offset_div, R.data.limbs, offset_mod) - # Perhaps the last to-be-moved item partially belongs to the next - # limb of S? - if (R.data.size % GMP_LIMB_BITS)+offset_mod>GMP_LIMB_BITS: - R.data.bits[R.data.limbs-1] |= (S.data.bits[offset_div+R.data.limbs]<<(GMP_LIMB_BITS-offset_mod)) - else: - mpn_copyi(R.data.bits, S.data.bits+offset_div, R.data.limbs) - # Perhaps the last few bits of the last limb have to be set to zero? - offset_mod = (length*S.itembitsize) % GMP_LIMB_BITS - if offset_mod: - R.data.bits[R.data.limbs-1] &= ((1)<=n>0: - if local_index+self.data.itembitsize > GMP_LIMB_BITS: - local_index = 0 - # tmp_limb can not provide the next item, we need to get new stuff - tmp_limb = self.data.data.bits[limb_index]>>bit_index - if bit_index and limb_index < max_limbs: - # We fill the rest of tmp_limb - tmp_limb |= self.data.data.bits[limb_index+1] << (GMP_LIMB_BITS - bit_index) - local_index += self.data.itembitsize - yield (tmp_limb&self.data.mask_item) - tmp_limb>>=self.data.itembitsize - bit_index += self.data.itembitsize - if bit_index>=GMP_LIMB_BITS: - bit_index -= GMP_LIMB_BITS - preinc(limb_index) - + cdef mp_size_t index + for index from 0 <= index < self.data.length: + yield biseq_getitem_py(self.data, index) def __getitem__(self, index): """ @@ -986,13 +932,15 @@ cdef class BoundedIntegerSequence: sage: BoundedIntegerSequence(51, [2, 7, 20]) in S False - Note that the items are compared up to congruence modulo the bound of - the sequence. Thus we have:: + Note that the items are not just compared by congruence modulo the + bound of the sequence, but by equality. Thus we have:: sage: 6+S.bound() in S - True - sage: S.index(6) == S.index(6+S.bound()) - True + False + sage: S.index(6+S.bound()) + Traceback (most recent call last): + ... + ValueError: BoundedIntegerSequence.index(x): x(=38) not in sequence TESTS: @@ -1041,7 +989,7 @@ cdef class BoundedIntegerSequence: NOTE: A conversion to a list is also possible by iterating over the - sequence, which actually is faster. + sequence. EXAMPLES:: @@ -1103,7 +1051,7 @@ cdef class BoundedIntegerSequence: EXAMPLES:: sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence - sage: S = BoundedIntegerSequence(21, [4,1,6,2,6,20,9]) + sage: S = BoundedIntegerSequence(21, [4,1,6,2,6,20,9,0]) sage: S.index(6) 2 sage: S.index(5) @@ -1128,11 +1076,15 @@ cdef class BoundedIntegerSequence: ... ValueError: Not a sub-sequence - Note that items are compared up to congruence modulo the bound of the + Items are *not* compared up to congruence modulo the bound of the sequence:: - sage: S.index(6) == S.index(6+S.bound()) - True + sage: S.index(0) + 7 + sage: S.index(S.bound()) + Traceback (most recent call last): + ... + ValueError: BoundedIntegerSequence.index(x): x(=32) not in sequence TESTS:: @@ -1143,9 +1095,9 @@ cdef class BoundedIntegerSequence: 11 """ - cdef int out + cdef mp_size_t out if not isinstance(other, BoundedIntegerSequence): - if other<0: + if other<0 or (other)&self.data.mask_item!=other: raise ValueError("BoundedIntegerSequence.index(x): x(={}) not in sequence".format(other)) try: out = biseq_index(self.data, other, 0) @@ -1240,7 +1192,7 @@ cdef class BoundedIntegerSequence: """ if other.startswith(self): return self - cdef int i = biseq_max_overlap(self.data, other.data) + cdef mp_size_t i = biseq_max_overlap(self.data, other.data) if i==-1: return None return self[i:] From 43f78ad50eee7259ab06d5eec1d4cdb03a43f50b Mon Sep 17 00:00:00 2001 From: Simon King Date: Tue, 28 Oct 2014 16:35:08 +0100 Subject: [PATCH 132/698] Adding a reference to trac --- src/sage/data_structures/bitset.pxi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/data_structures/bitset.pxi b/src/sage/data_structures/bitset.pxi index cb75e8d2e1c..bbe19811cf2 100644 --- a/src/sage/data_structures/bitset.pxi +++ b/src/sage/data_structures/bitset.pxi @@ -13,7 +13,7 @@ AUTHORS: - Jeroen Demeyer (2014-09-05): use mpn_* functions from MPIR in the implementation (:trac`13352` and :trac:`16937`) - Simon King (2014-10-28): ``bitset_rshift`` and ``bitset_lshift`` respecting - the size of the given bitsets. + the size of the given bitsets (:trac:`15820`) """ #***************************************************************************** From 7a0dd469527c8a4f39d8d891703fcf5feecda9a1 Mon Sep 17 00:00:00 2001 From: Simon King Date: Tue, 28 Oct 2014 17:43:23 +0100 Subject: [PATCH 133/698] Some improvements of the doc --- src/sage/data_structures/bitset.pxi | 8 ++++---- .../data_structures/bounded_integer_sequences.pyx | 15 ++------------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/sage/data_structures/bitset.pxi b/src/sage/data_structures/bitset.pxi index bbe19811cf2..ffcb2a76369 100644 --- a/src/sage/data_structures/bitset.pxi +++ b/src/sage/data_structures/bitset.pxi @@ -603,8 +603,8 @@ cdef void bitset_rshift(bitset_t r, bitset_t a, mp_bitcnt_t n): Shift the bitset ``a`` right by ``n`` bits and store the result in ``r``. - If the result of the shift would exceed the size of ``r``, then it - will be cut. + There are no assumptions on the sizes of ``a`` and ``r``. Bits which are + shifted outside of the resulting bitset are discarded. """ if n >= a.size: mpn_zero(r.bits, r.limbs) @@ -640,8 +640,8 @@ cdef void bitset_lshift(bitset_t r, bitset_t a, mp_bitcnt_t n): Shift the bitset ``a`` left by ``n`` bits and store the result in ``r``. - If the result of the shift would exceed the size of ``r``, then it - will be cut. + There are no assumptions on the sizes of ``a`` and ``r``. Bits which are + shifted outside of the resulting bitset are discarded. """ if n >= r.size: mpn_zero(r.bits, r.limbs) diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index b25ad3fc7db..be016764e50 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -165,7 +165,7 @@ cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1: for item in data: item_limb = item if item_limb > bound: - raise ValueError("list item {} larger than {}".format(data[index], bound) ) + raise ValueError("list item {} larger than {}".format(item, bound) ) biseq_inititem(R, index, item_limb) index += 1 @@ -463,14 +463,8 @@ cdef class BoundedIntegerSequence: True sage: S[200:400] in S True - - Items will not just be compared by congruence modulo the bound of the - sequence, but by equality. Thus, we have:: - sage: S[200]+S.bound() in S False - sage: L[200]+S.bound() in L - False Bounded integer sequences are immutable, and thus copies are identical. This is the same for tuples, but of course not for lists:: @@ -932,8 +926,7 @@ cdef class BoundedIntegerSequence: sage: BoundedIntegerSequence(51, [2, 7, 20]) in S False - Note that the items are not just compared by congruence modulo the - bound of the sequence, but by equality. Thus we have:: + :: sage: 6+S.bound() in S False @@ -1075,10 +1068,6 @@ cdef class BoundedIntegerSequence: Traceback (most recent call last): ... ValueError: Not a sub-sequence - - Items are *not* compared up to congruence modulo the bound of the - sequence:: - sage: S.index(0) 7 sage: S.index(S.bound()) From 6723c7e44dbae3118e3dff259fd0e633915b53c9 Mon Sep 17 00:00:00 2001 From: Simon King Date: Wed, 29 Oct 2014 01:44:45 +0100 Subject: [PATCH 134/698] Fix highest bits of bitsets after fixing --- src/sage/data_structures/bitset.pxi | 9 +++++---- src/sage/data_structures/bounded_integer_sequences.pyx | 7 +++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/sage/data_structures/bitset.pxi b/src/sage/data_structures/bitset.pxi index ffcb2a76369..8d0b1d4b18d 100644 --- a/src/sage/data_structures/bitset.pxi +++ b/src/sage/data_structures/bitset.pxi @@ -619,21 +619,22 @@ cdef void bitset_rshift(bitset_t r, bitset_t a, mp_bitcnt_t n): if nbits: # mpn_rshift only does shifts less than a limb - if shifted_limbs <= r.limbs: + if shifted_limbs < r.limbs: mpn_rshift(r.bits, a.bits + nlimbs, shifted_limbs, nbits) else: mpn_rshift(r.bits, a.bits + nlimbs, r.limbs, nbits) # Add the additional bits from top limb of a r.bits[r.limbs-1] |= a.bits[r.limbs+nlimbs] << (GMP_LIMB_BITS - nbits) + bitset_fix(r) else: - if shifted_limbs <= r.limbs: + if shifted_limbs < r.limbs: mpn_copyi(r.bits, a.bits + nlimbs, shifted_limbs) else: mpn_copyi(r.bits, a.bits + nlimbs, r.limbs) bitset_fix(r) # Clear top limbs - if r.limbs + nlimbs >= a.limbs + 1: - mpn_zero(r.bits + (r.limbs - nlimbs), r.limbs + nlimbs - a.limbs) + if r.limbs + nlimbs > a.limbs: + mpn_zero(r.bits + (r.limbs - nlimbs), r.limbs - shifted_limbs) cdef void bitset_lshift(bitset_t r, bitset_t a, mp_bitcnt_t n): """ diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index be016764e50..b9913384440 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -887,6 +887,13 @@ cdef class BoundedIntegerSequence: sage: B[8:] <17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10> + :: + + sage: B1 = BoundedIntegerSequence(8, [0,7]) + sage: B2 = BoundedIntegerSequence(8, [2,1,4]) + sage: B1[0:1]+B2 + <0, 2, 1, 4> + """ cdef BoundedIntegerSequence out cdef Py_ssize_t start, stop, step, slicelength From b6ef6d5c5faffe4059b1539f00e25dd98b9481c0 Mon Sep 17 00:00:00 2001 From: Simon King Date: Wed, 29 Oct 2014 15:05:51 +0100 Subject: [PATCH 135/698] Rename biseq_slice -> biseq_init_slice --- src/sage/data_structures/bounded_integer_sequences.pxd | 2 +- src/sage/data_structures/bounded_integer_sequences.pyx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pxd b/src/sage/data_structures/bounded_integer_sequences.pxd index 4eefe01c93e..b816bf2d18d 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pxd +++ b/src/sage/data_structures/bounded_integer_sequences.pxd @@ -46,7 +46,7 @@ cdef size_t biseq_getitem(biseq_t S, mp_size_t index) cdef biseq_getitem_py(biseq_t S, mp_size_t index) cdef inline void biseq_inititem(biseq_t S, mp_size_t index, size_t item) cdef inline void biseq_clearitem(biseq_t S, mp_size_t index) -cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1 +cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1 cdef class BoundedIntegerSequence: cdef biseq_t data diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index b9913384440..0c0843bdb1c 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -74,7 +74,7 @@ Cython modules: Set ``S[index] = 0``, without checking margins. -- ``cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1`` +- ``cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1`` Initialises ``R`` with ``S[start:stop:step]``. @@ -317,7 +317,7 @@ cdef inline void biseq_clearitem(biseq_t S, mp_size_t index): # Our item is stored using 2 limbs, add the part from the upper limb S.data.bits[limb_index+1] &= ~(S.mask_item >> (GMP_LIMB_BITS - bit_index)) -cdef bint biseq_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1: +cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1: """ Create the slice S[start:stop:step] as bounded integer sequence and write the result to ``R``, which must not be initialised. @@ -902,7 +902,7 @@ cdef class BoundedIntegerSequence: if start==0 and stop==self.data.length and step==1: return self out = BoundedIntegerSequence.__new__(BoundedIntegerSequence, 0, None) - biseq_slice(out.data, self.data, start, stop, step) + biseq_init_slice(out.data, self.data, start, stop, step) return out cdef Py_ssize_t ind try: From 0e51c4a8ae1720e301b4d57ee51289de475bf51d Mon Sep 17 00:00:00 2001 From: Simon King Date: Thu, 30 Oct 2014 11:53:28 +0100 Subject: [PATCH 136/698] Change the type of an argument --- src/sage/data_structures/bounded_integer_sequences.pxd | 2 +- src/sage/data_structures/bounded_integer_sequences.pyx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pxd b/src/sage/data_structures/bounded_integer_sequences.pxd index b816bf2d18d..7e93713a628 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pxd +++ b/src/sage/data_structures/bounded_integer_sequences.pxd @@ -46,7 +46,7 @@ cdef size_t biseq_getitem(biseq_t S, mp_size_t index) cdef biseq_getitem_py(biseq_t S, mp_size_t index) cdef inline void biseq_inititem(biseq_t S, mp_size_t index, size_t item) cdef inline void biseq_clearitem(biseq_t S, mp_size_t index) -cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1 +cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, mp_size_t step) except -1 cdef class BoundedIntegerSequence: cdef biseq_t data diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index 0c0843bdb1c..0612f26e58f 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -74,7 +74,7 @@ Cython modules: Set ``S[index] = 0``, without checking margins. -- ``cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1`` +- ``cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, mp_size_t step) except -1`` Initialises ``R`` with ``S[start:stop:step]``. @@ -317,7 +317,7 @@ cdef inline void biseq_clearitem(biseq_t S, mp_size_t index): # Our item is stored using 2 limbs, add the part from the upper limb S.data.bits[limb_index+1] &= ~(S.mask_item >> (GMP_LIMB_BITS - bit_index)) -cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, int step) except -1: +cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, mp_size_t step) except -1: """ Create the slice S[start:stop:step] as bounded integer sequence and write the result to ``R``, which must not be initialised. From f65acdedf20554ed8cbd88fde232da4229d96f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 31 Oct 2014 20:33:59 +0100 Subject: [PATCH 137/698] trac #16603 first review commit --- src/sage/matrix/matrix2.pyx | 12 +++---- src/sage/matrix/matrix_misc.py | 62 +++++++++++++++++++--------------- 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index ff6bca4367a..b8b746e850f 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -900,7 +900,6 @@ cdef class Matrix(matrix1.Matrix): pm = pm + self.matrix_from_rows_and_columns(rows, cols).permanent() return pm - def rook_vector(self, check = False): r""" Return the rook vector of the matrix ``self``. @@ -952,7 +951,8 @@ cdef class Matrix(matrix1.Matrix): m = self._nrows n = self._ncols if not m <= n: - raise ValueError, "must have m <= n, but m (=%s) and n (=%s)"%(m,n) + raise ValueError("must have m <= n, but m (=%s) and n (=%s)" + % (m, n)) if check: # verify that self[i, j] in {0, 1} @@ -960,12 +960,11 @@ cdef class Matrix(matrix1.Matrix): for j in range(n): x = self.get_unsafe(i, j) if not (x == 0 or x == 1): - raise ValueError, "must have zero or one, but we have (=%s)"%x + raise ValueError("must have zero or one, but we have (=%s)" % x) - p = permanental_minor_vector(self) - return p + return permanental_minor_vector(self) - def minors(self,k): + def minors(self, k): r""" Return the list of all `k \times k` minors of self. @@ -14283,4 +14282,3 @@ def _jordan_form_vector_in_difference(V, W): if v not in W_space: return v return None - diff --git a/src/sage/matrix/matrix_misc.py b/src/sage/matrix/matrix_misc.py index 774acc85227..14b13231ef9 100644 --- a/src/sage/matrix/matrix_misc.py +++ b/src/sage/matrix/matrix_misc.py @@ -202,6 +202,11 @@ def weak_popov_form(M,ascend=True): return (matrix(r)/den, matrix(N), d) def _prm_mul(p1, p2, free_vars_indices, K): + """ + MISSING DOCUMENTATION HERE + + EXAMPLES:: + """ p = {} mask_free = 0 one = int(1) @@ -215,31 +220,37 @@ def _prm_mul(p1, p2, free_vars_indices, K): if exp1 & exp2: continue exp = exp1 | exp2 - v = v1*v2 + v = v1 * v2 if exp & mask_free: for i in free_vars_indices: - #print 'DB14 exp=%s i=%s' %(exp, i) if exp & (one << i): exp = exp.__xor__(one << i) - #print 'DB14b exp=%s' % exp p[exp] = get(exp, K.zero()) + v return p def _is_free_var(i, k, m): """ - i current row - k index of the variable - m matrix as a list of lists - returns true if the variable `k` does not occur from row `i` on + Return ``True`` if the variable `k` does not occur from row `i` on. + + INPUT: + + - i -- current row + - k -- index of the variable + - m -- matrix as a list of lists + + EXAMPLES:: + + sage: from sage.matrix.matrix_misc import _is_free_var + sage: m = [[1,2,3], [2,0,4], [2,0,4]] + sage: _is_free_var(1,1,m) + True """ - for j in range(i, len(m)): - if m[j][k] != 0: - return False - return True + return all(m[j][k] == 0 for j in range(i, len(m))) + def permanental_minor_vector(m, permanent_only=False): - """ + r""" Return the polynomial of the sums of permanental minors of a matrix `m` in array form. @@ -247,16 +258,15 @@ def permanental_minor_vector(m, permanent_only=False): .. MATH:: - \sum_0^{min(nrows, ncols)} p_i(m) x^i - - where `p_i(m) = m.permanental_minor(i)` + \sum_0^{min(nrows, ncols)} p_i(m) x^i + where `p_i(m)` is ``m.permanental_minor(i)``. INPUT: - - `m` - matrix + - `m` -- matrix - - `permanent_only` if True, only the permanent is computed + - `permanent_only` -- boolean, if ``True``, only the permanent is computed OUTPUT: @@ -273,20 +283,19 @@ def permanental_minor_vector(m, permanent_only=False): :: - sage: from sage.matrix.matrix_misc import permanental_minor_vector sage: M = MatrixSpace(ZZ,4,4) sage: A = M([1,0,1,0,1,0,1,0,1,0,10,10,1,0,1,1]) sage: permanental_minor_vector(A) [1, 28, 114, 84, 0] - :: + An example over `\QQ`:: sage: M = MatrixSpace(QQ,2,2) sage: A = M([1/5,2/7,3/2,4/5]) sage: permanental_minor_vector(A, 1) 103/175 - :: + An example with polynomial coefficients:: sage: R. = PolynomialRing(ZZ) sage: A = MatrixSpace(R,2)([[a,1], [a,a+1]]) @@ -295,15 +304,14 @@ def permanental_minor_vector(m, permanent_only=False): REFERENCES: - P. Butera and M. Pernici - ``Sums of permanental minors using Grassmann algebra'' - http://arxiv.org/abs/1406.5337 + .. [ButPer] P. Butera and M. Pernici "Sums of permanental minors + using Grassmann algebra", :arxiv:`1406.5337` """ K = PolynomialRing(m.base_ring(), 'K') m = list(m) nrows = len(m) ncols = len(m[0]) - p = {int(0):K.one()} + p = {int(0): K.one()} t = K.gen() done_vars = set() one = int(1) @@ -315,12 +323,12 @@ def permanental_minor_vector(m, permanent_only=False): a = m[i] for j in range(len(a)): if a[j]: - p1[one< Date: Sun, 2 Nov 2014 09:23:13 -0500 Subject: [PATCH 138/698] 15393: fixed numerous small issues from review --- .../projective/endPN_automorphism_group.py | 283 +++++++----------- .../schemes/projective/projective_morphism.py | 13 +- 2 files changed, 112 insertions(+), 184 deletions(-) diff --git a/src/sage/schemes/projective/endPN_automorphism_group.py b/src/sage/schemes/projective/endPN_automorphism_group.py index f862ddfd24d..e9f6e66b190 100644 --- a/src/sage/schemes/projective/endPN_automorphism_group.py +++ b/src/sage/schemes/projective/endPN_automorphism_group.py @@ -5,7 +5,7 @@ - Xander Faber, Michelle Manes, Bianca Viray: algorithm and original code "Computing Conjugating Sets and Automorphism Groups of Rational Functions" - by Xander Faber, Michelle Manes, and Bianca Viray + by Xander Faber, Michelle Manes, and Bianca Viray [FMV] - Joao de Faria, Ben Hutz, Bianca Thompson (11-2013): adaption for inclusion in Sage @@ -20,6 +20,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** +from copy import copy from sage.combinat.subset import Subsets from sage.functions.all import sqrt from itertools import permutations, combinations @@ -29,10 +30,11 @@ from sage.misc.misc_c import prod from sage.rings.arith import is_square, divisors from sage.rings.finite_rings.constructor import GF +from sage.rings.finite_rings.integer_mod_ring import Integers from sage.rings.fraction_field import FractionField from sage.rings.integer_ring import ZZ from sage.rings.number_field.number_field import NumberField -from sage.rings.arith import gcd, lcm +from sage.rings.arith import gcd, lcm, CRT from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import QQ from sage.sets.primes import Primes @@ -44,8 +46,7 @@ def automorphism_group_QQ_fixedpoints(rational_function, return_functions = Fals ALGORITHM: - See Algorithm 3 in "Computing Conjugating Sets and Automorphism Groups of Rational Functions" - by Xander Faber, Michelle Manes, and Bianca Viray + See Algorithm 3 in Faber-Manes-Viray [FMV] INPUT: @@ -86,8 +87,8 @@ def automorphism_group_QQ_fixedpoints(rational_function, return_functions = Fals sage: F. = PolynomialRing(QQ) sage: rational_function = (z^2 - 4*z -3)/(-3*z^2 - 2*z + 2) sage: from sage.schemes.projective.endPN_automorphism_group import automorphism_group_QQ_fixedpoints - sage: automorphism_group_QQ_fixedpoints(rational_function, True) - [z, (-z - 1)/z, -1/(z + 1)] + sage: automorphism_group_QQ_fixedpoints(rational_function, True, True) + ([z, (-z - 1)/z, -1/(z + 1)], 'Cyclic of order 3') """ if rational_function.parent().is_field(): @@ -123,7 +124,7 @@ def automorphism_group_QQ_fixedpoints(rational_function, return_functions = Fals if return_functions: elements = [z] else: - elements = [matrix(ZZ, 2, [1,0,0,1])] + elements = [matrix(F, 2, [1,0,0,1])] rational_roots = h.roots(multiplicities = False) @@ -131,8 +132,11 @@ def automorphism_group_QQ_fixedpoints(rational_function, return_functions = Fals #check if infinity is a fixed point if g.degree() < d: #then infinity is a fixed point - for T in g.roots(multiplicities = False):#find elements in W of the form - alpha = T #(infinty, y) + #find elements in W of the form (infinty, y) + #where W is the set of F-rational points (x,y) such that + #x is fixed by phi and phi(y)=x + for T in g.roots(multiplicities = False): + alpha = T zeta = -1 s = (zeta*z + alpha*(1 - zeta)) if s(phi(z)) == phi(s(z)): @@ -180,6 +184,7 @@ def automorphism_group_QQ_fixedpoints(rational_function, return_functions = Fals (1 - zeta), (alpha*zeta - beta)])) #first look at rational fixed points + #Subsets is ok since we just needed unordered pair over QQ for S in Subsets(rational_roots, 2): zeta = -1 alpha = S[0] @@ -256,7 +261,7 @@ def automorphism_group_QQ_fixedpoints(rational_function, return_functions = Fals elif is_square(-3*disc): #psi[0] generates Q(zeta_3) alpha = psi[0].change_ring(L2).roots()[0][0] beta = alpha.trace() - alpha - for zeta in [ZZ(1)/ZZ(2)*(1 + isqrt3), ZZ(1)/ZZ(2)*(1 - isqrt3),ZZ(1)/ZZ(2)*(-1 + isqrt3), ZZ(1)/ZZ(2)*(-1 - isqrt3)]: + for zeta in [F(1)/F(2)*(1 + isqrt3), F(1)/F(2)*(1 - isqrt3),F(1)/F(2)*(-1 + isqrt3), F(1)/F(2)*(-1 - isqrt3)]: a = (alpha - zeta*beta)/(1 - zeta) d = (alpha*zeta - beta)/(1 - zeta) if a in F and d in F: @@ -284,7 +289,7 @@ def height_bound(polynomial): This function returns a bound on the height of `F`, when viewed as an element of `\mathbb{P}^3` - We have proved that `ht(F) <= 6^{[K:Q]}*M`, where `M` is the Mahler measure of `f` + In [FMV] it is proven that `ht(F) <= 6^{[K:Q]}*M`, where `M` is the Mahler measure of `f` M is bounded above by `H(f)`, so we return the floor of `6*H(f)` (since `ht(F)` is an integer) @@ -329,8 +334,7 @@ def height_bound(polynomial): def PGL_repn(rational_function): r""" - Take a linear fraction transformation (an automorphism of `\mathbb{P}^1`) - and represent it as a 2x2 matrix (an element of `GL_2`). + Take a linear fraction transformation and represent it as a 2x2 matrix. INPUT: @@ -362,12 +366,13 @@ def PGL_repn(rational_function): def PGL_order(A): r""" - Find the multiplicative order of an element ``A`` of `GL_2(R)` that - has a finite order as an element of `PGL_2(R)`. + Find the multiplicative order of a linear fractional transformation that + has a finite order as an element of `PGL_2(R)`. ``A`` can be represented + either as a rational function or a 2x2 matrix INPUT: - - ``A`` -- an element of `GL_2(R)` + - ``A`` -- a linear fractional transformation OUTPUT: @@ -379,51 +384,24 @@ def PGL_order(A): sage: from sage.schemes.projective.endPN_automorphism_group import PGL_order sage: PGL_order(M) 2 + + :: + + sage: R. = PolynomialRing(QQ) + sage: from sage.schemes.projective.endPN_automorphism_group import PGL_order + sage: PGL_order(-1/x) + 2 """ n = 1 - B = A + AA = PGL_repn(A) + B = copy(AA) while B[0][0] != B[1][1] or B[0][1] != 0 or B[1][0] != 0: n = n + 1 - B = A*B + B = AA*B return n -def get_orders(L): - r""" - Find the multiplicative orders of a list of linear fractional transformations - that have a finite order - - INPUT: - - - ``L`` -- a list of degree 1 rational functions over `R` with finite order - - OUTPUT: - - - a list of positive integers and list of the `GL_2` representation of the - elements of `L` - - EXAMPLES:: - - sage: R. = PolynomialRing(QQ) - sage: L = [x, -x, 1/x, -1/x, (-x + 1)/(x + 1), (x + 1)/(x - 1), (x - 1)/(x + 1),(-x - 1)/(x - 1)] - sage: from sage.schemes.projective.endPN_automorphism_group import get_orders - sage: get_orders(L) - ([1, 2, 2, 2, 2, 2, 4, 4], [[1 0] - [0 1], [-1 0] - [ 0 1], [0 1] - [1 0], [ 0 -1] - [ 1 0], [-1 1] - [ 1 1], [ 1 1] - [ 1 -1], [ 1 -1] - [ 1 1], [-1 -1] - [ 1 -1]]) - """ - auts = [PGL_repn(A) for A in L] - auts.sort(key = PGL_order) - orders = [PGL_order(A) for A in auts] - return orders, auts - def CRT_helper(automorphisms, moduli): r""" Given a list of automorphisms over various `Zmod(p^k)` find a list @@ -486,11 +464,11 @@ def CRT_automorphisms(automorphisms, order_elts, degree, moduli): - ``degree`` - a positive integer - - ``moduli`` -- list of the various `p^k` + - ``moduli`` -- list of prime powers, i.e., `p^k` OUTPUT: - - a list of automorphisms over `Zmod(M)`. + - a list containing a list of automorphisms over `Zmod(M)` and the product of the moduli EXAMPLES:: @@ -503,13 +481,12 @@ def CRT_automorphisms(automorphisms, order_elts, degree, moduli): ([[0 1] [1 0]], 5) """ - # restrict to automorphisms of degree d - d = degree + # restrict to automorphisms of degree `degree` degree_d_autos = [] for j in range(len(automorphisms)): L = automorphisms[j] degree_d_autos.append( - [L[i] for i in range(len(L)) if order_elts[j][i] == d]) + [L[i] for i in range(len(L)) if order_elts[j][i] == degree]) # get list of CRT'ed automorphisms return CRT_helper(degree_d_autos, moduli) @@ -518,7 +495,7 @@ def valid_automorphisms(automorphisms_CRT, rational_function, ht_bound, M, return_functions = False): r""" Checks whether an element that is an automorphism of ``rational_function`` modulo `p^k` for various - `p`s and `k`s can be lifted to an automorphim over `ZZ`. It uses the fact that every + `p` s and `k` s can be lifted to an automorphism over `ZZ`. It uses the fact that every automorphism has height at most ``ht_bound`` INPUT: @@ -529,9 +506,9 @@ def valid_automorphisms(automorphisms_CRT, rational_function, ht_bound, M, - ``ht_bound`` - a positive integer - - ``M`` -- a list of prime powers + - ``M`` -- a positive integer, a product of prime powers - - ``return_functions`` -- Boolean, + - ``return_functions`` -- Boolean. default: False (optional) OUTPUT: @@ -545,13 +522,6 @@ def valid_automorphisms(automorphisms_CRT, rational_function, ht_bound, M, sage: valid_automorphisms([matrix(GF(5),[[0,1],[1,0]])], F, 48, 5, True) [1/z] """ -# if rational_function.parent().is_field(): -# K = rational_function.parent() -# R = K.ring() -# else: -# R = rational_function.parent() -# K = R.fraction_field() - z = rational_function.parent().gen(0) valid_auto = [] for A in automorphisms_CRT: @@ -565,9 +535,7 @@ def valid_automorphisms(automorphisms_CRT, rational_function, ht_bound, M, cc = scalar*c - (scalar*c/M).round()*M dd = scalar*d - (scalar*d/M).round()*M g = gcd([aa,bb,cc,dd]) - if gcd(scalar, M) == 1 and abs(aa) <= ht_bound*g and\ - abs(bb) <= ht_bound*g and abs(cc) <= ht_bound*g and\ - abs(dd) <= ht_bound*g: + if gcd(scalar, M) == 1 and max(abs(aa), abs(bb), abs(cc), abs(dd)) <= ht_bound*g: f = ((aa/g)*z + bb/g)/(cc/g*z + dd/g) if rational_function(f(z)) == f(rational_function(z)): if return_functions: @@ -580,9 +548,9 @@ def valid_automorphisms(automorphisms_CRT, rational_function, ht_bound, M, def remove_redundant_automorphisms(automorphisms, order_elts, moduli,integral_autos): r""" - if an element of Aut_{F_p} has been lifted to `QQ` + If an element of Aut_{F_p} has been lifted to `QQ` remove that element from `Aut_{F_p}` so we don't - attempt to lift that element again unecessarily + attempt to lift that element again unnecessarily INPUT: @@ -653,24 +621,24 @@ def remove_redundant_automorphisms(automorphisms, order_elts, moduli,integral_au def automorphism_group_QQ_CRT(rational_function, prime_lower_bound = 4, return_functions = True, iso_type=False): r""" Determines the complete group of rational automorphisms (under the conjugation action - of `PGL(2,QQ)`) for a rational function of one variable. + of `PGL(2,QQ)`) for a rational function of one variable, see [FMV] for details. INPUT: - ``rational_function`` - a rational function of a univariate polynomial ring over `QQ` - prime_lower_bound`` -- a positive integer - a lower bound for the primes to use for - the Chinese Remainder Theorem step. (optional) + the Chinese Remainder Theorem step. default: 4 (optional) - ``return_functions`` -- Boolean - True returns linear fractional transformations - False returns elements of `PGL(2,QQ)` (optional). + False returns elements of `PGL(2,QQ)` default: True (optional). - ``iso_type`` -- Boolean - True returns the isomorphism type of the automorphism group. default: False (optional) OUTPUT: - - a complete list of automorphisms of `rational_function` as linear fractional transformations + - a complete list of automorphisms of `rational_function` EXAMPLES:: @@ -732,10 +700,10 @@ def automorphism_group_QQ_CRT(rational_function, prime_lower_bound = 4, return_f # 2*gcd(2*[K:Q] + 1, d^3 - d) #Determining the set that is used to obtain the height bound - h = squarefree_part(f - g*z) # take minimal polynomial of fixed points + h = R(prod(x[0] for x in (R(f - g*z)).factor()))# take minimal polynomial of fixed points if h.degree() == 2: #if there are only 2 finite fixed points, take preimage of fixed points h = h[2]*f**2 + h[1]*f*g + h[0]*g**2 - elif h.degree() == 1: #if there is just 1 finite fixed points, take preimages under phi^2 + elif h.degree() == 1: #if there is just 1 finite fixed point, take preimages under phi^2 psi = phi(phi(z)) f2 = psi.numerator() g2 = psi.denominator() @@ -763,23 +731,22 @@ def automorphism_group_QQ_CRT(rational_function, prime_lower_bound = 4, return_f badorders = [1, 12]# order 12 not possible over Q, even though 4 and 6 are - #over Q, elts of PGL_2 of finite order can only have order dividing 6 or 4, + #over QQ, elts of PGL_2 of finite order can only have order dividing 6 or 4, # and the finite subgroups can only be cyclic or dihedral (Beauville) so # the only possible groups are C_n, D_2n for n|6 or n|4 # all of these groups have order dividing 24 while (congruence < (2*MaxH**2)) and len(elements) < gcd(orderaut + [24]): if badprimes%p != 0: #prime of good reduction - #hp = h.change_ring(GF(p)) # compute automorphisms mod p phi_p = f.change_ring(GF(p))/g.change_ring(GF(p)) - orders, sorted_automorphisms = get_orders(automorphism_group_FF(phi_p)) + sorted_automorphisms = automorphism_group_FF(phi_p) + sorted_automorphisms.sort(key = PGL_order) + orders = [PGL_order(A) for A in sorted_automorphisms] automorphisms.append(sorted_automorphisms) orderaut.append(len(automorphisms[-1])) orderelts.append(orders) - - k = 1 - primepowers.append(p**k) + primepowers.append(p) # check if we already found 8 or 12 automorphisms # and the gcd of orders over Fp and 24 is 24 @@ -794,7 +761,7 @@ def automorphism_group_QQ_CRT(rational_function, prime_lower_bound = 4, return_f N = gcd(orderaut + [12]) #all orders of elements divide N for order in [O for O in divisors(N) \ if not O in badorders]: #range over all orders - # that are possible over Q such that we haven't already + # that are possible over QQ such that we haven't already # found all elements of that order # First count number of elements of particular order @@ -802,7 +769,6 @@ def automorphism_group_QQ_CRT(rational_function, prime_lower_bound = 4, return_f for L in orderelts: numeltsoffixedorder.append(L.count(order)) numelts = min(numeltsoffixedorder) - # # Have some elts of fixed order mod p for each p if numelts != 0: #CRT order d elements together and check if @@ -812,8 +778,7 @@ def automorphism_group_QQ_CRT(rational_function, prime_lower_bound = 4, return_f temp = valid_automorphisms(autos, phi, MaxH, M, return_functions) elements.extend(temp) - # - # + if (len(elements) == gcd(orderaut + [24])): #found enough automorphisms if iso_type: @@ -824,7 +789,7 @@ def automorphism_group_QQ_CRT(rational_function, prime_lower_bound = 4, return_f # found all elements of order 'order; elif len(temp) != 0: # found some elements of order 'order' - # if an element of Aut_{F_p} has been lifted to Q + # if an element of Aut_{F_p} has been lifted to QQ # remove that element from Aut_{F_p} so we don't # attempt to lift that element again unecessarily automorphisms=remove_redundant_automorphisms(automorphisms, @@ -848,10 +813,8 @@ def automorphism_group_QQ_CRT(rational_function, prime_lower_bound = 4, return_f if iso_type: return(elements, which_group(elements)) return elements - else: - k = 0 + congruence = congruence*p - congruence = congruence*p**k p = primes.next(p) if iso_type: @@ -862,15 +825,9 @@ def automorphism_group_FF(rational_function, absolute=False, iso_type=False, ret r""" This function computes automorphism groups over finite fields. - AUTHORS: - - - Algorithm developed by X. Faber, M. Manes, B. Viray - - Last updated June 29, 2012 - ALGORITHM: - See Algorithm 4 in Computing Conjugating Sets and Automorphism Groups of Rational Functions - by Xander Faber, Michelle Manes, and Bianca Viray + See Algorithm 4 in Faber-Manes-Viray [FMV] INPUT: @@ -884,7 +841,7 @@ def automorphism_group_FF(rational_function, absolute=False, iso_type=False, ret default: False (optional) - ``return_functions`` -- Boolean, True returns linear fractional transformations - False returns elements of `PGL(2)`. (optional) + False returns elements of `PGL(2)`. default: False (optional) OUTPUT: @@ -892,7 +849,7 @@ def automorphism_group_FF(rational_function, absolute=False, iso_type=False, ret EXAMPLES:: - sage: R. = PolynomialRing(GF(5^2,'t')) + sage: R. = PolynomialRing(GF(5^2, 't')) sage: from sage.schemes.projective.endPN_automorphism_group import automorphism_group_FF sage: automorphism_group_FF((x^2+x+1)/(x+1)) [ @@ -902,22 +859,21 @@ def automorphism_group_FF(rational_function, absolute=False, iso_type=False, ret :: - sage: R. = PolynomialRing(GF(2^5,'t')) + sage: R. = PolynomialRing(GF(2^5, 't')) sage: from sage.schemes.projective.endPN_automorphism_group import automorphism_group_FF - sage: automorphism_group_FF(x^(5),True,False,True) + sage: automorphism_group_FF(x^(5), True, False, True) [Univariate Polynomial Ring in w over Finite Field in b of size 2^5, [w, 1/w]] :: - sage: R. = PolynomialRing(GF(2^5,'t')) + sage: R. = PolynomialRing(GF(2^5, 't')) sage: from sage.schemes.projective.endPN_automorphism_group import automorphism_group_FF - sage: automorphism_group_FF(x^(5),False,False,True) + sage: automorphism_group_FF(x^(5), False, False, True) [x, 1/x] """ if absolute==False: G = automorphism_group_FF_alg3(rational_function) - else: G = automorphism_group_FF_alg2(rational_function) @@ -935,18 +891,16 @@ def automorphism_group_FF(rational_function, absolute=False, iso_type=False, ret if iso_type == False: return G - elif absolute == False: return G, which_group(G) - else: return G, which_group(G[1]) -def field_descent(sigma, yy): +def field_descent(sigma, y): r""" Function for descending an element in a field E to a subfield F. - Here F, E must be finite fields or number fields. This function determine - the unique image of subfield which is ``yy` by the embedding ``sigma`` if it exists. + Here F, E must be finite fields or number fields. This function determines + the unique image of subfield which is ``y`` by the embedding ``sigma`` if it exists. Otherwise returns ``None``. This functionality is necessary because Sage does not keep track of subfields. @@ -954,7 +908,7 @@ def field_descent(sigma, yy): - ``sigma``-- an embedding sigma: `F` -> `E` of fields. - - ``yy`` --an element of the field `E` + - ``y`` --an element of the field `E` OUTPUT: @@ -969,7 +923,6 @@ def field_descent(sigma, yy): sage: field_descent(s, R(1)) 1 """ - y = yy F = sigma.domain() a = F.gen() @@ -980,7 +933,6 @@ def field_descent(sigma, yy): K = F.prime_subfield() R = PolynomialRing(K,'X') - X = R.gen(0) f = R(sigma(a).polynomial().coeffs()) g = R(y.polynomial().coeffs()) @@ -1002,7 +954,7 @@ def field_descent(sigma, yy): return x + F(quotient)*a**(steps) -def rational_function_coefficient_descent(rational_function, ssigma, poly_ring): +def rational_function_coefficient_descent(rational_function, sigma, poly_ring): r""" Function for descending the coefficients of a rational function from field `E` to a subfield `F`. Here `F`, `E` must be finite fields or number fields. @@ -1014,7 +966,7 @@ def rational_function_coefficient_descent(rational_function, ssigma, poly_ring): - ``rational_function``--a rational function with coefficients in a field `E`, - - ``ssigma``-- a field embedding sigma: `F` -> `E`. + - ``sigma``-- a field embedding sigma: `F` -> `E`. - ``poly_ring``-- a polynomial ring `R` with coefficients in `F`. @@ -1042,7 +994,6 @@ def rational_function_coefficient_descent(rational_function, ssigma, poly_ring): if rational_function == S(0): return poly_ring(0) - sigma = ssigma num=S(rational_function.numerator()) denom=S(rational_function.denominator()) f = num.coefficients() @@ -1054,10 +1005,9 @@ def rational_function_coefficient_descent(rational_function, ssigma, poly_ring): if None in ff or None in gg: return - R = poly_ring - z = R.gen(0) - numer = sum( R(ff[i])*z**fe[i] for i in range(len(ff)) ) - denom = sum( R(gg[i])*z**ge[i] for i in range(len(gg)) ) + z = poly_ring.gen(0) + numer = sum( poly_ring(ff[i])*z**fe[i] for i in range(len(ff)) ) + denom = sum( poly_ring(gg[i])*z**ge[i] for i in range(len(gg)) ) return numer / denom def rational_function_coerce(rational_function, sigma, S_polys): @@ -1108,11 +1058,11 @@ def rational_function_reduce(rational_function): INPUT: - - ``rational_function``--rational function `= F/G` in univariate polynomial ring. + - ``rational_function`` -- rational function `= F/G` in univariate polynomial ring. OUTPUT: - - `(F/gcd(F,G) ) / (G/gcd(F,G))`. + - rational function -- `(F/gcd(F,G) ) / (G/gcd(F,G))`. EXAMPLES:: @@ -1130,17 +1080,16 @@ def rational_function_reduce(rational_function): def three_stable_points(rational_function, invariant_list): r""" - Implementation of Algorithm 1 for automorphism groups from "Computing - Conjugating Sets and Automorphism Groups of Rational Functions" by Xander - Faber, Michelle Manes, and Bianca Viray. + Implementation of Algorithm 1 for automorphism groups from + Fbaer-Manes-Viary [FMV]. INPUT: - - ``rational_function``--rational function phi defined over finite + - ``rational_function``--rational function `phi` defined over finite field `E`. - ``invariant_list``-- a list of at least `3` points of `\mathbb{P}^1(E)` that - is stable under `Aut_phi(E)`. + is stable under `Aut_{phi}(E)`. OUTPUT: @@ -1202,17 +1151,16 @@ def three_stable_points(rational_function, invariant_list): s = K(a*z + b) / K(c*z + d) if s(phi(z)) == phi(s(z)) and s not in automorphisms: automorphisms.append(s) - return automorphisms def automorphism_group_FF_alg2(rational_function): r""" Implementation of algorithm for determining the absolute automorphism - group over a finite field, given an invariant set. + group over a finite field, given an invariant set., see [FMV]. INPUT: - - ``rational_function``--a rational function defined over a finite field `F`. + - ``rational_function``--a rational function defined over a finite field. OUTPUT: @@ -1265,14 +1213,12 @@ def automorphism_group_FF_alg2(rational_function): if n >= 3: T_poly = minimal_fix_poly infinity_check = bool(fix.degree() < D+1) - elif n == 2: # Infinity is a fixed point if bool(fix.degree() < D+1): y = fix.roots(multiplicities=False)[0] preimage = g*(f(z) - y*g(z)) infinity_check = 1 - # Infinity is not a fixed point else: C = minimal_fix_poly.coeffs() @@ -1295,13 +1241,13 @@ def automorphism_group_FF_alg2(rational_function): # Infinity is not a fixed point else: y = fix.roots(multiplicities=False)[0] - preimage = f(z) - y*g(z) + preimage = R(f(z) - y*g(z)) minimal_preimage = R(prod(x[0] for x in preimage.factor())) if minimal_preimage.degree() + bool(preimage.degree()= 3: T_poly = minimal_preimage infinity_check = bool(preimage.degree() 1: @@ -1448,7 +1393,6 @@ def order_p_automorphisms(rational_function, pre_data): # loop over all F-rational pre-images for guy in pre_image: pt = guy[0] - # treat case of multiple F-rational fixed points or # 1 F-rational fixed point with F-rational pre-images if T != []: @@ -1459,7 +1403,6 @@ def order_p_automorphisms(rational_function, pre_data): s = z + M[i][0] - M[0][0] if s(phi(z)) == phi(s(z)): automorphisms_p.append(s) - else: u = F(1) / (z - pt[0]) u_inv = pt[0] + F(1)/z @@ -1471,7 +1414,6 @@ def order_p_automorphisms(rational_function, pre_data): s = u_inv( u(z) + uy2 - uy1 ) if s(phi(z)) == phi(s(z)): automorphisms_p.append(s) - elif T==[]: # create the extension field generated by pre-images of the unique fixed point T_poly = pre_image[0][2] @@ -1482,12 +1424,10 @@ def order_p_automorphisms(rational_function, pre_data): S = PolynomialRing(E,'w') w = S.gen(0) E_poly = rational_function_coerce(T_poly, sigma, S) - # List of roots permuted by elements of order p # Since infinity is F-rational, it won't appear in this list T = [ [alpha, E(1)] for alpha in E_poly.roots(ring=E, multiplicities=False)] - # coerce the rational function and fixed point into E Phi = rational_function_coerce(phi, sigma, S) Pt = [sigma(pt[0]), sigma(pt[1])] @@ -1498,7 +1438,6 @@ def order_p_automorphisms(rational_function, pre_data): s = w + T[i][0] - T[0][0] if s(Phi(w)) == Phi(s(w)): automorphisms_p.append(rational_function_coefficient_descent(s, sigma, R)) - else: u = E(1) / (w - Pt[0]) u_inv = Pt[0] + E(1)/w @@ -1520,11 +1459,12 @@ def automorphisms_fixing_pair(rational_function, pair, quad): - ``pair``-- a pair of points of `\mathbb{P}^1(E)`. - - ``quad``-- an indicator if this is a quadratic pair of points + - ``quad``-- Boolean: an indicator if this is a quadratic pair of points OUTPUT: - - set of automorphisms defined over `E` that fix the pair, excluding the identity. + - set of automorphisms with order prime to characteristic defined over `E` that fix + the pair, excluding the identity. EXAMPLES:: @@ -1546,25 +1486,26 @@ def automorphisms_fixing_pair(rational_function, pair, quad): z = R.gen(0) phi = K(rational_function) E = R.base_ring() - T = pair f = phi.numerator() g = phi.denominator() D = max(f.degree(), g.degree()) - if T[0] == [1,0]: - u = K(z - T[1][0]) - u_inv = K(z + T[1][0]) - elif T[1] == [1,0]: - u = K(E(1) / (z - T[0][0])) - u_inv = K( (T[0][0]*z + 1) / z ) + #assumes the second coordiante of the point is 1 + if pair[0] == [1,0]: + u = K(z - pair[1][0]) + u_inv = K(z + pair[1][0]) + elif pair[1] == [1,0]: + u = K(E(1) / (z - pair[0][0])) + u_inv = K( (pair[0][0]*z + 1) / z ) else: - u = K( (z - T[1][0]) / (z - T[0][0]) ) - u_inv = K( (T[0][0]*z - T[1][0] ) / (z - 1) ) + u = K( (z - pair[1][0]) / (z - pair[0][0]) ) + u_inv = K( (pair[0][0]*z - pair[1][0] ) / (z - 1) ) automorphisms_prime_to_p = [] - # Quadratic automorphisms have order dividing q+1 and D, D-1, or D+1 if quad==True: + #need sqrt to get the cardinality of the base field and not the + #degree 2 extension q = sqrt(E.cardinality()) zeta = (E.multiplicative_generator())**(q-1) for j in [-1,0,1]: @@ -1591,7 +1532,7 @@ def automorphisms_fixing_pair(rational_function, pair, quad): def automorphism_group_FF_alg3(rational_function): r""" - Implementation of Algorithm 3 in the paper by Faber/Manes/Viray + Implementation of Algorithm 3 in the paper by Faber/Manes/Viray [FMV] for computing the automorphism group over a finite field. INPUT: @@ -1639,7 +1580,7 @@ def automorphism_group_FF_alg3(rational_function): # Compute the set of distinct F-rational and F-quadratic # factors of the fixed point polynomial - fix = f(z) - z*g(z) + fix = R(f(z) - z*g(z)) linear_fix = gcd(fix, z**q - z); quad_temp = fix.quo_rem(linear_fix)[0] residual = gcd(quad_temp, z**q - z) @@ -1672,7 +1613,7 @@ def automorphism_group_FF_alg3(rational_function): Fpre.append([F(1), F(0)]) # infinity is a pre-image of 0 elif f.degree() == g.degree() and f.leading_coefficient() == y[0]*g.leading_coefficient(): Fpre.append([F(1), F(0)]) # infinity is a pre-image of y[0] - # remove y[0] as a root of pre-image polynomial ??? + # remove y[0] as a root of pre-image polynomial h = (f - y[0]*g).quo_rem(z-y[0])[0] h_common = gcd(h, z-y[0]) while h_common.degree() > 0: @@ -1757,15 +1698,12 @@ def automorphism_group_FF_alg3(rational_function): return automorphisms -################################################################################ - -# Input: a finite list of elements of PGL(2,K) that we know a priori form a group -# Output: the isomorphism type of the group -# This function makes heavy use of the classification of finite subgroups of PGL(2,K) def which_group(list_of_elements): r""" Given a finite subgroup of `PGL2` determine its isomorphism class. + This function makes heavy use of the classification of finite subgroups of `PGL(2,K)` + INPUT: - ``list_of_elements``-- a finite list of elements of `PGL(2,K)` @@ -1794,7 +1732,7 @@ def which_group(list_of_elements): # invalid input if n == 0: - return + raise(ValueError, "Group must have at least one element") # define ground field and ambient function field rational_function = G[-1] @@ -1832,14 +1770,12 @@ def which_group(list_of_elements): H.append(h) H = list(set(H)) if len(H) == n: - # return ['Cyclic of order {0}'.format(n), g] return 'Cyclic of order {0}'.format(n) if len(H) > max_reg_cyclic[0] and gcd(len(H), p) != p: max_reg_cyclic = [len(H), g, H] discard = list(set(discard +H)) # adjoin all new elements to discard n_reg = max_reg_cyclic[0] - # Test for dihedral subgroup. A subgroup of index 2 is always normal, so the # presence of a cyclic subgroup H of index 2 indicates the group is either # H x Z/2Z or dihedral. The former occurs only if H has order 1 or 2, both of @@ -1847,16 +1783,13 @@ def which_group(list_of_elements): if 2*n_reg == n: for g in G: if g not in max_reg_cyclic[2]: - # return ['Dihedral of order {0}'.format(n), [max_reg_cyclic[1],g]] return 'Dihedral of order {0}'.format(n) - # Check the p-irregular cases. There is overlap in these cases when p^e = 2, # which is dihedral and so already dealt with above. By the classification theorem, # these are either p-semi-elementary, PGL(2,q), PSL(2,q), or A_5 when p=3. The latter # case is already covered by the remaining sporadic cases below. if e > 0: if n_reg == m: # p-semi-elementary - # return ['{0}-semi-elementary of order {1}'.format(p, n), 'No generator support'] return '{0}-semi-elementary of order {1}'.format(p, n) if n_reg == m / (p**e - 1) and m == p**(2*e) - 1: # PGL(2) return 'PGL(2,{0})'.format(p**e) @@ -1866,11 +1799,7 @@ def which_group(list_of_elements): # Treat sporadic cases if n == 12: return ['A_4'] - elif n == 24: return ['S_4'] - else: - return ['A_5'] - - return \ No newline at end of file + return ['A_5'] \ No newline at end of file diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index f17c4fda242..be436a63765 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -2160,10 +2160,12 @@ def automorphism_group(self, **kwds): AUTHORS: - Original algorithm written by Xander Faber, Michelle Manes, Bianca Viray + - Modified by Joao Alberto de Faria, Ben Hutz, Bianca Thompson REFERENCES: - ..[FMV] - "Computing Conjugating Sets and Automorphism Groups of Rational Functions" + + .. [FMV] Computing Conjugating Sets and Automorphism Groups of Rational Functions by Xander Faber, Michelle Manes, and Bianca Viray EXAMPLES:: @@ -3059,7 +3061,7 @@ def possible_periods(self, return_points=False): def automorphism_group(self, **kwds): r""" Given a homogenous rational function, this calculates the subsgroup of `PGL2` that is - the automorphism group of ``self``. + the automorphism group of ``self``, see [FMV] fir algorithm. INPUT: @@ -3078,12 +3080,9 @@ def automorphism_group(self, **kwds): AUTHORS: - - Original algorithm written by Xander Faber, Michelle Manes, Bianca Viray - - Modified by Joao Alberto de Faria, Ben Hutz, Bianca Thompson + - Original algorithm written by Xander Faber, Michelle Manes, Bianca Viray\ - REFERENCES: - ..[FMV] - "Computing Conjugating Sets and Automorphism Groups of Rational Functions" - by Xander Faber, Michelle Manes, and Bianca Viray + - Modified by Joao Alberto de Faria, Ben Hutz, Bianca Thompson EXAMPLES:: From 947ddd16da731019f25a951e43bf551ad997a700 Mon Sep 17 00:00:00 2001 From: Mario Pernici Date: Wed, 5 Nov 2014 18:32:53 +0100 Subject: [PATCH 139/698] Added missing documentation in ``_prm_mul``; changed name of variable from 'K' to 't' in ``permanental_minor_vector``. --- src/sage/matrix/matrix_misc.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/sage/matrix/matrix_misc.py b/src/sage/matrix/matrix_misc.py index 14b13231ef9..90c70efa6d7 100644 --- a/src/sage/matrix/matrix_misc.py +++ b/src/sage/matrix/matrix_misc.py @@ -203,9 +203,29 @@ def weak_popov_form(M,ascend=True): def _prm_mul(p1, p2, free_vars_indices, K): """ - MISSING DOCUMENTATION HERE + Return the product of `p1` and `p2`, putting free variables to 1. + + In the following example, + ``p1 = 1 + t*e_0 + t*e_1`` + ``p2 = 1 + t*e_0 + t*e_2; 'e_0` free variable; + using the fact that `e_i` are nilpotent and setting + `e_0 = 1` after performing the product one gets + ``p1 * p2 = (1 + 2*t) + (t + t^2)*e_1 + (t + t^2)*e_2 + t^2*e_1*e_2`` + + The polynomials are represented in dictionary form; to a + variable ``eta_i`` it is associated the key ``1 << i``; + so in the following example 'e_1' corresponds to the key '2' + and 'e_1*e_2' to the key '6'. EXAMPLES:: + + sage: from sage.matrix.matrix_misc import _prm_mul + sage: K = PolynomialRing(ZZ, 't') + sage: t = K.gen() + sage: p1 = {0: 1, 1: t, 4: t} + sage: p2 = {0: 1, 1: t, 2: t} + sage: _prm_mul(p1, p2, [0], K) + {0: 2*t + 1, 2: t^2 + t, 4: t^2 + t, 6: t^2} """ p = {} mask_free = 0 @@ -307,7 +327,7 @@ def permanental_minor_vector(m, permanent_only=False): .. [ButPer] P. Butera and M. Pernici "Sums of permanental minors using Grassmann algebra", :arxiv:`1406.5337` """ - K = PolynomialRing(m.base_ring(), 'K') + K = PolynomialRing(m.base_ring(), 't') m = list(m) nrows = len(m) ncols = len(m[0]) From 3fe2da9b9b7452542ffefa67ce857c58420d9d56 Mon Sep 17 00:00:00 2001 From: Karl-Dieter Crisman Date: Fri, 7 Nov 2014 14:29:05 -0500 Subject: [PATCH 140/698] Added even more plot cube root info, incl. to FAQ --- src/doc/en/faq/faq-usage.rst | 15 +++++++++++++++ src/sage/plot/plot.py | 17 ++++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/doc/en/faq/faq-usage.rst b/src/doc/en/faq/faq-usage.rst index 94ebacce9c6..a3eccd08fc2 100644 --- a/src/doc/en/faq/faq-usage.rst +++ b/src/doc/en/faq/faq-usage.rst @@ -661,6 +661,21 @@ then reboot. See `this page `_ for more details. +How do I plot the cube root (or other odd roots) for negative input? +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +This is one of the most frequently asked questions. There are several +methods mentioned in the plot documentation, but this one is easiest:: + + sage: plot(sign(x)*abs(x)^(1/3),-1,1) + Graphics object consisting of 1 graphics primitive + +The *reason* this is necessary is that Sage returns complex numbers +for odd roots of negative numbers when numerically approximated, which +is a `standard convention `_. + + sage: N((-1)^(1/3)) + 0.500000000000000 + 0.866025403784439*I How do I use the bitwise XOR operator in Sage? """""""""""""""""""""""""""""""""""""""""""""" diff --git a/src/sage/plot/plot.py b/src/sage/plot/plot.py index bcd66da6997..71e879aaa2a 100644 --- a/src/sage/plot/plot.py +++ b/src/sage/plot/plot.py @@ -1006,15 +1006,22 @@ def plot(funcs, *args, **kwds): Graphics object consisting of 1 graphics primitive sage: set_verbose(0) - To plot the negative real cube root, use something like the following:: + Plotting the real cube root function for negative input + requires avoiding the complex numbers one would usually get. + The easiest way is to use absolute value:: - sage: plot(lambda x : RR(x).nth_root(3), (x,-1, 1)) + sage: plot(sign(x)*abs(x)^(1/3), (x,-1,1)) Graphics object consisting of 1 graphics primitive - Another way to avoid getting complex numbers for negative input is to - calculate for the positive and negate the answer:: + We can also use the following:: + + sage: plot(sign(x)*(x*sign(x))^(1/3), (x,-4,4)) + Graphics object consisting of 1 graphics primitive - sage: plot(sign(x)*abs(x)^(1/3),-1,1) + A way that points to how to plot other functions without + symbolic variants is using lambda functions:: + + sage: plot(lambda x : RR(x).nth_root(3), (x,-1, 1)) Graphics object consisting of 1 graphics primitive We can detect the poles of a function:: From a59fe8caa1f0c7a272cbc1493fb65aac298e9608 Mon Sep 17 00:00:00 2001 From: Ralf Stephan Date: Mon, 10 Nov 2014 10:45:14 +0100 Subject: [PATCH 141/698] 17311: pass calls to Polynomial --- .../polynomial/polynomial_real_mpfr_dense.pyx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_real_mpfr_dense.pyx b/src/sage/rings/polynomial/polynomial_real_mpfr_dense.pyx index 7df469769f2..061b6aa4701 100644 --- a/src/sage/rings/polynomial/polynomial_real_mpfr_dense.pyx +++ b/src/sage/rings/polynomial/polynomial_real_mpfr_dense.pyx @@ -641,7 +641,7 @@ cdef class PolynomialRealDense(Polynomial): else: return a * ~a[a.degree()] << min(aval, bval) - def __call__(self, xx): + def __call__(self, *args, **kwds): """ EXAMPLES:: @@ -669,16 +669,29 @@ cdef class PolynomialRealDense(Polynomial): sage: f = PolynomialRealDense(RR['x']) sage: f(12) 0.000000000000000 + + TESTS:: + + sage: R. = RR[] # :trac:`17311` + sage: (x^2+1)(x=5) + 26.0000000000000 """ + if len(args) == 1: + xx = args[0] + else: + return Polynomial.__call__(self, *args, **kwds) + if not PY_TYPE_CHECK(xx, RealNumber): if self._base_ring.has_coerce_map_from(parent(xx)): xx = self._base_ring(xx) else: return Polynomial.__call__(self, xx) + cdef Py_ssize_t i cdef mp_rnd_t rnd = self._base_ring.rnd cdef RealNumber x = xx cdef RealNumber res + if (x._parent).__prec < self._base_ring.__prec: res = RealNumber(x._parent) else: @@ -704,7 +717,7 @@ cdef class PolynomialRealDense(Polynomial): mpfr_mul(res.value, res.value, x.value, rnd) mpfr_add(res.value, res.value, self._coeffs[i], rnd) return res - + def change_ring(self, R): """ EXAMPLES:: From a524288bad0774624c4823c37203341041117d65 Mon Sep 17 00:00:00 2001 From: Joao de Faria Date: Mon, 10 Nov 2014 16:06:53 -0500 Subject: [PATCH 142/698] Adapted code to not have to check for numerator --- .../schemes/projective/projective_morphism.py | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 105804d2157..9c122c700cf 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -1659,8 +1659,8 @@ def height_difference_bound(self, prec=None): 10.7632079329219 """ BR = self.domain().base_ring() - if not BR in NumberFields: - raise NotImplemenetedError("Must be a number field") + if not BR in NumberFields(): + raise NotImplementedError("Must be a number field") if not self.is_endomorphism(): raise NotImplementedError("Must be an endomorphism of projective space") if prec is None: @@ -1674,30 +1674,32 @@ def height_difference_bound(self, prec=None): U = self.global_height(prec) + R(binomial(N + d, d)).log() #compute lower bound - from explicit polynomials of Nullstellensatz CR = self.domain().coordinate_ring() - try: - Def_polys = BR.defining_polynomial() - except AttributeError: - Def_polys = [] - I = CR.ideal(self.defining_polynomials(), Def_polys) + CR = CR.change_ring(BR) #lift only works over fields + I = CR.ideal(self.defining_polynomials()) MCP = [] for k in range(N + 1): CoeffPolys = (CR.gen(k) ** D).lift(I) + print CoeffPolys Res = 1 - h = 1 for j in range(len(CoeffPolys)): if CoeffPolys[j] != 0: + #make this a list comprehension for i in range(len(CoeffPolys[j].coefficients())): Res = lcm(Res, abs(CoeffPolys[j].coefficients()[i].denominator())) - h = max(h, abs(CoeffPolys[j].coefficients()[i].numerator())) - MCP.append([Res, Res * h]) #since we need to clear denominators - maxh = 1 + h = max([c.global_height() for g in CoeffPolys for c in (Res*g).coefficients()]) + MCP.append([Res, h]) #since we need to clear denominators + print MCP + maxh = 0 gcdRes = 0 for k in range(len(MCP)): gcdRes = gcd(gcdRes, MCP[k][0]) maxh = max(maxh, MCP[k][1]) - L = abs(R(gcdRes / ((N + 1) * binomial(N + D - d, D - d) * maxh)).log()) - + print maxh + print R(gcdRes).log() + print R((N + 1) * binomial(N + D - d, D - d)).log() + L = abs( R(gcdRes).log() - R((N + 1) * binomial(N + D - d, D - d)).log() - maxh) C = max(U, L) #height difference dh(P) - L <= h(f(P)) <= dh(P) +U + print U,L return(C / (d - 1)) def multiplier(self, P, n, check=True): From f6ad07dd076109edea0b923bdeb3427a4b2e4f33 Mon Sep 17 00:00:00 2001 From: David Coudert Date: Tue, 11 Nov 2014 16:44:34 +0100 Subject: [PATCH 143/698] trac #17227: update module documentation --- src/sage/graphs/hyperbolicity.pyx | 64 ++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/src/sage/graphs/hyperbolicity.pyx b/src/sage/graphs/hyperbolicity.pyx index a50ba8ddf3a..04b80af7c7f 100644 --- a/src/sage/graphs/hyperbolicity.pyx +++ b/src/sage/graphs/hyperbolicity.pyx @@ -47,42 +47,64 @@ Hyperbolicity proposed in [FIV12]_. This remains very long for large-scale graphs, and much harder to implement. + Several improvements over the naive algorithm have been proposed and are + implemented in the current module. - An improvement over the naive algorithm has been proposed in [CCL12]_, and - is implemented in the current module. Like the naive algorithm, it has - complexity `O(n^4)` but behaves much better in practice. It uses the - following fact : + - It is shown in [Soto11]_ that `hyp(a, b, c, d)` is upper bounded by the + smallest distance between the vertices in `\{a,b,c,d\}` divided by 2. - Assume that `S_1 = dist(a, b) + dist(c, d)` is the largest among + .. MATH:: + + hyp(a, b, c, d) \leq \min_{u,v\in\{a,b,c,d\}}\frac{dist(u,v)}{2} + + This result is used to reduce the number of tested 4-tuples in the naive + implementation. + + - Another upper bound on `hyp(a, b, c, d)` has been proved in [CCL12]_. It + is used to design an algorithm with worse case time complexity in `O(n^4)` + but that behaves much better in practice. + + Assume that `S_1 = dist(a, b) + dist(c, d)` is the largest sum among `S_1,S_2,S_3`. We have .. MATH:: - S_2 + S_3 =& dist(a, c) + dist(b, d) + dist(a, d) + dist(b, c)\\ - =& [ dist(a, c) + dist(b, c) ] + [ dist(a, d) + dist(b, d)]\\ - \geq &dist(a,b) + dist(a,b)\\ - \geq &2dist(a,b)\\ + S_2 + S_3 =& dist(a, c) + dist(b, d) + dist(a, d) + dist(b, c)\\ + =& [ dist(a, c) + dist(b, c) ] + [ dist(a, d) + dist(b, d)]\\ + \geq &dist(a,b) + dist(a,b)\\ + \geq &2dist(a,b)\\ Now, since `S_1` is the largest sum, we have .. MATH:: - hyp(a, b, c, d) =& S_1 - \max\{S_2, S_3\}\\ - \leq& S_1 - \frac{S_2+ S_3}{2}\\ - \leq& S_1 - dist(a, b)\\ - =& dist(c, d)\\ + hyp(a, b, c, d) =& S_1 - \max\{S_2, S_3\}\\ + \leq& S_1 - \frac{S_2+ S_3}{2}\\ + \leq& S_1 - dist(a, b)\\ + =& dist(c, d)\\ We obtain similarly that `hyp(a, b, c, d) \leq dist(a, b)`. Consequently, in the implementation, we ensure that `S_1` is larger than `S_2` and `S_3` using an ordering of the pairs by decreasing lengths. Furthermore, we use the best value `h` found so far to cut exploration. - The worst case time complexity of this algorithm is `O(n^4)`, but it - performs very well in practice since it cuts the search space. This - algorithm can be turned into an approximation algorithm since at any step of - its execution we maintain an upper and a lower bound. We can thus stop - execution as soon as a multiplicative approximation factor or an additive - one is proven. + The worst case time complexity of this algorithm is `O(n^4)`, but it + performs very well in practice since it cuts the search space. This + algorithm can be turned into an approximation algorithm since at any step + of its execution we maintain an upper and a lower bound. We can thus stop + execution as soon as a multiplicative approximation factor or an additive + one is proven. + + - The notion of ''far-apart pairs'' has been introduced in [Soto11]_ to + further reduce the number of 4-tuples to consider. We say that the pair + `(a,b)` is far-apart if for every `w` in `V\setminus\{a,b\}` we have + `dist(w,a)+dist(a,b) > dist(w,b)` and `dist(w,b)+dist(a,b) > dist(w,a)`, + and determining the set of far-apart pairs can be done in time `O(nm)` + using BFS. Now, it is proved in [Soto11]_ that there exists two far-apart + pairs `(a,b)` and `(c,d)` satisfying `\delta(G) = hyp(a, b, c, d)/2`. For + instance, the `n\times m`-grid has only two far-apart pairs, and so + computing its hyperbolicity is immediate. + TODO: @@ -115,6 +137,10 @@ REFERENCES: .. [Gromov87] M. Gromov. Hyperbolic groups. Essays in Group Theory, 8:75--263, 1987. +.. [Soto11] M. A. Soto Gomez. 2011. Quelques proprietes topologiques des graphes + et applications a internet et aux reseaux. Ph.D. Dissertation. Univ. Paris + Diderot (Paris 7). + AUTHORS: - David Coudert (2012): initial version, exact and approximate algorithm, From b0c2006e167ed33423fa7a988a30bd72eef88a19 Mon Sep 17 00:00:00 2001 From: David Coudert Date: Tue, 11 Nov 2014 16:59:43 +0100 Subject: [PATCH 144/698] trac #17227: adds basic+ algorithm --- src/sage/graphs/hyperbolicity.pyx | 83 +++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 20 deletions(-) diff --git a/src/sage/graphs/hyperbolicity.pyx b/src/sage/graphs/hyperbolicity.pyx index 04b80af7c7f..557eba06c2a 100644 --- a/src/sage/graphs/hyperbolicity.pyx +++ b/src/sage/graphs/hyperbolicity.pyx @@ -166,8 +166,10 @@ from sage.rings.integer_ring import ZZ from sage.rings.real_mpfr import RR from sage.functions.other import floor from sage.misc.bitset import Bitset -from libc.stdint cimport uint16_t, uint32_t, uint64_t +from libc.stdint cimport uint16_t, uint32_t, uint64_t, INT32_MAX include "sage/ext/stdsage.pxi" +include "sage/ext/stdsage.pxi" +include "sage/misc/bitset.pxi" # Defining a pair of vertices as a C struct @@ -267,13 +269,14 @@ cdef inline int __hyp__(unsigned short ** distances, int a, int b, int c, int d) cdef tuple __hyperbolicity_basic_algorithm__(int N, unsigned short ** distances, + use_bounds = True, verbose = False): """ Returns **twice** the hyperbolicity of a graph, and a certificate. This method implements the basic algorithm for computing the hyperbolicity - of a graph, that is iterating over all 4-tuples. See the module's - documentation for more details. + of a graph, that is iterating over all 4-tuples, with a cutting rule + proposed in [Soto11]_. See the module's documentation for more details. INPUTS: @@ -281,6 +284,9 @@ cdef tuple __hyperbolicity_basic_algorithm__(int N, - ``distances`` -- path distance matrix (see the distance_all_pairs module). + - ``use_bounds`` -- (default: ``True``) is boolean. Uses a cutting rule + proposed in [Soto11]_ when set to ``True``. + - ``verbose`` -- (default: ``False``) is boolean. Set to True to display some information during execution. @@ -294,25 +300,53 @@ cdef tuple __hyperbolicity_basic_algorithm__(int N, - ``certificate`` -- 4-tuple of vertices maximizing the value `h`. If no such 4-tuple is found, the empty list [] is returned. """ - cdef int a, b, c, d, S1, S2, S3, hh, h_LB + cdef int a, b, c, d, hh, h_LB cdef list certificate h_LB = -1 - for 0 <= a < N-3: - for a < b < N-2: - for b < c < N-1: - for c < d < N: + if use_bounds: + for 0 <= a < N-3: + for a < b < N-2: + + # We use the cutting rule proposed in [Soto11]_ + if 2*distances[a][b] <= h_LB: + continue + + for b < c < N-1: - # We compute the hyperbolicity of the 4-tuple - hh = __hyp__(distances, a, b, c, d) + # We use the cutting rule proposed in [Soto11]_ + if 2*distances[a][c] <= h_LB or 2*distances[b][c] <= h_LB: + continue - # We compare the value with previously known bound - if hh > h_LB: - h_LB = hh - certificate = [a, b, c, d] + for c < d < N: - if verbose: - print 'New lower bound:',ZZ(hh)/2 + # We compute the hyperbolicity of the 4-tuple + hh = __hyp__(distances, a, b, c, d) + + # We compare the value with previously known bound + if hh > h_LB: + h_LB = hh + certificate = [a, b, c, d] + + if verbose: + print 'New lower bound:', ZZ(hh)/2 + + else: + for 0 <= a < N-3: + for a < b < N-2: + for b < c < N-1: + for c < d < N: + + # We compute the hyperbolicity of the 4-tuple + hh = __hyp__(distances, a, b, c, d) + + # We compare the value with previously known bound + if hh > h_LB: + h_LB = hh + certificate = [a, b, c, d] + + if verbose: + print 'New lower bound:',ZZ(hh)/2 # Last, we return the computed value and the certificate if h_LB != -1: @@ -779,6 +813,10 @@ def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=N - ``'basic'`` is an exhaustive algorithm considering all possible 4-tuples and so have time complexity in `O(n^4)`. + - ``'basic+'`` uses a cutting rule proposed in [Soto11]_ to + significantly reduce the overall computation time of the ``'basic'`` + algorithm. + - ``'cuts'`` is an exact algorithm proposed in [CCL12_]. It considers the 4-tuples in an ordering allowing to cut the search space as soon as a new lower bound is found (see the module's documentation). This @@ -851,6 +889,8 @@ def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=N (1/2, [0, 1, 2, 3], 1/2) sage: hyperbolicity(G,algorithm='basic') (1/2, [0, 1, 2, 3], 1/2) + sage: hyperbolicity(G,algorithm='basic+') + (1/2, [0, 1, 2, 3], 1/2) sage: hyperbolicity(G,algorithm='dom') (0, [0, 2, 8, 9], 1) @@ -877,10 +917,11 @@ def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=N sage: for i in xrange(10): # long time ... G = graphs.RandomBarabasiAlbert(100,2) ... d1,_,_ = hyperbolicity(G,algorithm='basic') + ... d4,_,_ = hyperbolicity(G,algorithm='basic+') ... d2,_,_ = hyperbolicity(G,algorithm='cuts') ... d3,_,_ = hyperbolicity(G,algorithm='cuts+') ... l3,_,u3 = hyperbolicity(G,approximation_factor=2) - ... if d1!=d2 or d1d1 or u3d1 or u3 Date: Tue, 11 Nov 2014 17:02:00 +0100 Subject: [PATCH 145/698] trac #17227: adds verbose parameter to greedy dominating set --- src/sage/graphs/hyperbolicity.pyx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/hyperbolicity.pyx b/src/sage/graphs/hyperbolicity.pyx index 557eba06c2a..2aae7246917 100644 --- a/src/sage/graphs/hyperbolicity.pyx +++ b/src/sage/graphs/hyperbolicity.pyx @@ -462,7 +462,7 @@ def elimination_ordering_of_simplicial_vertices(G, max_degree=4, verbose=False): # Greedy dominating set ###################################################################### -def _greedy_dominating_set(H): +def _greedy_dominating_set(H, verbose=False): r""" Returns a greedy approximation of a dominating set """ @@ -474,6 +474,10 @@ def _greedy_dominating_set(H): seen.add(u) DOM.append(u) seen.update(H.neighbor_iterator(u)) + + if verbose: + print "Greedy dominating set:", sorted(list(DOM)) + return DOM ###################################################################### @@ -1090,7 +1094,7 @@ def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=N elif algorithm == 'dom': # Computes a dominating set DOM of H, and computes the # hyperbolicity considering only vertices in DOM - DOM = _greedy_dominating_set(H) + DOM = _greedy_dominating_set(H, verbose=verbose) elim = [u for u in H.vertex_iterator() if not u in DOM] # We need at least 4 vertices while len(DOM)<4: From 6b61e14de6a423bbfb221eecbbb155aa1311b534 Mon Sep 17 00:00:00 2001 From: David Coudert Date: Tue, 11 Nov 2014 17:20:32 +0100 Subject: [PATCH 146/698] trac #17227: add a method to compute both distances and far-apart pairs --- src/sage/graphs/hyperbolicity.pyx | 127 ++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/src/sage/graphs/hyperbolicity.pyx b/src/sage/graphs/hyperbolicity.pyx index 2aae7246917..210edc5e079 100644 --- a/src/sage/graphs/hyperbolicity.pyx +++ b/src/sage/graphs/hyperbolicity.pyx @@ -480,6 +480,133 @@ def _greedy_dominating_set(H, verbose=False): return DOM +###################################################################### +# Distances and far-apart pairs +###################################################################### + +from sage.graphs.base.static_sparse_graph cimport short_digraph, init_short_digraph, free_short_digraph + +cdef inline distances_and_far_apart_pairs(gg, + unsigned short * distances, + unsigned short * far_apart_pairs): + """ + Compute both distances between all pairs and far-apart pairs. + + See the module's documentation for the definition of far-apart pairs. + + This method assumes that the arays distances and far_apart_pairs have been + allocated with size `n^2`. + """ + + cdef int n = gg.order() + cdef int i + + if distances == NULL or far_apart_pairs == NULL: + raise ValueError("This method can only be used to compute both "+ + "distances and far-apart pairs.") + elif n > -1: + # Computing the distances/far_apart_pairs can only be done if we have + # less than MAX_UNSIGNED_SHORT vertices. + raise ValueError("The graph backend contains more than "+ + str( -1)+" nodes and we cannot "+ + "compute the matrix of distances/far-apart pairs on "+ + "something like that !") + + # The vertices which have already been visited + cdef bitset_t seen + bitset_init(seen, n) + + # The list of waiting vertices, the beginning and the end of the list + cdef uint32_t * waiting_list = sage_malloc(n * sizeof(uint32_t)) + if waiting_list == NULL: + sage_free(seen) + raise MemoryError("Unable to allocate array 'waiting_list' with size %d." %(n)) + cdef uint32_t waiting_beginning = 0 + cdef uint32_t waiting_end = 0 + + cdef uint32_t source + cdef uint32_t v, u + + cdef unsigned short ** c_far_apart = sage_malloc(n * sizeof(unsigned short*)) + if c_far_apart == NULL: + bitset_free(seen) + sage_free(waiting_list) + raise MemoryError("Unable to allocate array 'c_far_apart' with size %d." %(n)) + + # All pairs are initially far-apart + memset(far_apart_pairs, 1, n * n * sizeof(unsigned short)) + for i from 0 <= i < n: + c_far_apart[i] = far_apart_pairs + i * n + c_far_apart[i][i] = 0 + + + # Copying the whole graph to obtain the list of neighbors quicker than by + # calling out_neighbors. This data structure is well documented in the + # module sage.graphs.base.static_sparse_graph + cdef short_digraph sd + init_short_digraph(sd, gg) + cdef uint32_t ** p_vertices = sd.neighbors + cdef uint32_t * p_tmp + cdef uint32_t * end + + cdef unsigned short * c_distances = distances + + # We run n different BFS taking each vertex as a source + for source from 0 <= source < n: + + # The source is seen + bitset_clear(seen) + bitset_add(seen, source) + c_distances[source] = 0 + + # and added to the queue + waiting_list[0] = source + waiting_beginning = 0 + waiting_end = 0 + + # For as long as there are vertices left to explore + while waiting_beginning <= waiting_end: + + # We pick the first one + v = waiting_list[waiting_beginning] + + p_tmp = p_vertices[v] + end = p_vertices[v+1] + + # Iterating over all the outneighbors u of v + while p_tmp < end: + u = p_tmp[0] + + # If we notice one of these neighbors is not seen yet, we set + # its parameters and add it to the queue to be explored later. + if not bitset_in(seen, u): + c_distances[u] = c_distances[v]+1 + bitset_add(seen, u) + waiting_end += 1 + waiting_list[waiting_end] = u + + if c_distances[u] == c_distances[v]+1: + # v is on the path from source to u + c_far_apart[source][v] = 0 + c_far_apart[v][source] = 0 + + p_tmp += 1 + + waiting_beginning += 1 + + # If not all the vertices have been met + for v from 0 <= v < n: + if not bitset_in(seen, v): + c_distances[v] = -1 + + c_distances += n + + bitset_free(seen) + sage_free(waiting_list) + free_short_digraph(sd) + sage_free(c_far_apart) + + ###################################################################### # Compute the hyperbolicity using a path decreasing length ordering ###################################################################### From 18dfcf29b236bec025925468998fd73f72d1d785 Mon Sep 17 00:00:00 2001 From: David Coudert Date: Tue, 11 Nov 2014 18:01:00 +0100 Subject: [PATCH 147/698] trac #17227: change the behavior of the cuts+ method that now uses far-apart pairs --- src/sage/graphs/hyperbolicity.pyx | 340 +++++++++++++++--------------- 1 file changed, 174 insertions(+), 166 deletions(-) diff --git a/src/sage/graphs/hyperbolicity.pyx b/src/sage/graphs/hyperbolicity.pyx index 210edc5e079..8be58e73d0e 100644 --- a/src/sage/graphs/hyperbolicity.pyx +++ b/src/sage/graphs/hyperbolicity.pyx @@ -654,11 +654,11 @@ cdef _order_pairs_according_elimination(elim, int N, pair *pairs, uint32_t nb_pa cdef tuple __hyperbolicity__(int N, unsigned short ** distances, + unsigned short ** far_apart_pairs, int D, int h_LB, float approximation_factor, float additive_gap, - elim, verbose = False): """ Return the hyperbolicity of a graph. @@ -672,6 +672,9 @@ cdef tuple __hyperbolicity__(int N, - ``distances`` -- path distance matrix + - ``far_apart_pairs`` -- 0/1 matrix of far-apart pairs. Pair ``(i,j)`` is + far-apart if ``far_apart_pairs[i][j]\neq 0``. + - ``D`` -- diameter of the graph - ``h_LB`` -- lower bound on the hyperbolicity @@ -687,9 +690,6 @@ cdef tuple __hyperbolicity__(int N, best found solution is less than additive gap. When the gap is 0.0, the problem is solved optimaly. - - ``elim`` -- list of vertices that should not be considered during - computations. - - ``verbose`` -- (default: ``False``) is boolean set to ``True`` to display some information during execution @@ -709,10 +709,11 @@ cdef tuple __hyperbolicity__(int N, - ``h_UB`` -- is an integer equal to the proven upper bound for `h`. When ``h == h_UB``, the returned solution is optimal. """ - cdef int i, j, l, l1, l2, h, hh, h_UB, a, b, c, d, S1, S2, S3 - cdef uint32_t x, y - cdef dict distr = {} + cdef int hh # can get negative value + cdef uint16_t a, b, c, d, h, h_UB + cdef uint32_t x, y, l1, l2, S1, S2, S3 cdef list certificate = [] + cdef unsigned short *p_far_apart # ==> Allocates and fills nb_pairs_of_length # @@ -720,11 +721,19 @@ cdef tuple __hyperbolicity__(int N, cdef uint32_t * nb_pairs_of_length = sage_calloc(D+1,sizeof(uint32_t)) if nb_pairs_of_length == NULL: sage_free(nb_pairs_of_length) - raise MemoryError + raise MemoryError("Unable to allocate array 'nb_pairs_of_length'.") - for 0 <= i < N: - for i+1 <= j < N: - nb_pairs_of_length[ distances[i][j] ] += 1 + # ==> Count the number of (far-apart) pairs of vertices at distance d + if far_apart_pairs == NULL: + for i from 0 <= i < N: + for j from i+1 <= j < N: + nb_pairs_of_length[ distances[i][j] ] += 1 + else: + for i from 0 <= i < N: + p_far_apart = far_apart_pairs[i] + for j from i+1 <= j < N: + if p_far_apart[j]: + nb_pairs_of_length[ distances[i][j] ] += 1 # ==> Allocates pairs_of_length # @@ -732,7 +741,7 @@ cdef tuple __hyperbolicity__(int N, cdef pair ** pairs_of_length = sage_malloc(sizeof(pair *)*(D+1)) if pairs_of_length == NULL: sage_free(nb_pairs_of_length) - raise MemoryError + raise MemoryError("Unable to allocate array 'pairs_of_length'.") # ==> Allocates cpt_pairs # @@ -741,10 +750,12 @@ cdef tuple __hyperbolicity__(int N, if cpt_pairs == NULL: sage_free(nb_pairs_of_length) sage_free(pairs_of_length) - raise MemoryError + raise MemoryError("Unable to allocate array 'cpt_pairs'.") # ==> Allocates pairs_of_length[d] for all d - for 1 <= i <= D: + cdef uint32_t nb_p = 0 + for i from 1 <= i <= D: + nb_p += nb_pairs_of_length[i] pairs_of_length[i] = sage_malloc(sizeof(pair)*nb_pairs_of_length[i]) if nb_pairs_of_length[i] > 0 and pairs_of_length[i] == NULL: @@ -754,38 +765,34 @@ cdef tuple __hyperbolicity__(int N, sage_free(nb_pairs_of_length) sage_free(pairs_of_length) sage_free(cpt_pairs) - raise MemoryError + raise MemoryError("Unable to allocate array 'pairs_of_length[i]'.") # ==> Fills pairs_of_length[d] for all d - for 0 <= i < N: - for i+1 <= j < N: - l = distances[i][j] - pairs_of_length[ l ][ cpt_pairs[ l ] ].s = i - pairs_of_length[ l ][ cpt_pairs[ l ] ].t = j - cpt_pairs[ l ] += 1 + if far_apart_pairs == NULL: + for i from 0 <= i < N: + for j from i+1 <= j < N: + k = distances[i][j] + if k: + pairs_of_length[ k ][ cpt_pairs[ k ] ].s = i + pairs_of_length[ k ][ cpt_pairs[ k ] ].t = j + cpt_pairs[ k ] += 1 + else: + for i from 0 <= i < N: + p_far_apart = far_apart_pairs[i] + for j from i+1 <= j < N: + if p_far_apart[j]: + k = distances[i][j] + pairs_of_length[ k ][ cpt_pairs[ k ] ].s = i + pairs_of_length[ k ][ cpt_pairs[ k ] ].t = j + cpt_pairs[ k ] += 1 sage_free(cpt_pairs) if verbose: print "Current 2 connected component has %d vertices and diameter %d" %(N,D) - print "Paths length distribution:", [ (l, nb_pairs_of_length[l]) for l in range(1, D+1) ] + print "Number of (far-apart) pairs: %d\t(%d pairs in total)" %(nb_p, binomial(N, 2)) + print "Repartition of (far-apart) pairs:", [ (i, nb_pairs_of_length[i]) for i in range(1, D+1) if nb_pairs_of_length[i]>0] - # ==> Allocates last_pair - # - # We change the ordering of the pairs to avoid considering pairs touching - # eliminated vertices (i.e., vertices in elim). We store in last_pair[l] the - # index of the last pair of length l to consider. - cdef uint32_t * last_pair = sage_malloc(sizeof(uint32_t)*(D+1)) - if last_pair == NULL: - for 1 <= i <= D: - sage_free(pairs_of_length[i]) - sage_free(nb_pairs_of_length) - sage_free(pairs_of_length) - sage_free(cpt_pairs) - raise MemoryError - - for 1 <= l <= D: - _order_pairs_according_elimination(elim, N, pairs_of_length[l], nb_pairs_of_length[l], last_pair+l) approximation_factor = min(approximation_factor, D) additive_gap = min(additive_gap, D) @@ -795,27 +802,23 @@ cdef tuple __hyperbolicity__(int N, # decreasing length1. This is to ensure a valid ordering for S1, to avoid # some tests, and to ease computation of bounds. cdef list triples = [] - for i in range(D,0,-1): - for j in range(D,i-1,-1): - triples.append((i+j,j,i)) + for l2 from D >= l2 > 0: + if nb_pairs_of_length[l2]>0: + for l1 from D >= l1 >= l2: + if nb_pairs_of_length[l1]>0: + triples.append((l1+l2, l1, l2)) # We use some short-cut variables for efficiency cdef pair * pairs_of_length_l1 cdef pair * pairs_of_length_l2 cdef uint32_t nb_pairs_of_length_l1, nb_pairs_of_length_l2 + cdef unsigned short * dist_a + cdef unsigned short * dist_b h = h_LB h_UB = D cdef int STOP = 0 for S1, l1, l2 in triples: - # If we cannot improve further, we stop - # - # See the module's documentation for an proof that this cut is - # valid. Remember that the triples are sorted in a specific order. - if l2 <= h: - h_UB = h - break - if h_UB > l2: h_UB = l2 @@ -824,83 +827,69 @@ cdef tuple __hyperbolicity__(int N, # Termination if required approximation is found if certificate and ( (h_UB <= h*approximation_factor) or (h_UB-h <= additive_gap) ): + STOP = 2 break + # If we cannot improve further, we stop + # + # See the module's documentation for an proof that this cut is + # valid. Remember that the triples are sorted in a specific order. + if l2 <= h: + h_UB = h + STOP = 1 + break + pairs_of_length_l1 = pairs_of_length[l1] + pairs_of_length_l2 = pairs_of_length[l2] nb_pairs_of_length_l1 = last_pair[l1] - x = 0 - while x < nb_pairs_of_length_l1: + nb_pairs_of_length_l2 = nb_pairs_of_length[l2] + + for x from 0 <= x < nb_pairs_of_length_l1: a = pairs_of_length_l1[x].s b = pairs_of_length_l1[x].t - - # If we cannot improve further, we stop - # - # See the module's documentation for an proof that this cut is - # valid. - if l2 <= h: - STOP = 1 - break - - # We do not want to test pairs of pairs twice if l1 == l2 - elif l1 == l2: - y = x+1 - else: - y = 0 - - pairs_of_length_l2 = pairs_of_length[l2] - nb_pairs_of_length_l2 = last_pair[l2] - while y < nb_pairs_of_length_l2: - c = pairs_of_length_l2[y].s - d = pairs_of_length_l2[y].t - - # If two points are equal, the value will be 0, so we skip the - # test. - if a == c or a == d or b == c or b == d: - y += 1 - continue - - # We compute the hyperbolicity of the 4-tuple. We have S1 = l1 + - # l2, and the order in which pairs are visited allow us to claim - # that S1 = max( S1, S2, S3 ). If at some point S1 is not the - # maximum value, the order ensures that the maximum value has - # previously been checked. - S2 = distances[a][c] + distances[b][d] - S3 = distances[a][d] + distances[b][c] - if S2 > S3: - hh = S1 - S2 - else: - hh = S1 - S3 - - if h < hh or not certificate: - # We update current bound on the hyperbolicity and the - # search space - h = hh - certificate = [a, b, c, d] - - if verbose: - print "New lower bound:",ZZ(hh)/2 - - # Termination if required approximation is found - if (h_UB <= h*approximation_factor) or (h_UB-h <= additive_gap): - STOP = 1 - break - - # We go for the next pair c-d - y += 1 - # We cut current exploration if we know we can not improve lower bound - # - # See the module's documentation for an proof that this cut is - # valid. - if l2 <= h: - STOP = 1 - h_UB = h - break - - if STOP: - break - - # We go for the next pair a-b - x += 1 + dist_a = distances[a] + dist_b = distances[b] + + # We do not want to test pairs of pairs twice if l1 == l2 + for y from (x+1 if l1==l2 else 0) <= y < nb_pairs_of_length_l2: + c = pairs_of_length_l2[y].s + d = pairs_of_length_l2[y].t + + # We compute the hyperbolicity of the 4-tuple. We have S1 = l1 + # + l2, and the order in which pairs are visited allow us to + # claim that S1 = max( S1, S2, S3 ). If at some point S1 is not + # the maximum value, the order ensures that the maximum value + # has previously been checked. + S2 = dist_a[c] + dist_b[d] + S3 = dist_a[d] + dist_b[c] + if S2 > S3: + hh = S1 - S2 + else: + hh = S1 - S3 + + if h < hh or not certificate: + # We update current bound on the hyperbolicity and the + # search space, unless hh==0 and two vertices are equal. + if h>0 or not (a==c or a==d or b==c or b==d): + h = hh + certificate = [a, b, c, d] + + if verbose: + print "New lower bound:",ZZ(hh)/2 + + # If we cannot improve further, we stop + if l2 <= h: + STOP = 1 + h_UB = h + break + + # Termination if required approximation is found + if (h_UB <= h*approximation_factor) or (h_UB-h <= additive_gap): + STOP = 2 + break + + if STOP: + break if STOP: break @@ -910,13 +899,13 @@ cdef tuple __hyperbolicity__(int N, for 1 <= i <= D: sage_free(pairs_of_length[i]) sage_free(pairs_of_length) - sage_free(last_pair) # Last, we return the computed value and the certificate if len(certificate) == 0: return ( -1, [], h_UB ) else: - return (h, certificate, h_UB) + # When using far-apart pairs, the loops may end + return (h, certificate, h_UB if STOP==2 else h) def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=None, verbose = False): @@ -953,16 +942,9 @@ def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=N as a new lower bound is found (see the module's documentation). This algorithm can be turned into a approximation algorithm. - - ``'cuts+'`` is an additive constant approximation algorithm. It - proceeds by first removing the simplicial vertices and then applying - the ``'cuts'`` algorithm on the remaining graph, as documented in - [CCL12_]. By default, the additive constant of the approximation is - one. This value can be increased by setting the ``additive_gap`` to - the desired value, provide ``additive_gap \geq 1``. In some cases, - the returned result is proven optimal. However, this algorithm - *cannot* be used to compute an approximation with multiplicative - factor, and so the ``approximation_factor`` parameter is just - ignored here. + - ``'cuts+'`` uses the notion of far-apart pairs as proposed in + [Soto11]_ to significantly reduce the overall computation time of + the ``'cuts'`` algorithm. - ``'dom'`` is an approximation with additive constant four. It computes the hyperbolicity of the vertices of a dominating set of @@ -982,8 +964,7 @@ def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=N function stop computations as soon as the difference between the upper bound and the best found solution is less than additive gap. When the gap is 0.0, the problem is solved optimaly. This parameter is used only when - the chosen algorithm is ``'cuts'`` or ``'cuts+'``. The parameter must be - ``\geq 1`` when used with ``'cuts+'``. + the chosen algorithm is ``'cuts'``. - ``verbose`` -- (default: ``False``) is a boolean set to True to display some information during execution: new upper and lower bounds, etc. @@ -1018,6 +999,8 @@ def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=N sage: G = graphs.PetersenGraph() sage: hyperbolicity(G,algorithm='cuts') (1/2, [0, 1, 2, 3], 1/2) + sage: hyperbolicity(G,algorithm='cuts+') + (1/2, [0, 1, 2, 3], 1/2) sage: hyperbolicity(G,algorithm='basic') (1/2, [0, 1, 2, 3], 1/2) sage: hyperbolicity(G,algorithm='basic+') @@ -1035,10 +1018,6 @@ def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=N (1, [(0, 0), (0, 9), (1, 0), (1, 9)], 4) sage: hyperbolicity(G,algorithm='cuts', additive_gap=2) (1, [(0, 0), (0, 9), (1, 0), (1, 9)], 3) - sage: hyperbolicity(G,algorithm='cuts+') - (1, [(0, 0), (0, 9), (1, 0), (1, 9)], 2) - sage: hyperbolicity(G,algorithm='cuts+', additive_gap=2) - (1, [(0, 0), (0, 9), (1, 0), (1, 9)], 3) sage: hyperbolicity(G,algorithm='dom') (1, [(0, 1), (0, 9), (1, 0), (1, 8)], 5) @@ -1052,7 +1031,7 @@ def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=N ... d2,_,_ = hyperbolicity(G,algorithm='cuts') ... d3,_,_ = hyperbolicity(G,algorithm='cuts+') ... l3,_,u3 = hyperbolicity(G,approximation_factor=2) - ... if d1!=d4 or d1!=d2 or d1d1 or u3d1 or u3= 0 when using the '%s' algorithm." %(algorithm)) - elif algorithm=='cuts+' and additive_gap < 1.0: - raise ValueError("The additive gap must be >= 1 when using the '%s' algorithm." %(algorithm)) else: print "The additive_gap is ignored when using the '%s' algorithm." %(algorithm) @@ -1145,7 +1122,9 @@ def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=N cdef unsigned short * _distances_ cdef unsigned short ** distances - cdef int i, j, k, N, hyp, hyp_UB, hh, hh_UB, D + cdef unsigned short * _far_apart_pairs_ + cdef unsigned short ** far_apart_pairs + cdef int i, j, N, hyp, hyp_UB, hh, hh_UB, D cdef dict distr = {} cdef list certificate = [] cdef list certif @@ -1175,8 +1154,8 @@ def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=N if len(V) > max( 3, 2*hyp) : # We build the subgraph and we relabel the vertices to ensure - # integer vertex names in the range [0..N-1] since the - # c_distances_all_pairs uses integer labels in the range [0..N-1]. + # integer vertex names in the range [0..N-1] since the distance + # computation methods use integer labels in the range [0..N-1]. H, mymap = _my_subgraph(G, V, relabel=True, return_map=True) N = H.num_verts() @@ -1187,11 +1166,31 @@ def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=N # We compute the distances and store the results in a 2D array, and # the diameter - _distances_ = c_distances_all_pairs(H) distances = sage_malloc(sizeof(unsigned short *)*N) if distances == NULL: sage_free(_distances_) - raise MemoryError + raise MemoryError("Unable to allocate array 'distances'.") + + if algorithm=='cuts+': + _distances_ = sage_malloc(N * N * sizeof(unsigned short)) + _far_apart_pairs_ = sage_malloc(N * N * sizeof(unsigned short)) + far_apart_pairs = sage_malloc(N * sizeof(unsigned short *)) + if _distances_ == NULL or _far_apart_pairs_ == NULL or far_apart_pairs == NULL: + sage_free(_distances_) + sage_free(distances) + sage_free(_far_apart_pairs_) + sage_free(far_apart_pairs) + raise MemoryError("Unable to allocate array '_distances_' or '_far_apart_pairs_'.") + + distances_and_far_apart_pairs(H, _distances_, _far_apart_pairs_) + + for 0 <= i < N: + far_apart_pairs[i] = _far_apart_pairs_ + i*N + + else: + _distances_ = c_distances_all_pairs(H) + _far_apart_pairs_ = NULL + far_apart_pairs = NULL D = 0 for 0 <= i < N: @@ -1200,33 +1199,40 @@ def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=N if distances[i][j] > D: D = distances[i][j] + # The hyperbolicity of a graph is upper bounded by diameter/2. + if D <= 2*hyp: + sage_free(_distances_) + sage_free(distances) + sage_free(_far_apart_pairs_) + sage_free(far_apart_pairs) + continue + # We call the cython function for computing the hyperbolicity with # the required parameters. - if algorithm == 'cuts': - hh, certif, hh_UB = __hyperbolicity__(N, distances, D, hyp, approximation_factor, 2*additive_gap, [], verbose) + if algorithm in ['cuts', 'cuts+']: + sig_on() + hh, certif, hh_UB = __hyperbolicity__(N, distances, far_apart_pairs, D, hyp, + approximation_factor, 2*additive_gap, verbose) + sig_off() hh_UB = min( hh_UB, D) - elif algorithm == 'cuts+': - # We compute the elimination ordering of simplicial vertices of H - elim = elimination_ordering_of_simplicial_vertices(H, max(2,floor(N**(1/2.0))), verbose) - if len(elim) > N-4: - # We know that this component has hyperbolicity <= 1 - certif = H.vertices()[:4] - hh = __hyp__(distances,certif[0],certif[1],certif[2],certif[3]) - hh_UB = 2 - else: - hh, certif, hh_UB = __hyperbolicity__(N, distances, D, hyp, 1.0, 2*additive_gap-2, elim, verbose) - hh_UB = min( hh_UB+2, D) - elif algorithm == 'dom': # Computes a dominating set DOM of H, and computes the # hyperbolicity considering only vertices in DOM DOM = _greedy_dominating_set(H, verbose=verbose) - elim = [u for u in H.vertex_iterator() if not u in DOM] # We need at least 4 vertices while len(DOM)<4: - DOM.append(elim.pop()) - hh, certif, hh_UB = __hyperbolicity__(N, distances, D, hyp, 1.0, 0.0, elim, verbose) + DOM.append(H.random_vertex()) + # We set null distances to vertices outside DOM. This way these + # vertices will not be considered anymore. + for i from 0 <= i < N: + if not i in DOM: + for j from 0 <= j < N: + distances[i][j] = 0 + distances[j][i] = 0 + sig_on() + hh, certif, hh_UB = __hyperbolicity__(N, distances, NULL, D, hyp, 1.0, 0.0, verbose) + sig_off() hh_UB = min( hh+8, D) elif algorithm in ['basic', 'basic+']: @@ -1250,6 +1256,8 @@ def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=N # We now release the memory sage_free(distances) sage_free(_distances_) + sage_free(_far_apart_pairs_) + sage_free(far_apart_pairs) # Last, we return the computed value and the certificate return ZZ(hyp)/2, sorted(certificate), ZZ(hyp_UB)/2 From 632bbb68bbd1e4e1a6b186b2f17197fe01c418aa Mon Sep 17 00:00:00 2001 From: David Coudert Date: Tue, 11 Nov 2014 18:02:42 +0100 Subject: [PATCH 148/698] trac #17227: remove methods that are no longer used --- src/sage/graphs/hyperbolicity.pyx | 42 ------------------------------- 1 file changed, 42 deletions(-) diff --git a/src/sage/graphs/hyperbolicity.pyx b/src/sage/graphs/hyperbolicity.pyx index 8be58e73d0e..940d2a79ce5 100644 --- a/src/sage/graphs/hyperbolicity.pyx +++ b/src/sage/graphs/hyperbolicity.pyx @@ -164,7 +164,6 @@ from sage.graphs.distances_all_pairs cimport c_distances_all_pairs from sage.rings.arith import binomial from sage.rings.integer_ring import ZZ from sage.rings.real_mpfr import RR -from sage.functions.other import floor from sage.misc.bitset import Bitset from libc.stdint cimport uint16_t, uint32_t, uint64_t, INT32_MAX include "sage/ext/stdsage.pxi" @@ -611,47 +610,6 @@ cdef inline distances_and_far_apart_pairs(gg, # Compute the hyperbolicity using a path decreasing length ordering ###################################################################### -cdef inline _invert_cells(pair * tab, uint32_t idxa, uint32_t idxb): - cdef pair tmp = tab[idxa] - tab[idxa] = tab[idxb] - tab[idxb] = tmp - - -cdef _order_pairs_according_elimination(elim, int N, pair *pairs, uint32_t nb_pairs, uint32_t *last_pair): - r""" - Re-order the pairs of vertices according the set of eliminated vertices. - - We put pairs of vertices with an extremity in ``elim`` at the end of the - array of pairs. We record the positions of the first pair of vertices in - ``elim``. If ``elim`` is empty, the ordering is unchanged and we set - ``last_pair=nb_pairs``. - """ - cdef uint32_t j, jmax - - jmax = nb_pairs-1 - if nb_pairs<=1 or not elim: - last_pair[0] = nb_pairs - else: - B = Bitset(iter(elim)) - j = 0 - while j0: - jmax -= 1 - - else: # This pair is at a correct position. - j += 1 - - # We record the position of the first pair of vertices in elim - last_pair[0] = jmax+1 - cdef tuple __hyperbolicity__(int N, unsigned short ** distances, unsigned short ** far_apart_pairs, From 329e8bfa63b0a95cdc7d226fc0a62b301629f1f0 Mon Sep 17 00:00:00 2001 From: David Coudert Date: Tue, 11 Nov 2014 18:13:08 +0100 Subject: [PATCH 149/698] trac #17227: remove other methods that are no longer used --- src/sage/graphs/hyperbolicity.pyx | 106 +----------------------------- 1 file changed, 2 insertions(+), 104 deletions(-) diff --git a/src/sage/graphs/hyperbolicity.pyx b/src/sage/graphs/hyperbolicity.pyx index 940d2a79ce5..ceb5acaaf70 100644 --- a/src/sage/graphs/hyperbolicity.pyx +++ b/src/sage/graphs/hyperbolicity.pyx @@ -145,6 +145,7 @@ AUTHORS: - David Coudert (2012): initial version, exact and approximate algorithm, distribution, sampling +- David Coudert (2014): improved exact algorithm using far-apart pairs Methods @@ -165,7 +166,7 @@ from sage.rings.arith import binomial from sage.rings.integer_ring import ZZ from sage.rings.real_mpfr import RR from sage.misc.bitset import Bitset -from libc.stdint cimport uint16_t, uint32_t, uint64_t, INT32_MAX +from libc.stdint cimport uint16_t, uint32_t, uint64_t include "sage/ext/stdsage.pxi" include "sage/ext/stdsage.pxi" include "sage/misc/bitset.pxi" @@ -354,109 +355,6 @@ cdef tuple __hyperbolicity_basic_algorithm__(int N, return ( -1, [] ) -###################################################################### -# Decomposition methods -###################################################################### - -def elimination_ordering_of_simplicial_vertices(G, max_degree=4, verbose=False): - r""" - Return an elimination ordering of simplicial vertices. - - An elimination ordering of simplicial vertices is an elimination ordering of - the vertices of the graphs such that the induced subgraph of their neighbors - is a clique. More precisely, as long as the graph has a vertex ``u`` such - that the induced subgraph of its neighbors is a clique, we remove ``u`` from - the graph, add it to the elimination ordering (list of vertices), and - repeat. This method is inspired from the decomposition of a graph by - clique-separators. - - INPUTS: - - - ``G`` -- a Graph - - - ``max_degree`` -- (default: 4) maximum degree of the vertices to consider. - The running time of this method depends on the value of this parameter. - - - ``verbose`` -- (default: ``False``) is boolean set to ``True`` to display - some information during execution. - - OUTPUT: - - - ``elim`` -- A ordered list of vertices such that vertex ``elim[i]`` is - removed before vertex ``elim[i+1]``. - - TESTS: - - Giving anything else than a Graph:: - - sage: from sage.graphs.hyperbolicity import elimination_ordering_of_simplicial_vertices - sage: elimination_ordering_of_simplicial_vertices([]) - Traceback (most recent call last): - ... - ValueError: The input parameter must be a Graph. - - Giving two small bounds on degree:: - - sage: from sage.graphs.hyperbolicity import elimination_ordering_of_simplicial_vertices - sage: elimination_ordering_of_simplicial_vertices(Graph(), max_degree=0) - Traceback (most recent call last): - ... - ValueError: The parameter max_degree must be > 0. - - Giving a graph built from a bipartite graph plus an edge:: - - sage: G = graphs.CompleteBipartiteGraph(2,10) - sage: G.add_edge(0,1) - sage: from sage.graphs.hyperbolicity import elimination_ordering_of_simplicial_vertices - sage: elimination_ordering_of_simplicial_vertices(G) - [2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 11] - sage: elimination_ordering_of_simplicial_vertices(G,max_degree=1) - [] - """ - if verbose: - print 'Entering elimination_ordering_of_simplicial_vertices' - - if not isinstance(G,Graph): - raise ValueError("The input parameter must be a Graph.") - elif max_degree < 1: - raise ValueError("The parameter max_degree must be > 0.") - - # We make a copy of the graph. We use a NetworkX graph since modifications - # are a bit faster this way. - import networkx - ggnx = networkx.empty_graph() - for u,v in G.edge_iterator(labels=None): - ggnx.add_edge(u,v) - - from sage.combinat.combination import Combinations - cdef list elim = [] - cdef set L = set() - - # We identify vertices of degree at most max_degree - for u,d in ggnx.degree_iter(): - if d<=max_degree: - L.add(u) - - while L: - # We pick up a vertex and check if the induced subgraph of its neighbors - # is a clique. If True, we record it, remove it from the graph, and - # update the list of vertices of degree at most max_degree. - u = L.pop() - X = ggnx.neighbors(u) - if all(ggnx.has_edge(v,w) for v,w in Combinations(X,2).list()): - elim.append(u) - ggnx.remove_node(u) - for v,d in ggnx.degree_iter(X): - if d<=max_degree: - L.add(v) - - if verbose: - print 'Propose to eliminate',len(elim),'of the',G.num_verts(),'vertices' - print 'End elimination_ordering_of_simplicial_vertices' - - return elim - - ###################################################################### # Greedy dominating set ###################################################################### From 5529a33923e3c8c45c0ef28d4b5fac2783050561 Mon Sep 17 00:00:00 2001 From: David Coudert Date: Tue, 11 Nov 2014 18:46:27 +0100 Subject: [PATCH 150/698] trac #17227: fix various indentation errors and small bugs --- src/sage/graphs/hyperbolicity.pyx | 100 ++++++++++++++++-------------- 1 file changed, 52 insertions(+), 48 deletions(-) diff --git a/src/sage/graphs/hyperbolicity.pyx b/src/sage/graphs/hyperbolicity.pyx index ceb5acaaf70..2fd613c1f75 100644 --- a/src/sage/graphs/hyperbolicity.pyx +++ b/src/sage/graphs/hyperbolicity.pyx @@ -167,7 +167,7 @@ from sage.rings.integer_ring import ZZ from sage.rings.real_mpfr import RR from sage.misc.bitset import Bitset from libc.stdint cimport uint16_t, uint32_t, uint64_t -include "sage/ext/stdsage.pxi" +include "sage/ext/interrupt.pxi" include "sage/ext/stdsage.pxi" include "sage/misc/bitset.pxi" @@ -269,8 +269,8 @@ cdef inline int __hyp__(unsigned short ** distances, int a, int b, int c, int d) cdef tuple __hyperbolicity_basic_algorithm__(int N, unsigned short ** distances, - use_bounds = True, - verbose = False): + use_bounds, + verbose): """ Returns **twice** the hyperbolicity of a graph, and a certificate. @@ -646,8 +646,12 @@ cdef tuple __hyperbolicity__(int N, if verbose: print "Current 2 connected component has %d vertices and diameter %d" %(N,D) - print "Number of (far-apart) pairs: %d\t(%d pairs in total)" %(nb_p, binomial(N, 2)) - print "Repartition of (far-apart) pairs:", [ (i, nb_pairs_of_length[i]) for i in range(1, D+1) if nb_pairs_of_length[i]>0] + if far_apart_pairs == NULL: + print "Number of pairs: %d" %(nb_p) + print "Repartition of pairs:", [ (i, nb_pairs_of_length[i]) for i in range(1, D+1) if nb_pairs_of_length[i]>0] + else: + print "Number of far-apart pairs: %d\t(%d pairs in total)" %(nb_p, binomial(N, 2)) + print "Repartition of far-apart pairs:", [ (i, nb_pairs_of_length[i]) for i in range(1, D+1) if nb_pairs_of_length[i]>0] approximation_factor = min(approximation_factor, D) @@ -697,7 +701,7 @@ cdef tuple __hyperbolicity__(int N, pairs_of_length_l1 = pairs_of_length[l1] pairs_of_length_l2 = pairs_of_length[l2] - nb_pairs_of_length_l1 = last_pair[l1] + nb_pairs_of_length_l1 = nb_pairs_of_length[l1] nb_pairs_of_length_l2 = nb_pairs_of_length[l2] for x from 0 <= x < nb_pairs_of_length_l1: @@ -706,46 +710,46 @@ cdef tuple __hyperbolicity__(int N, dist_a = distances[a] dist_b = distances[b] - # We do not want to test pairs of pairs twice if l1 == l2 - for y from (x+1 if l1==l2 else 0) <= y < nb_pairs_of_length_l2: - c = pairs_of_length_l2[y].s - d = pairs_of_length_l2[y].t - - # We compute the hyperbolicity of the 4-tuple. We have S1 = l1 - # + l2, and the order in which pairs are visited allow us to - # claim that S1 = max( S1, S2, S3 ). If at some point S1 is not - # the maximum value, the order ensures that the maximum value - # has previously been checked. - S2 = dist_a[c] + dist_b[d] - S3 = dist_a[d] + dist_b[c] - if S2 > S3: - hh = S1 - S2 - else: - hh = S1 - S3 - - if h < hh or not certificate: - # We update current bound on the hyperbolicity and the - # search space, unless hh==0 and two vertices are equal. - if h>0 or not (a==c or a==d or b==c or b==d): - h = hh - certificate = [a, b, c, d] - - if verbose: - print "New lower bound:",ZZ(hh)/2 - - # If we cannot improve further, we stop - if l2 <= h: - STOP = 1 - h_UB = h - break - - # Termination if required approximation is found - if (h_UB <= h*approximation_factor) or (h_UB-h <= additive_gap): - STOP = 2 - break - - if STOP: - break + # We do not want to test pairs of pairs twice if l1 == l2 + for y from (x+1 if l1==l2 else 0) <= y < nb_pairs_of_length_l2: + c = pairs_of_length_l2[y].s + d = pairs_of_length_l2[y].t + + # We compute the hyperbolicity of the 4-tuple. We have S1 = l1 + + # l2, and the order in which pairs are visited allow us to claim + # that S1 = max( S1, S2, S3 ). If at some point S1 is not the + # maximum value, the order ensures that the maximum value has + # previously been checked. + S2 = dist_a[c] + dist_b[d] + S3 = dist_a[d] + dist_b[c] + if S2 > S3: + hh = S1 - S2 + else: + hh = S1 - S3 + + if h < hh or not certificate: + # We update current bound on the hyperbolicity and the + # search space, unless hh==0 and two vertices are equal. + if h>0 or not (a==c or a==d or b==c or b==d): + h = hh + certificate = [a, b, c, d] + + if verbose: + print "New lower bound:",ZZ(hh)/2 + + # If we cannot improve further, we stop + if l2 <= h: + STOP = 1 + h_UB = h + break + + # Termination if required approximation is found + if (h_UB <= h*approximation_factor) or (h_UB-h <= additive_gap): + STOP = 2 + break + + if STOP: + break if STOP: break @@ -761,7 +765,7 @@ cdef tuple __hyperbolicity__(int N, return ( -1, [], h_UB ) else: # When using far-apart pairs, the loops may end - return (h, certificate, h_UB if STOP==2 else h) + return (h, certificate, h_UB if STOP==2 else h) def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=None, verbose = False): @@ -1093,7 +1097,7 @@ def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=N elif algorithm in ['basic', 'basic+']: sig_on() - hh, certif = __hyperbolicity_basic_algorithm__(N, distances, use_bounds=algorithm=='basic+', verbose) + hh, certif = __hyperbolicity_basic_algorithm__(N, distances, algorithm=='basic+', verbose) sig_off() hh_UB = hh From f64e556c31802d06134265b225cc3f6cb715bf28 Mon Sep 17 00:00:00 2001 From: Joao de Faria Date: Wed, 12 Nov 2014 13:14:14 -0500 Subject: [PATCH 151/698] Deleted lines used for testing --- src/sage/schemes/projective/projective_morphism.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 9c122c700cf..984e6a0aec4 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -1688,18 +1688,13 @@ def height_difference_bound(self, prec=None): Res = lcm(Res, abs(CoeffPolys[j].coefficients()[i].denominator())) h = max([c.global_height() for g in CoeffPolys for c in (Res*g).coefficients()]) MCP.append([Res, h]) #since we need to clear denominators - print MCP maxh = 0 gcdRes = 0 for k in range(len(MCP)): gcdRes = gcd(gcdRes, MCP[k][0]) maxh = max(maxh, MCP[k][1]) - print maxh - print R(gcdRes).log() - print R((N + 1) * binomial(N + D - d, D - d)).log() L = abs( R(gcdRes).log() - R((N + 1) * binomial(N + D - d, D - d)).log() - maxh) C = max(U, L) #height difference dh(P) - L <= h(f(P)) <= dh(P) +U - print U,L return(C / (d - 1)) def multiplier(self, P, n, check=True): From 260d72770646ca316f4cef378179cb2a2256837b Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Mon, 17 Nov 2014 13:58:38 +0000 Subject: [PATCH 152/698] Document patches in the patch file --- src/doc/en/developer/packaging.rst | 38 +++++++++++++------- src/doc/en/developer/packaging_old_spkgs.rst | 10 +++--- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/doc/en/developer/packaging.rst b/src/doc/en/developer/packaging.rst index 6abadf6e866..f78420e30c1 100644 --- a/src/doc/en/developer/packaging.rst +++ b/src/doc/en/developer/packaging.rst @@ -204,9 +204,8 @@ The ``SPKG.txt`` file should follow this pattern:: == Special Update/Build Instructions == - List patches that need to be applied and what they do. If the - tarball was modified by hand and not via a spkg-src script, - describe what was changed. + If the tarball was modified by hand and not via a spkg-src + script, describe what was changed. with ``PACKAGE_NAME`` replaced by the the package name. Legacy @@ -220,10 +219,29 @@ Patching Sources ---------------- Actual changes to the source code must be via patches, which should be -placed in the ``patches`` directory. GNU patch is distributed with Sage, -so you can rely on it being available. All patches must be documented in -``SPKG.txt``, i.e. what they do, if they are platform specific, if they -should be pushed upstream, etc. +placed in the ``patches`` directory. GNU patch is distributed with +Sage, so you can rely on it being available. Patches must include +documentation in their header (before the first diff hunk), so a +typical patch file should look like this:: + + Add autodoc_builtin_argspec config option + + Following the title line you can add a multi-line description of + what the patch does, where you got it from if you did not write it + yourself, if they are platform specific, if they should be pushed + upstream, etc... + + diff -dru Sphinx-1.2.2/sphinx/ext/autodoc.py.orig Sphinx-1.2.2/sphinx/ext/autodoc.py + --- Sphinx-1.2.2/sphinx/ext/autodoc.py.orig 2014-03-02 20:38:09.000000000 +1300 + +++ Sphinx-1.2.2/sphinx/ext/autodoc.py 2014-10-19 23:02:09.000000000 +1300 + @@ -1452,6 +1462,7 @@ + + app.add_config_value('autoclass_content', 'class', True) + app.add_config_value('autodoc_member_order', 'alphabetic', True) + + app.add_config_value('autodoc_builtin_argspec', None, True) + app.add_config_value('autodoc_default_flags', [], True) + app.add_config_value('autodoc_docstring_signature', True, True) + app.add_event('autodoc-process-docstring') Patches to files in ``src/`` need to be applied in ``spkg-install``, that is, if there are any patches then your ``spkg-install`` script @@ -240,12 +258,6 @@ should contain a section like this:: which applies the patches to the sources. -A special case where no patch would be necessary is when an author -provides an already fine SPKG on the net which includes all files needed -for ``SAGE_ROOT/build/pkgs/foo`` and the source in its ``src/`` -subdirectory. Here it suffices to put the web link to the package into -the ticket. - .. _section-spkg-src: diff --git a/src/doc/en/developer/packaging_old_spkgs.rst b/src/doc/en/developer/packaging_old_spkgs.rst index 0ec2361633d..bcc07d37b27 100644 --- a/src/doc/en/developer/packaging_old_spkgs.rst +++ b/src/doc/en/developer/packaging_old_spkgs.rst @@ -124,11 +124,11 @@ More precisely, the directory should contain the following: - ``patches/``: this directory contains patches to source files in ``src/``. See :ref:`section-old-spkg-patching-overview`. Patches to files in ``src/`` should be applied in ``spkg-install``, and all - patches must be documented in ``SPKG.txt``, i.e. what they do, if - they are platform specific, if they should be pushed upstream, - etc. To ensure that all patched versions of upstream source files - under ``src/`` are under revision control, the whole directory - ``patches/`` must be under revision control. + patches must be self-documenting, i.e. the header must contain what + they do, if they are platform specific, if they should be pushed + upstream, etc. To ensure that all patched versions of upstream + source files under ``src/`` are under revision control, the whole + directory ``patches/`` must be under revision control. **Never** apply patches to upstream source files under ``src/`` and then package up an spkg. Such a mixture of upstream source with Sage From 577b688a805235e5c89b13db8e94d6e642dbb675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jori=20M=C3=A4ntysalo?= Date: Tue, 18 Nov 2014 15:56:40 +0200 Subject: [PATCH 153/698] Make relabeling a lattice to return lattice, not poset. --- src/sage/combinat/posets/posets.py | 32 +++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index b1feb7296c4..febfe6edbe7 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -3314,6 +3314,12 @@ def relabel(self, relabeling): sage: Q.cover_relations() [[12, 6], [12, 4], [6, 3], [6, 2], [4, 2], [3, 1], [2, 1]] + Relabeling a (semi)lattice gives a (semi)lattice: + + sage: P=JoinSemilattice({0:[1]}) + sage: type(P.relabel(lambda n: n+1)) + + .. NOTE:: As can be seen in the above examples, the default linear @@ -3342,6 +3348,9 @@ def relabel(self, relabeling): sage: p1 == p3 True """ + from sage.combinat.posets.lattices import LatticePoset, \ + JoinSemilattice, MeetSemilattice, FiniteLatticePoset, \ + FiniteMeetSemilattice, FiniteJoinSemilattice if isinstance(relabeling, (list, tuple)): relabeling = {i:relabeling[i] for i in range(len(self._elements))} else: @@ -3353,9 +3362,26 @@ def relabel(self, relabeling): else: elements = tuple(relabeling[self._element_to_vertex(x)] for x in self._elements) - return FinitePoset(self._hasse_diagram.relabel(relabeling, inplace=False), - elements=elements, - category=self.category(), + + + if isinstance(self, FiniteLatticePoset): + return FiniteLatticePoset(self._hasse_diagram.relabel(relabeling, + inplace=False), + elements=elements, category=self.category(), + facade=self._is_facade) + if isinstance(self, FiniteMeetSemilattice): + return FiniteMeetSemilattice(self._hasse_diagram.relabel(relabeling, + inplace=False), + elements=elements, category=self.category(), + facade=self._is_facade) + if isinstance(self, FiniteJoinSemilattice): + return FiniteJoinSemilattice(self._hasse_diagram.relabel(relabeling, + inplace=False), + elements=elements, category=self.category(), + facade=self._is_facade) + return FinitePoset(self._hasse_diagram.relabel(relabeling, + inplace=False), + elements=elements, category=self.category(), facade=self._is_facade) def canonical_label(self): From 0925390c0d1eacabd75bb24c815d30124c8e8a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Tue, 18 Nov 2014 16:44:23 +0100 Subject: [PATCH 154/698] 17364: All homsets category should be subcategories of the category of all homsets --- src/sage/categories/additive_magmas.py | 4 +- src/sage/categories/hecke_modules.py | 13 +- src/sage/categories/homsets.py | 188 ++++++++++++------------- src/sage/categories/schemes.py | 22 +-- 4 files changed, 105 insertions(+), 122 deletions(-) diff --git a/src/sage/categories/additive_magmas.py b/src/sage/categories/additive_magmas.py index 1ae0cebf9cc..d53224417cf 100644 --- a/src/sage/categories/additive_magmas.py +++ b/src/sage/categories/additive_magmas.py @@ -489,7 +489,7 @@ def extra_super_categories(self): sage: AdditiveMagmas().Homsets().extra_super_categories() [Category of additive magmas] sage: AdditiveMagmas().Homsets().super_categories() - [Category of additive magmas] + [Category of additive magmas, Category of homsets] """ return [AdditiveMagmas()] @@ -864,7 +864,7 @@ def extra_super_categories(self): sage: AdditiveMagmas().AdditiveUnital().Homsets().extra_super_categories() [Category of additive unital additive magmas] sage: AdditiveMagmas().AdditiveUnital().Homsets().super_categories() - [Category of additive unital additive magmas] + [Category of additive unital additive magmas, Category of homsets] """ return [AdditiveMagmas().AdditiveUnital()] diff --git a/src/sage/categories/hecke_modules.py b/src/sage/categories/hecke_modules.py index 2f1cb3a29d1..a1c12a3f02b 100644 --- a/src/sage/categories/hecke_modules.py +++ b/src/sage/categories/hecke_modules.py @@ -151,15 +151,14 @@ def _Hom_(self, Y, category): return HeckeModuleHomspace(self, Y, category = category) class Homsets(HomsetsCategory): - def extra_super_categories_disabled(self): - """ - EXAMPLES:: + """ + .. TODO:: shall there be any additional category structure on Homsets of hecke modules? - sage: HeckeModules(ZZ).Homsets().extra_super_categories() - [Category of homsets] - """ - return [] # FIXME: what category structure is there on Homsets of hecke modules? + TESTS:: + sage: HeckeModules(ZZ).Homsets().super_categories() + [Category of homsets] + """ def base_ring(self): """ diff --git a/src/sage/categories/homsets.py b/src/sage/categories/homsets.py index c9eaa79a8c1..7306aa6e94a 100644 --- a/src/sage/categories/homsets.py +++ b/src/sage/categories/homsets.py @@ -23,126 +23,87 @@ class HomsetsCategory(FunctorialConstructionCategory): _functor_category = "Homsets" @classmethod - @cached_function - def category_of(cls, category, *args): + def default_super_categories(cls, category): """ - Return the homsets category of ``category``. - - This classmethod centralizes the construction of all homset - categories. - - The ``cls`` and ``args`` arguments below are essentially - unused. Their purpose is solely to let the code deviate as - little as possible from the generic implementation of this - method: :meth:`FunctorialConstructionCategory.category_of`. - The reason for this deviation is that, unlike in the other - functorial constructions which are covariant, we recurse only - on *full* supercategories; then, we need a special treatment - for the base case were a category neither defines the - ``Homsets`` construction, nor inherits it from its full - supercategories. + Return the default super categories of ``category.Homsets()``. INPUT: - - ``cls`` -- :class:`HomsetsCategory` or a subclass thereof + - ``cls`` -- the category class for the functor `F` - ``category`` -- a category `Cat` - - ``*args`` -- (unused) + + OUTPUT: a category + + As for the other functorial constructions, if ``category`` + implements a nested ``Homsets`` class, this method is used in + combination with ``category.Homsets().extra_super_categories()`` + to compute the super categories of ``category.Homsets()``. EXAMPLES: - If ``category`` implements a ``Homsets`` class, then this - class is used to build the homset category:: + If ``category`` has one or more full super categories, then + the join of their respective homsets category is returned. In + this example, this join consists of a single category:: sage: from sage.categories.homsets import HomsetsCategory - sage: H = HomsetsCategory.category_of(Modules(ZZ)); H - Category of homsets of modules over Integer Ring - sage: type(H) - - - Otherwise, if ``category`` has one or more full super - categories, then the join of their respective homsets category - is returned. In this example, the join consists of a single - category:: + sage: from sage.categories.additive_groups import AdditiveGroups - sage: C = Modules(ZZ).WithBasis().FiniteDimensional() + sage: C = AdditiveGroups() sage: C.full_super_categories() - [Category of modules with basis over Integer Ring, - Category of finite dimensional modules over Integer Ring] - sage: H = HomsetsCategory.category_of(C); H - Category of homsets of modules with basis over Integer Ring + [Category of additive inverse additive unital additive magmas, + Category of additive monoids] + sage: H = HomsetsCategory.default_super_categories(C); H + Category of homsets of additive monoids sage: type(H) - - - As a last resort, a :class:`HomsetsOf` of the categories - forming the structure of ``self`` is constructed:: + - sage: H = HomsetsCategory.category_of(Magmas()); H - Category of homsets of magmas - sage: type(H) - + and, given that nothing specific is currently implemented for + homsets of additive groups, ``H`` is directly the category + thereof:: - sage: HomsetsCategory.category_of(Rings()) - Category of homsets of unital magmas and additive unital additive magmas - """ - functor_category = getattr(category.__class__, cls._functor_category) - if isinstance(functor_category, type) and issubclass(functor_category, Category): - return functor_category(category, *args) - elif category.full_super_categories(): - return cls.default_super_categories(category, *args) - else: - return HomsetsOf(Category.join(category.structure())) - - @classmethod - def default_super_categories(cls, category): - """ - Return the default super categories of ``category.Homsets()`` - - INPUT: - - - ``cls`` -- the category class for the functor `F` - - ``category`` -- a category `Cat` + sage: C.Homsets() + Category of homsets of additive monoids - OUTPUT: a category + Similarly for rings: a ring homset is just a homset of unital + magmas and additive magmas:: - .. TODO:: adapt everything below + sage: Rings().Homsets() + Category of homsets of unital magmas and additive unital additive magmas - The default implementation is to return the join of the - categories of `F(A,B,...)` for `A,B,...` in turn in each of - the super categories of ``category``. + Otherwise, if ``category`` implements a nested class + ``Homsets``, this method returns the category of all homsets:: - This is implemented as a class method, in order to be able to - reconstruct the functorial category associated to each of the - super categories of ``category``. + sage: AdditiveMagmas.Homsets + + sage: HomsetsCategory.default_super_categories(AdditiveMagmas()) + Category of homsets - EXAMPLES:: + which gives one of the super categories of + ``category.Homsets()``:: sage: AdditiveMagmas().Homsets().super_categories() - [Category of additive magmas] + [Category of additive magmas, Category of homsets] sage: AdditiveMagmas().AdditiveUnital().Homsets().super_categories() - [Category of additive unital additive magmas] - - For now nothing specific is implemented for homsets of - additive groups compared to homsets of monoids:: - - sage: from sage.categories.additive_groups import AdditiveGroups - sage: AdditiveGroups().Homsets() - Category of homsets of additive monoids + [Category of additive unital additive magmas, Category of homsets] - Similarly for rings; so a ring homset is a homset of unital - magmas and additive magmas:: + the other coming from ``category.Homsets().extra_super_categories()``:: - sage: Rings().Homsets() - Category of homsets of unital magmas and additive unital additive magmas - """ - return Category.join([getattr(cat, cls._functor_category)() - for cat in category.full_super_categories()]) + sage: AdditiveMagmas().Homsets().extra_super_categories() + [Category of additive magmas] + Finally, as a last resort, this method returns a stub category + modelling the homsets of this category:: - def extra_super_categories(self): - """ - Return the extra super categories of ``self``. + sage: hasattr(Posets, "Homsets") + False + sage: H = HomsetsCategory.default_super_categories(Posets()); H + Category of homsets of posets + sage: type(H) + + sage: Posets().Homsets() + Category of homsets of posets - EXAMPLES:: + TESTS:: sage: Objects().Homsets().super_categories() [Category of homsets] @@ -151,8 +112,15 @@ def extra_super_categories(self): sage: (Magmas() & Posets()).Homsets().super_categories() [Category of homsets] """ - return [Homsets()] - + if category.full_super_categories(): + return Category.join([getattr(cat, cls._functor_category)() + for cat in category.full_super_categories()]) + else: + functor_category = getattr(category.__class__, cls._functor_category) + if isinstance(functor_category, type) and issubclass(functor_category, Category): + return Homsets() + else: + return HomsetsOf(Category.join(category.structure())) def _test_homsets_category(self, **options): r""" @@ -169,6 +137,7 @@ def _test_homsets_category(self, **options): #from sage.categories.sets_cat import Sets tester = self._tester(**options) tester.assert_(self.is_subcategory(Category.join(self.base_category().structure()).Homsets())) + tester.assert_(self.is_subcategory(Homsets())) @cached_method def base(self): @@ -233,6 +202,24 @@ def _repr_object_names(self): object_names = ' and '.join(cat._repr_object_names() for cat in base_category.super_categories()) return "homsets of %s"%(object_names) + def super_categories(self): + r""" + Return the super categories of ``self``. + + A stub homset category admits a single super category, namely + the category of all homsets. + + EXAMPLES: + + sage: C = (Magmas() & Posets()).Homsets(); C + Category of homsets of magmas and posets + sage: type(C) + + sage: C.super_categories() + [Category of homsets] + """ + return [Homsets()] + class Homsets(Category_singleton): """ The category of all homsets. @@ -252,10 +239,17 @@ class Homsets(Category_singleton): or equivalently that we only implement locally small categories. See :wikipedia:`Category_(mathematics)`. - .. TODO:: + :trac:`17364`: every homset category shall be a subcategory of the + category of all homsets: + + sage: Schemes().Homsets().is_subcategory(Homsets()) + True + sage: AdditiveMagmas().Homsets().is_subcategory(Homsets()) + True + sage: AdditiveMagmas().AdditiveUnital().Homsets().is_subcategory(Homsets()) + True - We would want a more general mechanism. See also - :meth:`Monoids.Homsets.extra_super_categories`. + This is tested in :meth:`HomsetsCategory._test_homsets_category`. """ def super_categories(self): """ diff --git a/src/sage/categories/schemes.py b/src/sage/categories/schemes.py index 8e4658c586a..dd5ace46f21 100644 --- a/src/sage/categories/schemes.py +++ b/src/sage/categories/schemes.py @@ -146,24 +146,14 @@ def _call_(self, x): class Homsets(HomsetsCategory): - def extra_super_categories(self): - """ - EXAMPLES:: - - sage: Schemes().Homsets().extra_super_categories() - [] - sage: Schemes().Homsets().super_categories() - [Category of objects] - - .. TODO:: - - What category structure is there on Homsets of schemes? - - .. TODO:: check that the result above is correct now - """ - return [] + """ + TESTS:: + sage: Schemes().Homsets().super_categories() + [Category of homsets] + .. TODO:: shall there be any additional category structure on Homsets of hecke modules? + """ ############################################################# # Schemes over a given base scheme. From 528e722ad865b8ab81a878cfb78d6f542f890cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jori=20M=C3=A4ntysalo?= Date: Wed, 19 Nov 2014 10:55:03 +0200 Subject: [PATCH 155/698] Shortened code. --- src/sage/combinat/posets/posets.py | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index febfe6edbe7..7a0ed23440d 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -3363,23 +3363,15 @@ def relabel(self, relabeling): elements = tuple(relabeling[self._element_to_vertex(x)] for x in self._elements) - if isinstance(self, FiniteLatticePoset): - return FiniteLatticePoset(self._hasse_diagram.relabel(relabeling, - inplace=False), - elements=elements, category=self.category(), - facade=self._is_facade) - if isinstance(self, FiniteMeetSemilattice): - return FiniteMeetSemilattice(self._hasse_diagram.relabel(relabeling, - inplace=False), - elements=elements, category=self.category(), - facade=self._is_facade) - if isinstance(self, FiniteJoinSemilattice): - return FiniteJoinSemilattice(self._hasse_diagram.relabel(relabeling, - inplace=False), - elements=elements, category=self.category(), - facade=self._is_facade) - return FinitePoset(self._hasse_diagram.relabel(relabeling, + constructor = FiniteLatticePoset + elif isinstance(self, FiniteMeetSemilattice): + constructor = FiniteMeetSemilattice + elif isinstance(self, FiniteJoinSemilattice): + constructor = FiniteJoinSemilattice + else: + constructor = FinitePoset + return constructor(self._hasse_diagram.relabel(relabeling, inplace=False), elements=elements, category=self.category(), facade=self._is_facade) From 9b7b8be3be9763f7330b8d1e787145124f351e76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jori=20M=C3=A4ntysalo?= Date: Wed, 19 Nov 2014 13:49:44 +0200 Subject: [PATCH 156/698] Product of lattices changed to lattice from poset. --- src/sage/combinat/posets/posets.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 7a0ed23440d..8f59a7ec67b 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -3065,7 +3065,21 @@ def product(self,other): sage: Q.is_isomorphic(Posets.BooleanLattice(4)) True """ - return Poset(self.hasse_diagram().cartesian_product(other.hasse_diagram()),cover_relations=True) + from sage.combinat.posets.lattices import LatticePoset, \ + JoinSemilattice, MeetSemilattice, FiniteLatticePoset, \ + FiniteMeetSemilattice, FiniteJoinSemilattice + if ( isinstance(self, FiniteLatticePoset) and + isinstance(other, FiniteLatticePoset) ): + constructor = FiniteLatticePoset + elif ( isinstance(self, FiniteMeetSemilattice) and + isinstance(other, FiniteMeetSemilattice) ): + constructor = FiniteMeetSemilattice + elif ( isinstance(self, FiniteJoinSemilattice) and + isinstance(other, FiniteJoinSemilattice) ): + constructor = FiniteJoinSemilattice + else: + constructor = FinitePoset + return constructor(self.hasse_diagram().cartesian_product(other.hasse_diagram())) def disjoint_union(self, other, labels='pairs'): """ From e0f676413fb2a7709514dfa67e851eaccb04e4a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jori=20M=C3=A4ntysalo?= Date: Wed, 19 Nov 2014 13:57:00 +0200 Subject: [PATCH 157/698] Correction for docstring. --- src/sage/combinat/posets/posets.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 8f59a7ec67b..522c381a923 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -3047,14 +3047,14 @@ def f(chain): def product(self,other): """ - Returns the cartesian product of ``self`` and ``other``. + Return the cartesian product of ``self`` and ``other``. EXAMPLES:: sage: P = Posets.ChainPoset(3) sage: Q = Posets.ChainPoset(4) sage: PQ = P.product(Q) ; PQ - Finite poset containing 12 elements + Finite lattice containing 12 elements sage: len(PQ.hasse_diagram().edges()) 17 sage: Q.product(P).is_isomorphic(PQ) From 4a9454f56d04c84824cd45a919c7dcbadcf95142 Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Wed, 19 Nov 2014 19:25:27 +0100 Subject: [PATCH 158/698] trac #17142: Broken doctest --- src/sage/categories/finite_posets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/categories/finite_posets.py b/src/sage/categories/finite_posets.py index a875242c8b4..81d2f0a2e43 100644 --- a/src/sage/categories/finite_posets.py +++ b/src/sage/categories/finite_posets.py @@ -673,7 +673,7 @@ def birational_free_labelling(self, linear_extension=None, sage: P = Posets.ChainPoset(2).product(Posets.ChainPoset(3)) sage: P - Finite poset containing 6 elements + Finite lattice containing 6 elements sage: lex = [(1,0),(0,0),(1,1),(0,1),(1,2),(0,2)] sage: l = P.birational_free_labelling(linear_extension=lex, ....: prefix="u", reduced=True) From 2144c6538f8b2f63b90f94277d25da37769fcfa8 Mon Sep 17 00:00:00 2001 From: Thierry Monteil Date: Thu, 20 Nov 2014 00:48:05 +0100 Subject: [PATCH 159/698] #17368 make pip standard and let it depend on python --- build/deps | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/deps b/build/deps index 1d813da63bb..dbb75764e86 100644 --- a/build/deps +++ b/build/deps @@ -79,6 +79,7 @@ all-sage: \ $(INST)/$(PARI) \ $(INST)/$(PEXPECT) \ $(INST)/$(PILLOW) \ + $(INST)/$(PIP) \ $(INST)/$(PKGCONF) \ $(INST)/$(PKGCONFIG) \ $(INST)/$(POLYBORI) \ @@ -243,6 +244,9 @@ $(INST)/$(PARI_GALDATA): $(INST)/$(PARI_SEADATA_SMALL): +$(PIPE) "$(SAGE_SPKG) $(PARI_SEADATA_SMALL) 2>&1" "tee -a $(SAGE_LOGS)/$(PARI_SEADATA_SMALL).log" +$(INST)/$(PIP): $(INST)/$(PYTHON) + +$(PIPE) "$(SAGE_SPKG) $(PIP) 2>&1" "tee -a $(SAGE_LOGS)/$(PIP).log" + $(INST)/$(POLYBORI): $(INST)/$(PYTHON) $(INST)/$(IPYTHON) \ $(INST)/$(SCONS) $(INST)/$(BOOST_CROPPED) \ $(INST)/$(M4RI) $(INST)/$(GD) From 0b0f0785e23437afa504bd537fb69df974a7c8c5 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Thu, 20 Nov 2014 03:19:33 -0800 Subject: [PATCH 160/698] Let ATLAS use Cygwin thread functions on Cygwin64. --- build/pkgs/atlas/patches/cygwin_threads.patch | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 build/pkgs/atlas/patches/cygwin_threads.patch diff --git a/build/pkgs/atlas/patches/cygwin_threads.patch b/build/pkgs/atlas/patches/cygwin_threads.patch new file mode 100644 index 00000000000..5f56db51160 --- /dev/null +++ b/build/pkgs/atlas/patches/cygwin_threads.patch @@ -0,0 +1,30 @@ +Let ATLAS use Cygwin thread functions on Cygwin64. +diff -druN ATLAS.orig/src/threads/ATL_thread_start.c ATLAS.new/src/threads/ATL_thread_start.c +--- ATLAS.orig/src/threads/ATL_thread_start.c 2014-07-10 09:22:06.000000000 -0700 ++++ ATLAS.new/src/threads/ATL_thread_start.c 2014-11-18 07:17:39.207997205 -0800 +@@ -14,14 +14,14 @@ + */ + { + #ifdef ATL_WINTHREADS +- #ifdef ATL_WIN32THREADS ++ #if defined(ATL_WIN32THREADS) || defined(__CYGWIN__) + DWORD thrID; + #else + unsigned thrID; + #endif + + #ifdef ATL_NOAFFINITY +- #ifdef ATL_WIN32THREADS ++ #if defined(ATL_WIN32THREADS) || defined(__CYGWIN__) + thr->thrH = CreateThread(NULL, 0, rout, arg, 0, &thrID); + #else + thr->thrH = (HANDLE)_beginthreadex(NULL, 0, rout, arg, 0, &thrID); +@@ -29,7 +29,7 @@ + ATL_assert(thr->thrH); + #else + thr->rank = proc; +- #ifdef ATL_WIN32THREADS ++ #if defined(ATL_WIN32THREADS) || defined(__CYGWIN__) + thr->thrH = CreateThread(NULL, 0, rout, arg, CREATE_SUSPENDED, &thrID); + #else + thr->thrH = (HANDLE)_beginthreadex(NULL, 0, rout, arg, From 64f5c3d90b0f473044a77b6b438f542eed7a4ef5 Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Thu, 20 Nov 2014 19:07:34 +0530 Subject: [PATCH 161/698] trac #17370: Setting .copy(immutable=False) everywhere --- src/sage/graphs/comparability.pyx | 2 +- src/sage/graphs/digraph.py | 8 ++++---- src/sage/graphs/generators/families.py | 2 +- src/sage/graphs/generic_graph.py | 10 +++++----- src/sage/graphs/graph.py | 6 +++--- src/sage/graphs/graph_coloring.py | 4 ++-- .../graphs/graph_decompositions/graph_products.pyx | 2 +- src/sage/graphs/graph_plot_js.py | 14 ++++++++++---- 8 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/sage/graphs/comparability.pyx b/src/sage/graphs/comparability.pyx index 08f47a52b91..a303d1c4d4f 100644 --- a/src/sage/graphs/comparability.pyx +++ b/src/sage/graphs/comparability.pyx @@ -370,7 +370,7 @@ def greedy_is_comparability_with_certificate(g, certificate = False): elif not certificate: return True - gg = g.copy() + gg = g.copy(immutable=False) from sage.graphs.digraph import DiGraph h = DiGraph() h.add_vertices(gg.vertices()) diff --git a/src/sage/graphs/digraph.py b/src/sage/graphs/digraph.py index 666666c4d4a..a680fd78ffc 100644 --- a/src/sage/graphs/digraph.py +++ b/src/sage/graphs/digraph.py @@ -1977,7 +1977,7 @@ def reverse_edge(self, u, v=None, label=None, inplace=True, multiedges=None): if not self.has_edge(u,v,label): raise ValueError("Input edge must exist in the digraph.") - tempG = self if inplace else self.copy() + tempG = self if inplace else self.copy(immutable=False) if label is None: if not tempG.allows_multiple_edges(): @@ -2111,7 +2111,7 @@ def reverse_edges(self, edges, inplace=True, multiedges=None): sage: Dr.edges() == D.reverse().edges() True """ - tempG = self if inplace else self.copy() + tempG = self if inplace else self.copy(immutable=False) for e in edges: tempG.reverse_edge(e,inplace=True,multiedges=multiedges) if not inplace: @@ -2547,7 +2547,7 @@ def _all_cycles_iterator_vertex(self, vertex, starting_vertices=None, simple=Fal for id, component in enumerate(sccs): for v in component: d[v] = id - h = self.copy() + h = self.copy(immutable=False) h.delete_edges([(u,v) for (u,v) in h.edge_iterator(labels=False) if d[u] != d[v]]) else: h = self @@ -2680,7 +2680,7 @@ def all_cycles_iterator(self, starting_vertices=None, simple=False, for id, component in enumerate(sccs): for v in component: d[v] = id - h = self.copy() + h = self.copy(immutable=False) h.delete_edges([ (u,v) for (u,v) in h.edge_iterator(labels=False) if d[u] != d[v] ]) # We create one cycles iterator per vertex. This is necessary if we diff --git a/src/sage/graphs/generators/families.py b/src/sage/graphs/generators/families.py index e8755ab1850..0ba1a135ab7 100644 --- a/src/sage/graphs/generators/families.py +++ b/src/sage/graphs/generators/families.py @@ -1278,7 +1278,7 @@ def MycielskiStep(g): """ # Make a copy of the input graph g - gg = g.copy() + gg = g.copy(immutable=False) # rename a vertex v of gg as (1,v) renamer = dict( [ (v, (1,v)) for v in g.vertices() ] ) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 79c92229610..2daf234eefb 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -5346,7 +5346,7 @@ def edge_cut(self, s, t, value_only=True, use_edge_labels=False, vertices=False, return self.flow(s,t,value_only=value_only,use_edge_labels=use_edge_labels, method=method) flow_value, flow_graph = self.flow(s,t,value_only=value_only,use_edge_labels=use_edge_labels, method=method) - g = self.copy() + g = self.copy(immutable=False) for u,v,l in flow_graph.edge_iterator(): if (not use_edge_labels or (weight(g.edge_label(u,v)) == weight(l))): @@ -10992,7 +10992,7 @@ def subgraph_search(self, G, induced=False): if induced: return self.subgraph(g) else: - Gcopy=G.copy() + Gcopy=G.copy(immutable=False) Gcopy.relabel(g) return self.subgraph(vertices=Gcopy.vertices(), edges=Gcopy.edges()) @@ -11345,7 +11345,7 @@ def is_chordal(self, certificate = False, algorithm = "B"): return all( gg.is_chordal() for gg in self.connected_components_subgraphs() ) hole = None - g = self.copy() + g = self.copy(immutable=False) # Algorithms # @@ -11650,7 +11650,7 @@ def is_interval(self, certificate = False): .. SEEALSO:: - :mod:`Interval Graph Recognition `. - + - :meth:`PQ ` -- Implementation of PQ-Trees. @@ -11670,7 +11670,7 @@ def is_interval(self, certificate = False): cliques = [] # As we will be deleting vertices ... - g = self.copy() + g = self.copy(immutable=False) for cc in self.connected_components_subgraphs(): diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 090172a9362..088a326793d 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -3271,7 +3271,7 @@ def degree_constrained_subgraph(self, bounds=None, solver=None, verbose=0): try: p.solve(log=verbose) - g = self.copy() + g = self.copy(immutable=False) b = p.get_values(b) g.delete_edges([(x,y) for x,y,_ in g.edge_iterator() if b[reorder(x,y)] < 0.5]) return g @@ -4187,7 +4187,7 @@ def fractional_chromatic_index(self, solver = None, verbose_constraints = 0, ver self._scream_if_not_simple() from sage.numerical.mip import MixedIntegerLinearProgram - g = self.copy() + g = self.copy(immutable=False) p = MixedIntegerLinearProgram(solver=solver, constraint_generation = True) # One variable per edge @@ -5812,7 +5812,7 @@ def vertex_cover(self, algorithm = "Cliquer", value_only = False, # We first create manually a copy of the graph to prevent creating # multi-edges when merging vertices, if edges have labels (e.g., weights). - g = self.copy() + g = self.copy(immutable=False) degree_at_most_two = set([u for u,du in g.degree(labels = True).items() if du <= 2]) diff --git a/src/sage/graphs/graph_coloring.py b/src/sage/graphs/graph_coloring.py index 352e20e73ee..6d74d61aaa8 100644 --- a/src/sage/graphs/graph_coloring.py +++ b/src/sage/graphs/graph_coloring.py @@ -1304,7 +1304,7 @@ class :class:`MixedIntegerLinearProgram answer = [[] for i in range(k)] add = lambda (u,v),i : answer[i].append((u,v)) else: - gg = g.copy() + gg = g.copy(immutable=False) gg.delete_edges(g.edges()) answer = [gg.copy() for i in range(k)] add = lambda (u,v),i : answer[i].add_edge((u,v)) @@ -1509,7 +1509,7 @@ class :class:`MixedIntegerLinearProgram answer = [[] for i in range(k)] add = lambda (u,v),i : answer[i].append((u,v)) else: - gg = g.copy() + gg = g.copy(immutable=False) gg.delete_edges(g.edges()) answer = [gg.copy() for i in range(k)] add = lambda (u,v),i : answer[i].add_edge((u,v)) diff --git a/src/sage/graphs/graph_decompositions/graph_products.pyx b/src/sage/graphs/graph_decompositions/graph_products.pyx index 0f937a92093..9556e68c8d1 100644 --- a/src/sage/graphs/graph_decompositions/graph_products.pyx +++ b/src/sage/graphs/graph_decompositions/graph_products.pyx @@ -227,7 +227,7 @@ def is_cartesian_product(g, certificate = False, relabeling = False): # As we need the vertices of g to be linearly ordered, we copy the graph and # relabel it - g = g.copy() + g = g.copy(immutable=False) trev = g.relabel(return_map = True) t = dict([(x,y) for y,x in trev.iteritems()]) diff --git a/src/sage/graphs/graph_plot_js.py b/src/sage/graphs/graph_plot_js.py index 2be010094b1..2a9fd12f66d 100644 --- a/src/sage/graphs/graph_plot_js.py +++ b/src/sage/graphs/graph_plot_js.py @@ -148,14 +148,14 @@ def gen_html_code(G, information. Set to ``0.04`` by default. .. WARNING:: - + Since the d3js package is not standard yet, the javascript is fetched from d3js.org website by the browser. If you want to avoid that (e.g. to protect your privacy or by lack of internet connection), you can install the d3js package for offline use with the Sage command ``install_package('d3js')`` or by running ``sage -i d3js`` from the command line. - + EXAMPLES:: sage: graphs.RandomTree(50).show(method="js") # optional -- internet @@ -183,6 +183,10 @@ def gen_html_code(G, sage: from sage.graphs.graph_plot_js import gen_html_code sage: filename = gen_html_code(graphs.PetersenGraph()) + + :trac:`17370`:: + + sage: filename = gen_html_code(graphs.CompleteBipartiteGraph(4,5)) """ directed = G.is_directed() multiple_edges = G.has_multiple_edges() @@ -269,12 +273,14 @@ def gen_html_code(G, for v in G.vertices(): x, y = Gpos[v] - pos.append([x, -y]) + pos.append([float(x), float(-y)]) # Encodes the data as a JSON string from json import JSONEncoder string = JSONEncoder().encode({"nodes": nodes, - "links": edges, "loops": loops, "pos": pos, + "links": edges, + "loops": loops, + "pos": pos, "directed": G.is_directed(), "charge": int(charge), "link_distance": int(link_distance), From dd55337ee2544cbdd6980010455d0840e2af80ea Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Thu, 20 Nov 2014 06:51:48 -0800 Subject: [PATCH 162/698] Only take installed files (in local) when rebasing on Cygwin. That is in particular not all the duplicate stuff in src/build. --- src/bin/sage-rebase.sh | 2 +- src/bin/sage-rebaseall.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bin/sage-rebase.sh b/src/bin/sage-rebase.sh index 461abdf6544..68f425cd1d6 100755 --- a/src/bin/sage-rebase.sh +++ b/src/bin/sage-rebase.sh @@ -11,6 +11,6 @@ # Invoke this script from a shell after going to the SAGE_ROOT directory. echo "Getting list of dlls. This may take a while..." -/bin/find -name "*.dll" -o -name "*.so" > /tmp/sage-dlls.lst +/bin/find local -name "*.dll" -o -name "*.so" > /tmp/sage-dlls.lst echo "Now rebasing..." /bin/rebase -O -T /tmp/sage-dlls.lst diff --git a/src/bin/sage-rebaseall.sh b/src/bin/sage-rebaseall.sh index 5e59e94e4f1..09398ca8fbf 100755 --- a/src/bin/sage-rebaseall.sh +++ b/src/bin/sage-rebaseall.sh @@ -17,6 +17,6 @@ # (which usually means admin rights). echo "Getting list of dlls. This may take a while..." -/bin/find -name "*.dll" -o -name "*.so" > /tmp/sage-dlls.lst +/bin/find local -name "*.dll" -o -name "*.so" > /tmp/sage-dlls.lst echo "Now rebasing..." /bin/rebaseall -T /tmp/sage-dlls.lst From 38093124eb01d154c48f6bdf19145519d9c20507 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Thu, 20 Nov 2014 09:42:57 -0800 Subject: [PATCH 163/698] Modify logic to set need_to_install_gcc. Only trigger GCC build if SAGE_INSTALL_GCC is unset and no previous install has been made. --- build/install | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/build/install b/build/install index fa9b36fd5f4..dde17569d3a 100755 --- a/build/install +++ b/build/install @@ -89,18 +89,7 @@ if [ -z "$FC" ]; then fi fi -if [ -f "$SAGE_LOCAL/bin/gcc" ]; then - # GCC is already installed. To disable unneeded rebuilding - # of GCC, we touch the installed file for GCC, such that it will - # really only be built if one of its dependencies has been upgraded. - echo >&2 "GCC was installed before, it will get re-installed if needed." - need_to_install_gcc=yes - for f in "$SAGE_SPKG_INST"/gcc-*; do - if [ -f "$f" ]; then - touch "$f" - fi - done -elif [ -n "$SAGE_INSTALL_GCC" ]; then +if [ -n "$SAGE_INSTALL_GCC" ]; then # Check the value of the environment variable SAGE_INSTALL_GCC case "$SAGE_INSTALL_GCC" in yes) @@ -117,6 +106,19 @@ else # SAGE_INSTALL_GCC is not set, install GCC when needed. need_to_install_gcc=no + if [ -f "$SAGE_LOCAL/bin/gcc" -a "`ls $SAGE_SPKG_INST/gcc-*`" != "" ]; then + # GCC is already installed. To disable unneeded rebuilding + # of GCC, we touch the installed file for GCC, such that it will + # really only be built if one of its dependencies has been upgraded. + echo >&2 "GCC was installed before, it will get re-installed if needed." + need_to_install_gcc=yes + for f in "$SAGE_SPKG_INST"/gcc-*; do + if [ -f "$f" ]; then + touch "$f" + fi + done + fi + # Check whether $CXX is some version of GCC. If it's a different # compiler, install GCC. CXXtype=`testcxx.sh $CXX` From bb1447dd4a3495b64963e9cb6878f8364c93a215 Mon Sep 17 00:00:00 2001 From: Karl-Dieter Crisman Date: Thu, 20 Nov 2014 13:06:37 -0500 Subject: [PATCH 164/698] Minor doc upgrades for #1678 --- src/doc/en/tutorial/interactive_shell.rst | 12 ++++++++++++ src/sage/functions/other.py | 15 +++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/doc/en/tutorial/interactive_shell.rst b/src/doc/en/tutorial/interactive_shell.rst index beef9814c3a..8f4a6e1d802 100644 --- a/src/doc/en/tutorial/interactive_shell.rst +++ b/src/doc/en/tutorial/interactive_shell.rst @@ -262,6 +262,18 @@ i.e., the amount of time that elapsed on your wall clock, is also 0.66 seconds. If your computer is heavily loaded with other programs, the wall time may be much larger than the CPU time. +It's also possible to use the ``timeit`` function to try to get +timing over a large number of iterations of a command. This gives +slightly different information, and requires the input of a string +with the command you want to time. + +.. skip + +:: + + sage: timeit("int(1938)^int(99484)") + 5 loops, best of 3: 44.8 ms per loop + Next we time exponentiation using the native Sage Integer type, which is implemented (in Cython) using the GMP library: diff --git a/src/sage/functions/other.py b/src/sage/functions/other.py index dc538e56e47..1af6afcb5ab 100644 --- a/src/sage/functions/other.py +++ b/src/sage/functions/other.py @@ -1735,8 +1735,23 @@ def sqrt(x, *args, **kwds): [2, -2] sage: sqrt(x^2) sqrt(x^2) + + For a non-symbolic square root, there are a few options. + The best is to numerically approximate afterward:: + sage: sqrt(2).n() 1.41421356237310 + sage: sqrt(2).n(prec=100) + 1.4142135623730950488016887242 + + Or one can input a numerical type. + + sage: sqrt(2.) + 1.41421356237310 + sage: sqrt(2.000000000000000000000000) + 1.41421356237309504880169 + sage: sqrt(4.0) + 2.00000000000000 To prevent automatic evaluation, one can use the ``hold`` parameter after coercing to the symbolic ring:: From 5d5ac7f03dd61566a973c0de610b224e4406e3e5 Mon Sep 17 00:00:00 2001 From: Andrew Fleckenstein Date: Thu, 20 Nov 2014 13:22:08 -0500 Subject: [PATCH 165/698] Trac 4485 - explain NameError in tutorial --- src/doc/en/tutorial/tour_algebra.rst | 13 +++++++++++++ src/doc/en/tutorial/tour_functions.rst | 10 +++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/doc/en/tutorial/tour_algebra.rst b/src/doc/en/tutorial/tour_algebra.rst index f132cf4ba36..cc3b5666d20 100644 --- a/src/doc/en/tutorial/tour_algebra.rst +++ b/src/doc/en/tutorial/tour_algebra.rst @@ -7,6 +7,19 @@ differentiation, integration, and Laplace transforms. See the `Sage Constructions `_ documentation for more examples. +In all these examples, it is important to note that the variables in the +functions are defined to be ``var(...)``. As an example: + +:: + + sage: u = var('u') + sage: diff(sin(u), u) + cos(u) + +If you get a ``NameError``, check to see if you mispelled something, +or forgot to define a variable with ``var(...)``. + + Solving Equations ----------------- diff --git a/src/doc/en/tutorial/tour_functions.rst b/src/doc/en/tutorial/tour_functions.rst index 784759ee2d3..600e218f57a 100644 --- a/src/doc/en/tutorial/tour_functions.rst +++ b/src/doc/en/tutorial/tour_functions.rst @@ -24,11 +24,11 @@ These functions can be plotted, but not differentiated or integrated. Graphics object consisting of 1 graphics primitive In the last line, note the syntax. Using ``plot(f(z), 0, 2)`` instead -will give an error, because ``z`` is a dummy variable in the -definition of ``f`` and is not defined outside of that -definition. Indeed, just ``f(z)`` returns an error. The following will -work in this case, although in general there are issues and so it -should probably be avoided (see item 4 below). +will give a ``NameError``, because ``z`` is a dummy variable in the +definition of ``f`` and is not defined outside of that definition. +In order to be able to use ``f(z)`` in the plot command, ``z`` +(or whatever is desired) needs to be defined as a variable. We +can use the syntax below, or in the next item in our list. .. link From 13513fa8760c747b2cb039d53c8e282030f7a128 Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" Date: Thu, 20 Nov 2014 11:35:22 -0800 Subject: [PATCH 166/698] Trac 9440: Document SAGE_DOCBUILD_OPTS --- src/doc/en/installation/source.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/doc/en/installation/source.rst b/src/doc/en/installation/source.rst index 33d7651765f..02ee4878356 100644 --- a/src/doc/en/installation/source.rst +++ b/src/doc/en/installation/source.rst @@ -937,6 +937,10 @@ Here are some of the more commonly used variables affecting the build process: Typically, building the documentation using LaTeX and dvipng takes longer and uses more memory and disk space than using MathJax. +- :envvar:`SAGE_DOCBUILD_OPTS` - the value of this variable is passed + as an argument to ``sage --docbuild all html`` or ``sage --docbuild + all pdf`` when you run ``make``, ``make doc``, or ``make doc-pdf``. + - :envvar:`SAGE_BUILD_DIR` - the default behavior is to build each spkg in a subdirectory of :file:`$SAGE_ROOT/local/var/tmp/sage/build/`; for example, build version 3.8.3.p12 of From b7182fb9571b1151ab9357779c3b42a1036ebe34 Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" Date: Fri, 21 Nov 2014 13:46:43 -0800 Subject: [PATCH 167/698] Trac 9440: document some more environment variables. --- src/doc/en/installation/source.rst | 39 ++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/doc/en/installation/source.rst b/src/doc/en/installation/source.rst index 02ee4878356..e2d60e5e96d 100644 --- a/src/doc/en/installation/source.rst +++ b/src/doc/en/installation/source.rst @@ -1142,6 +1142,21 @@ Environment variables dealing with specific Sage packages: - If this variable is unset, include the patch on sun4v machines only. +- :envvar:`PARI_CONFIGURE` - use this to pass extra parameters to + PARI's ``Configure`` script, for example to specify graphics + support (which is disabled by default). See the file + :file:`build/pkgs/pari/spkg-install` for more information. + +- :envvar:`SAGE_TUNE_PARI`: If yes, enable PARI self-tuning. Note that + this can be time-consuming. If you set this variable to "yes", you + will also see this: ``WARNING: Tuning PARI/GP is unreliable. You may + find your build of PARI fails, or PARI/GP does not work properly + once built. We recommend to build this package with + SAGE_CHECK="yes".`` + +- :envvar:`PARI_MAKEFLAGS`: The value of this variable is passed as an + argument to the ``$MAKE`` command when compiling PARI. + Some standard environment variables which are used by Sage: - :envvar:`CC` - while some programs allow you to use this to specify your C @@ -1170,7 +1185,13 @@ Some standard environment variables which are used by Sage: - :envvar:`CFLAGS`, :envvar:`CXXFLAGS` and :envvar:`FCFLAGS` - the flags for the C compiler, the C++ compiler and the Fortran compiler, respectively. The same comments apply to these: setting them may cause problems, because - they are not universally respected among the Sage packages. + they are not universally respected among the Sage packages. Note + also that ``export CFLAGS=""`` does not have the same effect as + ``unset CFLAGS``. The latter is preferable. + +- Similar comments apply to other compiler and linker flags like + :envvar:`CPPFLAGS`, :envvar:`LDFLAGS`, :envvar:`CXXFLAG64`, + :envvar:`LDFLAG64`, and :envvar:`LD`. Sage uses the following environment variables when it runs: @@ -1235,7 +1256,7 @@ Variables dealing with doctesting: - :envvar:`SAGE_TIMEOUT` - used for Sage's doctesting: the number of seconds to allow a doctest before timing it out. - If this isn't set, the default is 360 seconds (6 minutes). + If this isn't set, the default is 300 seconds (5 minutes). - :envvar:`SAGE_TIMEOUT_LONG` - used for Sage's doctesting: the number of seconds to allow a doctest before timing it out, if tests are run using @@ -1252,6 +1273,20 @@ Variables dealing with doctesting: and `here (unpickle_all) `_. +Sage sets some other environment variables. The most accurate way to +see what Sage does is to first run ``env`` from a shell prompt to see +what environment variables you have set. Then run ``sage --sh -c +env`` to see the list after Sage sets its variables. (This runs a +separate shell, executes the shell command ``env``, and then exits +that shell, so after running this, your settings will be restored.) +Alternatively, you can peruse the shell script +:file:`src/bin/sage-env`. + +Sage also has some environment-like settings. Some of these correspond +to actual environment variables while others have names like +environment variables but are only available while Sage is running. To +see a list, execute ``sage.env.[TAB]`` while running Sage. + .. comment: *************************************************************************** FIX THIS! From 79280e197ff0507b3c2b29ed23fe7aefaedc9aae Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" Date: Fri, 21 Nov 2014 13:56:01 -0800 Subject: [PATCH 168/698] Trac 9440: document SAGE_TEST_*_ITER --- src/doc/en/installation/source.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/doc/en/installation/source.rst b/src/doc/en/installation/source.rst index e2d60e5e96d..07118a330aa 100644 --- a/src/doc/en/installation/source.rst +++ b/src/doc/en/installation/source.rst @@ -1273,6 +1273,13 @@ Variables dealing with doctesting: and `here (unpickle_all) `_. +- :envvar:`SAGE_TEST_GLOBAL_ITER`, :envvar:`SAGE_TEST_ITER`: these can + be used instead of passing the flags ``--global-iterations`` and + ``--file-iterations``, respectively, to ``sage -t``. Indeed, these + variables are only used if the flags are unset. Run ``sage -t -h`` + for more information on the effects of these flags (and therefore + these variables). + Sage sets some other environment variables. The most accurate way to see what Sage does is to first run ``env`` from a shell prompt to see what environment variables you have set. Then run ``sage --sh -c From dbea30c4b9a705a80e7f3c81d2f2a6a739a79e9c Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" Date: Fri, 21 Nov 2014 14:19:32 -0800 Subject: [PATCH 169/698] Trac 9440: change date in source.rst --- src/doc/en/installation/source.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/en/installation/source.rst b/src/doc/en/installation/source.rst index 07118a330aa..5eefdded52c 100644 --- a/src/doc/en/installation/source.rst +++ b/src/doc/en/installation/source.rst @@ -1416,4 +1416,4 @@ would be appropriate if you have a Core i3/5/7 processor with AVX support. -**This page was last updated in October 2014 (Sage 6.4).** +**This page was last updated in November 2014 (Sage 6.5).** From 107e511f3857ccef93a01d2c22a6caa51b9ecf23 Mon Sep 17 00:00:00 2001 From: Thierry Monteil Date: Sat, 22 Nov 2014 15:08:39 +0100 Subject: [PATCH 170/698] #17368 forgot to modify install script. --- build/install | 1 + 1 file changed, 1 insertion(+) diff --git a/build/install b/build/install index fa9b36fd5f4..66292a2ca91 100755 --- a/build/install +++ b/build/install @@ -328,6 +328,7 @@ PARI_SEADATA_SMALL=`newest_version pari_seadata_small` PATCH=`newest_version patch` PEXPECT=`newest_version pexpect` PILLOW=`newest_version pillow` +PIP=`newest_version pip` PKGCONF=`newest_version pkgconf` PKGCONFIG=`newest_version pkgconfig` POLYBORI=`newest_version polybori` From 013e2e27978d4b48dd38ee3a00825f385286b0ba Mon Sep 17 00:00:00 2001 From: Thierry Monteil Date: Sat, 22 Nov 2014 15:31:33 +0100 Subject: [PATCH 171/698] #17368 remove a test related to pip being optional. --- src/bin/sage | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/bin/sage b/src/bin/sage index ca077604578..68e4fa7b3dc 100755 --- a/src/bin/sage +++ b/src/bin/sage @@ -449,10 +449,6 @@ if [ "$1" = '-scons' -o "$1" = '--scons' ]; then fi if [ "$1" = '-pip' -o "$1" = '--pip' ]; then - if [ ! -x "$SAGE_LOCAL/bin/pip" ]; then - echo "Pip is not installed. Run \"sage -i pip\" to install it." - exit 1 - fi shift exec pip "$@" fi From 612f8ede28c281e6e5f4bb0e3864ca35ff3906c3 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Wed, 5 Nov 2014 14:01:33 -0500 Subject: [PATCH 172/698] Trac #14630: Add Expression.simplify_real() method. The new simplify_real() method allows the user to declare that his expression is real, and allows the otherwise unavailable simplification of sqrt(x^2) to abs(x). It does this by, 1. Temporarily sets the Maxima simplification domain to 'real' (as opposed to the default of 'complex'). 2. Assumes all variables in the expression are real using the assume() facility. 3. Calls simplify() on the expression. 4. Restores the domain and forgets the approproate assumptions. Note: an earlier doctest which made assumptions but didn't forget() was also fixed. --- src/sage/symbolic/expression.pyx | 107 ++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 2 deletions(-) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 021c40c91eb..18fa070309a 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -8005,8 +8005,9 @@ cdef class Expression(CommutativeRingElement): .. seealso:: :meth:`simplify_full`, :meth:`simplify_trig`, - :meth:`simplify_rational`, :meth:`simplify_factorial`, - :meth:`simplify_log`, :meth:`canonicalize_radical` + :meth:`simplify_rational`, :meth:`simplify_rectform` + :meth:`simplify_factorial`, :meth:`simplify_log`, + :meth:`simplify_real`, :meth:`canonicalize_radical` EXAMPLES:: @@ -8081,6 +8082,7 @@ cdef class Expression(CommutativeRingElement): sage: f = (1/2)*log(2*t) + (1/2)*log(1/t) sage: f.simplify_full() 1/2*log(2*t) - 1/2*log(t) + sage: forget() """ x = self @@ -8234,6 +8236,107 @@ cdef class Expression(CommutativeRingElement): return self + + def simplify_real(self): + r""" + Simplify the given expression over the real numbers. This allows + the simplification of `\sqrt{x^{2}}` into `\left|x\right|`. + + INPUT: + + - ``self`` -- the expression to convert. + + OUTPUT: + + A new expression, equivalent to the original one under the + assumption that the variables involved are real. + + EXAMPLES:: + + sage: f = sqrt(x^2) + sage: f.simplify_real() + abs(x) + + TESTS: + + We set the Maxima ``domain`` variable to 'real' before we call + out to Maxima. When we return, however, we should set the + ``domain`` back to what it was, rather than assuming that it + was 'complex':: + + sage: from sage.calculus.calculus import maxima + sage: maxima('domain: real;') + real + sage: x.simplify_real() + x + sage: maxima('domain;') + real + sage: maxima('domain: complex;') + complex + + We forget the assumptions that our variables are real after + simplification; make sure we don't forget an assumption that + existed before we were called:: + + sage: assume(x, 'real') + sage: x.simplify_real() + x + sage: assumptions() + [x is real] + sage: forget() + + We also want to be sure that we don't forget assumptions on + other variables:: + + sage: x,y,z = SR.var('x,y,z') + sage: assume(y, 'integer') + sage: assume(z, 'antisymmetric') + sage: x.simplify_real() + x + sage: assumptions() + [y is integer, z is antisymmetric] + sage: forget() + + No new assumptions should exist after the call:: + + sage: assumptions() + [] + sage: x.simplify_real() + x + sage: assumptions() + [] + + """ + from sage.symbolic.assumptions import assume, assumptions, forget + from sage.calculus.calculus import maxima + original_domain = maxima.eval('domain') + original_assumptions = assumptions() + + maxima.eval('domain: real$') + + # We might as well go all the way and tell Maxima to assume + # that all variables are real. Since we're setting the + # simplification domain (and it's indiscriminate), you'd + # better not call this unless your variables really are real + # anyway. + for v in self.variables(): + assume(v, 'real'); + + result = self.simplify(); + + # Set the domain back to what it was before we were called. + maxima.eval('domain: %s$' % original_domain) + + # Forget all assumptions, and restore the ones that existed + # when we were called. This is much simpler than the bookkeeping + # necessary otherwise. + forget() + for assumption in original_assumptions: + assume(assumption); + + return result + + def simplify_trig(self,expand=True): r""" Optionally expand and then employ identities such as From 649e3b3eece6daea3d3c043d2034f3416a85fb09 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sat, 22 Nov 2014 10:07:52 -0500 Subject: [PATCH 173/698] Trac #14630: Add Expression.simplify_hypergeometric() to the "see also" list for Expression.simplify(). --- src/sage/symbolic/expression.pyx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 18fa070309a..290971fe4b1 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -8007,7 +8007,8 @@ cdef class Expression(CommutativeRingElement): :meth:`simplify_full`, :meth:`simplify_trig`, :meth:`simplify_rational`, :meth:`simplify_rectform` :meth:`simplify_factorial`, :meth:`simplify_log`, - :meth:`simplify_real`, :meth:`canonicalize_radical` + :meth:`simplify_real`, :meth:`simplify_hypergeometric`, + :meth:`canonicalize_radical` EXAMPLES:: From 23ae04da4749a4f48f48023d6029c89db58c7a56 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Sat, 22 Nov 2014 22:10:42 +0000 Subject: [PATCH 174/698] Ensure that the timer is started before catching exception --- src/sage/doctest/forker.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py index 6d938922a90..ec7dde01b7d 100644 --- a/src/sage/doctest/forker.py +++ b/src/sage/doctest/forker.py @@ -843,9 +843,8 @@ def compile_and_execute(self, example, compiler, globs): globs.start() example.sequence_number = len(self.history) self.history.append(example) - timer = Timer() + timer = Timer().start() try: - timer.start() compiled = compiler(example) timer.start() # reset timer exec(compiled, globs) From 39a14e6d0b3a47b8b29abd9603adec0f234b6607 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Sat, 22 Nov 2014 22:33:50 +0000 Subject: [PATCH 175/698] Disable doctest with unreasonably high memory consumption --- src/sage/matrix/matrix_integer_dense.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx index 0cc61a967b7..7cac5119db8 100644 --- a/src/sage/matrix/matrix_integer_dense.pyx +++ b/src/sage/matrix/matrix_integer_dense.pyx @@ -2817,7 +2817,7 @@ cdef class Matrix_integer_dense(matrix_dense.Matrix_dense): # dense or sparse Traceback (most recent call last): ... TypeError: delta must be <= 1 - sage: L = X.LLL(delta=1) + sage: L = X.LLL(delta=1) # not tested, will eat lots of ram Traceback (most recent call last): ... RuntimeError: infinite loop in LLL From 4b87328ca22c9fd041ee9264b43de4eba60037c1 Mon Sep 17 00:00:00 2001 From: David Coudert Date: Sun, 23 Nov 2014 00:54:23 +0100 Subject: [PATCH 176/698] trac #17227: change include bitset to comply with patch 17196 --- src/sage/graphs/hyperbolicity.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/hyperbolicity.pyx b/src/sage/graphs/hyperbolicity.pyx index 01df98c6cfe..566bb10dab3 100644 --- a/src/sage/graphs/hyperbolicity.pyx +++ b/src/sage/graphs/hyperbolicity.pyx @@ -170,7 +170,7 @@ from sage.data_structures.bitset import Bitset from libc.stdint cimport uint16_t, uint32_t, uint64_t include "sage/ext/interrupt.pxi" include "sage/ext/stdsage.pxi" -include "sage/misc/bitset.pxi" +include "sage/data_structures/bitset.pxi" # Defining a pair of vertices as a C struct From 3bea4e5a07c418528a77cc52b649aaa6c2c10782 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Sun, 23 Nov 2014 15:10:56 -0600 Subject: [PATCH 177/698] trac #17385: replacement uniq -> set --- src/sage/graphs/digraph.py | 11 +++++------ src/sage/graphs/graph.py | 11 +++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/sage/graphs/digraph.py b/src/sage/graphs/digraph.py index fc0c9a9450e..ee0778a9dfc 100644 --- a/src/sage/graphs/digraph.py +++ b/src/sage/graphs/digraph.py @@ -571,7 +571,6 @@ def __init__(self, data=None, pos=None, loops=None, format=None, msg = '' GenericGraph.__init__(self) from sage.structure.element import is_Matrix - from sage.misc.misc import uniq if sparse == False: if data_structure != "sparse": @@ -738,7 +737,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, if multiedges is None: multiedges = False format = 'adjacency_matrix' if format == 'adjacency_matrix': - entries = uniq(data.list()) + entries = set(data.list()) for e in entries: try: e = int(e) @@ -773,7 +772,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, if len(NZ) != 2: msg += "There must be two nonzero entries (-1 & 1) per column." raise ValueError(msg) - L = sorted(uniq(c.list())) + L = sorted(set(c.list())) if L != [-1,0,1]: msg += "Each column represents an edge: -1 goes to 1." raise ValueError(msg) @@ -785,7 +784,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, if weighted is None: weighted = False if multiedges is None: total = len(positions) - multiedges = ( len(uniq(positions)) < total ) + multiedges = ( len(set(positions)) < total ) num_verts = data.nrows() elif format == 'DiGraph': if loops is None: loops = data.allows_loops() @@ -794,7 +793,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, if multiedges is None: multiedges = data.allows_multiple_edges() elif not multiedges: e = data.edges(labels=False) - if len(e) != len(uniq(e)): + if len(e) != len(set(e)): raise ValueError("No multiple edges but input digraph"+ " has multiple edges.") if weighted is None: weighted = data.weighted() @@ -848,7 +847,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, if loops is None: loops = False if weighted is None: weighted = False for u in data: - if len(uniq(data[u])) != len(data[u]): + if len(set(data[u])) != len(data[u]): if multiedges is False: v = (v for v in data[u] if data[u].count(v) > 1).next() raise ValueError("Non-multidigraph got several edges (%s,%s)"%(u,v)) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index ca8d23a75dc..9c3ada32665 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -1116,7 +1116,6 @@ def __init__(self, data=None, pos=None, loops=None, format=None, GenericGraph.__init__(self) msg = '' from sage.structure.element import is_Matrix - from sage.misc.misc import uniq if sparse == False: if data_structure != "sparse": @@ -1333,7 +1332,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, if multiedges is None: multiedges = False format = 'adjacency_matrix' if format == 'adjacency_matrix': - entries = uniq(data.list()) + entries = set(data.list()) for e in entries: try: e = int(e) @@ -1377,7 +1376,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, raise ValueError(msg) else: positions.append(tuple(NZ)) - L = sorted(uniq(c.list())) + L = sorted(set(c.list())) if data.nrows() != (2 if len(NZ) == 2 else 1): desirable = [-1, 0, 1] if len(NZ) == 2 else [0, 1] @@ -1391,7 +1390,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, if weighted is None: weighted = False if multiedges is None: total = len(positions) - multiedges = ( len(uniq(positions)) < total ) + multiedges = ( len(set(positions)) < total ) num_verts = data.nrows() elif format == 'Graph': if loops is None: loops = data.allows_loops() @@ -1401,7 +1400,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, elif not multiedges: e = data.edges(labels=False) e = [sorted(f) for f in e] - if len(e) != len(uniq(e)): + if len(e) != len(set(e)): raise ValueError("No multiple edges but input graph"+ " has multiple edges.") if weighted is None: weighted = data.weighted() @@ -1460,7 +1459,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, if loops is None: loops = False if weighted is None: weighted = False for u in data: - if len(uniq(data[u])) != len(data[u]): + if len(set(data[u])) != len(data[u]): if multiedges is False: v = (v for v in data[u] if data[u].count(v) > 1).next() raise ValueError("Non-multigraph got several edges (%s,%s)"%(u,v)) From 3f8a98bc9caa9f64504cf2d85ce4ed39ea7ce12c Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Sun, 23 Nov 2014 15:38:13 -0600 Subject: [PATCH 178/698] trac #17385: various optimization --- src/sage/graphs/digraph.py | 127 +++++++++++++++++++++---------------- src/sage/graphs/graph.py | 67 +++++++++++-------- 2 files changed, 113 insertions(+), 81 deletions(-) diff --git a/src/sage/graphs/digraph.py b/src/sage/graphs/digraph.py index ee0778a9dfc..dde022017d4 100644 --- a/src/sage/graphs/digraph.py +++ b/src/sage/graphs/digraph.py @@ -101,6 +101,7 @@ """ from sage.rings.integer import Integer +from sage.rings.integer_ring import ZZ from sage.misc.superseded import deprecation import sage.graphs.generic_graph_pyx as generic_graph_pyx from sage.graphs.generic_graph import GenericGraph @@ -567,12 +568,20 @@ def __init__(self, data=None, pos=None, loops=None, format=None, Traceback (most recent call last): ... ValueError: Non-multidigraph got several edges (0,1) + + Check the error when the input has a loop but ``loops`` is set to False + (:trac:`17385`):: + + sage: DiGraph([(0,0)], loops=False) + Traceback (most recent call last): + ... + ValueError: No loops but dict has loop at 0. """ msg = '' GenericGraph.__init__(self) from sage.structure.element import is_Matrix - if sparse == False: + if sparse is False: if data_structure != "sparse": raise ValueError("The 'sparse' argument is an alias for " "'data_structure'. Please do not define both.") @@ -737,33 +746,37 @@ def __init__(self, data=None, pos=None, loops=None, format=None, if multiedges is None: multiedges = False format = 'adjacency_matrix' if format == 'adjacency_matrix': - entries = set(data.list()) - for e in entries: - try: - e = int(e) - assert e >= 0 - except Exception: - if weighted is False: - raise ValueError("Non-weighted digraph's"+ - " adjacency matrix must have only nonnegative"+ - " integer entries") - weighted = True - if multiedges is None: multiedges = False - break + if data.base_ring() != ZZ: + data = data.change_ring(ZZ) + if data.is_sparse(): + entries = set(data[i,j] for i,j in data.nonzero_positions()) + else: + entries = set(data.list()) + + if ((weighted is None or weighted is False) and + any(e < 0 for e in entries)): + if weighted is False: + raise ValueError("Non-weighted digraph's"+ + " adjacency matrix must have only nonnegative"+ + " integer entries") + weighted = True + if multiedges is None: multiedges = False if weighted is None: weighted = False if multiedges is None: - multiedges = ((not weighted) and sorted(entries) != [0,1]) - - for i in xrange(data.nrows()): - if data[i,i] != 0: - if loops is None: loops = True - elif not loops: - raise ValueError("Non-looped digraph's adjacency"+ - " matrix must have zeroes on the diagonal.") - break + multiedges = ((not weighted) and any(e != 0 and e != 1 for e in entries)) + + if ((loops is None or loops is False) and + any(data[i,i] for i in xrange(data.nrows()))): + if loops is False: + raise ValueError("Non-looped digraph's adjacency"+ + " matrix must have zeroes on the diagonal.") + loops = True + if loops is None: + loops = False + num_verts = data.nrows() elif format == 'incidence_matrix': positions = [] @@ -811,48 +824,54 @@ def __init__(self, data=None, pos=None, loops=None, format=None, elif format == 'dict_of_dicts': if not all(isinstance(data[u], dict) for u in data): raise ValueError("Input dict must be a consistent format.") - verts = set(data.keys()) - if loops is None or loops is False: - for u in data: - if u in data[u]: - if loops is None: loops = True - elif loops is False: - raise ValueError("No loops but dict has loops.") - break - if loops is None: loops = False + + if ((loops is None or loops is False) and + any(u in neighb for u,neighb in data.iteritems())): + if loops is False: + u = (u for u,neighb in data.iteritems() if u in neighb).next() + raise ValueError("No loops but dict has loop at {}.".format(u)) + loops = True + if loops is None: + loops = False + if weighted is None: weighted = False - for u in data: - for v in data[u]: - if v not in verts: verts.add(v) - if multiedges is not False and not isinstance(data[u][v], list): - if multiedges is None: multiedges = False - if multiedges: - raise ValueError("Dict of dicts for multidigraph must be in the format {v : {u : list}}") + + if ((multiedges is True or multiedges is None) and + not all(isinstance(neighb[v], list) for neighb in data.itervalues() for v in neighb)): + if multiedges is True: + raise ValueError("Dict of dicts for multidigraph must be in the format {v : {u : list}}") + multiedges = False if multiedges is None and len(data) > 0: multiedges = True + + verts = set().union(data.keys(), *data.values()) num_verts = len(verts) elif format == 'dict_of_lists': # convert to a dict of lists if not already one if not all(isinstance(data[u], list) for u in data): - data = dict([u, list(data[u])] for u in data) + data = {u: list(v) for u,v in data.iteritems()} + + if ((loops is None or loops is False) and + any(u in neighb for u,neighb in data.iteritems())): + if loops is False: + u = (u for u,neighb in data.iteritems() if u in neighb).next() + raise ValueError("No loops but dict has loop at {}.".format(u)) + loops = True + if loops is None: + loops = False - verts = set().union(data.keys(),*data.values()) - if loops is None or loops is False: - for u in data: - if u in data[u]: - if loops is None: loops = True - elif loops is False: - raise ValueError("No loops but dict has loops.") - break - if loops is None: loops = False if weighted is None: weighted = False - for u in data: - if len(set(data[u])) != len(data[u]): + + if ((multiedges is None or multiedges is False) and + any(len(set(neighb)) != len(neighb) for neighb in data.itervalues())): if multiedges is False: - v = (v for v in data[u] if data[u].count(v) > 1).next() + uv = ((u,v) for u,neighb in data.iteritems() for v in neighb if neighb.count(v) > 1).next() raise ValueError("Non-multidigraph got several edges (%s,%s)"%(u,v)) - if multiedges is None: multiedges = True - if multiedges is None: multiedges = False + multiedges = True + if multiedges is None: + multiedges = False + + verts = set().union(data.keys(),*data.values()) num_verts = len(verts) elif format == 'NX': if weighted is None: diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 9c3ada32665..2d2bc47583b 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -1112,12 +1112,20 @@ def __init__(self, data=None, pos=None, loops=None, format=None, Traceback (most recent call last): ... ValueError: Non-multigraph got several edges (0,1) + + Check the error when the input has a loop but ``loops`` is set to False + (:trac:`17385`):: + + sage: Graph([(0,0)], loops=False) + Traceback (most recent call last): + ... + ValueError: No loops but dict has a loop at 0. """ GenericGraph.__init__(self) msg = '' from sage.structure.element import is_Matrix - if sparse == False: + if sparse is False: if data_structure != "sparse": raise ValueError("The 'sparse' argument is an alias for " "'data_structure'. Please do not define both.") @@ -1419,19 +1427,19 @@ def __init__(self, data=None, pos=None, loops=None, format=None, elif format == 'dict_of_dicts': if not all(isinstance(data[u], dict) for u in data): raise ValueError("Input dict must be a consistent format.") - verts = set(data.keys()) - if loops is None or loops is False: - for u in data: - if u in data[u]: - if loops is None: loops = True - elif loops is False: - raise ValueError("No loops but dict has loops.") - break - if loops is None: loops = False + + if ((loops is None or loops is False) and + any(u in neighb for u,neighb in data.iteritems())): + if loops is False: + u = (u for u,neighb in data.iteritems() if u in neighb).next() + raise ValueError("No loops but dict has loop at {}.".format(u)) + loops = True + if loops is None: + loops = False + if weighted is None: weighted = False for u in data: for v in data[u]: - if v not in verts: verts.add(v) if hash(u) > hash(v): if v in data and u in data[v]: if data[u][v] != data[v][u]: @@ -1443,28 +1451,34 @@ def __init__(self, data=None, pos=None, loops=None, format=None, raise ValueError("Dict of dicts for multigraph must be in the format {v : {u : list}}") if multiedges is None and len(data) > 0: multiedges = True + + verts = set().union(data.keys(), *data.values()) num_verts = len(verts) elif format == 'dict_of_lists': if not all(isinstance(data[u], list) for u in data): raise ValueError("Input dict must be a consistent format.") - verts = set().union(data.keys(),*data.values()) - if loops is None or loops is False: - for u in data: - if u in data[u]: - if loops is None: loops = True - elif loops is False: - raise ValueError("No loops but dict has loops.") - break - if loops is None: loops = False + if ((loops is None or loops is False) and + any(u in neighb for u,neighb in data.iteritems())): + if loops is False: + u = (u for u,neighb in data.iteritems() if u in neighb).next() + raise ValueError("No loops but dict has a loop at {}.".format(u)) + loops = True + if loops is None: + loops = False + if weighted is None: weighted = False - for u in data: - if len(set(data[u])) != len(data[u]): + + if ((multiedges is None or multiedges is False) and + any(len(set(neighb)) != len(neighb) for neighb in data.itervalues())): if multiedges is False: - v = (v for v in data[u] if data[u].count(v) > 1).next() - raise ValueError("Non-multigraph got several edges (%s,%s)"%(u,v)) - if multiedges is None: multiedges = True - if multiedges is None: multiedges = False + uv = ((u,v) for u,neighb in data.iteritems() for v in neighb if neighb.count(v) > 1).next() + raise ValueError("Non-multigraph got several edges (%s,%s)"%uv) + multiedges = True + if multiedges is None: + multiedges = False + + verts = set().union(data.keys(),*data.values()) num_verts = len(verts) elif format == 'NX': if weighted is None: @@ -6861,7 +6875,6 @@ def ihara_zeta_function_inverse(self): of the Ihara zeta function, Involve (http://msp.org/involve/2008/1-2/involve-v1-n2-p08-p.pdf) """ from sage.matrix.constructor import matrix - from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing ring = PolynomialRing(ZZ, 't') From 0fa9c20b5cf44989b40726e5c740c82a564a5263 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Sun, 23 Nov 2014 19:05:17 -0600 Subject: [PATCH 179/698] trac #17385: more cleanup after reviewer's comment --- src/sage/graphs/digraph.py | 56 +++++++++++++++++++------------- src/sage/graphs/graph.py | 66 +++++++++++++++++++++----------------- 2 files changed, 71 insertions(+), 51 deletions(-) diff --git a/src/sage/graphs/digraph.py b/src/sage/graphs/digraph.py index dde022017d4..64f1d8dcfd1 100644 --- a/src/sage/graphs/digraph.py +++ b/src/sage/graphs/digraph.py @@ -352,6 +352,15 @@ class DiGraph(GenericGraph): sage: DiGraph(M) Digraph on 5 vertices + sage: M = Matrix([[0,1,-1],[-1,0,-1/2],[1,1/2,0]]); M + [ 0 1 -1] + [ -1 0 -1/2] + [ 1 1/2 0] + sage: G = DiGraph(M,sparse=True); G + Digraph on 3 vertices + sage: G.weighted() + True + - an incidence matrix:: sage: M = Matrix(6, [-1,0,0,0,1, 1,-1,0,0,0, 0,1,-1,0,0, 0,0,1,-1,0, 0,0,0,1,-1, 0,0,0,0,0]); M @@ -746,16 +755,24 @@ def __init__(self, data=None, pos=None, loops=None, format=None, if multiedges is None: multiedges = False format = 'adjacency_matrix' if format == 'adjacency_matrix': - if data.base_ring() != ZZ: - data = data.change_ring(ZZ) + # note: the adjacency matrix might be weighted and hence not + # necessarily consists of integers + if not weighted and data.base_ring() != ZZ: + try: + data = data.change_ring(ZZ) + except TypeError: + if weighted is False: + raise ValueError("Non-weighted graph's"+ + " adjacency matrix must have only nonnegative"+ + " integer entries") + weighted = True if data.is_sparse(): entries = set(data[i,j] for i,j in data.nonzero_positions()) else: entries = set(data.list()) - if ((weighted is None or weighted is False) and - any(e < 0 for e in entries)): + if not weighted and any(e < 0 for e in entries): if weighted is False: raise ValueError("Non-weighted digraph's"+ " adjacency matrix must have only nonnegative"+ @@ -768,8 +785,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, if multiedges is None: multiedges = ((not weighted) and any(e != 0 and e != 1 for e in entries)) - if ((loops is None or loops is False) and - any(data[i,i] for i in xrange(data.nrows()))): + if not loops and any(data[i,i] for i in xrange(data.nrows())): if loops is False: raise ValueError("Non-looped digraph's adjacency"+ " matrix must have zeroes on the diagonal.") @@ -825,8 +841,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, if not all(isinstance(data[u], dict) for u in data): raise ValueError("Input dict must be a consistent format.") - if ((loops is None or loops is False) and - any(u in neighb for u,neighb in data.iteritems())): + if not loops and any(u in neighb for u,neighb in data.iteritems()): if loops is False: u = (u for u,neighb in data.iteritems() if u in neighb).next() raise ValueError("No loops but dict has loop at {}.".format(u)) @@ -836,8 +851,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, if weighted is None: weighted = False - if ((multiedges is True or multiedges is None) and - not all(isinstance(neighb[v], list) for neighb in data.itervalues() for v in neighb)): + if not multiedges and not all(isinstance(neighb[v], list) for neighb in data.itervalues() for v in neighb): if multiedges is True: raise ValueError("Dict of dicts for multidigraph must be in the format {v : {u : list}}") multiedges = False @@ -851,23 +865,21 @@ def __init__(self, data=None, pos=None, loops=None, format=None, if not all(isinstance(data[u], list) for u in data): data = {u: list(v) for u,v in data.iteritems()} - if ((loops is None or loops is False) and - any(u in neighb for u,neighb in data.iteritems())): - if loops is False: - u = (u for u,neighb in data.iteritems() if u in neighb).next() - raise ValueError("No loops but dict has loop at {}.".format(u)) - loops = True + if not loops and any(u in neighb for u,neighb in data.iteritems()): + if loops is False: + u = (u for u,neighb in data.iteritems() if u in neighb).next() + raise ValueError("No loops but dict has loop at {}.".format(u)) + loops = True if loops is None: loops = False if weighted is None: weighted = False - if ((multiedges is None or multiedges is False) and - any(len(set(neighb)) != len(neighb) for neighb in data.itervalues())): - if multiedges is False: - uv = ((u,v) for u,neighb in data.iteritems() for v in neighb if neighb.count(v) > 1).next() - raise ValueError("Non-multidigraph got several edges (%s,%s)"%(u,v)) - multiedges = True + if not multiedges and any(len(set(neighb)) != len(neighb) for neighb in data.itervalues()): + if multiedges is False: + uv = ((u,v) for u,neighb in data.iteritems() for v in neighb if neighb.count(v) > 1).next() + raise ValueError("Non-multidigraph got several edges (%s,%s)"%(u,v)) + multiedges = True if multiedges is None: multiedges = False diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 2d2bc47583b..32ffcfc9eb0 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -1340,33 +1340,44 @@ def __init__(self, data=None, pos=None, loops=None, format=None, if multiedges is None: multiedges = False format = 'adjacency_matrix' if format == 'adjacency_matrix': - entries = set(data.list()) - for e in entries: + # note: the adjacency matrix might be weighted and hence not + # necessarily consists of integers + if not weighted and data.base_ring() != ZZ: try: - e = int(e) - assert e >= 0 - except Exception: + data = data.change_ring(ZZ) + except TypeError: if weighted is False: raise ValueError("Non-weighted graph's"+ " adjacency matrix must have only nonnegative"+ " integer entries") weighted = True - if multiedges is None: multiedges = False - break + if data.is_sparse(): + entries = set(data[i,j] for i,j in data.nonzero_positions()) + else: + entries = set(data.list()) + + if not weighted and any(e < 0 for e in entries): + if weighted is False: + raise ValueError("Non-weighted digraph's"+ + " adjacency matrix must have only nonnegative"+ + " integer entries") + weighted = True + if multiedges is None: multiedges = False if weighted is None: weighted = False if multiedges is None: - multiedges = ((not weighted) and sorted(entries) != [0,1]) + multiedges = ((not weighted) and any(e != 0 and e != 1 for e in entries)) + + if not loops and any(data[i,i] for i in xrange(data.nrows())): + if loops is False: + raise ValueError("Non-looped digraph's adjacency"+ + " matrix must have zeroes on the diagonal.") + loops = True + if loops is None: + loops = False - for i in xrange(data.nrows()): - if data[i,i] != 0: - if loops is None: loops = True - elif not loops: - raise ValueError("Non-looped graph's adjacency"+ - " matrix must have zeroes on the diagonal.") - break num_verts = data.nrows() elif format == 'incidence_matrix': positions = [] @@ -1428,8 +1439,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, if not all(isinstance(data[u], dict) for u in data): raise ValueError("Input dict must be a consistent format.") - if ((loops is None or loops is False) and - any(u in neighb for u,neighb in data.iteritems())): + if not loops and any(u in neighb for u,neighb in data.iteritems()): if loops is False: u = (u for u,neighb in data.iteritems() if u in neighb).next() raise ValueError("No loops but dict has loop at {}.".format(u)) @@ -1458,23 +1468,21 @@ def __init__(self, data=None, pos=None, loops=None, format=None, if not all(isinstance(data[u], list) for u in data): raise ValueError("Input dict must be a consistent format.") - if ((loops is None or loops is False) and - any(u in neighb for u,neighb in data.iteritems())): - if loops is False: - u = (u for u,neighb in data.iteritems() if u in neighb).next() - raise ValueError("No loops but dict has a loop at {}.".format(u)) - loops = True + if not loops and any(u in neighb for u,neighb in data.iteritems()): + if loops is False: + u = (u for u,neighb in data.iteritems() if u in neighb).next() + raise ValueError("No loops but dict has a loop at {}.".format(u)) + loops = True if loops is None: loops = False if weighted is None: weighted = False - if ((multiedges is None or multiedges is False) and - any(len(set(neighb)) != len(neighb) for neighb in data.itervalues())): - if multiedges is False: - uv = ((u,v) for u,neighb in data.iteritems() for v in neighb if neighb.count(v) > 1).next() - raise ValueError("Non-multigraph got several edges (%s,%s)"%uv) - multiedges = True + if not multiedges and any(len(set(neighb)) != len(neighb) for neighb in data.itervalues()): + if multiedges is False: + uv = ((u,v) for u,neighb in data.iteritems() for v in neighb if neighb.count(v) > 1).next() + raise ValueError("Non-multigraph got several edges (%s,%s)"%uv) + multiedges = True if multiedges is None: multiedges = False From a9a70312e5c91e58fde7e79af051d6c35bf35b2a Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 25 Nov 2014 10:48:39 -0500 Subject: [PATCH 180/698] Trac #17389: Remove unsafe simplifications from test_relation_maxima(). When testing equality with assumptions, one branch of test_relation_maxima() in sage.symbolic.relation will try to simplify a difference (left- minus right-hand side) to zero. But some of the simplifications it uses, namely canonicalize_radical() and simplify_log(), are unsafe for complex variables. This commit removes those operations from the list, and adds two new (safe) simplifications: simplify_factorial() and simplify_rectform(). Test cases are added for bugs involving complex variables, and for expressions that can be reduced to zero using the new simplifications. --- src/sage/symbolic/relation.py | 68 +++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/src/sage/symbolic/relation.py b/src/sage/symbolic/relation.py index 4c7e7ada9c3..007ce114f38 100644 --- a/src/sage/symbolic/relation.py +++ b/src/sage/symbolic/relation.py @@ -393,6 +393,60 @@ def test_relation_maxima(relation): sage: test_relation_maxima(x!=1) False sage: forget() + + TESTS: + + Ensure that ``canonicalize_radical()`` and ``simplify_log`` are not + used inappropriately, :trac:`17389`. Either one would simplify ``f`` + to zero below:: + + sage: x,y = SR.var('x,y') + sage: assume(y, 'complex') + sage: f = log(x*y) - (log(x) + log(y)) + sage: f(x=-1, y=i) + -2*I*pi + sage: test_relation_maxima(f == 0) + False + sage: forget() + + Ensure that the ``sqrt(x^2)`` -> ``abs(x)`` simplification is not + performed when testing equality:: + + sage: assume(x, 'complex') + sage: f = sqrt(x^2) - abs(x) + sage: test_relation_maxima(f == 0) + False + sage: forget() + + If assumptions are made, ``simplify_rectform()`` is used:: + + sage: assume(x, 'real') + sage: f1 = ( e^(I*x) - e^(-I*x) ) / ( I*e^(I*x) + I*e^(-I*x) ) + sage: f2 = sin(x)/cos(x) + sage: test_relation_maxima(f1 - f2 == 0) + True + sage: forget() + + But not if ``x`` itself is complex:: + + sage: assume(x, 'complex') + sage: f1 = ( e^(I*x) - e^(-I*x) ) / ( I*e^(I*x) + I*e^(-I*x) ) + sage: f2 = sin(x)/cos(x) + sage: test_relation_maxima(f1 - f2 == 0) + False + sage: forget() + + If assumptions are made, then ``simplify_factorial()`` is used:: + + sage: n,k = SR.var('n,k') + sage: assume(n, 'integer') + sage: assume(k, 'integer') + sage: f1 = factorial(n+1)/factorial(n) + sage: f2 = n + 1 + sage: test_relation_maxima(f1 - f2 == 0) + True + sage: forget() + """ m = relation._maxima_() @@ -432,8 +486,18 @@ def test_relation_maxima(relation): if repr(difference) == '0': return True - #Try to apply some simplifications to see if left - right == 0 - simp_list = [difference.simplify_log, difference.simplify_rational,difference.canonicalize_radical,difference.simplify_trig] + # Try to apply some simplifications to see if left - right == 0. + # + # TODO: If simplify_log() is ever removed from simplify_full(), we + # can replace all of these individual simplifications with a + # single call to simplify_full(). That would work in cases where + # two simplifications are needed consecutively; the current + # approach does not. + # + simp_list = [difference.simplify_factorial(), + difference.simplify_rational(), + difference.simplify_rectform(), + difference.simplify_trig()] for f in simp_list: try: if repr( f() ).strip() == "0": From fff80ed2653f9e0ac5f791a034b72cc04f495bb0 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Tue, 25 Nov 2014 14:51:33 +0100 Subject: [PATCH 181/698] Make some methods private --- src/sage/crypto/mq/sr.py | 8 +-- .../rings/finite_rings/element_givaro.pyx | 54 +++++++++++-------- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/sage/crypto/mq/sr.py b/src/sage/crypto/mq/sr.py index efe368be9a4..4ea767ad77a 100644 --- a/src/sage/crypto/mq/sr.py +++ b/src/sage/crypto/mq/sr.py @@ -1436,9 +1436,9 @@ def hex_str_matrix(self, M): for x in range(M.nrows()): for y in range(M.ncols()): if e == 8: - st.append("%02X"%(int(str(M[x, y].int_repr())))) + st.append("%02X" % M[x, y].integer_representation()) else: - st.append("%X"%(int(str(M[x, y].int_repr())))) + st.append("%X" % M[x, y].integer_representation()) st.append("\n") return " ".join(st) @@ -1467,9 +1467,9 @@ def hex_str_vector(self, M): for y in range(M.ncols()): for x in range(M.nrows()): if e == 8: - st.append("%02X"%(int(str(M[x, y].int_repr())))) + st.append("%02X" % M[x, y].integer_representation()) else: - st.append("%X"%(int(str(M[x, y].int_repr())))) + st.append("%X" % M[x, y].integer_representation()) #st.append("\n") return "".join(st) diff --git a/src/sage/rings/finite_rings/element_givaro.pyx b/src/sage/rings/finite_rings/element_givaro.pyx index 6d68261aa37..d9ad7c017a1 100644 --- a/src/sage/rings/finite_rings/element_givaro.pyx +++ b/src/sage/rings/finite_rings/element_givaro.pyx @@ -74,6 +74,8 @@ from sage.structure.parent cimport Parent from sage.structure.parent_base cimport ParentWithBase from sage.structure.parent_gens cimport ParentWithGens +from sage.misc.superseded import deprecated_function_alias + cdef object is_IntegerMod cdef object Integer cdef object Rational @@ -1439,12 +1441,14 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): def integer_representation(FiniteField_givaroElement self): """ Return the integer representation of ``self``. When ``self`` is in the - prime subfield, the integer returned is equal to ``self`` and not - to ``log_repr``. + prime subfield, the integer returned is equal to ``self``. - Elements of this field are represented as ints in as follows: - for `e \in \GF{p}[x]` with `e = a_0 + a_1x + a_2x^2 + \cdots`, `e` is - represented as: `n= a_0 + a_1 p + a_2 p^2 + \cdots`. + Elements of this field are represented as integers as follows: + given the element `e \in \GF{p}[x]` with + `e = a_0 + a_1 x + a_2 x^2 + \cdots`, the integer representation + is `a_0 + a_1 p + a_2 p^2 + \cdots`. + + OUTPUT: A Python ``int``. EXAMPLES:: @@ -1479,28 +1483,30 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): return Integer(a) raise TypeError, "not in prime subfield" - def log_to_int(FiniteField_givaroElement self): + def _log_to_int(FiniteField_givaroElement self): r""" - Returns the int representation of ``self``, as a Sage integer. Use - ``int(self)`` to directly get a Python int. + Return the int representation of ``self``, as a Sage integer. - Elements of this field are represented as ints in as follows: - for `e \in \GF{p}[x]` with `e = a_0 + a_1x + a_2x^2 + \cdots`, `e` is - represented as: `n = a_0 + a_1 p + a_2 p^2 + \cdots`. + Elements of this field are represented as ints as follows: + given the element `e \in \GF{p}[x]` with + `e = a_0 + a_1x + a_2x^2 + \cdots`, the int representation is + `a_0 + a_1 p + a_2 p^2 + \cdots`. EXAMPLES:: sage: k. = GF(5^2); k Finite Field in b of size 5^2 - sage: k(4).log_to_int() + sage: k(4)._log_to_int() 4 - sage: b.log_to_int() + sage: b._log_to_int() 5 - sage: type(b.log_to_int()) + sage: type(b._log_to_int()) """ return Integer(self._cache.log_to_int(self.element)) + log_to_int = deprecated_function_alias(11295, _log_to_int) + def log(FiniteField_givaroElement self, base): """ Return the log to the base `b` of ``self``, i.e., an integer `n` @@ -1523,7 +1529,7 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): b = self.parent()(base) return sage.groups.generic.discrete_log(self, b) - def int_repr(FiniteField_givaroElement self): + def _int_repr(FiniteField_givaroElement self): r""" Return the string representation of ``self`` as an int (as returned by :meth:`log_to_int`). @@ -1532,12 +1538,14 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): sage: k. = GF(5^2); k Finite Field in b of size 5^2 - sage: (b+1).int_repr() + sage: (b+1)._int_repr() '6' """ return self._cache._element_int_repr(self) - def log_repr(FiniteField_givaroElement self): + int_repr = deprecated_function_alias(11295, _int_repr) + + def _log_repr(FiniteField_givaroElement self): r""" Return the log representation of ``self`` as a string. See the documentation of the ``_element_log_repr`` function of the @@ -1547,12 +1555,14 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): sage: k. = GF(5^2); k Finite Field in b of size 5^2 - sage: (b+2).log_repr() + sage: (b+2)._log_repr() '15' """ return self._cache._element_log_repr(self) - def poly_repr(FiniteField_givaroElement self): + log_repr = deprecated_function_alias(11295, _log_repr) + + def _poly_repr(FiniteField_givaroElement self): r""" Return representation of this finite field element as a polynomial in the generator. @@ -1561,11 +1571,13 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): sage: k. = GF(5^2); k Finite Field in b of size 5^2 - sage: (b+2).poly_repr() + sage: (b+2)._poly_repr() 'b + 2' """ return self._cache._element_poly_repr(self) + poly_repr = deprecated_function_alias(11295, _poly_repr) + def polynomial(FiniteField_givaroElement self, name=None): """ Return self viewed as a polynomial over @@ -1743,7 +1755,7 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): sage: hash(a) 5 """ - return hash(self.log_to_int()) + return hash(self.integer_representation()) def _vector_(FiniteField_givaroElement self, reverse=False): """ From 68c545a5edb07ea87adea5850a143195723dfced Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 26 Nov 2014 15:38:08 +0100 Subject: [PATCH 182/698] Fix bugs due to Python 2 int division --- src/sage/functions/exp_integral.py | 27 ++++++++++++++++----------- src/sage/functions/wigner.py | 24 +++++++++++++++++------- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/sage/functions/exp_integral.py b/src/sage/functions/exp_integral.py index 8bafb0d60ea..4c43657c566 100644 --- a/src/sage/functions/exp_integral.py +++ b/src/sage/functions/exp_integral.py @@ -42,18 +42,15 @@ #***************************************************************************** # Copyright (C) 2011 Benjamin Jones # -# Distributed under the terms of the GNU General Public License (GPL) -# -# This code is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# The full text of the GPL is available at: -# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** +from __future__ import division + from sage.symbolic.function import BuiltinFunction from sage.symbolic.expression import Expression from sage.structure.coerce import parent @@ -175,9 +172,15 @@ def _eval_(self, n, z): exp_integral_e(1.00000000000000, x) sage: exp_integral_e(x, 1.0) exp_integral_e(x, 1.00000000000000) - sage: exp_integral_e(1.0, 1.0) - 0.219383934395520 + sage: exp_integral_e(3, 0) + 1/2 + + TESTS: + + Check that Python ints work (:trac:`14766`):: + sage: exp_integral_e(int(3), 0) + 0.5 """ z_zero = False # special case: z == 0 and n > 1 @@ -212,6 +215,8 @@ def _evalf_(self, n, z, parent=None, algorithm=None): """ EXAMPLES:: + sage: exp_integral_e(1.0, 1.0) + 0.219383934395520 sage: N(exp_integral_e(1, 1+I)) 0.000281624451981418 - 0.179324535039359*I sage: exp_integral_e(1, RealField(100)(1)) diff --git a/src/sage/functions/wigner.py b/src/sage/functions/wigner.py index e71ccdf3087..04fa72830de 100644 --- a/src/sage/functions/wigner.py +++ b/src/sage/functions/wigner.py @@ -621,16 +621,24 @@ def gaunt(l_1, l_2, l_3, m_1, m_2, m_3, prec=None): sage: gaunt(1000,1000,1200,9,3,-12).n(64) 0.00689500421922113448 - It is an error to use non-integer values for `l` and `m`:: + If the sum of the `l_i` is odd, the answer is zero, even for Python + ints (see :trac:`14766`):: + + sage: gaunt(1,2,2,1,0,-1) + 0 + sage: gaunt(int(1),int(2),int(2),1,0,-1) + 0 + + It is an error to use non-integer values for `l` or `m`:: sage: gaunt(1.2,0,1.2,0,0,0) Traceback (most recent call last): ... - ValueError: l values must be integer + TypeError: Attempt to coerce non-integral RealNumber to Integer sage: gaunt(1,0,1,1.1,0,-1.1) Traceback (most recent call last): ... - ValueError: m values must be integer + TypeError: Attempt to coerce non-integral RealNumber to Integer NOTES: @@ -681,10 +689,12 @@ def gaunt(l_1, l_2, l_3, m_1, m_2, m_3, prec=None): - Jens Rasch (2009-03-24): initial version for Sage """ - if int(l_1) != l_1 or int(l_2) != l_2 or int(l_3) != l_3: - raise ValueError("l values must be integer") - if int(m_1) != m_1 or int(m_2) != m_2 or int(m_3) != m_3: - raise ValueError("m values must be integer") + l_1 = Integer(l_1) + l_2 = Integer(l_2) + l_3 = Integer(l_3) + m_1 = Integer(m_1) + m_2 = Integer(m_2) + m_3 = Integer(m_3) bigL = (l_1 + l_2 + l_3) / 2 a1 = l_1 + l_2 - l_3 From cf463b7e80c6d0d93d017a894d11275ce83c4427 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Wed, 26 Nov 2014 14:55:19 +0000 Subject: [PATCH 183/698] Fix doctest (and a typo) after new combinat doc merge. --- src/sage/misc/dev_tools.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/sage/misc/dev_tools.py b/src/sage/misc/dev_tools.py index 8e09e9f16de..03541ffaedb 100644 --- a/src/sage/misc/dev_tools.py +++ b/src/sage/misc/dev_tools.py @@ -156,10 +156,9 @@ def load_submodules(module=None, exclude_pattern=None): EXAMPLES:: sage: sage.misc.dev_tools.load_submodules(sage.combinat) - load sage.combinat.cluster_algebra_quiver.cluster_seed... suceeded - load sage.combinat.cluster_algebra_quiver.mutation_class... suceeded + load sage.combinat.algebraic_combinatorics... succeeded ... - load sage.combinat.words.suffix_trees... suceeded + load sage.combinat.words.suffix_trees... succeeded Calling a second time has no effect (since the function does not import modules already imported):: @@ -169,15 +168,15 @@ def load_submodules(module=None, exclude_pattern=None): The second argument allows to exclude a pattern:: sage: sage.misc.dev_tools.load_submodules(sage.geometry, "database$|lattice") - load sage.geometry.fan_isomorphism... suceeded - load sage.geometry.hyperplane_arrangement.affine_subspace... suceeded + load sage.geometry.fan_isomorphism... succeeded + load sage.geometry.hyperplane_arrangement.affine_subspace... succeeded ... - load sage.geometry.riemannian_manifolds.surface3d_generators... suceeded + load sage.geometry.riemannian_manifolds.surface3d_generators... succeeded sage: sage.misc.dev_tools.load_submodules(sage.geometry) - load sage.geometry.polyhedron.lattice_euclidean_group_element... suceeded - load sage.geometry.polyhedron.palp_database... suceeded - load sage.geometry.polyhedron.ppl_lattice_polygon... suceeded + load sage.geometry.polyhedron.lattice_euclidean_group_element... succeeded + load sage.geometry.polyhedron.palp_database... succeeded + load sage.geometry.polyhedron.ppl_lattice_polygon... succeeded """ import sys import pkgutil @@ -207,7 +206,7 @@ def load_submodules(module=None, exclude_pattern=None): sys.stdout.flush() loader = importer.find_module(module_name) loader.load_module(module_name) - sys.stdout.write(" suceeded\n") + sys.stdout.write(" succeeded\n") except (ValueError,AttributeError,TypeError,ImportError): # we might get error because of cython code that has been # compiled but with source removed @@ -456,8 +455,8 @@ def import_statements(*objects, **options): ValueError: no object matched by 'EnumeratedSetFromIterator' was found. sage: from sage.misc.dev_tools import load_submodules sage: load_submodules(sage.sets) - load sage.sets.cartesian_product... suceeded - load sage.sets.set_from_iterator... suceeded + load sage.sets.cartesian_product... succeeded + load sage.sets.set_from_iterator... succeeded sage: import_statements('EnumeratedSetFromIterator') from sage.sets.set_from_iterator import EnumeratedSetFromIterator From aef96aa6d74e18850b45fa2a84cb3cb335ad7947 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Wed, 26 Nov 2014 15:18:05 +0000 Subject: [PATCH 184/698] Use more usual ordering for source files in combinat module list. --- src/doc/en/reference/combinat/module_list.rst | 120 +++++++++--------- 1 file changed, 61 insertions(+), 59 deletions(-) diff --git a/src/doc/en/reference/combinat/module_list.rst b/src/doc/en/reference/combinat/module_list.rst index c3376951e5b..fdf85166dc0 100644 --- a/src/doc/en/reference/combinat/module_list.rst +++ b/src/doc/en/reference/combinat/module_list.rst @@ -3,19 +3,21 @@ Alphabetical module list .. NOTE:: - This can be updated semi-automatically by running in ``src/sage/combinat``:: + This can be updated semi-automatically by running in ``src/sage/combinat``:: - for x in **/*.py*; do echo " sage/combinat/$x"; done | perl -pe 's/\.pyx?$//' >! /tmp/module_list.rst + cd $SAGE_ROOT/src/sage/combinat + find -name "*.py*" | sed 's|\.py\?||; s|\./| sage/combinat/|' | LANG=en_US.UTF-8 LC_COLLATE=C sort >> $SAGE_ROOT/src/doc/en/reference/combinat/module_list.rst - and copy pasting the result back there. + and copy pasting the result back there. .. TODO:: - Improve this list by not flattening the module hierarchical structure. + Improve this list by not flattening the module hierarchical structure. .. toctree:: :maxdepth: 1 + sage/combinat/__init__ sage/combinat/abstract_tree sage/combinat/affine_permutation sage/combinat/algebraic_combinatorics @@ -27,31 +29,32 @@ Alphabetical module list sage/combinat/cartesian_product sage/combinat/catalog_partitions sage/combinat/choose_nk + sage/combinat/cluster_algebra_quiver/__init__ sage/combinat/cluster_algebra_quiver/all sage/combinat/cluster_algebra_quiver/cluster_seed - sage/combinat/cluster_algebra_quiver/__init__ sage/combinat/cluster_algebra_quiver/mutation_class sage/combinat/cluster_algebra_quiver/mutation_type - sage/combinat/cluster_algebra_quiver/quiver_mutation_type sage/combinat/cluster_algebra_quiver/quiver - sage/combinat/combinat_cython + sage/combinat/cluster_algebra_quiver/quiver_mutation_type + sage/combinat/combinat + sage/combinat/combinat_cythonx sage/combinat/combination sage/combinat/combinatorial_algebra sage/combinat/combinatorial_map - sage/combinat/combinat sage/combinat/composition sage/combinat/composition_signed sage/combinat/composition_tableau sage/combinat/core sage/combinat/counting - sage/combinat/crystals/affine_factorization + sage/combinat/crystals/__init__ sage/combinat/crystals/affine + sage/combinat/crystals/affine_factorization sage/combinat/crystals/alcove_path sage/combinat/crystals/all + sage/combinat/crystals/catalog sage/combinat/crystals/catalog_elementary_crystals sage/combinat/crystals/catalog_infinity_crystals sage/combinat/crystals/catalog_kirillov_reshetikhin - sage/combinat/crystals/catalog sage/combinat/crystals/crystals sage/combinat/crystals/direct_sum sage/combinat/crystals/elementary_crystals @@ -59,125 +62,123 @@ Alphabetical module list sage/combinat/crystals/generalized_young_walls sage/combinat/crystals/highest_weight_crystals sage/combinat/crystals/infinity_crystals - sage/combinat/crystals/__init__ sage/combinat/crystals/kirillov_reshetikhin sage/combinat/crystals/kyoto_path_model - sage/combinat/crystals/letters + sage/combinat/crystals/lettersx sage/combinat/crystals/littelmann_path sage/combinat/crystals/monomial_crystals sage/combinat/crystals/spins sage/combinat/crystals/tensor_product sage/combinat/cyclic_sieving_phenomenon - sage/combinat/debruijn_sequence - sage/combinat/degree_sequences + sage/combinat/debruijn_sequencex + sage/combinat/degree_sequencesx sage/combinat/derangements sage/combinat/descent_algebra + sage/combinat/designs/__init__ sage/combinat/designs/all sage/combinat/designs/bibd sage/combinat/designs/block_design sage/combinat/designs/covering_design sage/combinat/designs/database sage/combinat/designs/design_catalog - sage/combinat/designs/designs_pyx + sage/combinat/designs/designs_pyxx sage/combinat/designs/difference_family sage/combinat/designs/difference_matrices sage/combinat/designs/ext_rep sage/combinat/designs/incidence_structures - sage/combinat/designs/__init__ sage/combinat/designs/latin_squares sage/combinat/designs/orthogonal_arrays sage/combinat/designs/orthogonal_arrays_build_recursive - sage/combinat/designs/orthogonal_arrays_find_recursive + sage/combinat/designs/orthogonal_arrays_find_recursivex sage/combinat/designs/steiner_quadruple_systems sage/combinat/diagram_algebras - sage/combinat/dict_addition + sage/combinat/dict_additionx sage/combinat/dlx sage/combinat/dyck_word - sage/combinat/enumerated_sets - sage/combinat/enumeration_mod_permgroup sage/combinat/e_one_star - sage/combinat/expnums + sage/combinat/enumerated_sets + sage/combinat/enumeration_mod_permgroupx + sage/combinat/expnumsx sage/combinat/family sage/combinat/finite_class - sage/combinat/finite_state_machine_generators sage/combinat/finite_state_machine + sage/combinat/finite_state_machine_generators sage/combinat/free_module sage/combinat/gelfand_tsetlin_patterns sage/combinat/graph_path sage/combinat/gray_codes sage/combinat/hall_polynomial - sage/combinat/__init__ sage/combinat/integer_list sage/combinat/integer_matrices sage/combinat/integer_vector - sage/combinat/integer_vectors_mod_permgroup sage/combinat/integer_vector_weighted + sage/combinat/integer_vectors_mod_permgroup sage/combinat/interval_posets + sage/combinat/k_tableau sage/combinat/kazhdan_lusztig sage/combinat/knutson_tao_puzzles - sage/combinat/k_tableau sage/combinat/lyndon_word + sage/combinat/matrices/__init__ sage/combinat/matrices/all - sage/combinat/matrices/dancing_links + sage/combinat/matrices/dancing_linksx sage/combinat/matrices/dlxcpp sage/combinat/matrices/hadamard_matrix - sage/combinat/matrices/__init__ sage/combinat/matrices/latin sage/combinat/misc sage/combinat/multichoose_nk + sage/combinat/ncsf_qsym/__init__ sage/combinat/ncsf_qsym/all sage/combinat/ncsf_qsym/combinatorics sage/combinat/ncsf_qsym/generic_basis_code - sage/combinat/ncsf_qsym/__init__ sage/combinat/ncsf_qsym/ncsf sage/combinat/ncsf_qsym/qsym sage/combinat/ncsf_qsym/tutorial + sage/combinat/ncsym/__init__ sage/combinat/ncsym/all sage/combinat/ncsym/bases sage/combinat/ncsym/dual - sage/combinat/ncsym/__init__ sage/combinat/ncsym/ncsym sage/combinat/necklace sage/combinat/non_decreasing_parking_function sage/combinat/ordered_tree sage/combinat/output sage/combinat/parking_functions - sage/combinat/partition_algebra sage/combinat/partition - sage/combinat/partitions + sage/combinat/partition_algebra sage/combinat/partition_tuple + sage/combinat/partitionsx sage/combinat/perfect_matching - sage/combinat/permutation_cython - sage/combinat/permutation_nk sage/combinat/permutation + sage/combinat/permutation_cythonx + sage/combinat/permutation_nk + sage/combinat/posets/__init__ sage/combinat/posets/all sage/combinat/posets/elements sage/combinat/posets/hasse_diagram - sage/combinat/posets/__init__ sage/combinat/posets/lattices sage/combinat/posets/linear_extensions sage/combinat/posets/poset_examples sage/combinat/posets/posets sage/combinat/q_analogues - sage/combinat/q_bernoulli + sage/combinat/q_bernoullix sage/combinat/quickref sage/combinat/ranker sage/combinat/restricted_growth sage/combinat/ribbon sage/combinat/ribbon_shaped_tableau sage/combinat/ribbon_tableau + sage/combinat/rigged_configurations/__init__ sage/combinat/rigged_configurations/all sage/combinat/rigged_configurations/bij_abstract_class - sage/combinat/rigged_configurations/bijection + sage/combinat/rigged_configurations/bij_type_A sage/combinat/rigged_configurations/bij_type_A2_dual sage/combinat/rigged_configurations/bij_type_A2_even sage/combinat/rigged_configurations/bij_type_A2_odd - sage/combinat/rigged_configurations/bij_type_A sage/combinat/rigged_configurations/bij_type_B sage/combinat/rigged_configurations/bij_type_C sage/combinat/rigged_configurations/bij_type_D sage/combinat/rigged_configurations/bij_type_D_twisted - sage/combinat/rigged_configurations/__init__ + sage/combinat/rigged_configurations/bijection sage/combinat/rigged_configurations/kleber_tree sage/combinat/rigged_configurations/kr_tableaux sage/combinat/rigged_configurations/rc_crystal @@ -185,8 +186,9 @@ Alphabetical module list sage/combinat/rigged_configurations/rigged_configuration_element sage/combinat/rigged_configurations/rigged_configurations sage/combinat/rigged_configurations/rigged_partition - sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element sage/combinat/rigged_configurations/tensor_product_kr_tableaux + sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element + sage/combinat/root_system/__init__ sage/combinat/root_system/all sage/combinat/root_system/ambient_space sage/combinat/root_system/associahedron @@ -197,7 +199,6 @@ Alphabetical module list sage/combinat/root_system/coxeter_matrix sage/combinat/root_system/dynkin_diagram sage/combinat/root_system/hecke_algebra_representation - sage/combinat/root_system/__init__ sage/combinat/root_system/non_symmetric_macdonald_polynomials sage/combinat/root_system/pieri_factors sage/combinat/root_system/plot @@ -205,26 +206,26 @@ Alphabetical module list sage/combinat/root_system/root_lattice_realizations sage/combinat/root_system/root_space sage/combinat/root_system/root_system - sage/combinat/root_system/type_A_affine - sage/combinat/root_system/type_affine sage/combinat/root_system/type_A - sage/combinat/root_system/type_B_affine - sage/combinat/root_system/type_BC_affine + sage/combinat/root_system/type_A_affine sage/combinat/root_system/type_B - sage/combinat/root_system/type_C_affine + sage/combinat/root_system/type_BC_affine + sage/combinat/root_system/type_B_affine sage/combinat/root_system/type_C - sage/combinat/root_system/type_D_affine + sage/combinat/root_system/type_C_affine sage/combinat/root_system/type_D - sage/combinat/root_system/type_dual - sage/combinat/root_system/type_E_affine + sage/combinat/root_system/type_D_affine sage/combinat/root_system/type_E - sage/combinat/root_system/type_F_affine - sage/combinat/root_system/type_folded + sage/combinat/root_system/type_E_affine sage/combinat/root_system/type_F - sage/combinat/root_system/type_G_affine + sage/combinat/root_system/type_F_affine sage/combinat/root_system/type_G + sage/combinat/root_system/type_G_affine sage/combinat/root_system/type_H sage/combinat/root_system/type_I + sage/combinat/root_system/type_affine + sage/combinat/root_system/type_dual + sage/combinat/root_system/type_folded sage/combinat/root_system/type_marked sage/combinat/root_system/type_reducible sage/combinat/root_system/type_relabel @@ -234,15 +235,15 @@ Alphabetical module list sage/combinat/root_system/weyl_group sage/combinat/rsk sage/combinat/schubert_polynomial - sage/combinat/set_partition_ordered sage/combinat/set_partition + sage/combinat/set_partition_ordered + sage/combinat/sf/__init__ sage/combinat/sf/all sage/combinat/sf/classical sage/combinat/sf/dual sage/combinat/sf/elementary sage/combinat/sf/hall_littlewood sage/combinat/sf/homogeneous - sage/combinat/sf/__init__ sage/combinat/sf/jack sage/combinat/sf/k_dual sage/combinat/sf/kfpoly @@ -255,8 +256,8 @@ Alphabetical module list sage/combinat/sf/orthotriang sage/combinat/sf/powersum sage/combinat/sf/schur - sage/combinat/sf/sfa sage/combinat/sf/sf + sage/combinat/sf/sfa sage/combinat/sf/witt sage/combinat/shuffle sage/combinat/sidon_sets @@ -265,6 +266,7 @@ Alphabetical module list sage/combinat/skew_partition sage/combinat/skew_tableau sage/combinat/sloane_functions + sage/combinat/species/__init__ sage/combinat/species/all sage/combinat/species/characteristic_species sage/combinat/species/combinatorial_logarithm @@ -273,7 +275,6 @@ Alphabetical module list sage/combinat/species/empty_species sage/combinat/species/functorial_composition_species sage/combinat/species/generating_series - sage/combinat/species/__init__ sage/combinat/species/library sage/combinat/species/linear_order_species sage/combinat/species/misc @@ -281,8 +282,8 @@ Alphabetical module list sage/combinat/species/permutation_species sage/combinat/species/product_species sage/combinat/species/recursive_species - sage/combinat/species/series_order sage/combinat/species/series + sage/combinat/species/series_order sage/combinat/species/set_species sage/combinat/species/species sage/combinat/species/stream @@ -304,20 +305,21 @@ Alphabetical module list sage/combinat/tuple sage/combinat/tutorial sage/combinat/vector_partition + sage/combinat/words/__init__ sage/combinat/words/abstract_word sage/combinat/words/all sage/combinat/words/alphabet sage/combinat/words/finite_word sage/combinat/words/infinite_word - sage/combinat/words/__init__ sage/combinat/words/morphism sage/combinat/words/paths sage/combinat/words/shuffle_product sage/combinat/words/suffix_trees - sage/combinat/words/word_datatypes + sage/combinat/words/word + sage/combinat/words/word_charx + sage/combinat/words/word_datatypesx sage/combinat/words/word_generators sage/combinat/words/word_infinite_datatypes sage/combinat/words/word_options - sage/combinat/words/word sage/combinat/words/words sage/combinat/yang_baxter_graph From bce4fb0c1665025c98ec15d89c1345a0a67e925c Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 26 Nov 2014 15:45:48 +0100 Subject: [PATCH 185/698] Use mpfr for Bessel functions if possible --- src/sage/functions/bessel.py | 46 ++++++++++++++++++++++++++++++- src/sage/libs/mpmath/ext_impl.pyx | 18 +++++++++--- src/sage/rings/real_mpfr.pyx | 4 +-- 3 files changed, 61 insertions(+), 7 deletions(-) diff --git a/src/sage/functions/bessel.py b/src/sage/functions/bessel.py index d9c4b677f7e..8df019aaa68 100644 --- a/src/sage/functions/bessel.py +++ b/src/sage/functions/bessel.py @@ -308,10 +308,32 @@ def _evalf_(self, n, x, parent=None, algorithm=None): EXAMPLES:: sage: bessel_J(0.0, 1.0) - 0.765197686557966 + 0.765197686557967 sage: bessel_J(0, 1).n(digits=20) 0.76519768655796655145 + sage: bessel_J(0.5, 1.5) + 0.649838074753747 + + Check for correct rounding (:trac:`17122`):: + + sage: R = RealField(113) + sage: a = R("8.935761195587725798762818805462843676e-01") + sage: aa = RealField(200)(a) + sage: for n in [-10..10]: + ....: b = bessel_J(R(n), a) + ....: bb = R(bessel_J(n, aa)) + ....: if b != bb: + ....: print n, b-bb """ + if parent is not None: + x = parent(x) + + try: + return x.jn(Integer(n)) + except Exception: + pass + + n, x = get_coercion_model().canonical_coercion(n, x) import mpmath return mpmath_utils.call(mpmath.besselj, n, x, parent=parent) @@ -457,11 +479,33 @@ def _evalf_(self, n, x, parent=None, algorithm=None): """ EXAMPLES:: + sage: bessel_Y(0.5, 1.5) + -0.0460831658930974 sage: bessel_Y(1.0+2*I, 3.0+4*I) 0.699410324467538 + 0.228917940896421*I sage: bessel_Y(0, 1).n(256) 0.08825696421567695798292676602351516282781752309067554671104384761199978932351 + + Check for correct rounding (:trac:`17122`):: + + sage: R = RealField(113) + sage: a = R("8.935761195587725798762818805462843676e-01") + sage: aa = RealField(200)(a) + sage: for n in [-10..10]: + ....: b = bessel_Y(R(n), a) + ....: bb = R(bessel_Y(n, aa)) + ....: if b != bb: + ....: print n, b-bb """ + if parent is not None: + x = parent(x) + + try: + return x.yn(Integer(n)) + except Exception: + pass + + n, x = get_coercion_model().canonical_coercion(n, x) import mpmath return mpmath_utils.call(mpmath.bessely, n, x, parent=parent) diff --git a/src/sage/libs/mpmath/ext_impl.pyx b/src/sage/libs/mpmath/ext_impl.pyx index fffe558d054..adddb23caae 100644 --- a/src/sage/libs/mpmath/ext_impl.pyx +++ b/src/sage/libs/mpmath/ext_impl.pyx @@ -25,10 +25,8 @@ from cpython.float cimport * from cpython.complex cimport * from cpython.number cimport * -cdef extern from "math.h": - cdef double fpow "pow" (double, double) - cdef double fsqrt "sqrt" (double) - cdef double frexp "frexp" (double, int*) +from libc.math cimport sqrt as fsqrt +from libc.math cimport frexp from sage.libs.gmp.all cimport * from sage.libs.mpfr cimport * @@ -1147,6 +1145,7 @@ cdef cy_exp_basecase(mpz_t y, mpz_t x, int prec): mpz_fdiv_q_2exp(x2, x2, prec) mpz_set(a, x2) while mpz_sgn(a): + sig_check() mpz_fdiv_q_ui(a, a, k) mpz_add(s0, s0, a) k += 1 @@ -1160,6 +1159,7 @@ cdef cy_exp_basecase(mpz_t y, mpz_t x, int prec): mpz_add(s0, s0, s1) u = r while r: + sig_check() mpz_mul(s0, s0, s0) mpz_fdiv_q_2exp(s0, s0, prec) r -= 1 @@ -2037,6 +2037,7 @@ cdef MPF_hypsum(MPF *a, MPF *b, int p, int q, param_types, str ztype, coeffs, z, else: mpz_set_tuple_fixed(ZRE, z, wp) for i in range(0,p): + sig_check() if param_types[i] == 'Z': mpz_init(AINT[aint]) mpz_set_integer(AINT[aint], coeffs[i]) @@ -2060,6 +2061,7 @@ cdef MPF_hypsum(MPF *a, MPF *b, int p, int q, param_types, str ztype, coeffs, z, else: raise ValueError for i in range(p,p+q): + sig_check() if param_types[i] == 'Z': mpz_init(BINT[bint]) mpz_set_integer(BINT[bint], coeffs[i]) @@ -2113,22 +2115,28 @@ cdef MPF_hypsum(MPF *a, MPF *b, int p, int q, param_types, str ztype, coeffs, z, # Multiply real factors for k in range(0, cancellable_real): + sig_check() mpz_mul(PRE, PRE, AREAL[k]) mpz_fdiv_q(PRE, PRE, BREAL[k]) for k in range(cancellable_real, areal): + sig_check() mpz_mul(PRE, PRE, AREAL[k]) mpz_fdiv_q_2exp(PRE, PRE, wp) for k in range(cancellable_real, breal): + sig_check() mpz_mul_2exp(PRE, PRE, wp) mpz_fdiv_q(PRE, PRE, BREAL[k]) if have_complex: for k in range(0, cancellable_real): + sig_check() mpz_mul(PIM, PIM, AREAL[k]) mpz_fdiv_q(PIM, PIM, BREAL[k]) for k in range(cancellable_real, areal): + sig_check() mpz_mul(PIM, PIM, AREAL[k]) mpz_fdiv_q_2exp(PIM, PIM, wp) for k in range(cancellable_real, breal): + sig_check() mpz_mul_2exp(PIM, PIM, wp) mpz_fdiv_q(PIM, PIM, BREAL[k]) @@ -2162,6 +2170,7 @@ cdef MPF_hypsum(MPF *a, MPF *b, int p, int q, param_types, str ztype, coeffs, z, mpz_fdiv_q(PIM, PIM, DIV) for i in range(acomplex): + sig_check() mpz_mul(TRE, PRE, ACRE[i]) mpz_submul(TRE, PIM, ACIM[i]) mpz_mul(TIM, PIM, ACRE[i]) @@ -2170,6 +2179,7 @@ cdef MPF_hypsum(MPF *a, MPF *b, int p, int q, param_types, str ztype, coeffs, z, mpz_fdiv_q_2exp(PIM, TIM, wp) for i in range(bcomplex): + sig_check() mpz_mul(URE, BCRE[i], BCRE[i]) mpz_addmul(URE, BCIM[i], BCIM[i]) mpz_mul(TRE, PRE, BCRE[i]) diff --git a/src/sage/rings/real_mpfr.pyx b/src/sage/rings/real_mpfr.pyx index 14c6f809e5a..42d09fb96d8 100644 --- a/src/sage/rings/real_mpfr.pyx +++ b/src/sage/rings/real_mpfr.pyx @@ -3769,7 +3769,7 @@ cdef class RealNumber(sage.structure.element.RingElement): def is_integer(self): """ - Return ``True`` if this number is a integer + Return ``True`` if this number is a integer. EXAMPLES:: @@ -3778,7 +3778,7 @@ cdef class RealNumber(sage.structure.element.RingElement): sage: RR(0.1).is_integer() False """ - return self in ZZ + return mpfr_integer_p(self.value) != 0 def __nonzero__(self): """ From c8c26e1ca6195841b5bd1bb900a33eef3bb30b60 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 26 Nov 2014 17:23:57 +0100 Subject: [PATCH 186/698] Convert Ginac function results to the correct parent --- src/sage/symbolic/function.pyx | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/sage/symbolic/function.pyx b/src/sage/symbolic/function.pyx index 70cd1c5d40a..53616f7098b 100644 --- a/src/sage/symbolic/function.pyx +++ b/src/sage/symbolic/function.pyx @@ -15,6 +15,7 @@ Classes for symbolic functions from ginac cimport * +from sage.rings.integer cimport smallInteger from sage.structure.sage_object cimport SageObject from expression cimport new_Expression_from_GEx, Expression from ring import SR @@ -809,6 +810,46 @@ cdef class GinacFunction(BuiltinFunction): BuiltinFunction.__init__(self, name, nargs, latex_name, conversions, evalf_params_first=evalf_params_first) + def __call__(self, *args, **kwds): + """ + Wrapper around ``BuiltinFunction.__call__()`` which converts + Python ``int``s which are returned by Ginac to Sage Integers. + + This is needed to fix :trac:`10133`, where Ginac evaluates + ``sin(0)`` to the Python int ``0``:: + + sage: from sage.symbolic.function import BuiltinFunction + sage: out = BuiltinFunction.__call__(sin, 0) + sage: out, parent(out) + (0, ) + + With this wrapper we have:: + + sage: out = sin(0) + sage: out, parent(out) + (0, Integer Ring) + + However, if all inputs are Python types, we do not convert:: + + sage: out = sin(int(0)) + sage: (out, parent(out)) + (0, ) + sage: out = arctan2(int(0), float(1)) + sage: (out, parent(out)) + (0, ) + sage: out = arctan2(int(0), RR(1)) + sage: (out, parent(out)) + (0, Integer Ring) + """ + res = super(GinacFunction, self).__call__(*args, **kwds) + + # Convert to Integer if the output was of type "int" and any of + # the inputs was a Sage Element + if isinstance(res, int) and any(isinstance(x, Element) for x in args): + return smallInteger(res) + else: + return res + cdef _is_registered(self): # Since this is function is defined in C++, it is already in # ginac's function registry From d365921d1bc4f3befd402cff0e65d48604382b63 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Wed, 26 Nov 2014 21:50:19 +0000 Subject: [PATCH 187/698] Do not pretend th module list in combinat doc is in alphabetical order. --- src/doc/en/reference/combinat/module_list.rst | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/doc/en/reference/combinat/module_list.rst b/src/doc/en/reference/combinat/module_list.rst index fdf85166dc0..15ec3e72f13 100644 --- a/src/doc/en/reference/combinat/module_list.rst +++ b/src/doc/en/reference/combinat/module_list.rst @@ -1,18 +1,22 @@ -Alphabetical module list -======================== +Module list +=========== + +.. NOTE:: + + This list is currently sorted in alphabetical order using the source files names. .. NOTE:: This can be updated semi-automatically by running in ``src/sage/combinat``:: - cd $SAGE_ROOT/src/sage/combinat - find -name "*.py*" | sed 's|\.py\?||; s|\./| sage/combinat/|' | LANG=en_US.UTF-8 LC_COLLATE=C sort >> $SAGE_ROOT/src/doc/en/reference/combinat/module_list.rst + find -name "*.py*" | sed 's|\.pyx\?$||; s|\./| sage/combinat/|' | LANG=en_US.UTF-8 LC_COLLATE=C sort > /tmp/module_list.rst and copy pasting the result back there. .. TODO:: - Improve this list by not flattening the module hierarchical structure. + Improve this list by sorting it in alphabetical order using the titles generated by Sphinx + and by not flattening the module hierarchical structure. .. toctree:: :maxdepth: 1 @@ -37,7 +41,7 @@ Alphabetical module list sage/combinat/cluster_algebra_quiver/quiver sage/combinat/cluster_algebra_quiver/quiver_mutation_type sage/combinat/combinat - sage/combinat/combinat_cythonx + sage/combinat/combinat_cython sage/combinat/combination sage/combinat/combinatorial_algebra sage/combinat/combinatorial_map @@ -64,14 +68,14 @@ Alphabetical module list sage/combinat/crystals/infinity_crystals sage/combinat/crystals/kirillov_reshetikhin sage/combinat/crystals/kyoto_path_model - sage/combinat/crystals/lettersx + sage/combinat/crystals/letters sage/combinat/crystals/littelmann_path sage/combinat/crystals/monomial_crystals sage/combinat/crystals/spins sage/combinat/crystals/tensor_product sage/combinat/cyclic_sieving_phenomenon - sage/combinat/debruijn_sequencex - sage/combinat/degree_sequencesx + sage/combinat/debruijn_sequence + sage/combinat/degree_sequences sage/combinat/derangements sage/combinat/descent_algebra sage/combinat/designs/__init__ @@ -81,7 +85,7 @@ Alphabetical module list sage/combinat/designs/covering_design sage/combinat/designs/database sage/combinat/designs/design_catalog - sage/combinat/designs/designs_pyxx + sage/combinat/designs/designs_pyx sage/combinat/designs/difference_family sage/combinat/designs/difference_matrices sage/combinat/designs/ext_rep @@ -89,16 +93,16 @@ Alphabetical module list sage/combinat/designs/latin_squares sage/combinat/designs/orthogonal_arrays sage/combinat/designs/orthogonal_arrays_build_recursive - sage/combinat/designs/orthogonal_arrays_find_recursivex + sage/combinat/designs/orthogonal_arrays_find_recursive sage/combinat/designs/steiner_quadruple_systems sage/combinat/diagram_algebras - sage/combinat/dict_additionx + sage/combinat/dict_addition sage/combinat/dlx sage/combinat/dyck_word sage/combinat/e_one_star sage/combinat/enumerated_sets - sage/combinat/enumeration_mod_permgroupx - sage/combinat/expnumsx + sage/combinat/enumeration_mod_permgroup + sage/combinat/expnums sage/combinat/family sage/combinat/finite_class sage/combinat/finite_state_machine @@ -120,7 +124,7 @@ Alphabetical module list sage/combinat/lyndon_word sage/combinat/matrices/__init__ sage/combinat/matrices/all - sage/combinat/matrices/dancing_linksx + sage/combinat/matrices/dancing_links sage/combinat/matrices/dlxcpp sage/combinat/matrices/hadamard_matrix sage/combinat/matrices/latin @@ -146,10 +150,10 @@ Alphabetical module list sage/combinat/partition sage/combinat/partition_algebra sage/combinat/partition_tuple - sage/combinat/partitionsx + sage/combinat/partitions sage/combinat/perfect_matching sage/combinat/permutation - sage/combinat/permutation_cythonx + sage/combinat/permutation_cython sage/combinat/permutation_nk sage/combinat/posets/__init__ sage/combinat/posets/all @@ -160,7 +164,7 @@ Alphabetical module list sage/combinat/posets/poset_examples sage/combinat/posets/posets sage/combinat/q_analogues - sage/combinat/q_bernoullix + sage/combinat/q_bernoulli sage/combinat/quickref sage/combinat/ranker sage/combinat/restricted_growth @@ -316,8 +320,8 @@ Alphabetical module list sage/combinat/words/shuffle_product sage/combinat/words/suffix_trees sage/combinat/words/word - sage/combinat/words/word_charx - sage/combinat/words/word_datatypesx + sage/combinat/words/word_char + sage/combinat/words/word_datatypes sage/combinat/words/word_generators sage/combinat/words/word_infinite_datatypes sage/combinat/words/word_options From 06d581f3566243970190e4898eaa3ab94e1a6e15 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Wed, 26 Nov 2014 21:58:34 +0000 Subject: [PATCH 188/698] Fix links from combinat doc to thematic tutorials. --- src/sage/combinat/algebraic_combinatorics.py | 6 +++--- src/sage/combinat/crystals/__init__.py | 2 +- src/sage/combinat/root_system/__init__.py | 2 +- src/sage/combinat/sf/sf.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/combinat/algebraic_combinatorics.py b/src/sage/combinat/algebraic_combinatorics.py index 152fe358b83..e6c5086050d 100644 --- a/src/sage/combinat/algebraic_combinatorics.py +++ b/src/sage/combinat/algebraic_combinatorics.py @@ -12,9 +12,9 @@ .. TODO:: get Sphinx to create those cross links properly -- `Algebraic Combinatorics in Sage <../../../../thematic_tutorials/algebraic_combinatorics.html>`_ -- `Lie Methods and Related Combinatorics in Sage <../../../../thematic_tutorials/lie.html>`_ -- `Linear Programming (Mixed Integer) <../../../../thematic_tutorials/linear_programming.html>`_ +- `Algebraic Combinatorics in Sage <../../../../../thematic_tutorials/algebraic_combinatorics.html>`_ +- `Lie Methods and Related Combinatorics in Sage <../../../../../thematic_tutorials/lie.html>`_ +- `Linear Programming (Mixed Integer) <../../../../../thematic_tutorials/linear_programming.html>`_ Enumerated sets of combinatorial objects ---------------------------------------- diff --git a/src/sage/combinat/crystals/__init__.py b/src/sage/combinat/crystals/__init__.py index 694eb1a519c..f26dcdc1f20 100644 --- a/src/sage/combinat/crystals/__init__.py +++ b/src/sage/combinat/crystals/__init__.py @@ -11,7 +11,7 @@ --------------------- - :ref:`sage.combinat.crystals.crystals` -- The `Lie Methods and Related Combinatorics <../../../../thematic_tutorials/lie.html>`_ thematic tutorial +- The `Lie Methods and Related Combinatorics <../../../../../thematic_tutorials/lie.html>`_ thematic tutorial Catalogs of crystals -------------------- diff --git a/src/sage/combinat/root_system/__init__.py b/src/sage/combinat/root_system/__init__.py index 4d0eadd76a9..f7408099868 100644 --- a/src/sage/combinat/root_system/__init__.py +++ b/src/sage/combinat/root_system/__init__.py @@ -20,7 +20,7 @@ - :class:`RootSystem` -- An introduction to root systems - :ref:`sage.combinat.root_system.plot` -- A root system visualization tutorial -- The `Lie Methods and Related Combinatorics <../../../../thematic_tutorials/lie.html>`_ thematic tutorial +- The `Lie Methods and Related Combinatorics <../../../../../thematic_tutorials/lie.html>`_ thematic tutorial Related material diff --git a/src/sage/combinat/sf/sf.py b/src/sage/combinat/sf/sf.py index 867259bc377..0970b9f39b4 100644 --- a/src/sage/combinat/sf/sf.py +++ b/src/sage/combinat/sf/sf.py @@ -267,7 +267,7 @@ class SymmetricFunctions(UniqueRepresentation, Parent): and restriction, respectively. The Schur functions can also be interpreted as characters of `GL_n`, see `Partitions and Schur functions`__. - __ ../../../../thematic_tutorials/lie/lie_basics.html#partitions-and-schur-polynomials + __ ../../../../../thematic_tutorials/lie/lie_basics.html#partitions-and-schur-polynomials .. rubric:: The omega involution From 7b753a2c64af971fc37d1fffa8f95e6fac1e0438 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Thu, 27 Nov 2014 14:07:16 +0000 Subject: [PATCH 189/698] Revert "Fix links from combinat doc to thematic tutorials." This reverts commit 06d581f3566243970190e4898eaa3ab94e1a6e15. --- src/sage/combinat/algebraic_combinatorics.py | 6 +++--- src/sage/combinat/crystals/__init__.py | 2 +- src/sage/combinat/root_system/__init__.py | 2 +- src/sage/combinat/sf/sf.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/combinat/algebraic_combinatorics.py b/src/sage/combinat/algebraic_combinatorics.py index e6c5086050d..152fe358b83 100644 --- a/src/sage/combinat/algebraic_combinatorics.py +++ b/src/sage/combinat/algebraic_combinatorics.py @@ -12,9 +12,9 @@ .. TODO:: get Sphinx to create those cross links properly -- `Algebraic Combinatorics in Sage <../../../../../thematic_tutorials/algebraic_combinatorics.html>`_ -- `Lie Methods and Related Combinatorics in Sage <../../../../../thematic_tutorials/lie.html>`_ -- `Linear Programming (Mixed Integer) <../../../../../thematic_tutorials/linear_programming.html>`_ +- `Algebraic Combinatorics in Sage <../../../../thematic_tutorials/algebraic_combinatorics.html>`_ +- `Lie Methods and Related Combinatorics in Sage <../../../../thematic_tutorials/lie.html>`_ +- `Linear Programming (Mixed Integer) <../../../../thematic_tutorials/linear_programming.html>`_ Enumerated sets of combinatorial objects ---------------------------------------- diff --git a/src/sage/combinat/crystals/__init__.py b/src/sage/combinat/crystals/__init__.py index f26dcdc1f20..694eb1a519c 100644 --- a/src/sage/combinat/crystals/__init__.py +++ b/src/sage/combinat/crystals/__init__.py @@ -11,7 +11,7 @@ --------------------- - :ref:`sage.combinat.crystals.crystals` -- The `Lie Methods and Related Combinatorics <../../../../../thematic_tutorials/lie.html>`_ thematic tutorial +- The `Lie Methods and Related Combinatorics <../../../../thematic_tutorials/lie.html>`_ thematic tutorial Catalogs of crystals -------------------- diff --git a/src/sage/combinat/root_system/__init__.py b/src/sage/combinat/root_system/__init__.py index f7408099868..4d0eadd76a9 100644 --- a/src/sage/combinat/root_system/__init__.py +++ b/src/sage/combinat/root_system/__init__.py @@ -20,7 +20,7 @@ - :class:`RootSystem` -- An introduction to root systems - :ref:`sage.combinat.root_system.plot` -- A root system visualization tutorial -- The `Lie Methods and Related Combinatorics <../../../../../thematic_tutorials/lie.html>`_ thematic tutorial +- The `Lie Methods and Related Combinatorics <../../../../thematic_tutorials/lie.html>`_ thematic tutorial Related material diff --git a/src/sage/combinat/sf/sf.py b/src/sage/combinat/sf/sf.py index 0970b9f39b4..867259bc377 100644 --- a/src/sage/combinat/sf/sf.py +++ b/src/sage/combinat/sf/sf.py @@ -267,7 +267,7 @@ class SymmetricFunctions(UniqueRepresentation, Parent): and restriction, respectively. The Schur functions can also be interpreted as characters of `GL_n`, see `Partitions and Schur functions`__. - __ ../../../../../thematic_tutorials/lie/lie_basics.html#partitions-and-schur-polynomials + __ ../../../../thematic_tutorials/lie/lie_basics.html#partitions-and-schur-polynomials .. rubric:: The omega involution From 48345733408db3721c5bbeba3031b2f4c0673492 Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Sun, 30 Nov 2014 16:46:36 +0530 Subject: [PATCH 190/698] trac #17227: Reviewer's commit --- src/sage/graphs/hyperbolicity.pyx | 181 ++++++++++++++++-------------- 1 file changed, 94 insertions(+), 87 deletions(-) diff --git a/src/sage/graphs/hyperbolicity.pyx b/src/sage/graphs/hyperbolicity.pyx index 566bb10dab3..e483ddd7176 100644 --- a/src/sage/graphs/hyperbolicity.pyx +++ b/src/sage/graphs/hyperbolicity.pyx @@ -98,13 +98,17 @@ Hyperbolicity - The notion of ''far-apart pairs'' has been introduced in [Soto11]_ to further reduce the number of 4-tuples to consider. We say that the pair `(a,b)` is far-apart if for every `w` in `V\setminus\{a,b\}` we have - `dist(w,a)+dist(a,b) > dist(w,b)` and `dist(w,b)+dist(a,b) > dist(w,a)`, - and determining the set of far-apart pairs can be done in time `O(nm)` - using BFS. Now, it is proved in [Soto11]_ that there exists two far-apart - pairs `(a,b)` and `(c,d)` satisfying `\delta(G) = hyp(a, b, c, d)/2`. For - instance, the `n\times m`-grid has only two far-apart pairs, and so - computing its hyperbolicity is immediate. + .. MATH:: + + dist(w,a)+dist(a,b) > dist(w,b) \text{ and }dist(w,b)+dist(a,b) > dist(w,a) + + Determining the set of far-apart pairs can be done in time `O(nm)` using + BFS. Now, it is proved in [Soto11]_ that there exists two far-apart pairs + `(a,b)` and `(c,d)` satisfying `\delta(G) = hyp(a, b, c, d)/2`. For + instance, the `n\times m`-grid has only two far-apart pairs, and so + computing its hyperbolicity is immediate once the far-apart pairs are + found. TODO: @@ -276,8 +280,9 @@ cdef tuple __hyperbolicity_basic_algorithm__(int N, Returns **twice** the hyperbolicity of a graph, and a certificate. This method implements the basic algorithm for computing the hyperbolicity - of a graph, that is iterating over all 4-tuples, with a cutting rule - proposed in [Soto11]_. See the module's documentation for more details. + of a graph which tests all `\binom n 4` 4-tuples of vertices. It can + optionally use a cutting rule proposed in [Soto11]_. See the module's + documentation for more details. INPUTS: @@ -291,7 +296,7 @@ cdef tuple __hyperbolicity_basic_algorithm__(int N, - ``verbose`` -- (default: ``False``) is boolean. Set to True to display some information during execution. - OUTPUTS: + OUTPUT: This function returns a tuple ( h, certificate ), where: @@ -300,6 +305,7 @@ cdef tuple __hyperbolicity_basic_algorithm__(int N, - ``certificate`` -- 4-tuple of vertices maximizing the value `h`. If no such 4-tuple is found, the empty list [] is returned. + """ cdef int a, b, c, d, hh, h_LB cdef list certificate @@ -400,44 +406,39 @@ cdef inline distances_and_far_apart_pairs(gg, cdef int i if distances == NULL or far_apart_pairs == NULL: - raise ValueError("This method can only be used to compute both "+ - "distances and far-apart pairs.") + raise ValueError("distances or far_apart_pairs is a NULL pointer") elif n > -1: # Computing the distances/far_apart_pairs can only be done if we have # less than MAX_UNSIGNED_SHORT vertices. - raise ValueError("The graph backend contains more than "+ - str( -1)+" nodes and we cannot "+ - "compute the matrix of distances/far-apart pairs on "+ - "something like that !") + raise ValueError("The graph backend contains more than {} nodes and " + "we cannot compute the matrix of distances/far-apart " + "pairs on something like that !".format( -1)) # The vertices which have already been visited cdef bitset_t seen bitset_init(seen, n) - # The list of waiting vertices, the beginning and the end of the list + # The list of waiting vertices cdef uint32_t * waiting_list = sage_malloc(n * sizeof(uint32_t)) - if waiting_list == NULL: - sage_free(seen) - raise MemoryError("Unable to allocate array 'waiting_list' with size %d." %(n)) - cdef uint32_t waiting_beginning = 0 - cdef uint32_t waiting_end = 0 - - cdef uint32_t source - cdef uint32_t v, u - cdef unsigned short ** c_far_apart = sage_malloc(n * sizeof(unsigned short*)) - if c_far_apart == NULL: + if waiting_list == NULL or c_far_apart == NULL: bitset_free(seen) sage_free(waiting_list) - raise MemoryError("Unable to allocate array 'c_far_apart' with size %d." %(n)) + sage_free(c_far_apart) + raise MemoryError + + # the beginning and the end of the list stored in waiting_list + cdef uint32_t waiting_beginning, waiting_end + + cdef uint32_t source + cdef uint32_t v, u - # All pairs are initially far-apart + # All pairs are initiall far-apart memset(far_apart_pairs, 1, n * n * sizeof(unsigned short)) for i from 0 <= i < n: c_far_apart[i] = far_apart_pairs + i * n c_far_apart[i][i] = 0 - # Copying the whole graph to obtain the list of neighbors quicker than by # calling out_neighbors. This data structure is well documented in the # module sage.graphs.base.static_sparse_graph @@ -446,7 +447,7 @@ cdef inline distances_and_far_apart_pairs(gg, cdef uint32_t ** p_vertices = sd.neighbors cdef uint32_t * p_tmp cdef uint32_t * end - + cdef unsigned short * c_distances = distances # We run n different BFS taking each vertex as a source @@ -571,58 +572,55 @@ cdef tuple __hyperbolicity__(int N, cdef uint32_t x, y, l1, l2, S1, S2, S3 cdef list certificate = [] cdef unsigned short *p_far_apart + cdef int nb_p = 0 + + if far_apart_pairs == NULL: + nb_p = (N*(N-1))/2 + else: + for i from 0 <= i < N: + p_far_apart = far_apart_pairs[i] + for j from i < j < N: + if far_apart_pairs[i][j]: + nb_p += 1 - # ==> Allocates and fills nb_pairs_of_length - # # nb_pairs_of_length[d] is the number of pairs of vertices at distance d cdef uint32_t * nb_pairs_of_length = sage_calloc(D+1,sizeof(uint32_t)) - if nb_pairs_of_length == NULL: + + # pairs_of_length[d] is the list of pairs of vertices at distance d + cdef pair ** pairs_of_length = sage_malloc(sizeof(pair *)*(D+1)) + + if pairs_of_length != NULL: + pairs_of_length[0] = sage_malloc(sizeof(pair)*nb_p) + + # temporary variable used to fill pairs_of_length + cdef uint32_t * cpt_pairs = sage_calloc(D+1,sizeof(uint32_t)) + + if (nb_pairs_of_length == NULL or + pairs_of_length == NULL or + pairs_of_length[0] == NULL or + cpt_pairs == NULL): + if pairs_of_length != NULL: + sage_free(pairs_of_length[0]) sage_free(nb_pairs_of_length) - raise MemoryError("Unable to allocate array 'nb_pairs_of_length'.") + sage_free(pairs_of_length) + sage_free(cpt_pairs) + raise MemoryError - # ==> Count the number of (far-apart) pairs of vertices at distance d + # ==> Fills nb_pairs_of_length if far_apart_pairs == NULL: for i from 0 <= i < N: - for j from i+1 <= j < N: + for j from i < j < N: nb_pairs_of_length[ distances[i][j] ] += 1 else: for i from 0 <= i < N: p_far_apart = far_apart_pairs[i] - for j from i+1 <= j < N: + for j from i < j < N: if p_far_apart[j]: nb_pairs_of_length[ distances[i][j] ] += 1 - # ==> Allocates pairs_of_length - # - # pairs_of_length[d] is the list of pairs of vertices at distance d - cdef pair ** pairs_of_length = sage_malloc(sizeof(pair *)*(D+1)) - if pairs_of_length == NULL: - sage_free(nb_pairs_of_length) - raise MemoryError("Unable to allocate array 'pairs_of_length'.") - - # ==> Allocates cpt_pairs - # - # (temporary variable used to fill pairs_of_length) - cdef uint32_t * cpt_pairs = sage_calloc(D+1,sizeof(uint32_t)) - if cpt_pairs == NULL: - sage_free(nb_pairs_of_length) - sage_free(pairs_of_length) - raise MemoryError("Unable to allocate array 'cpt_pairs'.") - - # ==> Allocates pairs_of_length[d] for all d - cdef uint32_t nb_p = 0 + # ==> Defines pairs_of_length[d] for all d for i from 1 <= i <= D: - nb_p += nb_pairs_of_length[i] - pairs_of_length[i] = sage_malloc(sizeof(pair)*nb_pairs_of_length[i]) - - if nb_pairs_of_length[i] > 0 and pairs_of_length[i] == NULL: - while i>1: - i -= 1 - sage_free(pairs_of_length[i]) - sage_free(nb_pairs_of_length) - sage_free(pairs_of_length) - sage_free(cpt_pairs) - raise MemoryError("Unable to allocate array 'pairs_of_length[i]'.") + pairs_of_length[i] = pairs_of_length[i-1] + nb_pairs_of_length[i-1] # ==> Fills pairs_of_length[d] for all d if far_apart_pairs == NULL: @@ -658,10 +656,10 @@ cdef tuple __hyperbolicity__(int N, approximation_factor = min(approximation_factor, D) additive_gap = min(additive_gap, D) - # We create the list of triples (sum,length1,length2) sorted in - # co-lexicographic order: decreasing by sum, decreasing by length2, - # decreasing length1. This is to ensure a valid ordering for S1, to avoid - # some tests, and to ease computation of bounds. + # We create the list of triples (sum,length1,length2) sorted in decreasing + # lexicographic order: decreasing by sum, decreasing by length2, decreasing + # length1. This is to ensure a valid ordering for S1, to avoid some tests, + # and to ease computation of bounds. cdef list triples = [] for l2 from D >= l2 > 0: if nb_pairs_of_length[l2]>0: @@ -678,6 +676,11 @@ cdef tuple __hyperbolicity__(int N, h = h_LB h_UB = D cdef int STOP = 0 + + # S1 = l1+l2 + # l1 = dist(a,b) + # l2 = dist(c,d) + # l1 >= l2 for S1, l1, l2 in triples: if h_UB > l2: @@ -693,10 +696,9 @@ cdef tuple __hyperbolicity__(int N, # If we cannot improve further, we stop # - # See the module's documentation for an proof that this cut is + # See the module's documentation for a proof that this cut is # valid. Remember that the triples are sorted in a specific order. - if l2 <= h: - h_UB = h + if h_UB <= h: STOP = 1 break @@ -718,9 +720,9 @@ cdef tuple __hyperbolicity__(int N, # We compute the hyperbolicity of the 4-tuple. We have S1 = l1 + # l2, and the order in which pairs are visited allow us to claim - # that S1 = max( S1, S2, S3 ). If at some point S1 is not the - # maximum value, the order ensures that the maximum value has - # previously been checked. + # that S1 = max( S1, S2, S3 ). Indeed, if S1 is not the maximum + # value, the order ensures that the maximum value has previously + # been checked. S2 = dist_a[c] + dist_b[d] S3 = dist_a[d] + dist_b[c] if S2 > S3: @@ -730,8 +732,11 @@ cdef tuple __hyperbolicity__(int N, if h < hh or not certificate: # We update current bound on the hyperbolicity and the - # search space, unless hh==0 and two vertices are equal. - if h>0 or not (a==c or a==d or b==c or b==d): + # search space. + # + # Note that if hh==0, we first make sure that a,b,c,d are + # all distinct and are a valid certificate. + if hh>0 or not (a==c or a==d or b==c or b==d): h = hh certificate = [a, b, c, d] @@ -757,8 +762,7 @@ cdef tuple __hyperbolicity__(int N, # We now free the memory sage_free(nb_pairs_of_length) - for 1 <= i <= D: - sage_free(pairs_of_length[i]) + sage_free(pairs_of_length[0]) sage_free(pairs_of_length) # Last, we return the computed value and the certificate @@ -768,7 +772,6 @@ cdef tuple __hyperbolicity__(int N, # When using far-apart pairs, the loops may end return (h, certificate, h_UB if STOP==2 else h) - def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=None, verbose = False): r""" Return the hyperbolicity of the graph or an approximation of this value. @@ -892,7 +895,7 @@ def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=N ... d2,_,_ = hyperbolicity(G,algorithm='cuts') ... d3,_,_ = hyperbolicity(G,algorithm='cuts+') ... l3,_,u3 = hyperbolicity(G,approximation_factor=2) - ... if d1!=d4 or d1!=d2 or d1!=d3 or l3>d1 or u3d1 or u3= 1.0.") - elif algorithm!='cuts': + elif algorithm=='cuts': + if not approximation_factor in RR or approximation_factor < 1.0: + raise ValueError("The approximation factor must be >= 1.0.") + else: print "The approximation_factor is ignored when using the '%s' algorithm." %(algorithm) if additive_gap is None: additive_gap = 0.0 @@ -1098,7 +1102,10 @@ def hyperbolicity(G, algorithm='cuts', approximation_factor=None, additive_gap=N elif algorithm in ['basic', 'basic+']: sig_on() - hh, certif = __hyperbolicity_basic_algorithm__(N, distances, algorithm=='basic+', verbose) + hh, certif = __hyperbolicity_basic_algorithm__(N, + distances, + use_bounds=(algorithm=='basic+'), + verbose=verbose) sig_off() hh_UB = hh From a156a7850e90b34995794476a20e9741d7718519 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Sun, 30 Nov 2014 17:40:20 +0000 Subject: [PATCH 191/698] Add AX_CHECK_ROOT macro --- configure.ac | 2 ++ m4/ax_check_root.m4 | 59 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 m4/ax_check_root.m4 diff --git a/configure.ac b/configure.ac index ecd27d6ee12..c1067b5c69d 100644 --- a/configure.ac +++ b/configure.ac @@ -32,6 +32,8 @@ AM_INIT_AUTOMAKE([1.9.6 foreign]) # Allow "configure --disable-maintainer-mode" to disable timestamp checking AM_MAINTAINER_MODE([enable]) +AX_CHECK_ROOT([AC_MSG_ERROR([You cannot build Sage as root, switch to a unpriviledged user])], []) + #--------------------------------------------------------- # We need to run this configure script with bash if test -z "$BASH_VERSION$CONFIG_SHELL" diff --git a/m4/ax_check_root.m4 b/m4/ax_check_root.m4 new file mode 100644 index 00000000000..2ac1f669229 --- /dev/null +++ b/m4/ax_check_root.m4 @@ -0,0 +1,59 @@ +# SYNOPSIS +# +# AX_CHECK_ROOT +# +# DESCRIPTION +# +# Check if the current UNIX user is root. +# +# Example: +# +# AX_CHECK_ROOT([action-if-yes], [action-if-no]) +# AX_CHECK_ROOT([], [AC_MSG_ERROR([We need root privileges])]) +# AX_CHECK_ROOT([AC_MSG_ERROR([Must not be root])], []) +# +# LICENSE +# +# Copyright (c) 2014 Volker Braun +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 5 + +AC_DEFUN([AX_CHECK_ROOT],[ +AC_MSG_CHECKING([for root user]) + +uid=`id -u` +if test "x$uid" == "x0"; then + AC_MSG_RESULT([yes]) + $1 +else + AC_MSG_RESULT([no]) + $2 +fi;dnl + +]) From 80d54890d91a024dfdd45a6d3eed4b8410dc25b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Sun, 30 Nov 2014 22:36:46 +0100 Subject: [PATCH 192/698] 16256: Module List -> Comprehensive Module List and link to trac ticket --- src/doc/en/reference/combinat/index.rst | 4 ++-- src/doc/en/reference/combinat/module_list.rst | 16 +++++----------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/doc/en/reference/combinat/index.rst b/src/doc/en/reference/combinat/index.rst index 2511a04a459..1066b9a34f3 100644 --- a/src/doc/en/reference/combinat/index.rst +++ b/src/doc/en/reference/combinat/index.rst @@ -4,8 +4,8 @@ Combinatorics .. automodule:: sage.combinat -Alphabetical Module List ------------------------- +Comprehensive Module List +------------------------- .. toctree:: :maxdepth: 1 diff --git a/src/doc/en/reference/combinat/module_list.rst b/src/doc/en/reference/combinat/module_list.rst index 15ec3e72f13..e84dc84733e 100644 --- a/src/doc/en/reference/combinat/module_list.rst +++ b/src/doc/en/reference/combinat/module_list.rst @@ -1,22 +1,16 @@ -Module list -=========== +Comprehensive Module list +========================= .. NOTE:: - This list is currently sorted in alphabetical order using the source files names. - -.. NOTE:: - - This can be updated semi-automatically by running in ``src/sage/combinat``:: + This list is currently sorted in alphabetical order w.r.t. the module names. + It can be updated semi-automatically by running in ``src/sage/combinat``:: find -name "*.py*" | sed 's|\.pyx\?$||; s|\./| sage/combinat/|' | LANG=en_US.UTF-8 LC_COLLATE=C sort > /tmp/module_list.rst and copy pasting the result back there. -.. TODO:: - - Improve this list by sorting it in alphabetical order using the titles generated by Sphinx - and by not flattening the module hierarchical structure. +.. TODO:: See :trac:`17421` for desirable improvements. .. toctree:: :maxdepth: 1 From f5aa239b4946392411d97f4269ef5e646e215bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Sun, 30 Nov 2014 22:50:34 +0100 Subject: [PATCH 193/698] #16256: fixed links to thematic tutorials --- src/sage/combinat/crystals/__init__.py | 2 +- src/sage/combinat/root_system/__init__.py | 2 +- src/sage/combinat/sf/sf.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/crystals/__init__.py b/src/sage/combinat/crystals/__init__.py index 694eb1a519c..f26dcdc1f20 100644 --- a/src/sage/combinat/crystals/__init__.py +++ b/src/sage/combinat/crystals/__init__.py @@ -11,7 +11,7 @@ --------------------- - :ref:`sage.combinat.crystals.crystals` -- The `Lie Methods and Related Combinatorics <../../../../thematic_tutorials/lie.html>`_ thematic tutorial +- The `Lie Methods and Related Combinatorics <../../../../../thematic_tutorials/lie.html>`_ thematic tutorial Catalogs of crystals -------------------- diff --git a/src/sage/combinat/root_system/__init__.py b/src/sage/combinat/root_system/__init__.py index 4d0eadd76a9..f7408099868 100644 --- a/src/sage/combinat/root_system/__init__.py +++ b/src/sage/combinat/root_system/__init__.py @@ -20,7 +20,7 @@ - :class:`RootSystem` -- An introduction to root systems - :ref:`sage.combinat.root_system.plot` -- A root system visualization tutorial -- The `Lie Methods and Related Combinatorics <../../../../thematic_tutorials/lie.html>`_ thematic tutorial +- The `Lie Methods and Related Combinatorics <../../../../../thematic_tutorials/lie.html>`_ thematic tutorial Related material diff --git a/src/sage/combinat/sf/sf.py b/src/sage/combinat/sf/sf.py index 867259bc377..0970b9f39b4 100644 --- a/src/sage/combinat/sf/sf.py +++ b/src/sage/combinat/sf/sf.py @@ -267,7 +267,7 @@ class SymmetricFunctions(UniqueRepresentation, Parent): and restriction, respectively. The Schur functions can also be interpreted as characters of `GL_n`, see `Partitions and Schur functions`__. - __ ../../../../thematic_tutorials/lie/lie_basics.html#partitions-and-schur-polynomials + __ ../../../../../thematic_tutorials/lie/lie_basics.html#partitions-and-schur-polynomials .. rubric:: The omega involution From a5208fd118f578f5f36a57caaf43e6a81e48653b Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Mon, 1 Dec 2014 17:58:39 +0530 Subject: [PATCH 194/698] trac #16256: Rewrite the posets doc page --- src/sage/combinat/designs/__init__.py | 4 ++-- src/sage/combinat/posets/__init__.py | 23 +++++++++++++++++------ src/sage/combinat/tamari_lattices.py | 10 +++++----- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/sage/combinat/designs/__init__.py b/src/sage/combinat/designs/__init__.py index 3b46fba32e0..9d965629391 100644 --- a/src/sage/combinat/designs/__init__.py +++ b/src/sage/combinat/designs/__init__.py @@ -1,6 +1,6 @@ __doc__ = r""" -Designs and Incidence Structures -================================ +Combinatorial Designs and Incidence Structures +============================================== All designs can be accessed by ``designs.`` and are listed in the design catalog: diff --git a/src/sage/combinat/posets/__init__.py b/src/sage/combinat/posets/__init__.py index 8b8f7451e44..8b6b80ea2eb 100644 --- a/src/sage/combinat/posets/__init__.py +++ b/src/sage/combinat/posets/__init__.py @@ -1,15 +1,26 @@ __doc__ = r""" Posets -====== + +Common posets can be accessed through ``posets.`` and are listed in the +posets catalog: + +- :ref:`Catalog of posets ` + +Poset-related classes: - :ref:`sage.combinat.posets.posets` -- Posets constructors: :func:`Poset`, :func:`MeetSemilattice`, :func:`JoinSemilattice`, :func:`LatticePoset` -- Posets categories: :class:`~sage.categories.posets.Posets` and :class:`~sage.categories.lattice_posets.LatticePosets` -- :class:`~sage.combinat.posets.linear_extensions.LinearExtensionOfPoset`, :class:`sage.combinat.posets.linear_extensions.LinearExtensionsOfPoset` +- :ref:`sage.combinat.posets.lattices` + +- :ref:`sage.combinat.posets.linear_extensions` -- Catalog of posets: :obj:`Posets` - :ref:`sage.combinat.tamari_lattices` - :ref:`sage.combinat.interval_posets` -""" + +If you are looking for Poset-related :ref:`categories +`, see +:class:`~sage.categories.posets.Posets` and +:class:`~sage.categories.lattice_posets.LatticePosets`. + + """ import all diff --git a/src/sage/combinat/tamari_lattices.py b/src/sage/combinat/tamari_lattices.py index 411b2ac992b..491b09586f1 100644 --- a/src/sage/combinat/tamari_lattices.py +++ b/src/sage/combinat/tamari_lattices.py @@ -1,5 +1,5 @@ r""" -The family of generalized Tamari lattices +Generalized Tamari lattices These lattices depend on three parameters `a`, `b` and `m`, where `a` and `b` are coprime positive integers and `m` is a nonnegative integer. @@ -7,13 +7,13 @@ The elements are :func:`Dyck paths` in the `(a \times b)`-rectangle. The order relation depends on `m`. -To use the provided functionality, you should import Tamari lattices by typing +To use the provided functionality, you should import Tamari lattices by typing:: -``from sage.combinat.tamari_lattices import TamariLattice`` + sage: from sage.combinat.tamari_lattices import TamariLattice -or +or:: -``from sage.combinat.tamari_lattices import GeneralizedTamariLattice``. + sage: from sage.combinat.tamari_lattices import GeneralizedTamariLattice EXAMPLES:: From aef6f774604504222290e65216d013b2f0eae954 Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Mon, 1 Dec 2014 18:26:43 +0530 Subject: [PATCH 195/698] trac #17424: Index of all poset constructions --- src/sage/combinat/posets/linear_extensions.py | 8 +++++ src/sage/combinat/posets/poset_examples.py | 34 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/sage/combinat/posets/linear_extensions.py b/src/sage/combinat/posets/linear_extensions.py index dc73dd915e5..a40b24d996f 100644 --- a/src/sage/combinat/posets/linear_extensions.py +++ b/src/sage/combinat/posets/linear_extensions.py @@ -1,6 +1,14 @@ # -*- coding: utf-8 -*- r""" Linear Extensions of Posets + +This module defines two classes: + +- :class:`LinearExtensionOfPoset` +- :class:`LinearExtensionsOfPoset` + +Classes and methods +------------------- """ #***************************************************************************** # Copyright (C) 2012 Anne Schilling diff --git a/src/sage/combinat/posets/poset_examples.py b/src/sage/combinat/posets/poset_examples.py index 81ec5e4277c..6dea0c2cfe5 100644 --- a/src/sage/combinat/posets/poset_examples.py +++ b/src/sage/combinat/posets/poset_examples.py @@ -1,5 +1,39 @@ r""" A collection of posets and lattices. + +All common posets can be accessed through the ``posets.`` object:: + + sage: posets.PentagonPoset() + Finite lattice containing 5 elements + +Moreover, the set of all posets of order `n` is represented by ``Posets(n)``:: + + sage: Posets(5) + Posets containing 5 vertices + +**Index of common posets:** + +.. csv-table:: + :class: contentstable + :widths: 30, 70 + :delim: | + + :meth:`~Posets.AntichainPoset` | Return an antichain on `n` elements. + :meth:`~Posets.BooleanLattice` | Return the Boolean lattice on `2^n` elements. + :meth:`~Posets.ChainPoset` | Return a chain on `n` elements. + :meth:`~Posets.DiamondPoset` | Return the lattice of rank two on `n` elements. + :meth:`~Posets.IntegerCompositions` | Return the poset of integer compositions of `n`. + :meth:`~Posets.IntegerPartitions` | Return the poset of integer partitions of ``n``. + :meth:`~Posets.PentagonPoset` | Return the Pentagon poset. + :meth:`~Posets.RandomPoset` | Return a random poset on `n` vertices according to a probability `p`. + :meth:`~Posets.RestrictedIntegerPartitions` | Return the poset of integer partitions of `n`, ordered by restricted refinement. + :meth:`~Posets.SSTPoset` | Return the poset on semistandard tableaux of shape `s` and largest entry `f` that is ordered by componentwise comparison. + :meth:`~Posets.SymmetricGroupBruhatIntervalPoset` | The poset of permutations with respect to Bruhat order. + :meth:`~Posets.SymmetricGroupBruhatOrderPoset` | The poset of permutations with respect to Bruhat order. + :meth:`~Posets.SymmetricGroupWeakOrderPoset` | The poset of permutations of `\{ 1, 2, \ldots, n \}` with respect to the weak order. + +Constructions +------------- """ #***************************************************************************** # Copyright (C) 2008 Peter Jipsen , From 28038c2531aefe461d11c7da4bc02d043dd2f86a Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Mon, 13 Oct 2014 09:51:43 +0200 Subject: [PATCH 196/698] trac #17149: iOA with big holes through product of OA --- .../combinat/designs/orthogonal_arrays.py | 43 ++++++++++++++++--- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/src/sage/combinat/designs/orthogonal_arrays.py b/src/sage/combinat/designs/orthogonal_arrays.py index 2f6f20449d4..ef1efd46ae6 100644 --- a/src/sage/combinat/designs/orthogonal_arrays.py +++ b/src/sage/combinat/designs/orthogonal_arrays.py @@ -1086,11 +1086,6 @@ def incomplete_orthogonal_array(k,n,holes_sizes,resolvable=False, existence=Fals - ``holes_sizes`` (list of integers) -- respective sizes of the holes to be found. - .. NOTE:: - - Right now the feature is only available when all holes have size 1, - i.e. `s_i=1`. - - ``resolvable`` (boolean) -- set to ``True`` if you want the design to be resolvable. The classes of the resolvable design are obtained as the first `n` blocks, then the next `n` blocks, etc ... Set to ``False`` by default. @@ -1106,8 +1101,15 @@ def incomplete_orthogonal_array(k,n,holes_sizes,resolvable=False, existence=Fals .. NOTE:: - By convention, the ground set is always `V = \{0, ..., n-1\}` and the - holes are `\{n-1, ..., n-s_1\}^k`, `\{n-s_1-1,...,n-s_1-s_2\}^k`, etc. + By convention, the ground set is always `V = \{0, ..., n-1\}`. + + If all holes have size 1, in the incomplete orthogonal array returned by + this function the holes are `\{n-1, ..., n-s_1\}^k`, + `\{n-s_1-1,...,n-s_1-s_2\}^k`, etc. + + More generally, if ``holes_sizes`` is equal to `u1,...,uk`, the `i`-th + hole is the set of points `\{n-\sum_{j\geq i}u_j,...,n-\sum_{j\geq + i+1}u_j\}^k`. .. SEEALSO:: @@ -1185,6 +1187,15 @@ def incomplete_orthogonal_array(k,n,holes_sizes,resolvable=False, existence=Fals ... NotImplementedError: I was not able to build this OA(6,36)-OA(6,8)-2.OA(6,9) + 10 holes of size 9 through the product construction:: + + sage: iOA = designs.incomplete_orthogonal_array(10,153,[9]*10) # long time + sage: OA9 = designs.orthogonal_arrays.build(10,9) + sage: for i in range(10): + ....: iOA.extend([[153-9*(i+1)+x for x in B] for B in OA9]) + sage: is_orthogonal_array(iOA,10,153) + True + REFERENCES: .. [BvR82] More mutually orthogonal Latin squares, @@ -1280,6 +1291,24 @@ def incomplete_orthogonal_array(k,n,holes_sizes,resolvable=False, existence=Fals OA = OA_from_quasi_difference_matrix(M,G,fill_hole=False) return [B[:k] for B in OA] + # Equal holes [h,h,...] with h>1 through OA product construction + # + # (i.e. OA(k,n1)-x.OA(k,1) and OA(k,n2) ==> OA(k,n1.n2)-x.OA(k,n2) ) + elif (not all_holes_of_size_1 and # h>1 + n%holes_sizes[0] == 0 and # h divides n + all(h==holes_sizes[0] for h in holes_sizes) and # holes of equal size + orthogonal_array(k,holes_sizes[0],existence=True) and # OA(k,h) + incomplete_orthogonal_array(k,n//holes_sizes[0],[1]*x,existence=True)): # OA(k,n/h)-x.OA(k,1) + if existence: + return True + from itertools import izip + h = holes_sizes[0] + iOA1 = incomplete_orthogonal_array(k,n//holes_sizes[0],[1]*x) + iOA2 = orthogonal_array(k,h) + + return [[B1[i]*h+B2[i] for i in range(k)] + for B1 in iOA1 + for B2 in iOA2] else: if existence: return Unknown From 478c6587dee3176250714979a995f39e8ffb49d3 Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Thu, 30 Oct 2014 12:52:21 +0100 Subject: [PATCH 197/698] trac #17149: y->sum_of_holes, x->number_of_holes, holes_sizes->holes --- .../combinat/designs/orthogonal_arrays.py | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/sage/combinat/designs/orthogonal_arrays.py b/src/sage/combinat/designs/orthogonal_arrays.py index ef1efd46ae6..d7aa61c5ffb 100644 --- a/src/sage/combinat/designs/orthogonal_arrays.py +++ b/src/sage/combinat/designs/orthogonal_arrays.py @@ -1064,7 +1064,7 @@ def largest_available_k(n,t=2): k += 1 return k -def incomplete_orthogonal_array(k,n,holes_sizes,resolvable=False, existence=False): +def incomplete_orthogonal_array(k,n,holes,resolvable=False, existence=False): r""" Return an `OA(k,n)-\sum_{1\leq i\leq x} OA(k,s_i)`. @@ -1083,8 +1083,7 @@ def incomplete_orthogonal_array(k,n,holes_sizes,resolvable=False, existence=Fals - ``k,n`` (integers) - - ``holes_sizes`` (list of integers) -- respective sizes of the holes to be - found. + - ``holes`` (list of integers) -- respective sizes of the holes to be found. - ``resolvable`` (boolean) -- set to ``True`` if you want the design to be resolvable. The classes of the resolvable design are obtained as the first @@ -1107,9 +1106,8 @@ def incomplete_orthogonal_array(k,n,holes_sizes,resolvable=False, existence=Fals this function the holes are `\{n-1, ..., n-s_1\}^k`, `\{n-s_1-1,...,n-s_1-s_2\}^k`, etc. - More generally, if ``holes_sizes`` is equal to `u1,...,uk`, the `i`-th - hole is the set of points `\{n-\sum_{j\geq i}u_j,...,n-\sum_{j\geq - i+1}u_j\}^k`. + More generally, if ``holes`` is equal to `u1,...,uk`, the `i`-th hole is + the set of points `\{n-\sum_{j\geq i}u_j,...,n-\sum_{j\geq i+1}u_j\}^k`. .. SEEALSO:: @@ -1204,24 +1202,26 @@ def incomplete_orthogonal_array(k,n,holes_sizes,resolvable=False, existence=Fals vol.39, num.3, pages 263-281 1982 """ - assert all(xx > 0 for xx in holes_sizes) + assert all(xx > 0 for xx in holes) from database import QDM - y = sum(holes_sizes) - x = len(holes_sizes) - all_holes_of_size_1 = (x==y) + OA = None - if y == 0: + sum_of_holes = sum(holes) + number_of_holes = len(holes) + all_holes_of_size_1 = (number_of_holes==sum_of_holes) + + if sum_of_holes == 0: return orthogonal_array(k,n,existence=existence,resolvable=resolvable) - if y > n: + if sum_of_holes > n: if existence: return False raise EmptySetError("The total size of holes must be smaller or equal than the size of the ground set") - if all_holes_of_size_1 and resolvable and y != n: + if all_holes_of_size_1 and resolvable and sum_of_holes != n: if existence: return False - raise EmptySetError("There is no resolvable incomplete OA({},{}) whose holes' sizes sum to {}!=n(={})".format(k,n,y,n)) + raise EmptySetError("There is no resolvable incomplete OA({},{}) whose holes' sizes sum to {}!=n(={})".format(k,n,sum_of_holes,n)) if all_holes_of_size_1 and resolvable: # n holes of size 1 --> equivalent to OA(k+1,n) if existence: @@ -1244,48 +1244,48 @@ def incomplete_orthogonal_array(k,n,holes_sizes,resolvable=False, existence=Fals return OA[:-n] # Easy case - elif all_holes_of_size_1 and x <= 1: + elif all_holes_of_size_1 and number_of_holes <= 1: if existence: return orthogonal_array(k,n,existence=True) OA = orthogonal_array(k,n) - independent_set = OA[:x] + independent_set = OA[:number_of_holes] - elif all_holes_of_size_1 and x <= 3 and n > k-1 and k >= 3 and existence: + elif all_holes_of_size_1 and number_of_holes <= 3 and n > k-1 and k >= 3 and existence: # This is lemma 2.3 from [BvR82]_ with u=1 return orthogonal_array(k,n,existence=True) - elif all_holes_of_size_1 and x >= 2 and k == n+1: + elif all_holes_of_size_1 and number_of_holes >= 2 and k == n+1: if existence: return False - raise EmptySetError("There is no OA(n+1,n) - {}.OA(n+1,1) as all blocks do intersect in a projective plane.".format(x)) + raise EmptySetError("There is no OA(n+1,n) - {}.OA(n+1,1) as all blocks do intersect in a projective plane.".format(number_of_holes)) # If we can build OA(k+1,n) then we can find n disjoint blocks in OA(k,n) elif all_holes_of_size_1 and orthogonal_array(k+1,n,existence=True): if existence: return True OA = orthogonal_array(k+1,n) - independent_set = [B[:-1] for B in OA if B[-1] == 0][:x] + independent_set = [B[:-1] for B in OA if B[-1] == 0][:number_of_holes] OA = [B[:-1] for B in OA] elif all_holes_of_size_1 and orthogonal_array(k,n,existence=True): OA = orthogonal_array(k,n) try: - independent_set = OA_find_disjoint_blocks(OA,k,n,x) + independent_set = OA_find_disjoint_blocks(OA,k,n,number_of_holes) except ValueError: if existence: return Unknown - raise NotImplementedError("I was not able to build this OA({},{})-{}.OA({},1)".format(k,n,x,k)) + raise NotImplementedError("I was not able to build this OA({},{})-{}.OA({},1)".format(k,n,number_of_holes,k)) if existence: return True - independent_set = OA_find_disjoint_blocks(OA,k,n,x) + independent_set = OA_find_disjoint_blocks(OA,k,n,number_of_holes) elif all_holes_of_size_1 and not orthogonal_array(k,n,existence=True): return orthogonal_array(k,n,existence=existence) # From a quasi-difference matrix - elif x==1 and any(uu==y and mu<=1 and lmbda==1 and k<=kk+1 for (nn,lmbda,mu,uu),(kk,_) in QDM.get((n,1),{}).iteritems()): + elif number_of_holes==1 and any(uu==sum_of_holes and mu<=1 and lmbda==1 and k<=kk+1 for (nn,lmbda,mu,uu),(kk,_) in QDM.get((n,1),{}).iteritems()): for (nn,lmbda,mu,uu),(kk,f) in QDM[n,1].iteritems(): - if uu==y and mu<=1 and lmbda==1 and k<=kk+1: + if uu==sum_of_holes and mu<=1 and lmbda==1 and k<=kk+1: break G,M = f() OA = OA_from_quasi_difference_matrix(M,G,fill_hole=False) @@ -1295,15 +1295,15 @@ def incomplete_orthogonal_array(k,n,holes_sizes,resolvable=False, existence=Fals # # (i.e. OA(k,n1)-x.OA(k,1) and OA(k,n2) ==> OA(k,n1.n2)-x.OA(k,n2) ) elif (not all_holes_of_size_1 and # h>1 - n%holes_sizes[0] == 0 and # h divides n - all(h==holes_sizes[0] for h in holes_sizes) and # holes of equal size - orthogonal_array(k,holes_sizes[0],existence=True) and # OA(k,h) - incomplete_orthogonal_array(k,n//holes_sizes[0],[1]*x,existence=True)): # OA(k,n/h)-x.OA(k,1) + n%holes[0] == 0 and # h divides n + all(h==holes[0] for h in holes) and # holes of equal size + orthogonal_array(k,holes[0],existence=True) and # OA(k,h) + incomplete_orthogonal_array(k,n//holes[0],[1]*number_of_holes,existence=True)): # OA(k,n/h)-x.OA(k,1) if existence: return True from itertools import izip - h = holes_sizes[0] - iOA1 = incomplete_orthogonal_array(k,n//holes_sizes[0],[1]*x) + h = holes[0] + iOA1 = incomplete_orthogonal_array(k,n//holes[0],[1]*number_of_holes) iOA2 = orthogonal_array(k,h) return [[B1[i]*h+B2[i] for i in range(k)] @@ -1315,10 +1315,10 @@ def incomplete_orthogonal_array(k,n,holes_sizes,resolvable=False, existence=Fals # format the list of holes from string import join f = lambda x: "" if x == 1 else "{}.".format(x) - holes_string = join(["-{}OA({},{})".format(f(holes_sizes.count(x)),k,x) for x in sorted(set(holes_sizes))],'') + holes_string = join(["-{}OA({},{})".format(f(holes.count(x)),k,x) for x in sorted(set(holes))],'') raise NotImplementedError("I was not able to build this OA({},{}){}".format(k,n,holes_string)) - assert x == len(independent_set) + assert number_of_holes == len(independent_set) for B in independent_set: OA.remove(B) From a9e7c28340317f10f64971b808e19288f533d2b6 Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Thu, 30 Oct 2014 14:58:38 +0100 Subject: [PATCH 198/698] trac #17149: Code cleaning --- .../combinat/designs/orthogonal_arrays.py | 73 +++++++++++-------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/src/sage/combinat/designs/orthogonal_arrays.py b/src/sage/combinat/designs/orthogonal_arrays.py index d7aa61c5ffb..0283a8fd01f 100644 --- a/src/sage/combinat/designs/orthogonal_arrays.py +++ b/src/sage/combinat/designs/orthogonal_arrays.py @@ -1145,8 +1145,7 @@ def incomplete_orthogonal_array(k,n,holes,resolvable=False, existence=False): sage: designs.incomplete_orthogonal_array(4,3,[1,1]) Traceback (most recent call last): ... - EmptySetError: There is no OA(n+1,n) - 2.OA(n+1,1) as all blocks do - intersect in a projective plane. + EmptySetError: There is no OA(n+1,n) - 2.OA(n+1,1) as all blocks intersect in a projective plane. sage: n=10 sage: k=designs.orthogonal_arrays.largest_available_k(n) sage: designs.incomplete_orthogonal_array(k,n,[1,1,1],existence=True) @@ -1176,7 +1175,7 @@ def incomplete_orthogonal_array(k,n,holes,resolvable=False, existence=False): sage: designs.incomplete_orthogonal_array(9,13,[1]*10,resolvable=True) Traceback (most recent call last): ... - EmptySetError: There is no resolvable incomplete OA(9,13) whose holes' sizes sum to 10!=n(=13) + EmptySetError: There is no resolvable incomplete OA(9,13) whose holes' sizes sum to 10 0 for xx in holes) - from database import QDM + from sage.combinat.designs.database import QDM + for h in holes: + if h<0: + raise ValueError("Holes must have size >=0, but {} was in the list").format(h) - OA = None + holes = [h for h in holes if h>0] - sum_of_holes = sum(holes) + if not holes: + return orthogonal_array(k,n,existence=existence,resolvable=resolvable) + + sum_of_holes = sum(holes) number_of_holes = len(holes) - all_holes_of_size_1 = (number_of_holes==sum_of_holes) + max_hole = max(holes) + min_hole = min(holes) - if sum_of_holes == 0: - return orthogonal_array(k,n,existence=existence,resolvable=resolvable) if sum_of_holes > n: if existence: return False raise EmptySetError("The total size of holes must be smaller or equal than the size of the ground set") - if all_holes_of_size_1 and resolvable and sum_of_holes != n: + if (max_hole == 1 and + resolvable and + sum_of_holes != n): if existence: return False - raise EmptySetError("There is no resolvable incomplete OA({},{}) whose holes' sizes sum to {}!=n(={})".format(k,n,sum_of_holes,n)) + raise EmptySetError("There is no resolvable incomplete OA({},{}) whose holes' sizes sum to {} equivalent to OA(k+1,n) + # resolvable OA(k,n)-n.OA(k,1) ==> equivalent to OA(k+1,n) + if max_hole==1 and resolvable: if existence: return orthogonal_array(k+1,n,existence=True) @@ -1244,30 +1250,36 @@ def incomplete_orthogonal_array(k,n,holes,resolvable=False, existence=False): return OA[:-n] # Easy case - elif all_holes_of_size_1 and number_of_holes <= 1: + elif max_hole==1 and number_of_holes <= 1: if existence: return orthogonal_array(k,n,existence=True) OA = orthogonal_array(k,n) independent_set = OA[:number_of_holes] - elif all_holes_of_size_1 and number_of_holes <= 3 and n > k-1 and k >= 3 and existence: - # This is lemma 2.3 from [BvR82]_ with u=1 + # This is lemma 2.3 from [BvR82]_ with u=1 + # + # TODO: handle larger holes too + elif (max_hole==1 and + existence and + number_of_holes <= 3 and + n > k-1 and k >= 3): return orthogonal_array(k,n,existence=True) - elif all_holes_of_size_1 and number_of_holes >= 2 and k == n+1: + elif max_hole==1 and number_of_holes >= 2 and k == n+1: if existence: return False - raise EmptySetError("There is no OA(n+1,n) - {}.OA(n+1,1) as all blocks do intersect in a projective plane.".format(number_of_holes)) + raise EmptySetError(("There is no OA(n+1,n) - {}.OA(n+1,1) as all blocks " + "intersect in a projective plane.").format(number_of_holes)) - # If we can build OA(k+1,n) then we can find n disjoint blocks in OA(k,n) - elif all_holes_of_size_1 and orthogonal_array(k+1,n,existence=True): + # Holes of size 1 from OA(k+1,n) + elif max_hole==1 and orthogonal_array(k+1,n,existence=True): if existence: return True OA = orthogonal_array(k+1,n) independent_set = [B[:-1] for B in OA if B[-1] == 0][:number_of_holes] OA = [B[:-1] for B in OA] - elif all_holes_of_size_1 and orthogonal_array(k,n,existence=True): + elif max_hole==1 and orthogonal_array(k,n,existence=True): OA = orthogonal_array(k,n) try: independent_set = OA_find_disjoint_blocks(OA,k,n,number_of_holes) @@ -1279,7 +1291,7 @@ def incomplete_orthogonal_array(k,n,holes,resolvable=False, existence=False): return True independent_set = OA_find_disjoint_blocks(OA,k,n,number_of_holes) - elif all_holes_of_size_1 and not orthogonal_array(k,n,existence=True): + elif max_hole==1 and not orthogonal_array(k,n,existence=True): return orthogonal_array(k,n,existence=existence) # From a quasi-difference matrix @@ -1294,15 +1306,14 @@ def incomplete_orthogonal_array(k,n,holes,resolvable=False, existence=False): # Equal holes [h,h,...] with h>1 through OA product construction # # (i.e. OA(k,n1)-x.OA(k,1) and OA(k,n2) ==> OA(k,n1.n2)-x.OA(k,n2) ) - elif (not all_holes_of_size_1 and # h>1 - n%holes[0] == 0 and # h divides n - all(h==holes[0] for h in holes) and # holes of equal size - orthogonal_array(k,holes[0],existence=True) and # OA(k,h) - incomplete_orthogonal_array(k,n//holes[0],[1]*number_of_holes,existence=True)): # OA(k,n/h)-x.OA(k,1) + elif (min_hole > 1 and + max_hole == min_hole and + n%min_hole == 0 and # h divides n + orthogonal_array(k,min_hole,existence=True) and # OA(k,h) + incomplete_orthogonal_array(k,n//min_hole,[1]*number_of_holes,existence=True)): # OA(k,n/h)-x.OA(k,1) if existence: return True - from itertools import izip - h = holes[0] + h = min_hole iOA1 = incomplete_orthogonal_array(k,n//holes[0],[1]*number_of_holes) iOA2 = orthogonal_array(k,h) @@ -1886,7 +1897,7 @@ def OA_from_PBD(k,n,PBD, check=True): sage: OA_from_PBD(4,10,pbd) Traceback (most recent call last): ... - EmptySetError: There is no OA(n+1,n) - 3.OA(n+1,1) as all blocks do intersect in a projective plane. + EmptySetError: There is no OA(n+1,n) - 3.OA(n+1,1) as all blocks intersect in a projective plane. Or an `OA(3,6)` (as the PBD has 10 points):: @@ -2119,7 +2130,7 @@ def is_available(k,n,t=2): INPUT: - ``k,n,t`` (integers) -- parameters of the orthogonal array. - +x .. SEEALSO:: :meth:`exists` From c3f7ddfc3695771b5998eb98fdfbb140b6e993d8 Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Mon, 1 Dec 2014 20:27:01 +0530 Subject: [PATCH 199/698] trac #17149: OA(10,1620) --- src/sage/combinat/designs/database.py | 33 ++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/sage/combinat/designs/database.py b/src/sage/combinat/designs/database.py index 17c6bdf519c..fc785395002 100644 --- a/src/sage/combinat/designs/database.py +++ b/src/sage/combinat/designs/database.py @@ -1916,6 +1916,36 @@ def OA_25_1262(): return OA_from_PBD(25,1262,PBD,check=False) +def OA_10_1620(): + r""" + Returns an OA(10,1620) + + This is obtained through the generalized Brouwer-van Rees + construction. Indeed, `1620 = 144.11+(36=4.9)` and there exists an + `OA(10,153) - OA(10,9)`. + + .. NOTE:: + + This function should be removed once + :func:`~sage.combinat.designs.orthogonal_arrays_find_recursive.find_brouwer_van_rees_with_one_truncated_column` + can handle all incomplete orthogonal arrays obtained through + :func:`~sage.combinat.designs.orthogonal_arrays.incomplete_orthogonal_array`. + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array + sage: from sage.combinat.designs.database import OA_10_1620 + sage: OA = OA_10_1620() # not tested -- ~7s + sage: print is_orthogonal_array(OA,10,1620,2) # not tested -- ~7s + True + + The design is available from the general constructor:: + + sage: designs.orthogonal_arrays.is_available(10,1620) + True + """ + return wilson_construction(None,10,11,144,[[(9,4)]]) + # Index of the OA constructions # # Associates to n the pair (k,f) where f() is a function that returns an OA(k,n) @@ -1952,7 +1982,8 @@ def OA_25_1262(): 640 : (11 , OA_11_640), 796 : (10 , OA_10_796), 896 : (15 , OA_15_896), - 1262 : (25 , OA_25_1262), + 1262 : (25, OA_25_1262), + 1620 : (10, OA_10_1620), } # Add this data to the module's doc LIST_OF_OA_CONSTRUCTIONS = join((":func:`OA({},{}) `".format(k,n,k,n) From 2330e61717599571938c23604ffbaae9a3b1e710 Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Mon, 1 Dec 2014 20:41:14 +0530 Subject: [PATCH 200/698] trac #17149: OA(9,1078) --- src/sage/combinat/designs/database.py | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/sage/combinat/designs/database.py b/src/sage/combinat/designs/database.py index fc785395002..cd392748f45 100644 --- a/src/sage/combinat/designs/database.py +++ b/src/sage/combinat/designs/database.py @@ -1879,6 +1879,36 @@ def OA_15_896(): return OA_n_times_2_pow_c_from_matrix(15,7,FiniteField(7),zip(*A),Y,check=False) +def OA_9_1078(): + r""" + Returns an OA(9,1078) + + This is obtained through the generalized Brouwer-van Rees + construction. Indeed, `1078 = 89.11 + (99=9.11)` and there exists an + `OA(9,100) - OA(9,11)`. + + .. NOTE:: + + This function should be removed once + :func:`~sage.combinat.designs.orthogonal_arrays_find_recursive.find_brouwer_van_rees_with_one_truncated_column` + can handle all incomplete orthogonal arrays obtained through + :func:`~sage.combinat.designs.orthogonal_arrays.incomplete_orthogonal_array`. + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array + sage: from sage.combinat.designs.database import OA_9_1078 + sage: OA = OA_9_1078() # not tested -- ~3s + sage: print is_orthogonal_array(OA,9,1078,2) # not tested -- ~3s + True + + The design is available from the general constructor:: + + sage: designs.orthogonal_arrays.is_available(9,1078) + True + """ + return wilson_construction(None,9,11,89,[[(11,9)]]) + def OA_25_1262(): r""" Returns an OA(25,1262) @@ -1982,6 +2012,7 @@ def OA_10_1620(): 640 : (11 , OA_11_640), 796 : (10 , OA_10_796), 896 : (15 , OA_15_896), + 1078 : (9 , OA_9_1078), 1262 : (25, OA_25_1262), 1620 : (10, OA_10_1620), } From da421999df22d2a0c851630eb6c9fd33b448d0c3 Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Mon, 1 Dec 2014 20:45:36 +0530 Subject: [PATCH 201/698] trac #17149: OA(9,1612) --- src/sage/combinat/designs/database.py | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/sage/combinat/designs/database.py b/src/sage/combinat/designs/database.py index cd392748f45..c28ea1c1871 100644 --- a/src/sage/combinat/designs/database.py +++ b/src/sage/combinat/designs/database.py @@ -1946,6 +1946,36 @@ def OA_25_1262(): return OA_from_PBD(25,1262,PBD,check=False) +def OA_9_1612(): + r""" + Returns an OA(9,1612) + + This is obtained through the generalized Brouwer-van Rees + construction. Indeed, `1612 = 89.17 + (99=9.11)` and there exists an + `OA(9,100) - OA(9,11)`. + + .. NOTE:: + + This function should be removed once + :func:`~sage.combinat.designs.orthogonal_arrays_find_recursive.find_brouwer_van_rees_with_one_truncated_column` + can handle all incomplete orthogonal arrays obtained through + :func:`~sage.combinat.designs.orthogonal_arrays.incomplete_orthogonal_array`. + + EXAMPLES:: + + sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array + sage: from sage.combinat.designs.database import OA_9_1612 + sage: OA = OA_9_1612() # not tested -- ~6s + sage: print is_orthogonal_array(OA,9,1612,2) # not tested -- ~6s + True + + The design is available from the general constructor:: + + sage: designs.orthogonal_arrays.is_available(9,1612) + True + """ + return wilson_construction(None,9,17,89,[[(11,9)]]) + def OA_10_1620(): r""" Returns an OA(10,1620) @@ -2014,6 +2044,7 @@ def OA_10_1620(): 896 : (15 , OA_15_896), 1078 : (9 , OA_9_1078), 1262 : (25, OA_25_1262), + 1612 : (9 , OA_9_1612), 1620 : (10, OA_10_1620), } # Add this data to the module's doc From 5f790bbf0d4ba2c4d0db33cd98ef66c245f051dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Mon, 1 Dec 2014 17:26:53 +0100 Subject: [PATCH 202/698] 17424: use the terminology 'catalog' for consistency with our other catalogs of groups, algebras, ... --- src/sage/combinat/posets/poset_examples.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/posets/poset_examples.py b/src/sage/combinat/posets/poset_examples.py index 6dea0c2cfe5..f26d3d1a160 100644 --- a/src/sage/combinat/posets/poset_examples.py +++ b/src/sage/combinat/posets/poset_examples.py @@ -1,7 +1,7 @@ r""" -A collection of posets and lattices. +A catalog of posets and lattices. -All common posets can be accessed through the ``posets.`` object:: +Some common posets can be accessed through the ``posets.`` object:: sage: posets.PentagonPoset() Finite lattice containing 5 elements @@ -11,7 +11,7 @@ sage: Posets(5) Posets containing 5 vertices -**Index of common posets:** +**Catalog of common posets:** .. csv-table:: :class: contentstable From 0311b867b41b608c35d95efdf885caa1b220b11e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 2 Dec 2014 10:59:07 +0100 Subject: [PATCH 203/698] trac #174xx cleanup of doc (mainly) in quiver_mutation_type --- .../quiver_mutation_type.py | 184 ++++++++++-------- 1 file changed, 107 insertions(+), 77 deletions(-) diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py index c4e4c742b0e..dee53b84f50 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py @@ -25,6 +25,7 @@ from sage.all import prod from sage.matrix.all import matrix + class QuiverMutationTypeFactory(SageObject): def __call__(self, *args): """ @@ -206,7 +207,8 @@ def samples(self, finite=None, affine=None, elliptic=None, mutation_finite=None) Returns a sample of the available quiver mutations types. INPUT: - - ``finite``, ``affine``, ``elliptic``, ``mutation_finite`` -- (default:None) if True or False, only these samples are returned. + + - ``finite``, ``affine``, ``elliptic``, ``mutation_finite`` -- (default:``None``) if ``True`` or ``False``, only these samples are returned. EXAMPLES:: @@ -282,7 +284,7 @@ def _samples(self): For the compendium on the cluster algebra and quiver package in Sage see - http://arxiv.org/abs/1102.4844 + :arxiv:`1102.4844` A `B`-matrix is a skew-symmetrizable `( n \times n )`-matrix `M`. I.e., there exists an invertible diagonal matrix `D` such that `DM` is skew-symmetric. @@ -331,7 +333,7 @@ def _samples(self): - A good reference for finite and affine Dynkin diagrams, including Kac's notation, is the Wikipedia article on `Dynkin diagrams `_. -- A good reference for the skew-symmetrizable elliptic diagrams is "Cluster algebras of finite mutation type via unfolding" by A. Felikson, M. Shapiro, and P. Tumarkin, `arXiv:1006.4276v4 `_. +- A good reference for the skew-symmetrizable elliptic diagrams is "Cluster algebras of finite mutation type via unfolding" by A. Felikson, M. Shapiro, and P. Tumarkin, :arxiv:`1006.4276v4`. EXAMPLES: @@ -564,10 +566,12 @@ def _samples(self): [ ['A', 3], ['B', 4] ] """ + class QuiverMutationType_abstract(UniqueRepresentation,SageObject): def __eq__(self,other): """ - Returns True iff self and other represent the same quiver mutation type. + Returns ``True`` iff ``self`` and ``other`` represent the same quiver + mutation type. EXAMPLES:: @@ -583,7 +587,7 @@ def __eq__(self,other): def _repr_(self): """ - Returns the string representation of self. + Returns the string representation of ``self``. EXAMPLES:: @@ -594,12 +598,12 @@ def _repr_(self): def plot(self, circular=False, directed=True): """ - Returns the plot of the underlying graph or digraph of self. + Returns the plot of the underlying graph or digraph of ``self``. INPUT: - - ``circular`` -- (default:False) if True, the circular plot is chosen, otherwise >>spring<< is used. - - ``directed`` -- (default: True) if True, the directed version is shown, otherwise the undirected. + - ``circular`` -- (default:``False``) if ``True``, the circular plot is chosen, otherwise >>spring<< is used. + - ``directed`` -- (default: ``True``) if ``True``, the directed version is shown, otherwise the undirected. EXAMPLES:: @@ -611,14 +615,15 @@ def plot(self, circular=False, directed=True): def show(self, circular=False, directed=True): """ - Shows the plot of the underlying digraph of self. + Shows the plot of the underlying digraph of ``self``. INPUT: - - ``circular`` -- (default:False) if True, the circular plot is chosen, otherwise >>spring<< is used. - - ``directed`` -- (default: True) if True, the directed version is shown, otherwise the undirected. + - ``circular`` -- (default:``False``) if ``True``, the circular plot is chosen, otherwise >>spring<< is used. + - ``directed`` -- (default: ``True``) if ``True``, the directed version is shown, otherwise the undirected. TESTS:: + sage: QMT = QuiverMutationType(['A',5]) sage: QMT.show() # long time """ @@ -626,7 +631,7 @@ def show(self, circular=False, directed=True): def letter(self): """ - Returns the classification letter of self. + Returns the classification letter of ``self``. EXAMPLES:: @@ -654,7 +659,9 @@ def letter(self): def rank(self): """ - Returns the rank, i.e., the number of vertices in the standard quiver of self. + Returns the rank in the standard quiver of ``self``. + + The rank is the number of vertices. EXAMPLES:: @@ -688,9 +695,10 @@ def rank(self): @cached_method def b_matrix(self): """ - Returns the B-matrix of the standard quiver of self. The conventions - for B-matrices agree with Fomin-Zelevinsky (up to a reordering of - the simple roots). + Returns the B-matrix of the standard quiver of ``self``. + + The conventions for B-matrices agree with Fomin-Zelevinsky (up + to a reordering of the simple roots). EXAMPLES:: @@ -713,14 +721,15 @@ def b_matrix(self): [ 0 0 0 -1 0 -1] [ 0 0 0 0 2 0] """ - return _edge_list_to_matrix( self._digraph.edges(), self._rank, 0 ) + return _edge_list_to_matrix(self._digraph.edges(), self._rank, 0) @cached_method def standard_quiver(self): """ - Returns the standard quiver of self. + Returns the standard quiver of ``self``. EXAMPLES:: + sage: mut_type = QuiverMutationType( ['A',5] ); mut_type ['A', 5] sage: mut_type.standard_quiver() @@ -742,14 +751,14 @@ def standard_quiver(self): Quiver on 12 vertices of type [ ['A', 3], ['B', 3], ['X', 6] ] """ from quiver import ClusterQuiver - Q = ClusterQuiver( self._digraph ) + Q = ClusterQuiver(self._digraph) Q._mutation_type = self return Q @cached_method def cartan_matrix(self): """ - Returns the Cartan matrix of self. + Returns the Cartan matrix of ``self``. Note that (up to a reordering of the simple roots) the convention for the definition of Cartan matrix, used here and elsewhere in Sage, @@ -791,7 +800,7 @@ def cartan_matrix(self): def is_irreducible(self): """ - Returns True if self is irreducible. + Returns ``True`` if ``self`` is irreducible. EXAMPLES:: @@ -803,8 +812,10 @@ def is_irreducible(self): def is_mutation_finite(self): """ - Returns True if self is of finite mutation type (i.e. its mutation - class has only finitely many different B-matrices). + Returns ``True`` if ``self`` is of finite mutation type. + + This means that its mutation class has only finitely many + different B-matrices. EXAMPLES:: @@ -816,7 +827,10 @@ class has only finitely many different B-matrices). def is_simply_laced(self): """ - Returns True if self is simply laced (i.e., the only arrows that appear in the quiver of self are single unlabelled arrows). + Returns ``True`` if ``self`` is simply laced. + + This means that the only arrows that appear in the quiver of + ``self`` are single unlabelled arrows. EXAMPLES:: @@ -836,7 +850,7 @@ def is_simply_laced(self): def is_skew_symmetric(self): """ - Returns True if the B-matrix of self is skew-symmetric. + Returns ``True`` if the B-matrix of ``self`` is skew-symmetric. EXAMPLES:: @@ -856,8 +870,10 @@ def is_skew_symmetric(self): def is_finite(self): """ - Returns True if self is of finite type (i.e., the cluster algebra - associated to self has only a finite number of cluster variables). + Returns ``True`` if ``self`` is of finite type. + + This means that the cluster algebra associated to ``self`` has + only a finite number of cluster variables. EXAMPLES:: @@ -873,7 +889,7 @@ def is_finite(self): def is_affine(self): """ - Returns True if self is of affine type. + Returns ``True`` if ``self`` is of affine type. EXAMPLES:: @@ -892,7 +908,7 @@ def is_affine(self): def is_elliptic(self): """ - Returns True if self is of elliptic type. + Returns ``True`` if ``self`` is of elliptic type. EXAMPLES:: @@ -911,7 +927,7 @@ def is_elliptic(self): def properties(self): """ - Prints a scheme of all properties of self. + Prints a scheme of all properties of ``self``. Most properties have natural definitions for either irreducible or reducible types. ``affine`` and ``elliptic`` are only defined for @@ -999,7 +1015,9 @@ def properties(self): print '\t- affine: ', self.is_affine() print '\t- elliptic: ', self.is_elliptic() -class QuiverMutationType_Irreducible(QuiverMutationType_abstract,UniqueRepresentation,SageObject): + +class QuiverMutationType_Irreducible(QuiverMutationType_abstract, + UniqueRepresentation, SageObject): """ The mutation type for a cluster algebra or a quiver. Should not be called directly, but through QuiverMutationType. """ @@ -1546,7 +1564,7 @@ def __init__(self, letter, rank, twist=None): def irreducible_components( self ): """ - Returns a list of all irreducible components of self. + Returns a list of all irreducible components of ``self``. EXAMPLES:: @@ -1560,7 +1578,7 @@ def irreducible_components( self ): @cached_method def class_size(self): """ - If it is known, the size of the mutation class of all quivers which are mutation equivalent to the standard quiver of self (up to isomorphism) is returned. + If it is known, the size of the mutation class of all quivers which are mutation equivalent to the standard quiver of ``self`` (up to isomorphism) is returned. Otherwise, NotImplemented is returned. Formula for finite type A is taken from Torkildsen - Counting @@ -1752,7 +1770,7 @@ def class_size(self): def dual(self): """ - Returns the QuiverMutationType which is dual to self. + Returns the QuiverMutationType which is dual to ``self``. EXAMPLES:: @@ -1806,7 +1824,9 @@ def dual(self): else: return self -class QuiverMutationType_Reducible(QuiverMutationType_abstract,UniqueRepresentation,SageObject): + +class QuiverMutationType_Reducible(QuiverMutationType_abstract, + UniqueRepresentation, SageObject): """ The mutation type for a cluster algebra or a quiver. Should not be called directly, but through QuiverMutationType. Inherits from @@ -1869,7 +1889,7 @@ def __init__(self, *args): def irreducible_components( self ): """ - Returns a list of all irreducible components of self. + Returns a list of all irreducible components of ``self``. EXAMPLES:: @@ -1893,9 +1913,9 @@ def irreducible_components( self ): @cached_method def class_size(self): """ - If it is known, the size of the mutation class of all quivers which are - mutation equivalent to the standard quiver of self (up to isomorphism) - is returned. + If it is known, the size of the mutation class of all quivers + which are mutation equivalent to the standard quiver of + ``self`` (up to isomorphism) is returned. Otherwise, NotImplemented is returned. @@ -1934,7 +1954,7 @@ def class_size(self): def dual(self): """ - Returns the QuiverMutationType which is dual to self. + Returns the QuiverMutationType which is dual to ``self``. EXAMPLES:: @@ -1946,21 +1966,24 @@ def dual(self): comps = self.irreducible_components() return QuiverMutationType( [comp.dual() for comp in comps ] ) + def _construct_classical_mutation_classes(n): r""" - Returns a dict with keys being tuples representing regular QuiverMutationTypes of the given rank, and with values being - lists or sets containing all mutation equivalent quivers as dig6 data. + Returns a dict with keys being tuples representing regular + QuiverMutationTypes of the given rank, and with values being lists + or sets containing all mutation equivalent quivers as dig6 data. EXAMPLES:: - sage: from sage.combinat.cluster_algebra_quiver.quiver_mutation_type import _construct_classical_mutation_classes - sage: rank_2_classes = _construct_classical_mutation_classes(2) # long time - sage: for mut_class in sorted(rank_2_classes.keys(),key=str): # long time - ... print mut_class, rank_2_classes[mut_class] - ('A', (1, 1), 1) [('AO', (((0, 1), (2, -2)),))] - ('A', 2) [('AO', ())] - ('B', 2) [('AO', (((0, 1), (1, -2)),)), ('AO', (((0, 1), (2, -1)),))] - ('BC', 1, 1) [('AO', (((0, 1), (1, -4)),)), ('AO', (((0, 1), (4, -1)),))] + sage: from sage.combinat.cluster_algebra_quiver.quiver_mutation_type import _construct_classical_mutation_classes + sage: rank_2_classes = _construct_classical_mutation_classes(2) # long time + sage: for mut_class in sorted(rank_2_classes.keys(),key=str): # long time + ....: print mut_class, rank_2_classes[mut_class] + ('A', (1, 1), 1) [('AO', (((0, 1), (2, -2)),))] + ('A', 2) [('AO', ())] + ('B', 2) [('AO', (((0, 1), (1, -2)),)), ('AO', (((0, 1), (2, -1)),))] + ('BC', 1, 1) [('AO', (((0, 1), (1, -4)),)), + ('AO', (((0, 1), (4, -1)),))] """ from sage.combinat.cluster_algebra_quiver.quiver import ClusterQuiver data = {} @@ -2000,22 +2023,23 @@ def _construct_classical_mutation_classes(n): return data + def _construct_exceptional_mutation_classes(n): r""" - Returns a dict with keys being tuples representing exceptional QuiverMutationTypes - of the given rank, and with values being lists or sets containing all - mutation equivalent quivers as dig6 data. + Returns a dict with keys being tuples representing exceptional + QuiverMutationTypes of the given rank, and with values being lists + or sets containing all mutation equivalent quivers as dig6 data. EXAMPLES:: - sage: from sage.combinat.cluster_algebra_quiver.quiver_mutation_type import _construct_exceptional_mutation_classes - sage: rank_3_exceptional = _construct_exceptional_mutation_classes(3) # long time - sage: for mut_class in sorted(rank_3_exceptional.keys(), key=str): # long time - ... print mut_class, rank_3_exceptional[mut_class] - ('G', 2, -1) [('BH?', (((1, 2), (1, -3)),)), ('BGO', (((2, 1), (3, -1)),)), ('BW?', (((0, 1), (3, -1)),)), ('BP?', (((0, 1), (1, -3)),)), - ('BP_', (((0, 1), (1, -3)), ((2, 0), (3, -1)))), ('BP_', (((0, 1), (3, -1)), ((1, 2), (1, -3)), ((2, 0), (2, -2))))] - ('G', 2, 1) [('BH?', (((1, 2), (3, -1)),)), ('BGO', (((2, 1), (1, -3)),)), ('BW?', (((0, 1), (1, -3)),)), ('BP?', (((0, 1), (3, -1)),)), - ('BKO', (((1, 0), (3, -1)), ((2, 1), (1, -3)))), ('BP_', (((0, 1), (2, -2)), ((1, 2), (1, -3)), ((2, 0), (3, -1))))] + sage: from sage.combinat.cluster_algebra_quiver.quiver_mutation_type import _construct_exceptional_mutation_classes + sage: rank_3_exceptional = _construct_exceptional_mutation_classes(3) # long time + sage: for mut_class in sorted(rank_3_exceptional.keys(), key=str): # long time + ....: print mut_class, rank_3_exceptional[mut_class] + ('G', 2, -1) [('BH?', (((1, 2), (1, -3)),)), ('BGO', (((2, 1), (3, -1)),)), ('BW?', (((0, 1), (3, -1)),)), ('BP?', (((0, 1), (1, -3)),)), + ('BP_', (((0, 1), (1, -3)), ((2, 0), (3, -1)))), ('BP_', (((0, 1), (3, -1)), ((1, 2), (1, -3)), ((2, 0), (2, -2))))] + ('G', 2, 1) [('BH?', (((1, 2), (3, -1)),)), ('BGO', (((2, 1), (1, -3)),)), ('BW?', (((0, 1), (1, -3)),)), ('BP?', (((0, 1), (3, -1)),)), + ('BKO', (((1, 0), (3, -1)), ((2, 1), (1, -3)))), ('BP_', (((0, 1), (2, -2)), ((1, 2), (1, -3)), ((2, 0), (3, -1))))] """ from sage.combinat.cluster_algebra_quiver.quiver import ClusterQuiver data = {} @@ -2058,6 +2082,7 @@ def _construct_exceptional_mutation_classes(n): return data + def _save_data_dig6(n, types='ClassicalExceptional', verbose=False): """ Saves all exceptional mutation classes as dig6 data into the file ``exc_classes_n.dig6`` in the folder ``DOT_SAGE``. @@ -2093,9 +2118,10 @@ def _save_data_dig6(n, types='ClassicalExceptional', verbose=False): import os.path import cPickle data = {} - possible_types = ['Classical','ClassicalExceptional','Exceptional'] + possible_types = ['Classical', 'ClassicalExceptional', 'Exceptional'] if types not in possible_types: - raise ValueError('The third input must be either ClassicalExceptional (default), Classical, or Exceptional.') + raise ValueError('The third input must be either ClassicalExceptional' + ' (default), Classical, or Exceptional.') if types in possible_types[:2]: data.update(_construct_classical_mutation_classes(n)) @@ -2114,6 +2140,7 @@ def _save_data_dig6(n, types='ClassicalExceptional', verbose=False): print "\nThe following types are saved to file", types_file,"and will now be used to determine quiver mutation types:" print keys + def save_quiver_data(n, up_to=True, types='ClassicalExceptional', verbose=True): r""" Saves mutation classes of certain quivers of ranks up to and equal to ``n`` or equal to ``n`` @@ -2125,8 +2152,8 @@ def save_quiver_data(n, up_to=True, types='ClassicalExceptional', verbose=True): - ``n``: the rank (or the upper limit on the rank) of the mutation classes that are being saved. - - ``up_to`` -- (default:True) if True, saves data for ranks smaller than or equal to ``n``. - If False, saves data for rank exactly ``n``. + - ``up_to`` -- (default:``True``) if ``True``, saves data for ranks smaller than or equal to ``n``. + If ``False``, saves data for rank exactly ``n``. - ``types`` -- (default:'ClassicalExceptional') if all, saves data for both exceptional mutation-finite quivers and for classical quiver. The input 'Exceptional' or 'Classical' is also allowed to save only part of this data. @@ -2169,7 +2196,8 @@ def save_quiver_data(n, up_to=True, types='ClassicalExceptional', verbose=True): # we finally clear the load_data load_data.clear_cache() -def _bipartite_graph_to_digraph( g ): + +def _bipartite_graph_to_digraph(g): """ Returns a digraph obtained from a bipartite graph g by choosing one set of the bipartition to be the set of sinks and the other to be the @@ -2198,9 +2226,10 @@ def _bipartite_graph_to_digraph( g ): dg.add_vertex(vert) return dg -def _is_mutation_type( data ): + +def _is_mutation_type(data): """ - Returns True if data is a QuiverMutationType. + Returns ``True`` if ``data`` is a QuiverMutationType. EXAMPLES:: @@ -2211,12 +2240,12 @@ def _is_mutation_type( data ): False """ try: - QuiverMutationType( data ) + QuiverMutationType(data) return True except Exception: return False -def _mutation_type_error( data ): +def _mutation_type_error(data): """ Outputs an error message because data which is not a valid quiver mutation type has been passed to QuiverMutationType. @@ -2244,7 +2273,8 @@ def _mutation_type_error( data ): raise ValueError(return_str) -def _edge_list_to_matrix( edges, n, m ): + +def _edge_list_to_matrix(edges, n, m): """ Returns the matrix obtained from the edge list of a quiver. @@ -2268,15 +2298,15 @@ def _edge_list_to_matrix( edges, n, m ): [ 0 1] [-1 0] """ - M = matrix(ZZ,n+m,n,sparse=True) + M = matrix(ZZ, n + m, n, sparse=True) for edge in edges: if edge[2] is None: - edge = (edge[0],edge[1],(1,-1)) + edge = (edge[0], edge[1], (1, -1)) elif edge[2] in ZZ: - edge = (edge[0],edge[1],(edge[2],-edge[2])) - v1,v2,(a,b) = edge + edge = (edge[0], edge[1], (edge[2], -edge[2])) + v1, v2, (a, b) = edge if v1 < n: - M[v2,v1] = b + M[v2, v1] = b if v2 < n: - M[v1,v2] = a + M[v1, v2] = a return M From 57eabf943fff95e7c8d2d3e91a548d169486c4fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 2 Dec 2014 12:05:42 +0100 Subject: [PATCH 204/698] trac #17432 imperative mode (Return !) and a few more line breaks --- .../quiver_mutation_type.py | 137 +++++++++++------- 1 file changed, 82 insertions(+), 55 deletions(-) diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py index dee53b84f50..8ad71365060 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py @@ -193,7 +193,7 @@ def __call__(self, *args): def _repr_(self): """ - Returns the string representation of ``self``. + Return the string representation of ``self``. EXAMPLES:: @@ -204,11 +204,13 @@ def _repr_(self): def samples(self, finite=None, affine=None, elliptic=None, mutation_finite=None): """ - Returns a sample of the available quiver mutations types. + Return a sample of the available quiver mutations types. INPUT: - - ``finite``, ``affine``, ``elliptic``, ``mutation_finite`` -- (default:``None``) if ``True`` or ``False``, only these samples are returned. + - ``finite``, ``affine``, ``elliptic``, ``mutation_finite`` -- + (default:``None``) if ``True`` or ``False``, only these + samples are returned. EXAMPLES:: @@ -250,7 +252,7 @@ def samples(self, finite=None, affine=None, elliptic=None, mutation_finite=None) @cached_method def _samples(self): """ - Returns a list of sample of available Cartan types. + Return a list of sample of available Cartan types. EXAMPLES:: @@ -331,9 +333,13 @@ def _samples(self): REFERENCES: -- A good reference for finite and affine Dynkin diagrams, including Kac's notation, is the Wikipedia article on `Dynkin diagrams `_. +- A good reference for finite and affine Dynkin diagrams, including + Kac's notation, is the Wikipedia article on `Dynkin diagrams + `_. -- A good reference for the skew-symmetrizable elliptic diagrams is "Cluster algebras of finite mutation type via unfolding" by A. Felikson, M. Shapiro, and P. Tumarkin, :arxiv:`1006.4276v4`. +- A good reference for the skew-symmetrizable elliptic diagrams is + "Cluster algebras of finite mutation type via unfolding" by + A. Felikson, M. Shapiro, and P. Tumarkin, :arxiv:`1006.4276v4`. EXAMPLES: @@ -570,7 +576,7 @@ def _samples(self): class QuiverMutationType_abstract(UniqueRepresentation,SageObject): def __eq__(self,other): """ - Returns ``True`` iff ``self`` and ``other`` represent the same quiver + Return ``True`` iff ``self`` and ``other`` represent the same quiver mutation type. EXAMPLES:: @@ -587,7 +593,7 @@ def __eq__(self,other): def _repr_(self): """ - Returns the string representation of ``self``. + Return the string representation of ``self``. EXAMPLES:: @@ -598,12 +604,15 @@ def _repr_(self): def plot(self, circular=False, directed=True): """ - Returns the plot of the underlying graph or digraph of ``self``. + Return the plot of the underlying graph or digraph of ``self``. INPUT: - - ``circular`` -- (default:``False``) if ``True``, the circular plot is chosen, otherwise >>spring<< is used. - - ``directed`` -- (default: ``True``) if ``True``, the directed version is shown, otherwise the undirected. + - ``circular`` -- (default:``False``) if ``True``, the + circular plot is chosen, otherwise >>spring<< is used. + + - ``directed`` -- (default: ``True``) if ``True``, the + directed version is shown, otherwise the undirected. EXAMPLES:: @@ -615,12 +624,15 @@ def plot(self, circular=False, directed=True): def show(self, circular=False, directed=True): """ - Shows the plot of the underlying digraph of ``self``. + Show the plot of the underlying digraph of ``self``. INPUT: - - ``circular`` -- (default:``False``) if ``True``, the circular plot is chosen, otherwise >>spring<< is used. - - ``directed`` -- (default: ``True``) if ``True``, the directed version is shown, otherwise the undirected. + - ``circular`` -- (default:``False``) if ``True``, the + circular plot is chosen, otherwise >>spring<< is used. + + - ``directed`` -- (default: ``True``) if ``True``, the + directed version is shown, otherwise the undirected. TESTS:: @@ -631,7 +643,7 @@ def show(self, circular=False, directed=True): def letter(self): """ - Returns the classification letter of ``self``. + Return the classification letter of ``self``. EXAMPLES:: @@ -659,7 +671,7 @@ def letter(self): def rank(self): """ - Returns the rank in the standard quiver of ``self``. + Return the rank in the standard quiver of ``self``. The rank is the number of vertices. @@ -695,7 +707,7 @@ def rank(self): @cached_method def b_matrix(self): """ - Returns the B-matrix of the standard quiver of ``self``. + Return the B-matrix of the standard quiver of ``self``. The conventions for B-matrices agree with Fomin-Zelevinsky (up to a reordering of the simple roots). @@ -726,7 +738,7 @@ def b_matrix(self): @cached_method def standard_quiver(self): """ - Returns the standard quiver of ``self``. + Return the standard quiver of ``self``. EXAMPLES:: @@ -758,7 +770,7 @@ def standard_quiver(self): @cached_method def cartan_matrix(self): """ - Returns the Cartan matrix of ``self``. + Return the Cartan matrix of ``self``. Note that (up to a reordering of the simple roots) the convention for the definition of Cartan matrix, used here and elsewhere in Sage, @@ -800,7 +812,7 @@ def cartan_matrix(self): def is_irreducible(self): """ - Returns ``True`` if ``self`` is irreducible. + Return ``True`` if ``self`` is irreducible. EXAMPLES:: @@ -812,7 +824,7 @@ def is_irreducible(self): def is_mutation_finite(self): """ - Returns ``True`` if ``self`` is of finite mutation type. + Return ``True`` if ``self`` is of finite mutation type. This means that its mutation class has only finitely many different B-matrices. @@ -827,7 +839,7 @@ def is_mutation_finite(self): def is_simply_laced(self): """ - Returns ``True`` if ``self`` is simply laced. + Return ``True`` if ``self`` is simply laced. This means that the only arrows that appear in the quiver of ``self`` are single unlabelled arrows. @@ -850,7 +862,7 @@ def is_simply_laced(self): def is_skew_symmetric(self): """ - Returns ``True`` if the B-matrix of ``self`` is skew-symmetric. + Return ``True`` if the B-matrix of ``self`` is skew-symmetric. EXAMPLES:: @@ -870,7 +882,7 @@ def is_skew_symmetric(self): def is_finite(self): """ - Returns ``True`` if ``self`` is of finite type. + Return ``True`` if ``self`` is of finite type. This means that the cluster algebra associated to ``self`` has only a finite number of cluster variables. @@ -889,7 +901,7 @@ def is_finite(self): def is_affine(self): """ - Returns ``True`` if ``self`` is of affine type. + Return ``True`` if ``self`` is of affine type. EXAMPLES:: @@ -908,7 +920,7 @@ def is_affine(self): def is_elliptic(self): """ - Returns ``True`` if ``self`` is of elliptic type. + Return ``True`` if ``self`` is of elliptic type. EXAMPLES:: @@ -927,7 +939,7 @@ def is_elliptic(self): def properties(self): """ - Prints a scheme of all properties of ``self``. + Print a scheme of all properties of ``self``. Most properties have natural definitions for either irreducible or reducible types. ``affine`` and ``elliptic`` are only defined for @@ -1019,7 +1031,8 @@ def properties(self): class QuiverMutationType_Irreducible(QuiverMutationType_abstract, UniqueRepresentation, SageObject): """ - The mutation type for a cluster algebra or a quiver. Should not be called directly, but through QuiverMutationType. + The mutation type for a cluster algebra or a quiver. Should not be + called directly, but through QuiverMutationType. """ def __init__(self, letter, rank, twist=None): """ @@ -1564,7 +1577,7 @@ def __init__(self, letter, rank, twist=None): def irreducible_components( self ): """ - Returns a list of all irreducible components of ``self``. + Return a list of all irreducible components of ``self``. EXAMPLES:: @@ -1578,8 +1591,11 @@ def irreducible_components( self ): @cached_method def class_size(self): """ - If it is known, the size of the mutation class of all quivers which are mutation equivalent to the standard quiver of ``self`` (up to isomorphism) is returned. - Otherwise, NotImplemented is returned. + If it is known, the size of the mutation class of all quivers + which are mutation equivalent to the standard quiver of + ``self`` (up to isomorphism) is returned. + + Otherwise, ``NotImplemented`` is returned. Formula for finite type A is taken from Torkildsen - Counting cluster-tilted algebras of type `A_n`. @@ -1770,7 +1786,7 @@ def class_size(self): def dual(self): """ - Returns the QuiverMutationType which is dual to ``self``. + Return the QuiverMutationType which is dual to ``self``. EXAMPLES:: @@ -1828,8 +1844,8 @@ def dual(self): class QuiverMutationType_Reducible(QuiverMutationType_abstract, UniqueRepresentation, SageObject): """ - The mutation type for a cluster algebra or a quiver. Should not be called - directly, but through QuiverMutationType. Inherits from + The mutation type for a cluster algebra or a quiver. Should not be + called directly, but through QuiverMutationType. Inherits from QuiverMutationType_abstract. """ def __init__(self, *args): @@ -1889,7 +1905,7 @@ def __init__(self, *args): def irreducible_components( self ): """ - Returns a list of all irreducible components of ``self``. + Return a list of all irreducible components of ``self``. EXAMPLES:: @@ -1917,7 +1933,7 @@ def class_size(self): which are mutation equivalent to the standard quiver of ``self`` (up to isomorphism) is returned. - Otherwise, NotImplemented is returned. + Otherwise, ``NotImplemented`` is returned. EXAMPLES:: @@ -1954,7 +1970,7 @@ def class_size(self): def dual(self): """ - Returns the QuiverMutationType which is dual to ``self``. + Return the QuiverMutationType which is dual to ``self``. EXAMPLES:: @@ -1969,7 +1985,7 @@ def dual(self): def _construct_classical_mutation_classes(n): r""" - Returns a dict with keys being tuples representing regular + Return a dict with keys being tuples representing regular QuiverMutationTypes of the given rank, and with values being lists or sets containing all mutation equivalent quivers as dig6 data. @@ -2026,7 +2042,7 @@ def _construct_classical_mutation_classes(n): def _construct_exceptional_mutation_classes(n): r""" - Returns a dict with keys being tuples representing exceptional + Return a dict with keys being tuples representing exceptional QuiverMutationTypes of the given rank, and with values being lists or sets containing all mutation equivalent quivers as dig6 data. @@ -2036,10 +2052,16 @@ def _construct_exceptional_mutation_classes(n): sage: rank_3_exceptional = _construct_exceptional_mutation_classes(3) # long time sage: for mut_class in sorted(rank_3_exceptional.keys(), key=str): # long time ....: print mut_class, rank_3_exceptional[mut_class] - ('G', 2, -1) [('BH?', (((1, 2), (1, -3)),)), ('BGO', (((2, 1), (3, -1)),)), ('BW?', (((0, 1), (3, -1)),)), ('BP?', (((0, 1), (1, -3)),)), - ('BP_', (((0, 1), (1, -3)), ((2, 0), (3, -1)))), ('BP_', (((0, 1), (3, -1)), ((1, 2), (1, -3)), ((2, 0), (2, -2))))] - ('G', 2, 1) [('BH?', (((1, 2), (3, -1)),)), ('BGO', (((2, 1), (1, -3)),)), ('BW?', (((0, 1), (1, -3)),)), ('BP?', (((0, 1), (3, -1)),)), - ('BKO', (((1, 0), (3, -1)), ((2, 1), (1, -3)))), ('BP_', (((0, 1), (2, -2)), ((1, 2), (1, -3)), ((2, 0), (3, -1))))] + ('G', 2, -1) [('BH?', (((1, 2), (1, -3)),)), + ('BGO', (((2, 1), (3, -1)),)), ('BW?', (((0, 1), (3, -1)),)), + ('BP?', (((0, 1), (1, -3)),)), + ('BP_', (((0, 1), (1, -3)), ((2, 0), (3, -1)))), + ('BP_', (((0, 1), (3, -1)), ((1, 2), (1, -3)), ((2, 0), (2, -2))))] + ('G', 2, 1) [('BH?', (((1, 2), (3, -1)),)), + ('BGO', (((2, 1), (1, -3)),)), ('BW?', (((0, 1), (1, -3)),)), + ('BP?', (((0, 1), (3, -1)),)), + ('BKO', (((1, 0), (3, -1)), ((2, 1), (1, -3)))), + ('BP_', (((0, 1), (2, -2)), ((1, 2), (1, -3)), ((2, 0), (3, -1))))] """ from sage.combinat.cluster_algebra_quiver.quiver import ClusterQuiver data = {} @@ -2085,7 +2107,7 @@ def _construct_exceptional_mutation_classes(n): def _save_data_dig6(n, types='ClassicalExceptional', verbose=False): """ - Saves all exceptional mutation classes as dig6 data into the file ``exc_classes_n.dig6`` in the folder ``DOT_SAGE``. + Save all exceptional mutation classes as dig6 data into the file ``exc_classes_n.dig6`` in the folder ``DOT_SAGE``. TESTS:: @@ -2143,20 +2165,25 @@ def _save_data_dig6(n, types='ClassicalExceptional', verbose=False): def save_quiver_data(n, up_to=True, types='ClassicalExceptional', verbose=True): r""" - Saves mutation classes of certain quivers of ranks up to and equal to ``n`` or equal to ``n`` - to ``DOT_SAGE/cluster_algebra_quiver/mutation_classes_n.dig6``. + Save mutation classes of certain quivers of ranks up to and equal + to ``n`` or equal to ``n`` to + ``DOT_SAGE/cluster_algebra_quiver/mutation_classes_n.dig6``. This data will then be used to determine quiver mutation types. INPUT: - - ``n``: the rank (or the upper limit on the rank) of the mutation classes that are being saved. + - ``n``: the rank (or the upper limit on the rank) of the mutation + classes that are being saved. - - ``up_to`` -- (default:``True``) if ``True``, saves data for ranks smaller than or equal to ``n``. - If ``False``, saves data for rank exactly ``n``. + - ``up_to`` -- (default:``True``) if ``True``, saves data for + ranks smaller than or equal to ``n``. If ``False``, saves data + for rank exactly ``n``. - - ``types`` -- (default:'ClassicalExceptional') if all, saves data for both exceptional mutation-finite quivers and for classical quiver. - The input 'Exceptional' or 'Classical' is also allowed to save only part of this data. + - ``types`` -- (default:'ClassicalExceptional') if all, saves data + for both exceptional mutation-finite quivers and for classical + quiver. The input 'Exceptional' or 'Classical' is also allowed + to save only part of this data. TESTS:: @@ -2199,7 +2226,7 @@ def save_quiver_data(n, up_to=True, types='ClassicalExceptional', verbose=True): def _bipartite_graph_to_digraph(g): """ - Returns a digraph obtained from a bipartite graph g by choosing one + Return a digraph obtained from a bipartite graph g by choosing one set of the bipartition to be the set of sinks and the other to be the set of sources. @@ -2229,7 +2256,7 @@ def _bipartite_graph_to_digraph(g): def _is_mutation_type(data): """ - Returns ``True`` if ``data`` is a QuiverMutationType. + Return ``True`` if ``data`` is a QuiverMutationType. EXAMPLES:: @@ -2247,7 +2274,7 @@ def _is_mutation_type(data): def _mutation_type_error(data): """ - Outputs an error message because data which is not a valid quiver mutation + Output an error message because data which is not a valid quiver mutation type has been passed to QuiverMutationType. EXAMPLES:: @@ -2276,7 +2303,7 @@ def _mutation_type_error(data): def _edge_list_to_matrix(edges, n, m): """ - Returns the matrix obtained from the edge list of a quiver. + Return the matrix obtained from the edge list of a quiver. INPUT: From bbbe0de4d69f80a2e50303636dea0ad646a371d9 Mon Sep 17 00:00:00 2001 From: Joao de Faria Date: Tue, 2 Dec 2014 08:44:24 -0500 Subject: [PATCH 205/698] Fixed code to read dim_rel +1 , added example that caused original issue --- src/sage/schemes/projective/projective_point.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/sage/schemes/projective/projective_point.py b/src/sage/schemes/projective/projective_point.py index 4c54016a6ad..7d28f9ec9ba 100644 --- a/src/sage/schemes/projective/projective_point.py +++ b/src/sage/schemes/projective/projective_point.py @@ -1115,8 +1115,19 @@ def clear_denominators(self): sage: Q=X([1/2,1/2,1]); sage: Q.clear_denominators(); Q (1 : 1 : 2) + + :: + + sage: PS. = ProjectiveSpace(QQ,1) + sage: Q=PS([3,2]) + sage: Q.scale_by(2/3) + sage: print Q + (1 : 2/3) + sage: Q.clear_denominators() + sage: print Q + (3 : 2) """ - self.scale_by(lcm([self[i].denominator() for i in range(self.codomain().ambient_space().dimension_relative())])) + self.scale_by(lcm([self[i].denominator() for i in range(self.codomain().ambient_space().dimension_relative()+1)])) class SchemeMorphism_point_projective_finite_field(SchemeMorphism_point_projective_field): From b9179dda733e03e144160af6c816f22c92e7c95f Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Tue, 2 Dec 2014 05:49:26 -0800 Subject: [PATCH 206/698] Treat GCC as a special case for updates. This simplifies the logic involved i GCC installation detection. --- build/install | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/build/install b/build/install index dde17569d3a..52814ba68e1 100755 --- a/build/install +++ b/build/install @@ -106,19 +106,6 @@ else # SAGE_INSTALL_GCC is not set, install GCC when needed. need_to_install_gcc=no - if [ -f "$SAGE_LOCAL/bin/gcc" -a "`ls $SAGE_SPKG_INST/gcc-*`" != "" ]; then - # GCC is already installed. To disable unneeded rebuilding - # of GCC, we touch the installed file for GCC, such that it will - # really only be built if one of its dependencies has been upgraded. - echo >&2 "GCC was installed before, it will get re-installed if needed." - need_to_install_gcc=yes - for f in "$SAGE_SPKG_INST"/gcc-*; do - if [ -f "$f" ]; then - touch "$f" - fi - done - fi - # Check whether $CXX is some version of GCC. If it's a different # compiler, install GCC. CXXtype=`testcxx.sh $CXX` From a02e785c5926887213eb0017dc9079223a759deb Mon Sep 17 00:00:00 2001 From: bhutz Date: Tue, 2 Dec 2014 12:01:11 -0500 Subject: [PATCH 207/698] 17325: clean up docs and condensed code --- .../schemes/projective/projective_point.py | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/sage/schemes/projective/projective_point.py b/src/sage/schemes/projective/projective_point.py index 7d28f9ec9ba..0c791f2edf6 100644 --- a/src/sage/schemes/projective/projective_point.py +++ b/src/sage/schemes/projective/projective_point.py @@ -1093,41 +1093,38 @@ def clear_denominators(self): EXAMPLES:: - sage: R.=PolynomialRing(QQ) - sage: P.=ProjectiveSpace(FractionField(R),2) - sage: Q=P([t,3/t^2,1]) + sage: R. = PolynomialRing(QQ) + sage: P. = ProjectiveSpace(FractionField(R), 2) + sage: Q = P([t, 3/t^2, 1]) sage: Q.clear_denominators(); Q (t^3 : 3 : t^2) :: - sage: R.=PolynomialRing(QQ) - sage: K.=NumberField(x^2-3) - sage: P.=ProjectiveSpace(K,2) - sage: Q=P([1/w,3,0]) + sage: R. = PolynomialRing(QQ) + sage: K. = NumberField(x^2 - 3) + sage: P. = ProjectiveSpace(K, 2) + sage: Q = P([1/w, 3, 0]) sage: Q.clear_denominators(); Q (w : 9 : 0) :: - sage: P.=ProjectiveSpace(QQ,2) - sage: X=P.subscheme(x^2-y^2); - sage: Q=X([1/2,1/2,1]); + sage: P. = ProjectiveSpace(QQ, 2) + sage: X = P.subscheme(x^2 - y^2); + sage: Q = X([1/2, 1/2, 1]); sage: Q.clear_denominators(); Q (1 : 1 : 2) :: - sage: PS. = ProjectiveSpace(QQ,1) - sage: Q=PS([3,2]) - sage: Q.scale_by(2/3) - sage: print Q + sage: PS. = ProjectiveSpace(QQ, 1) + sage: Q = PS.point([1, 2/3], False); Q (1 : 2/3) - sage: Q.clear_denominators() - sage: print Q + sage: Q.clear_denominators(); Q (3 : 2) """ - self.scale_by(lcm([self[i].denominator() for i in range(self.codomain().ambient_space().dimension_relative()+1)])) + self.scale_by(lcm([t.denominator() for t in self])) class SchemeMorphism_point_projective_finite_field(SchemeMorphism_point_projective_field): From 32ae67c2fe24800943b883fe7f591bea784e5789 Mon Sep 17 00:00:00 2001 From: Ralf Stephan Date: Tue, 2 Dec 2014 18:22:55 +0100 Subject: [PATCH 208/698] 17399: do not let maxima handle ex.series coefficients --- src/sage/symbolic/expression.pyx | 36 +++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 021c40c91eb..8605f8f295c 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -5156,17 +5156,37 @@ cdef class Expression(CommutativeRingElement): sage: p = (17/3*a)*x^(3/2) + x*y + 1/x + x^x sage: p.coefficients(x) [[1, -1], [x^x, 0], [y, 1], [17/3*a, 3/2]] + + Series coefficients are now handled correctly (:trac:`17399`):: + + sage: s=(1/(1-x)).series(x,6) + sage: s.coeffs() + [[1, 0], [1, 1], [1, 2], [1, 3], [1, 4], [1, 5]] + sage: x,y = var("x,y") + sage: s=(1/(1-y-x)).series(x,6) + sage: s.coeffs(y) + [] + sage: s.coeffs() + [[-1/(y - 1), 0], + [(y - 1)^(-2), 1], + [-1/(y - 1)^3, 2], + [(y - 1)^(-4), 3], + [-1/(y - 1)^5, 4], + [(y - 1)^(-6), 5]] """ - f = self._maxima_() - maxima = f.parent() - maxima._eval_line('load(coeflist)') if x is None: x = self.default_variable() - x = self.parent().var(repr(x)) - G = f.coeffs(x) - from sage.calculus.calculus import symbolic_expression_from_maxima_string - S = symbolic_expression_from_maxima_string(repr(G)) - return S[1:] + # x = self.parent().var(str(x)) + if is_a_series(self._gobj): + return [[self.coeff(x, d), d] for d in xrange(self.degree(x))] + else: + f = self._maxima_() + maxima = f.parent() + maxima._eval_line('load(coeflist)') + G = f.coeffs(x) + from sage.calculus.calculus import symbolic_expression_from_maxima_string + S = symbolic_expression_from_maxima_string(repr(G)) + return S[1:] coeffs = coefficients From b20353c382e1cd77fa5e34092a7989253e9a9e67 Mon Sep 17 00:00:00 2001 From: Ben Hutz Date: Tue, 2 Dec 2014 14:39:11 -0500 Subject: [PATCH 209/698] 17429: make == a positive check for project points and morphisms --- .../schemes/projective/projective_morphism.py | 6 +----- .../schemes/projective/projective_point.py | 21 ++++++++++++------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index f9b53e8458b..070f9caad02 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -324,11 +324,7 @@ def __eq__(self, right): if self.parent() != right.parent(): return False n = len(self._polys) - for i in range(0, n): - for j in range(i + 1, n): - if self._polys[i] * right._polys[j] != self._polys[j] * right._polys[i]: - return False - return True + return all([self[i]*right[j] == self[j]*right[i] for i in range(0, n) for j in range(i+1, n)]) def __ne__(self, right): """ diff --git a/src/sage/schemes/projective/projective_point.py b/src/sage/schemes/projective/projective_point.py index 4c54016a6ad..e014d241f6e 100644 --- a/src/sage/schemes/projective/projective_point.py +++ b/src/sage/schemes/projective/projective_point.py @@ -243,20 +243,27 @@ def __eq__(self,right): sage: P==Q True + Check that :trac:`17429` is fixed:: + + sage: R. = PolynomialRing(QQ) + sage: r = (x^2-x-3).polynomial(x).roots(ComplexIntervalField(),multiplicities = False) + sage: P. = ProjectiveSpace(ComplexIntervalField(), 1) + sage: P1 = P(r[0], 1) + sage: H = End(P) + sage: f = H([x^2-3*y^2, y^2]) + sage: Q1 = f(P1) + sage: Q1 == P1 + False """ if not isinstance(right, SchemeMorphism_point): try: right = self.codomain()(right) except TypeError: return False - if self.codomain()!=right.codomain(): + if self.codomain() != right.codomain(): return False - n=len(self._coords) - for i in range(0,n): - for j in range(i+1,n): - if self._coords[i]*right._coords[j] != self._coords[j]*right._coords[i]: - return False - return True + n = len(self._coords) + return all([self[i]*right[j] == self[j]*right[i] for i in range(0,n) for j in range(i+1, n)]) def __ne__(self,right): """ From c8108f8b96b33fcedbb22e13f331e3f2ed99ab05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Wed, 3 Dec 2014 09:10:15 +0100 Subject: [PATCH 210/698] 16256: fixed ReST typo in newly included file preventing PDF doc compilation --- src/sage/combinat/words/word_char.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/words/word_char.pyx b/src/sage/combinat/words/word_char.pyx index aa69849115a..5ff580d84ad 100644 --- a/src/sage/combinat/words/word_char.pyx +++ b/src/sage/combinat/words/word_char.pyx @@ -31,7 +31,7 @@ cdef size_t SIZE_T_MAX = -( 1) def reversed_word_iterator(WordDatatype_char w): r""" This function exists only because it is not possible to use yield in the - special method `__reversed__`. + special method ``__reversed__``. EXAMPLES:: From d7da52cfd46a01f6710b79a01ea2f05ec4e9b96a Mon Sep 17 00:00:00 2001 From: Ralf Stephan Date: Wed, 3 Dec 2014 15:52:39 +0100 Subject: [PATCH 211/698] 17438: implement coeff list --- src/sage/symbolic/expression.pyx | 39 ++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 021c40c91eb..12a4d14904b 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -5124,7 +5124,7 @@ cdef class Expression(CommutativeRingElement): coeff = coefficient - def coefficients(self, x=None): + def coefficients(self, x=None, sparse=True): r""" Return the coefficients of this symbolic expression as a polynomial in x. @@ -5144,18 +5144,33 @@ cdef class Expression(CommutativeRingElement): sage: p = x^3 - (x-3)*(x^2+x) + 1 sage: p.coefficients() [[1, 0], [3, 1], [2, 2]] + sage: p.coefficients(sparse=False) + [1, 3, 2] + sage: p = x - x^3 + 5/7*x^5 + sage: p.coefficients() + [[1, 1], [-1, 3], [5/7, 5]] + sage: p.coefficients(sparse=False) + [0, 1, 0, -1, 0, 5/7] sage: p = expand((x-a*sqrt(2))^2 + x + 1); p -2*sqrt(2)*a*x + 2*a^2 + x^2 + x + 1 sage: p.coefficients(a) [[x^2 + x + 1, 0], [-2*sqrt(2)*x, 1], [2, 2]] + sage: p.coefficients(a, sparse=False) + [x^2 + x + 1, -2*sqrt(2)*x, 2] sage: p.coefficients(x) [[2*a^2 + 1, 0], [-2*sqrt(2)*a + 1, 1], [1, 2]] + sage: p.coefficients(x, sparse=False) + [2*a^2 + 1, -2*sqrt(2)*a + 1, 1] - A polynomial with wacky exponents:: + The behaviour is undefined with noninteger or negative exponents:: sage: p = (17/3*a)*x^(3/2) + x*y + 1/x + x^x sage: p.coefficients(x) [[1, -1], [x^x, 0], [y, 1], [17/3*a, 3/2]] + sage: p.coefficients(x, sparse=False) + Traceback (most recent call last): + ... + ValueError: Cannot return dense coefficient list with noninteger exponents. """ f = self._maxima_() maxima = f.parent() @@ -5166,9 +5181,23 @@ cdef class Expression(CommutativeRingElement): G = f.coeffs(x) from sage.calculus.calculus import symbolic_expression_from_maxima_string S = symbolic_expression_from_maxima_string(repr(G)) - return S[1:] - - coeffs = coefficients + l = S[1:] + if sparse is True: + return l + else: + from sage.rings.integer_ring import ZZ + if any(not c[1] in ZZ for c in l): + raise ValueError("Cannot return dense coefficient list with noninteger exponents.") + val = l[0][1] + if val < 0: + raise ValueError("Cannot return dense coefficient list with negative valuation.") + deg = l[-1][1] + ret = [ZZ(0)] * int(deg+1) + for c in l: + ret[c[1]] = c[0] + return ret + + coeffs = coefficients def leading_coefficient(self, s): """ From 98959fb6c4ae60350aeb171f3740483c8c56dc30 Mon Sep 17 00:00:00 2001 From: Joao de Faria Date: Wed, 3 Dec 2014 12:38:12 -0500 Subject: [PATCH 212/698] 17082 - fixed error checks --- src/sage/schemes/projective/projective_morphism.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 984e6a0aec4..3f8ee275ea0 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -1659,8 +1659,8 @@ def height_difference_bound(self, prec=None): 10.7632079329219 """ BR = self.domain().base_ring() - if not BR in NumberFields(): - raise NotImplementedError("Must be a number field") + if not BR in NumberFields() and not BR == ZZ: + raise NotImplementedError("Must be a number field or the integers") if not self.is_endomorphism(): raise NotImplementedError("Must be an endomorphism of projective space") if prec is None: @@ -1674,16 +1674,15 @@ def height_difference_bound(self, prec=None): U = self.global_height(prec) + R(binomial(N + d, d)).log() #compute lower bound - from explicit polynomials of Nullstellensatz CR = self.domain().coordinate_ring() - CR = CR.change_ring(BR) #lift only works over fields + if BR == ZZ: + CR = CR.change_ring(QQ) #lift only works over fields I = CR.ideal(self.defining_polynomials()) MCP = [] for k in range(N + 1): CoeffPolys = (CR.gen(k) ** D).lift(I) - print CoeffPolys Res = 1 for j in range(len(CoeffPolys)): if CoeffPolys[j] != 0: - #make this a list comprehension for i in range(len(CoeffPolys[j].coefficients())): Res = lcm(Res, abs(CoeffPolys[j].coefficients()[i].denominator())) h = max([c.global_height() for g in CoeffPolys for c in (Res*g).coefficients()]) From 09349098e9a50e01761b46402198c40ba3becd3c Mon Sep 17 00:00:00 2001 From: Joao de Faria Date: Wed, 3 Dec 2014 12:45:54 -0500 Subject: [PATCH 213/698] 17082- added num field example --- src/sage/schemes/projective/projective_morphism.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 3f8ee275ea0..07292deeb95 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -1656,8 +1656,18 @@ def height_difference_bound(self, prec=None): 11.0020998412042 sage: f.normalize_coordinates() sage: f.height_difference_bound() - 10.7632079329219 - """ + 10.3089526606443 + + :: + + sage: R.=QQ[] + sage: K. = NumberField(x^3 - 2) + sage: P. = ProjectiveSpace(K,2) + sage: H = End(P) + sage: f = H([1/(c+1)*x^2+c*y^2,210*x*y,10000*z^2]) + sage: f.height_difference_bound() + 11.0020998412042 +""" BR = self.domain().base_ring() if not BR in NumberFields() and not BR == ZZ: raise NotImplementedError("Must be a number field or the integers") From 51a7d2f9c74e9b79a9f2822efcdf6d8deac028a3 Mon Sep 17 00:00:00 2001 From: Grayson Jorgenson Date: Wed, 3 Dec 2014 13:17:56 -0500 Subject: [PATCH 214/698] Calls change_ring separately on the numerator and denominator of fraction field elements in the morphism _polys list. --- src/sage/schemes/generic/morphism.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/sage/schemes/generic/morphism.py b/src/sage/schemes/generic/morphism.py index 2e5445a26a7..9a40448a1bd 100644 --- a/src/sage/schemes/generic/morphism.py +++ b/src/sage/schemes/generic/morphism.py @@ -84,6 +84,7 @@ from sage.categories.homset import Homset, Hom, End from sage.rings.all import Integer from sage.rings.commutative_ring import is_CommutativeRing +from sage.rings.fraction_field_element import FractionFieldElement from sage.rings.morphism import is_RingHomomorphism from point import is_SchemeTopologicalPoint from sage.rings.infinity import infinity @@ -1351,6 +1352,17 @@ def change_ring(self,R, check=True): To: Affine Space of dimension 2 over Rational Field Defn: Defined on coordinates by sending (x : y) to (x^2, y^2) + + :: + + sage: A.=AffineSpace(QQ,2) + sage: H=Hom(A,A) + sage: f=H([3*x^2/y,y^2/x]) + sage: f.change_ring(RR) + Scheme endomorphism of Affine Space of dimension 2 over Real Field with + 53 bits of precision + Defn: Defined on coordinates by sending (x, y) to + (3.00000000000000*x^2/y, y^2/x) """ T=self.domain().change_ring(R) @@ -1360,7 +1372,12 @@ def change_ring(self,R, check=True): S=self.codomain().change_ring(R) H=Hom(T,S) - G=[f.change_ring(R) for f in self._polys] + G = [] + for f in self._polys: + if isinstance(f,FractionFieldElement) == True: + G.append(f.numerator().change_ring(R) / f.denominator().change_ring(R)) + else: + G.append(f.change_ring(R)) return(H(G,check)) From bf375679641dcd174babbc95f883551f3349b627 Mon Sep 17 00:00:00 2001 From: Thierry Monteil Date: Wed, 3 Dec 2014 20:27:28 +0100 Subject: [PATCH 215/698] #17368 : add setuptools as a dependency. --- build/deps | 2 +- build/pkgs/pip/SPKG.txt | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/build/deps b/build/deps index dbb75764e86..afb6f3c9947 100644 --- a/build/deps +++ b/build/deps @@ -244,7 +244,7 @@ $(INST)/$(PARI_GALDATA): $(INST)/$(PARI_SEADATA_SMALL): +$(PIPE) "$(SAGE_SPKG) $(PARI_SEADATA_SMALL) 2>&1" "tee -a $(SAGE_LOGS)/$(PARI_SEADATA_SMALL).log" -$(INST)/$(PIP): $(INST)/$(PYTHON) +$(INST)/$(PIP): $(INST)/$(PYTHON) $(INST)/$(SETUPTOOLS) +$(PIPE) "$(SAGE_SPKG) $(PIP) 2>&1" "tee -a $(SAGE_LOGS)/$(PIP).log" $(INST)/$(POLYBORI): $(INST)/$(PYTHON) $(INST)/$(IPYTHON) \ diff --git a/build/pkgs/pip/SPKG.txt b/build/pkgs/pip/SPKG.txt index 14ae13b755b..ebdd18450ed 100644 --- a/build/pkgs/pip/SPKG.txt +++ b/build/pkgs/pip/SPKG.txt @@ -10,10 +10,6 @@ easy_install. MIT -== SPKG Maintainers == - -* Vincent Delecroix - == Upstream Contact == Project Page: https://github.com/pypa/pip @@ -26,3 +22,5 @@ Docs: https://pip.pypa.io/ == Dependencies == * python +* setuptools + From 7380e00fcfecfc5d563b82ba5383cdea9b8f8ba7 Mon Sep 17 00:00:00 2001 From: Thierry Monteil Date: Wed, 3 Dec 2014 20:33:01 +0100 Subject: [PATCH 216/698] #17368 add pip to COPYING.txt --- COPYING.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/COPYING.txt b/COPYING.txt index 7e94ff31677..fe671c47a44 100644 --- a/COPYING.txt +++ b/COPYING.txt @@ -89,6 +89,7 @@ pari GPLv2+ patch GPLv2+ pexpect Python License pillow Apache License 2.0 +pip MIT License pkgconf ISC License (equivalent to Simplified BSD) pkgconfig MIT License polybori GPLv2+ From 7fe79fb6ec8b72e31db862d018c142a77515a0eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Wed, 3 Dec 2014 21:54:11 +0100 Subject: [PATCH 217/698] 16256: made oeis tests optional (depend on internet) --- src/sage/combinat/quickref.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/quickref.py b/src/sage/combinat/quickref.py index bb645b6487c..c730fc6c397 100644 --- a/src/sage/combinat/quickref.py +++ b/src/sage/combinat/quickref.py @@ -4,7 +4,7 @@ Integer Sequences:: - sage: s = oeis([1,3,19,211]); s + sage: s = oeis([1,3,19,211]); s # optional - internet 0: A000275: Coefficients of a Bessel function (reciprocal of J_0(z)); also pairs of permutations with rise/rise forbidden. sage: s[0].programs() 0: (PARI) a(n)=if(n<0,0,n!^2*4^n*polcoeff(1/besselj(0,x+x*O(x^(2*n))),2*n)) /* _Michael Somos_, May 17 2004 */ @@ -28,7 +28,7 @@ Constructions and Species:: sage: for (p, s) in CartesianProduct(P, S): print p, s # not tested - sage: DisjointUnionEnumeratedSets(Family(lambda n: IntegerVectors(n, 3), NonNegativeIntegers)) # not tested + sage: DisjointUnionEnumeratedSets(Family(lambda n: IntegerVectors(n, 3), NonNegativeIntegers)) # not tested Words:: From 1287dd7cdeb43ff964123b73edd47ef78a2eb0c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 3 Dec 2014 22:10:47 +0100 Subject: [PATCH 218/698] trac #17432 more work on long lines, and wikipedia role --- .../quiver_mutation_type.py | 245 ++++++++++++------ 1 file changed, 170 insertions(+), 75 deletions(-) diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py index 8ad71365060..2fa9a916b5d 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py @@ -202,15 +202,23 @@ def _repr_(self): """ return "QuiverMutationType" - def samples(self, finite=None, affine=None, elliptic=None, mutation_finite=None): + def samples(self, finite=None, affine=None, elliptic=None, + mutation_finite=None): """ Return a sample of the available quiver mutations types. INPUT: - - ``finite``, ``affine``, ``elliptic``, ``mutation_finite`` -- - (default:``None``) if ``True`` or ``False``, only these - samples are returned. + - ``finite`` + + - ``affine`` + + - ``elliptic`` + + - ``mutation_finite`` + + All four input keywords default values are ``None``. If + set to ``True`` or ``False``, only these samples are returned. EXAMPLES:: @@ -246,7 +254,8 @@ def samples(self, finite=None, affine=None, elliptic=None, mutation_finite=None) if elliptic is not None: result = [t for t in result if t.is_elliptic() == elliptic] if mutation_finite is not None: - result = [t for t in result if t.is_mutation_finite() == mutation_finite] + result = [t for t in result + if t.is_mutation_finite() == mutation_finite] return result @cached_method @@ -278,64 +287,113 @@ def _samples(self): QuiverMutationType.__doc__ = \ r""" -*Quiver mutation types* can be seen as a slight generalization of *generalized Cartan types*. +*Quiver mutation types* can be seen as a slight generalization of + *generalized Cartan types*. Background on generalized Cartan types can be found at - http://en.wikipedia.org/wiki/Generalized_Cartan_matrix + :wikipedia:`Generalized_Cartan_matrix` For the compendium on the cluster algebra and quiver package in Sage see :arxiv:`1102.4844` A `B`-matrix is a skew-symmetrizable `( n \times n )`-matrix `M`. -I.e., there exists an invertible diagonal matrix `D` such that `DM` is skew-symmetric. -`M` can be encoded as a *quiver* by having a directed edge from vertex `i` to vertex `j` -with label `(a,b)` if `a = M_{i,j} > 0` and `b = M_{j,i} < 0`. -We consider quivers up to *mutation equivalence*. +I.e., there exists an invertible diagonal matrix `D` such that `DM` is +skew-symmetric. `M` can be encoded as a *quiver* by having a directed +edge from vertex `i` to vertex `j` with label `(a,b)` if `a = M_{i,j} +> 0` and `b = M_{j,i} < 0`. We consider quivers up to *mutation +equivalence*. To a quiver mutation type we can associate a *generalized Cartan type* -by sending `M` to the generalized Cartan matrix `C(M)` obtained by replacing all -positive entries by their negatives and adding `2`'s on the main diagonal. +by sending `M` to the generalized Cartan matrix `C(M)` obtained by +replacing all positive entries by their negatives and adding `2`'s on +the main diagonal. -``QuiverMutationType`` constructs a quiver mutation type object. For more detail on the possible different types, please see the compendium. +``QuiverMutationType`` constructs a quiver mutation type object. For +more detail on the possible different types, please see the +compendium. INPUT: -The input consists either of a quiver mutation type, or of a ``letter`` (a string), a ``rank`` (one integer or a list/tuple of integers), and an optional ``twist`` (an integer or a list of integers). There are several different naming conventions for quiver mutation types. - -- Finite type -- ``letter`` is a Dynkin type (A-G), and ``rank`` is the rank. - -- Affine type -- there is more than one convention for naming affine types. - * Kac's notation: ``letter`` is a Dynkin type, ``rank`` is the rank of the associated finite Dynkin diagram, and ``twist`` is the twist, which could be 1, 2, or 3. In the special case of affine type A, there is more than one quiver mutation type associated to the Cartan type. In this case only, ``rank`` is a pair of integers (i,j), giving the number of edges pointing clockwise and the number of edges pointing counter-clockwise. The total number of vertices is given by i+j in this case. - - * Naive notation: ``letter`` is one of 'BB', 'BC', 'BD', 'CC', 'CD'. The name specifies the two ends of the diagram, which are joined by a path. The total number of vertices is given by ``rank +1`` (to match the indexing people expect because these are affine types). In general, ``rank`` must be large enough for the picture to make sense, but we accept ``letter`` is ``BC`` and ``rank=1``. - - * Macdonald notation: for the dual of an untwisted affine type (such as ['C', 6,1]), we accept a twist of -1 (i.e., ['C',6,-1]). - -- Elliptic type -- ``letter`` is a Dynkin type, ``rank`` is the rank of the finite Dynkin diagram, and ``twist`` is a tuple of two integers. We follow Saito's notation. +The input consists either of a quiver mutation type, or of a +``letter`` (a string), a ``rank`` (one integer or a list/tuple of +integers), and an optional ``twist`` (an integer or a list of +integers). There are several different naming conventions for quiver +mutation types. + +- Finite type -- ``letter`` is a Dynkin type (A-G), and ``rank`` is + the rank. + +- Affine type -- there is more than one convention for naming affine +types. * Kac's notation: ``letter`` is a Dynkin type, ``rank`` is the +rank of the associated finite Dynkin diagram, and ``twist`` is the +twist, which could be 1, 2, or 3. In the special case of affine type +A, there is more than one quiver mutation type associated to the +Cartan type. In this case only, ``rank`` is a pair of integers (i,j), +giving the number of edges pointing clockwise and the number of edges +pointing counter-clockwise. The total number of vertices is given by +i+j in this case. + + * Naive notation: ``letter`` is one of 'BB', 'BC', 'BD', 'CC', + 'CD'. The name specifies the two ends of the diagram, which are + joined by a path. The total number of vertices is given by + ``rank +1`` (to match the indexing people expect because these + are affine types). In general, ``rank`` must be large enough + for the picture to make sense, but we accept ``letter`` is + ``BC`` and ``rank=1``. + + * Macdonald notation: for the dual of an untwisted affine type + (such as ['C', 6,1]), we accept a twist of -1 (i.e., + ['C',6,-1]). + +- Elliptic type -- ``letter`` is a Dynkin type, ``rank`` is the rank + of the finite Dynkin diagram, and ``twist`` is a tuple of two + integers. We follow Saito's notation. - Other shapes: - * Rank 2: ``letter`` is 'R2', and ``rank`` is a pair of integers specifying the label on the unique edge. - - * Triangle: ``letter`` is ``TR``, and ``rank`` is the number of vertices along a side. - - * T: This defines a quiver shaped like a T. ``letter`` is 'T', and the ``rank`` is a triple, whose entries specify the number of vertices along each path from the branch point (counting the branch point). - - * Grassmannian: This defines the cluster algebra (without coefficients) corresponding to the cluster algebra with coefficients which is the co-ordinate ring of a Grassmannian. ``letter`` is 'GR'. ``rank`` is a pair of integers (`k`, `n`) with 'k' < 'n' specifying the Grassmannian of `k`-planes in `n`-space. This defines a quiver given by a (k-1) x (n-k-1) grid where each square is cyclically oriented. - - * Exceptional mutation finite quivers: The two exceptional mutation finite quivers, found by Derksen-Owen, have ``letter`` as 'X' and ``rank`` 6 or 7, equal to the number of vertices. - - * AE, BE, CE, DE: Quivers are built of one end which looks like type (affine A), B, C, or D, and the other end which looks like type E (i.e., it consists of two antennae, one of length one, and one of length two). ``letter`` is 'AE', 'BE', 'CE', or 'DE', and ``rank`` is the total number of vertices. Note that 'AE' is of a slightly different form and requires ``rank`` to be a pair of integers (i,j) just as in the case of affine type A. See Exercise 4.3 in Kac's book Infinite Dimensional Lie Algebras for more details. - - * Infinite type E: It is also possible to obtain infinite-type E quivers by specifying ``letter`` as 'E' and ``rank`` as the number of vertices. + * Rank 2: ``letter`` is 'R2', and ``rank`` is a pair of integers + specifying the label on the unique edge. + + * Triangle: ``letter`` is ``TR``, and ``rank`` is the number of + vertices along a side. + + * T: This defines a quiver shaped like a T. ``letter`` is 'T', + and the ``rank`` is a triple, whose entries specify the number + of vertices along each path from the branch point (counting the + branch point). + + * Grassmannian: This defines the cluster algebra (without + coefficients) corresponding to the cluster algebra with + coefficients which is the co-ordinate ring of a Grassmannian. + ``letter`` is 'GR'. ``rank`` is a pair of integers (`k`, `n`) + with 'k' < 'n' specifying the Grassmannian of `k`-planes in + `n`-space. This defines a quiver given by a (k-1) x (n-k-1) + grid where each square is cyclically oriented. + + * Exceptional mutation finite quivers: The two exceptional + mutation finite quivers, found by Derksen-Owen, have ``letter`` + as 'X' and ``rank`` 6 or 7, equal to the number of vertices. + + * AE, BE, CE, DE: Quivers are built of one end which looks like + type (affine A), B, C, or D, and the other end which looks like + type E (i.e., it consists of two antennae, one of length one, + and one of length two). ``letter`` is 'AE', 'BE', 'CE', or + 'DE', and ``rank`` is the total number of vertices. Note that + 'AE' is of a slightly different form and requires ``rank`` to be + a pair of integers (i,j) just as in the case of affine type A. + See Exercise 4.3 in Kac's book Infinite Dimensional Lie Algebras + for more details. + + * Infinite type E: It is also possible to obtain infinite-type E + quivers by specifying ``letter`` as 'E' and ``rank`` as the + number of vertices. REFERENCES: - A good reference for finite and affine Dynkin diagrams, including - Kac's notation, is the Wikipedia article on `Dynkin diagrams - `_. + Kac's notation, is the Wikipedia article :wikipedia:`Dynkin_diagram`. - A good reference for the skew-symmetrizable elliptic diagrams is "Cluster algebras of finite mutation type via unfolding" by @@ -1112,10 +1170,12 @@ def __init__(self, letter, rank, twist=None): self._info['finite'] = True else: _mutation_type_error( data ) - # types ['A',1] and ['A',[0,1],1] need to be treated on itself (as there is no edge) + # types ['A',1] and ['A',[0,1],1] need to be treated on + # itself (as there is no edge) if twist is None and self._rank == 1 or twist == 1 and self._rank == 1: self._graph.add_vertex( 0 ) - # type ['A',[1,1],1] needs to be treated on itself as well (as there is a double edge) + # type ['A',[1,1],1] needs to be treated on itself as well + # (as there is a double edge) elif twist == 1 and self._bi_rank[0] == 1 and self._bi_rank[1] == 1: self._graph.add_edge( 0,1,2 ) else: @@ -1279,9 +1339,11 @@ def __init__(self, letter, rank, twist=None): if rank == 6: self._graph.add_edges( [ (0,1),(1,2),(2,3),(3,4),(2,5) ] ) elif rank == 7: - self._graph.add_edges( [ (0,1),(1,2),(2,3),(3,4),(4,5),(2,6) ] ) + self._graph.add_edges([(0, 1), (1, 2), (2, 3), + (3, 4), (4, 5), (2, 6)]) elif rank == 8: - self._graph.add_edges( [ (0,1),(1,2),(2,3),(3,4),(4,5),(5,6),(2,7) ] ) + self._graph.add_edges([(0, 1), (1, 2), (2, 3), + (3, 4), (4, 5), (5, 6),(2, 7)]) elif rank in [6,7,8] and twist == 1: self._rank = rank + 1 self._info['mutation_finite'] = True @@ -1394,32 +1456,43 @@ def __init__(self, letter, rank, twist=None): self._rank = rank + 1 self._info['mutation_finite'] = True self._info['affine'] = True - self._graph.add_edges( [ (0,1,None), (1,2,None),(2,3,(1,-2)),(3,4,None) ] ) + self._graph.add_edges( [ (0,1,None), (1,2,None), + (2,3,(1,-2)),(3,4,None) ] ) elif rank == 4 and twist == -1: self._rank = rank + 1 self._info['mutation_finite'] = True self._info['affine'] = True - self._graph.add_edges( [ (0,1,None), (1,2,None),(2,3,(2,-1)),(3,4,None) ] ) + self._graph.add_edges( [ (0,1,None), (1,2,None), + (2,3,(2,-1)),(3,4,None) ] ) elif rank == 4 and (twist == [1,2]): self._rank = rank + 2 self._info['mutation_finite'] = True self._info['elliptic'] = True - self._digraph.add_edges( [ (0,1,None), (1,2,None), (2,3,(2,-1)), (4,2,(1,-2)), (3,4,2), (4,5,None), (5,3,None) ]) + self._digraph.add_edges( [ (0,1,None), (1,2,None), + (2,3,(2,-1)), (4,2,(1,-2)), + (3,4,2), (4,5,None), (5,3,None) ]) elif rank == 4 and (twist == [2,1]): self._rank = rank + 2 self._info['mutation_finite'] = True self._info['elliptic'] = True - self._digraph.add_edges( [ (0,1,None), (1,2,None), (2,3,(1,-2)), (4,2,(2,-1)), (3,4,2), (4,5,None), (5,3,None) ]) + self._digraph.add_edges( [ (0,1,None), (1,2,None), + (2,3,(1,-2)), (4,2,(2,-1)), + (3,4,2), (4,5,None), (5,3,None) ]) elif rank == 4 and twist == [2,2]: self._rank = rank + 2 self._info['mutation_finite'] = True self._info['elliptic'] = True - self._digraph.add_edges( [ (0,1,None), (1,2,None), (3,1,None), (2,3,2), (4,2,(2,-1)), (3,4,(1,-2)), (5,4,None) ] ) + self._digraph.add_edges( [ (0,1,None), (1,2,None), + (3,1,None), (2,3,2), + (4,2,(2,-1)), (3,4,(1,-2)), + (5,4,None) ] ) elif rank == 4 and twist == [1,1]: self._rank = rank + 2 self._info['mutation_finite'] = True self._info['elliptic'] = True - self._digraph.add_edges( [ (0,1,None), (1,2,None), (3,1,None), (2,3,2), (4,2,(1,-2)), (3,4,(2,-1)), (5,4,None) ] ) + self._digraph.add_edges( [ (0,1,None), (1,2,None), + (3,1,None), (2,3,2), (4,2,(1,-2)), + (3,4,(2,-1)), (5,4,None) ] ) else: _mutation_type_error( data ) @@ -1456,12 +1529,14 @@ def __init__(self, letter, rank, twist=None): self._rank = rank + 2 self._info['mutation_finite'] = True self._info['elliptic'] = True - self._digraph.add_edges( [ (1,0,None), (0,2,2), (3,0,(3,-1)), (2,1,None), (2,3, (1,-3))]) + self._digraph.add_edges( [ (1,0,None), (0,2,2), (3,0,(3,-1)), + (2,1,None), (2,3, (1,-3))]) elif rank == 2 and twist == [1,1]: self._rank = rank + 2 self._info['mutation_finite'] = True self._info['elliptic'] = True - self._digraph.add_edges( [ (1,0,None), (0,2,2), (3,0,(1,-3)), (2,1,None), (2,3,(3,-1)) ] ) + self._digraph.add_edges( [ (1,0,None), (0,2,2), (3,0,(1,-3)), + (2,1,None), (2,3,(3,-1)) ] ) else: _mutation_type_error( data ) @@ -1550,7 +1625,9 @@ def __init__(self, letter, rank, twist=None): self._rank = rank self._info['mutation_finite'] = True self._info['skew_symmetric'] = True - self._digraph.add_edges( [ (0,1,2),(1,2,None),(2,0,None),(2,3,None),(3,4,2),(4,2,None),(2,5,None) ] ) + self._digraph.add_edges( [ (0,1,2),(1,2,None),(2,0,None), + (2,3,None),(3,4,2),(4,2,None), + (2,5,None) ] ) if rank == 7: self._digraph.add_edges( [ (5,6,2),(6,2,None) ] ) else: @@ -1565,7 +1642,8 @@ def __init__(self, letter, rank, twist=None): if self._graph.is_bipartite(): self._digraph = _bipartite_graph_to_digraph( self._graph ) else: - raise ValueError('The QuiverMutationType does not have a Coxeter diagram.') + raise ValueError('The QuiverMutationType does not have ' + 'a Coxeter diagram.') # in the other cases, the graph is constructed from the digraph if not self._graph: @@ -1643,7 +1721,8 @@ def class_size(self): # type A (finite and affine) if self._letter == 'A': - # the formula is taken from Torkildsen - Counting cluster-tilted algebras of type A + # the formula is taken from Torkildsen - Counting + # cluster-tilted algebras of type A if self.is_finite(): n = self._rank a = binomial( 2*(n+1), n+1 ) / (n+2) @@ -1660,21 +1739,28 @@ def class_size(self): n = i+j f = Euler_Phi() if i == j: - return ( binomial( 2*i,i ) + sum( f(k) * binomial(2*i/k,i/k)**2 for k in [k for k in i.divisors() if k in j.divisors()] ) / n ) / 4 + return ( binomial( 2*i,i ) + + sum( f(k) * binomial(2*i/k,i/k)**2 + for k in [k for k in i.divisors() + if k in j.divisors()] ) / n ) / 4 else: - return sum( f(k) * binomial(2*i/k,i/k) * binomial(2*j/k,j/k) for k in [k for k in i.divisors() if k in j.divisors()] ) / ( 2 * n ) + return sum( f(k) * binomial(2*i/k,i/k) * + binomial(2*j/k,j/k) + for k in [k for k in i.divisors() + if k in j.divisors()] ) / ( 2 * n ) # types B and C (finite and affine) - elif self._letter in ['B','C']: - # this formula is proven but nowhere published - # correctness is clear enough that I don't think a warning is needed + elif self._letter in ['B', 'C']: + # this formula is proven but nowhere published correctness + # is clear enough that I don't think a warning is needed if self.is_finite(): n = self._rank - return binomial( 2*n, n ) / (n+1) + return binomial(2 * n, n) / (n + 1) elif self._letter in ['BB','CC']: # these two formulas are not yet proven - print Warning ("Warning: This method uses a formula which has not been proved correct.") + print Warning("Warning: This method uses a formula " + "which has not been proved correct.") if self.is_affine(): if self._twist == 1: n = self._rank - 1 @@ -1686,7 +1772,8 @@ def class_size(self): # type BC (affine) elif self._letter == 'BC': # this formula is not yet proven - print Warning ("Warning: This method uses a formula which has not been proved correct.") + print Warning("Warning: This method uses a formula " + "which has not been proved correct.") if self.is_affine(): if self._twist == 1: n = self._rank - 1 @@ -1695,7 +1782,8 @@ def class_size(self): # types BD and CD (affine) elif self._letter in ['BD','CD']: # this formula is not yet proven - print Warning ("Warning: This method uses a formula which has not been proved correct.") + print Warning("Warning: This method uses a formula " + "which has not been proved correct.") if self.is_affine(): if self._twist == 1: n = self._rank - 2 @@ -1709,15 +1797,17 @@ def class_size(self): return 6 else: f = Euler_Phi() - n = ZZ( self._rank ) - return sum( f( n/k ) * binomial( 2*k, k ) for k in n.divisors() ) / (2*n) + n = ZZ(self._rank) + return sum( f( n/k ) * binomial( 2*k, k ) + for k in n.divisors() ) / (2*n) # this formula is not yet proven elif self.is_affine(): n = self._rank - 3 if n == 2: return 9 else: - print Warning ("Warning: This method uses a formula which has not been proved correct.") + print Warning ("Warning: This method uses a formula " + "which has not been proved correct.") if n%2==1: return 2*binomial(2*n,n) else: @@ -1869,11 +1959,14 @@ def __init__(self, *args): # _info is initialized self._info = {} self._info['irreducible'] = False - self._info['mutation_finite'] = all( comp.is_mutation_finite() for comp in data ) - self._info['simply_laced'] = all( comp.is_simply_laced() for comp in data ) - self._info['skew_symmetric'] = all( comp.is_skew_symmetric() for comp in data ) - self._info['finite'] = all( comp.is_finite() for comp in data ) - self._info['irreducible_components'] = copy( data ) + self._info['mutation_finite'] = all(comp.is_mutation_finite() + for comp in data) + self._info['simply_laced'] = all(comp.is_simply_laced() + for comp in data) + self._info['skew_symmetric'] = all(comp.is_skew_symmetric() + for comp in data) + self._info['finite'] = all(comp.is_finite() for comp in data) + self._info['irreducible_components'] = copy(data) # letter and rank are initialized self._letter = '' @@ -1919,7 +2012,8 @@ def irreducible_components( self ): sage: mut_type.irreducible_components() (['A', 3], ['B', 3]) - sage: mut_type = QuiverMutationType(['A',3],['B',3],['X',6]); mut_type + sage: mut_type = QuiverMutationType(['A',3],['B',3],['X',6]) + sage: mut_type [ ['A', 3], ['B', 3], ['X', 6] ] sage: mut_type.irreducible_components() (['A', 3], ['B', 3], ['X', 6]) @@ -1942,7 +2036,8 @@ def class_size(self): sage: mut_type.class_size() 20 - sage: mut_type = QuiverMutationType(['A',3],['B',3],['X',6]); mut_type + sage: mut_type = QuiverMutationType(['A',3],['B',3],['X',6]) + sage: mut_type [ ['A', 3], ['B', 3], ['X', 6] ] sage: mut_type.class_size() 100 From 7e5f21754e6c056d71609830729c093ba09b56a6 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 3 Dec 2014 22:27:59 +0100 Subject: [PATCH 219/698] Reorganize logic of bitset shifts --- src/sage/data_structures/bitset.pxi | 59 ++++++++++++++++------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/src/sage/data_structures/bitset.pxi b/src/sage/data_structures/bitset.pxi index 10f2cd03fd5..2e63d7e43e9 100644 --- a/src/sage/data_structures/bitset.pxi +++ b/src/sage/data_structures/bitset.pxi @@ -612,29 +612,30 @@ cdef void bitset_rshift(bitset_t r, bitset_t a, mp_bitcnt_t n): # Number of limbs on the right of a which will totally be shifted out cdef mp_size_t nlimbs = n >> index_shift - # Number of limbs of a which will survive the shift + # Number of limbs to be shifted assuming r is large enough cdef mp_size_t shifted_limbs = a.limbs - nlimbs # Number of bits to shift additionally cdef mp_bitcnt_t nbits = n % GMP_LIMB_BITS - if nbits: - # mpn_rshift only does shifts less than a limb - if shifted_limbs < r.limbs: + if shifted_limbs < r.limbs: + if nbits: mpn_rshift(r.bits, a.bits + nlimbs, shifted_limbs, nbits) else: + mpn_copyi(r.bits, a.bits + nlimbs, shifted_limbs) + + # Clear top limbs (note that r.limbs - shifted_limbs >= 1) + mpn_zero(r.bits + (r.limbs - nlimbs), r.limbs - shifted_limbs) + else: + # Number of limbs to shift is r.limbs + if nbits: mpn_rshift(r.bits, a.bits + nlimbs, r.limbs, nbits) # Add the additional bits from top limb of a r.bits[r.limbs-1] |= a.bits[r.limbs+nlimbs] << (GMP_LIMB_BITS - nbits) - bitset_fix(r) - else: - if shifted_limbs < r.limbs: - mpn_copyi(r.bits, a.bits + nlimbs, shifted_limbs) else: mpn_copyi(r.bits, a.bits + nlimbs, r.limbs) - bitset_fix(r) - # Clear top limbs - if r.limbs + nlimbs > a.limbs: - mpn_zero(r.bits + (r.limbs - nlimbs), r.limbs - shifted_limbs) + + # Clear bits outside bitset in top limb + bitset_fix(r) cdef void bitset_lshift(bitset_t r, bitset_t a, mp_bitcnt_t n): """ @@ -648,27 +649,33 @@ cdef void bitset_lshift(bitset_t r, bitset_t a, mp_bitcnt_t n): mpn_zero(r.bits, r.limbs) return - # Number of limbs on the left of r which will totally be shifted out + # Number of limbs on the right of r which will totally be zeroed cdef mp_size_t nlimbs = n >> index_shift - # Number of limbs of a which would fit into r - cdef mp_size_t max_shifted_limbs = r.limbs - nlimbs + # Number of limbs to be shifted assuming a is large enough + cdef mp_size_t shifted_limbs = r.limbs - nlimbs # Number of bits to shift additionally cdef mp_bitcnt_t nbits = n % GMP_LIMB_BITS - cdef mp_limb_t out - if nbits: - # mpn_lshift only does shifts less than a limb - if max_shifted_limbs <= a.limbs: - mpn_lshift(r.bits + nlimbs, a.bits, max_shifted_limbs, nbits) - else: + cdef mp_limb_t out = 0 + if shifted_limbs > a.limbs: + if nbits: out = mpn_lshift(r.bits + nlimbs, a.bits, a.limbs, nbits) - r.bits[nlimbs+a.limbs] = out - else: - if max_shifted_limbs <= a.limbs: - mpn_copyd(r.bits + nlimbs, a.bits, max_shifted_limbs) else: mpn_copyd(r.bits + nlimbs, a.bits, a.limbs) - bitset_fix(r) + + # Clear top limbs (note that shifted_limbs - a.limbs >= 1) + mpn_zero(r.bits + a.limbs + nlimbs, shifted_limbs - a.limbs) + # Store extra limb shifted in from a + r.bits[nlimbs+a.limbs] = out + else: + if nbits: + mpn_lshift(r.bits + nlimbs, a.bits, shifted_limbs, nbits) + else: + mpn_copyd(r.bits + nlimbs, a.bits, shifted_limbs) + + # Clear bits outside bitset in top limb + bitset_fix(r) + # Clear bottom limbs mpn_zero(r.bits, nlimbs) From d0a5c78fc58c86fa830c6223d735a1507b3c434c Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 4 Dec 2014 10:00:50 +0100 Subject: [PATCH 220/698] Move bitset_fix() function --- src/sage/data_structures/bitset.pxi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/data_structures/bitset.pxi b/src/sage/data_structures/bitset.pxi index 2e63d7e43e9..bc6ac3cb647 100644 --- a/src/sage/data_structures/bitset.pxi +++ b/src/sage/data_structures/bitset.pxi @@ -66,12 +66,6 @@ cdef inline mp_limb_t limb_lower_bits_up(mp_bitcnt_t n): """ return ((-1)) >> (((-n)) % GMP_LIMB_BITS) -cdef inline void bitset_fix(bitset_t bits): - """ - Clear upper bits in upper limb which should be zero. - """ - bits.bits[bits.limbs - 1] &= limb_lower_bits_up(bits.size) - ############################################################################# # Bitset Initalization ############################################################################# @@ -146,6 +140,12 @@ cdef inline void bitset_copy(bitset_t dst, bitset_t src): """ mpn_copyi(dst.bits, src.bits, src.limbs) +cdef inline void bitset_fix(bitset_t bits): + """ + Clear upper bits in upper limb which should be zero. + """ + bits.bits[bits.limbs - 1] &= limb_lower_bits_up(bits.size) + ############################################################################# # Bitset Comparison ############################################################################# From 9452fa934b8064657743e4ba32869430304fdb13 Mon Sep 17 00:00:00 2001 From: Ralf Stephan Date: Thu, 4 Dec 2014 10:17:18 +0100 Subject: [PATCH 221/698] 17438: deprecate ex.coeff/coeffs() --- src/sage/calculus/calculus.py | 2 +- src/sage/combinat/tutorial.py | 2 +- src/sage/databases/oeis.py | 2 +- src/sage/matrix/constructor.py | 2 +- src/sage/modules/vector_space_morphism.py | 2 +- src/sage/rings/padics/factory.py | 2 +- src/sage/symbolic/expression.pyx | 48 ++++++++++++------- src/sage/symbolic/function_factory.py | 4 +- .../tests/french_book/nonlinear_doctest.py | 2 +- 9 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/sage/calculus/calculus.py b/src/sage/calculus/calculus.py index 7e340e5ba06..63a7af8ad52 100644 --- a/src/sage/calculus/calculus.py +++ b/src/sage/calculus/calculus.py @@ -379,7 +379,7 @@ + 4*euler_gamma*(sqrt(3)*pi + 9*log(3)) + 27*log(3)^2 + 12*psi(1, 1/3))*x^2*gamma(1/3) - 1/6*(6*euler_gamma + sqrt(3)*pi + 9*log(3))*x*gamma(1/3) + gamma(1/3) - sage: map(lambda f:f[0].n(), _.coeffs()) # numerical coefficients to make comparison easier; Maple 12 gives same answer + sage: map(lambda f:f[0].n(), _.coefficients()) # numerical coefficients to make comparison easier; Maple 12 gives same answer [2.6789385347..., -8.3905259853..., 26.662447494..., -80.683148377...] Ensure that ticket #8582 is fixed:: diff --git a/src/sage/combinat/tutorial.py b/src/sage/combinat/tutorial.py index ddd5a87a785..b38a543e527 100644 --- a/src/sage/combinat/tutorial.py +++ b/src/sage/combinat/tutorial.py @@ -319,7 +319,7 @@ or calculate, more or less instantaneously, the 100-th coefficient:: - sage: C.series(z, 101).coeff(z,100) + sage: C.series(z, 101).coefficient(z,100) 227508830794229349661819540395688853956041682601541047340 It is unfortunate to have to recalculate everything if at some point we diff --git a/src/sage/databases/oeis.py b/src/sage/databases/oeis.py index 99a3d56ab9f..66a556ccb48 100644 --- a/src/sage/databases/oeis.py +++ b/src/sage/databases/oeis.py @@ -95,7 +95,7 @@ :: sage: x = var('x') ; f(x) = e^(e^x - 1) - sage: L = [a*factorial(b) for a,b in taylor(f(x), x, 0, 20).coeffs()] ; L + sage: L = [a*factorial(b) for a,b in taylor(f(x), x, 0, 20).coefficients()] ; L [1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, 678570, 4213597, 27644437, 190899322, 1382958545, 10480142147, 82864869804, 682076806159, 5832742205057, 51724158235372] diff --git a/src/sage/matrix/constructor.py b/src/sage/matrix/constructor.py index 552a22f6b59..4ccc9d0fe08 100644 --- a/src/sage/matrix/constructor.py +++ b/src/sage/matrix/constructor.py @@ -2906,7 +2906,7 @@ def companion_matrix(poly, format='right'): ... TypeError: input must be a polynomial (not a symbolic expression, see docstring), or other iterable, not y^3 - 2*y + 1 - sage: coeff_list = [q(y=0)] + [q.coeff(y^k) for k in range(1, q.degree(y)+1)] + sage: coeff_list = [q(y=0)] + [q.coefficient(y^k) for k in range(1, q.degree(y)+1)] sage: coeff_list [1, -2, 0, 1] sage: companion_matrix(coeff_list) diff --git a/src/sage/modules/vector_space_morphism.py b/src/sage/modules/vector_space_morphism.py index 63f43024377..6e7961ce69a 100644 --- a/src/sage/modules/vector_space_morphism.py +++ b/src/sage/modules/vector_space_morphism.py @@ -748,7 +748,7 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): raise ValueError('symbolic function has the wrong number of inputs for domain') if n != C.degree(): raise ValueError('symbolic function has the wrong number of outputs for codomain') - arg2 = [[e.coeff(a) for e in exprs] for a in args] + arg2 = [[e.coefficient(a) for e in exprs] for a in args] try: arg2 = matrix(D.base_ring(), m, n, arg2) except TypeError as e: diff --git a/src/sage/rings/padics/factory.py b/src/sage/rings/padics/factory.py index bf6edc5f89f..a5b3593e483 100644 --- a/src/sage/rings/padics/factory.py +++ b/src/sage/rings/padics/factory.py @@ -2277,7 +2277,7 @@ def create_key_and_extra_args(self, base, premodulus, prec = None, print_mode = # the information needed to shift right with full precision from the premodulus. if is_Expression(premodulus): # Here we assume that the output of coeffs is sorted in increasing order by exponent: - coeffs = premodulus.coeffs() + coeffs = premodulus.coefficients() preseed = premodulus / coeffs[-1][0] preseed -= preseed.variables()[0]**coeffs[-1][1] preseed /= base.prime() # here we assume that the base is unramified over Qp diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 12a4d14904b..d56febeb191 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -832,21 +832,21 @@ cdef class Expression(CommutativeRingElement): EXAMPLES:: sage: f = x^3 + 17*x -3 - sage: ZZ(f.coeff(x^3)) + sage: ZZ(f.coefficient(x^3)) 1 - sage: ZZ(f.coeff(x)) + sage: ZZ(f.coefficient(x)) 17 - sage: ZZ(f.coeff(x,0)) + sage: ZZ(f.coefficient(x,0)) -3 - sage: type(ZZ(f.coeff(x,0))) + sage: type(ZZ(f.coefficient(x,0))) Coercion is done if necessary:: sage: f = x^3 + 17/1*x - sage: ZZ(f.coeff(x)) + sage: ZZ(f.coefficient(x)) 17 - sage: type(ZZ(f.coeff(x))) + sage: type(ZZ(f.coefficient(x))) If the symbolic expression is just a wrapper around an integer, @@ -914,15 +914,15 @@ cdef class Expression(CommutativeRingElement): EXAMPLES:: sage: f = x^3 + 17/1*x - 3/8 - sage: QQ(f.coeff(x^2)) + sage: QQ(f.coefficient(x^2)) 0 - sage: QQ(f.coeff(x^3)) + sage: QQ(f.coefficient(x^3)) 1 - sage: a = QQ(f.coeff(x)); a + sage: a = QQ(f.coefficient(x)); a 17 sage: type(a) - sage: QQ(f.coeff(x,0)) + sage: QQ(f.coefficient(x,0)) -3/8 If the symbolic expression is just a wrapper around a rational, @@ -4093,9 +4093,9 @@ cdef class Expression(CommutativeRingElement): False sage: (4*x^2 + x + 3).has(x) True - sage: (4*x^2 - x + 3).coeff(x,1) + sage: (4*x^2 - x + 3).coefficient(x,1) -1 - sage: (4*x^2 + x + 3).coeff(x,1) + sage: (4*x^2 + x + 3).coefficient(x,1) 1 """ cdef Expression p = self.coerce_in(pattern) @@ -5103,12 +5103,19 @@ cdef class Expression(CommutativeRingElement): sage: var('x,y,z') (x, y, z) sage: f = x*y*z^2 - sage: f.coeff(x*y) + sage: f.coefficient(x*y) z^2 - sage: f.coeff(x*y, 2) + sage: f.coefficient(x*y, 2) Traceback (most recent call last): ... TypeError: n != 1 only allowed for s being a variable + + Using ``coeff()`` is now deprecated (:trac:`17438`):: + + sage: x.coeff(x) + doctest:...: DeprecationWarning: coeff is deprecated. Please use coefficient instead. + See http://trac.sagemath.org/17438 for details. + 1 """ cdef Expression ss = self.coerce_in(s) if n != 1 and not is_a_symbol(ss._gobj): @@ -5118,11 +5125,11 @@ cdef class Expression(CommutativeRingElement): if is_a_mul(ss._gobj): # necessarily n=1 here res = self for i from 0 <= i < ss._gobj.nops(): - res = res.coeff(new_Expression_from_GEx(self._parent, ss._gobj.op(i))) + res = res.coefficient(new_Expression_from_GEx(self._parent, ss._gobj.op(i))) return res return new_Expression_from_GEx(self._parent, self._gobj.coeff(ss._gobj, n)) - coeff = coefficient + coeff = deprecated_function_alias(17438, coefficient) def coefficients(self, x=None, sparse=True): r""" @@ -5171,6 +5178,13 @@ cdef class Expression(CommutativeRingElement): Traceback (most recent call last): ... ValueError: Cannot return dense coefficient list with noninteger exponents. + + Using ``coeffs()`` is now deprecated (:trac:`17438`):: + + sage: x.coeffs() + doctest:...: DeprecationWarning: coeffs is deprecated. Please use coefficients instead. + See http://trac.sagemath.org/17438 for details. + [[1, 1]] """ f = self._maxima_() maxima = f.parent() @@ -5197,7 +5211,7 @@ cdef class Expression(CommutativeRingElement): ret[c[1]] = c[0] return ret - coeffs = coefficients + coeffs = deprecated_function_alias(17438, coefficients) def leading_coefficient(self, s): """ diff --git a/src/sage/symbolic/function_factory.py b/src/sage/symbolic/function_factory.py index a72a4ec8f4e..42012a3d3a5 100644 --- a/src/sage/symbolic/function_factory.py +++ b/src/sage/symbolic/function_factory.py @@ -217,9 +217,9 @@ def function(s, *args, **kwds): (r^2*D[0, 0](psi)(r) + 2*r*D[0](psi)(r))/r^2 sage: g.expand() 2*D[0](psi)(r)/r + D[0, 0](psi)(r) - sage: g.coeff(psi.derivative(r,2)) + sage: g.coefficient(psi.derivative(r,2)) 1 - sage: g.coeff(psi.derivative(r,1)) + sage: g.coefficient(psi.derivative(r,1)) 2/r Defining custom methods for automatic or numeric evaluation, derivation, diff --git a/src/sage/tests/french_book/nonlinear_doctest.py b/src/sage/tests/french_book/nonlinear_doctest.py index f00eeaa4bf3..d61bba5cf20 100644 --- a/src/sage/tests/french_book/nonlinear_doctest.py +++ b/src/sage/tests/french_book/nonlinear_doctest.py @@ -73,7 +73,7 @@ sage: x, a, b, c, d = var('x, a, b, c, d') sage: P = a * x^3 + b * x^2 + c * x + d sage: alpha = var('alpha') - sage: P.subs(x=x + alpha).expand().coeff(x, 2) + sage: P.subs(x=x + alpha).expand().coefficient(x, 2) 3*a*alpha + b sage: P.subs(x = x - b / (3 * a)).expand().collect(x) a*x^3 - 1/3*(b^2/a - 3*c)*x + 2/27*b^3/a^2 - 1/3*b*c/a + d From 0fec129b1055535de50cf4e5c663662e0d877742 Mon Sep 17 00:00:00 2001 From: Ralf Stephan Date: Thu, 4 Dec 2014 10:35:08 +0100 Subject: [PATCH 222/698] 17438: implement ex.list() --- src/sage/symbolic/expression.pyx | 41 ++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index d56febeb191..dccf1b7d119 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -5140,9 +5140,14 @@ cdef class Expression(CommutativeRingElement): - ``x`` -- optional variable. OUTPUT: + + Depending on the value of ``sparse``, - A list of pairs ``(expr, n)``, where ``expr`` is a symbolic - expression and ``n`` is a power. + - A list of pairs ``(expr, n)``, where ``expr`` is a symbolic + expression and ``n`` is a power (``sparse=True``, default) + + - A list of expressions where the ``n``-th element is the coefficient of + ``x^n`` when self is seen as polynomial in ``x`` (``sparse=False``). EXAMPLES:: @@ -5212,6 +5217,38 @@ cdef class Expression(CommutativeRingElement): return ret coeffs = deprecated_function_alias(17438, coefficients) + + def list(self, x=None): + r""" + Return the coefficients of this symbolic expression as a polynomial in x. + + INPUT: + + - ``x`` -- optional variable. + + OUTPUT: + + A list of expressions where the ``n``-th element is the coefficient of + ``x^n`` when self is seen as polynomial in ``x``. + + EXAMPLES:: + + sage: var('x, y, a') + (x, y, a) + sage: (x^5).list() + [0, 0, 0, 0, 0, 1] + sage: p = x^3 - (x-3)*(x^2+x) + 1 + sage: p.list() + [1, 3, 2] + sage: p = x - x^3 + 5/7*x^5 + sage: p.list() + [0, 1, 0, -1, 0, 5/7] + sage: p = expand((x-a*sqrt(2))^2 + x + 1); p + -2*sqrt(2)*a*x + 2*a^2 + x^2 + x + 1 + sage: p.list(a) + [x^2 + x + 1, -2*sqrt(2)*x, 2] + """ + return self.coefficients(x=x, sparse=False) def leading_coefficient(self, s): """ From 0c646186f3522ab9bf3210ddc9bd3baf7b1b4664 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 4 Dec 2014 10:05:32 +0100 Subject: [PATCH 223/698] Documentation fixes --- .../bounded_integer_sequences.pyx | 61 ++++++++++--------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index 0612f26e58f..488fa50328b 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -1,31 +1,27 @@ r""" Sequences of bounded integers -AUTHORS: - -- Simon King, Jeroen Demeyer (2014-10): initial version - This module provides :class:`BoundedIntegerSequence`, which implements sequences of bounded integers and is for many (but not all) operations faster than representing the same sequence as a Python :class:`tuple`. The underlying data structure is similar to :class:`~sage.misc.bitset.Bitset`, which means that certain operations are implemented by using fast shift -operations from GMP. The following boilerplate functions can be cimported in -Cython modules: +operations from MPIR. The following boilerplate functions can be +cimported in Cython modules: - ``cdef bint biseq_init(biseq_t R, mp_size_t l, mp_size_t itemsize) except -1`` - Allocate memory (filled with zero) for a bounded integer sequence - of length l with items fitting in itemsize bits. + Allocate memory for a bounded integer sequence of length ``l`` with + items fitting in ``itemsize`` bits. - ``cdef inline void biseq_dealloc(biseq_t S)`` - Free the data stored in ``S``. + Deallocate the memory used by ``S``. - ``cdef bint biseq_init_copy(biseq_t R, biseq_t S)`` - Copy S to the unallocated bitset R. + Initialize ``R`` as a copy of ``S``. - ``cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1`` @@ -43,27 +39,27 @@ Cython modules: - ``cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2`` - Returns the position *in ``S1``* of ``S2`` as a subsequence of + Return the position in ``S1`` of ``S2`` as a subsequence of ``S1[start:]``, or ``-1`` if ``S2`` is not a subsequence. Does not check whether the sequences have the same bound! - ``cdef mp_size_t biseq_max_overlap(biseq_t S1, biseq_t S2) except 0`` - Returns the minimal *positive* integer ``i`` such that ``S2`` starts with + Return the minimal *positive* integer ``i`` such that ``S2`` starts with ``S1[i:]``. This function will *not* test whether ``S2`` starts with ``S1``! - ``cdef mp_size_t biseq_index(biseq_t S, size_t item, mp_size_t start) except -2`` - Returns the position *in S* of the item in ``S[start:]``, or ``-1`` if + Return the position in ``S`` of the item in ``S[start:]``, or ``-1`` if ``S[start:]`` does not contain the item. - ``cdef size_t biseq_getitem(biseq_t S, mp_size_t index)`` - Returns ``S[index]``, without checking margins. + Return ``S[index]``, without checking margins. - ``cdef size_t biseq_getitem_py(biseq_t S, mp_size_t index)`` - Returns ``S[index]`` as Python ``int`` or ``long``, without checking margins. + Return ``S[index]`` as Python ``int`` or ``long``, without checking margins. - ``cdef biseq_inititem(biseq_t S, mp_size_t index, size_t item)`` @@ -72,11 +68,15 @@ Cython modules: - ``cdef inline void biseq_clearitem(biseq_t S, mp_size_t index)`` - Set ``S[index] = 0``, without checking margins. + Set ``S[index] = 0``, without checking margins. - ``cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, mp_size_t step) except -1`` - Initialises ``R`` with ``S[start:stop:step]``. + Initialise ``R`` with ``S[start:stop:step]``. + +AUTHORS: + +- Simon King, Jeroen Demeyer (2014-10): initial version (:trac:`15820`) """ #***************************************************************************** @@ -116,8 +116,8 @@ from cython.operator import dereference as deref, preincrement as preinc, predec @cython.overflowcheck cdef bint biseq_init(biseq_t R, mp_size_t l, mp_bitcnt_t itemsize) except -1: """ - Allocate memory for a bounded integer sequence of length l with items - fitting in itemsize bits. + Allocate memory for a bounded integer sequence of length ``l`` with + items fitting in ``itemsize`` bits. """ cdef mp_bitcnt_t totalbitsize if l: @@ -131,13 +131,13 @@ cdef bint biseq_init(biseq_t R, mp_size_t l, mp_bitcnt_t itemsize) except -1: cdef inline void biseq_dealloc(biseq_t S): """ - Deallocate the memory used by S. + Deallocate the memory used by ``S``. """ bitset_free(S.data) cdef bint biseq_init_copy(biseq_t R, biseq_t S) except -1: """ - Initialize R as a copy of S. + Initialize ``R`` as a copy of ``S``. """ biseq_init(R, S.length, S.itembitsize) bitset_copy(R.data, S.data) @@ -193,7 +193,8 @@ cdef bint biseq_init_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1: cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1: """ - Tests if bounded integer sequence S1 starts with bounded integer sequence S2 + Tests if bounded integer sequence ``S1`` starts with bounded integer + sequence ``S2``. ASSUMPTION: @@ -211,7 +212,8 @@ cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1: cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2: """ - Tests if the bounded integer sequence ``S1[start:]`` contains a sub-sequence ``S2`` + Tests if the bounded integer sequence ``S1[start:]`` contains a + sub-sequence ``S2``. INPUT: @@ -246,8 +248,8 @@ cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2 cdef mp_size_t biseq_index(biseq_t S, size_t item, mp_size_t start) except -2: """ - Returns the position in S of an item in S[start:], or -1 if S[start:] does - not contain the item. + Returns the position in ``S`` of an item in ``S[start:]``, or -1 if + ``S[start:]`` does not contain the item. """ cdef mp_size_t index @@ -259,7 +261,7 @@ cdef mp_size_t biseq_index(biseq_t S, size_t item, mp_size_t start) except -2: cdef inline size_t biseq_getitem(biseq_t S, mp_size_t index): """ - Get item S[index], without checking margins. + Get item ``S[index]``, without checking margins. """ cdef mp_bitcnt_t limb_index, bit_index @@ -276,7 +278,8 @@ cdef inline size_t biseq_getitem(biseq_t S, mp_size_t index): cdef biseq_getitem_py(biseq_t S, mp_size_t index): """ - Get item S[index] as a Python ``int`` or ``long``, without checking margins. + Get item ``S[index]`` as a Python ``int`` or ``long``, without + checking margins. """ cdef size_t out = biseq_getitem(S, index) @@ -319,8 +322,8 @@ cdef inline void biseq_clearitem(biseq_t S, mp_size_t index): cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, mp_size_t step) except -1: """ - Create the slice S[start:stop:step] as bounded integer sequence and write - the result to ``R``, which must not be initialised. + Create the slice ``S[start:stop:step]`` as bounded integer sequence + and write the result to ``R``, which must not be initialised. """ cdef mp_size_t length, total_shift, n From 93e64fd518f9088da631e6b4126c740f7722af77 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 4 Dec 2014 10:50:39 +0100 Subject: [PATCH 224/698] Always raise OverflowError if list item is out of bounds --- .../bounded_integer_sequences.pyx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index 488fa50328b..cdb08c9c1b0 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -158,15 +158,15 @@ cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1: - ``bound`` -- a number which is the maximal value of an item """ cdef mp_size_t index = 0 - cdef mp_limb_t item_limb + cdef size_t item_c biseq_init(R, len(data), BIT_COUNT(bound|1)) for item in data: - item_limb = item - if item_limb > bound: - raise ValueError("list item {} larger than {}".format(item, bound) ) - biseq_inititem(R, index, item_limb) + item_c = item + if item_c > bound: + raise OverflowError("list item {!r} larger than {}".format(item, bound) ) + biseq_inititem(R, index, item_c) index += 1 # @@ -426,7 +426,7 @@ cdef class BoundedIntegerSequence: sage: BoundedIntegerSequence(16, [2, 7, 20]) Traceback (most recent call last): ... - ValueError: list item 20 larger than 15 + OverflowError: list item 20 larger than 15 Bounded integer sequences are iterable, and we see that we can recover the originally given list:: @@ -538,13 +538,13 @@ cdef class BoundedIntegerSequence: sage: BoundedIntegerSequence(16, [2, 7, -20]) Traceback (most recent call last): ... - OverflowError: can't convert negative value to mp_limb_t + OverflowError: can't convert negative value to size_t sage: BoundedIntegerSequence(1, [0, 0, 0]) <0, 0, 0> sage: BoundedIntegerSequence(1, [0, 1, 0]) Traceback (most recent call last): ... - ValueError: list item 1 larger than 0 + OverflowError: list item 1 larger than 0 sage: BoundedIntegerSequence(0, [0, 1, 0]) Traceback (most recent call last): ... @@ -648,7 +648,7 @@ cdef class BoundedIntegerSequence: sage: BoundedIntegerSequence(100, [200]) Traceback (most recent call last): ... - ValueError: list item 200 larger than 99 + OverflowError: list item 200 larger than 99 Bounds that are too large:: From 99820cfcc289efa8fd54468b296051c9cc13891a Mon Sep 17 00:00:00 2001 From: Ralf Stephan Date: Thu, 4 Dec 2014 11:03:32 +0100 Subject: [PATCH 225/698] 17399: roll back previous commit to allow merge of 17428 --- src/sage/symbolic/expression.pyx | 36 +++++++------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 8605f8f295c..021c40c91eb 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -5156,37 +5156,17 @@ cdef class Expression(CommutativeRingElement): sage: p = (17/3*a)*x^(3/2) + x*y + 1/x + x^x sage: p.coefficients(x) [[1, -1], [x^x, 0], [y, 1], [17/3*a, 3/2]] - - Series coefficients are now handled correctly (:trac:`17399`):: - - sage: s=(1/(1-x)).series(x,6) - sage: s.coeffs() - [[1, 0], [1, 1], [1, 2], [1, 3], [1, 4], [1, 5]] - sage: x,y = var("x,y") - sage: s=(1/(1-y-x)).series(x,6) - sage: s.coeffs(y) - [] - sage: s.coeffs() - [[-1/(y - 1), 0], - [(y - 1)^(-2), 1], - [-1/(y - 1)^3, 2], - [(y - 1)^(-4), 3], - [-1/(y - 1)^5, 4], - [(y - 1)^(-6), 5]] """ + f = self._maxima_() + maxima = f.parent() + maxima._eval_line('load(coeflist)') if x is None: x = self.default_variable() - # x = self.parent().var(str(x)) - if is_a_series(self._gobj): - return [[self.coeff(x, d), d] for d in xrange(self.degree(x))] - else: - f = self._maxima_() - maxima = f.parent() - maxima._eval_line('load(coeflist)') - G = f.coeffs(x) - from sage.calculus.calculus import symbolic_expression_from_maxima_string - S = symbolic_expression_from_maxima_string(repr(G)) - return S[1:] + x = self.parent().var(repr(x)) + G = f.coeffs(x) + from sage.calculus.calculus import symbolic_expression_from_maxima_string + S = symbolic_expression_from_maxima_string(repr(G)) + return S[1:] coeffs = coefficients From 411fe4e04b87e5fdf87e4c3f4052e6747e09eca8 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 4 Dec 2014 11:41:27 +0100 Subject: [PATCH 226/698] Simplify/fix the logic of some biseq functions --- .../bounded_integer_sequences.pyx | 47 ++++++++----------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index cdb08c9c1b0..99c5cfe0172 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -102,7 +102,6 @@ cdef extern from "Python.h": cdef PyInt_FromSize_t(size_t ival) cimport cython -from cython.operator import dereference as deref, preincrement as preinc, predecrement as predec, postincrement as postinc ################### # Boilerplate @@ -232,18 +231,12 @@ cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2 tested. """ - if S1.length0: - if stop>start: + cdef mp_size_t length = 0 + if step > 0: + if stop > start: length = ((stop-start-1)//step)+1 - else: - biseq_init(R, 0, S.itembitsize) - return True else: - if stop>=start: - biseq_init(R, 0, S.itembitsize) - return True - else: + if stop < start: length = ((stop-start+1)//step)+1 biseq_init(R, length, S.itembitsize) - total_shift = start*S.itembitsize - if step==1: + + if not length: + return 0 + + if step == 1: # Slicing essentially boils down to a shift operation. - bitset_rshift(R.data, S.data, total_shift) - return True + bitset_rshift(R.data, S.data, start*S.itembitsize) + return 0 + # In the general case, we move item by item. cdef mp_size_t src_index = start - cdef mp_size_t tgt_index = 0 - for n from length>=n>0: - biseq_inititem(R, postinc(tgt_index), biseq_getitem(S, src_index)) + cdef mp_size_t tgt_index + for tgt_index in range(length): + biseq_inititem(R, tgt_index, biseq_getitem(S, src_index)) src_index += step cdef mp_size_t biseq_max_overlap(biseq_t S1, biseq_t S2) except 0: From cf166a67ba74f42f619671129f09028b9c174a1d Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 4 Dec 2014 13:54:49 +0100 Subject: [PATCH 227/698] Generalise biseq_max_overlap() and rename as biseq_reverse_contains() --- .../bounded_integer_sequences.pxd | 2 +- .../bounded_integer_sequences.pyx | 120 +++++++++--------- 2 files changed, 59 insertions(+), 63 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pxd b/src/sage/data_structures/bounded_integer_sequences.pxd index 7e93713a628..edc3e1fe78a 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pxd +++ b/src/sage/data_structures/bounded_integer_sequences.pxd @@ -40,7 +40,7 @@ cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1 cdef bint biseq_init_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1 cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1 cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2 -cdef mp_size_t biseq_max_overlap(biseq_t S1, biseq_t S2) except 0 +cdef mp_size_t biseq_reverse_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2 cdef mp_size_t biseq_index(biseq_t S, size_t item, mp_size_t start) except -2 cdef size_t biseq_getitem(biseq_t S, mp_size_t index) cdef biseq_getitem_py(biseq_t S, mp_size_t index) diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index 99c5cfe0172..94a463220e7 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -43,10 +43,11 @@ cimported in Cython modules: ``S1[start:]``, or ``-1`` if ``S2`` is not a subsequence. Does not check whether the sequences have the same bound! -- ``cdef mp_size_t biseq_max_overlap(biseq_t S1, biseq_t S2) except 0`` +- ``cdef mp_size_t biseq_reverse_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2:`` - Return the minimal *positive* integer ``i`` such that ``S2`` starts with - ``S1[i:]``. This function will *not* test whether ``S2`` starts with ``S1``! + Return ``i`` such that the bounded integer sequence ``S1`` starts with + the sequence ``S2[i:]``, where ``start <= i < S2.length``, or return + ``-1`` if no such ``i`` exists. - ``cdef mp_size_t biseq_index(biseq_t S, size_t item, mp_size_t start) except -2`` @@ -209,36 +210,6 @@ cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1: return mpn_equal_bits(S1.data.bits, S2.data.bits, S2.data.size) -cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2: - """ - Tests if the bounded integer sequence ``S1[start:]`` contains a - sub-sequence ``S2``. - - INPUT: - - - ``S1``, ``S2`` -- two bounded integer sequences - - ``start`` -- integer, start index - - OUTPUT: - - Index ``i>=start`` such that ``S1[i:]`` starts with ``S2``, or ``-1`` if - ``S1[start:]`` does not contain ``S2``. - - ASSUMPTION: - - - The two sequences must have equivalent bounds, i.e., the items on the - sequences must fit into the same number of bits. This condition is not - tested. - - """ - if S2.length == 0: - return start - cdef mp_size_t index - for index from start <= index <= S1.length-S2.length: - if mpn_equal_bits_shifted(S2.data.bits, S1.data.bits, S2.data.size, index*S1.itembitsize): - return index - return -1 - cdef mp_size_t biseq_index(biseq_t S, size_t item, mp_size_t start) except -2: """ Returns the position in ``S`` of an item in ``S[start:]``, or -1 if @@ -343,44 +314,72 @@ cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop biseq_inititem(R, tgt_index, biseq_getitem(S, src_index)) src_index += step -cdef mp_size_t biseq_max_overlap(biseq_t S1, biseq_t S2) except 0: + +cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2: """ - Returns the smallest **positive** integer ``i`` such that ``S2`` starts with ``S1[i:]``. + Tests if the bounded integer sequence ``S1[start:]`` contains a + sub-sequence ``S2``. - Returns ``-1`` if there is no overlap. Note that ``i==0`` (``S2`` starts with ``S1``) - will not be considered! + INPUT: + + - ``S1``, ``S2`` -- two bounded integer sequences + - ``start`` -- integer, start index + + OUTPUT: + + Index ``i >= start`` such that ``S1[i:]`` starts with ``S2``, or ``-1`` if + ``S1[start:]`` does not contain ``S2``. + + ASSUMPTION: + + - The two sequences must have equivalent bounds, i.e., the items on the + sequences must fit into the same number of bits. This condition is not + tested. + + """ + if S2.length == 0: + return start + cdef mp_size_t index + for index from start <= index <= S1.length-S2.length: + if mpn_equal_bits_shifted(S2.data.bits, S1.data.bits, + S2.length*S2.itembitsize, index*S2.itembitsize): + return index + return -1 + +cdef mp_size_t biseq_reverse_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2: + """ + Return ``i`` such that the bounded integer sequence ``S1`` starts with + the sequence ``S2[i:]``, where ``start <= i < S2.length``. INPUT: - ``S1``, ``S2`` -- two bounded integer sequences + - ``start`` -- integer, start index + + OUTPUT: + + Index ``i >= start`` such that ``S1`` starts with ``S2[i:], or ``-1`` + if no such ``i < S2.length`` exists. ASSUMPTION: - The two sequences must have equivalent bounds, i.e., the items on the - sequences must fit into the same number of bits. This condition is not - tested. + - The two sequences must have equivalent bounds, i.e., the items on the + sequences must fit into the same number of bits. This condition is not + tested. """ - if S1.length == 0: - raise ValueError("First argument must be of positive length") - cdef mp_size_t index, start_index - if S2.length>=S1.length: - start_index = 1 - else: - start_index = S1.length-S2.length - if start_index == S1.length: - return -1 - cdef mp_bitcnt_t offset = S1.itembitsize*start_index - cdef mp_bitcnt_t overlap = (S1.length-start_index)*S1.itembitsize - for index from start_index<=index """ - if other.startswith(self): - return self - cdef mp_size_t i = biseq_max_overlap(self.data, other.data) + cdef mp_size_t i = biseq_reverse_contains(other.data, self.data, 0) if i==-1: return None return self[i:] @@ -1371,5 +1368,4 @@ def _biseq_stresstest(): T = L[randint(0,99)] biseq_startswith(S.data,T.data) biseq_contains(S.data, T.data, 0) - if S.data.length>0: - biseq_max_overlap(S.data, T.data) + biseq_reverse_contains(S.data, T.data, 0) From 6cd5286d987cf944621fb7666f1756b7785bcd0b Mon Sep 17 00:00:00 2001 From: Ralf Stephan Date: Thu, 4 Dec 2014 15:04:08 +0100 Subject: [PATCH 228/698] 17399: handle series in ex.coefficients() --- src/sage/symbolic/expression.pyx | 42 +++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index dccf1b7d119..762a02924cc 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -5173,6 +5173,8 @@ cdef class Expression(CommutativeRingElement): [[2*a^2 + 1, 0], [-2*sqrt(2)*a + 1, 1], [1, 2]] sage: p.coefficients(x, sparse=False) [2*a^2 + 1, -2*sqrt(2)*a + 1, 1] + + TESTS: The behaviour is undefined with noninteger or negative exponents:: @@ -5190,17 +5192,34 @@ cdef class Expression(CommutativeRingElement): doctest:...: DeprecationWarning: coeffs is deprecated. Please use coefficients instead. See http://trac.sagemath.org/17438 for details. [[1, 1]] + + Series coefficients are now handled correctly (:trac:`17399`):: + + sage: s=(1/(1-x)).series(x,6); s + 1 + 1*x + 1*x^2 + 1*x^3 + 1*x^4 + 1*x^5 + Order(x^6) + sage: s.coefficients() + [[1, 0], [1, 1], [1, 2], [1, 3], [1, 4], [1, 5]] + sage: s.coefficients(x, sparse=False) + [1, 1, 1, 1, 1, 1] + sage: x,y = var("x,y") + sage: s=(1/(1-y*x-x)).series(x,3); s + 1 + (y + 1)*x + ((y + 1)^2)*x^2 + Order(x^3) + sage: s.coefficients(x, sparse=False) + [1, y + 1, (y + 1)^2] """ - f = self._maxima_() - maxima = f.parent() - maxima._eval_line('load(coeflist)') if x is None: x = self.default_variable() - x = self.parent().var(repr(x)) - G = f.coeffs(x) - from sage.calculus.calculus import symbolic_expression_from_maxima_string - S = symbolic_expression_from_maxima_string(repr(G)) - l = S[1:] + if is_a_series(self._gobj): + l = [[self.coefficient(x, d), d] for d in xrange(self.degree(x))] + else: + f = self._maxima_() + maxima = f.parent() + maxima._eval_line('load(coeflist)') + G = f.coeffs(x) + from sage.calculus.calculus import symbolic_expression_from_maxima_string + S = symbolic_expression_from_maxima_string(repr(G)) + l = S[1:] + if sparse is True: return l else: @@ -5237,9 +5256,6 @@ cdef class Expression(CommutativeRingElement): (x, y, a) sage: (x^5).list() [0, 0, 0, 0, 0, 1] - sage: p = x^3 - (x-3)*(x^2+x) + 1 - sage: p.list() - [1, 3, 2] sage: p = x - x^3 + 5/7*x^5 sage: p.list() [0, 1, 0, -1, 0, 5/7] @@ -5247,6 +5263,10 @@ cdef class Expression(CommutativeRingElement): -2*sqrt(2)*a*x + 2*a^2 + x^2 + x + 1 sage: p.list(a) [x^2 + x + 1, -2*sqrt(2)*x, 2] + sage: s=(1/(1-x)).series(x,6); s + 1 + 1*x + 1*x^2 + 1*x^3 + 1*x^4 + 1*x^5 + Order(x^6) + sage: s.list() + [1, 1, 1, 1, 1, 1] """ return self.coefficients(x=x, sparse=False) From 8db9f6542a54ead67c1df3d069103b620e85eea6 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 4 Dec 2014 14:31:04 +0100 Subject: [PATCH 229/698] Various improvements to BoundedIntegerSequence --- .../bounded_integer_sequences.pxd | 1 - .../bounded_integer_sequences.pyx | 183 ++++++++++-------- 2 files changed, 98 insertions(+), 86 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pxd b/src/sage/data_structures/bounded_integer_sequences.pxd index edc3e1fe78a..af6e9c15f41 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pxd +++ b/src/sage/data_structures/bounded_integer_sequences.pxd @@ -50,7 +50,6 @@ cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop cdef class BoundedIntegerSequence: cdef biseq_t data - cdef str str(self) cpdef bint startswith(self, BoundedIntegerSequence other) cpdef list list(self) cpdef BoundedIntegerSequence maximal_overlap(self, BoundedIntegerSequence other) diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index 94a463220e7..f391ccab88c 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -384,17 +384,17 @@ cdef mp_size_t biseq_reverse_contains(biseq_t S1, biseq_t S2, mp_size_t start) e # A cdef class that wraps the above, and # behaves like a tuple -from sage.rings.integer import Integer +from sage.rings.integer cimport smallInteger cdef class BoundedIntegerSequence: """ A sequence of non-negative uniformely bounded integers. INPUT: - - ``bound``, non-negative integer. When zero, a :class:`ValueError` + - ``bound`` -- non-negative integer. When zero, a :class:`ValueError` will be raised. Otherwise, the given bound is replaced by the power of two that is at least the given bound. - - ``data``, a list of integers. + - ``data`` -- a list of integers. EXAMPLES: @@ -426,9 +426,7 @@ cdef class BoundedIntegerSequence: sage: list(L) == L True - Getting items and slicing works in the same way as for lists. Note, - however, that slicing is an operation that is relatively slow for bounded - integer sequences. :: + Getting items and slicing works in the same way as for lists:: sage: n = randint(0,4999) sage: S[n] == L[n] @@ -470,8 +468,8 @@ cdef class BoundedIntegerSequence: sage: copy(L) is L False - Concatenation works in the same way for list, tuples and bounded integer - sequences:: + Concatenation works in the same way for lists, tuples and bounded + integer sequences:: sage: M = [randint(0,31) for i in range(5000)] sage: T = BoundedIntegerSequence(32, M) @@ -569,7 +567,7 @@ cdef class BoundedIntegerSequence: """ # In __init__, we'll raise an error if the bound is 0. - self.data.length = 0 + self.data.data.bits = NULL def __dealloc__(self): """ @@ -588,12 +586,11 @@ cdef class BoundedIntegerSequence: """ INPUT: - - ``bound`` -- non-negative. When zero, a :class:`ValueError` - will be raised. Otherwise, the given bound is replaced by the - next power of two that is greater than the given - bound. - - ``data`` -- a list of integers. The given integers will be - truncated to be less than the bound. + - ``bound`` -- positive integer. The given bound is replaced by + the next power of two that is greater than the given bound. + + - ``data`` -- a list of non-negative integers, all less than + ``bound``. EXAMPLES:: @@ -622,10 +619,9 @@ cdef class BoundedIntegerSequence: ... OverflowError: long int too large to convert - We are testing the corner case of the maximal possible bound - on a 32-bit system:: + We are testing the corner case of the maximal possible bound:: - sage: S = BoundedIntegerSequence(2^32, [8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10]) + sage: S = BoundedIntegerSequence(2*(sys.maxsize+1), [8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10]) sage: S <8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10> @@ -635,10 +631,10 @@ cdef class BoundedIntegerSequence: Traceback (most recent call last): ... OverflowError: long int too large to convert - sage: BoundedIntegerSequence(100, [200]) + sage: BoundedIntegerSequence(100, [100]) Traceback (most recent call last): ... - OverflowError: list item 200 larger than 99 + OverflowError: list item 100 larger than 99 Bounds that are too large:: @@ -670,7 +666,6 @@ cdef class BoundedIntegerSequence: """ Pickling of :class:`BoundedIntegerSequence` - EXAMPLES:: sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence @@ -745,28 +740,11 @@ cdef class BoundedIntegerSequence: <0, 0, 0, 0> """ - return '<'+self.str()+'>' - - cdef str str(self): - """ - A cdef helper function, returns the string representation without the brackets. - - Used in :meth:`__repr__`. - - EXAMPLES:: - - sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence - sage: BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) # indirect doctest - <4, 1, 6, 2, 7, 20, 9> - - """ - if self.data.length==0: - return '' - return ('{!s:}'+(self.data.length-1)*', {!s:}').format(*self.list()) + return "<" + ", ".join(str(x) for x in self) + ">" def bound(self): """ - The bound of this bounded integer sequence + Return the bound of this bounded integer sequence. All items of this sequence are non-negative integers less than the returned bound. The bound is a power of two. @@ -782,7 +760,7 @@ cdef class BoundedIntegerSequence: 64 """ - return Integer(1)< + <8, 6, 4, 2, 0> sage: S[1::2] - <1, 2, 2, 5> + <1, 3, 5, 7> :: @@ -905,7 +903,7 @@ cdef class BoundedIntegerSequence: if ind < 0: ind += self.data.length if ind < 0 or ind >= self.data.length: - raise IndexError("ind out of range") + raise IndexError("index out of range") return biseq_getitem_py(self.data, ind) def __contains__(self, other): @@ -933,7 +931,7 @@ cdef class BoundedIntegerSequence: sage: S.index(6+S.bound()) Traceback (most recent call last): ... - ValueError: BoundedIntegerSequence.index(x): x(=38) not in sequence + ValueError: 38 is not in sequence TESTS: @@ -967,13 +965,21 @@ cdef class BoundedIntegerSequence: sage: B.index(B[8:]) 8 + :: + + sage: -1 in B + False + """ if not isinstance(other, BoundedIntegerSequence): - return biseq_index(self.data, other, 0)>=0 + try: + return biseq_index(self.data, other, 0) >= 0 + except OverflowError: + return False cdef BoundedIntegerSequence right = other if self.data.itembitsize!=right.data.itembitsize: return False - return biseq_contains(self.data, right.data, 0)>=0 + return biseq_contains(self.data, right.data, 0) >= 0 cpdef list list(self): """ @@ -1050,58 +1056,69 @@ cdef class BoundedIntegerSequence: sage: S.index(5) Traceback (most recent call last): ... - ValueError: BoundedIntegerSequence.index(x): x(=5) not in sequence - sage: S.index(-3) - Traceback (most recent call last): - ... - ValueError: BoundedIntegerSequence.index(x): x(=-3) not in sequence + ValueError: 5 is not in sequence sage: S.index(BoundedIntegerSequence(21, [6, 2, 6])) 2 sage: S.index(BoundedIntegerSequence(21, [6, 2, 7])) Traceback (most recent call last): ... - ValueError: Not a sub-sequence + ValueError: not a sub-sequence The bound of (sub-)sequences matters:: sage: S.index(BoundedIntegerSequence(51, [6, 2, 6])) Traceback (most recent call last): ... - ValueError: Not a sub-sequence + ValueError: not a sub-sequence sage: S.index(0) 7 sage: S.index(S.bound()) Traceback (most recent call last): ... - ValueError: BoundedIntegerSequence.index(x): x(=32) not in sequence + ValueError: 32 is not in sequence TESTS:: - sage: S = BoundedIntegerSequence(8, [2, 2, 2, 1, 2, 4, 3, 3, 3, 2, 2, 0]) + sage: S = BoundedIntegerSequence(10^9, [2, 2, 2, 1, 2, 4, 3, 3, 3, 2, 2, 0]) sage: S[11] 0 sage: S.index(0) 11 + :: + + sage: S.index(-3) + Traceback (most recent call last): + ... + ValueError: -3 is not in sequence + sage: S.index(2^100) + Traceback (most recent call last): + ... + ValueError: 1267650600228229401496703205376 is not in sequence + sage: S.index("hello") + Traceback (most recent call last): + ... + TypeError: an integer is required + """ cdef mp_size_t out if not isinstance(other, BoundedIntegerSequence): - if other<0 or (other)&self.data.mask_item!=other: - raise ValueError("BoundedIntegerSequence.index(x): x(={}) not in sequence".format(other)) try: - out = biseq_index(self.data, other, 0) - except TypeError: - raise ValueError("BoundedIntegerSequence.index(x): x(={}) not in sequence".format(other)) - if out>=0: + out = biseq_index(self.data, other, 0) + except OverflowError: + out = -1 + if out >= 0: return out - raise ValueError("BoundedIntegerSequence.index(x): x(={}) not in sequence".format(other)) + raise ValueError("{!r} is not in sequence".format(other)) + cdef BoundedIntegerSequence right = other - if self.data.itembitsize!=right.data.itembitsize: - raise ValueError("Not a sub-sequence") - out = biseq_contains(self.data, right.data, 0) - if out>=0: + if self.data.itembitsize != right.data.itembitsize: + out = -1 + else: + out = biseq_contains(self.data, right.data, 0) + if out >= 0: return out - raise ValueError("Not a sub-sequence") + raise ValueError("not a sub-sequence") def __add__(self, other): """ @@ -1130,7 +1147,7 @@ cdef class BoundedIntegerSequence: sage: T+list(S) Traceback (most recent call last): ... - TypeError: Cannot convert list to sage.data_structures.bounded_integer_sequences.BoundedIntegerSequence + TypeError: Cannot convert list to sage.data_structures.bounded_integer_sequences.BoundedIntegerSequence sage: T+None Traceback (most recent call last): ... @@ -1235,7 +1252,7 @@ cdef class BoundedIntegerSequence: """ cdef BoundedIntegerSequence right - cdef BoundedIntegerSequence Self + cdef BoundedIntegerSequence left if other is None: return 1 if self is None: @@ -1245,16 +1262,16 @@ cdef class BoundedIntegerSequence: except TypeError: return -1 try: - Self = self + left = self except TypeError: return 1 - cdef int c = cmp(Self.data.itembitsize, right.data.itembitsize) + cdef int c = cmp(left.data.itembitsize, right.data.itembitsize) if c: return c - c = cmp(Self.data.length, right.data.length) + c = cmp(left.data.length, right.data.length) if c: return c - return bitset_cmp(Self.data.data, right.data.data) + return bitset_cmp(left.data.data, right.data.data) def __hash__(self): """ @@ -1306,18 +1323,14 @@ cpdef BoundedIntegerSequence NewBISEQ(tuple bitset_data, mp_bitcnt_t itembitsize And another one:: - sage: S = BoundedIntegerSequence(2^32-1, [8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10]) + sage: S = BoundedIntegerSequence(2*sys.maxsize, [8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10]) sage: loads(dumps(S)) <8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10> """ cdef BoundedIntegerSequence out = BoundedIntegerSequence.__new__(BoundedIntegerSequence) - out.data.itembitsize = itembitsize - out.data.mask_item = limb_lower_bits_up(itembitsize) - out.data.length = length - # bitset_unpickle assumes that out.data.data is initialised. - bitset_init(out.data.data, GMP_LIMB_BITS) + biseq_init(out.data, length, itembitsize) bitset_unpickle(out.data.data, bitset_data) return out From d8c8636df3ad7a71467db4b145cd3b3eeb87a9b0 Mon Sep 17 00:00:00 2001 From: kcrisman Date: Thu, 4 Dec 2014 13:19:27 -0500 Subject: [PATCH 230/698] Clarify what plot is in tour of sage --- src/doc/en/a_tour_of_sage/index.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/doc/en/a_tour_of_sage/index.rst b/src/doc/en/a_tour_of_sage/index.rst index cdd49dadcad..ef3222ef4c1 100644 --- a/src/doc/en/a_tour_of_sage/index.rst +++ b/src/doc/en/a_tour_of_sage/index.rst @@ -59,6 +59,11 @@ The result is a list of equalities. sage: S[0].rhs() -1/2*sqrt(4*a + 1) - 1/2 + +Naturally, Sage can plot various useful functions. + +:: + sage: show(plot(sin(x) + sin(1.6*x), 0, 40)) .. image:: sin_plot.* From f4ac40fe96cc610f0e7dd8bda02fc7049d783725 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Fri, 5 Dec 2014 07:52:34 +0100 Subject: [PATCH 231/698] trac #17443: deprecate abs + generic apply_map --- src/sage/matrix/matrix2.pyx | 171 ++++++++++++++++++++++++++++++- src/sage/matrix/matrix_dense.pyx | 137 ------------------------- 2 files changed, 168 insertions(+), 140 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index c9f97f84722..60f507cb76d 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -1466,7 +1466,7 @@ cdef class Matrix(matrix1.Matrix): def __abs__(self): """ - Synonym for self.determinant(...). + Not defined (since :trac:`17443`) EXAMPLES:: @@ -1474,9 +1474,174 @@ cdef class Matrix(matrix1.Matrix): [1 2] [3 4] sage: abs(a) - -2 + Traceback (most recent call last): + ... + TypeError: absolute value is not defined on matrices. If you want + the L^1-norm use m.norm(1) and if you want the matrix obtained by + applying the absolute value to the coefficents use m.apply_map(abs). + """ + raise TypeError("absolute value is not defined on matrices. If you want " + "the L^1-norm use m.norm(1) and if you want the matrix " + "obtained by applying the absolute value to the " + "coefficents use m.apply_map(abs).") + + def apply_morphism(self, phi): + """ + Apply the morphism phi to the coefficients of this dense matrix. + + The resulting matrix is over the codomain of phi. + + INPUT: + + + - ``phi`` - a morphism, so phi is callable and + phi.domain() and phi.codomain() are defined. The codomain must be a + ring. + + OUTPUT: a matrix over the codomain of phi + + EXAMPLES:: + + sage: m = matrix(ZZ, 3, range(9)) + sage: phi = ZZ.hom(GF(5)) + sage: m.apply_morphism(phi) + [0 1 2] + [3 4 0] + [1 2 3] + sage: parent(m.apply_morphism(phi)) + Full MatrixSpace of 3 by 3 dense matrices over Finite Field of size 5 + + We apply a morphism to a matrix over a polynomial ring:: + + sage: R. = QQ[] + sage: m = matrix(2, [x,x^2 + y, 2/3*y^2-x, x]); m + [ x x^2 + y] + [2/3*y^2 - x x] + sage: phi = R.hom([y,x]) + sage: m.apply_morphism(phi) + [ y y^2 + x] + [2/3*x^2 - y y] + """ + M = self.parent().change_ring(phi.codomain()) + if self.is_sparse(): + values = {(i,j): phi(z) for (i,j),z in self.dict()} + else: + values = [phi(z) for z in self.list()] + image = M(values) + if self._subdivisions is not None: + image.subdivide(*self.subdivisions()) + return image + + def apply_map(self, phi, R=None, sparse=None): + """ + Apply the given map phi (an arbitrary Python function or callable + object) to this dense matrix. If R is not given, automatically + determine the base ring of the resulting matrix. + + INPUT: + + - ``sparse`` -- True to make the output a sparse matrix; default False + + - ``phi`` - arbitrary Python function or callable object + + - ``R`` - (optional) ring + + OUTPUT: a matrix over R + + EXAMPLES:: + + sage: m = matrix(ZZ, 3, range(9)) + sage: k. = GF(9) + sage: f = lambda x: k(x) + sage: n = m.apply_map(f); n + [0 1 2] + [0 1 2] + [0 1 2] + sage: n.parent() + Full MatrixSpace of 3 by 3 dense matrices over Finite Field in a of size 3^2 + + In this example, we explicitly specify the codomain. + + :: + + sage: s = GF(3) + sage: f = lambda x: s(x) + sage: n = m.apply_map(f, k); n + [0 1 2] + [0 1 2] + [0 1 2] + sage: n.parent() + Full MatrixSpace of 3 by 3 dense matrices over Finite Field in a of size 3^2 + + If self is subdivided, the result will be as well:: + + sage: m = matrix(2, 2, srange(4)) + sage: m.subdivide(None, 1); m + [0|1] + [2|3] + sage: m.apply_map(lambda x: x*x) + [0|1] + [4|9] + + If the matrix is sparse, the result will be as well:: + + sage: m = matrix(ZZ,100,100,sparse=True) + sage: m[18,32] = -6 + sage: m[1,83] = 19 + sage: n = m.apply_map(abs, R=ZZ) + sage: n.dict() + {(1, 83): 19, (18, 32): 6} + sage: n.is_sparse() + True + + If the map sends most of the matrix to zero, then it may be useful + to get the result as a sparse matrix. + + :: + + sage: m = matrix(ZZ, 3, 3, range(1, 10)) + sage: n = m.apply_map(lambda x: 1//x, sparse=True); n + [1 0 0] + [0 0 0] + [0 0 0] + sage: n.parent() + Full MatrixSpace of 3 by 3 sparse matrices over Integer Ring + + TESTS:: + + sage: m = matrix([]) + sage: m.apply_map(lambda x: x*x) == m + True + + sage: m.apply_map(lambda x: x*x, sparse=True).parent() + Full MatrixSpace of 0 by 0 sparse matrices over Integer Ring """ - return self.determinant() + if self._nrows == 0 or self._ncols == 0: + if sparse is None or self.is_sparse() is sparse: + return self.__copy__() + elif sparse: + return self.sparse_matrix() + else: + return self.dense_matrix() + + if self.is_sparse(): + values = {(i,j): phi(v) for (i,j),v in self.dict().iteritems()} + if R is None: + R = sage.structure.sequence.Sequence(values.values()).universe() + else: + values = [phi(v) for v in self.list()] + if R is None: + R = sage.structure.sequence.Sequence(values).universe() + + if sparse is None or sparse is self.is_sparse(): + M = self.parent().change_ring(R) + else: + M = sage.matrix.matrix_space.MatrixSpace(R, self._nrows, + self._ncols, sparse=sparse) + image = M(values) + if self._subdivisions is not None: + image.subdivide(*self.subdivisions()) + return image def characteristic_polynomial(self, *args, **kwds): """ diff --git a/src/sage/matrix/matrix_dense.pyx b/src/sage/matrix/matrix_dense.pyx index 31fe4020211..615efaf9202 100644 --- a/src/sage/matrix/matrix_dense.pyx +++ b/src/sage/matrix/matrix_dense.pyx @@ -266,143 +266,6 @@ cdef class Matrix_dense(matrix.Matrix): prod.set_unsafe(r,c,entry) return prod - def apply_morphism(self, phi): - """ - Apply the morphism phi to the coefficients of this dense matrix. - - The resulting matrix is over the codomain of phi. - - INPUT: - - - - ``phi`` - a morphism, so phi is callable and - phi.domain() and phi.codomain() are defined. The codomain must be a - ring. - - - OUTPUT: a matrix over the codomain of phi - - EXAMPLES:: - - sage: m = matrix(ZZ, 3, range(9)) - sage: phi = ZZ.hom(GF(5)) - sage: m.apply_morphism(phi) - [0 1 2] - [3 4 0] - [1 2 3] - sage: parent(m.apply_morphism(phi)) - Full MatrixSpace of 3 by 3 dense matrices over Finite Field of size 5 - - We apply a morphism to a matrix over a polynomial ring:: - - sage: R. = QQ[] - sage: m = matrix(2, [x,x^2 + y, 2/3*y^2-x, x]); m - [ x x^2 + y] - [2/3*y^2 - x x] - sage: phi = R.hom([y,x]) - sage: m.apply_morphism(phi) - [ y y^2 + x] - [2/3*x^2 - y y] - """ - R = phi.codomain() - M = sage.matrix.matrix_space.MatrixSpace(R, self._nrows, - self._ncols, sparse=False) - image = M([phi(z) for z in self.list()]) - if self._subdivisions is not None: - image.subdivide(*self.subdivisions()) - return image - - def apply_map(self, phi, R=None, sparse=False): - """ - Apply the given map phi (an arbitrary Python function or callable - object) to this dense matrix. If R is not given, automatically - determine the base ring of the resulting matrix. - - INPUT: - sparse -- True to make the output a sparse matrix; default False - - - - ``phi`` - arbitrary Python function or callable - object - - - ``R`` - (optional) ring - - - OUTPUT: a matrix over R - - EXAMPLES:: - - sage: m = matrix(ZZ, 3, range(9)) - sage: k. = GF(9) - sage: f = lambda x: k(x) - sage: n = m.apply_map(f); n - [0 1 2] - [0 1 2] - [0 1 2] - sage: n.parent() - Full MatrixSpace of 3 by 3 dense matrices over Finite Field in a of size 3^2 - - In this example, we explicitly specify the codomain. - - :: - - sage: s = GF(3) - sage: f = lambda x: s(x) - sage: n = m.apply_map(f, k); n - [0 1 2] - [0 1 2] - [0 1 2] - sage: n.parent() - Full MatrixSpace of 3 by 3 dense matrices over Finite Field in a of size 3^2 - - If self is subdivided, the result will be as well:: - - sage: m = matrix(2, 2, srange(4)) - sage: m.subdivide(None, 1); m - [0|1] - [2|3] - sage: m.apply_map(lambda x: x*x) - [0|1] - [4|9] - - If the map sends most of the matrix to zero, then it may be useful - to get the result as a sparse matrix. - - :: - - sage: m = matrix(ZZ, 3, 3, range(1, 10)) - sage: n = m.apply_map(lambda x: 1//x, sparse=True); n - [1 0 0] - [0 0 0] - [0 0 0] - sage: n.parent() - Full MatrixSpace of 3 by 3 sparse matrices over Integer Ring - - TESTS:: - - sage: m = matrix([]) - sage: m.apply_map(lambda x: x*x) == m - True - - sage: m.apply_map(lambda x: x*x, sparse=True).parent() - Full MatrixSpace of 0 by 0 sparse matrices over Integer Ring - """ - if self._nrows==0 or self._ncols==0: - if sparse: - return self.sparse_matrix() - else: - return self.__copy__() - v = [phi(z) for z in self.list()] - if R is None: - v = sage.structure.sequence.Sequence(v) - R = v.universe() - M = sage.matrix.matrix_space.MatrixSpace(R, self._nrows, - self._ncols, sparse=sparse) - image = M(v) - if self._subdivisions is not None: - image.subdivide(*self.subdivisions()) - return image - def _derivative(self, var=None, R=None): """ Differentiate with respect to var by differentiating each element From 253fc21867d070748a2c6391fbddd960e98c1aaa Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Thu, 27 Nov 2014 19:44:20 +0530 Subject: [PATCH 232/698] trac #17408: Faster transitive_reduction (=> faster Poset creation) --- src/sage/combinat/posets/posets.py | 3 +- src/sage/graphs/base/static_dense_graph.pyx | 2 +- src/sage/graphs/generic_graph.py | 19 +++--- src/sage/graphs/generic_graph_pyx.pyx | 64 +++++++++++++++++++++ 4 files changed, 75 insertions(+), 13 deletions(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index c5747a43c28..ef2233eeb49 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -549,7 +549,8 @@ def Poset(data=None, element_labels=None, cover_relations=False, linear_extensio # Determine cover relations, if necessary. if cover_relations is False: - D = D.transitive_reduction() + from sage.graphs.generic_graph_pyx import transitive_reduction_acyclic + D = transitive_reduction_acyclic(D) # Check that the digraph does not contain loops, multiple edges # and is transitively reduced. diff --git a/src/sage/graphs/base/static_dense_graph.pyx b/src/sage/graphs/base/static_dense_graph.pyx index b872d51117b..11e98fe212d 100644 --- a/src/sage/graphs/base/static_dense_graph.pyx +++ b/src/sage/graphs/base/static_dense_graph.pyx @@ -41,7 +41,7 @@ Functions --------- """ -cdef dict dense_graph_init(binary_matrix_t m, g, translation = False): +cdef dict dense_graph_init(binary_matrix_t m, g, translation=False): r""" Initializes the binary matrix from a Sage (di)graph. diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 632464aaeae..b0b43e0de10 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -14575,15 +14575,9 @@ def transitive_closure(self): sage: digraphs.Path(5).copy(immutable=True).transitive_closure() Transitive closure of Path: Digraph on 5 vertices """ - from copy import copy G = self.copy(immutable=False) G.name('Transitive closure of ' + self.name()) - for v in G: - # todo optimization opportunity: we are adding edges that - # are already in the graph and we are adding edges - # one at a time. - for e in G.breadth_first_search(v): - G.add_edge((v,e)) + G.add_edges((v,e) for v in G for e in G.breadth_first_search(v)) return G def transitive_reduction(self): @@ -14612,14 +14606,17 @@ def transitive_reduction(self): sage: g.transitive_reduction().size() 5 """ - from copy import copy - from sage.rings.infinity import Infinity - G = copy(self) + if self.is_directed_acyclic(): + from sage.graphs.generic_graph_pyx import transitive_reduction_acyclic + return transitive_reduction_acyclic(self) + + G = self.copy(immutable=False) + n = G.order() for e in self.edge_iterator(): # Try deleting the edge, see if we still have a path # between the vertices. G.delete_edge(e) - if G.distance(e[0],e[1])==Infinity: + if G.distance(e[0],e[1]) > n: # oops, we shouldn't have deleted it G.add_edge(e) return G diff --git a/src/sage/graphs/generic_graph_pyx.pyx b/src/sage/graphs/generic_graph_pyx.pyx index c456ffe29cc..983d600ea9c 100644 --- a/src/sage/graphs/generic_graph_pyx.pyx +++ b/src/sage/graphs/generic_graph_pyx.pyx @@ -18,6 +18,7 @@ AUTHORS: include "sage/ext/interrupt.pxi" include 'sage/ext/cdefs.pxi' include 'sage/ext/stdsage.pxi' +include "sage/misc/binary_matrix.pxi" # import from Python standard library from sage.misc.prandom import random @@ -1280,3 +1281,66 @@ cpdef tuple find_hamiltonian( G, long max_iter=100000, long reset_bound=30000, l return (True,output) +def transitive_reduction_acyclic(G): + r""" + Returns the transitive reduction of an acyclic digraph + + INPUT: + + - ``G`` -- an acyclic digraph. + + EXAMPLE:: + + sage: from sage.graphs.generic_graph_pyx import transitive_reduction_acyclic + sage: G = posets.BooleanLattice(4).hasse_diagram() + sage: G == transitive_reduction_acyclic(G.transitive_closure()) + True + """ + cdef int n = G.order() + cdef dict v_to_int = {vv:i for i,vv in enumerate(G.vertices())} + cdef int u,v,i + + cdef list linear_extension = G.topological_sort() + linear_extension.reverse() + + cdef binary_matrix_t closure + + # Build the transitive closure of G + # + # A point is reachable from u if it is one of its neighbours, or if it is + # reachable from one of its neighbours. + binary_matrix_init(closure,n,n) + binary_matrix_fill(closure,0) + for uu in linear_extension: + u = v_to_int[uu] + for vv in G.neighbors_out(uu): + v = v_to_int[vv] + binary_matrix_set1(closure,u,v) + for i in range(closure.width): + closure.rows[u][i] |= closure.rows[v][i] + + # Build the transitive reduction of G + # + # An edge uv belongs to the transitive reduction of G if no outneighbor of u + # can reach v (except v itself, of course). + linear_extension.reverse() + cdef list useful_edges = [] + for uu in linear_extension: + u = v_to_int[uu] + for vv in G.neighbors_out(uu): + v = v_to_int[vv] + for i in range(closure.width): + closure.rows[u][i] &= ~closure.rows[v][i] + for vv in G.neighbors_out(uu): + v = v_to_int[vv] + if binary_matrix_get(closure,u,v): + useful_edges.append((uu,vv)) + + from sage.graphs.digraph import DiGraph + reduced = DiGraph() + reduced.add_edges(useful_edges) + reduced.add_vertices(linear_extension) + + binary_matrix_free(closure) + + return reduced From 179ffcff2b52c1b5f19a10a25acbc3139a13f3ce Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Fri, 5 Dec 2014 11:52:06 +0000 Subject: [PATCH 233/698] initialilzing with stuff from 2.8, with new patches added, and old commented --- build/pkgs/normaliz/SPKG.txt | 48 +++++++++++++++++++ build/pkgs/normaliz/checksums.ini | 4 ++ build/pkgs/normaliz/package-version.txt | 1 + .../patches/00-remove-static-option.patch | 11 +++++ .../01-adjust-size-of-input-matrix-fix.patch | 12 +++++ .../normaliz/patches/cstddef_include.patch | 12 +++++ .../normaliz/patches/no_static_stuff.patch | 13 +++++ build/pkgs/normaliz/spkg-install | 24 ++++++++++ 8 files changed, 125 insertions(+) create mode 100644 build/pkgs/normaliz/SPKG.txt create mode 100644 build/pkgs/normaliz/checksums.ini create mode 100644 build/pkgs/normaliz/package-version.txt create mode 100644 build/pkgs/normaliz/patches/00-remove-static-option.patch create mode 100644 build/pkgs/normaliz/patches/01-adjust-size-of-input-matrix-fix.patch create mode 100644 build/pkgs/normaliz/patches/cstddef_include.patch create mode 100644 build/pkgs/normaliz/patches/no_static_stuff.patch create mode 100755 build/pkgs/normaliz/spkg-install diff --git a/build/pkgs/normaliz/SPKG.txt b/build/pkgs/normaliz/SPKG.txt new file mode 100644 index 00000000000..f9fa657566f --- /dev/null +++ b/build/pkgs/normaliz/SPKG.txt @@ -0,0 +1,48 @@ += normaliz = + +== Description == + +Normaliz is a tool for computations in affine monoids, vector configurations, lattice polytopes, and rational cones. + +For more details see http://www.mathematik.uni-osnabrueck.de/normaliz/ + +== License == + + * GPL v3 + +== SPKG Maintainers == + + * Andrey Novoseltsev + +== Upstream Contact == + + * Winfried Bruns + * Bogdan Ichim + * Christof Söger + +== Dependencies == + +== Special Update/Build Instructions == + + * The upstream "basic package" is placed in src/ + +=== Patches === + + * 00-remove-static-option.patch ensures MacOS compatibility. + + * 01-adjust-size-of-input-matrix-fix.patch fixes regression in 2.8 Singular interface (provided by Christof Söger from upstream). + +== Changelog == + +=== normaliz-2.8.p1 (Dima Pasechnik, December 1 2014) === + + * added binary option to a patch call, as it now needs is + +=== normaliz-2.8.p0 (Dima Pasechnik, December 2 2012) === + + * Bumped up the version due to a nontrivial patch to singular.lib + +=== normaliz-2.8 (Andrey Novoseltsev, December 2 2012) === + + * Initial release. See Sage Trac #13234. + diff --git a/build/pkgs/normaliz/checksums.ini b/build/pkgs/normaliz/checksums.ini new file mode 100644 index 00000000000..f58244dd7ac --- /dev/null +++ b/build/pkgs/normaliz/checksums.ini @@ -0,0 +1,4 @@ +tarball=normaliz-VERSION.tar.bz2 +sha1=1b0202c74c15316059512f846704285ed1db187a +md5=190b0217419478cef719e7ab22472ea5 +cksum=3250052656 diff --git a/build/pkgs/normaliz/package-version.txt b/build/pkgs/normaliz/package-version.txt new file mode 100644 index 00000000000..3cf561c0b67 --- /dev/null +++ b/build/pkgs/normaliz/package-version.txt @@ -0,0 +1 @@ +2.12.1 diff --git a/build/pkgs/normaliz/patches/00-remove-static-option.patch b/build/pkgs/normaliz/patches/00-remove-static-option.patch new file mode 100644 index 00000000000..9b24b217a17 --- /dev/null +++ b/build/pkgs/normaliz/patches/00-remove-static-option.patch @@ -0,0 +1,11 @@ +--- a/source/Makefile.configuration 2012-06-20 19:22:32.000000000 -0600 ++++ b/source/Makefile.configuration 2012-10-21 21:01:53.175417130 -0600 +@@ -18,8 +18,4 @@ + CXXFLAGS += -fopenmp + endif + +-##for mac link libgcc not static +-NORMFLAGS = -static +-#NORMFLAGS = -static-libgcc +- + GMPFLAGS = -lgmpxx -lgmp diff --git a/build/pkgs/normaliz/patches/01-adjust-size-of-input-matrix-fix.patch b/build/pkgs/normaliz/patches/01-adjust-size-of-input-matrix-fix.patch new file mode 100644 index 00000000000..a5977c97458 --- /dev/null +++ b/build/pkgs/normaliz/patches/01-adjust-size-of-input-matrix-fix.patch @@ -0,0 +1,12 @@ +--- a/Singular/normaliz.lib 2012-06-29 11:08:48.000000000 -0600 ++++ b/Singular/normaliz.lib 2012-12-02 17:58:34.273516924 -0700 +@@ -1371,7 +1374,8 @@ + + //adjust size of input matrix + if (!last_comp) { // remove last component +- intmat tmp = expo_vecs[1..nrows(expo_vecs),1..(ncols(expo_vecs)-1)]; ++ intmat tmp[nrows(expo_vecs)][ncols(expo_vecs)-1] ++ = expo_vecs[1..nrows(expo_vecs),1..(ncols(expo_vecs)-1)]; + expo_vecs = tmp; + } + intmat nmz_data=runNormaliz(expo_vecs,nmz_mode,prepareGrading(#)); diff --git a/build/pkgs/normaliz/patches/cstddef_include.patch b/build/pkgs/normaliz/patches/cstddef_include.patch new file mode 100644 index 00000000000..86d4af876a0 --- /dev/null +++ b/build/pkgs/normaliz/patches/cstddef_include.patch @@ -0,0 +1,12 @@ +diff --git a/source/libnormaliz/general.h b/source/libnormaliz/general.h +index 2719378..c58a474 100644 +--- a/source/libnormaliz/general.h ++++ b/source/libnormaliz/general.h +@@ -25,6 +25,7 @@ + #define GENERAL_H_ + + ++#include + #include + #include + diff --git a/build/pkgs/normaliz/patches/no_static_stuff.patch b/build/pkgs/normaliz/patches/no_static_stuff.patch new file mode 100644 index 00000000000..1b8ee9978a8 --- /dev/null +++ b/build/pkgs/normaliz/patches/no_static_stuff.patch @@ -0,0 +1,13 @@ +diff --git a/source/Makefile.configuration b/source/Makefile.configuration +index 2160c1b..6f4cd95 100644 +--- a/source/Makefile.configuration ++++ b/source/Makefile.configuration +@@ -19,7 +19,7 @@ else + endif + + ## for distributing the executables link static (does not work for mac) +-CXXFLAGS += -static ++#CXXFLAGS += -static + ## for almost static compilation on Mac use + #CXXFLAGS += -static-libgcc + ## make it compatible with older Mac versions diff --git a/build/pkgs/normaliz/spkg-install b/build/pkgs/normaliz/spkg-install new file mode 100755 index 00000000000..f9b9de357a6 --- /dev/null +++ b/build/pkgs/normaliz/spkg-install @@ -0,0 +1,24 @@ +#!/usr/bin/env sh + +die () { + echo "$@" 1>&2 + exit 1 +} + +[ -n "$SAGE_LOCAL" ] || die 'Error: $SAGE_LOCAL not set. Source sage-env or run this script from `sage -sh`.' + +cd src +#patch -p1 < ../patches/00-remove-static-option.patch || die "Error: Couldn't apply patch." +patch -p1 < ../patches/cstddef_include.patch || die "Error: Couldn't apply patch." +patch -p1 < ../patches/no_static_stuff.patch || die "Error: Couldn't apply patch." +#patch --binary -p1 < ../patches/01-adjust-size-of-input-matrix-fix.patch || die "Error: Couldn't apply patch." + +export CXXFLAGS="-I$SAGE_LOCAL/include $CXXFLAGS" +cd source +$MAKE || die "Error building Normaliz." + +cp -pf normaliz "$SAGE_LOCAL/bin/" || die "Error installing Normaliz." + +cd ../Singular +cp -pf normaliz.lib "$SAGE_LOCAL/share/singular/" || die "Error installing normaliz.lib for Singular." + From 1b265b7dd78ba0158813ce202bb836bf0cf72094 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Fri, 5 Dec 2014 12:15:59 +0000 Subject: [PATCH 234/698] cleaning up --- build/pkgs/normaliz/SPKG.txt | 21 +++++++++++++++---- .../patches/00-remove-static-option.patch | 11 ---------- .../01-adjust-size-of-input-matrix-fix.patch | 12 ----------- build/pkgs/normaliz/spkg-install | 2 -- 4 files changed, 17 insertions(+), 29 deletions(-) delete mode 100644 build/pkgs/normaliz/patches/00-remove-static-option.patch delete mode 100644 build/pkgs/normaliz/patches/01-adjust-size-of-input-matrix-fix.patch diff --git a/build/pkgs/normaliz/SPKG.txt b/build/pkgs/normaliz/SPKG.txt index f9fa657566f..073c2b306fc 100644 --- a/build/pkgs/normaliz/SPKG.txt +++ b/build/pkgs/normaliz/SPKG.txt @@ -12,6 +12,7 @@ For more details see http://www.mathematik.uni-osnabrueck.de/normaliz/ == SPKG Maintainers == + * Dima Pasechnik * Andrey Novoseltsev == Upstream Contact == @@ -24,17 +25,29 @@ For more details see http://www.mathematik.uni-osnabrueck.de/normaliz/ == Special Update/Build Instructions == - * The upstream "basic package" is placed in src/ +* Normaliz is now distributed as .zip archive. + Download it from http://www.home.uni-osnabrueck.de/wbruns/normaliz/Normaliz2.12.1/ + unzip + tar cjf normaliz-.tar.bz2 + put the latter in $SAGEROOT/upstream/, etc. === Patches === - * 00-remove-static-option.patch ensures MacOS compatibility. - - * 01-adjust-size-of-input-matrix-fix.patch fixes regression in 2.8 Singular interface (provided by Christof Söger from upstream). + * no_static_stuff.patch - patching included into Makefile stuff that sets '-static' in CXXFLAGS + * cstddef_include.patch - include before mpir/gmp, to work around the MPIR bug == Changelog == +=== normaliz-2.12.1 (Dima Pasechnik, December 5 2014) === + + * switched to spkg new style + * removed old obsolete patches + * added patch to get rid of '-static' + * added patch to include before mpir/gmp, to work around the MPIR bug + triggered by the update of gcc to 4.9.2 + === normaliz-2.8.p1 (Dima Pasechnik, December 1 2014) === + (not be be released, see link on #17426) * added binary option to a patch call, as it now needs is diff --git a/build/pkgs/normaliz/patches/00-remove-static-option.patch b/build/pkgs/normaliz/patches/00-remove-static-option.patch deleted file mode 100644 index 9b24b217a17..00000000000 --- a/build/pkgs/normaliz/patches/00-remove-static-option.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/source/Makefile.configuration 2012-06-20 19:22:32.000000000 -0600 -+++ b/source/Makefile.configuration 2012-10-21 21:01:53.175417130 -0600 -@@ -18,8 +18,4 @@ - CXXFLAGS += -fopenmp - endif - --##for mac link libgcc not static --NORMFLAGS = -static --#NORMFLAGS = -static-libgcc -- - GMPFLAGS = -lgmpxx -lgmp diff --git a/build/pkgs/normaliz/patches/01-adjust-size-of-input-matrix-fix.patch b/build/pkgs/normaliz/patches/01-adjust-size-of-input-matrix-fix.patch deleted file mode 100644 index a5977c97458..00000000000 --- a/build/pkgs/normaliz/patches/01-adjust-size-of-input-matrix-fix.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/Singular/normaliz.lib 2012-06-29 11:08:48.000000000 -0600 -+++ b/Singular/normaliz.lib 2012-12-02 17:58:34.273516924 -0700 -@@ -1371,7 +1374,8 @@ - - //adjust size of input matrix - if (!last_comp) { // remove last component -- intmat tmp = expo_vecs[1..nrows(expo_vecs),1..(ncols(expo_vecs)-1)]; -+ intmat tmp[nrows(expo_vecs)][ncols(expo_vecs)-1] -+ = expo_vecs[1..nrows(expo_vecs),1..(ncols(expo_vecs)-1)]; - expo_vecs = tmp; - } - intmat nmz_data=runNormaliz(expo_vecs,nmz_mode,prepareGrading(#)); diff --git a/build/pkgs/normaliz/spkg-install b/build/pkgs/normaliz/spkg-install index f9b9de357a6..7d39f87b1d5 100755 --- a/build/pkgs/normaliz/spkg-install +++ b/build/pkgs/normaliz/spkg-install @@ -8,10 +8,8 @@ die () { [ -n "$SAGE_LOCAL" ] || die 'Error: $SAGE_LOCAL not set. Source sage-env or run this script from `sage -sh`.' cd src -#patch -p1 < ../patches/00-remove-static-option.patch || die "Error: Couldn't apply patch." patch -p1 < ../patches/cstddef_include.patch || die "Error: Couldn't apply patch." patch -p1 < ../patches/no_static_stuff.patch || die "Error: Couldn't apply patch." -#patch --binary -p1 < ../patches/01-adjust-size-of-input-matrix-fix.patch || die "Error: Couldn't apply patch." export CXXFLAGS="-I$SAGE_LOCAL/include $CXXFLAGS" cd source From 1560ce8dff16ed1fceabcc5656312f718d874211 Mon Sep 17 00:00:00 2001 From: Simon King Date: Fri, 5 Dec 2014 00:56:46 +0100 Subject: [PATCH 235/698] Rename biseq_reverse_contains as biseq_startswith_tail --- .../bounded_integer_sequences.pxd | 2 +- .../bounded_integer_sequences.pyx | 32 +++++++++++-------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pxd b/src/sage/data_structures/bounded_integer_sequences.pxd index af6e9c15f41..ee819024c27 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pxd +++ b/src/sage/data_structures/bounded_integer_sequences.pxd @@ -40,7 +40,7 @@ cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1 cdef bint biseq_init_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1 cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1 cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2 -cdef mp_size_t biseq_reverse_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2 +cdef mp_size_t biseq_startswith_tail(biseq_t S1, biseq_t S2, mp_size_t start) except -2 cdef mp_size_t biseq_index(biseq_t S, size_t item, mp_size_t start) except -2 cdef size_t biseq_getitem(biseq_t S, mp_size_t index) cdef biseq_getitem_py(biseq_t S, mp_size_t index) diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index f391ccab88c..7f5e63292cc 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -43,11 +43,11 @@ cimported in Cython modules: ``S1[start:]``, or ``-1`` if ``S2`` is not a subsequence. Does not check whether the sequences have the same bound! -- ``cdef mp_size_t biseq_reverse_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2:`` +- ``cdef mp_size_t biseq_starswith_tail(biseq_t S1, biseq_t S2, mp_size_t start) except -2:`` - Return ``i`` such that the bounded integer sequence ``S1`` starts with - the sequence ``S2[i:]``, where ``start <= i < S2.length``, or return - ``-1`` if no such ``i`` exists. + Return the smallest number ``i`` such that the bounded integer sequence + ``S1`` starts with the sequence ``S2[i:]``, where ``start <= i < + S1.length``, or return ``-1`` if no such ``i`` exists. - ``cdef mp_size_t biseq_index(biseq_t S, size_t item, mp_size_t start) except -2`` @@ -327,8 +327,8 @@ cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2 OUTPUT: - Index ``i >= start`` such that ``S1[i:]`` starts with ``S2``, or ``-1`` if - ``S1[start:]`` does not contain ``S2``. + The smallest index ``i >= start`` such that ``S1[i:]`` starts with + ``S2``, or ``-1`` if ``S1[start:]`` does not contain ``S2``. ASSUMPTION: @@ -346,10 +346,11 @@ cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2 return index return -1 -cdef mp_size_t biseq_reverse_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2: +cdef mp_size_t biseq_startswith_tail(biseq_t S1, biseq_t S2, mp_size_t start) except -2: """ - Return ``i`` such that the bounded integer sequence ``S1`` starts with - the sequence ``S2[i:]``, where ``start <= i < S2.length``. + Return the smallest index ``i`` such that the bounded integer sequence + ``S1`` starts with the sequence ``S2[i:]``, where ``start <= i < + S2.length``. INPUT: @@ -358,8 +359,8 @@ cdef mp_size_t biseq_reverse_contains(biseq_t S1, biseq_t S2, mp_size_t start) e OUTPUT: - Index ``i >= start`` such that ``S1`` starts with ``S2[i:], or ``-1`` - if no such ``i < S2.length`` exists. + The smallest index ``i >= start`` such that ``S1`` starts with ``S2[i:], + or ``-1`` if no such ``i < S2.length`` exists. ASSUMPTION: @@ -379,7 +380,6 @@ cdef mp_size_t biseq_reverse_contains(biseq_t S1, biseq_t S2, mp_size_t start) e return -1 - ########################################### # A cdef class that wraps the above, and # behaves like a tuple @@ -1194,9 +1194,13 @@ cdef class BoundedIntegerSequence: None sage: (X+S).maximal_overlap(BoundedIntegerSequence(21, [0,0])) <0, 0> + sage: B1 = BoundedIntegerSequence(4,[1,2,3,2,3,2,3]) + sage: B2 = BoundedIntegerSequence(4,[2,3,2,3,2,3,1]) + sage: B1.maximal_overlap(B2) + <2, 3, 2, 3, 2, 3> """ - cdef mp_size_t i = biseq_reverse_contains(other.data, self.data, 0) + cdef mp_size_t i = biseq_startswith_tail(other.data, self.data, 0) if i==-1: return None return self[i:] @@ -1381,4 +1385,4 @@ def _biseq_stresstest(): T = L[randint(0,99)] biseq_startswith(S.data,T.data) biseq_contains(S.data, T.data, 0) - biseq_reverse_contains(S.data, T.data, 0) + biseq_startswith_tail(S.data, T.data, 0) From ae4317a3ad0c946133c13fa44a51bf681e465fa4 Mon Sep 17 00:00:00 2001 From: Ben Hutz Date: Fri, 5 Dec 2014 10:32:57 -0500 Subject: [PATCH 236/698] 17429: fixed typos --- src/sage/schemes/projective/projective_point.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/projective/projective_point.py b/src/sage/schemes/projective/projective_point.py index e014d241f6e..7a2b9603863 100644 --- a/src/sage/schemes/projective/projective_point.py +++ b/src/sage/schemes/projective/projective_point.py @@ -165,7 +165,7 @@ def __init__(self, X, v, check=True): def __eq__(self,right): """ - Tests the proejctive equality of two points. + Tests the projective equality of two points. INPUT: @@ -267,7 +267,7 @@ def __eq__(self,right): def __ne__(self,right): """ - Tests the proejctive equality of two points. + Tests the projective equality of two points. INPUT: From 0eebe9015c55f3f5a349a1605e3cafa070f17014 Mon Sep 17 00:00:00 2001 From: Ben Hutz Date: Fri, 5 Dec 2014 10:59:12 -0500 Subject: [PATCH 237/698] 17427: improve hash for projective points --- .../schemes/projective/projective_point.py | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/sage/schemes/projective/projective_point.py b/src/sage/schemes/projective/projective_point.py index 4c54016a6ad..6f94616aab5 100644 --- a/src/sage/schemes/projective/projective_point.py +++ b/src/sage/schemes/projective/projective_point.py @@ -35,10 +35,12 @@ # http://www.gnu.org/licenses/ #***************************************************************************** +from sage.categories.integral_domains import IntegralDomains from sage.categories.number_fields import NumberFields _NumberFields = NumberFields() from sage.rings.infinity import infinity from sage.rings.arith import gcd, lcm, is_prime +from sage.rings.fraction_field import FractionField from sage.rings.integer_ring import ZZ from sage.rings.number_field.order import is_NumberFieldOrder from sage.rings.padics.all import Qp @@ -340,6 +342,48 @@ def __ne__(self,right): return True return False + def __hash__(self): + """ + Computes the hash value of ``self``. + + OUTPUT: Integer. + + EXAMPLES:: + + sage: P.=ProjectiveSpace(ZZ,1) + sage: hash(P([1,1])) + 7316841028997809016 # 64-bit + sage: hash(P.point([2,2], False)) + 7316841028997809016 # 64-bit + + :: + + sage: R.=PolynomialRing(QQ) + sage: K.=NumberField(x^2+3) + sage: O=K.maximal_order() + sage: P.=ProjectiveSpace(O,1) + sage: hash(P([1+w,2])) + 4801154424156762579 # 64-bit + sage: hash(P([2,1-w])) + 4801154424156762579 # 64-bit + + :: + + sage: P.=ProjectiveSpace(Zmod(10), 1) + sage: hash(P([2,5])) + 4677413289753502123 # 64-bit + """ + R = self.codomain().base_ring() + #if there is a fraction field normalize the point so that + #equal points have equal hash values + if R in IntegralDomains(): + P = self.change_ring(FractionField(R)) + P.normalize_coordinates() + return hash(str(P)) + #if there is no good way to normalize return + #a constant value + return hash(self.codomain()) + def scale_by(self,t): """ Scale the coordinates of the point ``self`` by `t`. A ``TypeError`` occurs if @@ -1056,6 +1100,24 @@ def __init__(self, X, v, check=True): self._coords = v + def __hash__(self): + """ + Computes the hash value of ``self``. + + OUTPUT: Integer. + + EXAMPLES:: + + sage: P.=ProjectiveSpace(QQ, 1) + sage: hash(P([1/2,1])) + 3714374126286711103 # 64-bit + sage: hash(P.point([1,2], False)) + 3714374126286711103 # 64-bit + """ + P = copy(self) + P.normalize_coordinates() + return hash(str(P)) + def normalize_coordinates(self): r""" Normalizes ``self`` so that the last non-zero coordinate is `1`. From ecb25f38a6c443569c805f2b5d6ca259e4c948f4 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Fri, 5 Dec 2014 16:21:09 +0000 Subject: [PATCH 238/698] bumped up to p0, due to patches we apply --- build/pkgs/normaliz/SPKG.txt | 2 +- build/pkgs/normaliz/package-version.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/pkgs/normaliz/SPKG.txt b/build/pkgs/normaliz/SPKG.txt index 073c2b306fc..507f027d39a 100644 --- a/build/pkgs/normaliz/SPKG.txt +++ b/build/pkgs/normaliz/SPKG.txt @@ -38,7 +38,7 @@ For more details see http://www.mathematik.uni-osnabrueck.de/normaliz/ == Changelog == -=== normaliz-2.12.1 (Dima Pasechnik, December 5 2014) === +=== normaliz-2.12.1.p0 (Dima Pasechnik, December 5 2014) === * switched to spkg new style * removed old obsolete patches diff --git a/build/pkgs/normaliz/package-version.txt b/build/pkgs/normaliz/package-version.txt index 3cf561c0b67..99c9c199e7e 100644 --- a/build/pkgs/normaliz/package-version.txt +++ b/build/pkgs/normaliz/package-version.txt @@ -1 +1 @@ -2.12.1 +2.12.1.p0 From 16c812ed493ce744beb93e349334bab7d1d546ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 5 Dec 2014 17:39:17 +0100 Subject: [PATCH 239/698] trac #17432 correct bullet list and wikipedia role --- .../quiver_mutation_type.py | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py index 2fa9a916b5d..dfa3551469f 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py @@ -326,14 +326,16 @@ def _samples(self): the rank. - Affine type -- there is more than one convention for naming affine -types. * Kac's notation: ``letter`` is a Dynkin type, ``rank`` is the -rank of the associated finite Dynkin diagram, and ``twist`` is the -twist, which could be 1, 2, or 3. In the special case of affine type -A, there is more than one quiver mutation type associated to the -Cartan type. In this case only, ``rank`` is a pair of integers (i,j), -giving the number of edges pointing clockwise and the number of edges -pointing counter-clockwise. The total number of vertices is given by -i+j in this case. + types. + + * Kac's notation: ``letter`` is a Dynkin type, ``rank`` is the + rank of the associated finite Dynkin diagram, and ``twist`` is the + twist, which could be 1, 2, or 3. In the special case of affine + type A, there is more than one quiver mutation type associated to + the Cartan type. In this case only, ``rank`` is a pair of integers + (i,j), giving the number of edges pointing clockwise and the number + of edges pointing counter-clockwise. The total number of vertices + is given by i+j in this case. * Naive notation: ``letter`` is one of 'BB', 'BC', 'BD', 'CC', 'CD'. The name specifies the two ends of the diagram, which are @@ -393,7 +395,7 @@ def _samples(self): REFERENCES: - A good reference for finite and affine Dynkin diagrams, including - Kac's notation, is the Wikipedia article :wikipedia:`Dynkin_diagram`. + Kac's notation, is the :wikipedia:`Dynkin_diagram`. - A good reference for the skew-symmetrizable elliptic diagrams is "Cluster algebras of finite mutation type via unfolding" by From 476d8c43f23185ea22c46a9b30fd37c9ead46668 Mon Sep 17 00:00:00 2001 From: Karl-Dieter Crisman Date: Fri, 5 Dec 2014 13:56:40 -0500 Subject: [PATCH 240/698] Add doctests for #7401 about derivatives at a point --- src/sage/symbolic/expression_conversions.py | 41 +++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/sage/symbolic/expression_conversions.py b/src/sage/symbolic/expression_conversions.py index 8a93b5d58d2..d09f9fc2c4d 100644 --- a/src/sage/symbolic/expression_conversions.py +++ b/src/sage/symbolic/expression_conversions.py @@ -507,6 +507,47 @@ def derivative(self, ex, operator): D[0](f)(x*y) sage: m.derivative(t, t.operator()) "at(diff('f(_SAGE_VAR_t0), _SAGE_VAR_t0, 1), [_SAGE_VAR_t0 = (_SAGE_VAR_x)*(_SAGE_VAR_y)])" + + TESTS: + + Most of these confirm that :trac:`7401` was fixed:: + + sage: t=var('t'); f=function('f', t) + sage: a = 2**e^t*f.subs(t=e^t)*diff(f,t).subs(t=e^t) + 2*t + sage: solve ( a == 0, diff(f,t).subs(t=e^t)) + [D[0](f)(e^t) == -2^(-e^t + 1)*t/f(e^t)] + + :: + + sage: a = function('f', x).diff(x).subs(x=exp(x)); b=maxima(a); b + %at('diff('f(_SAGE_VAR_t0),_SAGE_VAR_t0,1),[_SAGE_VAR_t0=%e^_SAGE_VAR_x]) + sage: b.sage() + D[0](f)(e^x) + + :: + + sage: a = function('f', x).diff(x).subs(x=4); b=maxima(a); b + %at('diff('f(_SAGE_VAR_t0),_SAGE_VAR_t0,1),[_SAGE_VAR_t0=4]) + sage: b.sage() + D[0](f)(4) + + It also works with more than one variable:: + + sage: x,y,=var('x y') + sage: a = function('f', x, y).diff(x).subs(x=4).subs(y=8) + sage: b=maxima(a); b + %at('diff('f(_SAGE_VAR_t0,_SAGE_VAR_t1),_SAGE_VAR_t0,1),[_SAGE_VAR_t0=4,_SAGE_VAR_t1=8]) + sage: b.sage() + D[0](f)(4, 8) + + :: + + sage: x,y,=var('x y') + sage: a = function('f', x, y).diff(x).subs(x=4) + sage: b=maxima(a); b + %at('diff('f(_SAGE_VAR_t0,_SAGE_VAR_t1),_SAGE_VAR_t0,1),[_SAGE_VAR_t0=4,_SAGE_VAR_t1=_SAGE_VAR_y]) + sage: b.sage() + D[0](f)(4, y) """ #This code should probably be moved into the interface #object in a nice way. From 6e7ad656ba3307ff67949e251550c101758f9963 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Fri, 5 Dec 2014 14:10:43 +0100 Subject: [PATCH 241/698] Show Cython code in IPython tracebacks --- build/pkgs/ipython/package-version.txt | 2 +- .../pkgs/ipython/patches/ultratb-master.patch | 1022 +++++++++++++++++ src/sage/all.py | 20 +- src/sage/libs/mwrank/interface.py | 10 +- src/sage/repl/interpreter.py | 23 +- src/sage/rings/integer_ring.pyx | 2 +- 6 files changed, 1056 insertions(+), 23 deletions(-) create mode 100644 build/pkgs/ipython/patches/ultratb-master.patch diff --git a/build/pkgs/ipython/package-version.txt b/build/pkgs/ipython/package-version.txt index 276cbf9e285..a0ffc34b8f6 100644 --- a/build/pkgs/ipython/package-version.txt +++ b/build/pkgs/ipython/package-version.txt @@ -1 +1 @@ -2.3.0 +2.3.0.p0 diff --git a/build/pkgs/ipython/patches/ultratb-master.patch b/build/pkgs/ipython/patches/ultratb-master.patch new file mode 100644 index 00000000000..dd50aacb6ad --- /dev/null +++ b/build/pkgs/ipython/patches/ultratb-master.patch @@ -0,0 +1,1022 @@ +Trac #17382: upgrade the whole file ultratb.py to latest git master + +--- a/IPython/core/ultratb.py 2014-10-02 01:55:50.000000000 +0200 ++++ b/IPython/core/ultratb.py 2014-12-06 10:59:11.228558666 +0100 +@@ -39,7 +39,7 @@ + Verbose). + + +-Installation instructions for ColorTB:: ++Installation instructions for VerboseTB:: + + import sys,ultratb + sys.excepthook = ultratb.VerboseTB() +@@ -73,11 +73,11 @@ + """ + + #***************************************************************************** +-# Copyright (C) 2001 Nathaniel Gray +-# Copyright (C) 2001-2004 Fernando Perez ++# Copyright (C) 2001 Nathaniel Gray ++# Copyright (C) 2001-2004 Fernando Perez + # +-# Distributed under the terms of the BSD License. The full license is in +-# the file COPYING, distributed as part of this software. ++# Distributed under the terms of the BSD License. The full license is in ++# the file COPYING, distributed as part of this software. + #***************************************************************************** + + from __future__ import unicode_literals +@@ -95,14 +95,14 @@ + import traceback + import types + +-try: # Python 2 ++try: # Python 2 + generate_tokens = tokenize.generate_tokens +-except AttributeError: # Python 3 ++except AttributeError: # Python 3 + generate_tokens = tokenize.tokenize + + # For purposes of monkeypatching inspect to fix a bug in it. +-from inspect import getsourcefile, getfile, getmodule,\ +- ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode ++from inspect import getsourcefile, getfile, getmodule, \ ++ ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode + + # IPython's own modules + # Modified pdb which doesn't damage IPython's readline handling +@@ -125,11 +125,11 @@ + + # Default color scheme. This is used, for example, by the traceback + # formatter. When running in an actual IPython instance, the user's rc.colors +-# value is used, but havinga module global makes this functionality available ++# value is used, but having a module global makes this functionality available + # to users of ultratb who are NOT running inside ipython. + DEFAULT_SCHEME = 'NoColor' + +-#--------------------------------------------------------------------------- ++# --------------------------------------------------------------------------- + # Code begins + + # Utility functions +@@ -141,6 +141,7 @@ + error('Internal Python error in the inspect module.\n' + 'Below is the traceback from this internal error.\n') + ++ + # This function is a monkeypatch we apply to the Python inspect module. We have + # now found when it's needed (see discussion on issue gh-1456), and we have a + # test case (IPython.core.tests.test_ultratb.ChangedPyFileTest) that fails if +@@ -212,7 +213,7 @@ + pmatch = pat.match + # fperez - fix: sometimes, co_firstlineno can give a number larger than + # the length of lines, which causes an error. Safeguard against that. +- lnum = min(object.co_firstlineno,len(lines))-1 ++ lnum = min(object.co_firstlineno, len(lines)) - 1 + while lnum > 0: + if pmatch(lines[lnum]): break + lnum -= 1 +@@ -220,9 +221,11 @@ + return lines, lnum + raise IOError('could not find code object') + ++ + # Monkeypatch inspect to apply our bugfix. + def with_patch_inspect(f): + """decorator for monkeypatching inspect.findsource""" ++ + def wrapped(*args, **kwargs): + save_findsource = inspect.findsource + inspect.findsource = findsource +@@ -230,8 +233,10 @@ + return f(*args, **kwargs) + finally: + inspect.findsource = save_findsource ++ + return wrapped + ++ + def fix_frame_records_filenames(records): + """Try to fix the filenames in each record from inspect.getinnerframes(). + +@@ -240,24 +245,25 @@ + """ + fixed_records = [] + for frame, filename, line_no, func_name, lines, index in records: +- # Look inside the frame's globals dictionary for __file__, which should +- # be better. +- better_fn = frame.f_globals.get('__file__', None) +- if isinstance(better_fn, str): +- # Check the type just in case someone did something weird with +- # __file__. It might also be None if the error occurred during +- # import. +- filename = better_fn ++ # Look inside the frame's globals dictionary for __file__, ++ # which should be better. However, keep Cython filenames since ++ # we prefer the source filenames over the compiled .so file. ++ if not filename.endswith(('.pyx', '.pxd', '.pxi')): ++ better_fn = frame.f_globals.get('__file__', None) ++ if isinstance(better_fn, str): ++ # Check the type just in case someone did something weird with ++ # __file__. It might also be None if the error occurred during ++ # import. ++ filename = better_fn + fixed_records.append((frame, filename, line_no, func_name, lines, index)) + return fixed_records + + + @with_patch_inspect +-def _fixed_getinnerframes(etb, context=1,tb_offset=0): +- LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5 +- +- records = fix_frame_records_filenames(inspect.getinnerframes(etb, context)) ++def _fixed_getinnerframes(etb, context=1, tb_offset=0): ++ LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5 + ++ records = fix_frame_records_filenames(inspect.getinnerframes(etb, context)) + # If the error is at the console, don't build any context, since it would + # otherwise produce 5 blank lines printed out (there is no file at the + # console) +@@ -272,9 +278,9 @@ + aux = traceback.extract_tb(etb) + assert len(records) == len(aux) + for i, (file, lnum, _, _) in zip(range(len(records)), aux): +- maybeStart = lnum-1 - context//2 +- start = max(maybeStart, 0) +- end = start + context ++ maybeStart = lnum - 1 - context // 2 ++ start = max(maybeStart, 0) ++ end = start + context + lines = ulinecache.getlines(file)[start:end] + buf = list(records[i]) + buf[LNUM_POS] = lnum +@@ -290,7 +296,8 @@ + + _parser = PyColorize.Parser() + +-def _format_traceback_lines(lnum, index, lines, Colors, lvals=None,scheme=None): ++ ++def _format_traceback_lines(lnum, index, lines, Colors, lvals=None, scheme=None): + numbers_width = INDENT_SIZE - 1 + res = [] + i = lnum - index +@@ -315,7 +322,7 @@ + # This is the line with the error + pad = numbers_width - len(str(i)) + if pad >= 3: +- marker = '-'*(pad-3) + '-> ' ++ marker = '-' * (pad - 3) + '-> ' + elif pad == 2: + marker = '> ' + elif pad == 1: +@@ -323,12 +330,12 @@ + else: + marker = '' + num = marker + str(i) +- line = '%s%s%s %s%s' %(Colors.linenoEm, num, +- Colors.line, line, Colors.Normal) ++ line = '%s%s%s %s%s' % (Colors.linenoEm, num, ++ Colors.line, line, Colors.Normal) + else: +- num = '%*s' % (numbers_width,i) +- line = '%s%s%s %s' %(Colors.lineno, num, +- Colors.Normal, line) ++ num = '%*s' % (numbers_width, i) ++ line = '%s%s%s %s' % (Colors.lineno, num, ++ Colors.Normal, line) + + res.append(line) + if lvals and i == lnum: +@@ -389,16 +396,16 @@ + + ostream = property(_get_ostream, _set_ostream) + +- def set_colors(self,*args,**kw): ++ def set_colors(self, *args, **kw): + """Shorthand access to the color table scheme selector method.""" + + # Set own color table +- self.color_scheme_table.set_active_scheme(*args,**kw) ++ self.color_scheme_table.set_active_scheme(*args, **kw) + # for convenience, set Colors to the active scheme + self.Colors = self.color_scheme_table.active_colors + # Also set colors of debugger +- if hasattr(self,'pdb') and self.pdb is not None: +- self.pdb.set_colors(*args,**kw) ++ if hasattr(self, 'pdb') and self.pdb is not None: ++ self.pdb.set_colors(*args, **kw) + + def color_toggle(self): + """Toggle between the currently active color scheme and NoColor.""" +@@ -453,7 +460,7 @@ + Because they are meant to be called without a full traceback (only a + list), instances of this class can't call the interactive pdb debugger.""" + +- def __init__(self,color_scheme = 'NoColor', call_pdb=False, ostream=None): ++ def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None): + TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb, + ostream=ostream) + +@@ -497,7 +504,7 @@ + elist = elist[tb_offset:] + + out_list.append('Traceback %s(most recent call last)%s:' % +- (Colors.normalEm, Colors.Normal) + '\n') ++ (Colors.normalEm, Colors.Normal) + '\n') + out_list.extend(self._format_list(elist)) + # The exception info should be a single entry in the list. + lines = ''.join(self._format_exception_only(etype, value)) +@@ -510,7 +517,7 @@ + ## out_list.append(lines[-1]) + + # This means it was indenting everything but the last line by a little +- # bit. I've disabled this for now, but if we see ugliness somewhre we ++ # bit. I've disabled this for now, but if we see ugliness somewhere we + # can restore it. + + return out_list +@@ -532,25 +539,24 @@ + list = [] + for filename, lineno, name, line in extracted_list[:-1]: + item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \ +- (Colors.filename, filename, Colors.Normal, +- Colors.lineno, lineno, Colors.Normal, +- Colors.name, name, Colors.Normal) ++ (Colors.filename, filename, Colors.Normal, ++ Colors.lineno, lineno, Colors.Normal, ++ Colors.name, name, Colors.Normal) + if line: + item += ' %s\n' % line.strip() + list.append(item) + # Emphasize the last entry + filename, lineno, name, line = extracted_list[-1] + item = '%s File %s"%s"%s, line %s%d%s, in %s%s%s%s\n' % \ +- (Colors.normalEm, +- Colors.filenameEm, filename, Colors.normalEm, +- Colors.linenoEm, lineno, Colors.normalEm, +- Colors.nameEm, name, Colors.normalEm, +- Colors.Normal) ++ (Colors.normalEm, ++ Colors.filenameEm, filename, Colors.normalEm, ++ Colors.linenoEm, lineno, Colors.normalEm, ++ Colors.nameEm, name, Colors.normalEm, ++ Colors.Normal) + if line: + item += '%s %s%s\n' % (Colors.line, line.strip(), +- Colors.Normal) ++ Colors.Normal) + list.append(item) +- #from pprint import pformat; print 'LISTTB', pformat(list) # dbg + return list + + def _format_exception_only(self, etype, value): +@@ -572,11 +578,10 @@ + stype = Colors.excName + etype.__name__ + Colors.Normal + if value is None: + # Not sure if this can still happen in Python 2.6 and above +- list.append( py3compat.cast_unicode(stype) + '\n') ++ list.append(py3compat.cast_unicode(stype) + '\n') + else: + if issubclass(etype, SyntaxError): + have_filedata = True +- #print 'filename is',filename # dbg + if not value.filename: value.filename = "" + if value.lineno: + lineno = value.lineno +@@ -585,9 +590,9 @@ + lineno = 'unknown' + textline = '' + list.append('%s File %s"%s"%s, line %s%s%s\n' % \ +- (Colors.normalEm, +- Colors.filenameEm, py3compat.cast_unicode(value.filename), Colors.normalEm, +- Colors.linenoEm, lineno, Colors.Normal )) ++ (Colors.normalEm, ++ Colors.filenameEm, py3compat.cast_unicode(value.filename), Colors.normalEm, ++ Colors.linenoEm, lineno, Colors.Normal )) + if textline == '': + textline = py3compat.cast_unicode(value.text, "utf-8") + +@@ -600,13 +605,13 @@ + Colors.Normal)) + if value.offset is not None: + s = ' ' +- for c in textline[i:value.offset-1]: ++ for c in textline[i:value.offset - 1]: + if c.isspace(): + s += c + else: + s += ' ' + list.append('%s%s^%s\n' % (Colors.caret, s, +- Colors.Normal) ) ++ Colors.Normal)) + + try: + s = value.msg +@@ -636,7 +641,6 @@ + """ + return ListTB.structured_traceback(self, etype, value, []) + +- + def show_exception_only(self, etype, evalue): + """Only print the exception type and message, without a traceback. + +@@ -659,6 +663,7 @@ + except: + return '' % type(value).__name__ + ++ + #---------------------------------------------------------------------------- + class VerboseTB(TBTools): + """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead +@@ -668,7 +673,7 @@ + traceback, to be used with alternate interpreters (because their own code + would appear in the traceback).""" + +- def __init__(self,color_scheme = 'Linux', call_pdb=False, ostream=None, ++ def __init__(self, color_scheme='Linux', call_pdb=False, ostream=None, + tb_offset=0, long_header=False, include_vars=True, + check_cache=None): + """Specify traceback offset, headers and color scheme. +@@ -691,132 +696,51 @@ + check_cache = linecache.checkcache + self.check_cache = check_cache + +- def structured_traceback(self, etype, evalue, etb, tb_offset=None, +- context=5): +- """Return a nice text document describing the traceback.""" +- +- tb_offset = self.tb_offset if tb_offset is None else tb_offset +- +- # some locals +- try: +- etype = etype.__name__ +- except AttributeError: +- pass +- Colors = self.Colors # just a shorthand + quicker name lookup +- ColorsNormal = Colors.Normal # used a lot +- col_scheme = self.color_scheme_table.active_scheme_name +- indent = ' '*INDENT_SIZE +- em_normal = '%s\n%s%s' % (Colors.valEm, indent,ColorsNormal) +- undefined = '%sundefined%s' % (Colors.em, ColorsNormal) +- exc = '%s%s%s' % (Colors.excName,etype,ColorsNormal) +- +- # some internal-use functions +- def text_repr(value): +- """Hopefully pretty robust repr equivalent.""" +- # this is pretty horrible but should always return *something* +- try: +- return pydoc.text.repr(value) +- except KeyboardInterrupt: +- raise +- except: +- try: +- return repr(value) +- except KeyboardInterrupt: +- raise +- except: +- try: +- # all still in an except block so we catch +- # getattr raising +- name = getattr(value, '__name__', None) +- if name: +- # ick, recursion +- return text_repr(name) +- klass = getattr(value, '__class__', None) +- if klass: +- return '%s instance' % text_repr(klass) +- except KeyboardInterrupt: +- raise +- except: +- return 'UNRECOVERABLE REPR FAILURE' +- def eqrepr(value, repr=text_repr): return '=%s' % repr(value) +- def nullrepr(value, repr=text_repr): return '' +- +- # meat of the code begins +- try: +- etype = etype.__name__ +- except AttributeError: +- pass +- +- if self.long_header: +- # Header with the exception type, python version, and date +- pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable +- date = time.ctime(time.time()) +- +- head = '%s%s%s\n%s%s%s\n%s' % (Colors.topline, '-'*75, ColorsNormal, +- exc, ' '*(75-len(str(etype))-len(pyver)), +- pyver, date.rjust(75) ) +- head += "\nA problem occured executing Python code. Here is the sequence of function"\ +- "\ncalls leading up to the error, with the most recent (innermost) call last." +- else: +- # Simplified header +- head = '%s%s%s\n%s%s' % (Colors.topline, '-'*75, ColorsNormal,exc, +- 'Traceback (most recent call last)'.\ +- rjust(75 - len(str(etype)) ) ) ++ def format_records(self, records): ++ Colors = self.Colors # just a shorthand + quicker name lookup ++ ColorsNormal = Colors.Normal # used a lot ++ col_scheme = self.color_scheme_table.active_scheme_name ++ indent = ' ' * INDENT_SIZE ++ em_normal = '%s\n%s%s' % (Colors.valEm, indent, ColorsNormal) ++ undefined = '%sundefined%s' % (Colors.em, ColorsNormal) + frames = [] +- # Flush cache before calling inspect. This helps alleviate some of the +- # problems with python 2.3's inspect.py. +- ##self.check_cache() +- # Drop topmost frames if requested +- try: +- # Try the default getinnerframes and Alex's: Alex's fixes some +- # problems, but it generates empty tracebacks for console errors +- # (5 blanks lines) where none should be returned. +- #records = inspect.getinnerframes(etb, context)[tb_offset:] +- #print 'python records:', records # dbg +- records = _fixed_getinnerframes(etb, context, tb_offset) +- #print 'alex records:', records # dbg +- except: +- +- # FIXME: I've been getting many crash reports from python 2.3 +- # users, traceable to inspect.py. If I can find a small test-case +- # to reproduce this, I should either write a better workaround or +- # file a bug report against inspect (if that's the real problem). +- # So far, I haven't been able to find an isolated example to +- # reproduce the problem. +- inspect_error() +- traceback.print_exc(file=self.ostream) +- info('\nUnfortunately, your original traceback can not be constructed.\n') +- return '' +- + # build some color string templates outside these nested loops +- tpl_link = '%s%%s%s' % (Colors.filenameEm,ColorsNormal) +- tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm, +- ColorsNormal) +- tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \ +- (Colors.vName, Colors.valEm, ColorsNormal) +- tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal) ++ tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal) ++ tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ++ ColorsNormal) ++ tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \ ++ (Colors.vName, Colors.valEm, ColorsNormal) ++ tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal) + tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal, + Colors.vName, ColorsNormal) +- tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal) +- tpl_line = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal) +- tpl_line_em = '%s%%s%s %%s%s' % (Colors.linenoEm,Colors.line, +- ColorsNormal) ++ tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal) ++ ++ tpl_line = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal) ++ tpl_line_em = '%s%%s%s %%s%s' % (Colors.linenoEm, Colors.line, ++ ColorsNormal) + +- # now, loop over all records printing context and info + abspath = os.path.abspath + for frame, file, lnum, func, lines, index in records: + #print '*** record:',file,lnum,func,lines,index # dbg + if not file: + file = '?' +- elif not(file.startswith(str("<")) and file.endswith(str(">"))): +- # Guess that filenames like aren't real filenames, so +- # don't call abspath on them. +- try: +- file = abspath(file) +- except OSError: +- # Not sure if this can still happen: abspath now works with +- # file names like +- pass ++ elif file.startswith(str("<")) and file.endswith(str(">")): ++ # Not a real filename, no problem... ++ pass ++ elif not os.path.isabs(file): ++ # Try to make the filename absolute by trying all ++ # sys.path entries (which is also what linecache does) ++ for dirname in sys.path: ++ try: ++ fullname = os.path.join(dirname, file) ++ if os.path.isfile(fullname): ++ file = os.path.abspath(fullname) ++ break ++ except Exception: ++ # Just in case that sys.path contains very ++ # strange entries... ++ pass ++ + file = py3compat.cast_unicode(file, util_path.fs_encoding) + link = tpl_link % file + args, varargs, varkw, locals = inspect.getargvalues(frame) +@@ -827,9 +751,9 @@ + # Decide whether to include variable details or not + var_repr = self.include_vars and eqrepr or nullrepr + try: +- call = tpl_call % (func,inspect.formatargvalues(args, +- varargs, varkw, +- locals,formatvalue=var_repr)) ++ call = tpl_call % (func, inspect.formatargvalues(args, ++ varargs, varkw, ++ locals, formatvalue=var_repr)) + except KeyError: + # This happens in situations like errors inside generator + # expressions, where local variables are listed in the +@@ -848,12 +772,12 @@ + # will illustrate the error, if this exception catch is + # disabled. + call = tpl_call_fail % func +- ++ + # Don't attempt to tokenize binary files. + if file.endswith(('.so', '.pyd', '.dll')): +- frames.append('%s %s\n' % (link,call)) ++ frames.append('%s %s\n' % (link, call)) + continue +- elif file.endswith(('.pyc','.pyo')): ++ elif file.endswith(('.pyc', '.pyo')): + # Look up the corresponding source file. + file = openpy.source_from_cache(file) + +@@ -867,7 +791,7 @@ + try: + names = [] + name_cont = False +- ++ + for token_type, token, start, end, line in generate_tokens(linereader): + # build composite names + if token_type == tokenize.NAME and token not in keyword.kwlist: +@@ -890,9 +814,11 @@ + name_cont = True + elif token_type == tokenize.NEWLINE: + break +- +- except (IndexError, UnicodeDecodeError): ++ ++ except (IndexError, UnicodeDecodeError, SyntaxError): + # signals exit of tokenizer ++ # SyntaxError can occur if the file is not actually Python ++ # - see gh-6300 + pass + except tokenize.TokenError as msg: + _m = ("An unexpected error occurred while tokenizing input\n" +@@ -909,11 +835,11 @@ + lvals = [] + if self.include_vars: + for name_full in unique_names: +- name_base = name_full.split('.',1)[0] ++ name_base = name_full.split('.', 1)[0] + if name_base in frame.f_code.co_varnames: + if name_base in locals: + try: +- value = repr(eval(name_full,locals)) ++ value = repr(eval(name_full, locals)) + except: + value = undefined + else: +@@ -922,69 +848,191 @@ + else: + if name_base in frame.f_globals: + try: +- value = repr(eval(name_full,frame.f_globals)) ++ value = repr(eval(name_full, frame.f_globals)) + except: + value = undefined + else: + value = undefined + name = tpl_global_var % name_full +- lvals.append(tpl_name_val % (name,value)) ++ lvals.append(tpl_name_val % (name, value)) + if lvals: +- lvals = '%s%s' % (indent,em_normal.join(lvals)) ++ lvals = '%s%s' % (indent, em_normal.join(lvals)) + else: + lvals = '' + +- level = '%s %s\n' % (link,call) ++ level = '%s %s\n' % (link, call) + + if index is None: + frames.append(level) + else: +- frames.append('%s%s' % (level,''.join( +- _format_traceback_lines(lnum,index,lines,Colors,lvals, ++ frames.append('%s%s' % (level, ''.join( ++ _format_traceback_lines(lnum, index, lines, Colors, lvals, + col_scheme)))) + ++ return frames ++ ++ def prepare_chained_exception_message(self, cause): ++ direct_cause = "\nThe above exception was the direct cause of the following exception:\n" ++ exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n" ++ ++ if cause: ++ message = [[direct_cause]] ++ else: ++ message = [[exception_during_handling]] ++ return message ++ ++ def prepare_header(self, etype, long_version=False): ++ colors = self.Colors # just a shorthand + quicker name lookup ++ colorsnormal = colors.Normal # used a lot ++ exc = '%s%s%s' % (colors.excName, etype, colorsnormal) ++ if long_version: ++ # Header with the exception type, python version, and date ++ pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable ++ date = time.ctime(time.time()) ++ ++ head = '%s%s%s\n%s%s%s\n%s' % (colors.topline, '-' * 75, colorsnormal, ++ exc, ' ' * (75 - len(str(etype)) - len(pyver)), ++ pyver, date.rjust(75) ) ++ head += "\nA problem occurred executing Python code. Here is the sequence of function" \ ++ "\ncalls leading up to the error, with the most recent (innermost) call last." ++ else: ++ # Simplified header ++ head = '%s%s' % (exc, 'Traceback (most recent call last)'. \ ++ rjust(75 - len(str(etype))) ) ++ ++ return head ++ ++ def format_exception(self, etype, evalue): ++ colors = self.Colors # just a shorthand + quicker name lookup ++ colorsnormal = colors.Normal # used a lot ++ indent = ' ' * INDENT_SIZE + # Get (safely) a string form of the exception info + try: +- etype_str,evalue_str = map(str,(etype,evalue)) ++ etype_str, evalue_str = map(str, (etype, evalue)) + except: + # User exception is improperly defined. +- etype,evalue = str,sys.exc_info()[:2] +- etype_str,evalue_str = map(str,(etype,evalue)) ++ etype, evalue = str, sys.exc_info()[:2] ++ etype_str, evalue_str = map(str, (etype, evalue)) + # ... and format it +- exception = ['%s%s%s: %s' % (Colors.excName, etype_str, +- ColorsNormal, py3compat.cast_unicode(evalue_str))] ++ exception = ['%s%s%s: %s' % (colors.excName, etype_str, ++ colorsnormal, py3compat.cast_unicode(evalue_str))] ++ + if (not py3compat.PY3) and type(evalue) is types.InstanceType: + try: + names = [w for w in dir(evalue) if isinstance(w, py3compat.string_types)] + except: +- # Every now and then, an object with funny inernals blows up ++ # Every now and then, an object with funny internals blows up + # when dir() is called on it. We do the best we can to report + # the problem and continue + _m = '%sException reporting error (object with broken dir())%s:' +- exception.append(_m % (Colors.excName,ColorsNormal)) +- etype_str,evalue_str = map(str,sys.exc_info()[:2]) +- exception.append('%s%s%s: %s' % (Colors.excName,etype_str, +- ColorsNormal, py3compat.cast_unicode(evalue_str))) ++ exception.append(_m % (colors.excName, colorsnormal)) ++ etype_str, evalue_str = map(str, sys.exc_info()[:2]) ++ exception.append('%s%s%s: %s' % (colors.excName, etype_str, ++ colorsnormal, py3compat.cast_unicode(evalue_str))) + names = [] + for name in names: + value = text_repr(getattr(evalue, name)) + exception.append('\n%s%s = %s' % (indent, name, value)) + +- # vds: >> ++ return exception ++ ++ def format_exception_as_a_whole(self, etype, evalue, etb, number_of_lines_of_context, tb_offset): ++ # some locals ++ try: ++ etype = etype.__name__ ++ except AttributeError: ++ pass ++ ++ tb_offset = self.tb_offset if tb_offset is None else tb_offset ++ head = self.prepare_header(etype, self.long_header) ++ records = self.get_records(etb, number_of_lines_of_context, tb_offset) ++ ++ frames = self.format_records(records) ++ if records is None: ++ return "" ++ ++ formatted_exception = self.format_exception(etype, evalue) + if records: +- filepath, lnum = records[-1][1:3] +- #print "file:", str(file), "linenb", str(lnum) # dbg +- filepath = os.path.abspath(filepath) +- ipinst = get_ipython() +- if ipinst is not None: +- ipinst.hooks.synchronize_with_editor(filepath, lnum, 0) +- # vds: << +- +- # return all our info assembled as a single string +- # return '%s\n\n%s\n%s' % (head,'\n'.join(frames),''.join(exception[0]) ) +- return [head] + frames + [''.join(exception[0])] ++ filepath, lnum = records[-1][1:3] ++ filepath = os.path.abspath(filepath) ++ ipinst = get_ipython() ++ if ipinst is not None: ++ ipinst.hooks.synchronize_with_editor(filepath, lnum, 0) ++ ++ return [[head] + frames + [''.join(formatted_exception[0])]] ++ ++ def get_records(self, etb, number_of_lines_of_context, tb_offset): ++ try: ++ # Try the default getinnerframes and Alex's: Alex's fixes some ++ # problems, but it generates empty tracebacks for console errors ++ # (5 blanks lines) where none should be returned. ++ return _fixed_getinnerframes(etb, number_of_lines_of_context, tb_offset) ++ except: ++ # FIXME: I've been getting many crash reports from python 2.3 ++ # users, traceable to inspect.py. If I can find a small test-case ++ # to reproduce this, I should either write a better workaround or ++ # file a bug report against inspect (if that's the real problem). ++ # So far, I haven't been able to find an isolated example to ++ # reproduce the problem. ++ inspect_error() ++ traceback.print_exc(file=self.ostream) ++ info('\nUnfortunately, your original traceback can not be constructed.\n') ++ return None ++ ++ def get_parts_of_chained_exception(self, evalue): ++ def get_chained_exception(exception_value): ++ cause = getattr(exception_value, '__cause__', None) ++ if cause: ++ return cause ++ return getattr(exception_value, '__context__', None) ++ ++ chained_evalue = get_chained_exception(evalue) ++ ++ if chained_evalue: ++ return chained_evalue.__class__, chained_evalue, chained_evalue.__traceback__ ++ ++ def structured_traceback(self, etype, evalue, etb, tb_offset=None, ++ number_of_lines_of_context=5): ++ """Return a nice text document describing the traceback.""" ++ ++ formatted_exception = self.format_exception_as_a_whole(etype, evalue, etb, number_of_lines_of_context, ++ tb_offset) + +- def debugger(self,force=False): ++ colors = self.Colors # just a shorthand + quicker name lookup ++ colorsnormal = colors.Normal # used a lot ++ head = '%s%s%s' % (colors.topline, '-' * 75, colorsnormal) ++ structured_traceback_parts = [head] ++ if py3compat.PY3: ++ chained_exceptions_tb_offset = 0 ++ lines_of_context = 3 ++ formatted_exceptions = formatted_exception ++ exception = self.get_parts_of_chained_exception(evalue) ++ if exception: ++ formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__) ++ etype, evalue, etb = exception ++ else: ++ evalue = None ++ while evalue: ++ formatted_exceptions += self.format_exception_as_a_whole(etype, evalue, etb, lines_of_context, ++ chained_exceptions_tb_offset) ++ exception = self.get_parts_of_chained_exception(evalue) ++ ++ if exception: ++ formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__) ++ etype, evalue, etb = exception ++ else: ++ evalue = None ++ ++ # we want to see exceptions in a reversed order: ++ # the first exception should be on top ++ for formatted_exception in reversed(formatted_exceptions): ++ structured_traceback_parts += formatted_exception ++ else: ++ structured_traceback_parts += formatted_exception[0] ++ ++ return structured_traceback_parts ++ ++ def debugger(self, force=False): + """Call up the pdb debugger if desired, always clean up the tb + reference. + +@@ -1014,7 +1062,7 @@ + with display_trap: + self.pdb.reset() + # Find the right frame so we don't pop up inside ipython itself +- if hasattr(self,'tb') and self.tb is not None: ++ if hasattr(self, 'tb') and self.tb is not None: + etb = self.tb + else: + etb = self.tb = sys.last_traceback +@@ -1025,7 +1073,7 @@ + self.pdb.botframe = etb.tb_frame + self.pdb.interaction(self.tb.tb_frame, self.tb) + +- if hasattr(self,'tb'): ++ if hasattr(self, 'tb'): + del self.tb + + def handler(self, info=None): +@@ -1050,6 +1098,7 @@ + except KeyboardInterrupt: + print("\nKeyboardInterrupt") + ++ + #---------------------------------------------------------------------------- + class FormattedTB(VerboseTB, ListTB): + """Subclass ListTB but allow calling with a traceback. +@@ -1069,7 +1118,7 @@ + check_cache=None): + + # NEVER change the order of this list. Put new modes at the end: +- self.valid_modes = ['Plain','Context','Verbose'] ++ self.valid_modes = ['Plain', 'Context', 'Verbose'] + self.verbose_modes = self.valid_modes[1:3] + + VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb, +@@ -1083,19 +1132,19 @@ + # set_mode also sets the tb_join_char attribute + self.set_mode(mode) + +- def _extract_tb(self,tb): ++ def _extract_tb(self, tb): + if tb: + return traceback.extract_tb(tb) + else: + return None + +- def structured_traceback(self, etype, value, tb, tb_offset=None, context=5): ++ def structured_traceback(self, etype, value, tb, tb_offset=None, number_of_lines_of_context=5): + tb_offset = self.tb_offset if tb_offset is None else tb_offset + mode = self.mode + if mode in self.verbose_modes: + # Verbose modes need a full traceback + return VerboseTB.structured_traceback( +- self, etype, value, tb, tb_offset, context ++ self, etype, value, tb, tb_offset, number_of_lines_of_context + ) + else: + # We must check the source cache because otherwise we can print +@@ -1104,7 +1153,7 @@ + # Now we can extract and format the exception + elist = self._extract_tb(tb) + return ListTB.structured_traceback( +- self, etype, value, elist, tb_offset, context ++ self, etype, value, elist, tb_offset, number_of_lines_of_context + ) + + def stb2text(self, stb): +@@ -1112,18 +1161,18 @@ + return self.tb_join_char.join(stb) + + +- def set_mode(self,mode=None): ++ def set_mode(self, mode=None): + """Switch to the desired mode. + + If mode is not specified, cycles through the available modes.""" + + if not mode: +- new_idx = ( self.valid_modes.index(self.mode) + 1 ) % \ ++ new_idx = (self.valid_modes.index(self.mode) + 1 ) % \ + len(self.valid_modes) + self.mode = self.valid_modes[new_idx] + elif mode not in self.valid_modes: +- raise ValueError('Unrecognized mode in FormattedTB: <'+mode+'>\n' +- 'Valid modes: '+str(self.valid_modes)) ++ raise ValueError('Unrecognized mode in FormattedTB: <' + mode + '>\n' ++ 'Valid modes: ' + str(self.valid_modes)) + else: + self.mode = mode + # include variable details only in 'Verbose' mode +@@ -1131,7 +1180,7 @@ + # Set the join character for generating text tracebacks + self.tb_join_char = self._join_chars[self.mode] + +- # some convenient shorcuts ++ # some convenient shortcuts + def plain(self): + self.set_mode(self.valid_modes[0]) + +@@ -1141,6 +1190,7 @@ + def verbose(self): + self.set_mode(self.valid_modes[2]) + ++ + #---------------------------------------------------------------------------- + class AutoFormattedTB(FormattedTB): + """A traceback printer which can be called on the fly. +@@ -1156,8 +1206,8 @@ + AutoTB() # or AutoTB(out=logfile) where logfile is an open file object + """ + +- def __call__(self,etype=None,evalue=None,etb=None, +- out=None,tb_offset=None): ++ def __call__(self, etype=None, evalue=None, etb=None, ++ out=None, tb_offset=None): + """Print out a formatted exception traceback. + + Optional arguments: +@@ -1167,7 +1217,6 @@ + per-call basis (this overrides temporarily the instance's tb_offset + given at initialization time. """ + +- + if out is None: + out = self.ostream + out.flush() +@@ -1182,33 +1231,36 @@ + print("\nKeyboardInterrupt") + + def structured_traceback(self, etype=None, value=None, tb=None, +- tb_offset=None, context=5): ++ tb_offset=None, number_of_lines_of_context=5): + if etype is None: +- etype,value,tb = sys.exc_info() ++ etype, value, tb = sys.exc_info() + self.tb = tb + return FormattedTB.structured_traceback( +- self, etype, value, tb, tb_offset, context) ++ self, etype, value, tb, tb_offset, number_of_lines_of_context) ++ + + #--------------------------------------------------------------------------- + + # A simple class to preserve Nathan's original functionality. + class ColorTB(FormattedTB): + """Shorthand to initialize a FormattedTB in Linux colors mode.""" +- def __init__(self,color_scheme='Linux',call_pdb=0): +- FormattedTB.__init__(self,color_scheme=color_scheme, ++ ++ def __init__(self, color_scheme='Linux', call_pdb=0): ++ FormattedTB.__init__(self, color_scheme=color_scheme, + call_pdb=call_pdb) + + + class SyntaxTB(ListTB): + """Extension which holds some state: the last exception value""" + +- def __init__(self,color_scheme = 'NoColor'): +- ListTB.__init__(self,color_scheme) ++ def __init__(self, color_scheme='NoColor'): ++ ListTB.__init__(self, color_scheme) + self.last_syntax_error = None + + def __call__(self, etype, value, elist): + self.last_syntax_error = value +- ListTB.__call__(self,etype,value,elist) ++ ++ ListTB.__call__(self, etype, value, elist) + + def structured_traceback(self, etype, value, elist, tb_offset=None, + context=5): +@@ -1223,7 +1275,7 @@ + if newtext: + value.text = newtext + return super(SyntaxTB, self).structured_traceback(etype, value, elist, +- tb_offset=tb_offset, context=context) ++ tb_offset=tb_offset, context=context) + + def clear_err_state(self): + """Return the current error state and clear it""" +@@ -1236,7 +1288,46 @@ + return ''.join(stb) + + ++# some internal-use functions ++def text_repr(value): ++ """Hopefully pretty robust repr equivalent.""" ++ # this is pretty horrible but should always return *something* ++ try: ++ return pydoc.text.repr(value) ++ except KeyboardInterrupt: ++ raise ++ except: ++ try: ++ return repr(value) ++ except KeyboardInterrupt: ++ raise ++ except: ++ try: ++ # all still in an except block so we catch ++ # getattr raising ++ name = getattr(value, '__name__', None) ++ if name: ++ # ick, recursion ++ return text_repr(name) ++ klass = getattr(value, '__class__', None) ++ if klass: ++ return '%s instance' % text_repr(klass) ++ except KeyboardInterrupt: ++ raise ++ except: ++ return 'UNRECOVERABLE REPR FAILURE' ++ ++ ++def eqrepr(value, repr=text_repr): ++ return '=%s' % repr(value) ++ ++ ++def nullrepr(value, repr=text_repr): ++ return '' ++ ++ + #---------------------------------------------------------------------------- ++ + # module testing (minimal) + if __name__ == "__main__": + def spam(c, d_e): diff --git a/src/sage/all.py b/src/sage/all.py index e1a7289eb73..0e0390cf4f2 100644 --- a/src/sage/all.py +++ b/src/sage/all.py @@ -188,6 +188,11 @@ from sage.rings.qqbar import _init_qqbar _init_qqbar() +# Add SAGE_SRC at the end of sys.path to enable Cython tracebacks +# (which use paths relative to SAGE_SRC) +sys.path.append(sage.env.SAGE_SRC) + + ########################################################### #### WARNING: # DO *not* import numpy / matplotlib / networkx here!! @@ -196,25 +201,10 @@ # when they are first needed. ########################################################### -################################################################### - -# maximize memory resources -#try: -# import resource # unix only... -# resource.setrlimit(resource.RLIMIT_AS, (-1,-1)) -#except Exception: -# pass - -# very useful 2-letter shortcuts CC = ComplexField() QQ = RationalField() RR = RealField() # default real field ZZ = IntegerRing() -# NOTE: QQ, RR, and ZZ are used by the pre-parser, and should not be -# overwritten by the user, unless they want to change the meaning of -# int and real in the interpreter (which is a potentially valid thing -# to do, and doesn't mess up anything else in the Sage library). - true = True false = False diff --git a/src/sage/libs/mwrank/interface.py b/src/sage/libs/mwrank/interface.py index 5ce11eb22b1..5e99f477c82 100644 --- a/src/sage/libs/mwrank/interface.py +++ b/src/sage/libs/mwrank/interface.py @@ -654,8 +654,9 @@ def gens(self): [[0, -1, 1]] """ self.saturate() - from sage.all import * - return eval(preparse(self.__two_descent_data().getbasis().replace(":",","))) + from sage.rings.all import Integer + L = eval(self.__two_descent_data().getbasis().replace(":",",")) + return [[Integer(x), Integer(y), Integer(z)] for (x,y,z) in L] def certain(self): r""" @@ -1406,5 +1407,6 @@ def points(self): [[1, -1, 1], [-2, 3, 1], [-14, 25, 8]] """ - from sage.all import * - return eval(preparse(self.__mw.getbasis().replace(":",","))) + L = eval(self.__mw.getbasis().replace(":",",")) + from sage.rings.all import Integer + return [[Integer(x), Integer(y), Integer(z)] for (x,y,z) in L] diff --git a/src/sage/repl/interpreter.py b/src/sage/repl/interpreter.py index ec7c9feb826..d4164a3dd91 100644 --- a/src/sage/repl/interpreter.py +++ b/src/sage/repl/interpreter.py @@ -68,16 +68,35 @@ that shell. The bulk of this functionality is provided through :class:`InterfaceShellTransformer`. +TESTS: + +Check that Cython source code appears in tracebacks:: + + sage: from sage.repl.interpreter import get_test_shell + sage: get_test_shell().run_cell('1/0') + --------------------------------------------------------------------------- + ... + /usr/local/src/sage-git/src/sage/rings/integer_ring.pyx in sage.rings.integer_ring.IntegerRing_class._div (build/cythonized/sage/rings/integer_ring.c:...)() + ... cdef rational.Rational x = PY_NEW(rational.Rational) + ... if mpz_sgn(right.value) == 0: + ... raise ZeroDivisionError('Rational division by zero') + ... mpz_set(mpq_numref(x.value), left.value) + ... mpz_set(mpq_denref(x.value), right.value) + + ZeroDivisionError: Rational division by zero """ #***************************************************************************** # Copyright (C) 2004-2012 William Stein # -# Distributed under the terms of the GNU General Public License (GPL) -# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** + import copy import os import re diff --git a/src/sage/rings/integer_ring.pyx b/src/sage/rings/integer_ring.pyx index 6426420afc9..bc455ab50ba 100644 --- a/src/sage/rings/integer_ring.pyx +++ b/src/sage/rings/integer_ring.pyx @@ -442,7 +442,7 @@ cdef class IntegerRing_class(PrincipalIdealDomain): """ cdef rational.Rational x = PY_NEW(rational.Rational) if mpz_sgn(right.value) == 0: - raise ZeroDivisionError, 'Rational division by zero' + raise ZeroDivisionError('Rational division by zero') mpz_set(mpq_numref(x.value), left.value) mpz_set(mpq_denref(x.value), right.value) mpq_canonicalize(x.value) From 4e9e1c51f6524bfa2d2c55d197b82a983dd01184 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Sat, 6 Dec 2014 12:42:43 +0100 Subject: [PATCH 242/698] Add interrupt handling to bounded integer sequences --- .../bounded_integer_sequences.pyx | 45 +++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index 7f5e63292cc..0ff59d82114 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -140,7 +140,9 @@ cdef bint biseq_init_copy(biseq_t R, biseq_t S) except -1: Initialize ``R`` as a copy of ``S``. """ biseq_init(R, S.length, S.itembitsize) + sig_on() bitset_copy(R.data, S.data) + sig_off() # # Conversion @@ -163,6 +165,7 @@ cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1: biseq_init(R, len(data), BIT_COUNT(bound|1)) for item in data: + sig_check() item_c = item if item_c > bound: raise OverflowError("list item {!r} larger than {}".format(item, bound) ) @@ -187,8 +190,10 @@ cdef bint biseq_init_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1: The result is written into ``R``, which must not be initialised """ biseq_init(R, S1.length + S2.length, S1.itembitsize) + sig_on() bitset_lshift(R.data, S2.data, S1.length * S1.itembitsize) bitset_or(R.data, R.data, S1.data) + sig_off() cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1: @@ -207,7 +212,10 @@ cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1: return False if S2.length == 0: return True - return mpn_equal_bits(S1.data.bits, S2.data.bits, S2.data.size) + sig_on() + ret = mpn_equal_bits(S1.data.bits, S2.data.bits, S2.data.size) + sig_off() + return ret cdef mp_size_t biseq_index(biseq_t S, size_t item, mp_size_t start) except -2: @@ -217,9 +225,12 @@ cdef mp_size_t biseq_index(biseq_t S, size_t item, mp_size_t start) except -2: """ cdef mp_size_t index + sig_on() for index from start <= index < S.length: if biseq_getitem(S, index) == item: + sig_off() return index + sig_off() return -1 @@ -304,15 +315,19 @@ cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop if step == 1: # Slicing essentially boils down to a shift operation. + sig_on() bitset_rshift(R.data, S.data, start*S.itembitsize) + sig_off() return 0 # In the general case, we move item by item. cdef mp_size_t src_index = start cdef mp_size_t tgt_index + sig_on() for tgt_index in range(length): biseq_inititem(R, tgt_index, biseq_getitem(S, src_index)) src_index += step + sig_off() cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2: @@ -340,10 +355,13 @@ cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2 if S2.length == 0: return start cdef mp_size_t index + sig_on() for index from start <= index <= S1.length-S2.length: if mpn_equal_bits_shifted(S2.data.bits, S1.data.bits, S2.length*S2.itembitsize, index*S2.itembitsize): + sig_off() return index + sig_off() return -1 cdef mp_size_t biseq_startswith_tail(biseq_t S1, biseq_t S2, mp_size_t start) except -2: @@ -373,10 +391,13 @@ cdef mp_size_t biseq_startswith_tail(biseq_t S1, biseq_t S2, mp_size_t start) ex if S1.length < S2.length - start: start = S2.length - S1.length cdef mp_size_t index + sig_on() for index from start <= index < S2.length: if mpn_equal_bits_shifted(S1.data.bits, S2.data.bits, (S2.length - index)*S2.itembitsize, index*S2.itembitsize): + sig_off() return index + sig_off() return -1 @@ -1335,7 +1356,9 @@ cpdef BoundedIntegerSequence NewBISEQ(tuple bitset_data, mp_bitcnt_t itembitsize cdef BoundedIntegerSequence out = BoundedIntegerSequence.__new__(BoundedIntegerSequence) # bitset_unpickle assumes that out.data.data is initialised. biseq_init(out.data, length, itembitsize) + sig_on() bitset_unpickle(out.data.data, bitset_data) + sig_off() return out def _biseq_stresstest(): @@ -1343,17 +1366,23 @@ def _biseq_stresstest(): This function creates many bounded integer sequences and manipulates them in various ways, in order to try to detect random memory corruptions. + This runs forever and must be interrupted (this means that + interrupting is also checked). + TESTS:: sage: from sage.data_structures.bounded_integer_sequences import _biseq_stresstest - sage: _biseq_stresstest() - + sage: alarm(1); _biseq_stresstest() # long time + Traceback (most recent call last): + ... + AlarmInterrupt """ - cdef int i + cdef int branch + cdef Py_ssize_t x, y, z from sage.misc.prandom import randint - cdef list L = [BoundedIntegerSequence(6, [randint(0,5) for x in range(randint(4,10))]) for y in range(100)] + cdef list L = [BoundedIntegerSequence(6, [randint(0,5) for z in range(randint(4,10))]) for y in range(100)] cdef BoundedIntegerSequence S, T - for i from 0<=i<10000: + while True: branch = randint(0,4) if branch == 0: L[randint(0,99)] = L[randint(0,99)]+L[randint(0,99)] @@ -1364,7 +1393,7 @@ def _biseq_stresstest(): z = randint(y,len(L[x])-1) L[randint(0,99)] = L[x][y:z] else: - L[x] = BoundedIntegerSequence(6, [randint(0,5) for x in range(randint(4,10))]) + L[x] = BoundedIntegerSequence(6, [randint(0,5) for z in range(randint(4,10))]) elif branch == 2: t = list(L[randint(0,99)]) t = repr(L[randint(0,99)]) @@ -1379,7 +1408,7 @@ def _biseq_stresstest(): except ValueError: raise ValueError("{} should be in {} (bound {}) at position {}".format(t,L[x],L[x].bound(),y)) else: - L[x] = BoundedIntegerSequence(6, [randint(0,5) for x in range(randint(4,10))]) + L[x] = BoundedIntegerSequence(6, [randint(0,5) for z in range(randint(4,10))]) elif branch == 4: S = L[randint(0,99)] T = L[randint(0,99)] From e6a4de841482f86499d6ae16769e6a220624b3a6 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Sat, 6 Dec 2014 13:49:52 +0100 Subject: [PATCH 243/698] trac #17443: change TypeError to a deprecation --- src/sage/matrix/matrix2.pyx | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 60f507cb76d..775664ba9b0 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -1466,7 +1466,10 @@ cdef class Matrix(matrix1.Matrix): def __abs__(self): """ - Not defined (since :trac:`17443`) + Deprecated. + + This function used to return the determinant. It is deprecated since + :trac:`17443`. EXAMPLES:: @@ -1474,16 +1477,21 @@ cdef class Matrix(matrix1.Matrix): [1 2] [3 4] sage: abs(a) - Traceback (most recent call last): - ... - TypeError: absolute value is not defined on matrices. If you want - the L^1-norm use m.norm(1) and if you want the matrix obtained by - applying the absolute value to the coefficents use m.apply_map(abs). - """ - raise TypeError("absolute value is not defined on matrices. If you want " - "the L^1-norm use m.norm(1) and if you want the matrix " - "obtained by applying the absolute value to the " - "coefficents use m.apply_map(abs).") + doctest:...: DeprecationWarning: abs(matrix) is deprecated. Use matrix.det()to + get the determinant. + See http://trac.sagemath.org/17443 for details. + -2 + """ + #TODO: after expiration of the one year deprecation, we should return a + # TypeError with the following kind of message: + # absolute value is not defined on matrices. If you want the + # L^1-norm use m.norm(1) and if you want the matrix obtained by + # applying the absolute value to the coefficents use + # m.apply_map(abs). + from sage.misc.superseded import deprecation + deprecation(17443, "abs(matrix) is deprecated. Use matrix.det()" + "to get the determinant.") + return self.det() def apply_morphism(self, phi): """ From fd76b65c59cee41a6542ca215805043454ed3055 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Sat, 6 Dec 2014 16:49:16 +0100 Subject: [PATCH 244/698] trac #9465: fricas package update --- build/pkgs/fricas/SPKG.txt | 20 ++++++++++++++++++++ build/pkgs/fricas/checksums.ini | 4 ++++ build/pkgs/fricas/package-version.txt | 1 + build/pkgs/fricas/spkg-install | 24 ++++++++++++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 build/pkgs/fricas/SPKG.txt create mode 100644 build/pkgs/fricas/checksums.ini create mode 100644 build/pkgs/fricas/package-version.txt create mode 100755 build/pkgs/fricas/spkg-install diff --git a/build/pkgs/fricas/SPKG.txt b/build/pkgs/fricas/SPKG.txt new file mode 100644 index 00000000000..32fc0067717 --- /dev/null +++ b/build/pkgs/fricas/SPKG.txt @@ -0,0 +1,20 @@ += fricas = + +== Description == + +This package install the software fricas. + +== License == + +Modified BSD license. + +== Upstream Contact == + +http://fricas.sourceforge.net/ + +== Dependencies == + +Put a bulleted list of dependencies here: + +* ecl + diff --git a/build/pkgs/fricas/checksums.ini b/build/pkgs/fricas/checksums.ini new file mode 100644 index 00000000000..a71ad016624 --- /dev/null +++ b/build/pkgs/fricas/checksums.ini @@ -0,0 +1,4 @@ +tarball=fricas-VERSION.tar.bz2 +sha1=689b3e474579655b76686a56a1928ef411cb179b +md5=ba4f3927d93f49b0d866e5e80fc5bf18 +cksum=2927195574 diff --git a/build/pkgs/fricas/package-version.txt b/build/pkgs/fricas/package-version.txt new file mode 100644 index 00000000000..e8ea05db814 --- /dev/null +++ b/build/pkgs/fricas/package-version.txt @@ -0,0 +1 @@ +1.2.4 diff --git a/build/pkgs/fricas/spkg-install b/build/pkgs/fricas/spkg-install new file mode 100755 index 00000000000..b88f37b1d34 --- /dev/null +++ b/build/pkgs/fricas/spkg-install @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +cd src + +./configure --prefix="$SAGE_LOCAL" \ + --libdir="$SAGE_LOCAL/lib" \ + --with-lisp=ecl + +if [ $? -ne 0 ]; then + echo >&2 "Error configuring fricas." + exit 1 +fi + +$MAKE +if [ $? -ne 0 ]; then + echo >&2 "Error building fricas." + exit 1 +fi + +$MAKE -j1 install +if [ $? -ne 0 ]; then + echo >&2 "Error installing fricas." + exit 1 +fi From eaf4c101e899afb963a84922cf5002d6681d7d6b Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sat, 6 Dec 2014 08:26:03 -0800 Subject: [PATCH 245/698] Put poly quotients domains in the category of IntegralDomains. --- src/sage/categories/fields.py | 5 +++- .../polynomial/polynomial_quotient_ring.py | 29 +++++++++++++++---- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/sage/categories/fields.py b/src/sage/categories/fields.py index 8260966d3c0..ebcc79f9708 100644 --- a/src/sage/categories/fields.py +++ b/src/sage/categories/fields.py @@ -126,7 +126,10 @@ def _contains_helper(cls): sage: P. = QQ[] sage: Q = P.quotient(x^2+2) sage: Q.category() - Join of Category of commutative algebras over Rational Field and Category of subquotients of monoids and Category of quotients of semigroups + Join of Category of integral domains + and Category of commutative algebras over Rational Field + and Category of subquotients of monoids + and Category of quotients of semigroups sage: F = Fields() sage: F._contains_helper(Q) False diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index bbf7bf17359..3560dd95ce1 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -238,7 +238,10 @@ class of the quotient ring and its newly created elements. sage: P. = QQ[] sage: Q = P.quotient(x^2+2) sage: Q.category() - Join of Category of commutative algebras over Rational Field and Category of subquotients of monoids and Category of quotients of semigroups + Join of Category of integral domains + and Category of commutative algebras over Rational Field + and Category of subquotients of monoids + and Category of quotients of semigroups The test suite passes:: @@ -292,7 +295,7 @@ class of the category, and store the current class of the quotient """ Element = PolynomialQuotientRingElement - def __init__(self, ring, polynomial, name=None): + def __init__(self, ring, polynomial, name=None, category=None): """ TEST:: @@ -314,7 +317,8 @@ def __init__(self, ring, polynomial, name=None): self.__ring = ring self.__polynomial = polynomial - sage.rings.commutative_ring.CommutativeRing.__init__(self, ring, names=name, category=CommutativeAlgebras(ring.base_ring()).Quotients()) + category = CommutativeAlgebras(ring.base_ring()).Quotients().or_subcategory(category) + sage.rings.commutative_ring.CommutativeRing.__init__(self, ring, names=name, category=category) def __reduce__(self): """ @@ -1415,8 +1419,23 @@ class PolynomialQuotientRing_domain(PolynomialQuotientRing_generic, sage.rings.i sage: loads(xbar.dumps()) == xbar True """ - def __init__(self, ring, polynomial, name=None): - PolynomialQuotientRing_generic.__init__(self, ring, polynomial, name) + def __init__(self, ring, polynomial, name=None, category=None): + r""" + Initialize ``self``. + + TESTS:: + + sage: R. = PolynomialRing(ZZ) + sage: S. = R.quotient(x^2 + 1) + sage: TestSuite(S).run() + + Check that :trac:`17450` is fixed:: + + sage: S in IntegralDomains() + True + """ + category = CommutativeAlgebras(ring.base_ring()).Quotients().NoZeroDivisors().or_subcategory(category) + PolynomialQuotientRing_generic.__init__(self, ring, polynomial, name, category) def __reduce__(self): return PolynomialQuotientRing_domain, (self.polynomial_ring(), From 6ff2fdff73efe7828741e3457cc31621f506e97e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 6 Dec 2014 17:38:53 +0100 Subject: [PATCH 246/698] trac #9465 more # optional - fricas so that tests pass --- src/sage/interfaces/fricas.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index baf87a66356..d7b8174e8db 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -1,15 +1,15 @@ r""" Interface to FriCAS -TODO: +.. TODO:: -- Evaluation using a file is not done. Any input line with more than a - few thousand characters would hang the system, so currently it - automatically raises an exception. + - Evaluation using a file is not done. Any input line with more + than a few thousand characters would hang the system, so currently it + automatically raises an exception. -- All completions of a given command. + - All completions of a given command. -- Interactive help. + - Interactive help. FriCAS is a free GPL-compatible (modified BSD license) general purpose computer algebra system based on Axiom. The FriCAS @@ -289,14 +289,14 @@ class FriCASExpectFunction(PanAxiomExpectFunction): def is_FriCASElement(x): """ - Returns True of x is of type FriCASElement. + Return True if x is of type FriCASElement. EXAMPLES:: - sage: from sage.interfaces.fricas import is_FriCASElement - sage: is_FriCASElement(fricas(2)) #optional - fricas + sage: from sage.interfaces.fricas import is_FriCASElement #optional - fricas + sage: is_FriCASElement(fricas(2)) #optional - fricas True - sage: is_FriCASElement(2) + sage: is_FriCASElement(2) #optional - fricas False """ return isinstance(x, FriCASElement) @@ -340,13 +340,13 @@ def __doctest_cleanup(): """ EXAMPLES:: - sage: from sage.interfaces.fricas import __doctest_cleanup - sage: a = FriCAS() + sage: from sage.interfaces.fricas import __doctest_cleanup #optional - fricas + sage: a = FriCAS() #optional - fricas sage: two = a(2) #optional - fricas sage: a.is_running() #optional - fricas True - sage: __doctest_cleanup() - sage: a.is_running() + sage: __doctest_cleanup() #optional - fricas + sage: a.is_running() #optional - fricas False """ import sage.interfaces.quit From 30d4ef22626d441cba3616bb996665b575aa3899 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Sat, 6 Dec 2014 18:11:08 +0100 Subject: [PATCH 247/698] Deprecate pari() function from sage/libs/pari/gen_py.py --- src/sage/libs/pari/gen.pxd | 2 +- src/sage/libs/pari/gen.pyx | 5 ++--- src/sage/libs/pari/gen_py.py | 11 +++++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/sage/libs/pari/gen.pxd b/src/sage/libs/pari/gen.pxd index afb08a48c9a..4941f395279 100644 --- a/src/sage/libs/pari/gen.pxd +++ b/src/sage/libs/pari/gen.pxd @@ -9,4 +9,4 @@ cdef class gen(sage.structure.element.RingElement): cdef pari_sp b cdef dict refers_to -cdef gen objtogen(object s) +cpdef gen objtogen(s) diff --git a/src/sage/libs/pari/gen.pyx b/src/sage/libs/pari/gen.pyx index 2ae470ad17b..15c9175ba02 100644 --- a/src/sage/libs/pari/gen.pyx +++ b/src/sage/libs/pari/gen.pyx @@ -181,8 +181,7 @@ cdef class gen(sage.structure.element.RingElement): True """ s = str(self) - import sage.libs.pari.gen_py - return sage.libs.pari.gen_py.pari, (s,) + return (objtogen, (s,)) cpdef ModuleElement _add_(self, ModuleElement right): pari_catch_sig_on() @@ -9657,7 +9656,7 @@ def init_pari_stack(s=8000000): P.allocatemem(s, silent=True) -cdef gen objtogen(s): +cpdef gen objtogen(s): """ Convert any Sage/Python object to a PARI gen. """ diff --git a/src/sage/libs/pari/gen_py.py b/src/sage/libs/pari/gen_py.py index 96eca4d7de5..06f06d0f893 100644 --- a/src/sage/libs/pari/gen_py.py +++ b/src/sage/libs/pari/gen_py.py @@ -98,19 +98,22 @@ def pari(x): ... ValueError: Cannot convert None to pari """ + from sage.misc.superseded import deprecation + deprecation(17451, 'gen_py.pari is deprecated, use sage.libs.pari.all.pari instead') from sage.libs.pari.all import pari return pari(x) + def python(z, locals=None): """ - Return the closest Python/Sage equivalent of the given pari object. + Return the closest Python/Sage equivalent of the given PARI object. INPUT: - - `z` -- pari object + - `z` -- PARI ``gen`` - - `locals` -- optional dictionary used in fallback cases that - involve sage_eval + - `locals` -- optional dictionary used in fallback cases that + involve sage_eval The component parts of a t_COMPLEX may be t_INT, t_REAL, t_INTMOD, t_FRAC, t_PADIC. The components need not have the same type From 858d7a9197144ee878bbe1c5b9687c4b12662143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 6 Dec 2014 21:30:50 +0100 Subject: [PATCH 248/698] trac #17408 reviewer commit, pep8 and other details --- src/sage/combinat/posets/posets.py | 7 +++++++ src/sage/graphs/digraph.py | 8 ++++---- src/sage/graphs/generic_graph.py | 14 +++++++------- src/sage/graphs/generic_graph_pyx.pyx | 14 +++++++------- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index ef2233eeb49..0b51736b468 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -487,6 +487,13 @@ def Poset(data=None, element_labels=None, cover_relations=False, linear_extensio Traceback (most recent call last): ... ValueError: element_labels should be a dict or a list if different from None. (Did you intend data to be equal to a pair ?) + + Another kind of bad input, digraphs with oriented cycles:: + + sage: Poset(DiGraph([[1,2],[2,3],[3,4],[4,1]])) + Traceback (most recent call last): + ... + TypeError: Digraph is not acyclic; there is no topological sort. """ # Avoiding some errors from the user when data should be a pair if (element_labels is not None and diff --git a/src/sage/graphs/digraph.py b/src/sage/graphs/digraph.py index fc0c9a9450e..159996f2f03 100644 --- a/src/sage/graphs/digraph.py +++ b/src/sage/graphs/digraph.py @@ -2933,7 +2933,7 @@ def topological_sort(self, implementation = "default"): sage: D.topological_sort() Traceback (most recent call last): ... - TypeError: Digraph is not acyclic-- there is no topological + TypeError: Digraph is not acyclic; there is no topological sort. .. note:: @@ -2967,7 +2967,7 @@ def topological_sort(self, implementation = "default"): if b: return ordering else: - raise TypeError('Digraph is not acyclic-- there is no topological sort.') + raise TypeError('Digraph is not acyclic; there is no topological sort.') elif implementation == "NetworkX" or implementation == "recursive": import networkx @@ -2976,7 +2976,7 @@ def topological_sort(self, implementation = "default"): else: S = networkx.topological_sort_recursive(self.networkx_graph(copy=False)) if S is None: - raise TypeError('Digraph is not acyclic-- there is no topological sort.') + raise TypeError('Digraph is not acyclic; there is no topological sort.') else: return S @@ -3026,7 +3026,7 @@ def topological_sort_generator(self): try: return LinearExtensions(self).list() except TypeError: - raise TypeError('Digraph is not acyclic-- there is no topological sort (or there was an error in sage/graphs/linearextensions.py).') + raise TypeError('Digraph is not acyclic; there is no topological sort (or there was an error in sage/graphs/linearextensions.py).') ### Visualization diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index b0b43e0de10..a8745cd2bc8 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -14577,7 +14577,7 @@ def transitive_closure(self): """ G = self.copy(immutable=False) G.name('Transitive closure of ' + self.name()) - G.add_edges((v,e) for v in G for e in G.breadth_first_search(v)) + G.add_edges((v, e) for v in G for e in G.breadth_first_search(v)) return G def transitive_reduction(self): @@ -14596,17 +14596,17 @@ def transitive_reduction(self): EXAMPLES:: - sage: g=graphs.PathGraph(4) - sage: g.transitive_reduction()==g + sage: g = graphs.PathGraph(4) + sage: g.transitive_reduction() == g True - sage: g=graphs.CompleteGraph(5) + sage: g = graphs.CompleteGraph(5) sage: edges = g.transitive_reduction().edges(); len(edges) 4 - sage: g=DiGraph({0:[1,2], 1:[2,3,4,5], 2:[4,5]}) + sage: g = DiGraph({0:[1,2], 1:[2,3,4,5], 2:[4,5]}) sage: g.transitive_reduction().size() 5 """ - if self.is_directed_acyclic(): + if self.is_directed() and self.is_directed_acyclic(): from sage.graphs.generic_graph_pyx import transitive_reduction_acyclic return transitive_reduction_acyclic(self) @@ -14616,7 +14616,7 @@ def transitive_reduction(self): # Try deleting the edge, see if we still have a path # between the vertices. G.delete_edge(e) - if G.distance(e[0],e[1]) > n: + if G.distance(e[0], e[1]) > n: # oops, we shouldn't have deleted it G.add_edge(e) return G diff --git a/src/sage/graphs/generic_graph_pyx.pyx b/src/sage/graphs/generic_graph_pyx.pyx index 983d600ea9c..5ad66a8feab 100644 --- a/src/sage/graphs/generic_graph_pyx.pyx +++ b/src/sage/graphs/generic_graph_pyx.pyx @@ -1297,8 +1297,8 @@ def transitive_reduction_acyclic(G): True """ cdef int n = G.order() - cdef dict v_to_int = {vv:i for i,vv in enumerate(G.vertices())} - cdef int u,v,i + cdef dict v_to_int = {vv: i for i, vv in enumerate(G.vertices())} + cdef int u, v, i cdef list linear_extension = G.topological_sort() linear_extension.reverse() @@ -1309,13 +1309,13 @@ def transitive_reduction_acyclic(G): # # A point is reachable from u if it is one of its neighbours, or if it is # reachable from one of its neighbours. - binary_matrix_init(closure,n,n) - binary_matrix_fill(closure,0) + binary_matrix_init(closure, n, n) + binary_matrix_fill(closure, 0) for uu in linear_extension: u = v_to_int[uu] for vv in G.neighbors_out(uu): v = v_to_int[vv] - binary_matrix_set1(closure,u,v) + binary_matrix_set1(closure, u, v) for i in range(closure.width): closure.rows[u][i] |= closure.rows[v][i] @@ -1333,8 +1333,8 @@ def transitive_reduction_acyclic(G): closure.rows[u][i] &= ~closure.rows[v][i] for vv in G.neighbors_out(uu): v = v_to_int[vv] - if binary_matrix_get(closure,u,v): - useful_edges.append((uu,vv)) + if binary_matrix_get(closure, u, v): + useful_edges.append((uu, vv)) from sage.graphs.digraph import DiGraph reduced = DiGraph() From a6fd53b0c8a0e451254cfd5afd25a40f7d1d8a2e Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Sat, 6 Dec 2014 19:24:49 +0100 Subject: [PATCH 249/698] trac #16603: speedup + doc --- src/sage/matrix/matrix_misc.py | 115 +++++++++++++++++---------------- 1 file changed, 59 insertions(+), 56 deletions(-) diff --git a/src/sage/matrix/matrix_misc.py b/src/sage/matrix/matrix_misc.py index 90c70efa6d7..c07f3e5086b 100644 --- a/src/sage/matrix/matrix_misc.py +++ b/src/sage/matrix/matrix_misc.py @@ -20,6 +20,7 @@ from sage.categories.fields import Fields from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.integer_ring import ZZ _Fields = Fields() def row_iterator(A): @@ -201,42 +202,33 @@ def weak_popov_form(M,ascend=True): # return reduced matrix and operations matrix return (matrix(r)/den, matrix(N), d) -def _prm_mul(p1, p2, free_vars_indices, K): +def prm_mul(p1, p2, free_vars_indices): """ - Return the product of `p1` and `p2`, putting free variables to 1. + Return the product of ``p1`` and ``p2``, putting free variables in + ``free_vars_indices`` to `1`. - In the following example, - ``p1 = 1 + t*e_0 + t*e_1`` - ``p2 = 1 + t*e_0 + t*e_2; 'e_0` free variable; - using the fact that `e_i` are nilpotent and setting - `e_0 = 1` after performing the product one gets - ``p1 * p2 = (1 + 2*t) + (t + t^2)*e_1 + (t + t^2)*e_2 + t^2*e_1*e_2`` - - The polynomials are represented in dictionary form; to a - variable ``eta_i`` it is associated the key ``1 << i``; - so in the following example 'e_1' corresponds to the key '2' - and 'e_1*e_2' to the key '6'. + This function is mainly use as a subroutine of + :func:`permanental_minor_vector`. EXAMPLES:: - sage: from sage.matrix.matrix_misc import _prm_mul - sage: K = PolynomialRing(ZZ, 't') - sage: t = K.gen() + sage: from sage.matrix.matrix_misc import prm_mul + sage: t = polygen(ZZ, 't') sage: p1 = {0: 1, 1: t, 4: t} sage: p2 = {0: 1, 1: t, 2: t} - sage: _prm_mul(p1, p2, [0], K) + sage: prm_mul(p1, p2, [0]) {0: 2*t + 1, 2: t^2 + t, 4: t^2 + t, 6: t^2} """ p = {} mask_free = 0 - one = int(1) + one = 1 for i in free_vars_indices: mask_free += one << i if not p2: return p get = p.get for exp1, v1 in p1.iteritems(): - for exp2, v2 in p2.items(): + for exp2, v2 in p2.iteritems(): if exp1 & exp2: continue exp = exp1 | exp2 @@ -244,31 +236,13 @@ def _prm_mul(p1, p2, free_vars_indices, K): if exp & mask_free: for i in free_vars_indices: if exp & (one << i): - exp = exp.__xor__(one << i) - p[exp] = get(exp, K.zero()) + v + exp ^= one << i + if exp not in p: + p[exp] = v + else: + p[exp] += v return p - -def _is_free_var(i, k, m): - """ - Return ``True`` if the variable `k` does not occur from row `i` on. - - INPUT: - - - i -- current row - - k -- index of the variable - - m -- matrix as a list of lists - - EXAMPLES:: - - sage: from sage.matrix.matrix_misc import _is_free_var - sage: m = [[1,2,3], [2,0,4], [2,0,4]] - sage: _is_free_var(1,1,m) - True - """ - return all(m[j][k] == 0 for j in range(i, len(m))) - - def permanental_minor_vector(m, permanent_only=False): r""" Return the polynomial of the sums of permanental minors of a matrix `m` @@ -280,17 +254,23 @@ def permanental_minor_vector(m, permanent_only=False): \sum_0^{min(nrows, ncols)} p_i(m) x^i - where `p_i(m)` is ``m.permanental_minor(i)``. + where `p_i(m)` is the `i`-th permanental minor of `m` (that can also be + obtained through the method + :meth:`~sage.matrix.matrix2.Matrix.permanental_minor` via + ``m.permanental_minor(i)``). INPUT: - - `m` -- matrix + - ``m`` -- matrix - - `permanent_only` -- boolean, if ``True``, only the permanent is computed + - ``permanent_only`` -- optional boolean. If ``True``, only the permanent + is computed (might be faster). OUTPUT: - polynomial in array form; the last element of the array is the permanent. + The list of coefficients of the polynomial, i.e. the coefficient of `x^i` is + at the `i`-th position in the list. In particular, the last element of the + list is the permanent. EXAMPLES:: @@ -307,39 +287,63 @@ def permanental_minor_vector(m, permanent_only=False): sage: A = M([1,0,1,0,1,0,1,0,1,0,10,10,1,0,1,1]) sage: permanental_minor_vector(A) [1, 28, 114, 84, 0] + sage: [A.permanental_minor(i) for i in range(5)] + [1, 28, 114, 84, 0] An example over `\QQ`:: sage: M = MatrixSpace(QQ,2,2) sage: A = M([1/5,2/7,3/2,4/5]) - sage: permanental_minor_vector(A, 1) + sage: permanental_minor_vector(A, True) 103/175 An example with polynomial coefficients:: sage: R. = PolynomialRing(ZZ) sage: A = MatrixSpace(R,2)([[a,1], [a,a+1]]) - sage: permanental_minor_vector(A, 1) + sage: permanental_minor_vector(A, True) a^2 + 2*a + ALGORITHM: + + The algorithm uses polynomials over the algebra + `K[\eta_1, \eta_2,\ldots, \eta_k]` where the `\eta_i` are commuting, + nilpotent of order `2` (i.e. `\eta_i^2 = 0`). Let us consider an example of + computation. Let `p_1 = 1 + t \eta_0 + t \eta_1` and + `p_2 = 1 + t \eta_0 + t \eta_2`. Then + + .. MATH:: + + p_1 p_2 = 1 + 2t \eta_0 + + t (\eta_1 + \eta_2) + + t^2 (\eta_0 \eta_1 + \eta_0 \eta_2 + \eta_1 \eta_2) + + The product is implemented as a subroutine in :func:`prm_mul`. The + polynomials are represented in dictionary form: to a variable `\eta_i` + it is associated the key `2^i` (or in Python ``1 << i``). So in the + above example `\eta_1` corresponds to the key `2` while the product + `\eta_1 \eta_2` to the key `6`. + + MORE DOC NEEDED!!! + REFERENCES: .. [ButPer] P. Butera and M. Pernici "Sums of permanental minors using Grassmann algebra", :arxiv:`1406.5337` """ K = PolynomialRing(m.base_ring(), 't') - m = list(m) - nrows = len(m) - ncols = len(m[0]) + nrows = m.nrows() + ncols = m.ncols() + m = m.rows() p = {int(0): K.one()} t = K.gen() done_vars = set() - one = int(1) + one = 1 for i in range(nrows): if permanent_only: p1 = {} else: - p1 = {int(0): K.one()} + p1 = {0: K.one()} a = m[i] for j in range(len(a)): if a[j]: @@ -348,11 +352,10 @@ def permanental_minor_vector(m, permanent_only=False): for j in range(ncols): if j in done_vars: continue - r = _is_free_var(i + 1, j, m) - if r: + if all(m[k][j] == 0 for k in range(i+1, len(m))): free_vars_indices.append(j) done_vars.add(j) - p = _prm_mul(p, p1, free_vars_indices, K) + p = prm_mul(p, p1, free_vars_indices) if not p: return K.zero() assert len(p) == 1 From f611f58d45d8a0989a47a744dfd537b8e54b2412 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Sat, 6 Dec 2014 21:58:17 +0100 Subject: [PATCH 250/698] trac #16603: add matrix_misc.py to the doc --- src/doc/en/reference/matrices/index.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/doc/en/reference/matrices/index.rst b/src/doc/en/reference/matrices/index.rst index 75c0bd93b6b..4e614ea67db 100644 --- a/src/doc/en/reference/matrices/index.rst +++ b/src/doc/en/reference/matrices/index.rst @@ -52,6 +52,8 @@ objects like operation tables (e.g. the multiplication table of a group). sage/matrix/docs + sage/matrix/matrix_misc + sage/matrix/matrix sage/matrix/matrix0 From 8013ac0ec55eebf4da64f09c011e90f0e25a145c Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Sun, 7 Dec 2014 01:07:37 +0100 Subject: [PATCH 251/698] trac #17452: clean min_wt_vec_gap --- src/sage/coding/linear_code.py | 36 +++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index f24b2a838b4..759c5a55255 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -379,6 +379,7 @@ def min_wt_vec_gap(Gmat, n, k, F, algorithm=None): - David Joyner (11-2005) """ current_randstate().set_seed_gap() + if algorithm=="guava": gap.LoadPackage('"guava"') from sage.interfaces.gap import gfq_gap_to_sage @@ -389,25 +390,28 @@ def min_wt_vec_gap(Gmat, n, k, F, algorithm=None): c = [gfq_gap_to_sage(cg[j],F) for j in range(1,n+1)] V = VectorSpace(F,n) return V(c) - qstr = str(F.order()) - zerovec = [0 for i in range(n)] - zerovecstr = "Z("+qstr+")*"+str(zerovec) - all = [] + + q = F.order() + ans = None + dist_min = n gap.eval('Gmat:='+Gmat) + gap.eval('K:=GF({})'.format(q)) + gap.eval('v:=Z({})*{}'.format(q,[0]*n)) for i in range(1,k+1): - gap.eval("P:=AClosestVectorCombinationsMatFFEVecFFECoords(Gmat, GF("+qstr+"),"+zerovecstr+","+str(i)+",0); d:=WeightVecFFE(P[1])") - v = gap("[P[1]]") - m = gap("[P[2]]") + gap.eval("P:=AClosestVectorCombinationsMatFFEVecFFECoords(Gmat,K,v,{},1)".format(i)) + gap.eval("d:=WeightVecFFE(P[1])") + v = gap("P[1]") + # P[2] is m = gap("[P[2]]") dist = gap("d") - #print v,m,dist - #print [gap.eval("v["+str(i+1)+"]") for i in range(n)] - all.append([v._matrix_(F), m._matrix_(F), int(dist)]) - ans = all[0] - for x in all: - if x[2]0: - ans = x - #print ans[0], ans[0].parent() - return vector(F,[x for x in ans[0].rows()[0]]) # ugly 1xn matrix->vector coercion! + if dist and dist < dist_min: + dist_min = dist + ans = list(v) + + if ans is None: + raise RuntimeError("there is a bug here!") + + # return the result as a vector (and not a 1xn matrix) + return vector(F, ans) def best_known_linear_code(n, k, F): r""" From 173f3ece741427bbc40f3f91305e0a14391ea7fb Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Sun, 7 Dec 2014 01:09:43 +0100 Subject: [PATCH 252/698] trac #17452: add a check for rank (+ doc) --- src/sage/coding/linear_code.py | 72 ++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index 759c5a55255..1964341d414 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -696,15 +696,19 @@ def self_orthogonal_binary_codes(n, k, b=2, parent=None, BC=None, equal=False, class LinearCode(module.Module): r""" - A class for linear codes over a finite field or finite ring. Each instance - is a linear code determined by a generator matrix `G` (i.e., a - `k \times n` matrix of (full) rank `k`, `k \leq n` over a finite field `F`. + Linear codes over a finite field or finite ring. + + A *linear code* is a subspace of a vector space over a finite field. It can + be defined by one of its basis or equivalently a generator matrix (a `k + \times n` matrix of full rank `k`). + + See :wikipedia:`Linear_code` for more information. INPUT: - - ``G`` -- a generator matrix over `F` (``G`` can be defined over a - finite ring but the matrices over that ring must have certain - attributes, such as ``rank``) + - ``gen_mat`` -- a generator matrix over a finite field (``G`` can be + defined over a finite ring but the matrices over that ring must have + certain attributes, such as ``rank``) - ``d`` -- (optional, default: ``None``) the minimum distance of the code @@ -713,9 +717,6 @@ class LinearCode(module.Module): The veracity of the minimum distance ``d``, if provided, is not checked. - OUTPUT: - - The linear code of length `n` over `F` having `G` as a generator matrix. EXAMPLES:: @@ -783,15 +784,51 @@ def __init__(self, gen_mat, d=None): sage: C = codes.HammingCode(3, GF(2)) sage: TestSuite(C).run() + + Check that it works even with input matrix with non full rank (see + :trac:`17452`):: + + sage: K. = GF(4) + sage: G = matrix([[a, a + 1, 1, a + 1, 1, 0, 0], + ....: [0, a, a + 1, 1, a + 1, 1, 0], + ....: [0, 0, a, a + 1, 1, a + 1, 1], + ....: [a + 1, 0, 1, 0, a + 1, 1, a + 1], + ....: [a, a + 1, a + 1, 0, 0, a + 1, 1], + ....: [a + 1, a, a, 1, 0, 0, a + 1], + ....: [a, a + 1, 1, a + 1, 1, 0, 0]]) + sage: C = LinearCode(G) + sage: C.basis() + [(1, 0, 0, a + 1, 0, 1, 0), + (0, 1, 0, 0, a + 1, 0, 1), + (0, 0, 1, a, a + 1, a, a + 1)] + sage: C.minimum_distance() + 3 + + Forbid the zero vector space (see :trac:`17452` and :trac:`6486`):: + + sage: G = matrix(GF(2), [[0,0,0]]) + sage: C = LinearCode(G) + Traceback (most recent call last): + ... + ValueError: this linear code contains no non-zero vector """ - base_ring = gen_mat[0,0].parent() + base_ring = gen_mat.base_ring() + # if the matrix does not have full rank we replace it + if gen_mat.rank() != gen_mat.nrows(): + from sage.matrix.constructor import matrix + basis = gen_mat.row_space().basis() + gen_mat = matrix(base_ring, basis) + + if gen_mat.nrows() == 0: + raise ValueError("this linear code contains no non-zero vector") + cat = Modules(base_ring).FiniteDimensional().WithBasis().Finite() facade_for = gen_mat.row(0).parent() self.Element = type(gen_mat.row(0)) # for when we make this a non-facade parent Parent.__init__(self, base=base_ring, facade=facade_for, category=cat) self.__gens = gen_mat.rows() self.__gen_mat = gen_mat - self.__length = len(gen_mat.row(0)) + self.__length = gen_mat.ncols() self.__dim = gen_mat.rank() self.__distance = d @@ -2189,20 +2226,7 @@ def minimum_distance(self, algorithm=None): Traceback (most recent call last): ... ValueError: The algorithm argument must be one of None, 'gap' or 'guava'; got 'something' - - This shows that ticket :trac:`#6486` has been resolved:: - - sage: G = matrix(GF(2),[[0,0,0]]) - sage: C = LinearCode(G) - sage: C.minimum_distance() - Traceback (most recent call last): - ... - ValueError: this linear code contains no non-zero vector """ - # Special code to handle the case where there is no non-zero vector. - if self.dimension() == 0: - raise ValueError("this linear code contains no non-zero vector") - # If the minimum distance has already been computed or provided by # the user then simply return the stored value. # This is done only if algorithm is None. From 3ae6f7cb84c34f323c15e7ba423231aead5876bf Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Fri, 5 Dec 2014 11:30:47 +0100 Subject: [PATCH 253/698] comparison by strings in tides interface --- src/sage/interfaces/tides.py | 79 +++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/src/sage/interfaces/tides.py b/src/sage/interfaces/tides.py index c3459753b82..96073fea42c 100644 --- a/src/sage/interfaces/tides.py +++ b/src/sage/interfaces/tides.py @@ -342,7 +342,7 @@ def remove_repeated(l1, l2): for i in range(len(l1)-1): j=i+1 while j Date: Sun, 7 Dec 2014 23:32:06 +0100 Subject: [PATCH 254/698] import_statements should ignore deprecated lazy imports --- src/sage/misc/dev_tools.py | 52 ++++++++++++++++++++++++----------- src/sage/misc/lazy_import.pyx | 13 +++++++++ 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/sage/misc/dev_tools.py b/src/sage/misc/dev_tools.py index 18cdde8cadf..9e2f655f598 100644 --- a/src/sage/misc/dev_tools.py +++ b/src/sage/misc/dev_tools.py @@ -349,7 +349,8 @@ def find_object_modules(obj): return module_to_obj -def import_statements(*objects, **options): + +def import_statements(*objects, **kwds): r""" Print import statements for the given objects. @@ -453,7 +454,7 @@ def import_statements(*objects, **options): sage: import_statements('EnumeratedSetFromIterator') Traceback (most recent call last): ... - ValueError: no object matched by 'EnumeratedSetFromIterator' was found. + LookupError: no object named 'EnumeratedSetFromIterator' sage: from sage.misc.dev_tools import load_submodules sage: load_submodules(sage.sets) load sage.sets.cartesian_product... suceeded @@ -466,7 +467,7 @@ def import_statements(*objects, **options): sage: import_statements('my_tailor_is_rich') Traceback (most recent call last): ... - ValueError: no object matched by 'my_tailor_is_rich' was found. + LookupError: no object named 'my_tailor_is_rich' sage: import_statements(5) Traceback (most recent call last): ... @@ -479,6 +480,17 @@ def import_statements(*objects, **options): sage: import_statements('NN') from sage.rings.semirings.non_negative_integer_semiring import NN + Deprecated lazy imports are ignored (see :trac:`17458`):: + + sage: lazy_import('sage.all', 'RR', 'deprecated_RR', namespace=sage.__dict__, deprecation=17458) + sage: import_statements('deprecated_RR') + Traceback (most recent call last): + ... + LookupError: object named 'deprecated_RR' is deprecated + sage: lazy_import('sage.all', 'RR', namespace=sage.__dict__, deprecation=17458) + sage: import_statements('RR') + from sage.rings.real_mpfr import RR + The following were fixed with :trac:`15351`:: sage: import_statements('Rationals') @@ -510,12 +522,12 @@ def import_statements(*objects, **options): # where "nameX" is an object in "module" that has to be # imported with the alias "aliasX" - lazy = options.pop("lazy", False) - verbose = options.pop("verbose", True) - answer_as_str = options.pop("answer_as_str",False) + lazy = kwds.pop("lazy", False) + verbose = kwds.pop("verbose", True) + answer_as_str = kwds.pop("answer_as_str", False) - if options: - raise ValueError("Unexpected '%s' argument"%options.keys()[0]) + if kwds: + raise TypeError("Unexpected '%s' argument"%kwds.keys()[0]) for obj in objects: name = None # the name of the object @@ -526,17 +538,20 @@ def import_statements(*objects, **options): obj = find_objects_from_name(name, 'sage') if len(obj) == 0: obj = find_objects_from_name(name) - if len(obj) == 0: - raise ValueError("no object matched by '%s' was found."%name) # remove lazy imported objects from list obj i = 0 + found_deprecated = False while i < len(obj): if isinstance(obj[i], LazyImport): - tmp = obj[i]._get_object() - del obj[i] - if all(u is not tmp for u in obj): - obj.append(tmp) + tmp = obj.pop(i) + # Ignore deprecated lazy imports + if tmp._is_deprecated(): + found_deprecated = True + else: + tmp = tmp._get_object() + if all(u is not tmp for u in obj): + obj.append(tmp) else: i += 1 @@ -550,8 +565,13 @@ def import_statements(*objects, **options): # choose a random object among the potentially enormous list of # objects we get from "name" - obj = obj[0] - + try: + obj = obj[0] + except IndexError: + if found_deprecated: + raise LookupError("object named %r is deprecated"%name) + else: + raise LookupError("no object named %r"%name) # 1'. if obj is a LazyImport we recover the real object if isinstance(obj, LazyImport): diff --git a/src/sage/misc/lazy_import.pyx b/src/sage/misc/lazy_import.pyx index 3dafe3962cf..f0c3dc450de 100644 --- a/src/sage/misc/lazy_import.pyx +++ b/src/sage/misc/lazy_import.pyx @@ -272,6 +272,19 @@ cdef class LazyImport(object): break return self._object + def _is_deprecated(self): + """ + Check whether a lazy import is deprecated. + + EXAMPLES:: + + sage: from sage.misc.lazy_import import LazyImport + sage: H = LazyImport('sage.categories.homsets', 'Homsets', deprecation=10668) + sage: H._is_deprecated() + True + """ + return self._deprecation is not None + def _sage_doc_(self): """ Return the docstring of the wrapped object for introspection. From fa8cb3694034f4d1735f7aaffee9c83e8ee65ce3 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Mon, 8 Dec 2014 00:17:23 +0100 Subject: [PATCH 255/698] Remove unused database modules --- src/doc/en/reference/databases/index.rst | 1 - src/sage/databases/all.py | 7 -- src/sage/databases/install.py | 65 --------------- src/sage/databases/lincodes.py | 102 ----------------------- 4 files changed, 175 deletions(-) delete mode 100644 src/sage/databases/install.py delete mode 100644 src/sage/databases/lincodes.py diff --git a/src/doc/en/reference/databases/index.rst b/src/doc/en/reference/databases/index.rst index ef16cc2f794..069c362f0be 100644 --- a/src/doc/en/reference/databases/index.rst +++ b/src/doc/en/reference/databases/index.rst @@ -53,7 +53,6 @@ database engine. sage/databases/cremona sage/databases/stein_watkins sage/databases/jones - sage/databases/lincodes sage/databases/oeis sage/databases/sloane sage/databases/conway diff --git a/src/sage/databases/all.py b/src/sage/databases/all.py index 5cd7ba997e2..4ff6cc81a7a 100644 --- a/src/sage/databases/all.py +++ b/src/sage/databases/all.py @@ -56,8 +56,6 @@ from stein_watkins import SteinWatkinsAllData, SteinWatkinsPrimeData -from install import database_install - from sloane import sloane_sequence, sloane_find, SloaneEncyclopedia from sage.misc.lazy_import import lazy_import @@ -65,11 +63,6 @@ from symbolic_data import SymbolicData -# commented out, since it's broken -- nobody updated the parser -# for the new format; nobody complained it didn't work, so it -# can't be that important. -#from lincodes import linear_code_bound - from odlyzko import zeta_zeros from db_modular_polynomials import \ diff --git a/src/sage/databases/install.py b/src/sage/databases/install.py deleted file mode 100644 index fc4768ff934..00000000000 --- a/src/sage/databases/install.py +++ /dev/null @@ -1,65 +0,0 @@ -""" -Automated database installation. - -This file defines a command "database_install": - -- takes name of db as argument - -- if db sitting in SAGE_ROOT, installs it - -- if not, downloads it with wget from modular - and installs it. -""" - - -from sage.misc.misc import SAGE_SHARE - -class GenericDatabaseInstaller: - def __init__(self, name): - self._name = name - - def __repr__(self): - return "Database installer for database %s"%self._name - - def name(self): - return self._name - - def directory(self): - """ - Returns the directory that contains this database. - """ - return "%s/%s"%(SAGE_SHARE, self._name) - - def archive_filename(self): - """ - Returns the filename of the database archive. - """ - return 'db-%s.tar'%self._name - - def get_archive_file(self): - """ - Makes sure that the archive file is in the SAGE_ROOT - directory. - """ - filename = self.archive_filename() - - def install(self): - F = self.archive_filename() - raise NotImplementedError - - - -def database_install(name): - """ - Install the database name. - - INPUT: - name -- string - OUTPUT: - installs the database so it is available to Sage. - (You may have to restart Sage.) - """ - i = name.find('.') - if i != -1: - name = name[:i] - print("Truncating database name to '%s'"%name) - D = GenericDatabaseInstaller(name) - D.install() - diff --git a/src/sage/databases/lincodes.py b/src/sage/databases/lincodes.py deleted file mode 100644 index ec2aa5397fa..00000000000 --- a/src/sage/databases/lincodes.py +++ /dev/null @@ -1,102 +0,0 @@ -""" -Linear codes -""" - -#***************************************************************************** -# -# Sage: Copyright (C) 2005 William Stein -# 2005 Steven Sivek -# -# Distributed under the terms of the GNU General Public License (GPL) -# -# This code is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# The full text of the GPL is available at: -# -# http://www.gnu.org/licenses/ -#***************************************************************************** - -import re - -def parse_bound_html(text, n, k): - lower, upper = -1, -1 - bound = re.compile(r'(?P[LU])b\(' - r'(?P[0-9]*),(?P[0-9]*)' - r'\) = (?P[0-9]*) '); - - for line in re.split(r'[\s,]*\n', text): - m = bound.search(line) - if m and int(m.group('n')) == n and int(m.group('k')) == k: - if m.group('type') == 'L': - lower = int(m.group('val')) - elif m.group('type') == 'U': - upper = int(m.group('val')) - return lower, upper - -## def linear_code_bound(q, n, k, verbose=False): -## r""" -## Find bounds on the minimum distance of linear codes over GF(q) -## with length n and dimension k, courtesy of -## \url{http://www.win.tue.nl/~aeb/voorlincod.html}. -## If no bounds are in the database, returns lower and upper -## bounds of -1. - -## INPUT: -## q -- integer, the field order, which must be in -## [2, 3, 4, 5, 7, 8, 9] -## n -- integer, the length of the code -## k -- integer, the dimension of the code -## verbose -- bool (default=False), print verbose message - -## OUTPUT: -## integer -- lower bound -## integer -- upper bound -## str -- text about why the bounds are as given - -## EXAMPLES: -## To find lower and upper bounds for values q=7, n=32, k=8, type -## sage: lower, upper, text = linear_code_bound(7, 32, 8) # optional - internet -## sage: lower # optional -## 19 -## sage: upper # optional -## 21 -## sage: text # optional -## 'Lb(32,8) = 19 DG4\n\nUb(32,8) = 21 follows by a one-step Griesmer bound from:\nUb(10,7) = 3 is found by considering shortening to:\nUb(9,6) = 3 is found by construction B:\n[consider deleting the (at most) 6 coordinates of a word in the dual]' - -## When bounds are not known the upper and lower returned bounds are -1: -## sage: linear_code_bound(9, 32, 200) # optional - internet -## (-1, -1, '(error executing -why-)') - -## This function raises an IOError if an error occurs downloading -## data or parsing it. It raises a ValueError if the q input is -## invalid. - -## AUTHOR: 2005-11-14: Steven Sivek -## """ -## q = Integer(q) -## if not q in [2, 3, 4, 5, 7, 8, 9]: -## raise ValueError, "q (=%s) must be in [2,3,4,5,7,8,9]"%q -## n = Integer(n) -## k = Integer(k) - -## param = ("%s/%s/%s"%(q,n,k)).replace('L','') - -## url = "http://homepages.cwi.nl/htbin/aeb/lincodbd/"+param -## if verbose: -## print "Looking up the bounds at %s"%url -## f = urllib.urlopen(url) -## s = f.read() -## f.close() - -## i = s.find("
")
-##     j = s.find("
") -## if i == -1 or j == -1: -## raise IOError, "Error parsing data (missing pre tags)." -## text = s[i+5:j].strip() -## lower, upper = parse_bound_html(text, n, k) - -## return lower, upper, text - From 4058557aeb437667548d9614f6ea98eb1458865b Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Mon, 8 Dec 2014 09:21:00 +0100 Subject: [PATCH 256/698] trac #17458: add ticket number to the LookupError --- src/sage/misc/dev_tools.py | 5 +++-- src/sage/misc/lazy_import.pyx | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/sage/misc/dev_tools.py b/src/sage/misc/dev_tools.py index 9e2f655f598..02047863f9b 100644 --- a/src/sage/misc/dev_tools.py +++ b/src/sage/misc/dev_tools.py @@ -486,7 +486,7 @@ def import_statements(*objects, **kwds): sage: import_statements('deprecated_RR') Traceback (most recent call last): ... - LookupError: object named 'deprecated_RR' is deprecated + LookupError: object named 'deprecated_RR' is deprecated (see trac #17458) sage: lazy_import('sage.all', 'RR', namespace=sage.__dict__, deprecation=17458) sage: import_statements('RR') from sage.rings.real_mpfr import RR @@ -548,6 +548,7 @@ def import_statements(*objects, **kwds): # Ignore deprecated lazy imports if tmp._is_deprecated(): found_deprecated = True + ticket = tmp._is_deprecated(trac_ticket=True) else: tmp = tmp._get_object() if all(u is not tmp for u in obj): @@ -569,7 +570,7 @@ def import_statements(*objects, **kwds): obj = obj[0] except IndexError: if found_deprecated: - raise LookupError("object named %r is deprecated"%name) + raise LookupError("object named %r is deprecated (see trac #%s)"%(name,ticket)) else: raise LookupError("no object named %r"%name) diff --git a/src/sage/misc/lazy_import.pyx b/src/sage/misc/lazy_import.pyx index f0c3dc450de..e49be0f1b49 100644 --- a/src/sage/misc/lazy_import.pyx +++ b/src/sage/misc/lazy_import.pyx @@ -272,7 +272,7 @@ cdef class LazyImport(object): break return self._object - def _is_deprecated(self): + def _is_deprecated(self, trac_ticket=False): """ Check whether a lazy import is deprecated. @@ -282,8 +282,18 @@ cdef class LazyImport(object): sage: H = LazyImport('sage.categories.homsets', 'Homsets', deprecation=10668) sage: H._is_deprecated() True - """ - return self._deprecation is not None + sage: H._is_deprecated(trac_ticket=True) + 10668 + """ + if trac_ticket: + if self._deprecation is None: + return 0 + try: + return self._deprecation[0] + except TypeError: + return self._deprecation + else: + return self._deprecation is not None def _sage_doc_(self): """ From 528e64a33c3d3267d0a5e4e8531bad6a1d16a05e Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Mon, 8 Dec 2014 10:19:01 +0100 Subject: [PATCH 257/698] Rename _is_deprecated() as _get_deprecation_ticket() --- src/sage/misc/dev_tools.py | 14 +++++++------- src/sage/misc/lazy_import.pyx | 30 ++++++++++++++++-------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/sage/misc/dev_tools.py b/src/sage/misc/dev_tools.py index 02047863f9b..df20638107f 100644 --- a/src/sage/misc/dev_tools.py +++ b/src/sage/misc/dev_tools.py @@ -486,7 +486,7 @@ def import_statements(*objects, **kwds): sage: import_statements('deprecated_RR') Traceback (most recent call last): ... - LookupError: object named 'deprecated_RR' is deprecated (see trac #17458) + LookupError: object named 'deprecated_RR' is deprecated (see trac ticket 17458) sage: lazy_import('sage.all', 'RR', namespace=sage.__dict__, deprecation=17458) sage: import_statements('RR') from sage.rings.real_mpfr import RR @@ -541,14 +541,14 @@ def import_statements(*objects, **kwds): # remove lazy imported objects from list obj i = 0 - found_deprecated = False + deprecation = None while i < len(obj): if isinstance(obj[i], LazyImport): tmp = obj.pop(i) # Ignore deprecated lazy imports - if tmp._is_deprecated(): - found_deprecated = True - ticket = tmp._is_deprecated(trac_ticket=True) + tmp_deprecation = tmp._get_deprecation_ticket() + if tmp_deprecation: + deprecation = tmp_deprecation else: tmp = tmp._get_object() if all(u is not tmp for u in obj): @@ -569,8 +569,8 @@ def import_statements(*objects, **kwds): try: obj = obj[0] except IndexError: - if found_deprecated: - raise LookupError("object named %r is deprecated (see trac #%s)"%(name,ticket)) + if deprecation: + raise LookupError("object named %r is deprecated (see trac ticket %s)"%(name, deprecation)) else: raise LookupError("no object named %r"%name) diff --git a/src/sage/misc/lazy_import.pyx b/src/sage/misc/lazy_import.pyx index e49be0f1b49..62f7abf5542 100644 --- a/src/sage/misc/lazy_import.pyx +++ b/src/sage/misc/lazy_import.pyx @@ -272,28 +272,30 @@ cdef class LazyImport(object): break return self._object - def _is_deprecated(self, trac_ticket=False): + def _get_deprecation_ticket(self): """ - Check whether a lazy import is deprecated. + Return the ticket number of the deprecation, or 0 if this lazy + import is not deprecated. EXAMPLES:: sage: from sage.misc.lazy_import import LazyImport + sage: H = LazyImport('sage.categories.homsets', 'Homsets') + sage: H._get_deprecation_ticket() + 0 sage: H = LazyImport('sage.categories.homsets', 'Homsets', deprecation=10668) - sage: H._is_deprecated() - True - sage: H._is_deprecated(trac_ticket=True) + sage: H._get_deprecation_ticket() + 10668 + sage: H = LazyImport('sage.categories.homsets', 'Homsets', deprecation=(10668, "this is deprecated")) + sage: H._get_deprecation_ticket() 10668 """ - if trac_ticket: - if self._deprecation is None: - return 0 - try: - return self._deprecation[0] - except TypeError: - return self._deprecation - else: - return self._deprecation is not None + if self._deprecation is None: + return 0 + try: + return self._deprecation[0] + except TypeError: + return self._deprecation def _sage_doc_(self): """ From 5b7363de53d56b9baed999a6c9ab51bac31c196f Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Mon, 8 Dec 2014 10:34:45 +0100 Subject: [PATCH 258/698] Remove obsolete sage-crap script --- src/bin/sage | 10 - src/bin/sage-crap | 621 -------------------------- src/doc/en/reference/repl/options.rst | 2 - 3 files changed, 633 deletions(-) delete mode 100755 src/bin/sage-crap diff --git a/src/bin/sage b/src/bin/sage index 4205ea5ff01..f323f679ba0 100755 --- a/src/bin/sage +++ b/src/bin/sage @@ -204,7 +204,6 @@ usage_advanced() { #### |.....................--.|...................................................| echo "Making Sage packages or distributions:" echo " -bdist VER -- build a binary distribution of Sage" - echo " -crap sage-ver.tar -- detect suspicious garbage in sage source tarball" echo " -pkg -- create Sage package dir.spkg from a given directory" echo " -pkg_nc -- as -pkg, but do not compress the package" echo " -sdist -- build a source distribution of Sage" @@ -628,15 +627,6 @@ if [ "$1" = '-rst2sws' -o "$1" = '--rst2sws' ]; then exec sage-rst2sws "$@" fi -##################################################################### -# Crap -##################################################################### - -if [ "$1" = "-crap" -o "$1" = "--crap" ]; then - shift - exec sage-crap $@ -fi - ##################################################################### # Run Sage's versions of the standard Algebra/Geometry etc. software ##################################################################### diff --git a/src/bin/sage-crap b/src/bin/sage-crap deleted file mode 100755 index f84010f6f19..00000000000 --- a/src/bin/sage-crap +++ /dev/null @@ -1,621 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2008, William Stein (with permission) -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of the Sage Project nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY WILLIAM STEIN ``AS IS'' AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL William Stein BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# uses system command 'file' to print out -# types of all files in (Sage) source tar -# -# prints "DONE" when finished -# -# takes about 15 CPU minutes to go through Sage -# -# version 20080118 -# -# The following file types are considered understood -# so no comment is made by them -# -# TXT type -# __init__.py, nodoctest.py files -# .hg directories -# *.html files (XML type) -# *.pdf (PDF type) -# symbolic links -# *.png (PNG image data) -# *.gif (GIF image data) -# *.tiff (TIFF image data) -# *.jpg (JPEG image data) -# *.s (Assembler source) -# -# Bad files (understood so NOT considered weird) -# -# MS-DOS executables -# ._* (AppleDouble encoded Macintosh files) -# *.class (JAVA) -# *.so (MACH-O) -# *.o (MACH-O) -# *.dylib (MACH-O) -# ELF -# - - -#runlevel = 0 # print everything -#runlevel = 1 # only print weird file types -runlevel = 2 # only print "bad" stuff - -import sys,os -import sage.misc.misc - -if len(sys.argv) != 2: - print "tar file required" - sys.exit() - -print os.path.abspath('.') -name = sys.argv[1] -basename = os.path.split(name)[1] -tempdir = sage.misc.misc.tmp_dir() -cmd = "cp %s %s"%(name,tempdir) -os.system(cmd) - -os.chdir(tempdir) -cmd = "tar xvf " + basename -print cmd -os.system(cmd) - -def cleanup(): - global tempdir - os.system('rm -rf "%s"'%tempdir) - -name = basename - -stack = [ name ] -print os.getcwd() + "/" + name -print "runlevel= ", runlevel -if (os.path.isfile(name) == False) and (os.path.isdir(name) == False): - print "does not exist!!!" - cleanup() - sys.exit() -while len(stack) > 0: - name = stack.pop() - if name == -1: # go up one level - os.chdir("..") - elif name == -2: # tar what you have looked at - basename = stack.pop() - tarname = stack.pop() - cmd = "tar cf " + tarname + " " + basename - os.system(cmd) - # remove base - cmd = "rm -rf '" + basename + "'" - if runlevel == 0: - print basename + " -> " + tarname - os.system(cmd) - elif name == -3: # gzip file - name = stack.pop() - if runlevel == 0: - print name + " -> " + name + ".gz" - cmd = "gzip '" + name + "'" - os.system(cmd) - elif name == -4: # bzip file - name = stack.pop() - cmd = "bzip2 '" + name + "'" - if runlevel == 0: - print name + " -> " + name + ".bz2" - os.system(cmd) - elif name == -5: # rename - newname = stack.pop() - name = stack.pop() - os.rename(newname,name) - if runlevel == 0: - print newname + " -> " + name - else: - fullname = os.getcwd() + "/" + name - # get file type - cmd = "file '" + name + "' > /tmp/temp" - os.system(cmd) - f = open('/tmp/temp','r') - file_output = f.read() - # if file is a directory - if file_output.find(': directory') > 0: - if name == ".hg": - if runlevel == 0: - print fullname + ": IGNORING" - # spkg/standard/fortran-20071120.p3/src/ - elif name == "g95": - if runlevel == 0: - print fullname + ": IGNORING" - else: - if runlevel == 0: - print fullname + ": DIR" - stack.append(-1) - sys.stdout.flush() - stack = stack + os.listdir(name) - os.chdir(name) - elif name.endswith('.spkg') > 0: - # if file name ends in .spkg - basename = name[0:name.find('.spkg')] - if file_output.find('bzip2') > 0: - newname = basename + '.tar.bz2' - elif file_output.find('tar') > 0: - newname = basename + '.tar' - os.rename(name,newname) - if runlevel == 0: - print fullname + " -> " + newname - stack.append(name) - stack.append(newname) - stack.append(-5) - stack.append(newname) - elif file_output.find(': bzip2') > 0: - # if file is a bzip2 file - cmd = 'bunzip2 ' + name - os.system(cmd) - basename = name[0:name.find('.bz2')] - if runlevel == 0: - print fullname + " -> " + basename - stack.append(basename) - stack.append(-4) - stack.append(basename) - elif file_output.find(': gzip ') > 0: - if name.endswith(".gz"): - # special case - BAD!!! - # 'spkg/standard/tachyon-0.98beta.p3/src/docs/tachyon.html.tar.gz' - # overwrites dir 'tachyon' - if name == "tachyon.html.tar.gz": - if runlevel <= 1: - print fullname + ": IGNORING" - else: - cmd = 'gunzip ' + name - os.system(cmd) - basename = name[0:name.find('.gz')] - stack.append(basename) - stack.append(-3) - stack.append(basename) - if runlevel == 0: - print fullname + " -> " + basename - elif name.endswith(".tgz"): - basename = name[0:name.find('.tgz')] - newname = basename + ".tar.gz" - os.rename(name, newname) - stack.append(name) - stack.append(newname) - stack.append(-5) - stack.append(newname) - if runlevel == 0: - print fullname + " -> " + newname - elif name.endswith(".dia"): # See http://live.gnome.org/Dia - basename = name[0:name.find('.dia')] - newname = basename + ".gz" - os.rename(name, newname) - stack.append(name) - stack.append(newname) - stack.append(-5) - stack.append(newname) - if runlevel == 0: - print fullname + " -> " + newname - elif name.endswith(".rda"): - if runlevel <= 1: - print fullname + ": R data format? (find error)" - else: - print fullname + ": GZIP with unusual suffix" - print "abnormal exit" - cleanup() - sys.exit() - elif file_output.find(': POSIX tar archive') > 0: - # special case BAD!!! - # 'spkg/standard/python-2.5.1.p10/src/Lib/test/testtar.tar' - # untars with error BAD!!! - if name == "testtar.tar": - if runlevel <= 1: - print fullname + ": IGNORING" - # special case BAD!!! - # 'spkg/standard/jmol-11.5.2/jmol/jars/vecmath1.2-1.14.tar' - # 'tar tvf' first line does NOT tell directory name - elif name == "vecmath1.2-1.14.tar": - if runlevel <= 1: - print fullname + ": IGNORING" - else: - # if file is a tar file - # get name that tar unpacks to - cmd = "tar tvf " + name + " > /tmp/temp" - os.system(cmd) - f = open('/tmp/temp','r') - temp0 = f.read() - temp1 = temp0.splitlines() - temp2 = temp1[0] - temp3 = temp2.split() - temp4 = temp3[len(temp3) - 1] - newname = temp4[0:len(temp4)-1] - # now untar - cmd = 'tar xf ' + name - os.system(cmd) - # remove tar file - os.unlink(os.getcwd() + '/' + name) - if runlevel == 0: - print fullname + " -> " + newname - # save tarfilename and newname on stack - stack.append(name) - stack.append(newname) - stack.append(-2) - stack.append(newname) - elif file_output.find('text') != -1: - if runlevel == 0: - print fullname + ": TXT" - elif file_output.find('TeX DVI') > 0: - if runlevel < 2: - print fullname + ": TeX DVI" - elif file_output.find(': XML') > 0: - if name.endswith(".html") > 0: - if runlevel == 0: - print fullname + ": XML" - else: - if runlevel < 2: - print fullname + ": XML" - elif file_output.find(': Zip archive data') > 0: - if runlevel < 2: - print fullname + ": ZIP" - elif file_output.find('Java') > 0: - if name.endswith(".class"): - if runlevel == 0: - print fullname + ": JAVA" - if runlevel == 2: - print fullname - else: - if runlevel < 2: - print fullname + ": JAVA" - elif file_output.find(': data') > 0: - if runlevel < 2: - print fullname + ": DATA" - elif file_output.find(': very short file (no magic)') > 0: - if name == "__init__.py": - if runlevel == 0: - print fullname + ": very short file (no magic)" - else: - if runlevel < 2: - print fullname + ": very short file (no magic)" - elif file_output.find(': DCL command file') > 0: - if runlevel < 2: - print fullname + ": DCL command file" - elif file_output.find(': CLIPPER instruction trace') > 0: - if runlevel < 2: - print fullname + ": CLIPPER instruction trace" - elif file_output.find(': Palm OS dynamic library data') > 0: - if runlevel < 2: - print fullname + ": Palm OS dynamic library data" - elif file_output.find(': 80386 COFF') > 0: - if runlevel < 2: - print fullname + ": 80386 COFF" - elif file_output.find(': ACB archive data') > 0: - if runlevel < 2: - print fullname + ": ACB archive data" - elif file_output.find(': MS Windows HtmlHelp Data') > 0: - if runlevel < 2: - print fullname + ": MS Windows HtmlHelp Data" - elif file_output.find(': AppleDouble encoded Macintosh file') > 0: - if name.startswith("._"): - if runlevel == 0: - print fullname + ": AppleDouble encoded Macintosh file" - if runlevel == 2: - print fullname - else: - if runlevel < 2: - print fullname + ": AppleDouble encoded Macintosh file" - elif file_output.find(': Macromedia Flash data') > 0: - if runlevel < 2: - print fullname + ": Macromedia Flash data" - elif file_output.find(': Microsoft Installer') > 0: - if runlevel < 2: - print fullname + ": Microsoft Installer" - elif file_output.find(': PNG image data') > 0: - if name.endswith(".png") > 0: - if runlevel == 0: - print fullname + ": PNG image data" - else: - if runlevel < 2: - print fullname + ": PNG image data" - elif file_output.find(': empty') > 0: - if name == "__init__.py": - if runlevel == 0: - print fullname + ": empty" - elif name == "nodoctest.py": - if runlevel == 0: - print fullname + ": empty" - else: - if runlevel < 2: - print fullname + ": empty" - elif file_output.find('8086 relocatable') > 0: - if runlevel < 2: - print fullname + ": 8086 relocatable" - elif file_output.find(': PC bitmap data') > 0: - if runlevel < 2: - print fullname + ": PC bitmap data" - elif file_output.find(': GIF image data') > 0: - if name.endswith(".gif") > 0: - if runlevel == 0: - print fullname + ": GIF image data" - else: - if runlevel < 2: - print fullname + ": GIF image data" - elif file_output.find(': Apple binary property list') > 0: - if runlevel < 2: - print fullname + ": Apple binary property list" - elif file_output.find(': LaTeX table of contents') > 0: - if runlevel < 2: - print fullname + ": LaTeX table of contents" - elif file_output.find(': Makeindex log file') > 0: - if runlevel < 2: - print fullname + ": Makeindex log file" - elif file_output.find(': LaTeX raw index file') > 0: - if runlevel < 2: - print fullname + ": LaTeX raw index file" - elif file_output.find('LaTeX auxiliary file') > 0: - if runlevel < 2: - print fullname + ": LaTeX auxiliary file" - elif file_output.find('TIFF image data') > 0: - if name.endswith(".tiff"): - if runlevel == 0: - print fullname + ": TIFF image data" - else: - if runlevel < 2: - print fullname + ": TIFF image data" - elif file_output.find('DOS EPS Binary File') > 0: - if runlevel < 2: - print fullname + ": DOS EPS Binary File" - elif file_output.find('MPEG sequence') > 0: - if runlevel < 2: - print fullname + ": MPEG sequence" - elif file_output.find('JPEG image data') > 0: - if name.endswith(".jpg"): - if runlevel == 0: - print fullname + ": JPEG image data" - else: - if runlevel < 2: - print fullname + ": JPEG image data" - elif file_output.find(': Apple Old Partition') > 0: - if runlevel < 2: - print fullname + ": Apple Old Partition" - elif file_output.find(': current ar archive') > 0: - if runlevel < 2: - print fullname + ": current ar archive" - elif file_output.find(': python 2.3 byte-compiled') > 0: - if runlevel < 2: - print fullname + ": python 2.3 byte-compiled" - elif file_output.find(': python 2.4 byte-compiled') > 0: - if runlevel < 2: - print fullname + ": python 2.4 byte-compiled" - elif file_output.find(': python 2.5 byte-compiled') > 0: - if runlevel < 2: - print fullname + ": python 2.5 byte-compiled" - elif file_output.find('Assembler source') > 0: - if name.endswith(".s"): - if runlevel == 0: - print fullname + ": Assembler source" - else: - if runlevel < 2: - print fullname + ": Assembler source" - elif file_output.find(': PDF') > 0: - if name.endswith(".pdf") > 0: - if runlevel == 0: - print fullname + ": PDF" - else: - if runlevel < 2: - print fullname + ": PDF" - elif file_output.find(': MS-DOS executable') > 0: - if runlevel == 0: - print fullname + ": MS-DOS executable" - if runlevel == 2: - print fullname - elif file_output.find(': DOS executable') > 0: - if runlevel < 2: - print fullname + ": DOS executable" - elif file_output.find(': Matlab v5 mat-file') > 0: - if runlevel < 2: - print fullname + ": Matlab v5 mat-file" - elif file_output.find(': Extreme Tracker AMS Module v1.3') > 0: - if runlevel < 2: - print fullname + ": Extreme Tracker AMS Module v1.3" - elif file_output.find(': JVT NAL sequence') > 0: - if runlevel < 2: - print fullname + ": JVT NAL sequence" - elif file_output.find(': NeXT/Apple typedstream data') > 0: - if runlevel < 2: - print fullname + ": NeXT/Apple typedstream data" - elif file_output.find(': Rich Text Format data') > 0: - if runlevel < 2: - print fullname + ": Rich Text Format data" - elif file_output.find(': AppleSingle encoded Macintosh file') > 0: - if runlevel < 2: - print fullname + ": AppleSingle encoded Macintosh file" - elif file_output.find(': Adobe Photoshop Image') > 0: - if runlevel < 2: - print fullname + ": Adobe Photoshop Image" - elif file_output.find(': Macintosh Application (data)') > 0: - if runlevel < 2: - print fullname + ": Macintosh Application (data)" - elif file_output.find(': X11 SNF font data') > 0: - if runlevel < 2: - print fullname + ": X11 SNF font data" - elif file_output.find(': Sun/NeXT audio data') > 0: - if runlevel < 2: - print fullname + ": Sun/NeXT audio data" - elif file_output.find(': Berkeley DB') > 0: - if runlevel < 2: - print fullname + ": Berkeley DB" - elif file_output.find(': multipart/mixed') > 0: - if runlevel < 2: - print fullname + ": multipart/mixed" - elif file_output.find(': message/rfc822') > 0: - if runlevel < 2: - print fullname + ": message/rfc822" - elif file_output.find(': LaTeX sorted index') > 0: - if runlevel < 2: - print fullname + ": LaTeX sorted index" - elif file_output.find(': Xara graphics file') > 0: - if runlevel < 2: - print fullname + ": Xara graphics file" - elif file_output.find(': PalmOS application') > 0: - if runlevel < 2: - print fullname + ": PalmOS application" - elif file_output.find(': Par archive data') > 0: - if runlevel < 2: - print fullname + ": Par archive data" - elif file_output.find(': PGP key public ring') > 0: - if runlevel < 2: - print fullname + ": PGP key public ring" - elif file_output.find(': GPG key public ring') > 0: - if runlevel < 2: - print fullname + ": GPG key public ring" - elif file_output.find(': PGP key security ring') > 0: - if runlevel < 2: - print fullname + ": PGP key security ring" - elif file_output.find(': FITS image data') > 0: - if runlevel < 2: - print fullname + ": FITS image data" - elif file_output.find(': Bio-Rad .PIC Image File') > 0: - if runlevel < 2: - print fullname + ": Bio-Rad .PIC Image File" - elif file_output.find(': Arhangel archive data') > 0: - if runlevel < 2: - print fullname + ": Arhangel archive data" - elif file_output.find(': RISC OS Draw file data') > 0: - if runlevel < 2: - print fullname + ": RISC OS Draw file data" - elif file_output.find(': CLIPPER instruction profile') > 0: - if runlevel < 2: - print fullname + ": CLIPPER instruction profile" - elif file_output.find(': character Computer Graphics Metafile') > 0: - if runlevel < 2: - print fullname + ": character Computer Graphics Metafile" - elif file_output.find(': Windows INF file') > 0: - if runlevel < 2: - print fullname + ": Windows INF file" - elif file_output.find(': Emacs v18 byte-compiled Lisp data') > 0: - if runlevel < 2: - print fullname + ": Emacs v18 byte-compiled Lisp data" - elif file_output.find(': Netpbm PPM') > 0: - if runlevel < 2: - print fullname + ": Netpbm PPM" - elif file_output.find(': TrueType font data') > 0: - if runlevel < 2: - print fullname + ": TrueType font data" - elif file_output.find(': ASCII font metrics') > 0: - if runlevel < 2: - print fullname + ": ASCII font metrics" - elif file_output.find(': Maple worksheet') > 0: - if runlevel < 2: - print fullname + ": Maple worksheet" - elif file_output.find(': GNU message catalog') > 0: - if runlevel < 2: - print fullname + ": GNU message catalog" - elif file_output.find(': ELF 32-bit LSB executable, Intel 80386') > 0: - if runlevel == 0: - print fullname + ": ELF 32-bit LSB executable" - if runlevel == 2: - print fullname - elif file_output.find(': symbolic link') > 0: - if runlevel == 0: - print fullname + ": symbolic link" - elif file_output.find('SysEx File') > 0: - if runlevel < 2: - print fullname + ": SysEx File" - elif file_output.find(': libtool library file') > 0: - if runlevel < 2: - print fullname + ": libtool library file" - elif file_output.find(': SQLite 3.x database') > 0: - if runlevel < 2: - print fullname + ": SQLite 3.x database" - elif file_output.find(': YAC archive data') > 0: - if runlevel < 2: - print fullname + ": YAC archive data" - elif file_output.find(': PGP armored data') > 0: - if runlevel < 2: - print fullname + ": PGP armored data" - elif file_output.find(': Apple QuickTime movie') > 0: - if runlevel < 2: - print fullname + ": Apple QuickTime movie" - elif file_output.find(': Quake I or II world') > 0: - if runlevel < 2: - print fullname + ": Quake I or II world" - elif file_output.find(': Mach-O') > 0: - if name.endswith(".so") | name.endswith(".o") | name.endswith(".dylib"): - if runlevel == 0: - print fullname + ": Mach-O" - if runlevel == 2: - print fullname - else: - if runlevel < 2: - print fullname + ": Mach-O" - elif file_output.find(': ELF 64-bit') > 0: - if runlevel == 0: - print fullname + ": ELF 64-bit" - if runlevel == 2: - print fullname - elif file_output.find(': ELF 32-bit') > 0: - if runlevel == 0: - print fullname + ": ELF 32-bit" - if runlevel == 2: - print fullname - elif file_output.find(': SPEC') > 0: - if runlevel < 2: - print fullname + ": SPEC" - elif file_output.find(': Octave binary data') > 0: - if runlevel < 2: - print fullname + ": Octave binary data" - elif file_output.find(': DBase 3 data file') > 0: - if runlevel < 2: - print fullname + ": DBase 3 data file" - elif file_output.find(': OpenOffice.org') > 0: - if runlevel < 2: - print fullname + ": OpenOffice.org" - elif file_output.find(': fifo (named pipe)') > 0: - if runlevel < 2: - print fullname + ": fifo (named pipe)" - elif file_output.find(': broken symbolic link') > 0: - if runlevel < 2: - print fullname + ": broken symbolic link" - elif file_output.find(': timezone data') > 0: - if runlevel < 2: - print fullname + ": timezone data" - elif file_output.find(': Macintosh Library (data)') > 0: - if runlevel < 2: - print fullname + ": Macintosh Library (data)" - elif file_output.find(': SPSS System File') > 0: - if runlevel < 2: - print fullname + ": SPSS System File" - elif file_output.find(': mc68020 pure executable not stripped') > 0: - if runlevel < 2: - print fullname + ": mc68020 pure executable not stripped" - elif file_output.find(': MPEG ADTS') > 0: - if runlevel < 2: - print fullname + ": MPEG ADTS" - elif file_output.find(': XPack DiskImage archive data') > 0: - if runlevel < 2: - print fullname + ": XPack DiskImage archive data" - elif file_output.find(': VMS Alpha executable') > 0: - if runlevel < 2: - print fullname + ": VMS Alpha executable" - else: - print fullname + ": UNKNOWN" - print file_output -cleanup() -print "DONE!!!" diff --git a/src/doc/en/reference/repl/options.rst b/src/doc/en/reference/repl/options.rst index a8738520ce5..10e1e9d6a97 100644 --- a/src/doc/en/reference/repl/options.rst +++ b/src/doc/en/reference/repl/options.rst @@ -208,8 +208,6 @@ Command-line options for Sage - ``--bdist VER`` -- build a binary distribution of Sage, with version ``VER`` - ``--sdist`` -- build a source distribution of Sage -- ``--crap sage-ver.tar`` -- detect suspicious garbage in the Sage - source tarball .. rubric:: Valgrind memory debugging From 75d7418c1d5e8e7bf2523cd2ad298d45fc4015d6 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Sun, 7 Dec 2014 10:32:35 +0100 Subject: [PATCH 259/698] Skip lazy imports when docbuilding --- src/doc/common/sage_autodoc.py | 6 ++++++ src/sage/combinat/rigged_configurations/kr_tableaux.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/doc/common/sage_autodoc.py b/src/doc/common/sage_autodoc.py index 40bceb16da8..b7969ab2413 100644 --- a/src/doc/common/sage_autodoc.py +++ b/src/doc/common/sage_autodoc.py @@ -39,6 +39,7 @@ from sphinx.util.docstrings import prepare_docstring from sage.misc.sageinspect import _sage_getdoc_unformatted, sage_getargspec, isclassinstance +from sage.misc.lazy_import import LazyImport try: base_exception = BaseException @@ -513,6 +514,11 @@ def filter_members(self, members, want_all): # process members and determine which to skip for (membername, member) in members: + # Immediately skip lazy imports to avoid deprecation + # messages (#17455). + if isinstance(member, LazyImport): + continue + # if isattr is True, the member is documented as an attribute isattr = False diff --git a/src/sage/combinat/rigged_configurations/kr_tableaux.py b/src/sage/combinat/rigged_configurations/kr_tableaux.py index ce46d2b2704..c1b87ea6173 100644 --- a/src/sage/combinat/rigged_configurations/kr_tableaux.py +++ b/src/sage/combinat/rigged_configurations/kr_tableaux.py @@ -501,7 +501,7 @@ def tensor(self, *crystals, **options): Return the tensor product of ``self`` with ``crystals``. If ``crystals`` is a list of (a tensor product of) KR tableaux, this - returns a :class:`TensorProductOfKirillovReshetikhinTableaux`. + returns a :class:`crystals.TensorProductOfKirillovReshetikhinTableaux`. EXAMPLES:: From b7eb59f3e5e048780f8abd9cc5cf33617d5f273d Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Mon, 8 Dec 2014 11:30:12 +0100 Subject: [PATCH 260/698] Remove some functions from sage/misc/functional.py --- src/sage/all.py | 2 +- .../examples/finite_coxeter_groups.py | 3 +- src/sage/geometry/toric_lattice.py | 3 +- .../abelian_gps/dual_abelian_group_element.py | 3 +- src/sage/misc/all.py | 9 +- src/sage/misc/functional.py | 269 ++---------------- src/sage/misc/sage_input.py | 4 +- src/sage/modular/abvar/homspace.py | 2 +- src/sage/monoids/string_monoid_element.py | 3 +- src/sage/monoids/string_ops.py | 2 +- src/sage/plot/plot3d/base.pyx | 3 - src/sage/plot/plot3d/transform.pyx | 8 +- src/sage/probability/random_variable.py | 4 +- src/sage/quadratic_forms/quadratic_form.py | 7 +- .../quadratic_form__local_normal_form.py | 4 - src/sage/rings/all.py | 1 + src/sage/rings/polynomial/convolution.py | 2 +- src/sage/rings/power_series_ring_element.pyx | 2 - src/sage/structure/all.py | 5 +- 19 files changed, 44 insertions(+), 292 deletions(-) diff --git a/src/sage/all.py b/src/sage/all.py index e1a7289eb73..fe49055569f 100644 --- a/src/sage/all.py +++ b/src/sage/all.py @@ -97,6 +97,7 @@ except ImportError: pass # dev scripts are disabled +from sage.structure.all import * from sage.rings.all import * from sage.matrix.all import * @@ -111,7 +112,6 @@ from sage.graphs.all import * from sage.groups.all import * from sage.databases.all import * -from sage.structure.all import * from sage.categories.all import * from sage.sets.all import * from sage.probability.all import * diff --git a/src/sage/categories/examples/finite_coxeter_groups.py b/src/sage/categories/examples/finite_coxeter_groups.py index d9a0bd75260..029e1b07274 100644 --- a/src/sage/categories/examples/finite_coxeter_groups.py +++ b/src/sage/categories/examples/finite_coxeter_groups.py @@ -145,6 +145,7 @@ def __contains__(self, x): Check in the element x is in the mathematical parent self. EXAMPLES:: + sage: D5 = FiniteCoxeterGroups().example() sage: D5.an_element() in D5 True @@ -153,7 +154,7 @@ def __contains__(self, x): (also tested by :meth:`test_an_element` :meth:`test_some_elements`) """ - from sage.misc.functional import parent + from sage.structure.all import parent return parent(x) is self @cached_method diff --git a/src/sage/geometry/toric_lattice.py b/src/sage/geometry/toric_lattice.py index 06bd33dc283..2bb12a197d5 100644 --- a/src/sage/geometry/toric_lattice.py +++ b/src/sage/geometry/toric_lattice.py @@ -149,7 +149,8 @@ from sage.geometry.toric_lattice_element import (ToricLatticeElement, is_ToricLatticeElement) from sage.geometry.toric_plotter import ToricPlotter -from sage.misc.all import latex, parent +from sage.misc.all import latex +from sage.structure.all import parent from sage.modules.fg_pid.fgp_element import FGP_Element from sage.modules.fg_pid.fgp_module import FGP_Module_class from sage.modules.free_module import (FreeModule_ambient_pid, diff --git a/src/sage/groups/abelian_gps/dual_abelian_group_element.py b/src/sage/groups/abelian_gps/dual_abelian_group_element.py index a44dfbc7d57..f7bfb1dbb88 100644 --- a/src/sage/groups/abelian_gps/dual_abelian_group_element.py +++ b/src/sage/groups/abelian_gps/dual_abelian_group_element.py @@ -57,7 +57,6 @@ from sage.rings.infinity import infinity from sage.rings.arith import * from sage.misc.misc import prod -from sage.misc.functional import exp from sage.rings.complex_field import is_ComplexField from sage.groups.abelian_gps.element_base import AbelianGroupElementBase from functools import reduce @@ -162,7 +161,7 @@ def __call__(self, g): from sage.symbolic.constants import pi I = F.gen() PI = F(pi) - ans = prod([exp(2*PI*I*expsX[i]*expsg[i]/order[i]) for i in range(len(expsX))]) + ans = prod([(2*PI*I*expsX[i]*expsg[i]/order[i]).exp() for i in range(len(expsX))]) return ans ans = F(1) ## assumes F is the cyclotomic field zeta = F.gen() diff --git a/src/sage/misc/all.py b/src/sage/misc/all.py index 05cc3da8031..0d7aad0d3c0 100644 --- a/src/sage/misc/all.py +++ b/src/sage/misc/all.py @@ -79,7 +79,6 @@ from func_persist import func_persist from functional import (additive_order, - sqrt as numerical_sqrt, base_ring, base_field, basis, @@ -96,13 +95,10 @@ discriminant, disc, eta, - exp, - factor, fcp, gen, gens, hecke_operator, - ideal, image, integral, integrate, integral_closure, @@ -116,6 +112,7 @@ kernel, krull_dimension, lift, + log as log_b, minimal_polynomial, minpoly, multiplicative_order, @@ -138,9 +135,7 @@ squarefree_part, symbolic_sum as sum, transpose, - zero, - log as log_b, - parent) + zero) from latex import LatexExpr, latex, view, pretty_print, pretty_print_default diff --git a/src/sage/misc/functional.py b/src/sage/misc/functional.py index a497908626b..dc87c66a937 100644 --- a/src/sage/misc/functional.py +++ b/src/sage/misc/functional.py @@ -15,19 +15,13 @@ #***************************************************************************** # Copyright (C) 2004 William Stein # -# Distributed under the terms of the GNU General Public License (GPL) -# -# This code is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# The full text of the GPL is available at: -# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** - import sage.misc.latex import sage.interfaces.expect import sage.interfaces.mathematica @@ -138,25 +132,6 @@ def category(x): import sage.categories.all return sage.categories.all.Objects() -def ceil(x): - """ - Returns the ceiling (least integer) function of x. - - EXAMPLES:: - - sage: ceil(3.5) - 4 - sage: ceil(7/2) - 4 - sage: ceil(-3.5) - -3 - sage: ceil(RIF(1.3,2.3)) - 3.? - """ - try: - return x.ceil() - except AttributeError: - return sage.rings.all.ceil(x) def characteristic_polynomial(x, var='x'): """ @@ -216,61 +191,6 @@ def coerce(P, x): except AttributeError: return P(x) - -def acos(x): - """ - Returns the arc cosine of x. - - EXAMPLES:: - - sage: acos(.5) - 1.04719755119660 - sage: acos(sin(pi/3)) - arccos(1/2*sqrt(3)) - sage: acos(sin(pi/3)).simplify_full() - 1/6*pi - """ - try: return x.acos() - except AttributeError: return RDF(x).acos() - -def asin(x): - """ - Returns the arc sine of x. - - EXAMPLES:: - - sage: asin(.5) - 0.523598775598299 - sage: asin(sin(pi/3)) - arcsin(1/2*sqrt(3)) - sage: asin(sin(pi/3)).simplify_full() - 1/3*pi - """ - try: return x.asin() - except AttributeError: return RDF(x).asin() - -def atan(x): - """ - Returns the arc tangent of x. - - EXAMPLES:: - - sage: z = atan(3);z - arctan(3) - sage: n(z) - 1.24904577239825 - sage: atan(tan(pi/4)) - 1/4*pi - """ - try: return x.atan() - except AttributeError: return RDF(x).atan() - -## def cuspidal_submodule(x): -## return x.cuspidal_submodule() - -## def cuspidal_subspace(x): -## return x.cuspidal_subspace() - def cyclotomic_polynomial(n, var='x'): """ Returns the `n^{th}` cyclotomic polynomial. @@ -376,13 +296,6 @@ def discriminant(x): disc = discriminant -# This is dangerous since it gets the scoping all wrong ?? -#import __builtin__ -#def eval(x): -# try: -# return x._eval_() -# except AttributeError: -# return __builtin__.eval(x) def eta(x): r""" @@ -403,52 +316,6 @@ def eta(x): try: return x.eta() except AttributeError: return CDF(x).eta() -def exp(x): - """ - Returns the value of the exponentiation function at x. - - EXAMPLES:: - - sage: exp(3) - e^3 - sage: exp(0) - 1 - sage: exp(2.5) - 12.1824939607035 - sage: exp(pi*i) - -1 - """ - try: return x.exp() - except AttributeError: return RDF(x).exp() - -def factor(x, *args, **kwds): - """ - Returns the (prime) factorization of x. - - EXAMPLES:: - - sage: factor(factorial(10)) - 2^8 * 3^4 * 5^2 * 7 - sage: n = next_prime(10^6); n - 1000003 - sage: factor(n) - 1000003 - - Note that this depends on the type of x:: - - sage: factor(55) - 5 * 11 - sage: factor(x^2+2*x+1) - (x + 1)^2 - sage: factor(55*x^2+110*x+55) - 55*(x + 1)^2 - - """ - try: return x.factor(*args, **kwds) - except AttributeError: return sage.rings.all.factor(x, *args, **kwds) - -factorization = factor -factorisation = factor def fcp(x, var='x'): """ @@ -462,13 +329,8 @@ def fcp(x, var='x'): x * (x^2 - 15*x - 18) """ try: return x.fcp(var) - except AttributeError: return factor(charpoly(x, var)) + except AttributeError: return charpoly(x, var).factor() -## def floor(x): -## try: -## return x.floor() -## except AttributeError: -## return sage.rings.all.floor(x) def gen(x): """ @@ -517,7 +379,6 @@ def hecke_operator(x,n): """ return x.hecke_operator(n) -ideal = sage.rings.ideal.Ideal def image(x): """ @@ -910,24 +771,6 @@ def is_field(x): """ return x.is_field() -def is_noetherian(x): - """ - Returns whether or not x is a Noetherian - object (has ascending chain condition). - - EXAMPLES:: - - sage: from sage.misc.functional import is_noetherian - sage: is_noetherian(ZZ) - True - sage: is_noetherian(QQ) - True - sage: A = SteenrodAlgebra(3) - sage: is_noetherian(A) - False - """ - - return x.is_noetherian() def is_odd(x): """ @@ -947,18 +790,6 @@ def is_odd(x): """ return not is_even(x) -## def j_invariant(x): -## """ -## Return the j_invariant of x. - -## EXAMPLES: -## sage: E = EllipticCurve([0, -1, 1, -10, -20]) -## sage: E -## Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field -## sage: j_invariant(E) -## -122023936/161051 -## """ -## return x.j_invariant() def kernel(x): """ @@ -1119,11 +950,6 @@ def multiplicative_order(x): """ return x.multiplicative_order() -## def new_submodule(x): -## return x.new_submodule() - -## def new_subspace(x): -## return x.new_subspace() def ngens(x): """ @@ -1500,12 +1326,18 @@ def one(R): EXAMPLES:: + sage: one(RR) + doctest:...: DeprecationWarning: one(R) is deprecated, use R.one() or R(1) instead + See http://trac.sagemath.org/17158 for details. + 1.00000000000000 sage: R. = PolynomialRing(QQ) sage: one(R)*x == x True sage: one(R) in R True """ + from sage.misc.superseded import deprecation + deprecation(17158, 'one(R) is deprecated, use R.one() or R(1) instead') return R(1) def order(x): @@ -1699,32 +1531,7 @@ def _do_show(x): return sage.misc.latex.latex(x) from latex import view view(x, mode='display') - #raise AttributeError, "object %s does not support show."%(x, ) - -def sqrt(x): - """ - Returns a square root of x. - - This function (``numerical_sqrt``) is deprecated. Use ``sqrt(x, - prec=n)`` instead. - EXAMPLES:: - - sage: numerical_sqrt(10.1) - doctest:...: DeprecationWarning: numerical_sqrt is deprecated, use sqrt(x, prec=n) instead - See http://trac.sagemath.org/5404 for details. - 3.17804971641414 - sage: numerical_sqrt(9) - 3 - """ - from sage.misc.superseded import deprecation - deprecation(5404, "numerical_sqrt is deprecated, use sqrt(x, prec=n) instead") - try: return x.sqrt() - except (AttributeError, ValueError): - try: - return RDF(x).sqrt() - except TypeError: - return CDF(x).sqrt() def isqrt(x): """ @@ -1782,6 +1589,8 @@ def squarefree_part(x): return x.squarefree_part() except AttributeError: pass + from sage.rings.arith import factor + from sage.structure.all import parent F = factor(x) n = parent(x)(1) for p, e in F: @@ -1789,20 +1598,6 @@ def squarefree_part(x): n *= p return n * F.unit() -## def square_root(x): -## """ -## Return a square root of x with the same parent as x, if possible, -## otherwise raise a ValueError. -## EXAMPLES: -## sage: square_root(9) -## 3 -## sage: square_root(100) -## 10 -## """ -## try: -## return x.square_root() -## except AttributeError: -## raise NotImplementedError def transpose(x): """ @@ -1819,15 +1614,6 @@ def transpose(x): """ return x.transpose() -## def vector(x, R): -## r""" -## Return the \sage vector over $R$ obtained from x, if possible. -## """ -## try: -## return x._vector_(R) -## except AttributeError: -## import sage.modules.free_module_element -## return sage.modules.free_module_element.Vector(x, R) def zero(R): """ @@ -1835,33 +1621,16 @@ def zero(R): EXAMPLES:: + sage: zero(RR) + doctest:...: DeprecationWarning: zero(R) is deprecated, use R.zero() or R(0) instead + See http://trac.sagemath.org/17158 for details. + 0.000000000000000 sage: R. = PolynomialRing(QQ) sage: zero(R) in R True sage: zero(R)*x == zero(R) True """ + from sage.misc.superseded import deprecation + deprecation(17158, 'zero(R) is deprecated, use R.zero() or R(0) instead') return R(0) - - - -################################################################# -# Generic parent -################################################################# -def parent(x): - """ - Returns x.parent() if defined, or type(x) if not. - - EXAMPLE:: - - sage: Z = parent(int(5)) - sage: Z(17) - 17 - sage: Z - - """ - try: - return x.parent() - except AttributeError: - return type(x) - diff --git a/src/sage/misc/sage_input.py b/src/sage/misc/sage_input.py index b34cf97e18c..d36f7eac315 100644 --- a/src/sage/misc/sage_input.py +++ b/src/sage/misc/sage_input.py @@ -444,7 +444,7 @@ def __call__(self, x, coerced=False): # However, we don't want to assume that hashing x is always # efficient, so we only try the lookup if some value of the same # type as x has been cached. - from sage.misc.functional import parent + from sage.structure.all import parent if type(x) in self._cached_types: v = self._cache.get((parent(x), x)) @@ -655,7 +655,7 @@ def cache(self, x, sie, name): GF_101 = GF(101) GF_101(42) + GF_101(43) """ - from sage.misc.functional import parent + from sage.structure.all import parent self._cached_types.add(type(x)) self._cache[(parent(x), x)] = sie diff --git a/src/sage/modular/abvar/homspace.py b/src/sage/modular/abvar/homspace.py index a601e50777f..30d8644acb7 100644 --- a/src/sage/modular/abvar/homspace.py +++ b/src/sage/modular/abvar/homspace.py @@ -174,7 +174,7 @@ from copy import copy from sage.categories.homset import HomsetWithBase, End -from sage.misc.functional import parent +from sage.structure.all import parent from sage.misc.lazy_attribute import lazy_attribute import abvar as abelian_variety diff --git a/src/sage/monoids/string_monoid_element.py b/src/sage/monoids/string_monoid_element.py index f0734da2348..a390eb483c1 100644 --- a/src/sage/monoids/string_monoid_element.py +++ b/src/sage/monoids/string_monoid_element.py @@ -24,8 +24,6 @@ # import operator from sage.rings.integer import Integer from sage.rings.all import RealField -# from sage.structure.element import MonoidElement -from sage.probability.random_variable import DiscreteProbabilitySpace from free_monoid_element import FreeMonoidElement import string_monoid @@ -511,4 +509,5 @@ def frequency_distribution(self, length=1, prec=0): X[c] = eps # Return a dictionary of probability distribution. This should # allow for easier parsing of the dictionary. + from sage.probability.random_variable import DiscreteProbabilitySpace return DiscreteProbabilitySpace(Alph, X, RR) diff --git a/src/sage/monoids/string_ops.py b/src/sage/monoids/string_ops.py index 7c24f14911c..cab8e9b10ce 100644 --- a/src/sage/monoids/string_ops.py +++ b/src/sage/monoids/string_ops.py @@ -7,7 +7,6 @@ #***************************************************************************** from sage.rings.all import RealField -from sage.probability.random_variable import DiscreteProbabilitySpace from string_monoid_element import StringMonoidElement def strip_encoding(S): @@ -47,6 +46,7 @@ def frequency_distribution(S, n=1, field=None): P[c] += eps else: P[c] = eps + from sage.probability.random_variable import DiscreteProbabilitySpace return DiscreteProbabilitySpace(S,P,field) raise TypeError("Argument S (= %s) must be a string, list, or tuple.") diff --git a/src/sage/plot/plot3d/base.pyx b/src/sage/plot/plot3d/base.pyx index d1ff9d142fb..335bb435fe2 100644 --- a/src/sage/plot/plot3d/base.pyx +++ b/src/sage/plot/plot3d/base.pyx @@ -34,7 +34,6 @@ from cpython.list cimport * import os from functools import reduce -from math import atan2 from random import randint import zipfile from cStringIO import StringIO @@ -45,9 +44,7 @@ from sage.env import SAGE_LOCAL from sage.modules.free_module_element import vector from sage.rings.real_double import RDF -from sage.misc.functional import sqrt, atan, acos from sage.misc.temporary_file import tmp_filename, graphics_filename - from texture import Texture, is_Texture from transform cimport Transformation, point_c, face_c include "point_c.pxi" diff --git a/src/sage/plot/plot3d/transform.pyx b/src/sage/plot/plot3d/transform.pyx index e79a52a4180..e4f11db18a5 100644 --- a/src/sage/plot/plot3d/transform.pyx +++ b/src/sage/plot/plot3d/transform.pyx @@ -7,17 +7,12 @@ # (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** -cdef extern from *: - double sin(double) - double cos(double) - double sqrt(double) -#from math import atan2, sin, cos, atan, sqrt, acos +from libc.math cimport sin, cos, sqrt include "point_c.pxi" from sage.rings.real_double import RDF -# from sage.misc.functional import sqrt, atan, acos from sage.matrix.constructor import matrix from sage.modules.free_module_element import vector @@ -25,7 +20,6 @@ from sage.modules.free_module_element import vector pi = RDF.pi() - cdef class Transformation: def __init__(self, scale=(1,1,1), rot=None, diff --git a/src/sage/probability/random_variable.py b/src/sage/probability/random_variable.py index ff81388cd55..68d84e634a9 100644 --- a/src/sage/probability/random_variable.py +++ b/src/sage/probability/random_variable.py @@ -16,7 +16,8 @@ #***************************************************************************** from sage.structure.parent_base import ParentWithBase -from sage.misc.functional import sqrt, log +from sage.misc.functional import log +from sage.functions.all import sqrt from sage.rings.real_mpfr import (RealField, is_RealField) from sage.rings.rational_field import is_RationalField from sage.sets.set import Set @@ -364,4 +365,3 @@ def neg_xlog2x(p): return -p*log(p,2) p = self.function() return sum([ neg_xlog2x(p[x]) for x in p.keys() ]) - diff --git a/src/sage/quadratic_forms/quadratic_form.py b/src/sage/quadratic_forms/quadratic_form.py index 4e3b1545556..f50558421f0 100644 --- a/src/sage/quadratic_forms/quadratic_form.py +++ b/src/sage/quadratic_forms/quadratic_form.py @@ -30,9 +30,10 @@ from sage.matrix.matrix import is_Matrix from sage.rings.integer_ring import IntegerRing, ZZ from sage.rings.ring import Ring -from sage.misc.functional import ideal, denominator, is_even, is_field +from sage.misc.functional import denominator, is_even, is_field from sage.rings.arith import GCD, LCM from sage.rings.principal_ideal_domain import is_PrincipalIdealDomain +from sage.rings.all import Ideal from sage.rings.ring import is_Ring from sage.matrix.matrix import is_Matrix from sage.structure.sage_object import SageObject @@ -1440,7 +1441,7 @@ def level(self): else: inv_denoms += [denominator(mat_inv[i,j])] lvl = LCM(inv_denoms) - lvl = ideal(self.base_ring()(lvl)).gen() + lvl = Ideal(self.base_ring()(lvl)).gen() ############################################################## ## To do this properly, the level should be the inverse of the ## fractional ideal (over R) generated by the entries whose @@ -1492,7 +1493,7 @@ def level_ideal(self): ## denominators we take above. =) ############################################################## - return ideal(self.base_ring()(self.level())) + return Ideal(self.base_ring()(self.level())) def bilinear_map(self,v,w): r""" diff --git a/src/sage/quadratic_forms/quadratic_form__local_normal_form.py b/src/sage/quadratic_forms/quadratic_form__local_normal_form.py index e6a19751f11..acf5b88c7da 100644 --- a/src/sage/quadratic_forms/quadratic_form__local_normal_form.py +++ b/src/sage/quadratic_forms/quadratic_form__local_normal_form.py @@ -25,10 +25,6 @@ from sage.rings.arith import GCD, valuation, is_prime -#from sage.misc.functional import ideal ## TODO: This can probably be removed! - - - def find_entry_with_minimal_scale_at_prime(self, p): """ Finds the entry of the quadratic form with minimal scale at the diff --git a/src/sage/rings/all.py b/src/sage/rings/all.py index 9da2e4543e0..35aa1951026 100644 --- a/src/sage/rings/all.py +++ b/src/sage/rings/all.py @@ -40,6 +40,7 @@ # Ideals from ideal import Ideal +ideal = Ideal # Quotient from quotient_ring import QuotientRing diff --git a/src/sage/rings/polynomial/convolution.py b/src/sage/rings/polynomial/convolution.py index 38d771d18e6..5c4dd61515a 100644 --- a/src/sage/rings/polynomial/convolution.py +++ b/src/sage/rings/polynomial/convolution.py @@ -50,7 +50,7 @@ #***************************************************************************** -from sage.misc.functional import parent +from sage.structure.all import parent from math import log, ceil diff --git a/src/sage/rings/power_series_ring_element.pyx b/src/sage/rings/power_series_ring_element.pyx index 77ec5368ce6..02a01498d4a 100644 --- a/src/sage/rings/power_series_ring_element.pyx +++ b/src/sage/rings/power_series_ring_element.pyx @@ -109,8 +109,6 @@ import rational_field, integer_ring from integer import Integer from sage.rings.finite_rings.integer_mod_ring import IntegerModRing from sage.libs.pari.all import pari -from sage.misc.functional import sqrt, log -from sage.rings.arith import integer_ceil as ceil from sage.misc.superseded import deprecated_function_alias from sage.categories.fields import Fields diff --git a/src/sage/structure/all.py b/src/sage/structure/all.py index 834e61436ac..08e550cb45a 100644 --- a/src/sage/structure/all.py +++ b/src/sage/structure/all.py @@ -6,10 +6,11 @@ from sage_object import SageObject -from element import (\ +from element import ( canonical_coercion, get_coercion_model, - coercion_traceback + coercion_traceback, + parent ) from parent import Parent From d4349b3e9ce5d741c3fb6090ed58ebc9f43d9e7d Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Mon, 8 Dec 2014 14:12:30 +0000 Subject: [PATCH 261/698] Use fixed tarball for IML 1.0.4. --- build/pkgs/iml/SPKG.txt | 7 ++++--- build/pkgs/iml/checksums.ini | 6 +++--- build/pkgs/iml/package-version.txt | 2 +- build/pkgs/iml/spkg-install | 7 ++----- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/build/pkgs/iml/SPKG.txt b/build/pkgs/iml/SPKG.txt index b1bfe7438d1..88c3e68ab00 100644 --- a/build/pkgs/iml/SPKG.txt +++ b/build/pkgs/iml/SPKG.txt @@ -22,13 +22,14 @@ Website: http://www.cs.uwaterloo.ca/~astorjoh/iml.html * Arne Storjohann astorjoh@uwaterloo.ca == Dependencies == - * GMP/MPIR + * GMP * ATLAS == Special Update/Build Instructions == - * Various files should be made executable. Run spkg-src after - extracting the sources to src/ to fix this. + * As of version 1.0.4, you need to repackage the upstream tarball + using the spkg-src script because there was a bugfix version of 1.0.4 + reposted upstream without version number bump. === Patches === diff --git a/build/pkgs/iml/checksums.ini b/build/pkgs/iml/checksums.ini index a8b36a10f71..01b215549c7 100644 --- a/build/pkgs/iml/checksums.ini +++ b/build/pkgs/iml/checksums.ini @@ -1,4 +1,4 @@ tarball=iml-VERSION.tar.bz2 -sha1=713a19f1076ddde07a7c3a45493440b745bd266b -md5=b5958c8d6ba89fff96ee82af6854cf7d -cksum=3114321274 +sha1=72355b1f4c4df8cd3ecf5fcbcbd72c9ad9afdba7 +md5=362f1a6a1d2df0c5f0ab41e5d2c87ac7 +cksum=507867168 diff --git a/build/pkgs/iml/package-version.txt b/build/pkgs/iml/package-version.txt index ee90284c27f..03f0209fbb3 100644 --- a/build/pkgs/iml/package-version.txt +++ b/build/pkgs/iml/package-version.txt @@ -1 +1 @@ -1.0.4 +1.0.4p1 diff --git a/build/pkgs/iml/spkg-install b/build/pkgs/iml/spkg-install index 79406956469..5f6986599a0 100755 --- a/build/pkgs/iml/spkg-install +++ b/build/pkgs/iml/spkg-install @@ -31,15 +31,12 @@ if [ "$SAGE64" = "yes" ]; then CFLAGS="-m64 $CFLAGS" fi -EXTRA_BLAS="" if [ $UNAME = "Darwin" ]; then - # copy cblas headers from gsl - cp ../patches/gsl_cblas.h cblas.h - EXTRA_BLAS="--with-cblas=-lcblas" + IML_CONFIGURE="--with-cblas=-lcblas $IML_CONFIGURE" fi ./configure --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" \ - --enable-shared --with-default="$SAGE_LOCAL" "$EXTRA_BLAS" + --enable-shared --with-default="$SAGE_LOCAL" "$IML_CONFIGURE" if [ $? -ne 0 ]; then echo >&2 "Error configuring IML." exit 1 From 823c116a5e575ddcbadaba0075ac00fec245efba Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Mon, 8 Dec 2014 14:39:52 +0000 Subject: [PATCH 262/698] Mark test needing internet as optional. --- src/sage/combinat/quickref.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/quickref.py b/src/sage/combinat/quickref.py index c730fc6c397..f939e8ba945 100644 --- a/src/sage/combinat/quickref.py +++ b/src/sage/combinat/quickref.py @@ -6,7 +6,7 @@ sage: s = oeis([1,3,19,211]); s # optional - internet 0: A000275: Coefficients of a Bessel function (reciprocal of J_0(z)); also pairs of permutations with rise/rise forbidden. - sage: s[0].programs() + sage: s[0].programs() # optional - internet 0: (PARI) a(n)=if(n<0,0,n!^2*4^n*polcoeff(1/besselj(0,x+x*O(x^(2*n))),2*n)) /* _Michael Somos_, May 17 2004 */ Combinatorial objects:: @@ -59,7 +59,7 @@ :mod:`Symmetric functions and combinatorial Hopf algebras `:: sage: Sym = SymmetricFunctions(QQ); Sym.inject_shorthands() - doctest:...: RuntimeWarning: redefining global value `s` + ... doctest:...: RuntimeWarning: redefining global value `e` sage: m( ( h[2,1] * (1 + 3 * p[2,1]) ) + s[2](s[3]) ) 3*m[1, 1, 1] + ... + 10*m[5, 1] + 4*m[6] From 244fb547b4b061b85e8d3ebb645bf7f651bff658 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Mon, 8 Dec 2014 15:04:52 +0000 Subject: [PATCH 263/698] Add spkg-src file for IML 1.0.4. --- build/pkgs/iml/spkg-src | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100755 build/pkgs/iml/spkg-src diff --git a/build/pkgs/iml/spkg-src b/build/pkgs/iml/spkg-src new file mode 100755 index 00000000000..fc299e09315 --- /dev/null +++ b/build/pkgs/iml/spkg-src @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +VERSION="1.0.4" +PATCHLEVEL="p1" + +if [ $# -ne 0 ]; then + UPSTREAM_SOURCE_DIRECTORY=$1 + echo "Using tarballs from $UPSTREAM_SOURCE_DIRECTORY instead of downloading" +fi + +SPKG_ROOT=`pwd` + +set -e +shopt -s extglob + +# Download sources +URL="http://www.cs.uwaterloo.ca/~astorjoh/" +if [ -z "$UPSTREAM_SOURCE_DIRECTORY" ]; then + tar xjf <( curl -L "$URL/iml-$VERSION.tar.bz2" ) +else + tar xjf "$UPSTREAM_SOURCE_DIRECTORY/iml-$VERSION.tar.bz2" +fi + +mv "iml-$VERSION" "iml-$VERSION$PATCHLEVEL" +tar cjf "iml-$VERSION$PATCHLEVEL.tar.bz2" "iml-$VERSION$PATCHLEVEL" From 2683b013cf0ff86a1cb661f8650d16b86cc60179 Mon Sep 17 00:00:00 2001 From: Ben Hutz Date: Mon, 8 Dec 2014 10:58:46 -0500 Subject: [PATCH 264/698] 17433: fix projective points for quotient rings --- .../schemes/projective/projective_point.py | 132 ++++++++---------- 1 file changed, 62 insertions(+), 70 deletions(-) diff --git a/src/sage/schemes/projective/projective_point.py b/src/sage/schemes/projective/projective_point.py index 4c54016a6ad..0de11996201 100644 --- a/src/sage/schemes/projective/projective_point.py +++ b/src/sage/schemes/projective/projective_point.py @@ -120,7 +120,7 @@ def __init__(self, X, v, check=True): :: sage: P. = ProjectiveSpace(2, ZZ) - sage: X=P.subscheme([x^2-y*z]) + sage: X = P.subscheme([x^2-y*z]) sage: X([2,2,2]) (2 : 2 : 2) """ @@ -141,7 +141,7 @@ def __init__(self, X, v, check=True): R = X.value_ring() v = Sequence(v, R) if len(v) == d-1: # very common special case - v.append(1) + v.append(R(1)) n = len(v) all_zero = True @@ -155,12 +155,6 @@ def __init__(self, X, v, check=True): X.extended_codomain()._check_satisfies_equations(v) - if isinstance(X.codomain().base_ring(), QuotientRing_generic): - lift_coords = [P.lift() for P in v] - else: - lift_coords = v - v = Sequence(lift_coords) - self._coords = v def __eq__(self,right): @@ -243,6 +237,13 @@ def __eq__(self,right): sage: P==Q True + Check that :trac:`17433` is fixed :: + + sage: P. = ProjectiveSpace(Zmod(10), 1) + sage: p1 = P(1/3, 1) + sage: p2 = P.point([1, 3], False) + sage: p1 == p2 + True """ if not isinstance(right, SchemeMorphism_point): try: @@ -349,41 +350,38 @@ def scale_by(self,t): - ``t`` -- a ring element - OUTPUT: - - - None. + OUTPUT: None. EXAMPLES:: - sage: R.=PolynomialRing(QQ) - sage: P=ProjectiveSpace(R,2,'x') - sage: p=P([3/5*t^3,6*t, t]) + sage: R. = PolynomialRing(QQ) + sage: P = ProjectiveSpace(R, 2, 'x') + sage: p = P([3/5*t^3, 6*t, t]) sage: p.scale_by(1/t); p (3/5*t^2 : 6 : 1) :: - sage: R.=PolynomialRing(QQ) - sage: S=R.quo(R.ideal(t^3)) - sage: P.=ProjectiveSpace(S,2) - sage: Q=P(t,1,1) + sage: R. = PolynomialRing(QQ) + sage: S = R.quo(R.ideal(t^3)) + sage: P. = ProjectiveSpace(S, 2) + sage: Q = P(t,1,1) sage: Q.scale_by(t);Q (tbar^2 : tbar : tbar) :: - sage: P.=ProjectiveSpace(ZZ,2) - sage: Q=P(2,2,2) + sage: P. = ProjectiveSpace(ZZ,2) + sage: Q = P(2,2,2) sage: Q.scale_by(1/2);Q (1 : 1 : 1) """ - if t==0: #what if R(t) == 0 ? + R = self.codomain().base_ring() + if t == 0: raise ValueError("Cannot scale by 0") - R=self.codomain().base_ring() if isinstance(R, QuotientRing_generic): - phi=R._internal_coerce_map_from(self.codomain().ambient_space().base_ring()) for i in range(self.codomain().ambient_space().dimension_relative()+1): - self._coords[i]=phi(self._coords[i]*t).lift() + self._coords[i]=R(self._coords[i].lift()*t) else: for i in range(self.codomain().ambient_space().dimension_relative()+1): self._coords[i]=R(self._coords[i]*t) @@ -394,9 +392,7 @@ def normalize_coordinates(self): .. WARNING:: The gcd will depend on the base ring. - OUTPUT: - - - None. + OUTPUT: None. EXAMPLES:: @@ -423,21 +419,11 @@ def normalize_coordinates(self): :: sage: P. = ProjectiveSpace(Zmod(20),1) - sage: Q = P(4,8) + sage: Q = P(3,6) sage: Q.normalize_coordinates() sage: Q (1 : 2) - :: - - sage: R. = PolynomialRing(QQ,1) - sage: S = R.quotient_ring(R.ideal(t^3)) - sage: P. = ProjectiveSpace(S,1) - sage: Q = P(t,t^2) - sage: Q.normalize_coordinates() - sage: Q - (1 : t) - Since the base ring is a polynomial ring over a field, only the gcd `c` is removed. :: @@ -455,29 +441,35 @@ def normalize_coordinates(self): sage: Q.normalize_coordinates();Q (1 : 2) """ - R=self.codomain().base_ring() - GCD = R(gcd(self[0],self[1])) - index=2 - if self[0]>0 or self[1] >0: - neg=0 - else: - neg=1 - while GCD!=1 and index < len(self._coords): - if self[index]>0: - neg=0 - GCD=R(gcd(GCD,self[index])) - index+=1 + R = self.codomain().base_ring() if isinstance(R,(QuotientRing_generic)): - R=R.cover_ring() - GCD=GCD.lift() - if GCD != 1: - if neg==1: - self.scale_by(R(-1)/GCD) + GCD = gcd(self[0].lift(),self[1].lift()) + index = 2 + if self[0].lift() > 0 or self[1].lift() > 0: + neg = 1 else: - self.scale_by(R(1)/GCD) + neg = -1 + while GCD != 1 and index < len(self._coords): + if self[index].lift() > 0: + neg = 1 + GCD = gcd(GCD,self[index].lift()) + index += 1 else: - if neg==1: - self.scale_by(R(-1)) + GCD = R(gcd(self[0], self[1])) + index = 2 + if self[0] > 0 or self[1] > 0: + neg = R(1) + else: + neg = R(-1) + while GCD != 1 and index < len(self._coords): + if self[index] > 0: + neg = R(1) + GCD = R(gcd(GCD,self[index])) + index += 1 + if GCD != 1: + self.scale_by(neg/GCD) + elif neg == -1: + self.scale_by(neg) def dehomogenize(self,n): r""" @@ -1013,7 +1005,7 @@ def __init__(self, X, v, check=True): :: sage: P. = ProjectiveSpace(2, QQ) - sage: X=P.subscheme([x^2-y*z]) + sage: X = P.subscheme([x^2-y*z]) sage: X([2,2,2]) (1 : 1 : 1) """ @@ -1034,7 +1026,7 @@ def __init__(self, X, v, check=True): R = X.value_ring() v = Sequence(v, R) if len(v) == d-1: # very common special case - v.append(1) + v.append(R(1)) n = len(v) all_zero = True @@ -1064,24 +1056,24 @@ def normalize_coordinates(self): EXAMPLES:: - sage: P.=ProjectiveSpace(GF(5),2) - sage: Q=P.point([1,3,0],false);Q + sage: P. = ProjectiveSpace(GF(5),2) + sage: Q = P.point([GF(5)(1), GF(5)(3), GF(5)(0)], False); Q (1 : 3 : 0) - sage: Q.normalize_coordinates();Q + sage: Q.normalize_coordinates(); Q (2 : 1 : 0) :: - sage: P.=ProjectiveSpace(QQ,2) - sage: X=P.subscheme(x^2-y^2); - sage: Q=X.point([23,23,46], false);Q + sage: P. = ProjectiveSpace(QQ, 2) + sage: X =P.subscheme(x^2-y^2); + sage: Q = X.point([23, 23, 46], False); Q (23 : 23 : 46) - sage: Q.normalize_coordinates();Q + sage: Q.normalize_coordinates(); Q (1/2 : 1/2 : 1) """ - index=self.codomain().ambient_space().dimension_relative() - while self[index]==0: - index-=1 + index = self.codomain().ambient_space().dimension_relative() + while self[index] == 0: + index -= 1 self.scale_by(1/self[index]) From 41a5b454cb321fc8e5d8fc058b7be77bdf2c6522 Mon Sep 17 00:00:00 2001 From: Ben Hutz Date: Mon, 8 Dec 2014 11:06:20 -0500 Subject: [PATCH 265/698] 17433: add more examples --- .../schemes/projective/projective_point.py | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/projective/projective_point.py b/src/sage/schemes/projective/projective_point.py index 0de11996201..4c5c9e957fc 100644 --- a/src/sage/schemes/projective/projective_point.py +++ b/src/sage/schemes/projective/projective_point.py @@ -123,6 +123,13 @@ def __init__(self, X, v, check=True): sage: X = P.subscheme([x^2-y*z]) sage: X([2,2,2]) (2 : 2 : 2) + + :: + + sage: R.=PolynomialRing(ZZ) + sage: P = ProjectiveSpace(1, R.quo(t^2+1)) + sage: P([2*t, 1]) + (2*tbar : 1) """ SchemeMorphism.__init__(self, X) if check: @@ -376,9 +383,9 @@ def scale_by(self,t): sage: Q.scale_by(1/2);Q (1 : 1 : 1) """ - R = self.codomain().base_ring() - if t == 0: + if t == 0: #what if R(t) == 0 ? raise ValueError("Cannot scale by 0") + R = self.codomain().base_ring() if isinstance(R, QuotientRing_generic): for i in range(self.codomain().ambient_space().dimension_relative()+1): self._coords[i]=R(self._coords[i].lift()*t) @@ -440,6 +447,17 @@ def normalize_coordinates(self): sage: Q = P(2*c,4*c) sage: Q.normalize_coordinates();Q (1 : 2) + + :: + + + sage: R. = PolynomialRing(QQ,1) + sage: S = R.quotient_ring(R.ideal(t^3)) + sage: P. = ProjectiveSpace(S,1) + sage: Q = P(t,t^2) + sage: Q.normalize_coordinates() + sage: Q + (1 : tbar) """ R = self.codomain().base_ring() if isinstance(R,(QuotientRing_generic)): @@ -1008,6 +1026,13 @@ def __init__(self, X, v, check=True): sage: X = P.subscheme([x^2-y*z]) sage: X([2,2,2]) (1 : 1 : 1) + + :: + + sage: P = ProjectiveSpace(1, GF(7)) + sage: Q=P([2, 1]) + sage: Q[0].parent() + Finite Field of size 7 """ SchemeMorphism.__init__(self, X) if check: From 8e3e894f5f5fac85062f7c035eaf273ca782fa52 Mon Sep 17 00:00:00 2001 From: Ben Hutz Date: Mon, 8 Dec 2014 11:09:04 -0500 Subject: [PATCH 266/698] 17433: fixed some typos --- src/sage/schemes/projective/projective_point.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/schemes/projective/projective_point.py b/src/sage/schemes/projective/projective_point.py index 4c5c9e957fc..f23c46a3161 100644 --- a/src/sage/schemes/projective/projective_point.py +++ b/src/sage/schemes/projective/projective_point.py @@ -450,7 +450,6 @@ def normalize_coordinates(self): :: - sage: R. = PolynomialRing(QQ,1) sage: S = R.quotient_ring(R.ideal(t^3)) sage: P. = ProjectiveSpace(S,1) From e31bd9d8d25f72de0bb38cca70549e090040f38e Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Sat, 6 Dec 2014 15:34:36 +0530 Subject: [PATCH 267/698] Remove a keyword in clustering_coeff, deprecated in #12806 on 2012-07-08 --- src/sage/graphs/generic_graph.py | 69 ++------------------------------ 1 file changed, 4 insertions(+), 65 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 632464aaeae..76ddcf24dfd 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -12003,7 +12003,7 @@ def clustering_average(self): import networkx return networkx.average_clustering(self.networkx_graph(copy=False)) - def clustering_coeff(self, nodes=None, weight=False, return_vertex_weights=True): + def clustering_coeff(self, nodes=None, weight=False): r""" Returns the clustering coefficient for each vertex in ``nodes`` as a dictionary keyed by vertex. @@ -12031,10 +12031,6 @@ def clustering_coeff(self, nodes=None, weight=False, return_vertex_weights=True) a string it used the indicated edge property as weight. ``weight = True`` is equivalent to ``weight = 'weight'`` - - ``return_vertex_weights`` is a boolean ensuring backwards - compatibility with deprecated features of NetworkX 1.2. It - should be set to ``False`` for all production code. - EXAMPLES:: sage: (graphs.FruchtGraph()).clustering_coeff().values() @@ -12049,8 +12045,7 @@ def clustering_coeff(self, nodes=None, weight=False, return_vertex_weights=True) 7: 0.3333333333333333, 8: 0.0, 9: 0.3333333333333333, 10: 0.3333333333333333, 11: 0.0} - sage: (graphs.FruchtGraph()).clustering_coeff(weight=True, - ... return_vertex_weights=False) + sage: (graphs.FruchtGraph()).clustering_coeff(weight=True) {0: 0.3333333333333333, 1: 0.3333333333333333, 2: 0.0, 3: 0.3333333333333333, 4: 0.3333333333333333, 5: 0.3333333333333333, 6: 0.3333333333333333, @@ -12060,68 +12055,12 @@ def clustering_coeff(self, nodes=None, weight=False, return_vertex_weights=True) {0: 0.3333333333333333, 1: 0.3333333333333333, 2: 0.0} sage: (graphs.FruchtGraph()).clustering_coeff(nodes=[0,1,2], - ... weight=True, return_vertex_weights=False) + ... weight=True) {0: 0.3333333333333333, 1: 0.3333333333333333, 2: 0.0} - TESTS: - - Doctests that demonstrate the deprecation of the two-dictionary - return value due to the NetworkX API change after 1.2. The - return_vertex_weights keyword is provided with a default value - of True for backwards compatibility with older versions of Sage. - When the deprecation period has expired and the keyword is - removed, these doctests should be removed as well. :: - - sage: (graphs.FruchtGraph()).clustering_coeff(weight=True, - ... return_vertex_weights=True) - doctest:...: DeprecationWarning: The option 'return_vertex_weights' - has been deprecated. Only offered for backwards compatibility with - NetworkX 1.2. - See http://trac.sagemath.org/12806 for details. - ({0: 0.3333333333333333, 1: 0.3333333333333333, 2: 0.0, - 3: 0.3333333333333333, 4: 0.3333333333333333, - 5: 0.3333333333333333, 6: 0.3333333333333333, - 7: 0.3333333333333333, 8: 0.0, 9: 0.3333333333333333, - 10: 0.3333333333333333, 11: 0.0}, {0: 0.08333333333333333, - 1: 0.08333333333333333, 2: 0.08333333333333333, - 3: 0.08333333333333333, 4: 0.08333333333333333, - 5: 0.08333333333333333, 6: 0.08333333333333333, - 7: 0.08333333333333333, 8: 0.08333333333333333, - 9: 0.08333333333333333, 10: 0.08333333333333333, - 11: 0.08333333333333333}) - - sage: (graphs.FruchtGraph()).clustering_coeff(nodes=[0, 1, 2], - ... weight=True, return_vertex_weights=True) - ({0: 0.3333333333333333, 1: 0.3333333333333333, 2: 0.0}, - {0: 0.3333333333333333, 1: 0.3333333333333333, - 2: 0.3333333333333333}) """ import networkx - if weight and return_vertex_weights: - # Running in compatibility mode with deprecated NetworkX 1.2 features - # All this code should be removed when the deprecation warning expires - from sage.misc.superseded import deprecation - deprecation(12806, "The option 'return_vertex_weights' has been " +\ - "deprecated. Only offered for backwards" +\ - " compatibility with NetworkX 1.2.") - G = self.networkx_graph(copy=False) - if G.is_directed(): - raise NetworkXError("Clustering algorithms are not defined for directed graphs.") - clusterc={} - weights={} - for v,d,t in networkx.cluster._triangles_and_degree_iter(G,nodes): - weights[v]=float(d*(d-1)) - if t==0: - clusterc[v]=0.0 - else: - clusterc[v]=t/float(d*(d-1)) - scale=1./sum(weights.itervalues()) - for v,w in weights.iteritems(): - weights[v]=w*scale - return clusterc,weights - - else: - return networkx.clustering(self.networkx_graph(copy=False), nodes, weight=weight) + return networkx.clustering(self.networkx_graph(copy=False), nodes, weight=weight) def cluster_transitivity(self): r""" From cfe6962f7644a76158c839f1e9f7d4ddcd9e494e Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Sat, 6 Dec 2014 15:37:06 +0530 Subject: [PATCH 268/698] Remove keyword "deg_seq" deprecated in #11927 on 2012-12-24 --- src/sage/graphs/graph_generators.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/sage/graphs/graph_generators.py b/src/sage/graphs/graph_generators.py index b6c4df81ba6..753b83e6c18 100644 --- a/src/sage/graphs/graph_generators.py +++ b/src/sage/graphs/graph_generators.py @@ -623,7 +623,7 @@ class GraphGenerators(): ########################################################################### def __call__(self, vertices=None, property=lambda x: True, augment='edges', - size=None, deg_seq=None, degree_sequence=None, loops=False, implementation='c_graph', + size=None, degree_sequence=None, loops=False, implementation='c_graph', sparse=True, copy = True): """ Accesses the generator of isomorphism class representatives. @@ -673,12 +673,6 @@ def __call__(self, vertices=None, property=lambda x: True, augment='edges', from sage.misc.superseded import deprecation from copy import copy as copyfun - if deg_seq is not None: - deprecation(11927, "The argument name deg_seq is deprecated. It will be " - "removed in a future release of Sage. So, please use " - "degree_sequence instead.") - if degree_sequence is None: - degree_sequence=deg_seq if degree_sequence is not None: if vertices is None: raise NotImplementedError From 6836c88366f7b7cc62b03d81d305d05f940fb6fe Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Sat, 6 Dec 2014 15:39:46 +0530 Subject: [PATCH 269/698] Remove RandomInterval deprecated in #13283 on 2013-07-29 --- src/sage/graphs/generators/random.py | 14 -------------- src/sage/graphs/graph_generators.py | 1 - 2 files changed, 15 deletions(-) diff --git a/src/sage/graphs/generators/random.py b/src/sage/graphs/generators/random.py index 5dbf44f8931..9656217b7f3 100644 --- a/src/sage/graphs/generators/random.py +++ b/src/sage/graphs/generators/random.py @@ -440,20 +440,6 @@ def RandomHolmeKim(n, m, p, seed=None): import networkx return Graph(networkx.powerlaw_cluster_graph(n, m, p, seed=seed)) -def RandomInterval(n): - """ - :meth:`RandomInterval` is deprecated. Use :meth:`RandomIntervalGraph` instead. - - TEST:: - - sage: g = graphs.RandomInterval(8) - doctest:...: DeprecationWarning: RandomInterval() is deprecated. Use RandomIntervalGraph() instead. - See http://trac.sagemath.org/13283 for details. - """ - from sage.misc.superseded import deprecation - deprecation(13283, "RandomInterval() is deprecated. Use RandomIntervalGraph() instead.") - return RandomIntervalGraph(n) - def RandomIntervalGraph(n): """ Returns a random interval graph. diff --git a/src/sage/graphs/graph_generators.py b/src/sage/graphs/graph_generators.py index 753b83e6c18..59cd006d387 100644 --- a/src/sage/graphs/graph_generators.py +++ b/src/sage/graphs/graph_generators.py @@ -1902,7 +1902,6 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None RandomGNM = staticmethod(sage.graphs.generators.random.RandomGNM) RandomGNP = staticmethod(sage.graphs.generators.random.RandomGNP) RandomHolmeKim = staticmethod(sage.graphs.generators.random.RandomHolmeKim) - RandomInterval = staticmethod(sage.graphs.generators.random.RandomInterval) # deprecated RandomIntervalGraph = staticmethod(sage.graphs.generators.random.RandomIntervalGraph) RandomLobster = staticmethod(sage.graphs.generators.random.RandomLobster) RandomNewmanWattsStrogatz = staticmethod(sage.graphs.generators.random.RandomNewmanWattsStrogatz) From 3a247a636f753b63620acd8ec449fb5d73c30816 Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Sat, 6 Dec 2014 16:16:31 +0530 Subject: [PATCH 270/698] Removed deprecated function aliases, added in #15551 on 2013-12-19 --- src/sage/graphs/generic_graph.py | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 76ddcf24dfd..54d2811217b 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -1913,13 +1913,6 @@ def _check_embedding_validity(self, embedding=None): sage: G._check_embedding_validity(d) True - TESTS:: - - sage: G.check_embedding_validity(d) - doctest:...: DeprecationWarning: check_embedding_validity is deprecated. Please use _check_embedding_validity instead. - See http://trac.sagemath.org/15551 for details. - True - """ if embedding is None: embedding = getattr(self, '_embedding', None) @@ -1941,8 +1934,6 @@ def _check_embedding_validity(self, embedding=None): return False return True - check_embedding_validity = deprecated_function_alias(15551, _check_embedding_validity) - def has_loops(self): """ Returns whether there are loops in the (di)graph. @@ -2493,13 +2484,6 @@ def _check_pos_validity(self, pos=None, dim = 2): sage: G = graphs.PetersenGraph() sage: G._check_pos_validity(p) True - - TESTS:: - - sage: G.check_pos_validity(p) - doctest:...: DeprecationWarning: check_pos_validity is deprecated. Please use _check_pos_validity instead. - See http://trac.sagemath.org/15551 for details. - True """ if pos is None: pos = self.get_pos(dim = dim) @@ -2514,8 +2498,6 @@ def _check_pos_validity(self, pos=None, dim = 2): return False return True - check_pos_validity = deprecated_function_alias(15551,_check_pos_validity) - def set_pos(self, pos, dim = 2): """ Sets the position dictionary, a dictionary specifying the @@ -4257,16 +4239,6 @@ def faces(self, embedding = None): Traceback (most recent call last): ... ValueError: No embedding is provided and the graph is not planar. - - TESTS: - - :trac:`15551` deprecated the ``trace_faces`` name:: - - sage: T.trace_faces({0: [1, 3, 2], 1: [0, 2, 3], 2: [0, 3, 1], 3: [0, 1, 2]}) - doctest:...: DeprecationWarning: trace_faces is deprecated. Please use faces instead. - See http://trac.sagemath.org/15551 for details. - [[(0, 1), (1, 2), (2, 0)], [(3, 2), (2, 1), (1, 3)], [(2, 3), (3, 0), (0, 2)], [(0, 3), (3, 1), (1, 0)]] - """ # Which embedding should we use ? if embedding is None: @@ -4313,8 +4285,6 @@ def faces(self, embedding = None): if (len(path) != 0): faces.append(path) return faces - trace_faces = deprecated_function_alias(15551, faces) - ### Connectivity def is_connected(self): From 7aeb12eea45eb1895bec6ddb283dabea12d09a62 Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Sat, 6 Dec 2014 16:18:44 +0530 Subject: [PATCH 271/698] Removed deprecated imports into the global namespace, added in #14499 on 2013-05-02 --- src/sage/combinat/designs/all.py | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/sage/combinat/designs/all.py b/src/sage/combinat/designs/all.py index fc3b63f2563..6d429f67d71 100644 --- a/src/sage/combinat/designs/all.py +++ b/src/sage/combinat/designs/all.py @@ -13,29 +13,6 @@ import design_catalog as designs -from sage.misc.superseded import deprecated_callable_import -deprecated_callable_import(14499, - 'sage.combinat.designs.block_design', - globals(), - locals(), - ["ProjectiveGeometryDesign", - "AffineGeometryDesign", - "WittDesign", - "HadamardDesign"], - ("This method soon will not be available in that " - "way anymore. To use it, you can now call it by " - "typing designs.%(name)s")) -deprecated_callable_import(14499, - 'sage.combinat.designs.covering_design', - globals(), - locals(), - ["best_known_covering_design_www"], - ("This method soon will not be available in that " - "way anymore. To use it, you can now call it by " - "typing designs.best_known_covering_design_from_LJCR")) - -del deprecated_callable_import - import sage.combinat.designs.steiner_quadruple_systems import sage.combinat.designs.orthogonal_arrays import sage.combinat.designs.latin_squares From 8f9e5ca89395a7ed0969ef9651915ec13cfc999a Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Sat, 6 Dec 2014 16:20:39 +0530 Subject: [PATCH 272/698] Removed Sum function deprecated in #13646 on 2012-10-30 --- src/sage/numerical/mip.pyx | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/sage/numerical/mip.pyx b/src/sage/numerical/mip.pyx index 04fb6c6eab2..ec13eea7026 100644 --- a/src/sage/numerical/mip.pyx +++ b/src/sage/numerical/mip.pyx @@ -2837,26 +2837,3 @@ cdef class MIPVariableParent(Parent): mip_variable_parent = MIPVariableParent() - -def Sum(x): - """ - Only for legacy support, use :meth:`MixedIntegerLinearProgram.sum` instead. - - EXAMPLES:: - - sage: from sage.numerical.mip import Sum - sage: Sum([]) - doctest:...: DeprecationWarning: use MixedIntegerLinearProgram.sum() instead - See http://trac.sagemath.org/13646 for details. - - sage: p = MixedIntegerLinearProgram() - sage: x = p.new_variable(nonnegative=True) - sage: Sum([ x[0]+x[1], x[1]+x[2], x[2]+x[3] ]) # deprecation is only shown once - x_0 + 2*x_1 + 2*x_2 + x_3 - """ - from sage.misc.superseded import deprecation - deprecation(13646, 'use MixedIntegerLinearProgram.sum() instead') - if not x: - return None - parent = x[0].parent() - return parent.sum(x) From bcca4ed797ced93bbc3651f535c333b85dd0e420 Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Mon, 8 Dec 2014 09:02:40 +0530 Subject: [PATCH 273/698] Removed group() function deprecated in #11360 on 2011-08-03 --- src/sage/groups/perm_gps/cubegroup.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/sage/groups/perm_gps/cubegroup.py b/src/sage/groups/perm_gps/cubegroup.py index e636880c934..49a7a3b69e3 100644 --- a/src/sage/groups/perm_gps/cubegroup.py +++ b/src/sage/groups/perm_gps/cubegroup.py @@ -565,21 +565,6 @@ def __repr__(self): """ return "The Rubik's cube group with generators R,L,F,B,U,D in SymmetricGroup(48)." - def group(self): - r""" - This is deprecated in trac:`11360`. Use the :class:`CubeGroup` instead. - - EXAMPLES:: - - sage: CubeGroup().group() - doctest:...: DeprecationWarning: group() is deprecated. Use the CubeGroup instead. - See http://trac.sagemath.org/11360 for details. - The Rubik's cube group with generators R,L,F,B,U,D in SymmetricGroup(48). - """ - from sage.misc.superseded import deprecation - deprecation(11360, 'group() is deprecated. Use the CubeGroup instead.') - return self - def B(self): """ Return the generator `B` in Singmaster notation. From 10106e33f752ff5b8e3020043ec68105be7b15f6 Mon Sep 17 00:00:00 2001 From: Nathann Cohen Date: Mon, 8 Dec 2014 09:04:17 +0530 Subject: [PATCH 274/698] Removed field_of_definition and base_field deprecated in #14014 on 2013-05-02 --- src/sage/groups/matrix_gps/matrix_group.py | 40 ---------------------- 1 file changed, 40 deletions(-) diff --git a/src/sage/groups/matrix_gps/matrix_group.py b/src/sage/groups/matrix_gps/matrix_group.py index b0185ea01ce..90515237962 100644 --- a/src/sage/groups/matrix_gps/matrix_group.py +++ b/src/sage/groups/matrix_gps/matrix_group.py @@ -167,46 +167,6 @@ def as_matrix_group(self): from sage.groups.matrix_gps.finitely_generated import MatrixGroup return MatrixGroup(self.gens()) - def field_of_definition(self, **kwds): - """ - Return a field that contains all the matrices in this matrix - group. - - EXAMPLES:: - - sage: G = SU(3,GF(5)) - sage: G.base_ring() - Finite Field in a of size 5^2 - sage: G.field_of_definition() - doctest:...: DeprecationWarning: Use base_ring() instead. - See http://trac.sagemath.org/14014 for details. - Finite Field in a of size 5^2 - sage: G = GO(4,GF(7),1) - sage: G.field_of_definition() - Finite Field of size 7 - sage: G.base_ring() - Finite Field of size 7 - """ - from sage.misc.superseded import deprecation - deprecation(14014, 'Use base_ring() instead.') - return self.base_ring() - - def base_field(self): - """ - Deprecated alias of :meth:`base_ring` - - EXAMPLES:: - - sage: G = SU(3,GF(5)) - sage: G.base_field() - doctest:...: DeprecationWarning: Use base_ring() instead. - See http://trac.sagemath.org/14014 for details. - Finite Field in a of size 5^2 - """ - from sage.misc.superseded import deprecation - deprecation(14014, 'Use base_ring() instead.') - return self.base_ring() - def _repr_(self): """ Return a string representation. From 4d6c87e5d2ba91cb16156f0dfb266180e0af9e2f Mon Sep 17 00:00:00 2001 From: Ben Hutz Date: Mon, 8 Dec 2014 13:54:10 -0500 Subject: [PATCH 275/698] 17427: adjusted formatting and added comments --- .../schemes/projective/projective_point.py | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/sage/schemes/projective/projective_point.py b/src/sage/schemes/projective/projective_point.py index 6f94616aab5..e373c7d8da4 100644 --- a/src/sage/schemes/projective/projective_point.py +++ b/src/sage/schemes/projective/projective_point.py @@ -344,13 +344,16 @@ def __ne__(self,right): def __hash__(self): """ - Computes the hash value of ``self``. + Computes the hash value of ``self``. If the base ring has a fraction + field, normalize the point in the fraction field and then hash so + that equal points have equal hash values. If the base ring is not + an integral domain, return the hash of the parent. OUTPUT: Integer. EXAMPLES:: - sage: P.=ProjectiveSpace(ZZ,1) + sage: P. = ProjectiveSpace(ZZ, 1) sage: hash(P([1,1])) 7316841028997809016 # 64-bit sage: hash(P.point([2,2], False)) @@ -358,18 +361,18 @@ def __hash__(self): :: - sage: R.=PolynomialRing(QQ) - sage: K.=NumberField(x^2+3) - sage: O=K.maximal_order() - sage: P.=ProjectiveSpace(O,1) - sage: hash(P([1+w,2])) + sage: R. = PolynomialRing(QQ) + sage: K. = NumberField(x^2 + 3) + sage: O = K.maximal_order() + sage: P. = ProjectiveSpace(O, 1) + sage: hash(P([1+w, 2])) 4801154424156762579 # 64-bit - sage: hash(P([2,1-w])) + sage: hash(P([2, 1-w])) 4801154424156762579 # 64-bit :: - sage: P.=ProjectiveSpace(Zmod(10), 1) + sage: P. = ProjectiveSpace(Zmod(10), 1) sage: hash(P([2,5])) 4677413289753502123 # 64-bit """ @@ -1108,10 +1111,10 @@ def __hash__(self): EXAMPLES:: - sage: P.=ProjectiveSpace(QQ, 1) - sage: hash(P([1/2,1])) + sage: P. = ProjectiveSpace(QQ, 1) + sage: hash(P([1/2, 1])) 3714374126286711103 # 64-bit - sage: hash(P.point([1,2], False)) + sage: hash(P.point([1, 2], False)) 3714374126286711103 # 64-bit """ P = copy(self) @@ -1186,38 +1189,35 @@ def __hash__(self): r""" Returns the integer hash of ``self`` - - OUTPUT: - - - integer + OUTPUT: Integer. EXAMPLES:: - sage: P.=ProjectiveSpace(GF(5),2) + sage: P. = ProjectiveSpace(GF(5), 2) sage: hash(P(2,1,2)) 41 :: - sage: P.=ProjectiveSpace(GF(7),2) - sage: X=P.subscheme(x^2-y^2) - sage: hash(X(1,1,2)) + sage: P. = ProjectiveSpace(GF(7), 2) + sage: X = P.subscheme(x^2 - y^2) + sage: hash(X(1, 1, 2)) 81 :: - sage: P.=ProjectiveSpace(GF(13),1) + sage: P. = ProjectiveSpace(GF(13), 1) sage: hash(P(3,4)) 17 :: - sage: P.=ProjectiveSpace(GF(13^3,'t'),1) + sage: P. = ProjectiveSpace(GF(13^3,'t'), 1) sage: hash(P(3,4)) 2201 """ - p=self.codomain().base_ring().order() - N=self.codomain().ambient_space().dimension_relative() + p = self.codomain().base_ring().order() + N = self.codomain().ambient_space().dimension_relative() return sum(hash(self[i])*p**i for i in range(N+1)) def orbit_structure(self,f): From c8fe21c4d1fb3bb4b6d3916800e216bdc8b7f6ef Mon Sep 17 00:00:00 2001 From: Clemens Heuberger Date: Mon, 8 Dec 2014 20:26:41 +0100 Subject: [PATCH 276/698] Trac #17471: finite_state_machine: Improve documentation of LaTeX output Add a link from the TOC to the introductory remarks on LaTeX output. In the introductory remarks on LaTeX output, add a remark which packages have to be loaded when using the output in a LaTeX file. --- src/sage/combinat/finite_state_machine.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/sage/combinat/finite_state_machine.py b/src/sage/combinat/finite_state_machine.py index 5552d354404..552f7a460b4 100644 --- a/src/sage/combinat/finite_state_machine.py +++ b/src/sage/combinat/finite_state_machine.py @@ -175,6 +175,10 @@ :meth:`~FiniteStateMachine.format_letter_negative` | Format negative numbers as overlined number :meth:`~FiniteStateMachine.format_transition_label_reversed` | Format words in transition labels in reversed order +.. SEEALSO:: + + :ref:`finite_state_machine_LaTeX_output` + :class:`FSMState` ----------------- @@ -412,6 +416,16 @@ \end{tikzpicture} sage: view(NAF) # not tested +To use the output of :func:`~sage.misc.latex.latex` in your own +`\LaTeX` file, you have to include + +.. code-block:: latex + + \usepackage{tikz} + \usetikzlibrary{automata} + +into the preamble of your file. + A simple transducer (binary inverter) ------------------------------------- From b6699929d45a09eb233f61e7e9c1b2c57f7cdf1c Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Mon, 8 Dec 2014 21:23:59 +0100 Subject: [PATCH 277/698] Trac 17359: fix Hom sets for schemes and Hecke modules --- src/sage/categories/hecke_modules.py | 20 ++++++++++++++++---- src/sage/categories/schemes.py | 15 +++++---------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/sage/categories/hecke_modules.py b/src/sage/categories/hecke_modules.py index a1c12a3f02b..3f97096e1d0 100644 --- a/src/sage/categories/hecke_modules.py +++ b/src/sage/categories/hecke_modules.py @@ -152,12 +152,9 @@ def _Hom_(self, Y, category): class Homsets(HomsetsCategory): """ - .. TODO:: shall there be any additional category structure on Homsets of hecke modules? - TESTS:: - sage: HeckeModules(ZZ).Homsets().super_categories() - [Category of homsets] + sage: TestSuite(HeckeModules(ZZ).Homsets()).run() """ def base_ring(self): @@ -169,5 +166,20 @@ def base_ring(self): """ return self.base_category().base_ring() + def extra_super_categories(self): + """ + TESTS: + + Check that Hom sets of Hecke modules are in the correct + category (see :trac:`17359`):: + + sage: HeckeModules(ZZ).Homsets().super_categories() + [Category of modules over Integer Ring, Category of homsets] + sage: HeckeModules(QQ).Homsets().super_categories() + [Category of vector spaces over Rational Field, Category of homsets] + """ + from sage.categories.modules import Modules + return [Modules(self.base_ring())] + class ParentMethods: pass diff --git a/src/sage/categories/schemes.py b/src/sage/categories/schemes.py index dd5ace46f21..5229fa4ae13 100644 --- a/src/sage/categories/schemes.py +++ b/src/sage/categories/schemes.py @@ -44,6 +44,11 @@ class Schemes(Category): TESTS:: sage: TestSuite(Schemes()).run() + + Check that Hom sets of schemes are in the correct category:: + + sage: Schemes().Homsets().super_categories() + [Category of homsets] """ @staticmethod @@ -145,16 +150,6 @@ def _call_(self, x): raise TypeError("No way to create an object or morphism in %s from %s"%(self, x)) - class Homsets(HomsetsCategory): - """ - TESTS:: - - sage: Schemes().Homsets().super_categories() - [Category of homsets] - - .. TODO:: shall there be any additional category structure on Homsets of hecke modules? - """ - ############################################################# # Schemes over a given base scheme. ############################################################# From 1b42461939b33aa604e47449449ff12d145bf9f4 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Mon, 8 Dec 2014 23:32:59 +0100 Subject: [PATCH 278/698] Trac 16507: use new multi-line doctest continuations --- src/sage/categories/pushout.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/sage/categories/pushout.py b/src/sage/categories/pushout.py index f2fc0b644f2..bcbe4ba554e 100644 --- a/src/sage/categories/pushout.py +++ b/src/sage/categories/pushout.py @@ -3171,24 +3171,24 @@ def pushout(R, S): sage: from sage.categories.pushout import ConstructionFunctor sage: class EvenPolynomialRing(type(QQ['x'])): - ... def __init__(self, base, var): - ... super(EvenPolynomialRing, self).__init__(base, var) - ... self.register_embedding(base[var]) - ... def __repr__(self): - ... return "Even Power " + super(EvenPolynomialRing, self).__repr__() - ... def construction(self): - ... return EvenPolynomialFunctor(), self.base()[self.variable_name()] - ... def _coerce_map_from_(self, R): - ... return self.base().has_coerce_map_from(R) - ... + ....: def __init__(self, base, var): + ....: super(EvenPolynomialRing, self).__init__(base, var) + ....: self.register_embedding(base[var]) + ....: def __repr__(self): + ....: return "Even Power " + super(EvenPolynomialRing, self).__repr__() + ....: def construction(self): + ....: return EvenPolynomialFunctor(), self.base()[self.variable_name()] + ....: def _coerce_map_from_(self, R): + ....: return self.base().has_coerce_map_from(R) + ....: sage: class EvenPolynomialFunctor(ConstructionFunctor): - ... rank = 10 - ... coercion_reversed = True - ... def __init__(self): - ... ConstructionFunctor.__init__(self, Rings(), Rings()) - ... def __call__(self, R): - ... return EvenPolynomialRing(R.base(), R.variable_name()) - ... + ....: rank = 10 + ....: coercion_reversed = True + ....: def __init__(self): + ....: ConstructionFunctor.__init__(self, Rings(), Rings()) + ....: def __call__(self, R): + ....: return EvenPolynomialRing(R.base(), R.variable_name()) + ....: sage: pushout(EvenPolynomialRing(QQ, 'x'), ZZ) Even Power Univariate Polynomial Ring in x over Rational Field sage: pushout(EvenPolynomialRing(QQ, 'x'), QQ) From 1ef05f2ef4aa238041f82aef54bc0c17003a35b4 Mon Sep 17 00:00:00 2001 From: Peter Bruin Date: Mon, 8 Dec 2014 23:54:58 +0100 Subject: [PATCH 279/698] Trac 16507: documentation improvements --- src/sage/categories/pushout.py | 92 +++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 41 deletions(-) diff --git a/src/sage/categories/pushout.py b/src/sage/categories/pushout.py index bcbe4ba554e..d0102357cbf 100644 --- a/src/sage/categories/pushout.py +++ b/src/sage/categories/pushout.py @@ -91,12 +91,13 @@ class ConstructionFunctor(Functor): """ def __mul__(self, other): """ - Compose construction functors to a composit construction functor, unless one of them is the identity. + Compose ``self`` and ``other`` to a composite construction + functor, unless one of them is the identity. NOTE: - The product is in functorial notation, i.e., when applying the product to an object - then the second factor is applied first. + The product is in functorial notation, i.e., when applying the + product to an object, the second factor is applied first. TESTS:: @@ -286,11 +287,7 @@ def expand(self): """ return [self] - # The pushout function below assumes that if F is a construction - # applied to an object X, then F(X) admits a coercion map from X. - # In derived classes, the following attribute should be set to - # True if F(X) has a coercion map _to_ X instead. This is - # currently used for the subspace construction. + # See the pushout() function below for explanation. coercion_reversed = False @@ -3072,48 +3069,53 @@ def __cmp__(self, other): def pushout(R, S): r""" - Given a pair of Objects R and S, try and construct a - reasonable object Y and return maps such that - canonically $R \leftarrow Y \rightarrow S$. + Given a pair of objects `R` and `S`, try to construct a + reasonable object `Y` and return maps such that + canonically `R \leftarrow Y \rightarrow S`. ALGORITHM: - This incorporates the idea of functors discussed Sage Days 4. - Every object R can be viewed as an initial object and - a series of functors (e.g. polynomial, quotient, extension, - completion, vector/matrix, etc.). Call the series of - increasingly-simple rings (with the associated functors) - the "tower" of R. The construction method is used to - create the tower. + This incorporates the idea of functors discussed at Sage Days 4. + Every object `R` can be viewed as an initial object and a series + of functors (e.g. polynomial, quotient, extension, completion, + vector/matrix, etc.). Call the series of increasingly simple + objects (with the associated functors) the "tower" of `R`. The + construction method is used to create the tower. - Given two objects R and S, try and find a common initial - object Z. If the towers of R and S meet, let Z be their - join. Otherwise, see if the top of one coerces naturally into - the other. + Given two objects `R` and `S`, try to find a common initial object + `Z`. If the towers of `R` and `S` meet, let `Z` be their join. + Otherwise, see if the top of one coerces naturally into the other. - Now we have an initial object and two ordered lists of - functors to apply. We wish to merge these in an unambiguous order, - popping elements off the top of one or the other tower as we - apply them to Z. + Now we have an initial object and two ordered lists of functors to + apply. We wish to merge these in an unambiguous order, popping + elements off the top of one or the other tower as we apply them to + `Z`. - - If the functors are distinct types, there is an absolute ordering - given by the rank attribute. Use this. + - If the functors are of distinct types, there is an absolute + ordering given by the rank attribute. Use this. - Otherwise: - If the tops are equal, we (try to) merge them. - - If exactly one occurs lower in the other tower - we may unambiguously apply the other (hoping for a later merge). + - If exactly one occurs lower in the other tower, we may + unambiguously apply the other (hoping for a later merge). - If the tops commute, we can apply either first. - Otherwise fail due to ambiguity. + The algorithm assumes by default that when a construction `F` is + applied to an object `X`, the object `F(X)` admits a coercion map + from `X`. However, the algorithm can also handle the case where + `F(X)` has a coercion map *to* `X` instead. In this case, the + attribute ``coercion_reversed`` of the class implementing `F` + should be set to ``True``. + EXAMPLES: - Here our "towers" are $R = Complete_7(Frac(\ZZ))$ and $Frac(Poly_x(\ZZ))$, - which give us $Frac(Poly_x(Complete_7(Frac(\ZZ))))$:: + Here our "towers" are `R = Complete_7(Frac(\ZZ))` and `Frac(Poly_x(\ZZ))`, + which give us `Frac(Poly_x(Complete_7(Frac(\ZZ))))`:: sage: from sage.categories.pushout import pushout sage: pushout(Qp(7), Frac(ZZ['x'])) @@ -3156,6 +3158,14 @@ def pushout(R, S): the :class:`SubspaceFunctor` construction) is only applied if it leads to a valid coercion:: + sage: A = ZZ^2 + sage: V = span([[1, 2]], QQ) + sage: P = sage.categories.pushout.pushout(A, V) + sage: P + Vector space of dimension 2 over Rational Field + sage: P.has_coerce_map_from(A) + True + sage: V = (QQ^3).span([[1, 2, 3/4]]) sage: A = ZZ^3 sage: pushout(A, V) @@ -3355,18 +3365,18 @@ def apply_from(Xc): def pushout_lattice(R, S): r""" - Given a pair of Objects $R$ and $S$, try and construct a - reasonable object $Y$ and return maps such that - canonically $R \leftarrow Y \rightarrow S$. + Given a pair of objects `R` and `S`, try to construct a + reasonable object `Y` and return maps such that + canonically `R \leftarrow Y \rightarrow S`. ALGORITHM: - This is based on the model that arose from much discussion at Sage Days 4. - Going up the tower of constructions of $R$ and $S$ (e.g. the reals - come from the rationals come from the integers) try and find a - common parent, and then try and fill in a lattice with these - two towers as sides with the top as the common ancestor and - the bottom will be the desired ring. + This is based on the model that arose from much discussion at + Sage Days 4. Going up the tower of constructions of `R` and `S` + (e.g. the reals come from the rationals come from the integers), + try to find a common parent, and then try to fill in a lattice + with these two towers as sides with the top as the common ancestor + and the bottom will be the desired ring. See the code for a specific worked-out example. From cc7fe0a9f49ded047e5d2ed8c2cbe57b8dbace1c Mon Sep 17 00:00:00 2001 From: Karl-Dieter Crisman Date: Mon, 8 Dec 2014 21:06:18 -0500 Subject: [PATCH 280/698] More doctests for #7401 --- src/sage/symbolic/expression_conversions.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/sage/symbolic/expression_conversions.py b/src/sage/symbolic/expression_conversions.py index d09f9fc2c4d..90e14c2d32e 100644 --- a/src/sage/symbolic/expression_conversions.py +++ b/src/sage/symbolic/expression_conversions.py @@ -531,19 +531,29 @@ def derivative(self, ex, operator): sage: b.sage() D[0](f)(4) - It also works with more than one variable:: + It also works with more than one variable. Note the preferred + syntax ``function('f')(x,y)`` to create a general symbolic function + of more than one variable:: sage: x,y,=var('x y') - sage: a = function('f', x, y).diff(x).subs(x=4).subs(y=8) + sage: a = function('f')(x, y).diff(x).subs(x=4).subs(y=8) sage: b=maxima(a); b %at('diff('f(_SAGE_VAR_t0,_SAGE_VAR_t1),_SAGE_VAR_t0,1),[_SAGE_VAR_t0=4,_SAGE_VAR_t1=8]) sage: b.sage() D[0](f)(4, 8) + :: + + sage: a = function('f')(x,y).diff(x) + sage: a + D[0](f)(x, y) + sage: maxima(a) + 'diff('f(_SAGE_VAR_x,_SAGE_VAR_y),_SAGE_VAR_x,1) + :: sage: x,y,=var('x y') - sage: a = function('f', x, y).diff(x).subs(x=4) + sage: a = function('f')(x, y).diff(x).subs(x=4) sage: b=maxima(a); b %at('diff('f(_SAGE_VAR_t0,_SAGE_VAR_t1),_SAGE_VAR_t0,1),[_SAGE_VAR_t0=4,_SAGE_VAR_t1=_SAGE_VAR_y]) sage: b.sage() From fa984b9e53f8ed73330a173e27a2c0bf1fdba7d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 9 Dec 2014 09:38:42 +0100 Subject: [PATCH 281/698] trac #17xxx adding a method vertex_digraph to polyhedra --- src/sage/geometry/polyhedron/base.py | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index 1896d7a0a93..edf6ade4c25 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -3278,6 +3278,38 @@ def vertex_graph(self): graph = vertex_graph + @cached_method + def vertex_digraph(self, f): + """ + Return the directed graph of the polyhedron according to a linear form. + + The underlying undirected graph is the graph of vertices and edges. + + INPUT: + + - `f` -- a linear form (as a tuple, list or vector) + + An edge is oriented from `v` to `w` if `f(v-w) > 0`. + + EXAMPLES:: + + sage: penta = Polyhedron([[0,0],[1,0],[0,1],[1,2],[3,2]]) + sage: penta.vertex_digraph(vector([1,1])) + Digraph on 5 vertices + + .. SEEALSO:: + + :meth:`vertex_graph` + """ + from sage.graphs.digraph import DiGraph + dg = DiGraph() + for j in range(self.n_vertices()): + vj = self.Vrepresentation(j) + for vi in vj.neighbors(): + if (vi.vector() - vj.vector()).dot_product(f) > 0: + dg.add_edge(vi, vj) + return dg + def polar(self): """ Return the polar (dual) polytope. From 0aed331ca64eb9186fb8a9b462f42415df96b1cb Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Mon, 8 Dec 2014 18:07:00 +0000 Subject: [PATCH 282/698] Make modular exponentiation of polynomial using FLINT interruptable. --- src/sage/libs/flint/nmod_poly_linkage.pxi | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sage/libs/flint/nmod_poly_linkage.pxi b/src/sage/libs/flint/nmod_poly_linkage.pxi index 301fea1d986..f00a2929f2a 100644 --- a/src/sage/libs/flint/nmod_poly_linkage.pxi +++ b/src/sage/libs/flint/nmod_poly_linkage.pxi @@ -21,6 +21,7 @@ from sage.libs.flint.nmod_poly cimport * from sage.libs.flint.ulong_extras cimport * include "sage/ext/stdsage.pxi" +include "sage/ext/cdefs.pxi" cdef inline celement *celement_new(unsigned long n): cdef celement *g = sage_malloc(sizeof(nmod_poly_t)) @@ -486,7 +487,7 @@ cdef inline int celement_pow(nmod_poly_t res, nmod_poly_t x, long e, nmod_poly_t nmod_poly_init(q, n) nmod_poly_init(tmp, n) - if nmod_poly_degree(x) == 1 and nmod_poly_get_coeff_ui(x,0) == 0 and nmod_poly_get_coeff_ui(x,1) == 1: + if nmod_poly_degree(x) == 1 and nmod_poly_get_coeff_ui(x,0) == 0 and nmod_poly_get_coeff_ui(x,1) == 1 and modulus != NULL and e < 2*nmod_poly_degree(modulus): nmod_poly_zero(res) nmod_poly_set_coeff_ui(res,e,1) elif e == 0: @@ -508,6 +509,7 @@ cdef inline int celement_pow(nmod_poly_t res, nmod_poly_t x, long e, nmod_poly_t nmod_poly_zero(res) nmod_poly_set_coeff_ui(res, 0, 1) e = e >> 1 + sig_on() while(e != 0): nmod_poly_pow(pow2, pow2, 2) if e % 2: @@ -515,6 +517,7 @@ cdef inline int celement_pow(nmod_poly_t res, nmod_poly_t x, long e, nmod_poly_t e = e >> 1 if modulus != NULL: nmod_poly_divrem(q, res, res, modulus) + sig_off() nmod_poly_clear(pow2) if modulus != NULL: From ef28e279723adb97ee90c4f01e016decd5bcbc4b Mon Sep 17 00:00:00 2001 From: Jean-Pierre Flori Date: Mon, 8 Dec 2014 18:19:47 +0000 Subject: [PATCH 283/698] Better fix for exponentiation of polys using FLINT nmod and test. --- src/sage/libs/flint/nmod_poly_linkage.pxi | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/sage/libs/flint/nmod_poly_linkage.pxi b/src/sage/libs/flint/nmod_poly_linkage.pxi index f00a2929f2a..3bc1f4f0dc6 100644 --- a/src/sage/libs/flint/nmod_poly_linkage.pxi +++ b/src/sage/libs/flint/nmod_poly_linkage.pxi @@ -430,7 +430,8 @@ cdef inline int celement_inv(nmod_poly_t res, nmod_poly_t a, unsigned long n) ex cdef inline int celement_pow(nmod_poly_t res, nmod_poly_t x, long e, nmod_poly_t modulus, unsigned long n) except -2: """ - EXAMPLE: + EXAMPLE:: + sage: P. = GF(32003)[] sage: f = 24998*x^2 + 29761*x + 2252 @@ -461,7 +462,7 @@ cdef inline int celement_pow(nmod_poly_t res, nmod_poly_t x, long e, nmod_poly_t sage: f^-5 24620/(x^10 + 20309*x^9 + 29185*x^8 + 11948*x^7 + 1965*x^6 + 7713*x^5 + 5810*x^4 + 20457*x^3 + 30732*x^2 + 9706*x + 4485) - Testing the modulus: + Testing the modulus:: sage: g = 20778*x^2 + 15346*x + 12697 @@ -479,6 +480,15 @@ cdef inline int celement_pow(nmod_poly_t res, nmod_poly_t x, long e, nmod_poly_t 7231*x + 17274 sage: f^5 % g 7231*x + 17274 + + Make sure that exponentiation can be interrupted, see :trac:`17470`:: + + sage: n = 1 << 30 + sage: alarm(1) + sage: x^n + Traceback (most recent call last): + ... + AlarmInterrupt """ cdef nmod_poly_t pow2 cdef nmod_poly_t q @@ -487,7 +497,7 @@ cdef inline int celement_pow(nmod_poly_t res, nmod_poly_t x, long e, nmod_poly_t nmod_poly_init(q, n) nmod_poly_init(tmp, n) - if nmod_poly_degree(x) == 1 and nmod_poly_get_coeff_ui(x,0) == 0 and nmod_poly_get_coeff_ui(x,1) == 1 and modulus != NULL and e < 2*nmod_poly_degree(modulus): + if nmod_poly_degree(x) == 1 and nmod_poly_get_coeff_ui(x,0) == 0 and nmod_poly_get_coeff_ui(x,1) == 1 and (modulus == NULL or e < 2*nmod_poly_degree(modulus)): nmod_poly_zero(res) nmod_poly_set_coeff_ui(res,e,1) elif e == 0: From f511623cce7bde7f022fa212a505526b3b62f0db Mon Sep 17 00:00:00 2001 From: Mario Pernici Date: Tue, 9 Dec 2014 13:58:03 +0100 Subject: [PATCH 284/698] Added documentation to `permanental_minor_vector` --- src/sage/matrix/matrix_misc.py | 67 +++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/src/sage/matrix/matrix_misc.py b/src/sage/matrix/matrix_misc.py index c07f3e5086b..cde1493eed3 100644 --- a/src/sage/matrix/matrix_misc.py +++ b/src/sage/matrix/matrix_misc.py @@ -306,10 +306,25 @@ def permanental_minor_vector(m, permanent_only=False): ALGORITHM: - The algorithm uses polynomials over the algebra - `K[\eta_1, \eta_2,\ldots, \eta_k]` where the `\eta_i` are commuting, - nilpotent of order `2` (i.e. `\eta_i^2 = 0`). Let us consider an example of - computation. Let `p_1 = 1 + t \eta_0 + t \eta_1` and + The permanent of a n x n matrix `A` is the coefficient of the + x_1...x_n monomial in + + .. MATH:: + + \prod_{i=1}^n \sum_{j=1}^n A_{ij} x_j + + Evaluating this product one can neglect `x_i^2`, that is `x_i` + can be considered to be nilpotent of order `2`. + + To formalize this procedure, consider polynomials over the algebra + `K[t, \eta_1, \eta_2,\ldots, \eta_k]` where the `\eta_i` are + commuting, nilpotent of order `2` (i.e. `\eta_i^2 = 0`), + and `t` is commuting. + Introduce an "integration" operation

consisting in the sum + of the coefficients of the non-vanishing monomials of the polynomial p. + + Let us consider an example of computation. + Let `p_1 = 1 + t \eta_0 + t \eta_1` and `p_2 = 1 + t \eta_0 + t \eta_2`. Then .. MATH:: @@ -318,13 +333,53 @@ def permanental_minor_vector(m, permanent_only=False): t (\eta_1 + \eta_2) + t^2 (\eta_0 \eta_1 + \eta_0 \eta_2 + \eta_1 \eta_2) + = 1 + 4t + 3t^2 + + A useful property is the following: let `p_1(\eta_0,..,\eta_k)` + be a polynomial in distributed form, and let `p_2(\eta_j,..,\eta_k)` + be a product of polynomials, with `j \ge 1`; one has + + .. MATH:: + = + + where `\eta_0,..,\eta_{j-1}` are replaced by `1` in `p_1`. + + In this formalism + + .. MATH:: + + perm(A) = < \prod_{i=1}^n \sum_{j=1}^n A_{ij} \eta_j > + + The sum of permanental k-minors of `A` is + + .. MATH:: + + permMinor (A, k) = \sum_{r,s} perm(A_{r,s}) + + where ``A_{r,s}`` is the matrix obtained eliminating the rows `r` + and the columns `s`. + + The generating function of the sums of the permanental minors + of a m x n matrix is + + .. MATH:: + + g(t) = < \prod_{i=1}^m (1 + t \sum_{j=1}^n A_{ij} \eta_j) > + + In fact the `t^k` coefficient of `g(t)` corresponds to choosing + `k` rows of `A`; `\eta_i` is associated to the i-th column; + nilpotency avoids having twice the same column in a product of A's. + The product is implemented as a subroutine in :func:`prm_mul`. The polynomials are represented in dictionary form: to a variable `\eta_i` it is associated the key `2^i` (or in Python ``1 << i``). So in the above example `\eta_1` corresponds to the key `2` while the product `\eta_1 \eta_2` to the key `6`. - MORE DOC NEEDED!!! + The complexity of this algorithm is `O(2^n m^2 n)`. + If `A` is a banded matrix with width `w`, that is `A_{ij}=0` for + `|i - j| > w`, and `w < n/2`, then the complexity of the + algorithm is `O(4^w (w+1) n^2)`. REFERENCES: @@ -335,7 +390,7 @@ def permanental_minor_vector(m, permanent_only=False): nrows = m.nrows() ncols = m.ncols() m = m.rows() - p = {int(0): K.one()} + p = {0: K.one()} t = K.gen() done_vars = set() one = 1 From 5329f4b69843bf36c8e00382f31e926777d76393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 9 Dec 2014 14:38:47 +0100 Subject: [PATCH 285/698] trac #17475 sympy name for heaviside --- src/sage/functions/generalized.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/functions/generalized.py b/src/sage/functions/generalized.py index 1444f55aee6..b0aef9e07b5 100644 --- a/src/sage/functions/generalized.py +++ b/src/sage/functions/generalized.py @@ -206,7 +206,9 @@ def __init__(self): H\left(x\right) """ BuiltinFunction.__init__(self, "heaviside", latex_name="H", - conversions=dict(mathematica='HeavisideTheta')) + conversions=dict(maxima='hstep', + mathematica='HeavisideTheta', + sympy='Heaviside')) def _eval_(self, x): """ @@ -419,12 +421,11 @@ class FunctionSignum(BuiltinFunction): TESTS: - Check if conversion to sympy works #11921:: + Check if conversion to sympy works :trac:`11921`:: sage: sgn(x)._sympy_() sign(x) - REFERENCES: - http://en.wikipedia.org/wiki/Sign_function From de039e41032dabf9ffb2459dc9627f725fca3017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 9 Dec 2014 14:58:30 +0100 Subject: [PATCH 286/698] trac #17475 some sympy names for elliptic functions --- src/sage/functions/special.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/sage/functions/special.py b/src/sage/functions/special.py index 283b4714fc6..9b9708bef05 100644 --- a/src/sage/functions/special.py +++ b/src/sage/functions/special.py @@ -871,7 +871,8 @@ def __init__(self): sage: elliptic_ec(0.1) 1.53075763689776 """ - MaximaFunction.__init__(self, "elliptic_ec", nargs=1) + MaximaFunction.__init__(self, "elliptic_ec", nargs=1, + conversion=dict(sympy='ellipe')) def _derivative_(self, *args, **kwds): """ @@ -944,7 +945,8 @@ def __init__(self): sage: elliptic_f (0.2, 0.1) 0.200132506747543 """ - MaximaFunction.__init__(self, "elliptic_f") + MaximaFunction.__init__(self, "elliptic_f", + conversion=dict(sympy='ellipf')) elliptic_f = EllipticF() @@ -973,7 +975,8 @@ def __init__(self): sage: elliptic_f(RR(pi/2), 0.5) 1.85407467730137 """ - MaximaFunction.__init__(self, "elliptic_kc", nargs=1) + MaximaFunction.__init__(self, "elliptic_kc", nargs=1, + conversion=dict(sympy='ellipk')) elliptic_kc = EllipticKC() @@ -1027,7 +1030,8 @@ def __init__(self): sage: elliptic_pi(0.1, 0.2, 0.3) 0.200665068220979 """ - MaximaFunction.__init__(self, "elliptic_pi", nargs=3) + MaximaFunction.__init__(self, "elliptic_pi", nargs=3, + conversion=dict(sympy='ellippi')) elliptic_pi = EllipticPi() From edab5643638484014ef433141add244a7c181e6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 9 Dec 2014 15:07:43 +0100 Subject: [PATCH 287/698] trac #17475 fixed wrong keyword for conversions --- src/sage/functions/special.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/functions/special.py b/src/sage/functions/special.py index 9b9708bef05..a1059303e2f 100644 --- a/src/sage/functions/special.py +++ b/src/sage/functions/special.py @@ -872,7 +872,7 @@ def __init__(self): 1.53075763689776 """ MaximaFunction.__init__(self, "elliptic_ec", nargs=1, - conversion=dict(sympy='ellipe')) + conversions=dict(sympy='ellipe')) def _derivative_(self, *args, **kwds): """ @@ -946,7 +946,7 @@ def __init__(self): 0.200132506747543 """ MaximaFunction.__init__(self, "elliptic_f", - conversion=dict(sympy='ellipf')) + conversions=dict(sympy='ellipf')) elliptic_f = EllipticF() @@ -976,7 +976,7 @@ def __init__(self): 1.85407467730137 """ MaximaFunction.__init__(self, "elliptic_kc", nargs=1, - conversion=dict(sympy='ellipk')) + conversions=dict(sympy='ellipk')) elliptic_kc = EllipticKC() @@ -1031,7 +1031,7 @@ def __init__(self): 0.200665068220979 """ MaximaFunction.__init__(self, "elliptic_pi", nargs=3, - conversion=dict(sympy='ellippi')) + conversions=dict(sympy='ellippi')) elliptic_pi = EllipticPi() From 638b9e71d3d3d2a63024942c9f2476b86dcc4352 Mon Sep 17 00:00:00 2001 From: Karl-Dieter Crisman Date: Tue, 9 Dec 2014 09:26:05 -0500 Subject: [PATCH 288/698] Tiny website improvements --- src/doc/en/reference/index.rst | 2 +- src/doc/en/tutorial/index.rst | 2 +- src/doc/en/website/templates/index.html | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/doc/en/reference/index.rst b/src/doc/en/reference/index.rst index bf6c7aeae25..3e130fde54f 100644 --- a/src/doc/en/reference/index.rst +++ b/src/doc/en/reference/index.rst @@ -1,5 +1,5 @@ Welcome to Sage's Reference Manual! -================================================= +=================================== This is a thematic index of all of `Sage's `_ features. It also contains many examples that illustrate their use, all of them diff --git a/src/doc/en/tutorial/index.rst b/src/doc/en/tutorial/index.rst index 6eee152e6e5..72b80ad2b5d 100644 --- a/src/doc/en/tutorial/index.rst +++ b/src/doc/en/tutorial/index.rst @@ -3,7 +3,7 @@ contain the root `toctree` directive. Welcome to the Sage Tutorial! -================================ +============================= Sage is free, open-source math software that supports research and teaching in algebra, geometry, number theory, cryptography, diff --git a/src/doc/en/website/templates/index.html b/src/doc/en/website/templates/index.html index 32d2ce2c569..d2d5064c370 100644 --- a/src/doc/en/website/templates/index.html +++ b/src/doc/en/website/templates/index.html @@ -1,5 +1,9 @@ {% extends "layout.html" %} +{% block htmltitle %} +Sage Documentation{{ titlesuffix }} +{% endblock %} + {%- block extrahead %}