From 56372862af845541b7aab3624770c5118a361413 Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Tue, 7 Sep 2021 09:14:07 +0200 Subject: [PATCH 001/228] Add an algorithm keyword to simplify. --- src/sage/calculus/functional.py | 28 ++++++++++++++++---- src/sage/symbolic/expression.pyx | 45 ++++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/src/sage/calculus/functional.py b/src/sage/calculus/functional.py index 0654118d257..54ebcbfe2b9 100644 --- a/src/sage/calculus/functional.py +++ b/src/sage/calculus/functional.py @@ -29,10 +29,13 @@ from .calculus import SR from sage.symbolic.expression import Expression -def simplify(f): +def simplify(f, algorithm="maxima", **kwds): r""" Simplify the expression `f`. + See the documentation of the :meth:`simplify` method of symbolic + expressions for details on options. + EXAMPLES: We simplify the expression `i + x - x`. :: @@ -42,11 +45,26 @@ def simplify(f): In fact, printing `f` yields the same thing - i.e., the simplified form. + + Some simplifications are algorithm-specific : + + :: + + sage: x, t = var("x, t") + sage: ex = 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/2/(I*x + I*sqrt(x^2 - 1)) + sage: ex.simplify() + 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/(2*I*x + 2*I*sqrt(x^2 - 1)) + sage: ex.simplify(algorithm="giac") + I*sqrt(x^2 - 1) + """ - try: - return f.simplify() - except AttributeError: - return f + if f.parent() is SR: + return f.simplify(algorithm=algorithm, **kwds) + else : + try: + return f.simplify() + except AttributeError: + return f def derivative(f, *args, **kwds): r""" diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 5273c7bdcac..8b3fc412cb4 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -10259,14 +10259,25 @@ cdef class Expression(CommutativeRingElement): else: return self - def simplify(self): + def simplify(self, algorithm="maxima", **kwds): """ Return a simplified version of this symbolic expression. - .. NOTE:: + INPUT: + - ``algorithm`` - one of : + + - ``maxima`` : currently, sends the expression to + ``maxima`` and converts it back to Sage. + + - ``sympy`` : converts the expression to ``sympy``, + simplifies it (passing any optional keyword(s)), and + converts the result to Sage. + + - ``giac`` : converts the expression to ``giac``, + simplifies it, and converts the result to Sage. - Currently, this just sends the expression to Maxima - and converts it back to Sage. + - ``fricas`` : converts the expression to ``fricas``, + simplifies it, and converts the result to Sage. .. SEEALSO:: @@ -10283,6 +10294,22 @@ cdef class Expression(CommutativeRingElement): sage: f.simplify() x^(-a + 1)*sin(2) + Some simplifications are quite algorithm-specific : + + :: + + sage: x, t = var("x, t") + sage: ex = cos(t).exponentialize() + sage: ex = ex.subs((sin(t).exponentialize()==x).solve(t)[0]) + sage: ex + 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/2/(I*x + I*sqrt(x^2 - 1)) + sage: ex.simplify() + 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/(2*I*x + 2*I*sqrt(x^2 - 1)) + sage: ex.simplify(algorithm="sympy") + I*(x^2 + sqrt(x^2 - 1)*x - 1)/(x + sqrt(x^2 - 1)) + sage: ex.simplify(algorithm="giac") + I*sqrt(x^2 - 1) + TESTS: Check that :trac:`14637` is fixed:: @@ -10292,7 +10319,15 @@ cdef class Expression(CommutativeRingElement): x sage: forget() """ - return self._parent(self._maxima_()) + if algorithm == "maxima" : + return self._parent(self._maxima_()) + if algorithm == "sympy" : + return self._sympy_().simplify(**kwds)._sage_() + if algorithm == "giac" : + return self._giac_().simplify()._sage_() + if algorithm == "fricas" : + return self._fricas_().simplify()._sage_() + raise ValueError("Algorithm %s unknown to simplify."%algorithm) def simplify_full(self): """ From 419aaa96fc8d0b75f054ac6add3c2a51fd96af38 Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Tue, 7 Sep 2021 09:14:07 +0200 Subject: [PATCH 002/228] Add an algorithm keyword to simplify. --- src/sage/calculus/functional.py | 28 ++++++++++++++++---- src/sage/symbolic/expression.pyx | 45 ++++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/src/sage/calculus/functional.py b/src/sage/calculus/functional.py index 0654118d257..54ebcbfe2b9 100644 --- a/src/sage/calculus/functional.py +++ b/src/sage/calculus/functional.py @@ -29,10 +29,13 @@ from .calculus import SR from sage.symbolic.expression import Expression -def simplify(f): +def simplify(f, algorithm="maxima", **kwds): r""" Simplify the expression `f`. + See the documentation of the :meth:`simplify` method of symbolic + expressions for details on options. + EXAMPLES: We simplify the expression `i + x - x`. :: @@ -42,11 +45,26 @@ def simplify(f): In fact, printing `f` yields the same thing - i.e., the simplified form. + + Some simplifications are algorithm-specific : + + :: + + sage: x, t = var("x, t") + sage: ex = 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/2/(I*x + I*sqrt(x^2 - 1)) + sage: ex.simplify() + 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/(2*I*x + 2*I*sqrt(x^2 - 1)) + sage: ex.simplify(algorithm="giac") + I*sqrt(x^2 - 1) + """ - try: - return f.simplify() - except AttributeError: - return f + if f.parent() is SR: + return f.simplify(algorithm=algorithm, **kwds) + else : + try: + return f.simplify() + except AttributeError: + return f def derivative(f, *args, **kwds): r""" diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 843cfee7f4c..336172a5191 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -10551,14 +10551,25 @@ cdef class Expression(Expression_abc): else: return self - def simplify(self): + def simplify(self, algorithm="maxima", **kwds): """ Return a simplified version of this symbolic expression. - .. NOTE:: + INPUT: + - ``algorithm`` - one of : + + - ``maxima`` : currently, sends the expression to + ``maxima`` and converts it back to Sage. + + - ``sympy`` : converts the expression to ``sympy``, + simplifies it (passing any optional keyword(s)), and + converts the result to Sage. + + - ``giac`` : converts the expression to ``giac``, + simplifies it, and converts the result to Sage. - Currently, this just sends the expression to Maxima - and converts it back to Sage. + - ``fricas`` : converts the expression to ``fricas``, + simplifies it, and converts the result to Sage. .. SEEALSO:: @@ -10575,6 +10586,22 @@ cdef class Expression(Expression_abc): sage: f.simplify() x^(-a + 1)*sin(2) + Some simplifications are quite algorithm-specific : + + :: + + sage: x, t = var("x, t") + sage: ex = cos(t).exponentialize() + sage: ex = ex.subs((sin(t).exponentialize()==x).solve(t)[0]) + sage: ex + 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/2/(I*x + I*sqrt(x^2 - 1)) + sage: ex.simplify() + 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/(2*I*x + 2*I*sqrt(x^2 - 1)) + sage: ex.simplify(algorithm="sympy") + I*(x^2 + sqrt(x^2 - 1)*x - 1)/(x + sqrt(x^2 - 1)) + sage: ex.simplify(algorithm="giac") + I*sqrt(x^2 - 1) + TESTS: Check that :trac:`14637` is fixed:: @@ -10584,7 +10611,15 @@ cdef class Expression(Expression_abc): x sage: forget() """ - return self._parent(self._maxima_()) + if algorithm == "maxima" : + return self._parent(self._maxima_()) + if algorithm == "sympy" : + return self._sympy_().simplify(**kwds)._sage_() + if algorithm == "giac" : + return self._giac_().simplify()._sage_() + if algorithm == "fricas" : + return self._fricas_().simplify()._sage_() + raise ValueError("Algorithm %s unknown to simplify."%algorithm) def simplify_full(self): """ From 16c7733f78de5952714ac5b5f4d6d565726272cf Mon Sep 17 00:00:00 2001 From: Emmanuel Charpentier Date: Wed, 15 Dec 2021 19:32:48 +0100 Subject: [PATCH 003/228] Trac#39472 : fix example for the simplify function (rebased on 9.5.beta7) --- src/sage/calculus/functional.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/calculus/functional.py b/src/sage/calculus/functional.py index 54ebcbfe2b9..9e106c05334 100644 --- a/src/sage/calculus/functional.py +++ b/src/sage/calculus/functional.py @@ -52,9 +52,9 @@ def simplify(f, algorithm="maxima", **kwds): sage: x, t = var("x, t") sage: ex = 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/2/(I*x + I*sqrt(x^2 - 1)) - sage: ex.simplify() + sage: simplify(ex) 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/(2*I*x + 2*I*sqrt(x^2 - 1)) - sage: ex.simplify(algorithm="giac") + sage: simplify(ex, algorithm="giac") I*sqrt(x^2 - 1) """ From f51f29a09bce023836a01c1d866eeecf26a078fa Mon Sep 17 00:00:00 2001 From: Sebastian Oehms Date: Fri, 15 Jul 2022 09:03:58 +0200 Subject: [PATCH 004/228] 34185: initial version --- src/bin/sage-runtests | 4 ++ src/sage/doctest/control.py | 110 +++++++++++++++++++++++++++++++- src/sage/features/__init__.py | 115 ++++++++++++++++++++++++++++++++++ 3 files changed, 228 insertions(+), 1 deletion(-) diff --git a/src/bin/sage-runtests b/src/bin/sage-runtests index 75e2119c99a..809aedf5724 100755 --- a/src/bin/sage-runtests +++ b/src/bin/sage-runtests @@ -52,6 +52,10 @@ if __name__ == "__main__": 'if set to "all", then all tests will be run; ' 'use "!FEATURE" to disable tests marked "# optional - FEATURE". ' 'Note that "!" needs to be quoted or escaped in the shell.') + parser.add_argument("--hide", metavar="FEATURES", default="", + help='run tests pretending that the software listed in FEATURES (separated by commas) is not installed; ' + 'if "all" is listed, will also hide features corresponding to all non standard packages; ' + 'if "optional" is listed, will also hide features corresponding to optional packages.') parser.add_argument("--randorder", type=int, metavar="SEED", help="randomize order of tests") parser.add_argument("--random-seed", dest="random_seed", type=int, metavar="SEED", help="random seed (integer) for fuzzing doctests", default=os.environ.get("SAGE_DOCTEST_RANDOM_SEED")) diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index beccbeacf1f..8714fddc99f 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -56,7 +56,6 @@ except ImportError: pass - class DocTestDefaults(SageObject): """ This class is used for doctesting the Sage doctest module. @@ -135,6 +134,7 @@ def __init__(self, **kwds): # displaying user-defined optional tags and we don't want to see # the auto_optional_tags there. self.optional = set(['sage']) | auto_optional_tags + self.hide = '' # > 0: always run GC before every test # < 0: disable GC @@ -398,6 +398,28 @@ def __init__(self, options, args): if options.verbose: options.show_skipped = True + options.hidden_features = set() + if isinstance(options.hide, str): + if not len(options.hide): + options.hide = set([]) + else: + s = options.hide.lower() + options.hide = set(s.split(',')) + for h in options.hide: + if not optionaltag_regex.search(h): + raise ValueError('invalid optional tag {!r}'.format(h)) + if 'all' in options.hide: + options.hide.discard('all') + from sage.features.all import all_features + feature_names = set([f.name for f in all_features() if not f.is_standard()]) + options.hide = options.hide.union(feature_names) + if 'optional' in options.hide: + options.hide.discard('optional') + from sage.features.all import all_features + feature_names = set([f.name for f in all_features() if f.is_optional()]) + options.hide = options.hide.union(feature_names) + + options.disabled_optional = set() if isinstance(options.optional, str): s = options.optional.lower() @@ -414,6 +436,8 @@ def __init__(self, options, args): options.optional.discard('optional') from sage.misc.package import list_packages for pkg in list_packages('optional', local=True).values(): + if pkg.name in options.hide: + continue if pkg.is_installed() and pkg.installed_version == pkg.remote_version: options.optional.add(pkg.name) @@ -1320,6 +1344,49 @@ def run(self): Features detected... 0 + We test the ``--hide`` option (:trac:`34185`): + + sage: from sage.doctest.control import test_hide + sage: filename = tmp_filename(ext='.py') + sage: with open(filename, 'w') as f: + ....: f.write(test_hide) + ....: f.close() + 402 + sage: DF = DocTestDefaults(hide='buckygen,all') + sage: DC = DocTestController(DF, [filename]) + sage: DC.run() + Running doctests with ID ... + Using --optional=sage + Features to be detected: ... + Doctesting 1 file. + sage -t ....py + [2 tests, ... s] + ---------------------------------------------------------------------- + All tests passed! + ---------------------------------------------------------------------- + Total time for all tests: ... seconds + cpu time: ... seconds + cumulative wall time: ... seconds + Features detected... + 0 + + sage: DF = DocTestDefaults(hide='benzene,optional') + sage: DC = DocTestController(DF, [filename]) + sage: DC.run() + Running doctests with ID ... + Using --optional=sage + Features to be detected: ... + Doctesting 1 file. + sage -t ....py + [2 tests, ... s] + ---------------------------------------------------------------------- + All tests passed! + ---------------------------------------------------------------------- + Total time for all tests: ... seconds + cpu time: ... seconds + cumulative wall time: ... seconds + Features detected... + 0 """ opt = self.options L = (opt.gdb, opt.valgrind, opt.massif, opt.cachegrind, opt.omega) @@ -1360,6 +1427,18 @@ def run(self): self.log("Using --optional=" + self._optional_tags_string()) available_software._allow_external = self.options.optional is True or 'external' in self.options.optional + + for h in self.options.hide: + try: + i = available_software._indices[h] + except KeyError: + pass + else: + f = available_software._features[i] + if f.is_present(): + f.hide() + self.options.hidden_features.add(f) + for o in self.options.disabled_optional: try: i = available_software._indices[o] @@ -1369,12 +1448,17 @@ def run(self): available_software._seen[i] = -1 self.log("Features to be detected: " + ','.join(available_software.detectable())) + if self.options.hidden_features: + self.log("Hidden features: " + ','.join([f.name for f in self.options.hidden_features])) self.add_files() self.expand_files_into_sources() self.filter_sources() self.sort_sources() self.run_doctests() + for f in self.options.hidden_features: + f.unhide() + self.log("Features detected for doctesting: " + ','.join(available_software.seen())) self.cleanup() @@ -1455,3 +1539,27 @@ def stringify(x): if not save_dtmode and IP is not None: IP.run_line_magic('colors', old_color) IP.config.TerminalInteractiveShell.colors = old_config_color + + +############################################################################### +# Declaration of doctest strings +############################################################################### + +test_hide=r"""{} +sage: next(graphs.fullerenes(20)) +Traceback (most recent call last): + ... +FeatureNotPresentError: buckygen is not available. +... +sage: next(graphs.fullerenes(20)) # optional buckygen +Graph on 20 vertices + +sage: len(list(graphs.fusenes(2))) +Traceback (most recent call last): + ... +FeatureNotPresentError: benzene is not available. +... +sage: len(list(graphs.fusenes(2))) # optional benzene +1 +{} +""".format('r"""', '"""') diff --git a/src/sage/features/__init__.py b/src/sage/features/__init__.py index fd899aa4770..bbe5dd1bd34 100644 --- a/src/sage/features/__init__.py +++ b/src/sage/features/__init__.py @@ -137,6 +137,7 @@ def __init__(self, name, spkg=None, url=None, description=None): self._cache_is_present = None self._cache_resolution = None + self._hidden = False def is_present(self): r""" @@ -173,6 +174,8 @@ def is_present(self): sage: TestFeature("other").is_present() FeatureTestResult('other', True) """ + if self._hidden: + return FeatureTestResult(self, False, reason="Feature `{name}` is hidden.".format(name=self.name)) # We do not use @cached_method here because we wish to use # Feature early in the build system of sagelib. if self._cache_is_present is None: @@ -225,6 +228,33 @@ def __repr__(self): description = f'{self.name!r}: {self.description}' if self.description else f'{self.name!r}' return f'Feature({description})' + def _spkg_type(self): + r""" + Return the type of the SPKG corresponding to this feature. + + EXAMPLES:: + + sage: from sage.features.databases import DatabaseCremona + sage: DatabaseCremona()._spkg_type() + 'optional' + + OUTPUT: + + The type as a string in ``('base', 'standard', 'optional', 'experimental')``. + If no SPKG corresponds to this feature ``None`` is returned. + """ + spkg_type = None + from sage.env import SAGE_PKGS + try: + f = open(os.path.join(SAGE_PKGS, self.name, "type")) + except IOError: + # Probably an empty directory => ignore + return None + + with f: + spkg_type = f.read().strip() + return spkg_type + def resolution(self): r""" Return a suggestion on how to make :meth:`is_present` pass if it did not @@ -240,6 +270,8 @@ def resolution(self): sage: Executable(name="CSDP", spkg="csdp", executable="theta", url="https://github.com/dimpase/csdp").resolution() # optional - sage_spkg '...To install CSDP...you can try to run...sage -i csdp...Further installation instructions might be available at https://github.com/dimpase/csdp.' """ + if self._hidden: + return "Use method `unhide` to make it available again." if self._cache_resolution is not None: return self._cache_resolution lines = [] @@ -251,6 +283,89 @@ def resolution(self): self._cache_resolution = "\n".join(lines) return self._cache_resolution + def is_standard(self): + r""" + Return whether this feature corresponds to a standard SPKG. + + EXAMPLES:: + + sage: from sage.features.databases import DatabaseCremona, DatabaseConwayPolynomials + sage: DatabaseCremona().is_standard() + False + sage: DatabaseConwayPolynomials().is_standard() + True + """ + if self.name.startswith('sage.'): + return True + return self._spkg_type() == 'standard' + + def is_optional(self): + r""" + Return whether this feature corresponds to an optional SPKG. + + EXAMPLES:: + + sage: from sage.features.databases import DatabaseCremona, DatabaseConwayPolynomials + sage: DatabaseCremona().is_optional() + True + sage: DatabaseConwayPolynomials().is_optional() + False + """ + return self._spkg_type() == 'optional' + + def hide(self): + r""" + Hide this feature. For example this is used when the doctest option + ``--hide``is set. Setting an installed feature as hidden pretends + that it is not available. To revert this use :meth:`unhide`. + + EXAMPLES: + + Benzene is an optional SPKG. The following test fails if it is hidden or + not installed. Thus, in the second invocation the optional tag is needed:: + + sage: from sage.features.graph_generators import Benzene + sage: Benzene().hide() + sage: len(list(graphs.fusenes(2))) + Traceback (most recent call last): + ... + FeatureNotPresentError: benzene is not available. + Feature `benzene` is hidden. + Use method `unhide` to make it available again. + + sage: Benzene().unhide() + sage: len(list(graphs.fusenes(2))) # optional benzene + 1 + """ + self._hidden = True + + def unhide(self): + r""" + Revert what :meth:`hide` does. + + EXAMPLES: + + Polycyclic is a standard GAP package since 4.10 (see :trac:`26856`). The + following test just fails if it is hidden. Thus, in the second + invocation no optional tag is needed:: + + sage: from sage.features.gap import GapPackage + sage: Polycyclic = GapPackage("polycyclic", spkg="gap_packages") + sage: Polycyclic.hide() + sage: libgap(AbelianGroup(3, [0,3,4], names="abc")) + Traceback (most recent call last): + ... + FeatureNotPresentError: gap_package_polycyclic is not available. + Feature `gap_package_polycyclic` is hidden. + Use method `unhide` to make it available again. + + sage: Polycyclic.unhide() + sage: libgap(AbelianGroup(3, [0,3,4], names="abc")) + Pcp-group with orders [ 0, 3, 4 ] + """ + self._hidden = False + + class FeatureNotPresentError(RuntimeError): From 3071dbc20e76459a23282001311b6fee3cd897c3 Mon Sep 17 00:00:00 2001 From: Sebastian Oehms Date: Mon, 18 Jul 2022 18:01:12 +0200 Subject: [PATCH 005/228] 34185: correction according to review --- src/sage/features/__init__.py | 12 ++-------- src/sage/misc/package.py | 41 +++++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/sage/features/__init__.py b/src/sage/features/__init__.py index bbe5dd1bd34..5887c1f26dd 100644 --- a/src/sage/features/__init__.py +++ b/src/sage/features/__init__.py @@ -243,17 +243,9 @@ def _spkg_type(self): The type as a string in ``('base', 'standard', 'optional', 'experimental')``. If no SPKG corresponds to this feature ``None`` is returned. """ + from sage.misc.package import _spkg_type + return _spkg_type(self.name) spkg_type = None - from sage.env import SAGE_PKGS - try: - f = open(os.path.join(SAGE_PKGS, self.name, "type")) - except IOError: - # Probably an empty directory => ignore - return None - - with f: - spkg_type = f.read().strip() - return spkg_type def resolution(self): r""" diff --git a/src/sage/misc/package.py b/src/sage/misc/package.py index 849ee71f3fb..a37bb95db3f 100644 --- a/src/sage/misc/package.py +++ b/src/sage/misc/package.py @@ -125,6 +125,38 @@ def pip_remote_version(pkg, pypi_url=DEFAULT_PYPI, ignore_URLError=False): stable_releases = [v for v in info['releases'] if 'a' not in v and 'b' not in v] return max(stable_releases) +def _spkg_type(name): + r""" + Return the type of the Sage package with the given name. + + INPUT: + + - ``name`` -- string giving the subdirectory name of the package under + ``SAGE_PKGS`` + + EXAMPLES:: + + sage: from sage.misc.package import _spkg_type + sage: _spkg_type('pip') + 'standard' + + OUTPUT: + + The type as a string in ``('base', 'standard', 'optional', 'experimental')``. + If no ``SPKG`` exists with the given name ``None`` is returned. + """ + spkg_type = None + from sage.env import SAGE_PKGS + try: + f = open(os.path.join(SAGE_PKGS, name, "type")) + except IOError: + # Probably an empty directory => ignore + return None + + with f: + spkg_type = f.read().strip() + return spkg_type + def pip_installed_packages(normalization=None): r""" @@ -311,15 +343,10 @@ def list_packages(*pkg_types: str, pkg_sources: List[str] = ['normal', 'pip', 's for p in lp: - try: - f = open(os.path.join(SAGE_PKGS, p, "type")) - except IOError: - # Probably an empty directory => ignore + typ = _spkg_type(p) + if not typ: continue - with f: - typ = f.read().strip() - if os.path.isfile(os.path.join(SAGE_PKGS, p, "requirements.txt")): src = 'pip' elif os.path.isfile(os.path.join(SAGE_PKGS, p, "checksums.ini")): From b4b562c56206b83fb23f259e6cba4f75304b43b9 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 25 Jul 2022 08:39:20 +0200 Subject: [PATCH 006/228] 34185: take care of joined features --- src/sage/doctest/control.py | 16 +++++++++-- src/sage/features/__init__.py | 22 +++++++++++++++ src/sage/features/join_feature.py | 47 +++++++++++++++++++++++++++++++ src/sage/misc/lazy_import.pyx | 7 ++++- 4 files changed, 88 insertions(+), 4 deletions(-) diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index 0d78b961d86..535c71557b1 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -1351,7 +1351,7 @@ def run(self): sage: with open(filename, 'w') as f: ....: f.write(test_hide) ....: f.close() - 402 + 729 sage: DF = DocTestDefaults(hide='buckygen,all') sage: DC = DocTestController(DF, [filename]) sage: DC.run() @@ -1360,7 +1360,7 @@ def run(self): Features to be detected: ... Doctesting 1 file. sage -t ....py - [2 tests, ... s] + [4 tests, ... s] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -1378,7 +1378,7 @@ def run(self): Features to be detected: ... Doctesting 1 file. sage -t ....py - [2 tests, ... s] + [4 tests, ... s] ---------------------------------------------------------------------- All tests passed! ---------------------------------------------------------------------- @@ -1438,6 +1438,9 @@ def run(self): if f.is_present(): f.hide() self.options.hidden_features.add(f) + for g in f.joined_features(): + if g.name in self.options.optional: + self.options.optional.discard(g.name) for o in self.options.disabled_optional: try: @@ -1561,5 +1564,12 @@ def stringify(x): ... sage: len(list(graphs.fusenes(2))) # optional benzene 1 +sage: from sage.matrix.matrix_space import get_matrix_class +sage: get_matrix_class(GF(25,'x'), 4, 4, False, 'meataxe') +Failed lazy import: +sage.matrix.matrix_gfpn_dense is not available. +... +sage: get_matrix_class(GF(25,'x'), 4, 4, False, 'meataxe') # optional meataxe + {} """.format('r"""', '"""') diff --git a/src/sage/features/__init__.py b/src/sage/features/__init__.py index 5887c1f26dd..1750908c74b 100644 --- a/src/sage/features/__init__.py +++ b/src/sage/features/__init__.py @@ -275,6 +275,28 @@ def resolution(self): self._cache_resolution = "\n".join(lines) return self._cache_resolution + def joined_features(self): + r""" + Return a list of features joined with ``self``. + + OUTPUT: + + A (possibly empty) list of instances of :class:`Feature`. + + EXAMPLES:: + + sage: from sage.features.graphviz import Graphviz + sage: Graphviz().joined_features() + [Feature('dot'), Feature('neato'), Feature('twopi')] + sage: from sage.features.interfaces import Mathematica + sage: Mathematica().joined_features() + [] + """ + from sage.features.join_feature import JoinFeature + if isinstance(self, JoinFeature): + return self._features + return [] + def is_standard(self): r""" Return whether this feature corresponds to a standard SPKG. diff --git a/src/sage/features/join_feature.py b/src/sage/features/join_feature.py index b29241eb462..218246190c4 100644 --- a/src/sage/features/join_feature.py +++ b/src/sage/features/join_feature.py @@ -94,3 +94,50 @@ def is_functional(self): if not test: return test return FeatureTestResult(self, True) + + def hide(self): + r""" + Hide this feature and all its joined features. + + EXAMPLES: + + sage: from sage.features.sagemath import sage__groups + sage: f = sage__groups() + sage: f.hide() + sage: f._features[0].is_present() + FeatureTestResult('sage.groups.perm_gps.permgroup', False) + + sage: f.require() + Traceback (most recent call last): + ... + FeatureNotPresentError: sage.groups is not available. + Feature `sage.groups` is hidden. + Use method `unhide` to make it available again. + """ + for f in self._features: + f.hide() + super(JoinFeature, self).hide() + + def unhide(self): + r""" + Hide this feature and all its joined features. + + EXAMPLES: + + sage: from sage.features.sagemath import sage__groups + sage: f = sage__groups() + sage: f.hide() + sage: f.is_present() + FeatureTestResult('sage.groups', False) + sage: f._features[0].is_present() + FeatureTestResult('sage.groups.perm_gps.permgroup', False) + + sage: f.unhide() + sage: f.is_present() # optional sage.groups + FeatureTestResult('sage.groups', True) + sage: f._features[0].is_present() # optional sage.groups + FeatureTestResult('sage.groups.perm_gps.permgroup', True) + """ + for f in self._features: + f.unhide() + super(JoinFeature, self).unhide() diff --git a/src/sage/misc/lazy_import.pyx b/src/sage/misc/lazy_import.pyx index 97055afb01a..bf41b4b9fca 100644 --- a/src/sage/misc/lazy_import.pyx +++ b/src/sage/misc/lazy_import.pyx @@ -248,13 +248,18 @@ cdef class LazyImport(): if finish_startup_called: warn(f"Option ``at_startup=True`` for lazy import {self._name} not needed anymore") + feature = self._feature try: self._object = getattr(__import__(self._module, {}, {}, [self._name]), self._name) except ImportError as e: - if self._feature: + if feature: raise FeatureNotPresentError(self._feature, reason=f'Importing {self._name} failed: {e}') raise + if feature: + # for the case that the feature is hidden + feature.require() + name = self._as_name if self._deprecation is not None: from sage.misc.superseded import deprecation_cython as deprecation From 6912c1c90c32d40057c49c47a735730b5f461053 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 9 Aug 2022 10:26:44 +0200 Subject: [PATCH 007/228] 34185: fix doctest failure + pep8 fixes --- src/sage/doctest/control.py | 22 +++++++++++----------- src/sage/features/__init__.py | 22 +++++++++++++--------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index 93474290aca..08a457be818 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -1364,7 +1364,7 @@ def run(self): sage: DC = DocTestController(DF, [filename]) sage: DC.run() Running doctests with ID ... - Using --optional=sage + Using --optional=sage... Features to be detected: ... Doctesting 1 file. sage -t ....py @@ -1556,28 +1556,28 @@ def stringify(x): # Declaration of doctest strings ############################################################################### -test_hide=r"""{} -sage: next(graphs.fullerenes(20)) +test_hide=r"""r{quotmark} +{prompt}: next(graphs.fullerenes(20)) Traceback (most recent call last): ... FeatureNotPresentError: buckygen is not available. ... -sage: next(graphs.fullerenes(20)) # optional buckygen +{prompt}: next(graphs.fullerenes(20)) # optional buckygen Graph on 20 vertices -sage: len(list(graphs.fusenes(2))) +{prompt}: len(list(graphs.fusenes(2))) Traceback (most recent call last): ... FeatureNotPresentError: benzene is not available. ... -sage: len(list(graphs.fusenes(2))) # optional benzene +{prompt}: len(list(graphs.fusenes(2))) # optional benzene 1 -sage: from sage.matrix.matrix_space import get_matrix_class -sage: get_matrix_class(GF(25,'x'), 4, 4, False, 'meataxe') +{prompt}: from sage.matrix.matrix_space import get_matrix_class +{prompt}: get_matrix_class(GF(25,'x'), 4, 4, False, 'meataxe') Failed lazy import: sage.matrix.matrix_gfpn_dense is not available. ... -sage: get_matrix_class(GF(25,'x'), 4, 4, False, 'meataxe') # optional meataxe +{prompt}: get_matrix_class(GF(25,'x'), 4, 4, False, 'meataxe') # optional meataxe -{} -""".format('r"""', '"""') +{quotmark} +""".format(quotmark='"""', prompt='sage') # using prompt to hide these lines from _test_enough_doctests diff --git a/src/sage/features/__init__.py b/src/sage/features/__init__.py index 3987f49cd13..534436724fd 100644 --- a/src/sage/features/__init__.py +++ b/src/sage/features/__init__.py @@ -74,8 +74,10 @@ def __call__(cls, *args, **kwds): else: return type.__call__(cls, *args, **kwds) + _trivial_unique_representation_cache = dict() + class TrivialUniqueRepresentation(metaclass=TrivialClasscallMetaClass): r""" A trivial version of :class:`UniqueRepresentation` without Cython dependencies. @@ -92,6 +94,7 @@ def __classcall__(cls, *args, **options): cached = _trivial_unique_representation_cache[key] = type.__call__(cls, *args, **options) return cached + class Feature(TrivialUniqueRepresentation): r""" A feature of the runtime environment @@ -244,7 +247,10 @@ def _spkg_type(self): If no SPKG corresponds to this feature ``None`` is returned. """ from sage.misc.package import _spkg_type - return _spkg_type(self.name) + spkg = self.spkg + if not spkg: + spkg = self.name + return _spkg_type(spkg) def resolution(self): r""" @@ -379,8 +385,6 @@ def unhide(self): self._hidden = False - - class FeatureNotPresentError(RuntimeError): r""" A missing feature error. @@ -499,8 +503,6 @@ def __bool__(self): """ return bool(self.is_present) - - def __repr__(self): r""" TESTS:: @@ -514,6 +516,7 @@ def __repr__(self): _cache_package_systems = None + def package_systems(): """ Return a list of :class:`~sage.features.pkg_systems.PackageSystem` objects @@ -799,7 +802,9 @@ def absolute_filename(self) -> str: A :class:`FeatureNotPresentError` is raised if the file cannot be found:: sage: from sage.features import StaticFile - sage: StaticFile(name="no_such_file", filename="KaT1aihu", search_path=(), spkg="some_spkg", url="http://rand.om").absolute_filename() # optional - sage_spkg + sage: StaticFile(name="no_such_file", filename="KaT1aihu",\ + search_path=(), spkg="some_spkg",\ + url="http://rand.om").absolute_filename() # optional - sage_spkg Traceback (most recent call last): ... FeatureNotPresentError: no_such_file is not available. @@ -811,9 +816,8 @@ def absolute_filename(self) -> str: path = os.path.join(directory, self.filename) if os.path.isfile(path) or os.path.isdir(path): return os.path.abspath(path) - raise FeatureNotPresentError(self, - reason="{filename!r} not found in any of {search_path}".format(filename=self.filename, search_path=self.search_path), - resolution=self.resolution()) + reason = "{filename!r} not found in any of {search_path}".format(filename=self.filename, search_path=self.search_path) + raise FeatureNotPresentError(self, reason=reason, resolution=self.resolution()) class CythonFeature(Feature): From 187bdcfbd2941841d90fe057652b448ccb86c5fd Mon Sep 17 00:00:00 2001 From: Sebastian Oehms Date: Tue, 6 Sep 2022 09:30:40 +0200 Subject: [PATCH 008/228] 34185: fix typos --- src/sage/features/join_feature.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/features/join_feature.py b/src/sage/features/join_feature.py index 218246190c4..88f65245317 100644 --- a/src/sage/features/join_feature.py +++ b/src/sage/features/join_feature.py @@ -24,6 +24,7 @@ class JoinFeature(Feature): sage: F.is_present() FeatureTestResult('xxyyyy', False) """ + def __init__(self, name, features, spkg=None, url=None, description=None): """ TESTS: @@ -99,7 +100,7 @@ def hide(self): r""" Hide this feature and all its joined features. - EXAMPLES: + EXAMPLES:: sage: from sage.features.sagemath import sage__groups sage: f = sage__groups() @@ -120,9 +121,9 @@ def hide(self): def unhide(self): r""" - Hide this feature and all its joined features. + Revert what :meth:`hide` does. - EXAMPLES: + EXAMPLES:: sage: from sage.features.sagemath import sage__groups sage: f = sage__groups() From 13b95377fdd8b0b6228250b7927b947c97ad244c Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Thu, 16 Mar 2023 09:05:19 +0100 Subject: [PATCH 009/228] put the actual description first in issue templates ...so that relevant information appears when hovering over items of the issue list, and so that one can read the actual issue on the issue page without scrolling over a full page of boilerplate. Also remove the title from the Description section of the PR template (same rationale). --- .github/ISSUE_TEMPLATE/bug_report.yml | 54 +++++++++++------------ .github/ISSUE_TEMPLATE/feature_report.yml | 14 +++--- .github/PULL_REQUEST_TEMPLATE.md | 2 - 3 files changed, 34 insertions(+), 36 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index f4ce719dcb8..3bf2378f927 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -3,33 +3,6 @@ description: Report a bug title: "" labels: "t: bug" body: - - type: checkboxes - attributes: - label: Is there an existing issue for this? - description: Please search to see if an issue already exists for the bug you encountered. - options: - - label: I have searched the existing issues for a bug report that matches the one I want to file, without success. - required: true - - type: checkboxes - attributes: - label: Did you read the documentation and troubleshoot guide? - description: Please read [README.md](https://github.com/sagemath/sage/blob/develop/README.md) and [the Troubleshooting section in the Installation Guide](https://doc.sagemath.org/html/en/installation/troubles.html). - options: - - label: I have read the documentation and troubleshoot guide - required: true - - type: textarea - attributes: - label: Environment - description: | - examples: - - **OS**: Ubuntu 20.04 - - Sage Version: 9.2 - value: | - - **OS**: - - **Sage Version**: - render: markdown - validations: - required: true - type: textarea attributes: label: Steps To Reproduce @@ -60,3 +33,30 @@ body: Links? References? Anything that will give us more context about the issue you are encountering! validations: required: false + - type: textarea + attributes: + label: Environment + description: | + examples: + - **OS**: Ubuntu 20.04 + - Sage Version: 9.2 + value: | + - **OS**: + - **Sage Version**: + render: markdown + validations: + required: true + - type: checkboxes + attributes: + label: Is there an existing issue for this? + description: Please search to see if an issue already exists for the bug you encountered. + options: + - label: I have searched the existing issues for a bug report that matches the one I want to file, without success. + required: true + - type: checkboxes + attributes: + label: Did you read the documentation and troubleshoot guide? + description: Please read [README.md](https://github.com/sagemath/sage/blob/develop/README.md) and [the Troubleshooting section in the Installation Guide](https://doc.sagemath.org/html/en/installation/troubles.html). + options: + - label: I have read the documentation and troubleshoot guide + required: true diff --git a/.github/ISSUE_TEMPLATE/feature_report.yml b/.github/ISSUE_TEMPLATE/feature_report.yml index 5505a45143a..22db7acac68 100644 --- a/.github/ISSUE_TEMPLATE/feature_report.yml +++ b/.github/ISSUE_TEMPLATE/feature_report.yml @@ -3,13 +3,6 @@ description: Suggest an idea title: "<title>" labels: "t: enhancement" body: - - type: checkboxes - attributes: - label: Is there an existing issue for this? - description: Please search to see if an issue already exists for the bug you encountered. - options: - - label: I have searched the existing issues for a bug report that matches the one I want to file, without success. - required: true - type: textarea attributes: label: Problem Description @@ -34,3 +27,10 @@ body: description: Add any other context about the problem here. validations: required: false + - type: checkboxes + attributes: + label: Is there an existing issue for this? + description: Please search to see if an issue already exists for the bug you encountered. + options: + - label: I have searched the existing issues for a bug report that matches the one I want to file, without success. + required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 0ba5857b820..13a90cd2224 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,8 +3,6 @@ Please provide a concise, informative and self-explanatory title. Don't put issue numbers in there, do this in the PR body below. For example, instead of "Fixes #1234" use "Introduce new method to calculate 1+1" --> -### 📚 Description - <!-- Describe your changes here in detail --> <!-- Why is this change required? What problem does it solve? --> <!-- If it resolves an open issue, please link to the issue here. For example "Closes #1337" --> From 2f302e6c3f150331fe1e1dc95a12e9e8d09b81e8 Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba <marc@mezzarobba.net> Date: Thu, 16 Mar 2023 09:12:40 +0100 Subject: [PATCH 010/228] encourage PR submitters to remove checkboxes... ...that don't make sense with their particular PR --- .github/PULL_REQUEST_TEMPLATE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 13a90cd2224..555feed03d8 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -12,6 +12,7 @@ For example, instead of "Fixes #1234" use "Introduce new method to calculate 1+1 <!-- Put an `x` in all the boxes that apply. --> <!-- If your change requires a documentation PR, please link it appropriately --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> +<!-- Feel free to remove irrelevant items. --> - [ ] I have made sure that the title is self-explanatory and the description concisely explains the PR. - [ ] I have linked an issue or discussion. From d6d7630d1347165ce20f1cc9e5aebc98891b799d Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba <marc@mezzarobba.net> Date: Thu, 16 Mar 2023 17:17:16 +0100 Subject: [PATCH 011/228] issue templates: move the instructions back to the beginning ...while keeping the checklist at the end. With this version, I thought it made sense to apply the change to ftbfs issues too. I left the "Environment" section near the beginning in that case, though it makes for a small inconsistency wrt the bug report template. --- .github/ISSUE_TEMPLATE/bug_report.yml | 13 +++++----- .../failure_building_from_source.yml | 25 +++++++++---------- .github/ISSUE_TEMPLATE/feature_report.yml | 5 +++- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 3bf2378f927..3d69721d33b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -3,6 +3,11 @@ description: Report a bug title: "<title>" labels: "t: bug" body: + - type: markdown + attributes: + value: | + * Please search to see if an issue already exists for the bug you encountered. + * Please read [README.md](https://github.com/sagemath/sage/blob/develop/README.md) and [the Troubleshooting section in the Installation Guide](https://doc.sagemath.org/html/en/installation/troubles.html). - type: textarea attributes: label: Steps To Reproduce @@ -48,15 +53,9 @@ body: required: true - type: checkboxes attributes: - label: Is there an existing issue for this? - description: Please search to see if an issue already exists for the bug you encountered. + label: Checklist options: - label: I have searched the existing issues for a bug report that matches the one I want to file, without success. required: true - - type: checkboxes - attributes: - label: Did you read the documentation and troubleshoot guide? - description: Please read [README.md](https://github.com/sagemath/sage/blob/develop/README.md) and [the Troubleshooting section in the Installation Guide](https://doc.sagemath.org/html/en/installation/troubles.html). - options: - label: I have read the documentation and troubleshoot guide required: true diff --git a/.github/ISSUE_TEMPLATE/failure_building_from_source.yml b/.github/ISSUE_TEMPLATE/failure_building_from_source.yml index afe651bf14d..2575f5c9a10 100644 --- a/.github/ISSUE_TEMPLATE/failure_building_from_source.yml +++ b/.github/ISSUE_TEMPLATE/failure_building_from_source.yml @@ -4,20 +4,11 @@ title: "<title>" labels: ['c: build', 't: bug'] assignees: [] body: - - type: checkboxes + - type: markdown attributes: - label: Is there an existing issue for this? - description: Please search to see if an issue already exists for the bug you encountered. - options: - - label: I have searched the existing issues for a bug report that matches the one I want to file, without success. - required: true - - type: checkboxes - attributes: - label: Did you read the documentation and troubleshoot guide? - description: Please read [README.md](https://github.com/sagemath/sage/blob/develop/README.md) and [the Troubleshooting sectionin the Installation Guide](https://doc.sagemath.org/html/en/installation/troubles.html). - options: - - label: I have read the documentation and troubleshoot guide - required: true + value: | + * Please search to see if an issue already exists for the bug you encountered. + * Please read [README.md](https://github.com/sagemath/sage/blob/develop/README.md) and [the Troubleshooting section in the Installation Guide](https://doc.sagemath.org/html/en/installation/troubles.html). - type: textarea attributes: label: Environment @@ -65,3 +56,11 @@ body: Links? References? Anything that will give us more context about the issue you are encountering! validations: required: false + - type: checkboxes + attributes: + label: Checklist + options: + - label: I have searched the existing issues for a bug report that matches the one I want to file, without success. + required: true + - label: I have read the documentation and troubleshoot guide + required: true diff --git a/.github/ISSUE_TEMPLATE/feature_report.yml b/.github/ISSUE_TEMPLATE/feature_report.yml index 22db7acac68..9f291204fd3 100644 --- a/.github/ISSUE_TEMPLATE/feature_report.yml +++ b/.github/ISSUE_TEMPLATE/feature_report.yml @@ -3,6 +3,10 @@ description: Suggest an idea title: "<title>" labels: "t: enhancement" body: + - type: markdown + attributes: + value: | + * Please search to see if an issue already exists for the bug you encountered. - type: textarea attributes: label: Problem Description @@ -30,7 +34,6 @@ body: - type: checkboxes attributes: label: Is there an existing issue for this? - description: Please search to see if an issue already exists for the bug you encountered. options: - label: I have searched the existing issues for a bug report that matches the one I want to file, without success. required: true From 0b02cf4dd4be47a1711ad54e8f98133c34824d77 Mon Sep 17 00:00:00 2001 From: Antonio Rojas <arojas@archlinux.org> Date: Fri, 10 Dec 2021 19:24:50 +0100 Subject: [PATCH 012/228] Update bliss to 0.77 --- build/pkgs/bliss/checksums.ini | 9 +++++---- build/pkgs/bliss/dependencies | 2 +- build/pkgs/bliss/package-version.txt | 2 +- build/pkgs/bliss/spkg-install.in | 6 ++++-- build/pkgs/bliss/spkg-src | 28 ---------------------------- 5 files changed, 11 insertions(+), 36 deletions(-) delete mode 100755 build/pkgs/bliss/spkg-src diff --git a/build/pkgs/bliss/checksums.ini b/build/pkgs/bliss/checksums.ini index e97d89587bf..0c1ebf647bc 100644 --- a/build/pkgs/bliss/checksums.ini +++ b/build/pkgs/bliss/checksums.ini @@ -1,4 +1,5 @@ -tarball=bliss-VERSION.tar.gz -sha1=1da8f098046824fbfff4c64c337e28b2a082f74f -md5=452aea8737d3c4ad0d8ff39180be8004 -cksum=2193930007 +tarball=bliss-VERSION.zip +sha1=c91c9dcbc11d66ffbcf6415e09ebe793df37be2a +md5=5707cbfd9fd00980571c64ab3584c505 +cksum=1626493724 +upstream_url=https://users.aalto.fi/~tjunttil/bliss/downloads/bliss-VERSION.zip diff --git a/build/pkgs/bliss/dependencies b/build/pkgs/bliss/dependencies index 4f00de20375..c225c495cc6 100644 --- a/build/pkgs/bliss/dependencies +++ b/build/pkgs/bliss/dependencies @@ -1,4 +1,4 @@ -# no dependencies +| cmake ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/bliss/package-version.txt b/build/pkgs/bliss/package-version.txt index e93ee1376fa..9e1e206c410 100644 --- a/build/pkgs/bliss/package-version.txt +++ b/build/pkgs/bliss/package-version.txt @@ -1 +1 @@ -0.73+debian-1+sage-2016-08-02.p0 +0.77 diff --git a/build/pkgs/bliss/spkg-install.in b/build/pkgs/bliss/spkg-install.in index aaf4c3037bc..4074f2e3e4a 100644 --- a/build/pkgs/bliss/spkg-install.in +++ b/build/pkgs/bliss/spkg-install.in @@ -1,4 +1,6 @@ cd src -sdh_configure --disable-gmp +sdh_cmake -DUSE_GMP=OFF -DCMAKE_VERBOSE_MAKEFILE=ON sdh_make -sdh_make_install +install -D src/*.hh -t $SAGE_LOCAL/include/bliss/ +install libbliss.so -t $SAGE_LOCAL/lib/ +install bliss -t $SAGE_LOCAL/bin/ diff --git a/build/pkgs/bliss/spkg-src b/build/pkgs/bliss/spkg-src deleted file mode 100755 index 90073233b77..00000000000 --- a/build/pkgs/bliss/spkg-src +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh -# -# creates the tarball in the current dir, to be moved to ../../../upstream -# -# adapted from cliquer/spkg-src - -die () { - echo >&2 "$@" - exit 1 -} - -rm -rf bliss/ -git clone -b sage_package https://github.com/mkoeppe/bliss.git || die "Failed to git clone" -cd bliss/ - -VERSION=`autoconf --trace='AC_INIT:$2'` -libtoolize || die "Failed to autoreconf" -autoreconf -fi || die "Failed to autoreconf" -automake --add-missing --copy || die "automake failed" -./configure || die "configure failed" - -rm -f bliss-$VERSION.tar.gz -make dist || die "make dist failed" -mv bliss-$VERSION.tar.gz ../ -cd .. -rm -rf bliss/ - - From 321bd7e95a62953df6a95a9d9d206e61559a13d1 Mon Sep 17 00:00:00 2001 From: Antonio Rojas <arojas@archlinux.org> Date: Fri, 10 Dec 2021 18:54:53 +0100 Subject: [PATCH 013/228] Port to changes in canonical_form --- src/sage/graphs/bliss.pyx | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/sage/graphs/bliss.pyx b/src/sage/graphs/bliss.pyx index 8c99ae1a184..717edd0b41b 100644 --- a/src/sage/graphs/bliss.pyx +++ b/src/sage/graphs/bliss.pyx @@ -47,22 +47,22 @@ cdef extern from "bliss/graph.hh" namespace "bliss": cdef cppclass Graph(AbstractGraph): Graph(const unsigned int) void add_edge(const unsigned int, const unsigned int) - void find_automorphisms(Stats&, void (*)(void*, unsigned int, - const unsigned int*), void*) void change_color(const unsigned int, const unsigned int) - const unsigned int* canonical_form(Stats&, void (*)(void*, unsigned int, - const unsigned int*), void*) + const unsigned int* canonical_form(Stats&) + +cdef extern from "bliss/digraph.hh" namespace "bliss": cdef cppclass Digraph(AbstractGraph): Digraph(const unsigned int) void add_edge(const unsigned int, const unsigned int) - void find_automorphisms(Stats&, void (*)(void*, unsigned int, - const unsigned int*), void*) - void change_color(const unsigned int, const unsigned int) - const unsigned int* canonical_form(Stats&, void (*)(void*, unsigned int, - const unsigned int*), void*) + void change_color(const unsigned int, const unsigned int); + const unsigned int* canonical_form(Stats&) unsigned int get_hash() +cdef extern from "bliss_find_automorphisms.h": + + void bliss_find_automorphisms(Graph*, void (*)(void*, unsigned int, const unsigned int*), void*, Stats&) + void bliss_find_automorphisms(Digraph*, void (*)(void*, unsigned int, const unsigned int*), void*, Stats&) cdef int encoding_numbits(int n): r""" @@ -124,10 +124,6 @@ cdef void add_gen(void *user_param, unsigned int n, const unsigned int *aut): sig_free(done) - -cdef void empty_hook(void *user_param, unsigned int n, const unsigned int *aut): - return - ##################################################### # constructing bliss graphs from edge lists ##################################################### @@ -346,10 +342,10 @@ cdef canonical_form_from_edge_list(int Vnr, list Vout, list Vin, int Lnr=1, list if directed: d = bliss_digraph_from_labelled_edges(Vnr, Lnr, Vout, Vin, labels, partition) - aut = d.canonical_form(s, empty_hook, NULL) + aut = d.canonical_form(s) else: g = bliss_graph_from_labelled_edges(Vnr, Lnr, Vout, Vin, labels, partition) - aut = g.canonical_form(s, empty_hook, NULL) + aut = g.canonical_form(s) for i in range(len(Vout)): x = Vout[i] From d0bc4ed984b3e2a73eef358482d8678892bd36b2 Mon Sep 17 00:00:00 2001 From: Antonio Rojas <arojas@archlinux.org> Date: Sun, 26 Dec 2021 14:05:37 +0100 Subject: [PATCH 014/228] Reimplement old find_automorphisms API in an external header --- src/sage/graphs/bliss.pyx | 4 ++-- src/sage/graphs/bliss_find_automorphisms.h | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 src/sage/graphs/bliss_find_automorphisms.h diff --git a/src/sage/graphs/bliss.pyx b/src/sage/graphs/bliss.pyx index 717edd0b41b..0670069067d 100644 --- a/src/sage/graphs/bliss.pyx +++ b/src/sage/graphs/bliss.pyx @@ -639,11 +639,11 @@ cdef automorphism_group_gens_from_edge_list(int Vnr, Vout, Vin, int Lnr=1, label if directed: d = bliss_digraph_from_labelled_edges(Vnr, Lnr, Vout, Vin, labels, partition) - d.find_automorphisms(s, add_gen, <void*>data) + bliss_find_automorphisms(d, add_gen, <void*>data, s) del d else: g = bliss_graph_from_labelled_edges(Vnr, Lnr, Vout, Vin, labels, partition) - g.find_automorphisms(s, add_gen, <void*>data) + bliss_find_automorphisms(g, add_gen, <void*>data, s) del g return [[cyc for cyc in gen if cyc[0] is not None] for gen in gens] diff --git a/src/sage/graphs/bliss_find_automorphisms.h b/src/sage/graphs/bliss_find_automorphisms.h new file mode 100644 index 00000000000..a2c084a163e --- /dev/null +++ b/src/sage/graphs/bliss_find_automorphisms.h @@ -0,0 +1,22 @@ +#include <bliss/graph.hh> +#include <bliss/digraph.hh> + +inline void bliss_find_automorphisms(bliss::Graph *graph, void (*hook)(void *user_param, unsigned int n, const unsigned int *aut), void *hook_user_param, bliss::Stats s) +{ + auto report_aut = [&](unsigned int n, const unsigned int *aut) -> void { + if(hook) + (*hook)(hook_user_param, n, aut); + }; + + graph->find_automorphisms(s, report_aut); +} + +inline void bliss_find_automorphisms(bliss::Digraph *graph, void (*hook)(void *user_param, unsigned int n, const unsigned int *aut), void *hook_user_param, bliss::Stats s) +{ + auto report_aut = [&](unsigned int n, const unsigned int *aut) -> void { + if(hook) + (*hook)(hook_user_param, n, aut); + }; + + graph->find_automorphisms(s, report_aut); +} From f2bfae0d2b07b61b5f063f61358aa527171956ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bissey?= <frp.bissey@gmail.com> Date: Tue, 14 Dec 2021 10:26:08 +1300 Subject: [PATCH 015/228] update bliss' SPKG.rst --- build/pkgs/bliss/SPKG.rst | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/build/pkgs/bliss/SPKG.rst b/build/pkgs/bliss/SPKG.rst index 875bc39a2df..77407f16ac7 100644 --- a/build/pkgs/bliss/SPKG.rst +++ b/build/pkgs/bliss/SPKG.rst @@ -10,17 +10,21 @@ canonical forms of graphs. License ------- -LGPL +LGPL3 Upstream Contact ---------------- -Bliss is currently being maintained by Tommi Junttila and Petteri Kaski. +Bliss is currently being maintained by Tommi Junttila at + +https://users.aalto.fi/~tjunttil/bliss/index.html + +Bliss used to be maintained by Tommi Junttila and Petteri Kaski up to version 0.73 at http://www.tcs.tkk.fi/Software/bliss/index.html -We apply patches generated from https://github.com/mkoeppe/bliss (branch -apply_debian_patches) as our upstream. This tracks the patches from the -Debian package, adding an autotools build system and adjusting the -include file locations. +Dependencies +------------ + +None From 0fc563cc566ac4e9d0b713195d0a4fb138abca06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bissey?= <frp.bissey@gmail.com> Date: Tue, 14 Dec 2021 10:25:38 +1300 Subject: [PATCH 016/228] patch an install target for bliss --- .../bliss/patches/bliss-0.77-install.patch | 32 +++++++++++++++++++ build/pkgs/bliss/spkg-install.in | 4 +-- 2 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 build/pkgs/bliss/patches/bliss-0.77-install.patch diff --git a/build/pkgs/bliss/patches/bliss-0.77-install.patch b/build/pkgs/bliss/patches/bliss-0.77-install.patch new file mode 100644 index 00000000000..caab14aa40f --- /dev/null +++ b/build/pkgs/bliss/patches/bliss-0.77-install.patch @@ -0,0 +1,32 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 01ed093..cfdb0a6 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -62,3 +62,27 @@ if(USE_GMP) + target_link_libraries(bliss-executable ${GMP_LIBRARIES}) + endif(USE_GMP) + set_target_properties(bliss-executable PROPERTIES OUTPUT_NAME bliss) ++ ++include(GNUInstallDirs) ++ ++set( ++ BLISS_HEADERS ++ src/bliss_C.h ++ src/uintseqhash.hh ++ src/abstractgraph.hh ++ src/stats.hh ++ src/digraph.hh ++ src/defs.hh ++ src/heap.hh ++ src/graph.hh ++ src/partition.hh ++ src/kqueue.hh ++ src/utils.hh ++ src/orbit.hh ++ src/timer.hh ++ src/bignum.hh ++) ++ ++install(TARGETS bliss-executable RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) ++install(TARGETS bliss LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) ++install(FILES ${BLISS_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/bliss) diff --git a/build/pkgs/bliss/spkg-install.in b/build/pkgs/bliss/spkg-install.in index 4074f2e3e4a..4124a2338e5 100644 --- a/build/pkgs/bliss/spkg-install.in +++ b/build/pkgs/bliss/spkg-install.in @@ -1,6 +1,4 @@ cd src sdh_cmake -DUSE_GMP=OFF -DCMAKE_VERBOSE_MAKEFILE=ON sdh_make -install -D src/*.hh -t $SAGE_LOCAL/include/bliss/ -install libbliss.so -t $SAGE_LOCAL/lib/ -install bliss -t $SAGE_LOCAL/bin/ +sdh_make_install From 363cdb986b06fcdc9920f6facdb3a820f68f1b1a Mon Sep 17 00:00:00 2001 From: Antonio Rojas <arojas@archlinux.org> Date: Sat, 25 Mar 2023 11:35:16 +0100 Subject: [PATCH 017/228] Fix pycodestyle --- src/sage/graphs/bliss.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/bliss.pyx b/src/sage/graphs/bliss.pyx index 0670069067d..f64be1c4d30 100644 --- a/src/sage/graphs/bliss.pyx +++ b/src/sage/graphs/bliss.pyx @@ -55,7 +55,7 @@ cdef extern from "bliss/digraph.hh" namespace "bliss": cdef cppclass Digraph(AbstractGraph): Digraph(const unsigned int) void add_edge(const unsigned int, const unsigned int) - void change_color(const unsigned int, const unsigned int); + void change_color(const unsigned int, const unsigned int) const unsigned int* canonical_form(Stats&) unsigned int get_hash() From 945744314d528893fb1915ef02c00df916a82452 Mon Sep 17 00:00:00 2001 From: Karan Handa <karan.handa_ug23@ashoka.edu.in> Date: Mon, 10 Apr 2023 20:59:21 +0530 Subject: [PATCH 018/228] Change round default from "away" to "even" Change round default along with examples. --- src/sage/rings/rational.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index 0e9d1f35f47..8c2fdbb098d 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -3338,7 +3338,7 @@ cdef class Rational(sage.structure.element.FieldElement): mpz_tdiv_q(n.value, mpq_numref(self.value), mpq_denref(self.value)) return n - def round(Rational self, mode="away"): + def round(Rational self, mode="even"): """ Return the nearest integer to ``self``, rounding away from 0 by default, for consistency with the builtin Python round. @@ -3362,13 +3362,13 @@ cdef class Rational(sage.structure.element.FieldElement): EXAMPLES:: sage: (9/2).round() - 5 + 4 sage: n = 4/3; n.round() 1 sage: n = -17/4; n.round() -4 sage: n = -5/2; n.round() - -3 + -2 sage: n.round("away") -3 sage: n.round("up") From 3f0582270a87e51e069d5fed78016b6c57d623b9 Mon Sep 17 00:00:00 2001 From: Karan Handa <karan.handa_ug23@ashoka.edu.in> Date: Mon, 10 Apr 2023 21:02:59 +0530 Subject: [PATCH 019/228] Change docstring --- src/sage/rings/rational.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index 8c2fdbb098d..29286b0db3f 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -3340,8 +3340,8 @@ cdef class Rational(sage.structure.element.FieldElement): def round(Rational self, mode="even"): """ - Return the nearest integer to ``self``, rounding away from 0 by - default, for consistency with the builtin Python round. + Return the nearest integer to ``self``, rounding to even by + default for consistency with the builtin Python round. INPUT: From 6fe18a11a186ecbfeb2e74f79962850d2a225a2f Mon Sep 17 00:00:00 2001 From: Aram Dermenjian <aram.dermenjian.math@gmail.com> Date: Thu, 27 Apr 2023 10:54:46 +0100 Subject: [PATCH 020/228] Initial addition of Russian style tableau --- src/sage/combinat/output.py | 63 ++++++++++++++++++++++++++++++++++-- src/sage/combinat/tableau.py | 52 ++++++++++++++++++++++++++++- 2 files changed, 111 insertions(+), 4 deletions(-) diff --git a/src/sage/combinat/output.py b/src/sage/combinat/output.py index 2e2a8aa5f39..398fdefc2f8 100644 --- a/src/sage/combinat/output.py +++ b/src/sage/combinat/output.py @@ -307,12 +307,22 @@ def end_line(r): end_line=lambda r: r'\\' # now we draw the array - tex=r'\raisebox{-.6ex}{$\begin{array}[%s]{*{%s}c}'%(align,max(map(len,array))) + raisebox_start = r'\raisebox{-.6ex}{' + raisebox_end = r'}' + lr_start = r'\lr{' + lr_end = r'}' + if Tableaux.options.convention == "Russian": + raisebox_start += r'\rotatebox{45}{' + raisebox_end += r'}' + lr_start += r'\rotatebox{-45}{' + lr_end += r'}' + + tex=r'%s$\begin{array}[%s]{*{%s}c}'%(raisebox_start,align,max(map(len,array))) tex+=end_line(0)+'\n' for r in range(len(array)): - tex+='&'.join('' if c is None else r'\lr{%s}'%(c,) for c in array[r]) + tex+='&'.join('' if c is None else r'%s%s%s'%(lr_start,c,lr_end) for c in array[r]) tex+=end_line(r+1)+'\n' - return tex+r'\end{array}$}' + return tex+r'\end{array}$'+raisebox_end def ascii_art_table(data, use_unicode=False, convention="English"): @@ -380,13 +390,60 @@ def ascii_art_table(data, use_unicode=False, convention="English"): uh = unicodedata.lookup('BOX DRAWINGS LIGHT UP AND HORIZONTAL') dh = unicodedata.lookup('BOX DRAWINGS LIGHT DOWN AND HORIZONTAL') vh = unicodedata.lookup('BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL') + urdl = unicodedata.lookup('BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT') + uldr = unicodedata.lookup('BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT') + x = unicodedata.lookup('BOX DRAWINGS LIGHT DIAGONAL CROSS') from sage.typeset.unicode_art import unicode_art as art else: v = '|' h = '-' dl = dr = ul = ur = vr = vl = uh = dh = vh = '+' + urdl = '/' + uldr = '\\' + x = 'X' from sage.typeset.ascii_art import ascii_art as art + if Tableaux.options.convention == "Russian": + if not data: + return urdl + uldr + '\n' + uldr + urdl + + str_tab = [[str(d) for d in row] for row in data] + col_widths = [2] * len(str_tab[0]) + for row in str_tab: + for i, e in enumerate(row): + col_widths[i] = max(col_widths[i], len(e)) + col_width = max(col_widths) + 1 + max_height = max([a + len(str_tab[a]) for a in range(len(str_tab))]) + empty_col = ' ' * (col_width * 2) + str_list = [] + for i in range(max_height): + # Get the row with the number on it + st = ' ' + ' ' * ((max_height - i - 1) * col_width) + for a in range(i + 1): + b = i - a + if a == 0: + st += uldr + else: + st += x + if len(str_tab[b:]) > 0 and len(str_tab[b][a:]) > 0: + st += str_tab[b][a].rjust(col_width,' ').ljust(col_width * 2 - 1, ' ') + else: + st += ' '*(col_width * 2 - 1) + if b == 0: + st += urdl + + # Do all of the additional rows + for j in range(col_width - 1, 0, -1): + st2 = ' ' + ' ' * ((max_height - i - 1) * col_width) + st2 += (' ' * j + uldr + ' ' * (2 * (col_width - j) - 1) + urdl + ' ' * (j - 1)) * (i + 1) + str_list.append(st2) + str_list.append(st) + import re + mm = min([len(re.search('^ +', l)[0]) for l in str_list]) - 1 + str_list = [l[mm:] for l in str_list] + str_list.reverse() + return '\n'.join(str_list) + if not data: return dr + dl + '\n' + ur + ul diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 0b327db6c06..927be3263f5 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -510,7 +510,25 @@ def _ascii_art_table(self, use_unicode=False): +---+---+---+ | 1 | 2 | 3 | +---+---+---+ + sage: Tableaux.options.convention="russian" + sage: print(t._repr_diagram()) + 1 2 3 + 4 5 + sage: print(t._ascii_art_table()) + \ X 5 X 3 / + \ / \ / \ / + \ / \ / \ / + \ 4 X 2 / + \ / \ / + \ / \ / + \ 1 / + \ / + \ / sage: t = Tableau([]); print(t._ascii_art_table()) + /\ + \/ + sage: Tableaux.options.convention="french" + sage: print(t._ascii_art_table()) ++ ++ sage: Tableaux.options._reset() @@ -546,6 +564,20 @@ def _ascii_art_table(self, use_unicode=False): +----+----+----+---+ | 1 | 2 | 15 | 7 | +----+----+----+---+ + sage: Tableaux.options.convention="russian" + sage: ascii_art(t) + \ 9 X 10 X 6 X 7 / + \ / \ / \ / \ / + \ / \ / \ / \ / + \ 8 X 5 X 15 / + \ / \ / \ / + \ / \ / \ / + \ 12 X 2 / + \ / \ / + \ / \ / + \ 1 / + \ / + \ / sage: Tableaux.options._reset() Unicode version:: @@ -573,6 +605,20 @@ def _ascii_art_table(self, use_unicode=False): ├────┼────┼────┬───┐ │ 1 │ 2 │ 15 │ 7 │ └────┴────┴────┴───┘ + sage: Tableaux.options.convention="russian" + sage: print(t._ascii_art_table(use_unicode=True)) + ╲ 9 ╳ 10 ╳ ╳ 7 ╱ + ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ + ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ + ╲ 8 ╳ 5 ╳ 15 ╱ + ╲ ╱ ╲ ╱ ╲ ╱ + ╲ ╱ ╲ ╱ ╲ ╱ + ╲ 12 ╳ 2 ╱ + ╲ ╱ ╲ ╱ + ╲ ╱ ╲ ╱ + ╲ 1 ╱ + ╲ ╱ + ╲ ╱ sage: Tableaux.options._reset() """ from sage.combinat.output import ascii_art_table @@ -5499,7 +5545,11 @@ class options(GlobalOptions): case_sensitive=False) convention = dict(default="English", description='Sets the convention used for displaying tableaux and partitions', - values=dict(English='use the English convention',French='use the French convention'), + values=dict( + English='use the English convention', + French='use the French convention', + Russian='use the Russian convention', + ), case_sensitive=False) notation = dict(alt_name="convention") From ba40be92eb957ee34c2ddceadbe941d70b438cc3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Tue, 2 May 2023 23:09:14 -0700 Subject: [PATCH 021/228] sage -docbuild all FORMAT: Run 'make doc-FORMAT' --- src/sage_docbuild/__main__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sage_docbuild/__main__.py b/src/sage_docbuild/__main__.py index c9b37120976..c3a7210fd1c 100644 --- a/src/sage_docbuild/__main__.py +++ b/src/sage_docbuild/__main__.py @@ -59,6 +59,7 @@ import logging import argparse import os +import shlex import sys import sphinx.ext.intersphinx from sage.env import SAGE_DOC_SRC @@ -441,6 +442,8 @@ def main(): if not name or not typ: parser.print_help() sys.exit(1) + elif name == 'all': + sys.exit(os.system(f'cd {shlex.quote(SAGE_DOC_SRC)} && ${{MAKE-make}} doc-{typ}')) # Set up module-wide logging. setup_logger(args.verbose, args.color) From 0d58b9fd2898ac98c395fa9fb43347a241f39442 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Tue, 2 May 2023 23:24:58 -0700 Subject: [PATCH 022/228] src/doc/en/installation/conda.rst: Explain how to docbuild --- src/doc/en/installation/conda.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/doc/en/installation/conda.rst b/src/doc/en/installation/conda.rst index b97be2eb971..5228611de3b 100644 --- a/src/doc/en/installation/conda.rst +++ b/src/doc/en/installation/conda.rst @@ -178,3 +178,8 @@ After editing any Cython files, rebuild the Sage library using:: In order to update the conda environment later, you can run:: $ mamba env update --file src/environment-dev.yml --name sage-dev + +To build the documentation, use:: + + $ pip install --no-build-isolation -v -v --editable ./pkgs/sage-docbuild + $ sage --docbuild all html From b219e9306681c1aaa6280ef502d23fee7e0c0509 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Tue, 2 May 2023 23:49:33 -0700 Subject: [PATCH 023/228] src/sage_docbuild/__main__.py: Run 'make' with parallelization --- src/sage_docbuild/__main__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage_docbuild/__main__.py b/src/sage_docbuild/__main__.py index c3a7210fd1c..d7984c7fc0f 100644 --- a/src/sage_docbuild/__main__.py +++ b/src/sage_docbuild/__main__.py @@ -443,7 +443,8 @@ def main(): parser.print_help() sys.exit(1) elif name == 'all': - sys.exit(os.system(f'cd {shlex.quote(SAGE_DOC_SRC)} && ${{MAKE-make}} doc-{typ}')) + sys.exit(os.system(f'cd {shlex.quote(SAGE_DOC_SRC)} ' + f'&& ${{MAKE:-make}} -j${{SAGE_NUM_THREADS_PARALLEL:-1}} doc-{typ}')) # Set up module-wide logging. setup_logger(args.verbose, args.color) From e0538950d79659c06da8b6d556cf35cd088286a3 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian <aram.dermenjian.math@gmail.com> Date: Fri, 12 May 2023 15:10:02 +0100 Subject: [PATCH 024/228] Adding doc tests and some additional functions --- src/sage/combinat/output.py | 276 +++++++++++++++++++++++++++++------ src/sage/combinat/tableau.py | 63 +++++++- 2 files changed, 289 insertions(+), 50 deletions(-) diff --git a/src/sage/combinat/output.py b/src/sage/combinat/output.py index 398fdefc2f8..f4a13d968c8 100644 --- a/src/sage/combinat/output.py +++ b/src/sage/combinat/output.py @@ -169,6 +169,70 @@ def tex_from_array(array, with_lines=True): &&\lr{3}\\ \end{array}$} } + sage: Tableaux.options.convention="russian" + sage: print(tex_from_array([[1,2,3],[4,5]])) + {\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}} + \raisebox{-.6ex}{\rotatebox{45}{$\begin{array}[t]{*{3}c}\cline{1-2} + \lr{\rotatebox{-45}{4}}&\lr{\rotatebox{-45}{5}}\\\cline{1-3} + \lr{\rotatebox{-45}{1}}&\lr{\rotatebox{-45}{2}}&\lr{\rotatebox{-45}{3}}\\\cline{1-3} + \end{array}$}} + } + sage: print(tex_from_array([[1,2,3],[4,5]], with_lines=False)) + {\def\lr#1{\multicolumn{1}{@{\hspace{.6ex}}c@{\hspace{.6ex}}}{\raisebox{-.3ex}{$#1$}}} + \raisebox{-.6ex}{\rotatebox{45}{$\begin{array}[t]{*{3}c}\\ + \lr{\rotatebox{-45}{4}}&\lr{\rotatebox{-45}{5}}\\ + \lr{\rotatebox{-45}{1}}&\lr{\rotatebox{-45}{2}}&\lr{\rotatebox{-45}{3}}\\ + \end{array}$}} + } + sage: print(tex_from_array([[1,2,3],[4,5,6,7],[8]])) + {\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}} + \raisebox{-.6ex}{\rotatebox{45}{$\begin{array}[t]{*{4}c}\cline{1-1} + \lr{\rotatebox{-45}{8}}\\\cline{1-4} + \lr{\rotatebox{-45}{4}}&\lr{\rotatebox{-45}{5}}&\lr{\rotatebox{-45}{6}}&\lr{\rotatebox{-45}{7}}\\\cline{1-4} + \lr{\rotatebox{-45}{1}}&\lr{\rotatebox{-45}{2}}&\lr{\rotatebox{-45}{3}}\\\cline{1-3} + \end{array}$}} + } + sage: print(tex_from_array([[1,2,3],[4,5,6,7],[8]], with_lines=False)) + {\def\lr#1{\multicolumn{1}{@{\hspace{.6ex}}c@{\hspace{.6ex}}}{\raisebox{-.3ex}{$#1$}}} + \raisebox{-.6ex}{\rotatebox{45}{$\begin{array}[t]{*{4}c}\\ + \lr{\rotatebox{-45}{8}}\\ + \lr{\rotatebox{-45}{4}}&\lr{\rotatebox{-45}{5}}&\lr{\rotatebox{-45}{6}}&\lr{\rotatebox{-45}{7}}\\ + \lr{\rotatebox{-45}{1}}&\lr{\rotatebox{-45}{2}}&\lr{\rotatebox{-45}{3}}\\ + \end{array}$}} + } + sage: print(tex_from_array([[None,None,3],[None,5,6,7],[8]])) + {\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}} + \raisebox{-.6ex}{\rotatebox{45}{$\begin{array}[t]{*{4}c}\cline{1-1} + \lr{\rotatebox{-45}{8}}\\\cline{1-4} + &\lr{\rotatebox{-45}{5}}&\lr{\rotatebox{-45}{6}}&\lr{\rotatebox{-45}{7}}\\\cline{2-4} + &&\lr{\rotatebox{-45}{3}}\\\cline{3-3} + \end{array}$}} + } + sage: print(tex_from_array([[None,None,3],[None,5,6,7],[None,8]])) + {\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}} + \raisebox{-.6ex}{\rotatebox{45}{$\begin{array}[t]{*{4}c}\cline{2-2} + &\lr{\rotatebox{-45}{8}}\\\cline{2-4} + &\lr{\rotatebox{-45}{5}}&\lr{\rotatebox{-45}{6}}&\lr{\rotatebox{-45}{7}}\\\cline{2-4} + &&\lr{\rotatebox{-45}{3}}\\\cline{3-3} + \end{array}$}} + } + sage: print(tex_from_array([[None,None,3],[None,5,6,7],[8]], with_lines=False)) + {\def\lr#1{\multicolumn{1}{@{\hspace{.6ex}}c@{\hspace{.6ex}}}{\raisebox{-.3ex}{$#1$}}} + \raisebox{-.6ex}{\rotatebox{45}{$\begin{array}[t]{*{4}c}\\ + \lr{\rotatebox{-45}{8}}\\ + &\lr{\rotatebox{-45}{5}}&\lr{\rotatebox{-45}{6}}&\lr{\rotatebox{-45}{7}}\\ + &&\lr{\rotatebox{-45}{3}}\\ + \end{array}$}} + } + sage: print(tex_from_array([[None,None,3],[None,5,6,7],[None,8]], with_lines=False)) + {\def\lr#1{\multicolumn{1}{@{\hspace{.6ex}}c@{\hspace{.6ex}}}{\raisebox{-.3ex}{$#1$}}} + \raisebox{-.6ex}{\rotatebox{45}{$\begin{array}[t]{*{4}c}\\ + &\lr{\rotatebox{-45}{8}}\\ + &\lr{\rotatebox{-45}{5}}&\lr{\rotatebox{-45}{6}}&\lr{\rotatebox{-45}{7}}\\ + &&\lr{\rotatebox{-45}{3}}\\ + \end{array}$}} + } + sage: Tableaux.options._reset() """ lr=lr_macro.substitute(bar='|' if with_lines else '') @@ -239,6 +303,30 @@ def tex_from_array_tuple(a_tuple, with_lines=True): &\lr{6}&\lr{7}\\ \end{array}$} } + sage: Tableaux.options.convention="russian" + sage: print(tex_from_array_tuple([[[1,2,3],[4,5]],[],[[None,6,7],[None,8],[9]]])) + {\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}} + \raisebox{-.6ex}{\rotatebox{45}{$\begin{array}[t]{*{3}c}\cline{1-2} + \lr{\rotatebox{-45}{4}}&\lr{\rotatebox{-45}{5}}\\\cline{1-3} + \lr{\rotatebox{-45}{1}}&\lr{\rotatebox{-45}{2}}&\lr{\rotatebox{-45}{3}}\\\cline{1-3} + \end{array}$}},\emptyset,\raisebox{-.6ex}{\rotatebox{45}{$\begin{array}[t]{*{3}c}\cline{1-1} + \lr{\rotatebox{-45}{9}}\\\cline{1-2} + &\lr{\rotatebox{-45}{8}}\\\cline{2-3} + &\lr{\rotatebox{-45}{6}}&\lr{\rotatebox{-45}{7}}\\\cline{2-3} + \end{array}$}} + } + sage: print(tex_from_array_tuple([[[1,2,3],[4,5]],[],[[None,6,7],[None,8],[9]]], with_lines=False)) + {\def\lr#1{\multicolumn{1}{@{\hspace{.6ex}}c@{\hspace{.6ex}}}{\raisebox{-.3ex}{$#1$}}} + \raisebox{-.6ex}{\rotatebox{45}{$\begin{array}[t]{*{3}c}\\ + \lr{\rotatebox{-45}{4}}&\lr{\rotatebox{-45}{5}}\\ + \lr{\rotatebox{-45}{1}}&\lr{\rotatebox{-45}{2}}&\lr{\rotatebox{-45}{3}}\\ + \end{array}$}},\emptyset,\raisebox{-.6ex}{\rotatebox{45}{$\begin{array}[t]{*{3}c}\\ + \lr{\rotatebox{-45}{9}}\\ + &\lr{\rotatebox{-45}{8}}\\ + &\lr{\rotatebox{-45}{6}}&\lr{\rotatebox{-45}{7}}\\ + \end{array}$}} + } + sage: Tableaux.options._reset() """ lr=lr_macro.substitute(bar='|' if with_lines else '') @@ -377,6 +465,9 @@ def ascii_art_table(data, use_unicode=False, convention="English"): │ 2 │ └───┘ """ + if convention == "Russian": + return ascii_art_table_russian(data, use_unicode) + if use_unicode: import unicodedata v = unicodedata.lookup('BOX DRAWINGS LIGHT VERTICAL') @@ -390,60 +481,13 @@ def ascii_art_table(data, use_unicode=False, convention="English"): uh = unicodedata.lookup('BOX DRAWINGS LIGHT UP AND HORIZONTAL') dh = unicodedata.lookup('BOX DRAWINGS LIGHT DOWN AND HORIZONTAL') vh = unicodedata.lookup('BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL') - urdl = unicodedata.lookup('BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT') - uldr = unicodedata.lookup('BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT') - x = unicodedata.lookup('BOX DRAWINGS LIGHT DIAGONAL CROSS') from sage.typeset.unicode_art import unicode_art as art else: v = '|' h = '-' dl = dr = ul = ur = vr = vl = uh = dh = vh = '+' - urdl = '/' - uldr = '\\' - x = 'X' from sage.typeset.ascii_art import ascii_art as art - if Tableaux.options.convention == "Russian": - if not data: - return urdl + uldr + '\n' + uldr + urdl - - str_tab = [[str(d) for d in row] for row in data] - col_widths = [2] * len(str_tab[0]) - for row in str_tab: - for i, e in enumerate(row): - col_widths[i] = max(col_widths[i], len(e)) - col_width = max(col_widths) + 1 - max_height = max([a + len(str_tab[a]) for a in range(len(str_tab))]) - empty_col = ' ' * (col_width * 2) - str_list = [] - for i in range(max_height): - # Get the row with the number on it - st = ' ' + ' ' * ((max_height - i - 1) * col_width) - for a in range(i + 1): - b = i - a - if a == 0: - st += uldr - else: - st += x - if len(str_tab[b:]) > 0 and len(str_tab[b][a:]) > 0: - st += str_tab[b][a].rjust(col_width,' ').ljust(col_width * 2 - 1, ' ') - else: - st += ' '*(col_width * 2 - 1) - if b == 0: - st += urdl - - # Do all of the additional rows - for j in range(col_width - 1, 0, -1): - st2 = ' ' + ' ' * ((max_height - i - 1) * col_width) - st2 += (' ' * j + uldr + ' ' * (2 * (col_width - j) - 1) + urdl + ' ' * (j - 1)) * (i + 1) - str_list.append(st2) - str_list.append(st) - import re - mm = min([len(re.search('^ +', l)[0]) for l in str_list]) - 1 - str_list = [l[mm:] for l in str_list] - str_list.reverse() - return '\n'.join(str_list) - if not data: return dr + dl + '\n' + ur + ul @@ -564,3 +608,141 @@ def get_len(e): return output.translate(tr) else: return output + +def ascii_art_table_russian(data, use_unicode=False, compact=False): + r""" + Return an ascii art table of ``data`` for the russian convention. + + EXAMPLES:: + + sage: from sage.combinat.output import ascii_art_table_russian + sage: data = [[None, None, 1], [2, 2], [3,4,5], [None, None, 10], [], [6]] + sage: print(ascii_art_table_russian(data)) + \ 6 X X 10 X X X / + \ / \ / \ / \ / \ / \ / + \ / \ / \ / \ / \ / \ / + \ X X 5 X X / + \ / \ / \ / \ / \ / + \ / \ / \ / \ / \ / + \ X 4 X X / + \ / \ / \ / \ / + \ / \ / \ / \ / + \ 3 X 2 X 1 / + \ / \ / \ / + \ / \ / \ / + \ 2 X / + \ / \ / + \ / \ / + \ / + \ / + \ / + sage: print(ascii_art_table_russian(data, use_unicode=True)) + ╲ 6 ╳ ╳ 10 ╳ ╳ ╳ ╱ + ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ + ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ + ╲ ╳ ╳ 5 ╳ ╳ ╱ + ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ + ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ + ╲ ╳ 4 ╳ ╳ ╱ + ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ + ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ + ╲ 3 ╳ 2 ╳ 1 ╱ + ╲ ╱ ╲ ╱ ╲ ╱ + ╲ ╱ ╲ ╱ ╲ ╱ + ╲ 2 ╳ ╱ + ╲ ╱ ╲ ╱ + ╲ ╱ ╲ ╱ + ╲ ╱ + ╲ ╱ + ╲ ╱ + sage: data = [[1, None, 2], [None, 2]] + sage: print(ascii_art_table_russian(data)) + \ X 2 X 2 / + \ / \ / \ / + \ / \ / \ / + \ X / + \ / \ / + \ / \ / + \ 1 / + \ / + \ / + sage: print(ascii_art_table_russian(data, use_unicode=True)) + ╲ ╳ 2 ╳ 2 ╱ + ╲ ╱ ╲ ╱ ╲ ╱ + ╲ ╱ ╲ ╱ ╲ ╱ + ╲ ╳ ╱ + ╲ ╱ ╲ ╱ + ╲ ╱ ╲ ╱ + ╲ 1 ╱ + ╲ ╱ + ╲ ╱ + """ + if use_unicode: + import unicodedata + urdl = unicodedata.lookup('BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT') + uldr = unicodedata.lookup('BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT') + x = unicodedata.lookup('BOX DRAWINGS LIGHT DIAGONAL CROSS') + from sage.typeset.unicode_art import unicode_art as art + else: + urdl = '/' + uldr = '\\' + x = 'X' + from sage.typeset.ascii_art import ascii_art as art + + if not data: + return urdl + uldr + '\n' + uldr + urdl + +# ncols = max(len(row) for row in data) +# str_tab = [[None]*ncols] + [[str(val) if val is not None else None for val in row] + [None]*(ncols-len(row)) +# for row in data] + str_tab = [[str(val) if val is not None else None for val in row] for row in data] + col_widths = [2] * len(str_tab[0]) + + if use_unicode: + # Special handling of overline not adding to printed length + def get_len(e): + if e is None: + return 0 + return len(e) - list(str(e)).count(u"\u0304") + else: + def get_len(e): + if e is None: + return 0 + return len(e) + + for row in str_tab: + for i, e in enumerate(row): + col_widths[i] = max(col_widths[i], get_len(e)) + if compact: + col_width = max(col_widths) - 1 + else: + col_width = max(col_widths) + 1 + max_height = max([a + len(str_tab[a]) for a in range(len(str_tab))]) + str_list = [] + for i in range(max_height): + # Get the row with the number on it + st = ' ' + ' ' * ((max_height - i - 1) * col_width) + for a in range(i + 1): + b = i - a + if a == 0: + st += uldr + else: + st += x + if len(str_tab[b:]) > 0 and len(str_tab[b][a:]) > 0 and str_tab[b][a] is not None: + st += str_tab[b][a].rjust(col_width,' ').ljust(col_width * 2 - 1, ' ') + else: + st += ' '*(col_width * 2 - 1) + if b == 0: + st += urdl + + # Do all of the additional rows + for j in range(col_width - 1, 0, -1): + st2 = ' ' + ' ' * ((max_height - i - 1) * col_width) + st2 += (' ' * j + uldr + ' ' * (2 * (col_width - j) - 1) + urdl + ' ' * (j - 1)) * (i + 1) + str_list.append(st2) + str_list.append(st) + import re + mm = min([len(re.search('^ +', l)[0]) for l in str_list]) - 1 + str_list = [l[mm:] for l in str_list] + str_list.reverse() + return "\n".join(str_list) diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 927be3263f5..5d8af593be6 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -392,6 +392,11 @@ def _repr_diagram(self): sage: print(t._repr_diagram()) 4 5 1 2 3 + sage: Tableaux.options.convention='russian' + sage: print(t._repr_diagram()) + 5 3 + 4 2 + 1 sage: Tableaux.options._reset() TESTS: @@ -413,6 +418,25 @@ def _repr_diagram(self): for i,e in enumerate(row): col_widths[i] = max(col_widths[i], len(e)) + if self.parent().options('convention') == "Russian": + col_width = max(col_widths) + 1 + max_height = max([a + len(str_tab[a]) for a in range(len(str_tab))]) + str_list = [] + for i in range(max_height): + st = ' ' * ((max_height - i - 1) * col_width) + for a in range(i + 1): + b = i - a + if len(str_tab[b:]) > 0 and len(str_tab[b][a:]) > 0: + st += str_tab[b][a].rjust(col_width, ' ').ljust(col_width * 2 - 1, ' ') + else: + st += ' ' * (col_width * 2 - 1) + str_list.append(st) + import re + mm = min([len(re.search('^ +', l)[0]) for l in str_list]) - 1 + str_list = [l[mm:] for l in str_list] + str_list.reverse() + return '\n'.join(str_list) + if self.parent().options('convention') == "French": str_tab = reversed(str_tab) @@ -463,6 +487,22 @@ def _ascii_art_(self): [ 3 ] [ 2 3 2 ] [ 1 2 3, 1 3, 1 2, 1 ] + sage: Tableaux.options(convention="russian", ascii_art="table") + sage: ascii_art(list(StandardTableaux(3))) + [ \ X X 3 / \ 3 X X / ] + [ \ / \ / \ / \ / \ / \ / ] + [ \ / \ / \ / \ / \ / \ / ] + [ \ X 2 / \ 2 X 3 / \ 3 X 2 / \ 2 X / ] + [ \ / \ / \ / \ / \ / \ / \ / \ / ] + [ \ / \ / \ / \ / \ / \ / \ / \ / ] + [ \ 1 / \ 1 / \ 1 / \ 1 / ] + [ \ / \ / \ / \ / ] + [ \ / , \ / , \ / , \ / ] + sage: Tableaux.options(ascii_art="repr") + sage: ascii_art(list(StandardTableaux(3))) + [ 3 3 ] + [ 2 2 3 3 2 2 ] + [ 1 , 1 , 1 , 1 ] sage: Tableaux.options._reset() """ ascii = self.parent().options._dispatch(self,'_ascii_art_','ascii_art') @@ -511,9 +551,6 @@ def _ascii_art_table(self, use_unicode=False): | 1 | 2 | 3 | +---+---+---+ sage: Tableaux.options.convention="russian" - sage: print(t._repr_diagram()) - 1 2 3 - 4 5 sage: print(t._ascii_art_table()) \ X 5 X 3 / \ / \ / \ / @@ -622,6 +659,7 @@ def _ascii_art_table(self, use_unicode=False): sage: Tableaux.options._reset() """ from sage.combinat.output import ascii_art_table + self.parent().options('convention') return ascii_art_table(self, use_unicode=use_unicode, convention=self.parent().options('convention')) @@ -639,6 +677,11 @@ def _ascii_art_compact(self): sage: print(t._ascii_art_compact()) |4|5| |1|2|3| + sage: Tableaux.options.convention="russian" + sage: print(t._ascii_art_compact()) + \ X5X3/ + \4X2/ + \1/ sage: Tableaux.options._reset() sage: t = Tableau([[1,2,3,10,15],[12,15,17]]) @@ -653,6 +696,9 @@ def _ascii_art_compact(self): if not self: return "." + if self.parent().options('convention') == "Russian": + from sage.combinat.output import ascii_art_table_russian + return ascii_art_table_russian(self, compact=True) if self.parent().options('convention') == "English": T = self else: @@ -665,6 +711,7 @@ def _ascii_art_compact(self): for i,e in enumerate(row): col_widths[i] = max(col_widths[i], len(e)) + return "\n".join("|" + "|".join("{:^{width}}".format(e, width=col_widths[i]) for i,e in enumerate(row)) @@ -694,6 +741,16 @@ def _latex_(self): \lr{1}&\lr{1}&\lr{2}\\\cline{1-3} \end{array}$} } + sage: Tableaux.options.convention="russian" + sage: latex(t) # indirect doctest + {\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}} + \raisebox{-.6ex}{\rotatebox{45}{$\begin{array}[t]{*{3}c}\cline{1-1} + \lr{\rotatebox{-45}{3}}\\\cline{1-2} + \lr{\rotatebox{-45}{2}}&\lr{\rotatebox{-45}{3}}\\\cline{1-3} + \lr{\rotatebox{-45}{1}}&\lr{\rotatebox{-45}{1}}&\lr{\rotatebox{-45}{2}}\\\cline{1-3} + \end{array}$}} + } + sage: Tableaux.options._reset() """ return self.parent().options._dispatch(self,'_latex_', 'latex') From 159eadc729a757e6f0562987c0c6087cbda901e5 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian <aram.dermenjian.math@gmail.com> Date: Mon, 15 May 2023 17:49:44 +0100 Subject: [PATCH 025/228] Add Russian plots and fix descent bug for plots --- src/sage/combinat/tableau.py | 84 ++++++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 9 deletions(-) diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 5d8af593be6..8c46f45b1cf 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -955,6 +955,11 @@ def pp(self): 5 3 4 1 2 3 + sage: Tableaux.options.convention="russian" + sage: T.pp() + 5 4 3 + 3 2 + 1 sage: Tableaux.options._reset() """ print(self._repr_diagram()) @@ -973,7 +978,7 @@ def plot(self, descents=False): Tableaux.options.convention="english" sphinx_plot(t.plot()) - Whereas if French notation is set, the first row of the tableau is on + If French notation is set, the first row of the tableau is on the bottom: .. PLOT:: @@ -984,6 +989,16 @@ def plot(self, descents=False): sphinx_plot(t.plot()) Tableaux.options.convention="english" + If Russian notation is set, we tilt the French by 45 degrees: + + .. PLOT:: + :width: 200 px + + t = Tableau([[1,2,3,4],[2,3],[5]]) + Tableaux.options.convention="russian" + sphinx_plot(t.plot()) + Tableaux.options.convention="english" + INPUT: - ``descents`` -- boolean (default: ``False``); if ``True``, @@ -1013,6 +1028,7 @@ def plot(self, descents=False): if descents and not self.is_standard(): raise ValueError("the tableau must be standard for 'descents=True'") + # For English we build up to down for French, down to up if self.parent().options('convention') == "English": m = 1 @@ -1020,24 +1036,74 @@ def plot(self, descents=False): m = -1 p = self.shape() + r = p.conjugate() - G = line([(0,0),(p[0],0)], axes=False, figsize=1.5) + # Increases the height + if self.parent().options('convention') == "Russian": + pp = p # h + rr = r + h = [-i-1 for i in range(len(p))] # v + v = [i+1 for i in range(len(r))] # d + + else: + pp = [0] * len(p) + rr = [0] * len(r) + h = [0] * len(p) + v = [0] * len(r) + + + G = line([(0,0),(p[0],pp[0])], axes=False, figsize=1.5) for i in range(len(p)): - G += line([(0,m*(-i-1)), (p[i],m*(-i-1))]) + G += line([(h[i], m*(-i-1)), (h[i]+p[i], pp[i]+m*(-i-1))]) - r = p.conjugate() - G += line([(0,0),(0,m*-r[0])]) + G += line([(0,0),(-rr[0],m*-r[0])]) for i in range(len(r)): - G += line([(i+1,0),(i+1,m*-r[i])]) + G += line([(i+1,v[i]),(i+1-rr[i],v[i]+m*-r[i])]) if descents: t = StandardTableau(self) for i in t.standard_descents(): c = t.cells_containing(i)[0] - G += polygon([(c[1],m*c[0]), (c[1]+1,m*c[0]), (c[1]+1,m*(-c[0]-1)), (c[1],m*(-c[0]-1))], rgbcolor=(1,0,1)) + if self.parent().options('convention') == "Russian": + G += polygon([(c[1]+1-v[c[0]],m*(-c[1]-c[0])), + (c[1]+2-v[c[0]],m*(-c[1]-c[0]-1)), + (c[1]+1-v[c[0]],m*(-c[1]-c[0]-2)), + (c[1]-v[c[0]],m*(-c[1]-c[0]-1)) + ], + rgbcolor=(1,0,1) + ) + else: + G += polygon([(c[1],m*-c[0]), + (c[1]+1,m*-c[0]), + (c[1]+1,m*(-c[0]-1)), + (c[1],m*(-c[0]-1)) + ], + rgbcolor=(1,0,1)) - for c in self.cells(): - G += text(str(self.entry(c)), (c[1]+0.5,m*(-c[0]-0.5))) + if self.parent().options('convention') == "Russian": + for c in self.cells(): + G += text(str(self.entry(c)), (c[1]+1-v[c[0]], m*(-c[1]-c[0]-1)) ) + else: + for c in self.cells(): + G += text(str(self.entry(c)), (c[1]+0.5,m*(-c[0]-0.5))) + +# G = line([(0,0),(p[0],0)], axes=False, figsize=1.5) +# for i in range(len(p)): +# G += line([(0,m*(-i-1)), (p[i],m*(-i-1))]) +# +# r = p.conjugate() +# G += line([(0,0),(0,m*-r[0])]) +# for i in range(len(r)): +# G += line([(i+1,0),(i+1,m*-r[i])]) +# +# if descents: +# t = StandardTableau(self) +# for i in t.standard_descents(): +# c = t.cells_containing(i)[0] +# G += polygon([(c[1],m*c[0]), (c[1]+1,m*c[0]), (c[1]+1,m*(-c[0]-1)), (c[1],m*(-c[0]-1))], rgbcolor=(1,0,1)) +# +# for c in self.cells(): +# G += text(str(self.entry(c)), (c[1]+0.5,m*(-c[0]-0.5))) return G From b231dcdb0e768a461a248775dd79c8d376ad71ea Mon Sep 17 00:00:00 2001 From: Aram Dermenjian <aram.dermenjian.math@gmail.com> Date: Tue, 16 May 2023 10:36:37 +0100 Subject: [PATCH 026/228] Lint fixes --- src/sage/combinat/output.py | 51 ++-- src/sage/combinat/tableau.py | 449 +++++++++++++++++------------------ 2 files changed, 241 insertions(+), 259 deletions(-) diff --git a/src/sage/combinat/output.py b/src/sage/combinat/output.py index f4a13d968c8..169851e34a1 100644 --- a/src/sage/combinat/output.py +++ b/src/sage/combinat/output.py @@ -235,7 +235,7 @@ def tex_from_array(array, with_lines=True): sage: Tableaux.options._reset() """ - lr=lr_macro.substitute(bar='|' if with_lines else '') + lr = lr_macro.substitute(bar='|' if with_lines else '') if Tableaux.options.convention == "English": return '{%s\n%s\n}' % (lr, tex_from_skew_array(array, with_lines)) else: @@ -329,13 +329,13 @@ def tex_from_array_tuple(a_tuple, with_lines=True): sage: Tableaux.options._reset() """ - lr=lr_macro.substitute(bar='|' if with_lines else '') + lr = lr_macro.substitute(bar='|' if with_lines else '') if Tableaux.options.convention == "English": return '{%s\n%s\n}' % (lr, ','.join( - r'\emptyset' if comp==[] else tex_from_skew_array(comp, with_lines) for comp in a_tuple)) + r'\emptyset' if comp == [] else tex_from_skew_array(comp, with_lines) for comp in a_tuple)) else: return '{%s\n%s\n}' % (lr, ','.join( - r'\emptyset' if comp==[] else tex_from_skew_array(comp[::-1], with_lines, align='t') for comp in a_tuple)) + r'\emptyset' if comp == [] else tex_from_skew_array(comp[::-1], with_lines, align='t') for comp in a_tuple)) def tex_from_skew_array(array, with_lines=False, align='b'): @@ -382,17 +382,17 @@ def tex_from_skew_array(array, with_lines=False, align='b'): def end_line(r): # in a slightly unpythonic way, we label the lines as 0, 1, ..., len(array) - if r==0: - return r'\cline{%s-%s}'%(nones[0],len(array[0])) - elif r==len(array): - start=nones[r-1] - finish=len(array[r-1]) + if r == 0: + return r'\cline{%s-%s}' % (nones[0], len(array[0])) + elif r == len(array): + start = nones[r-1] + finish = len(array[r-1]) else: - start=min(nones[r], nones[r-1]) - finish=max(len(array[r]), len(array[r-1])) - return r'\\' if start>finish else r'\\\cline{%s-%s}'%(start, finish) + start = min(nones[r], nones[r-1]) + finish = max(len(array[r]), len(array[r-1])) + return r'\\' if start > finish else r'\\\cline{%s-%s}' % (start, finish) else: - end_line=lambda r: r'\\' + end_line = lambda r: r'\\' # now we draw the array raisebox_start = r'\raisebox{-.6ex}{' @@ -405,11 +405,11 @@ def end_line(r): lr_start += r'\rotatebox{-45}{' lr_end += r'}' - tex=r'%s$\begin{array}[%s]{*{%s}c}'%(raisebox_start,align,max(map(len,array))) - tex+=end_line(0)+'\n' + tex = r'%s$\begin{array}[%s]{*{%s}c}' % (raisebox_start, align, max(map(len, array))) + tex += end_line(0)+'\n' for r in range(len(array)): - tex+='&'.join('' if c is None else r'%s%s%s'%(lr_start,c,lr_end) for c in array[r]) - tex+=end_line(r+1)+'\n' + tex += '&'.join('' if c is None else r'%s%s%s' % (lr_start, c, lr_end) for c in array[r]) + tex += end_line(r+1)+'\n' return tex+r'\end{array}$'+raisebox_end @@ -470,8 +470,8 @@ def ascii_art_table(data, use_unicode=False, convention="English"): if use_unicode: import unicodedata - v = unicodedata.lookup('BOX DRAWINGS LIGHT VERTICAL') - h = unicodedata.lookup('BOX DRAWINGS LIGHT HORIZONTAL') + v = unicodedata.lookup('BOX DRAWINGS LIGHT VERTICAL') + h = unicodedata.lookup('BOX DRAWINGS LIGHT HORIZONTAL') dl = unicodedata.lookup('BOX DRAWINGS LIGHT DOWN AND LEFT') dr = unicodedata.lookup('BOX DRAWINGS LIGHT DOWN AND RIGHT') ul = unicodedata.lookup('BOX DRAWINGS LIGHT UP AND LEFT') @@ -511,17 +511,17 @@ def get_len(e): return 0 return len(e) for row in str_tab: - for i,e in enumerate(row): + for i, e in enumerate(row): col_widths[i] = max(col_widths[i], get_len(e)) matr = [] # just the list of lines - for nrow,row in enumerate(str_tab): - if nrow == 0: # skip the first row + for nrow, row in enumerate(str_tab): + if nrow == 0: # skip the first row continue l1 = "" l2 = "" - for i,(e,w) in enumerate(zip(row, col_widths)): + for i, (e, w) in enumerate(zip(row, col_widths)): prev_row = str_tab[nrow-1] if i == 0: if e is None: @@ -573,7 +573,7 @@ def get_len(e): l1 += vh + h*(2+w) else: if prev_row[i-1] is None and prev_row[i] is None: - l1 += dh + h*(2+w) + l1 += dh + h*(2+w) else: l1 += vh + h*(2+w) l2 += "{} {:^{width}} ".format(v, e, width=w) @@ -609,6 +609,7 @@ def get_len(e): else: return output + def ascii_art_table_russian(data, use_unicode=False, compact=False): r""" Return an ascii art table of ``data`` for the russian convention. @@ -729,7 +730,7 @@ def get_len(e): else: st += x if len(str_tab[b:]) > 0 and len(str_tab[b][a:]) > 0 and str_tab[b][a] is not None: - st += str_tab[b][a].rjust(col_width,' ').ljust(col_width * 2 - 1, ' ') + st += str_tab[b][a].rjust(col_width, ' ').ljust(col_width * 2 - 1, ' ') else: st += ' '*(col_width * 2 - 1) if b == 0: diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 8c46f45b1cf..ee17e14e928 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -359,7 +359,7 @@ def _repr_(self): 1,2,3/4,5 sage: Tableaux.options._reset() """ - return self.parent().options._dispatch(self,'_repr_','display') + return self.parent().options._dispatch(self, '_repr_', 'display') def _repr_list(self): """ @@ -415,7 +415,7 @@ def _repr_diagram(self): str_tab = [[str(data) for data in row] for row in self] col_widths = [2]*len(str_tab[0]) for row in str_tab: - for i,e in enumerate(row): + for i, e in enumerate(row): col_widths[i] = max(col_widths[i], len(e)) if self.parent().options('convention') == "Russian": @@ -432,8 +432,8 @@ def _repr_diagram(self): st += ' ' * (col_width * 2 - 1) str_list.append(st) import re - mm = min([len(re.search('^ +', l)[0]) for l in str_list]) - 1 - str_list = [l[mm:] for l in str_list] + mm = min([len(re.search('^ +', sline)[0]) for sline in str_list]) - 1 + str_list = [sline[mm:] for sline in str_list] str_list.reverse() return '\n'.join(str_list) @@ -441,8 +441,8 @@ def _repr_diagram(self): str_tab = reversed(str_tab) return "\n".join(" " - + " ".join("{:>{width}}".format(e,width=col_widths[i]) - for i,e in enumerate(row)) + + " ".join("{:>{width}}".format(e, width=col_widths[i]) + for i, e in enumerate(row)) for row in str_tab) def _repr_compact(self): @@ -461,7 +461,7 @@ def _repr_compact(self): return '/'.join(','.join('%s' % r for r in row) for row in self) def _ascii_art_(self): - """ + r''' TESTS:: sage: ascii_art(list(StandardTableaux(3))) @@ -504,8 +504,8 @@ def _ascii_art_(self): [ 2 2 3 3 2 2 ] [ 1 , 1 , 1 , 1 ] sage: Tableaux.options._reset() - """ - ascii = self.parent().options._dispatch(self,'_ascii_art_','ascii_art') + ''' + ascii = self.parent().options._dispatch(self, '_ascii_art_', 'ascii_art') from sage.typeset.ascii_art import AsciiArt return AsciiArt(ascii.splitlines()) @@ -531,7 +531,7 @@ def _unicode_art_(self): _ascii_art_repr = _repr_diagram def _ascii_art_table(self, use_unicode=False): - """ + r''' TESTS: We check that :trac:`16487` is fixed:: @@ -657,14 +657,14 @@ def _ascii_art_table(self, use_unicode=False): ╲ ╱ ╲ ╱ sage: Tableaux.options._reset() - """ + ''' from sage.combinat.output import ascii_art_table self.parent().options('convention') return ascii_art_table(self, use_unicode=use_unicode, convention=self.parent().options('convention')) def _ascii_art_compact(self): - """ + r''' TESTS: We check that :trac:`16487` is fixed:: @@ -692,7 +692,7 @@ def _ascii_art_compact(self): sage: t = Tableau([]) sage: print(t._ascii_art_compact()) . - """ + ''' if not self: return "." @@ -708,13 +708,12 @@ def _ascii_art_compact(self): str_tab = [[str(_) for _ in row] for row in T] col_widths = [1]*len(self[0]) for row in str_tab: - for i,e in enumerate(row): + for i, e in enumerate(row): col_widths[i] = max(col_widths[i], len(e)) - return "\n".join("|" + "|".join("{:^{width}}".format(e, width=col_widths[i]) - for i,e in enumerate(row)) + for i, e in enumerate(row)) + "|" for row in str_tab) def _latex_(self): @@ -753,9 +752,9 @@ def _latex_(self): sage: Tableaux.options._reset() """ - return self.parent().options._dispatch(self,'_latex_', 'latex') + return self.parent().options._dispatch(self, '_latex_', 'latex') - _latex_list=_repr_list + _latex_list = _repr_list def _latex_diagram(self): r""" @@ -796,11 +795,11 @@ def __truediv__(self, t): ValueError: the shape of the tableau must contain the partition """ from sage.combinat.partition import _Partitions - #if t is a list, convert it to a partition first + # if t is a list, convert it to a partition first if isinstance(t, list): t = _Partitions(t) - #Check to make sure that tableau shape contains t + # Check to make sure that tableau shape contains t if not self.shape().contains(t): raise ValueError("the shape of the tableau must contain the partition") @@ -839,9 +838,9 @@ def __call__(self, *cell): IndexError: the cell (3,3) is not contained in [[1, 2, 3], [4, 5]] """ try: - i,j = cell + i, j = cell except ValueError: - i,j = cell[0] + i, j = cell[0] try: return self[i][j] @@ -852,7 +851,8 @@ def level(self): """ Return the level of ``self``, which is always 1. - This function exists mainly for compatibility with :class:`TableauTuple`. + This function exists mainly for compatibility with + :class:`TableauTuple`. EXAMPLES:: @@ -864,8 +864,8 @@ def level(self): def components(self): """ This function returns a list containing itself. It exists mainly for - compatibility with :class:`TableauTuple` as it allows constructions like the - example below. + compatibility with :class:`TableauTuple` as it allows constructions + like the example below. EXAMPLES:: @@ -914,7 +914,7 @@ def corners(self): """ return self.shape().corners() - @combinatorial_map(order=2,name='conjugate') + @combinatorial_map(order=2, name='conjugate') def conjugate(self): """ Return the conjugate of ``self``. @@ -1028,7 +1028,6 @@ def plot(self, descents=False): if descents and not self.is_standard(): raise ValueError("the tableau must be standard for 'descents=True'") - # For English we build up to down for French, down to up if self.parent().options('convention') == "English": m = 1 @@ -1040,10 +1039,10 @@ def plot(self, descents=False): # Increases the height if self.parent().options('convention') == "Russian": - pp = p # h + pp = p # h rr = r - h = [-i-1 for i in range(len(p))] # v - v = [i+1 for i in range(len(r))] # d + h = [-i-1 for i in range(len(p))] + v = [i+1 for i in range(len(r))] else: pp = [0] * len(p) @@ -1051,59 +1050,40 @@ def plot(self, descents=False): h = [0] * len(p) v = [0] * len(r) - - G = line([(0,0),(p[0],pp[0])], axes=False, figsize=1.5) + G = line([(0, 0), (p[0], pp[0])], axes=False, figsize=1.5) for i in range(len(p)): G += line([(h[i], m*(-i-1)), (h[i]+p[i], pp[i]+m*(-i-1))]) - G += line([(0,0),(-rr[0],m*-r[0])]) + G += line([(0, 0), (-rr[0], m*-r[0])]) for i in range(len(r)): - G += line([(i+1,v[i]),(i+1-rr[i],v[i]+m*-r[i])]) + G += line([(i+1, v[i]), (i+1-rr[i], v[i]+m*-r[i])]) if descents: t = StandardTableau(self) for i in t.standard_descents(): c = t.cells_containing(i)[0] if self.parent().options('convention') == "Russian": - G += polygon([(c[1]+1-v[c[0]],m*(-c[1]-c[0])), - (c[1]+2-v[c[0]],m*(-c[1]-c[0]-1)), - (c[1]+1-v[c[0]],m*(-c[1]-c[0]-2)), - (c[1]-v[c[0]],m*(-c[1]-c[0]-1)) + G += polygon([(c[1]+1-v[c[0]], m*(-c[1]-c[0])), + (c[1]+2-v[c[0]], m*(-c[1]-c[0]-1)), + (c[1]+1-v[c[0]], m*(-c[1]-c[0]-2)), + (c[1]-v[c[0]], m*(-c[1]-c[0]-1)) ], - rgbcolor=(1,0,1) + rgbcolor=(1, 0, 1) ) else: - G += polygon([(c[1],m*-c[0]), - (c[1]+1,m*-c[0]), - (c[1]+1,m*(-c[0]-1)), - (c[1],m*(-c[0]-1)) + G += polygon([(c[1], m*-c[0]), + (c[1]+1, m*-c[0]), + (c[1]+1, m*(-c[0]-1)), + (c[1], m*(-c[0]-1)) ], - rgbcolor=(1,0,1)) + rgbcolor=(1, 0, 1)) if self.parent().options('convention') == "Russian": for c in self.cells(): - G += text(str(self.entry(c)), (c[1]+1-v[c[0]], m*(-c[1]-c[0]-1)) ) + G += text(str(self.entry(c)), (c[1]+1-v[c[0]], m*(-c[1]-c[0]-1))) else: for c in self.cells(): - G += text(str(self.entry(c)), (c[1]+0.5,m*(-c[0]-0.5))) - -# G = line([(0,0),(p[0],0)], axes=False, figsize=1.5) -# for i in range(len(p)): -# G += line([(0,m*(-i-1)), (p[i],m*(-i-1))]) -# -# r = p.conjugate() -# G += line([(0,0),(0,m*-r[0])]) -# for i in range(len(r)): -# G += line([(i+1,0),(i+1,m*-r[i])]) -# -# if descents: -# t = StandardTableau(self) -# for i in t.standard_descents(): -# c = t.cells_containing(i)[0] -# G += polygon([(c[1],m*c[0]), (c[1]+1,m*c[0]), (c[1]+1,m*(-c[0]-1)), (c[1],m*(-c[0]-1))], rgbcolor=(1,0,1)) -# -# for c in self.cells(): -# G += text(str(self.entry(c)), (c[1]+0.5,m*(-c[0]-0.5))) + G += text(str(self.entry(c)), (c[1]+0.5, m*(-c[0]-0.5))) return G @@ -1177,10 +1157,10 @@ def descents(self): [(1, 0), (1, 1)] """ descents = [] - for i in range(1,len(self)): + for i in range(1, len(self)): for j in range(len(self[i])): if self[i][j] > self[i-1][j]: - descents.append((i,j)) + descents.append((i, j)) return descents def major_index(self): @@ -1211,7 +1191,7 @@ def major_index(self): """ descents = self.descents() p = self.shape() - return len(descents) + sum([ p.leg_length(*d) for d in descents ]) + return len(descents) + sum([p.leg_length(*d) for d in descents]) def inversions(self): """ @@ -1244,13 +1224,13 @@ def inversions(self): # find the d that satisfy condition 1 for k in range(j+1, len(row)): if entry > row[k]: - inversions.append( ((i,j),(i,k)) ) + inversions.append(((i, j), (i, k))) # find the d that satisfy condition 2 if i == 0: continue for k in range(j): if entry > previous_row[k]: - inversions.append( ((i,j),(i-1,k)) ) + inversions.append(((i, j), (i-1, k))) previous_row = row return inversions @@ -1329,19 +1309,19 @@ def to_sign_matrix(self, max_entry=None): raise ValueError("the entries must be non-negative integers") from sage.matrix.matrix_space import MatrixSpace if max_entry is None: - max_entry=max([max(c) for c in self]) + max_entry = max([max(c) for c in self]) MS = MatrixSpace(ZZ, len(self[0]), max_entry) Tconj = self.conjugate() - l = len(Tconj) - d = {(l-i-1,elem-1): 1 for i, row in enumerate(Tconj) for elem in row} + conj_len = len(Tconj) + d = {(conj_len-i-1, elem-1): 1 for i, row in enumerate(Tconj) for elem in row} partial_sum_matrix = MS(d) from copy import copy sign_matrix = copy(MS.zero()) for j in range(max_entry): - sign_matrix[0,j] = partial_sum_matrix[0,j] - for i in range(1,l): + sign_matrix[0, j] = partial_sum_matrix[0, j] + for i in range(1, conj_len): for j in range(max_entry): - sign_matrix[i,j] = partial_sum_matrix[i,j] - partial_sum_matrix[i-1,j] + sign_matrix[i, j] = partial_sum_matrix[i, j] - partial_sum_matrix[i-1, j] return sign_matrix def schuetzenberger_involution(self, n=None, check=True): @@ -1408,7 +1388,7 @@ def schuetzenberger_involution(self, n=None, check=True): return SemistandardTableau(list(t)) return t - @combinatorial_map(order=2,name='evacuation') + @combinatorial_map(order=2, name='evacuation') def evacuation(self, n=None, check=True): r""" Return the evacuation of the tableau ``self``. @@ -1455,7 +1435,7 @@ def evacuation(self, n=None, check=True): sage: s.parent() Standard tableaux """ - return self.schuetzenberger_involution(n,check) + return self.schuetzenberger_involution(n, check) @combinatorial_map(name="standardization") def standardization(self, check=True): @@ -1671,7 +1651,7 @@ def entry(self, cell): sage: t.entry( (1,1) ) 4 """ - i,j = cell + i, j = cell return self[i][j] def weight(self): @@ -1743,7 +1723,7 @@ def is_row_strict(self): sage: Tableau([[5, 3], [2, 4]]).is_row_strict() False """ - return all(row[i]<row[i+1] for row in self for i in range(len(row)-1)) + return all(row[i] < row[i+1] for row in self for i in range(len(row)-1)) def is_row_increasing(self, weak=False): r""" @@ -1915,7 +1895,8 @@ def is_rectangular(self): def vertical_flip(self): """ - Return the tableau obtained by vertically flipping the tableau ``self``. + Return the tableau obtained by vertically flipping the tableau + ``self``. This only works for rectangular tableaux. @@ -1943,7 +1924,7 @@ def rotate_180(self): if not self.is_rectangular(): raise TypeError("the tableau must be rectangular to use rotate_180()") - return Tableau([ [l for l in reversed(row)] for row in reversed(self) ]) + return Tableau([[rline for rline in reversed(row)] for row in reversed(self)]) def cells(self): """ @@ -1959,7 +1940,7 @@ def cells(self): """ s = [] for i, row in enumerate(self): - s += [ (i,j) for j in range(len(row)) ] + s += [(i, j) for j in range(len(row))] return s def cells_containing(self, i): @@ -1996,9 +1977,9 @@ def cells_containing(self, i): cell_list = [] for r in range(len(self)-1, -1, -1): rth_row = self[r] - for c,val in enumerate(rth_row): + for c, val in enumerate(rth_row): if val == i: - cell_list.append((r,c)) + cell_list.append((r, c)) return cell_list def leq(self, secondtab): @@ -2084,10 +2065,10 @@ def k_weight(self, k): w = self.weight() s = self.cells() - for l in range(1,len(w)+1): - new_s = [(i,j) for i,j in s if self[i][j] == l] + for l in range(1, len(w)+1): + new_s = [(i, j) for i, j in s if self[i][j] == l] - #If there are no elements that meet the condition + # If there are no elements that meet the condition if new_s == []: res.append(0) continue @@ -2110,8 +2091,8 @@ def is_k_tableau(self, k): False """ shapes = self.to_chain() - kshapes = [ la.k_conjugate(k) for la in shapes ] - return all( kshapes[i+1].contains(kshapes[i]) for i in range(len(shapes)-1) ) + kshapes = [la.k_conjugate(k) for la in shapes] + return all(kshapes[i+1].contains(kshapes[i]) for i in range(len(shapes)-1)) def restrict(self, n): """ @@ -2166,14 +2147,14 @@ def restrict(self, n): sage: _.category() Category of elements of Semistandard tableaux """ - res = [ [y for y in row if y <= n] for row in self ] + res = [[y for y in row if y <= n] for row in self] res = [row for row in res if row] # attempt to return a tableau of the same type try: - return self.parent()( res ) + return self.parent()(res) except Exception: try: - return self.parent().Element( res ) + return self.parent().Element(res) except Exception: return Tableau(res) @@ -2337,7 +2318,7 @@ def bump(self, x): new_t = self.to_list() for row in new_t: i = 0 - #try to insert to_insert into row + # try to insert to_insert into row while i < len(row): if to_insert < row[i]: t = to_insert @@ -2346,15 +2327,15 @@ def bump(self, x): break i += 1 - #if we haven't already inserted to_insert - #append it to the end of row + # if we haven't already inserted to_insert + # append it to the end of row if i == len(row): row.append(to_insert) if isinstance(self, SemistandardTableau): return SemistandardTableau(new_t) return Tableau(new_t) - #if we got here, we are at the end of the tableau - #add to_insert as the last row + # if we got here, we are at the end of the tableau + # add to_insert as the last row new_t.append([to_insert]) if isinstance(self, SemistandardTableau): return SemistandardTableau(new_t) @@ -2467,7 +2448,7 @@ def insert_word(self, w, left=False): w = [i for i in reversed(w)] res = self for i in w: - res = res.schensted_insert(i,left=left) + res = res.schensted_insert(i, left=left) return res def reverse_bump(self, loc): @@ -2665,33 +2646,33 @@ def _slide_up(self, c): """ new_st = self.to_list() spotl, spotc = c - while [spotl, spotc] != [0,0]: - #once moving box is in first column, just move letters up - #(French notation!) + while [spotl, spotc] != [0, 0]: + # once moving box is in first column, just move letters up + # (French notation!) if spotc == 0: new_st[spotl][spotc] = new_st[spotl-1][spotc] spotl -= 1 continue - #once moving box is in first row, just move letters up + # once moving box is in first row, just move letters up elif spotl == 0: new_st[spotl][spotc] = new_st[spotl][spotc-1] spotc -= 1 continue else: - #If we get to this stage, we need to compare + # If we get to this stage, we need to compare below = new_st[spotl-1][spotc] left = new_st[spotl][spotc-1] if below >= left: - #Swap with the cell below + # Swap with the cell below new_st[spotl][spotc] = new_st[spotl-1][spotc] spotl -= 1 continue else: - #Swap with the cell to the left + # Swap with the cell to the left new_st[spotl][spotc] = new_st[spotl][spotc-1] spotc -= 1 continue - #set box in position (0,0) to 0 + # set box in position (0,0) to 0 new_st[0][0] = 0 return Tableau(new_st) @@ -2718,14 +2699,14 @@ def _slide_down(self, c, n): [[1, 2, 2, 2, 2, 3], [2, 4, 4, 6, 6], [4, 5, 7, 11], [5, 8]] """ new_st = self.to_list() - #new_st is a deep copy of self, so as not to mess around with self. + # new_st is a deep copy of self, so as not to mess around with self. new_st_shape = [len(x) for x in self] spotl, spotc = c - #spotl and spotc are the coordinates of the wandering hole. - #All comments and variable names below refer to French notation. + # spotl and spotc are the coordinates of the wandering hole. + # All comments and variable names below refer to French notation. while True: - #"right_neighbor" and "upper_neighbor" refer to neighbors of the - #hole. + # "right_neighbor" and "upper_neighbor" refer to neighbors of the + # hole. go_right = None if len(new_st_shape) > spotl + 1 and new_st_shape[spotl + 1] >= spotc + 1: upper_neighbor = new_st[spotl + 1][spotc] @@ -2832,7 +2813,7 @@ def promotion_inverse(self, n): return self s = self.shape()[0] l = self.weight()[0] - word = [i-1 for row in reversed(self) for i in row if i>1] + word = [i-1 for row in reversed(self) for i in row if i > 1] t = Tableau([]) t = t.insert_word(word) t = t.to_list() @@ -2992,8 +2973,8 @@ def row_stabilizer(self): gens = [list(range(1, k + 1))] for row in self: for j in range(len(row) - 1): - gens.append( (row[j], row[j + 1]) ) - return PermutationGroup( gens ) + gens.append((row[j], row[j + 1])) + return PermutationGroup(gens) def column_stabilizer(self): """ @@ -3054,7 +3035,7 @@ def _heights(self): heights = [1]*(cor[0][1]) for i in range(1, ncor): - heights += [ cor[i][0] ]*(cor[i][1]-cor[i-1][1]) + heights += [cor[i][0]]*(cor[i][1]-cor[i-1][1]) return heights @@ -3214,13 +3195,13 @@ def add_entry(self, cell, m): if r == len(tab) and c == 0: tab.append([m]) else: - raise IndexError('%s is not an addable cell of the tableau' % ((r,c),)) + raise IndexError('%s is not an addable cell of the tableau' % ((r, c),)) else: tab_r = tab[r] if c == len(tab_r): tab_r.append(m) else: - raise IndexError('%s is not an addable cell of the tableau' % ((r,c),)) + raise IndexError('%s is not an addable cell of the tableau' % ((r, c),)) # attempt to return a tableau of the same type as self if tab in self.parent(): @@ -3255,8 +3236,8 @@ def catabolism(self): if h == 0: return self else: - #Remove the top row and insert it back in - return Tableau(self[1:]).insert_word(self[0],left=True) + # Remove the top row and insert it back in + return Tableau(self[1:]).insert_word(self[0], left=True) def catabolism_sequence(self): """ @@ -3334,7 +3315,7 @@ def lambda_catabolism(self, part): w1 = list(sum((row for row in reversed(self[m:])), ())) w2 = [] - for i,row in enumerate(reversed(self[:m])): + for i, row in enumerate(reversed(self[:m])): w2 += row[part[-1 - i]:] return Tableau([]).insert_word(w2 + w1) @@ -3374,8 +3355,8 @@ def reduced_lambda_catabolism(self, part): a = self[0][0] - part = [ min(part1[i], len(self[i])) for i in range(min(len(part1),len(self)))] - tt_part = Tableau([ [a+i]*part[i] for i in range(len(part)) ]) + part = [min(part1[i], len(self[i])) for i in range(min(len(part1), len(self)))] + tt_part = Tableau([[a+i]*part[i] for i in range(len(part))]) t_part = Tableau([[self[i][j] for j in range(part[i])] for i in range(len(part))]) if t_part == tt_part: @@ -3468,8 +3449,8 @@ def promotion_operator(self, i): weight = self.weight() perm = permutation.from_reduced_word(range(1, len(weight)+1)) l = part.add_horizontal_border_strip(i) - ltab = [ from_chain( chain + [next] ) for next in l ] - return [ x.symmetric_group_action_on_values(perm) for x in ltab ] + ltab = [from_chain(chain + [next]) for next in l] + return [x.symmetric_group_action_on_values(perm) for x in ltab] ################################## # actions on tableaux from words # @@ -3599,9 +3580,9 @@ def atom(self): sage: Tableau([[1,2,3],[4,5],[6]]).atom() [3, 2, 1] """ - ll = [ t.socle() for t in self.catabolism_sequence() ] + ll = [t.socle() for t in self.catabolism_sequence()] lres = ll[:] - for i in range(1,len(ll)): + for i in range(1, len(ll)): lres[i] = ll[i] - ll[i-1] return lres @@ -3735,7 +3716,7 @@ def right_key_tableau(self): update.append(col_b[:-1]) else: update.append(col_b) - key[i].insert(0,key_val) + key[i].insert(0, key_val) right_cols = update return Tableau(key).conjugate() @@ -3795,7 +3776,7 @@ def left_key_tableau(self): key[0] = list(cols_list[0]) from bisect import bisect_right - for i, col_a in enumerate(cols_list[1:],1): + for i, col_a in enumerate(cols_list[1:], 1): left_cols = cols_list[:i] for elem in reversed(col_a): key_val = elem @@ -3805,7 +3786,7 @@ def left_key_tableau(self): key_val = col_b[j] update.insert(0, col_b[:j]) left_cols = update - key[i].insert(0,key_val) + key[i].insert(0, key_val) return Tableau(key).conjugate() ################# @@ -3907,7 +3888,7 @@ def flush(self): for t in S: if s[0][0]+1 == t[0][0] and s[1] == t[1] and ( (s[1] >= 1 and self[s[0][0]+1][s[1]-1] <= self[s[0][0]][s[1]]) - or (s[1] < 1 and self[s[0][0]+1][s[1]] != s[0][0]+2) ): + or (s[1] < 1 and self[s[0][0]+1][s[1]] != s[0][0]+2)): f += 1 return f @@ -3936,7 +3917,7 @@ def content(self, k, multicharge=[0]): ... ValueError: 6 does not appear in tableau """ - for r,row in enumerate(self): + for r, row in enumerate(self): try: return row.index(k) - r + multicharge[0] except ValueError: @@ -4021,8 +4002,8 @@ def residue_sequence(self, e, multicharge=(0,)): 4-residue sequence (0,1,3,0) with multicharge (0) """ res = [0] * self.size() - for r,row in enumerate(self): - for c,entry in enumerate(row): + for r, row in enumerate(self): + for c, entry in enumerate(row): res[entry-1] = multicharge[0] - r + c from sage.combinat.tableau_residues import ResidueSequence return ResidueSequence(e, multicharge, res, check=False) @@ -4060,7 +4041,7 @@ def degree(self, e, multicharge=(0,)): if n == 0: return 0 - deg = self.shape()._initial_degree(e,multicharge) + deg = self.shape()._initial_degree(e, multicharge) res = self.shape().initial_tableau().residue_sequence(e, multicharge) for r in self.reduced_row_word(): if res[r] == res[r+1]: @@ -4848,15 +4829,15 @@ def up(self): sage: [x for x in t.up()] [[[1, 2, 3]], [[1, 2], [3]]] """ - #Get a list of all places where we can add a cell - #to the shape of self + # Get a list of all places where we can add a cell + # to the shape of self outside_corners = self.shape().outside_corners() n = self.size() - #Go through and add n+1 to the end of each - #of the rows + # Go through and add n+1 to the end of each + # of the rows for row, _ in outside_corners: new_t = [list(_) for _ in self] if row != len(self): @@ -4932,12 +4913,12 @@ def standard_descents(self): [] """ descents = [] - #whatpart gives the number for which self is a partition + # whatpart gives the number for which self is a partition whatpart = sum(i for i in self.shape()) - #now find the descents + # now find the descents for i in range(1, whatpart): - #find out what row i and i+1 are in (we're using the - #standardness of self here) + # find out what row i and i+1 are in (we're using the + # standardness of self here) for row in self: if row.count(i + 1): break @@ -5079,7 +5060,7 @@ def from_chain(chain): for i in reversed(range(2, len(chain) + 1)): for j in range(len(chain[i - 1])): for k in range(chain[i - 1][j]): - res[j][k] = i -1 + res[j][k] = i - 1 T = Tableaux_all() return T.element_class(T, res) @@ -5124,7 +5105,7 @@ def from_shape_and_word(shape, w, convention="French"): if convention == "French": shape = reversed(shape) for l in shape: - res.append( tuple(w[j:j+l]) ) + res.append(tuple(w[j:j+l])) j += l if convention == "French": res.reverse() @@ -5390,7 +5371,7 @@ def K_promotion_inverse(self, ceiling=None): ans = ans.K_bender_knuth(i) return ans - @combinatorial_map(order=2,name='K-evacuation') + @combinatorial_map(order=2, name='K-evacuation') def K_evacuation(self, ceiling=None): """ Return the K-evacuation involution from [TY2009]_ to ``self``. @@ -5803,7 +5784,7 @@ def __init__(self, n): super().__init__(category=Sets()) self.size = n - def __contains__(self,x): + def __contains__(self, x): """ TESTS:: @@ -5843,13 +5824,13 @@ def an_element(self): sage: T.an_element() [] """ - if self.size==0: + if self.size == 0: return self.element_class(self, []) - if self.size==1: + if self.size == 1: return self.element_class(self, [[1]]) - return self.element_class(self, [[1]*(self.size-1),[1]]) + return self.element_class(self, [[1]*(self.size-1), [1]]) ########################## @@ -6052,27 +6033,27 @@ def __classcall_private__(cls, *args, **kwargs): # The first arg could be either a size or a shape if isinstance(args[0], (int, Integer)): if size is not None: - raise ValueError( "size was specified more than once" ) + raise ValueError("size was specified more than once") else: size = args[0] else: if shape is not None: - raise ValueError( "the shape was specified more than once" ) + raise ValueError("the shape was specified more than once") shape = args[0] # we check it's a partition later if len(args) == 2: # The second non-keyword argument is the weight if mu is not None: - raise ValueError( "the weight was specified more than once" ) + raise ValueError("the weight was specified more than once") else: mu = args[1] # Consistency checks if size is not None: if not isinstance(size, (int, Integer)): - raise ValueError( "size must be an integer" ) + raise ValueError("size must be an integer") elif size < 0: - raise ValueError( "size must be non-negative" ) + raise ValueError("size must be non-negative") if shape is not None: from sage.combinat.skew_partition import SkewPartitions @@ -6084,40 +6065,40 @@ def __classcall_private__(cls, *args, **kwargs): from sage.combinat.skew_tableau import SemistandardSkewTableaux return SemistandardSkewTableaux(shape, mu) else: - raise ValueError( "shape must be a (skew) partition" ) + raise ValueError("shape must be a (skew) partition") if mu is not None: if mu not in Compositions() and mu not in _Partitions: - raise ValueError( "mu must be a composition" ) + raise ValueError("mu must be a composition") mu = Composition(mu) is_inf = max_entry is PlusInfinity() if max_entry is not None: if not is_inf and not isinstance(max_entry, (int, Integer)): - raise ValueError( "max_entry must be an integer or PlusInfinity" ) + raise ValueError("max_entry must be an integer or PlusInfinity") elif max_entry <= 0: - raise ValueError( "max_entry must be positive" ) + raise ValueError("max_entry must be positive") if (mu is not None) and (max_entry is not None): if max_entry != len(mu): - raise ValueError( "the maximum entry must match the weight" ) + raise ValueError("the maximum entry must match the weight") if (size is not None) and (shape is not None): if sum(shape) != size: # This could return an empty class instead of an error - raise ValueError( "size and shape are different sizes" ) + raise ValueError("size and shape are different sizes") if (size is not None) and (mu is not None): if sum(mu) != size: # This could return an empty class instead of an error - raise ValueError( "size and eval are different sizes" ) + raise ValueError("size and eval are different sizes") # Dispatch appropriately if (shape is not None) and (mu is not None): if sum(shape) != sum(mu): # This could return an empty class instead of an error - raise ValueError( "shape and eval are different sizes" ) + raise ValueError("shape and eval are different sizes") else: return SemistandardTableaux_shape_weight(shape, mu) @@ -6222,26 +6203,26 @@ def __getitem__(self, r): ... ValueError: infinite set """ - if isinstance(r,(int,Integer)): + if isinstance(r, (int, Integer)): return self.unrank(r) - elif isinstance(r,slice): - start=0 if r.start is None else r.start - stop=r.stop + elif isinstance(r, slice): + start = 0 if r.start is None else r.start + stop = r.stop if stop is None and not self.is_finite(): - raise ValueError( 'infinite set' ) + raise ValueError('infinite set') else: - raise ValueError( 'r must be an integer or a slice' ) - count=0 - tabs=[] + raise ValueError('r must be an integer or a slice') + count = 0 + tabs = [] for t in self: - if count==stop: + if count == stop: break - if count>=start: + if count >= start: tabs.append(t) - count+=1 + count += 1 # this is to cope with empty slices endpoints like [:6] or [:} - if count==stop or stop is None: + if count == stop or stop is None: return tabs raise IndexError('value out of range') @@ -6656,14 +6637,14 @@ def random_element(self): pos += 1 tot += weights[pos] # we now have pos elements over the diagonal and n - 2 * pos on it - m = diagonal_matrix( list(IntegerVectors(self.size - 2 * pos, - self.max_entry).random_element()) ) + m = diagonal_matrix(list(IntegerVectors(self.size - 2 * pos, + self.max_entry).random_element())) above_diagonal = list(IntegerVectors(pos, kchoose2m1 + 1).random_element()) index = 0 for i in range(self.max_entry - 1): for j in range(i + 1, self.max_entry): - m[i,j] = above_diagonal[index] - m[j,i] = above_diagonal[index] + m[i, j] = above_diagonal[index] + m[j, i] = above_diagonal[index] index += 1 return RSK(m)[0] @@ -6869,9 +6850,9 @@ def random_element(self): """ from sage.misc.prandom import randint - with_sentinels = [max(i,j) for i,j in zip([0]+list(self.shape), [k+1 for k in self.shape]+[0])] + with_sentinels = [max(i, j) for i, j in zip([0]+list(self.shape), [k+1 for k in self.shape]+[0])] t = [[self.max_entry+1]*i for i in with_sentinels] - for i,l in enumerate(self.shape): + for i, l in enumerate(self.shape): for j in range(l): content = j - i t[i][j] = randint(1 - content, self.max_entry) @@ -6894,7 +6875,7 @@ def random_element(self): row += 1 x = t[row][col + 1] y = t[row + 1][col] - return SemistandardTableau([l[:c] for l,c in zip(t, self.shape)]) + return SemistandardTableau([l[:c] for l, c in zip(t, self.shape)]) def cardinality(self, algorithm='hook'): r""" @@ -6945,7 +6926,7 @@ def cardinality(self, algorithm='hook'): conj = self.shape.conjugate() num = Integer(1) den = Integer(1) - for i,l in enumerate(self.shape): + for i, l in enumerate(self.shape): for j in range(l): num *= self.max_entry + j - i den *= l + conj[j] - i - j - 1 @@ -7281,8 +7262,8 @@ def __classcall_private__(cls, *args, **kwargs): return RowStandardTableaux_shape(_Partitions(n)) elif n in SkewPartitions(): - #from sage.combinat.skew_tableau import RowStandardSkewTableaux - #return RowStandardSkewTableaux(n) + # from sage.combinat.skew_tableau import RowStandardSkewTableaux + # return RowStandardSkewTableaux(n) raise NotImplementedError("row standard skew tableaux not yet implemented") if not isinstance(n, (int, Integer)) or n < 0: @@ -7316,9 +7297,9 @@ def __contains__(self, x): if isinstance(x, RowStandardTableau): return True elif Tableaux.__contains__(self, x): - flatx = sorted(sum((list(row) for row in x),[])) - return ( flatx == list(range(1,len(flatx)+1)) - and all(row[i] < row[i+1] for row in x for i in range(len(row)-1)) ) + flatx = sorted(sum((list(row) for row in x), [])) + return (flatx == list(range(1, len(flatx)+1)) + and all(row[i] < row[i+1] for row in x for i in range(len(row)-1))) return False @@ -7454,7 +7435,7 @@ def an_element(self): elif self._size == 1: return self.element_class(self, [[1]]) else: - return self.element_class(self, [range(1,self._size + 1)]) + return self.element_class(self, [range(1, self._size + 1)]) class RowStandardTableaux_shape(RowStandardTableaux): @@ -7536,9 +7517,9 @@ def __iter__(self): relations = [] m = 1 for row in self.shape: - relations += [(m+i,m+i+1) for i in range(row-1)] + relations += [(m+i, m+i+1) for i in range(row-1)] m += row - P = Poset((range(1,self.shape.size()+1), relations)) + P = Poset((range(1, self.shape.size()+1), relations)) L = P.linear_extensions() # now run through the linear extensions and return the corresponding tableau for lin in L: @@ -7717,10 +7698,10 @@ def __contains__(self, x): return True elif Tableaux.__contains__(self, x): flatx = sorted(sum((list(row) for row in x), [])) - return flatx == list(range(1,len(flatx)+1)) and (len(x)==0 or - (all(row[i]<row[i+1] for row in x for i in range(len(row)-1)) and - all(x[r][c]<x[r+1][c] for r in range(len(x)-1) - for c in range(len(x[r+1])) ) + return flatx == list(range(1, len(flatx)+1)) and (len(x) == 0 or + (all(row[i] < row[i+1] for row in x for i in range(len(row)-1)) and + all(x[r][c] < x[r+1][c] for r in range(len(x)-1) + for c in range(len(x[r+1]))) )) return False @@ -7960,7 +7941,7 @@ def random_element(self): matching = PerfectMatchings(set(range(1, self.size + 1)) - set(fixed_point_positions)).random_element() permutation_cycle_rep = ([(fixed_point,) for fixed_point in fixed_point_positions] - + [(a,b) for a,b in matching]) + + [(a, b) for a, b in matching]) return from_cycles(self.size, permutation_cycle_rep).robinson_schensted()[0] @@ -8092,7 +8073,7 @@ def __iter__(self): """ pi = self.shape - #Set the initial tableau by filling it in going down the columns + # Set the initial tableau by filling it in going down the columns tableau = [[None]*n for n in pi] size = sum(pi) row = 0 @@ -8100,9 +8081,9 @@ def __iter__(self): for i in range(size): tableau[row][col] = i+1 - #If we can move down, then do it; - #otherwise, move to the next column over - if ( row + 1 < len(pi) and col < pi[row+1]): + # If we can move down, then do it; + # otherwise, move to the next column over + if (row + 1 < len(pi) and col < pi[row+1]): row += 1 else: row = 0 @@ -8112,59 +8093,59 @@ def __iter__(self): # iterate until we reach the last tableau which is # filled with the row indices. - last_tableau = sum([[row]*l for (row,l) in enumerate(pi)], []) + last_tableau = sum([[row]*l for (row, l) in enumerate(pi)], []) - #Convert the tableau to "vector format" - #tableau_vector[i] is the row that number i - #is in + # Convert the tableau to "vector format" + # tableau_vector[i] is the row that number i + # is in tableau_vector = [None]*size for row in range(len(pi)): for col in range(pi[row]): tableau_vector[tableau[row][col]-1] = row - while tableau_vector!=last_tableau: - #Locate the smallest integer j such that j is not - #in the lowest corner of the subtableau T_j formed by - #1,...,j. This happens to be first j such that - #tableau_vector[j]<tableau_vector[j-1]. - #l will correspond to the shape of T_j + while tableau_vector != last_tableau: + # Locate the smallest integer j such that j is not + # in the lowest corner of the subtableau T_j formed by + # 1,...,j. This happens to be first j such that + # ntableau_vector[j]<tableau_vector[j-1]. + # l will correspond to the shape of T_j l = [0]*size l[0] = 1 j = 0 - for i in range(1,size): + for i in range(1, size): l[tableau_vector[i]] += 1 - if ( tableau_vector[i] < tableau_vector[i-1] ): + if (tableau_vector[i] < tableau_vector[i-1]): j = i break - #Find the last nonzero row of l and store it in k + # Find the last nonzero row of l and store it in k i = size - 1 - while ( l[i] == 0 ): + while (l[i] == 0): i -= 1 k = i - #Find a new row for the letter j (next lowest corner) - t = l[ 1 + tableau_vector[j] ] + # Find a new row for the letter j (next lowest corner) + t = l[1 + tableau_vector[j]] i = k - while ( l[i] != t ): + while (l[i] != t): i -= 1 - #Move the letter j to row i + # Move the letter j to row i tableau_vector[j] = i l[i] -= 1 - #Fill in the columns of T_j using 1,...,j-1 in increasing order + # Fill in the columns of T_j using 1,...,j-1 in increasing order m = 0 - while ( m < j ): + while (m < j): r = 0 - while ( l[r] != 0 ): + while (l[r] != 0): tableau_vector[m] = r l[r] -= 1 m += 1 r += 1 - #Convert the tableau vector back to the regular tableau - #format + # Convert the tableau vector back to the regular tableau + # format row_count = [0] * len(pi) tableau = [[None] * n for n in pi] @@ -8226,7 +8207,7 @@ def random_element(self): cells = [] for i in range(len(p)): for j in range(p[i]): - cells.append((i,j)) + cells.append((i, j)) m = sum(p) while m > 0: @@ -8343,7 +8324,7 @@ def symmetric_group_action_on_values(word, perm): l = r + 1 places_r, places_l = unmatched_places(w, l, r) - #Now change the number of l's and r's in the new word + # Now change the number of l's and r's in the new word nbl = len(places_l) nbr = len(places_r) ma = max(nbl, nbr) @@ -8613,8 +8594,8 @@ def __classcall_private__(cls, *args, **kwargs): elif shape in SkewPartitions(): raise NotImplementedError("skew increasing tableaux are not" " currently implemented") - #from sage.combinat.skew_tableau import IncreasingSkewTableaux - #return IncreasingSkewTableaux(shape, wt) + # from sage.combinat.skew_tableau import IncreasingSkewTableaux + # return IncreasingSkewTableaux(shape, wt) else: raise ValueError("shape must be a (skew) partition") @@ -8758,9 +8739,9 @@ def __getitem__(self, r): ... ValueError: infinite set """ - if isinstance(r, (int,Integer)): + if isinstance(r, (int, Integer)): return self.unrank(r) - elif isinstance(r,slice): + elif isinstance(r, slice): start = 0 if r.start is None else r.start stop = r.stop if stop is None and not self.is_finite(): @@ -9444,10 +9425,10 @@ def __iter__(self): list_of_inc_tabs.append(self.element_class(self, active_tab)) continue growth_spots = [] - for (r,c) in unfilled_spots: - if (r-1,c) not in active_tab.cells() or active_tab[r-1][c] != 0: - if (r,c-1) not in active_tab.cells() or active_tab[r][c-1] != 0: - growth_spots.append((r,c)) + for (r, c) in unfilled_spots: + if (r-1, c) not in active_tab.cells() or active_tab[r-1][c] != 0: + if (r, c-1) not in active_tab.cells() or active_tab[r][c-1] != 0: + growth_spots.append((r, c)) growth_choices = list(powerset(growth_spots)) top_value = max(active_tab.entries()) try: @@ -9456,9 +9437,9 @@ def __iter__(self): continue for growth_choice in growth_choices[1:]: new_tab = [[0] * k for k in self.shape] - for (r,c) in active_tab.cells(): + for (r, c) in active_tab.cells(): new_tab[r][c] = active_tab[r][c] - for (r,c) in growth_choice: + for (r, c) in growth_choice: new_tab[r][c] = growth_num list_of_partial_inc_tabs.append(Tableau(new_tab)) for inctab in list_of_inc_tabs: From 1aa7fcbf0a4ffa8e4cfe0ed8c568ac842eb8a681 Mon Sep 17 00:00:00 2001 From: OP5642 <ognjenpetrov@yahoo.com> Date: Sat, 20 May 2023 23:34:05 +0200 Subject: [PATCH 027/228] Initial work on is_minimally_non_golod() method --- src/sage/topology/simplicial_complex.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/sage/topology/simplicial_complex.py b/src/sage/topology/simplicial_complex.py index fcfea71bf1f..f9aefacd12e 100644 --- a/src/sage/topology/simplicial_complex.py +++ b/src/sage/topology/simplicial_complex.py @@ -4920,6 +4920,22 @@ def bigraded_betti_number(self, a, b, base_ring=ZZ): return B + def is_minimally_non_golod(self, decomposition=True): + r""" + Return whether `self` is minimally non-Golod. + + A simplicial complex is Golod if multiplication and all higher + Massey operations in the associated Tor-algebra are trivial. If + a simplicial complex itself is not Golod, but deleting each vertex + gives us a full subcomplex that is Golod, then we say that a simplicial + complex is minimally non-Golod. + + :param decomposition: If ``False``, do not print the decomposition + of the corresponding moment-angle complex + :type decomposition: boolean; optional, default ``True`` + """ + #TODO + # Miscellaneous utility functions. # The following two functions can be used to generate the facets for From 913f84dae4ae5a908fa4ba99ef3ea7902f167b38 Mon Sep 17 00:00:00 2001 From: OP5642 <ognjenpetrov@yahoo.com> Date: Mon, 22 May 2023 00:40:03 +0200 Subject: [PATCH 028/228] Added is_golod() method --- src/sage/topology/simplicial_complex.py | 28 ++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/sage/topology/simplicial_complex.py b/src/sage/topology/simplicial_complex.py index f9aefacd12e..f404bf0dfc4 100644 --- a/src/sage/topology/simplicial_complex.py +++ b/src/sage/topology/simplicial_complex.py @@ -4920,13 +4920,27 @@ def bigraded_betti_number(self, a, b, base_ring=ZZ): return B + def is_golod(self): + r""" + Return whether `self` is Golod. + + A simplicial complex is Golod if multiplication and all higher + Massey operations in the associated Tor-algebra are trivial. This + is done by checking the bigraded Betti numbers. + """ + H = set(a+b for (a, b) in self.bigraded_betti_numbers()) + + for i in H: + for j in H: + if i + j in H: + return False + return True + def is_minimally_non_golod(self, decomposition=True): r""" Return whether `self` is minimally non-Golod. - A simplicial complex is Golod if multiplication and all higher - Massey operations in the associated Tor-algebra are trivial. If - a simplicial complex itself is not Golod, but deleting each vertex + If a simplicial complex itself is not Golod, but deleting each vertex gives us a full subcomplex that is Golod, then we say that a simplicial complex is minimally non-Golod. @@ -4935,6 +4949,14 @@ def is_minimally_non_golod(self, decomposition=True): :type decomposition: boolean; optional, default ``True`` """ #TODO + L = self.vertices() + n = len(L) + + for x in combinations(L, n-1): + if not self.generated_subcomplex(x).is_golod(): + return False + + return True # Miscellaneous utility functions. From b695c0428c8366250d342c64681d0aa073128f34 Mon Sep 17 00:00:00 2001 From: Sebastian Oehms <seb.oehms@gmail.com> Date: Mon, 22 May 2023 21:41:38 +0200 Subject: [PATCH 029/228] 34185: fix RST issues --- src/sage/doctest/control.py | 2 +- src/sage/features/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index 7621927212b..7a7428bb78c 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -1353,7 +1353,7 @@ def run(self): Features detected... 0 - We test the ``--hide`` option (:trac:`34185`): + We test the ``--hide`` option (:trac:`34185`):: sage: from sage.doctest.control import test_hide sage: filename = tmp_filename(ext='.py') diff --git a/src/sage/features/__init__.py b/src/sage/features/__init__.py index 54994a4d859..79c47a621b2 100644 --- a/src/sage/features/__init__.py +++ b/src/sage/features/__init__.py @@ -348,7 +348,7 @@ def is_optional(self): def hide(self): r""" Hide this feature. For example this is used when the doctest option - ``--hide``is set. Setting an installed feature as hidden pretends + ``--hide`` is set. Setting an installed feature as hidden pretends that it is not available. To revert this use :meth:`unhide`. EXAMPLES: From e74eb7d3237fbf8fdd78e6eea56c28099661fdc2 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian <aram.dermenjian.math@gmail.com> Date: Thu, 25 May 2023 16:12:44 +0100 Subject: [PATCH 030/228] Change design for Russian Tableau in Ascii art --- src/sage/combinat/output.py | 188 +++++++++++++++++++---------------- src/sage/combinat/tableau.py | 44 ++++---- 2 files changed, 123 insertions(+), 109 deletions(-) diff --git a/src/sage/combinat/output.py b/src/sage/combinat/output.py index 169851e34a1..e91cf917526 100644 --- a/src/sage/combinat/output.py +++ b/src/sage/combinat/output.py @@ -617,66 +617,61 @@ def ascii_art_table_russian(data, use_unicode=False, compact=False): EXAMPLES:: sage: from sage.combinat.output import ascii_art_table_russian - sage: data = [[None, None, 1], [2, 2], [3,4,5], [None, None, 10], [], [6]] + sage: data = [[None, None, 1], [2, 2, 2], [3,4], [None, 10], [6]] sage: print(ascii_art_table_russian(data)) - \ 6 X X 10 X X X / - \ / \ / \ / \ / \ / \ / - \ / \ / \ / \ / \ / \ / - \ X X 5 X X / - \ / \ / \ / \ / \ / - \ / \ / \ / \ / \ / - \ X 4 X X / - \ / \ / \ / \ / - \ / \ / \ / \ / - \ 3 X 2 X 1 / - \ / \ / \ / - \ / \ / \ / - \ 2 X / - \ / \ / - \ / \ / - \ / - \ / - \ / + / \ / \ + / \ / \ + \ 6 X 10 \ + \ / \ / \ / \ + \ / \ / \ / \ + \ X 4 X 2 \ + \ / \ / \ / \ + \ / \ / \ / \ + \ 3 X 2 X 1 / + \ / \ / \ / + \ / \ / \ / + \ 2 X / + \ / \ / + \ / \ / + \ / + \ / + \ / + sage: print(ascii_art_table_russian(data, use_unicode=True)) - ╲ 6 ╳ ╳ 10 ╳ ╳ ╳ ╱ - ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ - ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ - ╲ ╳ ╳ 5 ╳ ╳ ╱ - ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ - ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ - ╲ ╳ 4 ╳ ╳ ╱ - ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ - ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ - ╲ 3 ╳ 2 ╳ 1 ╱ - ╲ ╱ ╲ ╱ ╲ ╱ - ╲ ╱ ╲ ╱ ╲ ╱ - ╲ 2 ╳ ╱ - ╲ ╱ ╲ ╱ - ╲ ╱ ╲ ╱ - ╲ ╱ - ╲ ╱ - ╲ ╱ + ╱ ╲ ╱ ╲ + ╱ ╲ ╱ ╲ + ╲ 6 ╳ 10 ╲ + ╲ ╱ ╲ ╱ ╲ ╱ ╲ + ╲ ╱ ╲ ╱ ╲ ╱ ╲ + ╲ ╳ 4 ╳ 2 ╲ + ╲ ╱ ╲ ╱ ╲ ╱ ╲ + ╲ ╱ ╲ ╱ ╲ ╱ ╲ + ╲ 3 ╳ 2 ╳ 1 ╱ + ╲ ╱ ╲ ╱ ╲ ╱ + ╲ ╱ ╲ ╱ ╲ ╱ + ╲ 2 ╳ ╱ + ╲ ╱ ╲ ╱ + ╲ ╱ ╲ ╱ + ╲ ╱ + ╲ ╱ + ╲ ╱ sage: data = [[1, None, 2], [None, 2]] sage: print(ascii_art_table_russian(data)) - \ X 2 X 2 / - \ / \ / \ / - \ / \ / \ / - \ X / - \ / \ / - \ / \ / - \ 1 / - \ / - \ / + / \ / \ + / 2 X 2 / + / \ / \ / + \ X / + \ / \ / + \ 1 / + \ / sage: print(ascii_art_table_russian(data, use_unicode=True)) - ╲ ╳ 2 ╳ 2 ╱ - ╲ ╱ ╲ ╱ ╲ ╱ - ╲ ╱ ╲ ╱ ╲ ╱ - ╲ ╳ ╱ - ╲ ╱ ╲ ╱ - ╲ ╱ ╲ ╱ - ╲ 1 ╱ - ╲ ╱ - ╲ ╱ + ╱ ╲ ╱ ╲ + ╱ 2 ╳ 2 ╱ + ╱ ╲ ╱ ╲ ╱ + ╲ ╳ ╱ + ╲ ╱ ╲ ╱ + ╲ 1 ╱ + ╲ ╱ """ if use_unicode: import unicodedata @@ -693,11 +688,6 @@ def ascii_art_table_russian(data, use_unicode=False, compact=False): if not data: return urdl + uldr + '\n' + uldr + urdl -# ncols = max(len(row) for row in data) -# str_tab = [[None]*ncols] + [[str(val) if val is not None else None for val in row] + [None]*(ncols-len(row)) -# for row in data] - str_tab = [[str(val) if val is not None else None for val in row] for row in data] - col_widths = [2] * len(str_tab[0]) if use_unicode: # Special handling of overline not adding to printed length @@ -711,39 +701,63 @@ def get_len(e): return 0 return len(e) - for row in str_tab: - for i, e in enumerate(row): - col_widths[i] = max(col_widths[i], get_len(e)) + # Length of max string (ensure it's odd) + str_tab = [[str(val) if val is not None else None for val in row] for row in data] + max_str = max([max([1] + [get_len(e) for e in row]) for row in str_tab]) + max_str = max_str + 1 - (max_str % 2) + if compact: - col_width = max(col_widths) - 1 + diag_length = max_str else: - col_width = max(col_widths) + 1 + diag_length = max_str + 2 # space on both sides + + row_height = int((diag_length + 1)/2) max_height = max([a + len(str_tab[a]) for a in range(len(str_tab))]) str_list = [] - for i in range(max_height): - # Get the row with the number on it - st = ' ' + ' ' * ((max_height - i - 1) * col_width) - for a in range(i + 1): - b = i - a - if a == 0: - st += uldr - else: - st += x - if len(str_tab[b:]) > 0 and len(str_tab[b][a:]) > 0 and str_tab[b][a] is not None: - st += str_tab[b][a].rjust(col_width, ' ').ljust(col_width * 2 - 1, ' ') - else: - st += ' '*(col_width * 2 - 1) - if b == 0: + for k in range(max_height, -1, -1): + for i in range(row_height): + if k == max_height and i == 0: + continue + st = ' ' * ((max_height - k) * (row_height)) + for j in range(k + 1): + st += ' ' * i + if len(str_tab[k-j:]) and (j == 0 or len(str_tab[k-j][j-1:])): + if i == 0: + if j > 0 and len(str_tab[k-j+1:]) and len(str_tab[k-j+1][j-1:]) and len(str_tab[k-j:]) and len(str_tab[k-j][j:]): + st += x + elif len(str_tab[k-j+1:]) and (j == 0 or len(str_tab[k-j+1][j-1:])): + st += uldr + elif len(str_tab[k-j:]) and len(str_tab[k-j][j:]): + if j == 0: + st += uldr + else: + st += urdl + # elif len(str_tab[k-j:]) and j > 0 and len(str_tab[k-j][j-1:]): + # st += '^' + else: + st += ' ' + else: + st += uldr + else: + st += ' ' + + if i == 0 and len(str_tab[k-j:]) and len(str_tab[k-j][j:]) and str_tab[k-j][j] is not None: + st_num = str_tab[k-j][j] + ln_left = int((len(st_num) - (len(st_num) % 2))/2) + st += st_num.rjust(row_height - 1 - ln_left + len(st_num), ' ').ljust(diag_length, ' ') + else: + st += ' ' * (diag_length - 2 * i) + if i > 0: + if (j == k and k < max_height and len(str_tab[0][j:])) or (len(str_tab[k-j-1:]) and len(str_tab[k-j-1][j:])): + st += urdl + else: + st += ' ' + st += ' ' * (i-1) + if i == 0 and j == k and k < max_height and len(str_tab[0][j:]): st += urdl + str_list.append(st) - # Do all of the additional rows - for j in range(col_width - 1, 0, -1): - st2 = ' ' + ' ' * ((max_height - i - 1) * col_width) - st2 += (' ' * j + uldr + ' ' * (2 * (col_width - j) - 1) + urdl + ' ' * (j - 1)) * (i + 1) - str_list.append(st2) - str_list.append(st) import re mm = min([len(re.search('^ +', l)[0]) for l in str_list]) - 1 - str_list = [l[mm:] for l in str_list] - str_list.reverse() + str_list = [l[mm:].rstrip() for l in str_list] return "\n".join(str_list) diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index ee17e14e928..6c2280710f2 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -489,15 +489,13 @@ def _ascii_art_(self): [ 1 2 3, 1 3, 1 2, 1 ] sage: Tableaux.options(convention="russian", ascii_art="table") sage: ascii_art(list(StandardTableaux(3))) - [ \ X X 3 / \ 3 X X / ] - [ \ / \ / \ / \ / \ / \ / ] - [ \ / \ / \ / \ / \ / \ / ] - [ \ X 2 / \ 2 X 3 / \ 3 X 2 / \ 2 X / ] - [ \ / \ / \ / \ / \ / \ / \ / \ / ] - [ \ / \ / \ / \ / \ / \ / \ / \ / ] - [ \ 1 / \ 1 / \ 1 / \ 1 / ] - [ \ / \ / \ / \ / ] - [ \ / , \ / , \ / , \ / ] + [ / \ / \ ] + [ / 3 / \ 3 \ ] + [ / \ / / \ / \ / \ / \ \ / \ ] + [ / 2 / \ 2 X 3 / \ 3 X 2 / \ 2 \ ] + [ / \ / \ / \ / \ / \ / \ / \ ] + [ \ 1 / \ 1 / \ 1 / \ 1 / ] + [ \ / , \ / , \ / , \ / ] sage: Tableaux.options(ascii_art="repr") sage: ascii_art(list(StandardTableaux(3))) [ 3 3 ] @@ -552,15 +550,13 @@ def _ascii_art_table(self, use_unicode=False): +---+---+---+ sage: Tableaux.options.convention="russian" sage: print(t._ascii_art_table()) - \ X 5 X 3 / - \ / \ / \ / - \ / \ / \ / - \ 4 X 2 / - \ / \ / - \ / \ / - \ 1 / - \ / - \ / + / \ / \ + / 5 X 3 / + / \ / \ / + \ 4 X 2 / + \ / \ / + \ 1 / + \ / sage: t = Tableau([]); print(t._ascii_art_table()) /\ \/ @@ -603,6 +599,8 @@ def _ascii_art_table(self, use_unicode=False): +----+----+----+---+ sage: Tableaux.options.convention="russian" sage: ascii_art(t) + / \ / \ / \ / \ + / \ / \ / \ / \ \ 9 X 10 X 6 X 7 / \ / \ / \ / \ / \ / \ / \ / \ / @@ -644,7 +642,9 @@ def _ascii_art_table(self, use_unicode=False): └────┴────┴────┴───┘ sage: Tableaux.options.convention="russian" sage: print(t._ascii_art_table(use_unicode=True)) - ╲ 9 ╳ 10 ╳ ╳ 7 ╱ + ╱ ╲ ╱ ╲ ╱ ╲ + ╱ ╲ ╱ ╲ ╱ ╲ + ╲ 9 ╳ 10 ╲ ╱ 7 ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ 8 ╳ 5 ╳ 15 ╱ @@ -679,9 +679,9 @@ def _ascii_art_compact(self): |1|2|3| sage: Tableaux.options.convention="russian" sage: print(t._ascii_art_compact()) - \ X5X3/ - \4X2/ - \1/ + /5X3/ + \4X2/ + \1/ sage: Tableaux.options._reset() sage: t = Tableau([[1,2,3,10,15],[12,15,17]]) From af8531a59fc07fc30784a749e3e75cfa3f3ce497 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian <aram.dermenjian.math@gmail.com> Date: Thu, 25 May 2023 16:13:39 +0100 Subject: [PATCH 031/228] Fix comment quotes --- src/sage/combinat/tableau.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 6c2280710f2..00e0382610b 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -461,7 +461,7 @@ def _repr_compact(self): return '/'.join(','.join('%s' % r for r in row) for row in self) def _ascii_art_(self): - r''' + r""" TESTS:: sage: ascii_art(list(StandardTableaux(3))) @@ -502,7 +502,7 @@ def _ascii_art_(self): [ 2 2 3 3 2 2 ] [ 1 , 1 , 1 , 1 ] sage: Tableaux.options._reset() - ''' + """ ascii = self.parent().options._dispatch(self, '_ascii_art_', 'ascii_art') from sage.typeset.ascii_art import AsciiArt return AsciiArt(ascii.splitlines()) @@ -529,7 +529,7 @@ def _unicode_art_(self): _ascii_art_repr = _repr_diagram def _ascii_art_table(self, use_unicode=False): - r''' + r""" TESTS: We check that :trac:`16487` is fixed:: @@ -657,14 +657,14 @@ def _ascii_art_table(self, use_unicode=False): ╲ ╱ ╲ ╱ sage: Tableaux.options._reset() - ''' + """ from sage.combinat.output import ascii_art_table self.parent().options('convention') return ascii_art_table(self, use_unicode=use_unicode, convention=self.parent().options('convention')) def _ascii_art_compact(self): - r''' + r""" TESTS: We check that :trac:`16487` is fixed:: @@ -692,7 +692,7 @@ def _ascii_art_compact(self): sage: t = Tableau([]) sage: print(t._ascii_art_compact()) . - ''' + """ if not self: return "." From 9a029155fe96e87f86ab8dd74806447ea2c47b12 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian <aram.dermenjian.math@gmail.com> Date: Thu, 25 May 2023 16:15:11 +0100 Subject: [PATCH 032/228] Remove parenthesis for while loops --- src/sage/combinat/tableau.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 00e0382610b..6b01ae998e2 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -8120,14 +8120,14 @@ def __iter__(self): # Find the last nonzero row of l and store it in k i = size - 1 - while (l[i] == 0): + while l[i] == 0: i -= 1 k = i # Find a new row for the letter j (next lowest corner) t = l[1 + tableau_vector[j]] i = k - while (l[i] != t): + while l[i] != t: i -= 1 # Move the letter j to row i @@ -8136,9 +8136,9 @@ def __iter__(self): # Fill in the columns of T_j using 1,...,j-1 in increasing order m = 0 - while (m < j): + while m < j: r = 0 - while (l[r] != 0): + while l[r] != 0: tableau_vector[m] = r l[r] -= 1 m += 1 From c3da4d839078c06f6bd28e6ec06322defa69d474 Mon Sep 17 00:00:00 2001 From: Sebastian Oehms <seb.oehms@gmail.com> Date: Thu, 25 May 2023 18:24:12 +0200 Subject: [PATCH 033/228] 34185 / 35668: fixes according to review --- src/bin/sage-runtests | 2 +- src/sage/features/__init__.py | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/bin/sage-runtests b/src/bin/sage-runtests index 2f3ad2d3829..29cc5a9299d 100755 --- a/src/bin/sage-runtests +++ b/src/bin/sage-runtests @@ -54,7 +54,7 @@ if __name__ == "__main__": 'Note that "!" needs to be quoted or escaped in the shell.') parser.add_argument("--hide", metavar="FEATURES", default="", help='run tests pretending that the software listed in FEATURES (separated by commas) is not installed; ' - 'if "all" is listed, will also hide features corresponding to all non standard packages; ' + 'if "all" is listed, will also hide features corresponding to all optional or experimental packages; ' 'if "optional" is listed, will also hide features corresponding to optional packages.') parser.add_argument("--randorder", type=int, metavar="SEED", help="randomize order of tests") parser.add_argument("--random-seed", dest="random_seed", type=int, metavar="SEED", help="random seed (integer) for fuzzing doctests", diff --git a/src/sage/features/__init__.py b/src/sage/features/__init__.py index 79c47a621b2..30ae1701784 100644 --- a/src/sage/features/__init__.py +++ b/src/sage/features/__init__.py @@ -295,7 +295,7 @@ def resolution(self): def joined_features(self): r""" - Return a list of features joined with ``self``. + Return a list of features that ``self`` is the join of. OUTPUT: @@ -306,14 +306,22 @@ def joined_features(self): sage: from sage.features.graphviz import Graphviz sage: Graphviz().joined_features() [Feature('dot'), Feature('neato'), Feature('twopi')] + sage: from sage.features.sagemath import sage__rings__function_field + sage: sage__rings__function_field().joined_features() + [Feature('sage.rings.function_field.function_field_polymod'), + Feature('sage.libs.singular'), + Feature('sage.libs.singular.singular'), + Feature('sage.interfaces.singular')] sage: from sage.features.interfaces import Mathematica sage: Mathematica().joined_features() [] """ from sage.features.join_feature import JoinFeature + res = [] if isinstance(self, JoinFeature): - return self._features - return [] + for f in self._features: + res += [f] + f.joined_features() + return res def is_standard(self): r""" From 5cbd601876ccdd4c66aaf4c70e9dd2b4bc3a84ae Mon Sep 17 00:00:00 2001 From: Aram Dermenjian <aram.dermenjian.math@gmail.com> Date: Fri, 26 May 2023 15:35:58 +0100 Subject: [PATCH 034/228] Initial change for blank tableau. --- src/sage/combinat/output.py | 6 ++++-- src/sage/combinat/tableau.py | 10 ++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/combinat/output.py b/src/sage/combinat/output.py index e91cf917526..e661d931318 100644 --- a/src/sage/combinat/output.py +++ b/src/sage/combinat/output.py @@ -489,7 +489,8 @@ def ascii_art_table(data, use_unicode=False, convention="English"): from sage.typeset.ascii_art import ascii_art as art if not data: - return dr + dl + '\n' + ur + ul + # return dr + dl + '\n' + ur + ul + return '' # Convert the input into a rectangular array with the top and bottom row # being all None's for ease later on. @@ -686,7 +687,8 @@ def ascii_art_table_russian(data, use_unicode=False, compact=False): from sage.typeset.ascii_art import ascii_art as art if not data: - return urdl + uldr + '\n' + uldr + urdl + # return urdl + uldr + '\n' + uldr + urdl + return '' if use_unicode: diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 6b01ae998e2..4662163ab54 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -520,8 +520,7 @@ def _unicode_art_(self): │ 5 │ └───┘ sage: unicode_art(Tableau([])) - ┌┐ - └┘ + <BLANKLINE> """ from sage.typeset.unicode_art import UnicodeArt return UnicodeArt(self._ascii_art_table(use_unicode=True).splitlines()) @@ -558,12 +557,11 @@ def _ascii_art_table(self, use_unicode=False): \ 1 / \ / sage: t = Tableau([]); print(t._ascii_art_table()) - /\ - \/ + <BLANKLINE> + sage: Tableaux.options.convention="french" sage: print(t._ascii_art_table()) - ++ - ++ + <BLANKLINE> sage: Tableaux.options._reset() sage: t = Tableau([[1,2,3,10,15],[12,15,17]]) From 12ce293ab1a1025b587d47c5e849facdd8d1ed6e Mon Sep 17 00:00:00 2001 From: Vincent Neiger <vneiger@users.noreply.github.com> Date: Tue, 30 May 2023 23:17:29 +0200 Subject: [PATCH 035/228] number field quadratic: fixing test and specifying rounding mode in the doc --- .../rings/number_field/number_field_element_quadratic.pyx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/number_field/number_field_element_quadratic.pyx b/src/sage/rings/number_field/number_field_element_quadratic.pyx index bcba57457e5..f0a99c02fe0 100644 --- a/src/sage/rings/number_field/number_field_element_quadratic.pyx +++ b/src/sage/rings/number_field/number_field_element_quadratic.pyx @@ -2310,7 +2310,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): def round(self): r""" - Returns the round (nearest integer). + Returns the round (nearest integer, away from zero in case of ties). EXAMPLES:: @@ -2332,9 +2332,9 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): sage: for _ in range(100): ....: a = QQ.random_element(1000,20) ....: b = QQ.random_element(1000,20) - ....: assert round(a) == round(K2(a)), a - ....: assert round(a) == round(K3(a)), a - ....: assert round(a) == round(K5(a)), a + ....: assert a.round("away") == round(K2(a)), a + ....: assert a.round("away") == round(K3(a)), a + ....: assert a.round("away") == round(K5(a)), a ....: assert round(a+b*sqrt(2.)) == round(a+b*sqrt2), (a, b) ....: assert round(a+b*sqrt(3.)) == round(a+b*sqrt3), (a, b) ....: assert round(a+b*sqrt(5.)) == round(a+b*sqrt5), (a, b) From a17f15363cfad76ed983db96c0187f9d2a3c8866 Mon Sep 17 00:00:00 2001 From: Vincent Neiger <vneiger@users.noreply.github.com> Date: Wed, 31 May 2023 12:01:42 +0200 Subject: [PATCH 036/228] fix weak Popov test and improve code documentation --- src/sage/matrix/matrix_polynomial_dense.pyx | 24 +++++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/sage/matrix/matrix_polynomial_dense.pyx b/src/sage/matrix/matrix_polynomial_dense.pyx index c3fd4d5bf61..fa54a6bab09 100644 --- a/src/sage/matrix/matrix_polynomial_dense.pyx +++ b/src/sage/matrix/matrix_polynomial_dense.pyx @@ -1663,20 +1663,30 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): if self.ncols() == 0 or self.nrows() == 0: return self._is_empty_popov(row_wise) leading_positions = self.leading_positions(shifts, row_wise) - # here, it will be convenient to have leading position - # larger than ncols for zero/empty rows - leading_positions = [pos if pos>=0 else self.ncols() + 1 for pos in leading_positions] + # here, because of the below sorting and of the convention that zero + # rows (resp. columns) are at the bottom (resp. right) of the matrix in + # the row-wise case (resp. column-wise case), it will be convenient to + # have leading position ncols (resp. nrows) for these zero vectors + pos_zero_vec = self.ncols() if row_wise else self.nrows() + leading_positions = [pos if pos>=0 else pos_zero_vec + 1 \ + for pos in leading_positions] # leading positions should not have duplicates, which is equivalent to: # once sorted, it doesn't contain a pair of equal successive entries + # (we do not sort if we want to test if not ordered: leading_positions.sort() # check that there is no zero vector, if it is forbidden - if leading_positions[-1] > self.ncols() and not include_zero_vectors: + # (in the ordered case, even though we have not sorted, this test of + # the last leading position is sufficient: in any case, if there is a + # zero vector followed by a nonzero one, the testing loop below will + # return False) + if leading_positions[-1] > pos_zero_vec and not include_zero_vectors: return False - # now leading_positions is nondecreasing: it remains to test whether - # it is strictly increasing (at least until the zero rows part) + # it remains to test whether leading_positions is strictly increasing + # until it reaches a zero vector (note this also checks that there is + # no zero vector encountered after a nonzero one) for index,next_leading_position in enumerate(leading_positions[1:]): - if next_leading_position <= self.ncols() and \ + if next_leading_position <= pos_zero_vec and \ next_leading_position <= leading_positions[index]: return False return True From 7b35369c57ee8dd1129f52ed595d2c0b860c8a40 Mon Sep 17 00:00:00 2001 From: Antonio Rojas <arojas@archlinux.org> Date: Thu, 1 Jun 2023 22:34:14 +0200 Subject: [PATCH 037/228] Run initialize-runtime-globals on maxima initialization to fix crashes with maxima 5.47 --- src/sage/interfaces/maxima_lib.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/interfaces/maxima_lib.py b/src/sage/interfaces/maxima_lib.py index bba8504aa92..c90196a0a48 100644 --- a/src/sage/interfaces/maxima_lib.py +++ b/src/sage/interfaces/maxima_lib.py @@ -133,6 +133,7 @@ ecl_eval("(require 'maxima \"{}\")".format(MAXIMA_FAS)) else: ecl_eval("(require 'maxima)") +ecl_eval("(maxima::initialize-runtime-globals)") ecl_eval("(in-package :maxima)") ecl_eval("(setq $nolabels t))") ecl_eval("(defvar *MAXIMA-LANG-SUBDIR* NIL)") From 2b57a084846c989eda9e560f5f400ea17f33a383 Mon Sep 17 00:00:00 2001 From: Antonio Rojas <arojas@archlinux.org> Date: Fri, 2 Jun 2023 00:08:24 +0200 Subject: [PATCH 038/228] Make tests pass with maxima 5.47 --- src/doc/de/tutorial/interfaces.rst | 4 +-- src/doc/de/tutorial/tour_algebra.rst | 4 +-- src/doc/en/constructions/linear_algebra.rst | 2 +- src/doc/en/tutorial/interfaces.rst | 4 +-- src/doc/en/tutorial/tour_algebra.rst | 4 +-- src/doc/es/tutorial/tour_algebra.rst | 4 +-- src/doc/fr/tutorial/interfaces.rst | 4 +-- src/doc/fr/tutorial/tour_algebra.rst | 4 +-- src/doc/it/tutorial/tour_algebra.rst | 4 +-- src/doc/ja/tutorial/interfaces.rst | 4 +-- src/doc/ja/tutorial/tour_algebra.rst | 4 +-- src/doc/pt/tutorial/interfaces.rst | 4 +-- src/doc/pt/tutorial/tour_algebra.rst | 4 +-- src/doc/ru/tutorial/interfaces.rst | 4 +-- src/doc/ru/tutorial/tour_algebra.rst | 4 +-- src/sage/calculus/calculus.py | 2 +- src/sage/calculus/desolvers.py | 6 ++--- src/sage/functions/bessel.py | 4 +-- src/sage/functions/hypergeometric.py | 5 +++- src/sage/functions/orthogonal_polys.py | 2 +- src/sage/functions/other.py | 2 +- src/sage/functions/special.py | 2 +- src/sage/interfaces/interface.py | 16 ++++++------ src/sage/interfaces/maxima.py | 28 ++++++++++----------- src/sage/interfaces/maxima_abstract.py | 6 ++--- src/sage/matrix/matrix1.pyx | 2 +- src/sage/modules/free_module_element.pyx | 2 +- src/sage/symbolic/relation.py | 2 +- 28 files changed, 70 insertions(+), 67 deletions(-) diff --git a/src/doc/de/tutorial/interfaces.rst b/src/doc/de/tutorial/interfaces.rst index edb4f383363..f3f98e7d206 100644 --- a/src/doc/de/tutorial/interfaces.rst +++ b/src/doc/de/tutorial/interfaces.rst @@ -273,7 +273,7 @@ deren :math:`i,j` Eintrag gerade :math:`i/j` ist, für :math:`i,j=1,\ldots,4`. sage: A.eigenvalues() [[0,4],[3,1]] sage: A.eigenvectors() - [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-4/3]],[[1,2,3,4]]]] + [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-...4/3...]],[[1,2,3,4]]]] Hier ein anderes Beispiel: @@ -335,7 +335,7 @@ Und der letzte ist die berühmte Kleinsche Flasche: sage: maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") 5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0 sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)") - -5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0) + -...5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)... sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") 5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y)) sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested diff --git a/src/doc/de/tutorial/tour_algebra.rst b/src/doc/de/tutorial/tour_algebra.rst index baba2553a25..9e2e67c53bd 100644 --- a/src/doc/de/tutorial/tour_algebra.rst +++ b/src/doc/de/tutorial/tour_algebra.rst @@ -211,7 +211,7 @@ Lösung: Berechnen Sie die Laplace-Transformierte der ersten Gleichung sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") sage: lde1 = de1.laplace("t","s"); lde1 - 2*((-%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) + 2*(...-...%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) Das ist schwierig zu lesen, es besagt jedoch, dass @@ -227,7 +227,7 @@ Laplace-Transformierte der zweiten Gleichung: sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") sage: lde2 = de2.laplace("t","s"); lde2 - (-%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s + ...-...%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s Dies besagt diff --git a/src/doc/en/constructions/linear_algebra.rst b/src/doc/en/constructions/linear_algebra.rst index 8894de9a5fd..f698342b02b 100644 --- a/src/doc/en/constructions/linear_algebra.rst +++ b/src/doc/en/constructions/linear_algebra.rst @@ -278,7 +278,7 @@ Another approach is to use the interface with Maxima: sage: A = maxima("matrix ([1, -4], [1, -1])") sage: eig = A.eigenvectors() sage: eig - [[[-sqrt(3)*%i,sqrt(3)*%i],[1,1]], [[[1,(sqrt(3)*%i+1)/4]],[[1,-(sqrt(3)*%i-1)/4]]]] + [[[-...sqrt(3)*%i...,sqrt(3)*%i],[1,1]], [[[1,(sqrt(3)*%i+1)/4]],[[1,-...(sqrt(3)*%i-1)/4...]]]] This tells us that :math:`\vec{v}_1 = [1,(\sqrt{3}i + 1)/4]` is an eigenvector of :math:`\lambda_1 = - \sqrt{3}i` (which occurs diff --git a/src/doc/en/tutorial/interfaces.rst b/src/doc/en/tutorial/interfaces.rst index b0e55345669..9728a5e2a5c 100644 --- a/src/doc/en/tutorial/interfaces.rst +++ b/src/doc/en/tutorial/interfaces.rst @@ -268,7 +268,7 @@ whose :math:`i,j` entry is :math:`i/j`, for sage: A.eigenvalues() [[0,4],[3,1]] sage: A.eigenvectors() - [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-4/3]],[[1,2,3,4]]]] + [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-...4/3...]],[[1,2,3,4]]]] Here's another example: @@ -321,7 +321,7 @@ The next plot is the famous Klein bottle (do not type the ``....:``):: sage: maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") 5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0 sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)") - -5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0) + -...5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)... sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") 5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y)) sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested diff --git a/src/doc/en/tutorial/tour_algebra.rst b/src/doc/en/tutorial/tour_algebra.rst index 2e872cc9059..e84c61bc54d 100644 --- a/src/doc/en/tutorial/tour_algebra.rst +++ b/src/doc/en/tutorial/tour_algebra.rst @@ -218,7 +218,7 @@ the notation :math:`x=x_{1}`, :math:`y=x_{2}`): sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") sage: lde1 = de1.laplace("t","s"); lde1 - 2*((-%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) + 2*(...-...%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) This is hard to read, but it says that @@ -233,7 +233,7 @@ Laplace transform of the second equation: sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") sage: lde2 = de2.laplace("t","s"); lde2 - (-%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s + ...-...%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s This says diff --git a/src/doc/es/tutorial/tour_algebra.rst b/src/doc/es/tutorial/tour_algebra.rst index dc1a7a96719..0edce6055df 100644 --- a/src/doc/es/tutorial/tour_algebra.rst +++ b/src/doc/es/tutorial/tour_algebra.rst @@ -198,7 +198,7 @@ la notación :math:`x=x_{1}`, :math:`y=x_{2}`): sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") sage: lde1 = de1.laplace("t","s"); lde1 - 2*((-%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) + 2*(...-...%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) El resultado puede ser difícil de leer, pero significa que @@ -213,7 +213,7 @@ Toma la transformada de Laplace de la segunda ecuación: sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") sage: lde2 = de2.laplace("t","s"); lde2 - (-%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s + ...-...%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s Esto dice diff --git a/src/doc/fr/tutorial/interfaces.rst b/src/doc/fr/tutorial/interfaces.rst index 1cd662f3083..569d7bba864 100644 --- a/src/doc/fr/tutorial/interfaces.rst +++ b/src/doc/fr/tutorial/interfaces.rst @@ -274,7 +274,7 @@ pour :math:`i,j=1,\ldots,4`. sage: A.eigenvalues() [[0,4],[3,1]] sage: A.eigenvectors() - [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-4/3]],[[1,2,3,4]]]] + [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-...4/3...]],[[1,2,3,4]]]] Un deuxième exemple : @@ -337,7 +337,7 @@ Et la fameuse bouteille de Klein (n'entrez pas les ``....:``): sage: maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") 5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0 sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)") - -5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0) + -...5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)... sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") 5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y)) sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested diff --git a/src/doc/fr/tutorial/tour_algebra.rst b/src/doc/fr/tutorial/tour_algebra.rst index 658894b2e8b..c67fd622630 100644 --- a/src/doc/fr/tutorial/tour_algebra.rst +++ b/src/doc/fr/tutorial/tour_algebra.rst @@ -183,7 +183,7 @@ Solution : Considérons la transformée de Laplace de la première équation sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") sage: lde1 = de1.laplace("t","s"); lde1 - 2*((-%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) + 2*(...-...%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) La réponse n'est pas très lisible, mais elle signifie que @@ -198,7 +198,7 @@ la seconde équation : sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") sage: lde2 = de2.laplace("t","s"); lde2 - (-%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s + ...-...%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s Ceci signifie diff --git a/src/doc/it/tutorial/tour_algebra.rst b/src/doc/it/tutorial/tour_algebra.rst index 5a5311e9b1c..af2292ffd68 100644 --- a/src/doc/it/tutorial/tour_algebra.rst +++ b/src/doc/it/tutorial/tour_algebra.rst @@ -184,7 +184,7 @@ la notazione :math:`x=x_{1}`, :math:`y=x_{2}`: sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") sage: lde1 = de1.laplace("t","s"); lde1 - 2*((-%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) + 2*(...-...%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) Questo è di difficile lettura, ma dice che @@ -199,7 +199,7 @@ trasformata di Laplace della seconda equazione: sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") sage: lde2 = de2.laplace("t","s"); lde2 - (-%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s + ...-...%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s che significa diff --git a/src/doc/ja/tutorial/interfaces.rst b/src/doc/ja/tutorial/interfaces.rst index 9c16b2eba08..19b168747b2 100644 --- a/src/doc/ja/tutorial/interfaces.rst +++ b/src/doc/ja/tutorial/interfaces.rst @@ -240,7 +240,7 @@ Sage/Maximaインターフェイスの使い方を例示するため,ここで sage: A.eigenvalues() [[0,4],[3,1]] sage: A.eigenvectors() - [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-4/3]],[[1,2,3,4]]]] + [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-...4/3...]],[[1,2,3,4]]]] 使用例をもう一つ示す: @@ -302,7 +302,7 @@ Sage/Maximaインターフェイスの使い方を例示するため,ここで sage: maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") 5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0 sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)") - -5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0) + -...5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)... sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") 5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y)) sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested diff --git a/src/doc/ja/tutorial/tour_algebra.rst b/src/doc/ja/tutorial/tour_algebra.rst index 784fd0d5c40..962d8e93d57 100644 --- a/src/doc/ja/tutorial/tour_algebra.rst +++ b/src/doc/ja/tutorial/tour_algebra.rst @@ -214,7 +214,7 @@ Sageを使って常微分方程式を研究することもできる. :math:`x' sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") sage: lde1 = de1.laplace("t","s"); lde1 - 2*((-%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) + 2*(...-...%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) この出力は読みにくいけれども,意味しているのは @@ -228,7 +228,7 @@ Sageを使って常微分方程式を研究することもできる. :math:`x' sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") sage: lde2 = de2.laplace("t","s"); lde2 - (-%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s + ...-...%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s 意味するところは diff --git a/src/doc/pt/tutorial/interfaces.rst b/src/doc/pt/tutorial/interfaces.rst index 386ef6456e5..778ff99df99 100644 --- a/src/doc/pt/tutorial/interfaces.rst +++ b/src/doc/pt/tutorial/interfaces.rst @@ -270,7 +270,7 @@ entrada :math:`i,j` é :math:`i/j`, para :math:`i,j=1,\ldots,4`. sage: A.eigenvalues() [[0,4],[3,1]] sage: A.eigenvectors() - [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-4/3]],[[1,2,3,4]]]] + [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-...4/3...]],[[1,2,3,4]]]] Aqui vai outro exemplo: @@ -334,7 +334,7 @@ E agora a famosa garrafa de Klein: ....: "- 10.0") 5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0 sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)") - -5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0) + -...5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)... sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") 5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y)) sage: maxima.plot3d("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested diff --git a/src/doc/pt/tutorial/tour_algebra.rst b/src/doc/pt/tutorial/tour_algebra.rst index baeb37b1c71..467ab1b3baa 100644 --- a/src/doc/pt/tutorial/tour_algebra.rst +++ b/src/doc/pt/tutorial/tour_algebra.rst @@ -206,7 +206,7 @@ equação (usando a notação :math:`x=x_{1}`, :math:`y=x_{2}`): sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") sage: lde1 = de1.laplace("t","s"); lde1 - 2*((-%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) + 2*(...-...%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) O resultado é um pouco difícil de ler, mas diz que @@ -221,7 +221,7 @@ calcule a transformada de Laplace da segunda equação: sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") sage: lde2 = de2.laplace("t","s"); lde2 - (-%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s + ...-...%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s O resultado significa que diff --git a/src/doc/ru/tutorial/interfaces.rst b/src/doc/ru/tutorial/interfaces.rst index ea84527f478..9ec728c282a 100644 --- a/src/doc/ru/tutorial/interfaces.rst +++ b/src/doc/ru/tutorial/interfaces.rst @@ -265,7 +265,7 @@ gnuplot, имеет методы решения и манипуляции мат sage: A.eigenvalues() [[0,4],[3,1]] sage: A.eigenvectors() - [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-4/3]],[[1,2,3,4]]]] + [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-...4/3...]],[[1,2,3,4]]]] Вот другой пример: @@ -326,7 +326,7 @@ gnuplot, имеет методы решения и манипуляции мат sage: maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") 5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0 sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)") - -5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0) + -...5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)... sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") 5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y)) sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested diff --git a/src/doc/ru/tutorial/tour_algebra.rst b/src/doc/ru/tutorial/tour_algebra.rst index 9f08c41d118..a32a1212303 100644 --- a/src/doc/ru/tutorial/tour_algebra.rst +++ b/src/doc/ru/tutorial/tour_algebra.rst @@ -200,7 +200,7 @@ Sage может использоваться для решения диффер sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") sage: lde1 = de1.laplace("t","s"); lde1 - 2*((-%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) + 2*(...-...%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) Данный результат тяжело читаем, однако должен быть понят как @@ -212,7 +212,7 @@ Sage может использоваться для решения диффер sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") sage: lde2 = de2.laplace("t","s"); lde2 - (-%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s + ...-...%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s Результат: diff --git a/src/sage/calculus/calculus.py b/src/sage/calculus/calculus.py index c707530b9f1..a826b8bf97f 100644 --- a/src/sage/calculus/calculus.py +++ b/src/sage/calculus/calculus.py @@ -783,7 +783,7 @@ def nintegral(ex, x, a, b, Now numerically integrating, we see why the answer is wrong:: sage: f.nintegrate(x,0,1) - (-480.0000000000001, 5.32907051820075...e-12, 21, 0) + (-480.000000000000..., 5.32907051820075...e-12, 21, 0) It is just because every floating point evaluation of return -480.0 in floating point. diff --git a/src/sage/calculus/desolvers.py b/src/sage/calculus/desolvers.py index e0c31925f44..6e91f7e2bb4 100644 --- a/src/sage/calculus/desolvers.py +++ b/src/sage/calculus/desolvers.py @@ -295,7 +295,7 @@ def desolve(de, dvar, ics=None, ivar=None, show_method=False, contrib_ode=False, Clairaut equation: general and singular solutions:: sage: desolve(diff(y,x)^2+x*diff(y,x)-y==0,y,contrib_ode=True,show_method=True) - [[y(x) == _C^2 + _C*x, y(x) == -1/4*x^2], 'clairault'] + [[y(x) == _C^2 + _C*x, y(x) == -1/4*x^2], 'clairau...'] For equations involving more variables we specify an independent variable:: @@ -1325,7 +1325,7 @@ def desolve_rk4(de, dvar, ics=None, ivar=None, end_points=None, step=0.1, output sage: x,y = var('x,y') sage: desolve_rk4(x*y*(2-y),y,ics=[0,1],end_points=1,step=0.5) - [[0, 1], [0.5, 1.12419127424558], [1.0, 1.461590162288825]] + [[0, 1], [0.5, 1.12419127424558], [1.0, 1.46159016228882...]] Variant 1 for input - we can pass ODE in the form used by desolve function In this example we integrate backwards, since @@ -1333,7 +1333,7 @@ def desolve_rk4(de, dvar, ics=None, ivar=None, end_points=None, step=0.1, output sage: y = function('y')(x) sage: desolve_rk4(diff(y,x)+y*(y-1) == x-2,y,ics=[1,1],step=0.5, end_points=0) - [[0.0, 8.904257108962112], [0.5, 1.909327945361535], [1, 1]] + [[0.0, 8.904257108962112], [0.5, 1.90932794536153...], [1, 1]] Here we show how to plot simple pictures. For more advanced applications use list_plot instead. To see the resulting picture diff --git a/src/sage/functions/bessel.py b/src/sage/functions/bessel.py index 95405c3d72f..e3d4f182d79 100644 --- a/src/sage/functions/bessel.py +++ b/src/sage/functions/bessel.py @@ -295,7 +295,7 @@ class Function_Bessel_J(BuiltinFunction): 1/24*x^3*hypergeometric((3/2,), (5/2, 3), -1/4*x^2) sage: m = maxima(bessel_J(2, x)) sage: m.integrate(x) - (hypergeometric([3/2],[5/2,3],-_SAGE_VAR_x^2/4)*_SAGE_VAR_x^3)/24 + (hypergeometric([3/2],[5/2,3],-..._SAGE_VAR_x^2/4)...*_SAGE_VAR_x^3)/24 Visualization (set plot_points to a higher value to get more detail):: @@ -1122,7 +1122,7 @@ def Bessel(*args, **kwds): sage: f.derivative('_SAGE_VAR_x') (%pi*csc(%pi*_SAGE_VAR_x) *('diff(bessel_i(-_SAGE_VAR_x,_SAGE_VAR_y),_SAGE_VAR_x,1) -'diff(bessel_i(_SAGE_VAR_x,_SAGE_VAR_y),_SAGE_VAR_x,1))) /2 -%pi*bessel_k(_SAGE_VAR_x,_SAGE_VAR_y)*cot(%pi*_SAGE_VAR_x) sage: f.derivative('_SAGE_VAR_y') - -(bessel_k(_SAGE_VAR_x+1,_SAGE_VAR_y)+bessel_k(_SAGE_VAR_x-1, _SAGE_VAR_y))/2 + -(...bessel_k(_SAGE_VAR_x+1,_SAGE_VAR_y)+bessel_k(_SAGE_VAR_x-1, _SAGE_VAR_y)).../2... Compute the particular solution to Bessel's Differential Equation that satisfies `y(1) = 1` and `y'(1) = 1`, then verify the initial conditions diff --git a/src/sage/functions/hypergeometric.py b/src/sage/functions/hypergeometric.py index 752b8422fc6..fc2fb5875ce 100644 --- a/src/sage/functions/hypergeometric.py +++ b/src/sage/functions/hypergeometric.py @@ -19,8 +19,11 @@ sage: sum(((2*I)^x/(x^3 + 1)*(1/4)^x), x, 0, oo) hypergeometric((1, 1, -1/2*I*sqrt(3) - 1/2, 1/2*I*sqrt(3) - 1/2),... (2, -1/2*I*sqrt(3) + 1/2, 1/2*I*sqrt(3) + 1/2), 1/2*I) - sage: sum((-1)^x/((2*x + 1)*factorial(2*x + 1)), x, 0, oo) + sage: res = sum((-1)^x/((2*x + 1)*factorial(2*x + 1)), x, 0, oo) + sage: res # not tested - depends on maxima version hypergeometric((1/2,), (3/2, 3/2), -1/4) + sage: res in [hypergeometric((1/2,), (3/2, 3/2), -1/4), sin_integral(1)] + True Simplification (note that ``simplify_full`` does not yet call ``simplify_hypergeometric``):: diff --git a/src/sage/functions/orthogonal_polys.py b/src/sage/functions/orthogonal_polys.py index 7398c763971..6127f5d9490 100644 --- a/src/sage/functions/orthogonal_polys.py +++ b/src/sage/functions/orthogonal_polys.py @@ -974,7 +974,7 @@ def __init__(self): sage: chebyshev_U(x, x)._sympy_() chebyshevu(x, x) sage: maxima(chebyshev_U(2,x, hold=True)) - 3*((-(8*(1-_SAGE_VAR_x))/3)+(4*(1-_SAGE_VAR_x)^2)/3+1) + 3*(...-...(8*(1-_SAGE_VAR_x))/3)+(4*(1-_SAGE_VAR_x)^2)/3+1) sage: maxima(chebyshev_U(n,x, hold=True)) chebyshev_u(_SAGE_VAR_n,_SAGE_VAR_x) """ diff --git a/src/sage/functions/other.py b/src/sage/functions/other.py index 3e2570e889e..39e144d9ca2 100644 --- a/src/sage/functions/other.py +++ b/src/sage/functions/other.py @@ -501,7 +501,7 @@ def __init__(self): sage: a = floor(5.4 + x); a floor(x + 5.40000000000000) sage: a.simplify() - floor(x + 0.4000000000000004) + 5 + floor(x + 0.400000000000000...) + 5 sage: a(x=2) 7 diff --git a/src/sage/functions/special.py b/src/sage/functions/special.py index faa6a73cc7e..3978392dba0 100644 --- a/src/sage/functions/special.py +++ b/src/sage/functions/special.py @@ -457,7 +457,7 @@ class EllipticE(BuiltinFunction): elliptic_e(z, 1) sage: # this is still wrong: must be abs(sin(z)) + 2*round(z/pi) sage: elliptic_e(z, 1).simplify() - 2*round(z/pi) + sin(z) + 2*round(z/pi) ... sin(...z) sage: elliptic_e(z, 0) z sage: elliptic_e(0.5, 0.1) # abs tol 2e-15 diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index 6baa4eb597c..bacbbfe87f9 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -1581,18 +1581,18 @@ def _mul_(self, right): sage: f = maxima.function('x','sin(x)') sage: g = maxima('-cos(x)') # not a function! sage: f*g - -cos(x)*sin(x) + -...cos(x)*sin(x)... sage: _(2) - -cos(2)*sin(2) + -...cos(2)*sin(2)... :: sage: f = maxima.function('x','sin(x)') sage: g = maxima('-cos(x)') sage: g*f - -cos(x)*sin(x) + -...cos(x)*sin(x)... sage: _(2) - -cos(2)*sin(2) + -...cos(2)*sin(2)... sage: 2*f 2*sin(x) """ @@ -1614,18 +1614,18 @@ def _div_(self, right): sage: f = maxima.function('x','sin(x)') sage: g = maxima('-cos(x)') sage: f/g - -sin(x)/cos(x) + -...sin(x)/cos(x)... sage: _(2) - -sin(2)/cos(2) + -...sin(2)/cos(2)... :: sage: f = maxima.function('x','sin(x)') sage: g = maxima('-cos(x)') sage: g/f - -cos(x)/sin(x) + -...cos(x)/sin(x)... sage: _(2) - -cos(2)/sin(2) + -...cos(2)/sin(2)... sage: 2/f 2/sin(x) """ diff --git a/src/sage/interfaces/maxima.py b/src/sage/interfaces/maxima.py index 4829560f98b..ebbd9133734 100644 --- a/src/sage/interfaces/maxima.py +++ b/src/sage/interfaces/maxima.py @@ -51,7 +51,7 @@ sage: F = maxima.factor('x^5 - y^5') sage: F - -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4) + -...(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)... sage: type(F) <class 'sage.interfaces.maxima.MaximaElement'> @@ -72,9 +72,9 @@ :: sage: repr(F) - '-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)' + '-...(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)...' sage: F.str() - '-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)' + '-...(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)...' The ``maxima.eval`` command evaluates an expression in maxima and returns the result as a *string* not a maxima object. @@ -82,7 +82,7 @@ :: sage: print(maxima.eval('factor(x^5 - y^5)')) - -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4) + -...(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)... We can create the polynomial `f` as a Maxima polynomial, then call the factor method on it. Notice that the notation @@ -95,7 +95,7 @@ sage: f^2 (x^5-y^5)^2 sage: f.factor() - -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4) + -...(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)... Control-C interruption works well with the maxima interface, because of the excellent implementation of maxima. For example, try @@ -161,20 +161,20 @@ sage: eqn = maxima(['a+b*c=1', 'b-a*c=0', 'a+b=5']) sage: s = eqn.solve('[a,b,c]'); s - [[a = -(sqrt(79)*%i-11)/4,b = (sqrt(79)*%i+9)/4, c = (sqrt(79)*%i+1)/10], [a = (sqrt(79)*%i+11)/4,b = -(sqrt(79)*%i-9)/4, c = -(sqrt(79)*%i-1)/10]] + [[a = -...(sqrt(79)*%i-11)/4...,b = (sqrt(79)*%i+9)/4, c = (sqrt(79)*%i+1)/10], [a = (sqrt(79)*%i+11)/4,b = -...(sqrt(79)*%i-9)/4..., c = -...(sqrt(79)*%i-1)/10...]] Here is an example of solving an algebraic equation:: sage: maxima('x^2+y^2=1').solve('y') [y = -sqrt(1-x^2),y = sqrt(1-x^2)] sage: maxima('x^2 + y^2 = (x^2 - y^2)/sqrt(x^2 + y^2)').solve('y') - [y = -sqrt(((-y^2)-x^2)*sqrt(y^2+x^2)+x^2), y = sqrt(((-y^2)-x^2)*sqrt(y^2+x^2)+x^2)] + [y = -sqrt((...-y^2...-x^2)*sqrt(y^2+x^2)+x^2), y = sqrt((...-y^2...-x^2)*sqrt(y^2+x^2)+x^2)] You can even nicely typeset the solution in latex:: sage: latex(s) - \left[ \left[ a=-{{\sqrt{79}\,i-11}\over{4}} , b={{\sqrt{79}\,i+9 }\over{4}} , c={{\sqrt{79}\,i+1}\over{10}} \right] , \left[ a={{ \sqrt{79}\,i+11}\over{4}} , b=-{{\sqrt{79}\,i-9}\over{4}} , c=-{{ \sqrt{79}\,i-1}\over{10}} \right] \right] + \left[ \left[ a=-...{{\sqrt{79}\,i-11}\over{4}}... , b={{...\sqrt{79}\,i+9...}\over{4}} , c={{\sqrt{79}\,i+1}\over{10}} \right] , \left[ a={{...\sqrt{79}\,i+11}\over{4}} , b=-...{{\sqrt{79}\,i-9...}\over{4}}... , c=-...{{...\sqrt{79}\,i-1}\over{10}}... \right] \right] To have the above appear onscreen via ``xdvi``, type ``view(s)``. (TODO: For OS X should create pdf output @@ -200,7 +200,7 @@ sage: f.diff('x') k*x^3*%e^(k*x)*sin(w*x)+3*x^2*%e^(k*x)*sin(w*x)+w*x^3*%e^(k*x) *cos(w*x) sage: f.integrate('x') - (((k*w^6+3*k^3*w^4+3*k^5*w^2+k^7)*x^3 +(3*w^6+3*k^2*w^4-3*k^4*w^2-3*k^6)*x^2+((-18*k*w^4)-12*k^3*w^2+6*k^5)*x-6*w^4 +36*k^2*w^2-6*k^4) *%e^(k*x)*sin(w*x) +(((-w^7)-3*k^2*w^5-3*k^4*w^3-k^6*w)*x^3 +(6*k*w^5+12*k^3*w^3+6*k^5*w)*x^2+(6*w^5-12*k^2*w^3-18*k^4*w)*x-24*k*w^3 +24*k^3*w) *%e^(k*x)*cos(w*x)) /(w^8+4*k^2*w^6+6*k^4*w^4+4*k^6*w^2+k^8) + (((k*w^6+3*k^3*w^4+3*k^5*w^2+k^7)*x^3 +(3*w^6+3*k^2*w^4-3*k^4*w^2-3*k^6)*x^2+(...-...18*k*w^4)-12*k^3*w^2+6*k^5)*x-6*w^4 +36*k^2*w^2-6*k^4) *%e^(k*x)*sin(w*x) +((...-w^7...-3*k^2*w^5-3*k^4*w^3-k^6*w)*x^3...+(6*k*w^5+12*k^3*w^3+6*k^5*w)*x^2...+(6*w^5-12*k^2*w^3-18*k^4*w)*x-24*k*w^3 +24*k^3*w) *%e^(k*x)*cos(w*x)) /(w^8+4*k^2*w^6+6*k^4*w^4+4*k^6*w^2+k^8) :: @@ -234,7 +234,7 @@ sage: A.eigenvalues() [[0,4],[3,1]] sage: A.eigenvectors() - [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-4/3]],[[1,2,3,4]]]] + [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-...4/3...]],[[1,2,3,4]]]] We can also compute the echelon form in Sage:: @@ -287,12 +287,12 @@ :: sage: maxima("laplace(diff(x(t),t,2),t,s)") - (-%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s + ...-...%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s It is difficult to read some of these without the 2d representation:: - sage: print(maxima("laplace(diff(x(t),t,2),t,s)")) + sage: print(maxima("laplace(diff(x(t),t,2),t,s)")) # not tested - depends on maxima version ! d ! 2 (- -- (x(t))! ) + s laplace(x(t), t, s) - x(0) s @@ -396,7 +396,7 @@ sage: g = maxima('exp(3*%i*x)/(6*%i) + exp(%i*x)/(2*%i) + c') sage: latex(g) - -{{i\,e^{3\,i\,x}}\over{6}}-{{i\,e^{i\,x}}\over{2}}+c + -...{{i\,e^{3\,i\,x}}\over{6}}...-{{i\,e^{i\,x}}\over{2}}+c Long Input ---------- @@ -684,7 +684,7 @@ def _expect_expr(self, expr=None, timeout=None): sage: maxima.assume('a>0') [a > 0] sage: maxima('integrate(1/(x^3*(a+b*x)^(1/3)),x)') - (-(b^2*log((b*x+a)^(2/3)+a^(1/3)*(b*x+a)^(1/3)+a^(2/3)))/(9*a^(7/3))) +(2*b^2*atan((2*(b*x+a)^(1/3)+a^(1/3))/(sqrt(3)*a^(1/3))))/(3^(3/2)*a^(7/3)) +(2*b^2*log((b*x+a)^(1/3)-a^(1/3)))/(9*a^(7/3)) +(4*b^2*(b*x+a)^(5/3)-7*a*b^2*(b*x+a)^(2/3)) /(6*a^2*(b*x+a)^2-12*a^3*(b*x+a)+6*a^4) + ...-...(b^2*log((b*x+a)^(2/3)+a^(1/3)*(b*x+a)^(1/3)+a^(2/3)))/(9*a^(7/3))) +(2*b^2*atan((2*(b*x+a)^(1/3)+a^(1/3))/(sqrt(3)*a^(1/3))))/(3^(3/2)*a^(7/3)) +(2*b^2*log((b*x+a)^(1/3)-a^(1/3)))/(9*a^(7/3)) +(4*b^2*(b*x+a)^(5/3)-7*a*b^2*(b*x+a)^(2/3)) /(6*a^2*(b*x+a)^2-12*a^3*(b*x+a)+6*a^4) sage: maxima('integrate(x^n,x)') Traceback (most recent call last): ... diff --git a/src/sage/interfaces/maxima_abstract.py b/src/sage/interfaces/maxima_abstract.py index 4f6306ba4fc..a5b5f35d188 100644 --- a/src/sage/interfaces/maxima_abstract.py +++ b/src/sage/interfaces/maxima_abstract.py @@ -856,9 +856,9 @@ def de_solve(self, de, vars, ics=None): sage: maxima.de_solve('diff(y,x,2) + 3*x = y', ['x','y']) y = %k1*%e^x+%k2*%e^-x+3*x sage: maxima.de_solve('diff(y,x) + 3*x = y', ['x','y']) - y = (%c-3*((-x)-1)*%e^-x)*%e^x + y = (%c-3*(...-x...-1)*%e^-x)*%e^x sage: maxima.de_solve('diff(y,x) + 3*x = y', ['x','y'],[1,1]) - y = -%e^-1*(5*%e^x-3*%e*x-3*%e) + y = -...%e^-1*(5*%e^x-3*%e*x-3*%e)... """ if not isinstance(vars, str): str_vars = '%s, %s'%(vars[1], vars[0]) @@ -1573,7 +1573,7 @@ def integral(self, var='x', min=None, max=None): :: sage: f = maxima('exp(x^2)').integral('x',0,1); f - -(sqrt(%pi)*%i*erf(%i))/2 + -...(sqrt(%pi)*%i*erf(%i))/2... sage: f.numer() 1.46265174590718... """ diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index f38c429d994..47df9fc80a5 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -248,7 +248,7 @@ cdef class Matrix(Matrix0): sage: a = maxima(m); a matrix([0,1,2],[3,4,5],[6,7,8]) sage: a.charpoly('x').expand() - (-x^3)+12*x^2+18*x + ...-x^3...+12*x^2+18*x sage: m.charpoly() x^3 - 12*x^2 - 18*x """ diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 0532ea0c9bd..94e63fdc5f8 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -4054,7 +4054,7 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: r=vector([t,t^2,sin(t)]) sage: vec,answers=r.nintegral(t,0,1) sage: vec - (0.5, 0.3333333333333334, 0.4596976941318602) + (0.5, 0.333333333333333..., 0.4596976941318602...) sage: type(vec) <class 'sage.modules.vector_real_double_dense.Vector_real_double_dense'> sage: answers diff --git a/src/sage/symbolic/relation.py b/src/sage/symbolic/relation.py index a72ab547c76..e0a3692a8ab 100644 --- a/src/sage/symbolic/relation.py +++ b/src/sage/symbolic/relation.py @@ -659,7 +659,7 @@ def solve(f, *args, **kwds): sage: sols = solve([x^3==y,y^2==x], [x,y]); sols[-1], sols[0] ([x == 0, y == 0], - [x == (0.3090169943749475 + 0.9510565162951535*I), + [x == (0.309016994374947... + 0.9510565162951535*I), y == (-0.8090169943749475 - 0.5877852522924731*I)]) sage: sols[0][0].rhs().pyobject().parent() Complex Double Field From ffff27dcaee4d3aa75214a6a5b05e3c3091aa2e2 Mon Sep 17 00:00:00 2001 From: Antonio Rojas <arojas@archlinux.org> Date: Fri, 2 Jun 2023 00:17:43 +0200 Subject: [PATCH 039/228] Fix one more test with maxima 5.47 --- src/sage/calculus/calculus.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/calculus/calculus.py b/src/sage/calculus/calculus.py index a826b8bf97f..f7ce8b95727 100644 --- a/src/sage/calculus/calculus.py +++ b/src/sage/calculus/calculus.py @@ -1336,7 +1336,7 @@ def limit(ex, dir=None, taylor=False, algorithm='maxima', **argv): sage: limit(floor(x), x=0, dir='+') 0 sage: limit(floor(x), x=0) - und + ...nd Maxima gives the right answer here, too, showing that :trac:`4142` is fixed:: From ee0928e72cad97a320eb68992920c84860fdc0e9 Mon Sep 17 00:00:00 2001 From: Antonio Rojas <arojas@archlinux.org> Date: Fri, 2 Jun 2023 08:19:40 +0200 Subject: [PATCH 040/228] Nicer fixes for tests --- src/doc/de/tutorial/interfaces.rst | 8 ++++---- src/doc/de/tutorial/tour_algebra.rst | 8 ++++---- src/doc/en/tutorial/interfaces.rst | 8 ++++---- src/doc/en/tutorial/tour_algebra.rst | 8 ++++---- src/doc/es/tutorial/tour_algebra.rst | 8 ++++---- src/doc/fr/tutorial/interfaces.rst | 8 ++++---- src/doc/fr/tutorial/tour_algebra.rst | 8 ++++---- src/doc/it/tutorial/tour_algebra.rst | 8 ++++---- src/doc/ja/tutorial/interfaces.rst | 8 ++++---- src/doc/ja/tutorial/tour_algebra.rst | 8 ++++---- src/doc/pt/tutorial/interfaces.rst | 8 ++++---- src/doc/pt/tutorial/tour_algebra.rst | 8 ++++---- src/doc/ru/tutorial/interfaces.rst | 8 ++++---- src/doc/ru/tutorial/tour_algebra.rst | 8 ++++---- src/sage/functions/bessel.py | 8 ++++---- 15 files changed, 60 insertions(+), 60 deletions(-) diff --git a/src/doc/de/tutorial/interfaces.rst b/src/doc/de/tutorial/interfaces.rst index f3f98e7d206..3b5bde7df15 100644 --- a/src/doc/de/tutorial/interfaces.rst +++ b/src/doc/de/tutorial/interfaces.rst @@ -272,8 +272,8 @@ deren :math:`i,j` Eintrag gerade :math:`i/j` ist, für :math:`i,j=1,\ldots,4`. matrix([1,1/2,1/3,1/4],[0,0,0,0],[0,0,0,0],[0,0,0,0]) sage: A.eigenvalues() [[0,4],[3,1]] - sage: A.eigenvectors() - [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-...4/3...]],[[1,2,3,4]]]] + sage: A.eigenvectors().sage() + [[[0, 4], [3, 1]], [[[1, 0, 0, -4], [0, 1, 0, -2], [0, 0, 1, -4/3]], [[1, 2, 3, 4]]]] Hier ein anderes Beispiel: @@ -334,8 +334,8 @@ Und der letzte ist die berühmte Kleinsche Flasche: sage: maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") 5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0 - sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)") - -...5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)... + sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() + -5*(cos(1/2*x)*cos(y) + sin(1/2*x)*sin(2*y) + 3.0)*sin(x) sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") 5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y)) sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested diff --git a/src/doc/de/tutorial/tour_algebra.rst b/src/doc/de/tutorial/tour_algebra.rst index 9e2e67c53bd..60e05332eaa 100644 --- a/src/doc/de/tutorial/tour_algebra.rst +++ b/src/doc/de/tutorial/tour_algebra.rst @@ -210,8 +210,8 @@ Lösung: Berechnen Sie die Laplace-Transformierte der ersten Gleichung :: sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") - sage: lde1 = de1.laplace("t","s"); lde1 - 2*(...-...%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) + sage: lde1 = de1.laplace("t","s"); lde1.sage() + 2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0) Das ist schwierig zu lesen, es besagt jedoch, dass @@ -226,8 +226,8 @@ Laplace-Transformierte der zweiten Gleichung: :: sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") - sage: lde2 = de2.laplace("t","s"); lde2 - ...-...%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s + sage: lde2 = de2.laplace("t","s"); lde2.sage() + s^2*laplace(y(t), t, s) - s*y(0) - 2*laplace(x(t), t, s) + 2*laplace(y(t), t, s) - D[0](y)(0) Dies besagt diff --git a/src/doc/en/tutorial/interfaces.rst b/src/doc/en/tutorial/interfaces.rst index 9728a5e2a5c..19c28f636d4 100644 --- a/src/doc/en/tutorial/interfaces.rst +++ b/src/doc/en/tutorial/interfaces.rst @@ -267,8 +267,8 @@ whose :math:`i,j` entry is :math:`i/j`, for matrix([1,1/2,1/3,1/4],[0,0,0,0],[0,0,0,0],[0,0,0,0]) sage: A.eigenvalues() [[0,4],[3,1]] - sage: A.eigenvectors() - [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-...4/3...]],[[1,2,3,4]]]] + sage: A.eigenvectors().sage() + [[[0, 4], [3, 1]], [[[1, 0, 0, -4], [0, 1, 0, -2], [0, 0, 1, -4/3]], [[1, 2, 3, 4]]]] Here's another example: @@ -320,8 +320,8 @@ The next plot is the famous Klein bottle (do not type the ``....:``):: sage: maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") 5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0 - sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)") - -...5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)... + sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() + -5*(cos(1/2*x)*cos(y) + sin(1/2*x)*sin(2*y) + 3.0)*sin(x) sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") 5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y)) sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested diff --git a/src/doc/en/tutorial/tour_algebra.rst b/src/doc/en/tutorial/tour_algebra.rst index e84c61bc54d..3a9830f16d5 100644 --- a/src/doc/en/tutorial/tour_algebra.rst +++ b/src/doc/en/tutorial/tour_algebra.rst @@ -217,8 +217,8 @@ the notation :math:`x=x_{1}`, :math:`y=x_{2}`): :: sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") - sage: lde1 = de1.laplace("t","s"); lde1 - 2*(...-...%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) + sage: lde1 = de1.laplace("t","s"); lde1.sage() + 2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0) This is hard to read, but it says that @@ -232,8 +232,8 @@ Laplace transform of the second equation: :: sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") - sage: lde2 = de2.laplace("t","s"); lde2 - ...-...%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s + sage: lde2 = de2.laplace("t","s"); lde2.sage() + s^2*laplace(y(t), t, s) - s*y(0) - 2*laplace(x(t), t, s) + 2*laplace(y(t), t, s) - D[0](y)(0) This says diff --git a/src/doc/es/tutorial/tour_algebra.rst b/src/doc/es/tutorial/tour_algebra.rst index 0edce6055df..c57e6775a49 100644 --- a/src/doc/es/tutorial/tour_algebra.rst +++ b/src/doc/es/tutorial/tour_algebra.rst @@ -197,8 +197,8 @@ la notación :math:`x=x_{1}`, :math:`y=x_{2}`): :: sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") - sage: lde1 = de1.laplace("t","s"); lde1 - 2*(...-...%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) + sage: lde1 = de1.laplace("t","s"); lde1.sage() + 2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0) El resultado puede ser difícil de leer, pero significa que @@ -212,8 +212,8 @@ Toma la transformada de Laplace de la segunda ecuación: :: sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") - sage: lde2 = de2.laplace("t","s"); lde2 - ...-...%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s + sage: lde2 = de2.laplace("t","s"); lde2.sage() + s^2*laplace(y(t), t, s) - s*y(0) - 2*laplace(x(t), t, s) + 2*laplace(y(t), t, s) - D[0](y)(0) Esto dice diff --git a/src/doc/fr/tutorial/interfaces.rst b/src/doc/fr/tutorial/interfaces.rst index 569d7bba864..807ab6d8ee2 100644 --- a/src/doc/fr/tutorial/interfaces.rst +++ b/src/doc/fr/tutorial/interfaces.rst @@ -273,8 +273,8 @@ pour :math:`i,j=1,\ldots,4`. matrix([1,1/2,1/3,1/4],[0,0,0,0],[0,0,0,0],[0,0,0,0]) sage: A.eigenvalues() [[0,4],[3,1]] - sage: A.eigenvectors() - [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-...4/3...]],[[1,2,3,4]]]] + sage: A.eigenvectors().sage() + [[[0, 4], [3, 1]], [[[1, 0, 0, -4], [0, 1, 0, -2], [0, 0, 1, -4/3]], [[1, 2, 3, 4]]]] Un deuxième exemple : @@ -336,8 +336,8 @@ Et la fameuse bouteille de Klein (n'entrez pas les ``....:``): sage: maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") 5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0 - sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)") - -...5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)... + sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() + -5*(cos(1/2*x)*cos(y) + sin(1/2*x)*sin(2*y) + 3.0)*sin(x) sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") 5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y)) sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested diff --git a/src/doc/fr/tutorial/tour_algebra.rst b/src/doc/fr/tutorial/tour_algebra.rst index c67fd622630..be534cd556b 100644 --- a/src/doc/fr/tutorial/tour_algebra.rst +++ b/src/doc/fr/tutorial/tour_algebra.rst @@ -182,8 +182,8 @@ Solution : Considérons la transformée de Laplace de la première équation :: sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") - sage: lde1 = de1.laplace("t","s"); lde1 - 2*(...-...%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) + sage: lde1 = de1.laplace("t","s"); lde1.sage() + 2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0) La réponse n'est pas très lisible, mais elle signifie que @@ -197,8 +197,8 @@ la seconde équation : :: sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") - sage: lde2 = de2.laplace("t","s"); lde2 - ...-...%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s + sage: lde2 = de2.laplace("t","s"); lde2.sage() + s^2*laplace(y(t), t, s) - s*y(0) - 2*laplace(x(t), t, s) + 2*laplace(y(t), t, s) - D[0](y)(0) Ceci signifie diff --git a/src/doc/it/tutorial/tour_algebra.rst b/src/doc/it/tutorial/tour_algebra.rst index af2292ffd68..5a153e6fb75 100644 --- a/src/doc/it/tutorial/tour_algebra.rst +++ b/src/doc/it/tutorial/tour_algebra.rst @@ -183,8 +183,8 @@ la notazione :math:`x=x_{1}`, :math:`y=x_{2}`: :: sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") - sage: lde1 = de1.laplace("t","s"); lde1 - 2*(...-...%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) + sage: lde1 = de1.laplace("t","s"); lde1.sage() + 2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0) Questo è di difficile lettura, ma dice che @@ -198,8 +198,8 @@ trasformata di Laplace della seconda equazione: :: sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") - sage: lde2 = de2.laplace("t","s"); lde2 - ...-...%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s + sage: lde2 = de2.laplace("t","s"); lde2.sage() + s^2*laplace(y(t), t, s) - s*y(0) - 2*laplace(x(t), t, s) + 2*laplace(y(t), t, s) - D[0](y)(0) che significa diff --git a/src/doc/ja/tutorial/interfaces.rst b/src/doc/ja/tutorial/interfaces.rst index 19b168747b2..b48087c7bca 100644 --- a/src/doc/ja/tutorial/interfaces.rst +++ b/src/doc/ja/tutorial/interfaces.rst @@ -239,8 +239,8 @@ Sage/Maximaインターフェイスの使い方を例示するため,ここで matrix([1,1/2,1/3,1/4],[0,0,0,0],[0,0,0,0],[0,0,0,0]) sage: A.eigenvalues() [[0,4],[3,1]] - sage: A.eigenvectors() - [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-...4/3...]],[[1,2,3,4]]]] + sage: A.eigenvectors().sage() + [[[0, 4], [3, 1]], [[[1, 0, 0, -4], [0, 1, 0, -2], [0, 0, 1, -4/3]], [[1, 2, 3, 4]]]] 使用例をもう一つ示す: @@ -301,8 +301,8 @@ Sage/Maximaインターフェイスの使い方を例示するため,ここで sage: maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") 5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0 - sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)") - -...5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)... + sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() + -5*(cos(1/2*x)*cos(y) + sin(1/2*x)*sin(2*y) + 3.0)*sin(x) sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") 5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y)) sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested diff --git a/src/doc/ja/tutorial/tour_algebra.rst b/src/doc/ja/tutorial/tour_algebra.rst index 962d8e93d57..64edd47b930 100644 --- a/src/doc/ja/tutorial/tour_algebra.rst +++ b/src/doc/ja/tutorial/tour_algebra.rst @@ -213,8 +213,8 @@ Sageを使って常微分方程式を研究することもできる. :math:`x' :: sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") - sage: lde1 = de1.laplace("t","s"); lde1 - 2*(...-...%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) + sage: lde1 = de1.laplace("t","s"); lde1.sage() + 2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0) この出力は読みにくいけれども,意味しているのは @@ -227,8 +227,8 @@ Sageを使って常微分方程式を研究することもできる. :math:`x' :: sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") - sage: lde2 = de2.laplace("t","s"); lde2 - ...-...%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s + sage: lde2 = de2.laplace("t","s"); lde2.sage() + s^2*laplace(y(t), t, s) - s*y(0) - 2*laplace(x(t), t, s) + 2*laplace(y(t), t, s) - D[0](y)(0) 意味するところは diff --git a/src/doc/pt/tutorial/interfaces.rst b/src/doc/pt/tutorial/interfaces.rst index 778ff99df99..b993b304a35 100644 --- a/src/doc/pt/tutorial/interfaces.rst +++ b/src/doc/pt/tutorial/interfaces.rst @@ -269,8 +269,8 @@ entrada :math:`i,j` é :math:`i/j`, para :math:`i,j=1,\ldots,4`. matrix([1,1/2,1/3,1/4],[0,0,0,0],[0,0,0,0],[0,0,0,0]) sage: A.eigenvalues() [[0,4],[3,1]] - sage: A.eigenvectors() - [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-...4/3...]],[[1,2,3,4]]]] + sage: A.eigenvectors().sage() + [[[0, 4], [3, 1]], [[[1, 0, 0, -4], [0, 1, 0, -2], [0, 0, 1, -4/3]], [[1, 2, 3, 4]]]] Aqui vai outro exemplo: @@ -333,8 +333,8 @@ E agora a famosa garrafa de Klein: sage: maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)" ....: "- 10.0") 5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0 - sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)") - -...5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)... + sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() + -5*(cos(1/2*x)*cos(y) + sin(1/2*x)*sin(2*y) + 3.0)*sin(x) sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") 5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y)) sage: maxima.plot3d("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested diff --git a/src/doc/pt/tutorial/tour_algebra.rst b/src/doc/pt/tutorial/tour_algebra.rst index 467ab1b3baa..b3cbd06d8d9 100644 --- a/src/doc/pt/tutorial/tour_algebra.rst +++ b/src/doc/pt/tutorial/tour_algebra.rst @@ -205,8 +205,8 @@ equação (usando a notação :math:`x=x_{1}`, :math:`y=x_{2}`): :: sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") - sage: lde1 = de1.laplace("t","s"); lde1 - 2*(...-...%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) + sage: lde1 = de1.laplace("t","s"); lde1.sage() + 2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0) O resultado é um pouco difícil de ler, mas diz que @@ -220,8 +220,8 @@ calcule a transformada de Laplace da segunda equação: :: sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") - sage: lde2 = de2.laplace("t","s"); lde2 - ...-...%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s + sage: lde2 = de2.laplace("t","s"); lde2.sage() + s^2*laplace(y(t), t, s) - s*y(0) - 2*laplace(x(t), t, s) + 2*laplace(y(t), t, s) - D[0](y)(0) O resultado significa que diff --git a/src/doc/ru/tutorial/interfaces.rst b/src/doc/ru/tutorial/interfaces.rst index 9ec728c282a..7d7886b26cf 100644 --- a/src/doc/ru/tutorial/interfaces.rst +++ b/src/doc/ru/tutorial/interfaces.rst @@ -264,8 +264,8 @@ gnuplot, имеет методы решения и манипуляции мат matrix([1,1/2,1/3,1/4],[0,0,0,0],[0,0,0,0],[0,0,0,0]) sage: A.eigenvalues() [[0,4],[3,1]] - sage: A.eigenvectors() - [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-...4/3...]],[[1,2,3,4]]]] + sage: A.eigenvectors().sage() + [[[0, 4], [3, 1]], [[[1, 0, 0, -4], [0, 1, 0, -2], [0, 0, 1, -4/3]], [[1, 2, 3, 4]]]] Вот другой пример: @@ -325,8 +325,8 @@ gnuplot, имеет методы решения и манипуляции мат sage: maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") 5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0 - sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)") - -...5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)... + sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() + -5*(cos(1/2*x)*cos(y) + sin(1/2*x)*sin(2*y) + 3.0)*sin(x) sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") 5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y)) sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested diff --git a/src/doc/ru/tutorial/tour_algebra.rst b/src/doc/ru/tutorial/tour_algebra.rst index a32a1212303..107571f6018 100644 --- a/src/doc/ru/tutorial/tour_algebra.rst +++ b/src/doc/ru/tutorial/tour_algebra.rst @@ -199,8 +199,8 @@ Sage может использоваться для решения диффер :: sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") - sage: lde1 = de1.laplace("t","s"); lde1 - 2*(...-...%at('diff(x(t),t,1),t = 0))+s^2*'laplace(x(t),t,s)-x(0)*s) -2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s) + sage: lde1 = de1.laplace("t","s"); lde1.sage() + 2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0) Данный результат тяжело читаем, однако должен быть понят как @@ -211,8 +211,8 @@ Sage может использоваться для решения диффер :: sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") - sage: lde2 = de2.laplace("t","s"); lde2 - ...-...%at('diff(y(t),t,1),t = 0))+s^2*'laplace(y(t),t,s) +2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s) -y(0)*s + sage: lde2 = de2.laplace("t","s"); lde2.sage() + s^2*laplace(y(t), t, s) - s*y(0) - 2*laplace(x(t), t, s) + 2*laplace(y(t), t, s) - D[0](y)(0) Результат: diff --git a/src/sage/functions/bessel.py b/src/sage/functions/bessel.py index e3d4f182d79..c53935d60fe 100644 --- a/src/sage/functions/bessel.py +++ b/src/sage/functions/bessel.py @@ -294,8 +294,8 @@ class Function_Bessel_J(BuiltinFunction): sage: f.integrate(x) 1/24*x^3*hypergeometric((3/2,), (5/2, 3), -1/4*x^2) sage: m = maxima(bessel_J(2, x)) - sage: m.integrate(x) - (hypergeometric([3/2],[5/2,3],-..._SAGE_VAR_x^2/4)...*_SAGE_VAR_x^3)/24 + sage: m.integrate(x).sage() + 1/24*x^3*hypergeometric((3/2,), (5/2, 3), -1/4*x^2) Visualization (set plot_points to a higher value to get more detail):: @@ -1121,8 +1121,8 @@ def Bessel(*args, **kwds): sage: f = maxima(Bessel(typ='K')(x,y)) sage: f.derivative('_SAGE_VAR_x') (%pi*csc(%pi*_SAGE_VAR_x) *('diff(bessel_i(-_SAGE_VAR_x,_SAGE_VAR_y),_SAGE_VAR_x,1) -'diff(bessel_i(_SAGE_VAR_x,_SAGE_VAR_y),_SAGE_VAR_x,1))) /2 -%pi*bessel_k(_SAGE_VAR_x,_SAGE_VAR_y)*cot(%pi*_SAGE_VAR_x) - sage: f.derivative('_SAGE_VAR_y') - -(...bessel_k(_SAGE_VAR_x+1,_SAGE_VAR_y)+bessel_k(_SAGE_VAR_x-1, _SAGE_VAR_y)).../2... + sage: f.derivative('_SAGE_VAR_y').sage() + -1/2*bessel_K(x + 1, y) - 1/2*bessel_K(x - 1, y) Compute the particular solution to Bessel's Differential Equation that satisfies `y(1) = 1` and `y'(1) = 1`, then verify the initial conditions From 893515e54836eec5a5763133deb4c99f211b7f76 Mon Sep 17 00:00:00 2001 From: Antonio Rojas <arojas@archlinux.org> Date: Sat, 3 Jun 2023 00:51:18 +0200 Subject: [PATCH 041/228] Improve one more test output --- src/doc/en/constructions/linear_algebra.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/en/constructions/linear_algebra.rst b/src/doc/en/constructions/linear_algebra.rst index f698342b02b..4e76c65ad0a 100644 --- a/src/doc/en/constructions/linear_algebra.rst +++ b/src/doc/en/constructions/linear_algebra.rst @@ -277,8 +277,8 @@ Another approach is to use the interface with Maxima: sage: A = maxima("matrix ([1, -4], [1, -1])") sage: eig = A.eigenvectors() - sage: eig - [[[-...sqrt(3)*%i...,sqrt(3)*%i],[1,1]], [[[1,(sqrt(3)*%i+1)/4]],[[1,-...(sqrt(3)*%i-1)/4...]]]] + sage: eig.sage() + [[[-I*sqrt(3), I*sqrt(3)], [1, 1]], [[[1, 1/4*I*sqrt(3) + 1/4]], [[1, -1/4*I*sqrt(3) + 1/4]]]] This tells us that :math:`\vec{v}_1 = [1,(\sqrt{3}i + 1)/4]` is an eigenvector of :math:`\lambda_1 = - \sqrt{3}i` (which occurs From 854f686b997256a30694f9278209272328f08c9a Mon Sep 17 00:00:00 2001 From: Antonio Rojas <arojas@archlinux.org> Date: Sat, 3 Jun 2023 00:54:22 +0200 Subject: [PATCH 042/228] Disable test that gives wrong answer with maxima < 5.47 --- src/sage/functions/special.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sage/functions/special.py b/src/sage/functions/special.py index 3978392dba0..d72e780836a 100644 --- a/src/sage/functions/special.py +++ b/src/sage/functions/special.py @@ -455,9 +455,8 @@ class EllipticE(BuiltinFunction): sage: z = var("z") sage: elliptic_e(z, 1) elliptic_e(z, 1) - sage: # this is still wrong: must be abs(sin(z)) + 2*round(z/pi) - sage: elliptic_e(z, 1).simplify() - 2*round(z/pi) ... sin(...z) + sage: elliptic_e(z, 1).simplify() # not tested - gives wrong answer with maxima < 5.47 + 2*round(z/pi) - sin(pi*round(z/pi) - z) sage: elliptic_e(z, 0) z sage: elliptic_e(0.5, 0.1) # abs tol 2e-15 From 479c0d0823a0b4a868cd0a14b5fc200c04db43b8 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian <aram.dermenjian.math@gmail.com> Date: Sat, 3 Jun 2023 13:58:39 +0100 Subject: [PATCH 043/228] Make Russian tableaux allow for entries --- src/sage/combinat/output.py | 159 +++++++++++++++++++----------------- 1 file changed, 84 insertions(+), 75 deletions(-) diff --git a/src/sage/combinat/output.py b/src/sage/combinat/output.py index e661d931318..3619ed5b5fc 100644 --- a/src/sage/combinat/output.py +++ b/src/sage/combinat/output.py @@ -618,61 +618,60 @@ def ascii_art_table_russian(data, use_unicode=False, compact=False): EXAMPLES:: sage: from sage.combinat.output import ascii_art_table_russian - sage: data = [[None, None, 1], [2, 2, 2], [3,4], [None, 10], [6]] + sage: data = [[None, None, 1], [2, 2], [3,4,5], [None, None, 10], [], [6]] sage: print(ascii_art_table_russian(data)) - / \ / \ - / \ / \ - \ 6 X 10 \ - \ / \ / \ / \ - \ / \ / \ / \ - \ X 4 X 2 \ - \ / \ / \ / \ - \ / \ / \ / \ - \ 3 X 2 X 1 / - \ / \ / \ / - \ / \ / \ / - \ 2 X / - \ / \ / - \ / \ / - \ / + / \ / \ + / \ / \ + \ 6 / \ 10 \ + \ / \ / \ + \ / \ / \ + X 5 / + / \ / + / \ / + / 4 X + / \ / \ / \ + / \ / \ / \ + \ 3 X 2 X 1 / + \ / \ / \ / + \ / \ / \ / + \ 2 / \ / \ / - sage: print(ascii_art_table_russian(data, use_unicode=True)) - ╱ ╲ ╱ ╲ - ╱ ╲ ╱ ╲ - ╲ 6 ╳ 10 ╲ - ╲ ╱ ╲ ╱ ╲ ╱ ╲ - ╲ ╱ ╲ ╱ ╲ ╱ ╲ - ╲ ╳ 4 ╳ 2 ╲ - ╲ ╱ ╲ ╱ ╲ ╱ ╲ - ╲ ╱ ╲ ╱ ╲ ╱ ╲ - ╲ 3 ╳ 2 ╳ 1 ╱ - ╲ ╱ ╲ ╱ ╲ ╱ - ╲ ╱ ╲ ╱ ╲ ╱ - ╲ 2 ╳ ╱ - ╲ ╱ ╲ ╱ - ╲ ╱ ╲ ╱ - ╲ ╱ + ╱ ╲ ╱ ╲ + ╱ ╲ ╱ ╲ + ╲ 6 ╱ ╲ 10 ╲ + ╲ ╱ ╲ ╱ ╲ + ╲ ╱ ╲ ╱ ╲ + ╳ 5 ╱ + ╱ ╲ ╱ + ╱ ╲ ╱ + ╱ 4 ╳ + ╱ ╲ ╱ ╲ ╱ ╲ + ╱ ╲ ╱ ╲ ╱ ╲ + ╲ 3 ╳ 2 ╳ 1 ╱ + ╲ ╱ ╲ ╱ ╲ ╱ + ╲ ╱ ╲ ╱ ╲ ╱ + ╲ 2 ╱ ╲ ╱ ╲ ╱ sage: data = [[1, None, 2], [None, 2]] sage: print(ascii_art_table_russian(data)) - / \ / \ - / 2 X 2 / - / \ / \ / - \ X / + / \ / \ + \ 2 X 2 / \ / \ / - \ 1 / - \ / + X + / \ + \ 1 / + \ / sage: print(ascii_art_table_russian(data, use_unicode=True)) - ╱ ╲ ╱ ╲ - ╱ 2 ╳ 2 ╱ - ╱ ╲ ╱ ╲ ╱ - ╲ ╳ ╱ + ╱ ╲ ╱ ╲ + ╲ 2 ╳ 2 ╱ ╲ ╱ ╲ ╱ - ╲ 1 ╱ - ╲ ╱ + ╳ + ╱ ╲ + ╲ 1 ╱ + ╲ ╱ """ if use_unicode: import unicodedata @@ -720,46 +719,56 @@ def get_len(e): for i in range(row_height): if k == max_height and i == 0: continue - st = ' ' * ((max_height - k) * (row_height)) + st = ' ' * ((max_height - k) * row_height) for j in range(k + 1): - st += ' ' * i - if len(str_tab[k-j:]) and (j == 0 or len(str_tab[k-j][j-1:])): - if i == 0: - if j > 0 and len(str_tab[k-j+1:]) and len(str_tab[k-j+1][j-1:]) and len(str_tab[k-j:]) and len(str_tab[k-j][j:]): - st += x - elif len(str_tab[k-j+1:]) and (j == 0 or len(str_tab[k-j+1][j-1:])): - st += uldr - elif len(str_tab[k-j:]) and len(str_tab[k-j][j:]): - if j == 0: - st += uldr - else: - st += urdl - # elif len(str_tab[k-j:]) and j > 0 and len(str_tab[k-j][j-1:]): - # st += '^' - else: - st += ' ' - else: + N_box = box_exists(str_tab, k-j+1, j) + S_box = box_exists(str_tab, k-j, j-1) + SE_box = box_exists(str_tab, k-j-1, j) + E_box = box_exists(str_tab, k-j, j) + W_box = box_exists(str_tab, k-j+1, j-1) + if i == 0: + if (N_box and S_box) or (W_box and E_box): + st += x + elif (E_box and S_box) or (W_box and N_box): + st += urdl + elif (E_box and N_box) or (W_box and S_box): st += uldr - else: - st += ' ' - - if i == 0 and len(str_tab[k-j:]) and len(str_tab[k-j][j:]) and str_tab[k-j][j] is not None: - st_num = str_tab[k-j][j] - ln_left = int((len(st_num) - (len(st_num) % 2))/2) - st += st_num.rjust(row_height - 1 - ln_left + len(st_num), ' ').ljust(diag_length, ' ') - else: - st += ' ' * (diag_length - 2 * i) - if i > 0: - if (j == k and k < max_height and len(str_tab[0][j:])) or (len(str_tab[k-j-1:]) and len(str_tab[k-j-1][j:])): + elif E_box: + st += uldr + elif W_box: st += urdl else: st += ' ' + if E_box: + st_num = str_tab[k-j][j] + ln_left = int((len(st_num) - (len(st_num) % 2))/2) + st += st_num.rjust(row_height - 1 - ln_left + len(st_num), ' ').ljust(diag_length, ' ') + else: + st += ' ' * diag_length + if j == k and E_box: + st += urdl + else: + lstr = ' ' + rstr = ' ' + if E_box or S_box: + lstr = uldr + if E_box or SE_box: + rstr = urdl + st += ' ' * i + st += lstr + st += ' ' * (2 * (row_height - i) - 1) + st += rstr st += ' ' * (i-1) - if i == 0 and j == k and k < max_height and len(str_tab[0][j:]): - st += urdl str_list.append(st) import re mm = min([len(re.search('^ +', l)[0]) for l in str_list]) - 1 str_list = [l[mm:].rstrip() for l in str_list] + while str_list[-1] == '': + str_list.pop() return "\n".join(str_list) + +def box_exists(tab, i, j): + if j < 0 or i < 0: + return False + return (len(tab[i:]) > 0 and len(tab[i][j:]) > 0 and tab[i][j] is not None) From 2a351f7f2d6e544f7d23fe5f93411de03a6c8451 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian <aram.dermenjian.math@gmail.com> Date: Sat, 3 Jun 2023 14:04:52 +0100 Subject: [PATCH 044/228] Lint fix and comment --- src/sage/combinat/output.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/output.py b/src/sage/combinat/output.py index 3619ed5b5fc..5a26a728b13 100644 --- a/src/sage/combinat/output.py +++ b/src/sage/combinat/output.py @@ -678,18 +678,15 @@ def ascii_art_table_russian(data, use_unicode=False, compact=False): urdl = unicodedata.lookup('BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT') uldr = unicodedata.lookup('BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT') x = unicodedata.lookup('BOX DRAWINGS LIGHT DIAGONAL CROSS') - from sage.typeset.unicode_art import unicode_art as art else: urdl = '/' uldr = '\\' x = 'X' - from sage.typeset.ascii_art import ascii_art as art if not data: # return urdl + uldr + '\n' + uldr + urdl return '' - if use_unicode: # Special handling of overline not adding to printed length def get_len(e): @@ -768,7 +765,11 @@ def get_len(e): str_list.pop() return "\n".join(str_list) + def box_exists(tab, i, j): + """ + For Russian tableaux, it checks if a certain box exists or not. + """ if j < 0 or i < 0: return False return (len(tab[i:]) > 0 and len(tab[i][j:]) > 0 and tab[i][j] is not None) From 0068ba64c53f5c985a3447f289559fdf791623cc Mon Sep 17 00:00:00 2001 From: Aram Dermenjian <aram.dermenjian.o+github@gmail.com> Date: Sun, 4 Jun 2023 08:49:10 +0100 Subject: [PATCH 045/228] Apply suggestions from code review Co-authored-by: Travis Scrimshaw <clfrngrown@aol.com> --- src/sage/combinat/output.py | 8 ++++---- src/sage/combinat/tableau.py | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/combinat/output.py b/src/sage/combinat/output.py index 5a26a728b13..d67b812f3a0 100644 --- a/src/sage/combinat/output.py +++ b/src/sage/combinat/output.py @@ -709,8 +709,8 @@ def get_len(e): else: diag_length = max_str + 2 # space on both sides - row_height = int((diag_length + 1)/2) - max_height = max([a + len(str_tab[a]) for a in range(len(str_tab))]) + row_height = int((diag_length + 1) // 2) + max_height = max(a + len(val) for a, val in enumerate(str_tab)) str_list = [] for k in range(max_height, -1, -1): for i in range(row_height): @@ -759,7 +759,7 @@ def get_len(e): str_list.append(st) import re - mm = min([len(re.search('^ +', l)[0]) for l in str_list]) - 1 + mm = min(len(re.search('^ +', l)[0]) for l in str_list) - 1 str_list = [l[mm:].rstrip() for l in str_list] while str_list[-1] == '': str_list.pop() @@ -772,4 +772,4 @@ def box_exists(tab, i, j): """ if j < 0 or i < 0: return False - return (len(tab[i:]) > 0 and len(tab[i][j:]) > 0 and tab[i][j] is not None) + return len(tab) >= i and len(tab[i]) >=j and tab[i][j] is not None diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 3e22f00563e..75d38e0b91d 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -420,7 +420,7 @@ def _repr_diagram(self): if self.parent().options('convention') == "Russian": col_width = max(col_widths) + 1 - max_height = max([a + len(str_tab[a]) for a in range(len(str_tab))]) + max_height = max(a + len(val) for a, val in enumerate(str_tab)) str_list = [] for i in range(max_height): st = ' ' * ((max_height - i - 1) * col_width) @@ -432,7 +432,7 @@ def _repr_diagram(self): st += ' ' * (col_width * 2 - 1) str_list.append(st) import re - mm = min([len(re.search('^ +', sline)[0]) for sline in str_list]) - 1 + mm = min(len(re.search('^ +', sline)[0]) for sline in str_list) - 1 str_list = [sline[mm:] for sline in str_list] str_list.reverse() return '\n'.join(str_list) @@ -987,7 +987,7 @@ def plot(self, descents=False): sphinx_plot(t.plot()) Tableaux.options.convention="english" - If Russian notation is set, we tilt the French by 45 degrees: + If Russian notation is set, we tilt the French notation by 45 degrees: .. PLOT:: :width: 200 px From 415f6c826eb4831a3b0b018ebc840a57795c5550 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian <aram.dermenjian.math@gmail.com> Date: Sun, 4 Jun 2023 09:01:08 +0100 Subject: [PATCH 046/228] Add doct tests and change function for box_exists --- src/sage/combinat/output.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/sage/combinat/output.py b/src/sage/combinat/output.py index d67b812f3a0..55b74fa27c0 100644 --- a/src/sage/combinat/output.py +++ b/src/sage/combinat/output.py @@ -769,7 +769,37 @@ def get_len(e): def box_exists(tab, i, j): """ For Russian tableaux, it checks if a certain box exists or not. + + Returns `True` if `tab[i][j]` exists and is not `None`. In particular this + allows for `tab[i][j]` to be `''` or `0`. + + INPUT: + + - ``tab`` -- An `array` of `array`s. + - ``i`` -- First coordinate + - ``j`` -- Second coordinate + + TESTS:: + + sage: from sage.combinat.output import box_exists + sage: tab = [[1,None,'', 0],[None]] + sage: box_exists(tab, 0, 0) + True + sage: box_exists(tab, 0, 1) + False + sage: box_exists(tab, 0, 2) + True + sage: box_exists(tab, 0, 3) + True + sage: box_exists(tab, 0, 4) + False + sage: box_exists(tab, 1, 0) + False + sage: box_exists(tab, 1, 1) + False + sage: box_exists(tab, 0, -1) + False """ if j < 0 or i < 0: return False - return len(tab) >= i and len(tab[i]) >=j and tab[i][j] is not None + return len(tab) > i and len(tab[i]) > j and tab[i][j] is not None From 5f56908654a18ff80bd3c838c83855b5c5743668 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian <aram.dermenjian.o+github@gmail.com> Date: Mon, 5 Jun 2023 07:10:42 +0100 Subject: [PATCH 047/228] Update src/sage/combinat/output.py Co-authored-by: Travis Scrimshaw <clfrngrown@aol.com> --- src/sage/combinat/output.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/sage/combinat/output.py b/src/sage/combinat/output.py index 55b74fa27c0..7ad0cd018ae 100644 --- a/src/sage/combinat/output.py +++ b/src/sage/combinat/output.py @@ -767,17 +767,15 @@ def get_len(e): def box_exists(tab, i, j): - """ - For Russian tableaux, it checks if a certain box exists or not. - - Returns `True` if `tab[i][j]` exists and is not `None`. In particular this - allows for `tab[i][j]` to be `''` or `0`. + r """ + Return ``True`` if ``tab[i][j]`` exists and is not ``None``; in particular this + allows for `tab[i][j]` to be ``''`` or ``0``. INPUT: - - ``tab`` -- An `array` of `array`s. - - ``i`` -- First coordinate - - ``j`` -- Second coordinate + - ``tab`` -- a list of lists + - ``i`` -- first coordinate + - ``j`` -- second coordinate TESTS:: From 2fda6a490f5993fa8adbf3e4f86959885112a3cf Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Mon, 24 Apr 2023 22:42:29 -0700 Subject: [PATCH 048/228] sage.combinat: Add # optional --- src/sage/combinat/backtrack.py | 2 +- src/sage/combinat/combinat.py | 258 +++++++++--------- src/sage/combinat/combination.py | 10 +- src/sage/combinat/combinatorial_map.py | 4 +- src/sage/combinat/composition.py | 73 +++--- src/sage/combinat/permutation.py | 345 +++++++++++++------------ 6 files changed, 358 insertions(+), 334 deletions(-) diff --git a/src/sage/combinat/backtrack.py b/src/sage/combinat/backtrack.py index 565b3efa973..777e511531f 100644 --- a/src/sage/combinat/backtrack.py +++ b/src/sage/combinat/backtrack.py @@ -63,7 +63,7 @@ def __iter__(self): sage: from sage.combinat.permutation import PatternAvoider sage: p = PatternAvoider(Permutations(4), [[1,3,2]]) - sage: len(list(p)) + sage: len(list(p)) # optional - sage.combinat 14 """ # Initialize the stack of generators with the initial data. diff --git a/src/sage/combinat/combinat.py b/src/sage/combinat/combinat.py index 195ff344e50..c4128a176b8 100644 --- a/src/sage/combinat/combinat.py +++ b/src/sage/combinat/combinat.py @@ -319,17 +319,17 @@ def bell_number(n, algorithm='flint', **options) -> Integer: EXAMPLES:: - sage: bell_number(10) + sage: bell_number(10) # optional - sage.libs.flint 115975 - sage: bell_number(2) + sage: bell_number(2) # optional - sage.libs.flint 2 - sage: bell_number(-10) + sage: bell_number(-10) # optional - sage.libs.flint Traceback (most recent call last): ... ArithmeticError: Bell numbers not defined for negative indices - sage: bell_number(1) + sage: bell_number(1) # optional - sage.libs.flint 1 - sage: bell_number(1/3) + sage: bell_number(1/3) # optional - sage.libs.flint Traceback (most recent call last): ... TypeError: no conversion of this rational to integer @@ -339,17 +339,17 @@ def bell_number(n, algorithm='flint', **options) -> Integer: first time, we deem the precision too low, we use our guess to (temporarily) raise mpmath's precision and the Bell number is recomputed. :: - sage: k = bell_number(30, 'mpmath'); k + sage: k = bell_number(30, 'mpmath'); k # optional - mpmath 846749014511809332450147 - sage: k == bell_number(30) + sage: k == bell_number(30) # optional - mpmath sage.libs.flint True If you knows what precision is necessary before computing the Bell number, you can use the ``prec`` option:: - sage: k2 = bell_number(30, 'mpmath', prec=30); k2 + sage: k2 = bell_number(30, 'mpmath', prec=30); k2 # optional - mpmath 846749014511809332450147 - sage: k == k2 + sage: k == k2 # optional - mpmath True .. WARNING:: @@ -357,18 +357,19 @@ def bell_number(n, algorithm='flint', **options) -> Integer: Running mpmath with the precision set too low can result in incorrect results:: - sage: k = bell_number(30, 'mpmath', prec=15); k + sage: k = bell_number(30, 'mpmath', prec=15); k # optional - mpmath 846749014511809388871680 - sage: k == bell_number(30) + sage: k == bell_number(30) # optional - mpmath False TESTS:: sage: all(bell_number(n) == bell_number(n,'dobinski') for n in range(100)) True - sage: all(bell_number(n) == bell_number(n,'gap') for n in range(100)) + sage: all(bell_number(n) == bell_number(n,'gap') for n in range(100)) # optional - sage.libs.gap True - sage: all(bell_number(n) == bell_number(n,'mpmath', prec=500) for n in range(200, 220)) + sage: all(bell_number(n) == bell_number(n,'mpmath', prec=500) # optional - mpmath sage.libs.flint + ....: for n in range(200, 220)) True AUTHORS: @@ -547,12 +548,12 @@ def euler_number(n, algorithm='flint') -> Integer: EXAMPLES:: - sage: [euler_number(i) for i in range(10)] + sage: [euler_number(i) for i in range(10)] # optional - sage.libs.flint [1, 0, -1, 0, 5, 0, -61, 0, 1385, 0] sage: x = PowerSeriesRing(QQ, 'x').gen().O(10) sage: 2/(exp(x)+exp(-x)) 1 - 1/2*x^2 + 5/24*x^4 - 61/720*x^6 + 277/8064*x^8 + O(x^10) - sage: [euler_number(i)/factorial(i) for i in range(11)] + sage: [euler_number(i)/factorial(i) for i in range(11)] # optional - sage.libs.flint [1, 0, -1/2, 0, 5/24, 0, -61/720, 0, 277/8064, 0, -50521/3628800] sage: euler_number(-1) Traceback (most recent call last): @@ -561,7 +562,7 @@ def euler_number(n, algorithm='flint') -> Integer: TESTS:: - sage: euler_number(6, 'maxima') + sage: euler_number(6, 'maxima') # optional - sage.symbolic -61 REFERENCES: @@ -705,21 +706,21 @@ def fibonacci(n, algorithm="pari") -> Integer: EXAMPLES:: - sage: fibonacci(10) + sage: fibonacci(10) # optional - sage.libs.pari 55 - sage: fibonacci(10, algorithm='gap') + sage: fibonacci(10, algorithm='gap') # optional - sage.libs.gap 55 :: - sage: fibonacci(-100) + sage: fibonacci(-100) # optional - sage.libs.pari -354224848179261915075 - sage: fibonacci(100) + sage: fibonacci(100) # optional - sage.libs.pari 354224848179261915075 :: - sage: fibonacci(0) + sage: fibonacci(0) # optional - sage.libs.pari 0 sage: fibonacci(1/2) Traceback (most recent call last): @@ -758,17 +759,17 @@ def lucas_number1(n, P, Q): EXAMPLES:: - sage: lucas_number1(5,1,-1) + sage: lucas_number1(5,1,-1) # optional - sage.libs.gap 5 - sage: lucas_number1(6,1,-1) + sage: lucas_number1(6,1,-1) # optional - sage.libs.gap 8 - sage: lucas_number1(7,1,-1) + sage: lucas_number1(7,1,-1) # optional - sage.libs.gap 13 - sage: lucas_number1(7,1,-2) + sage: lucas_number1(7,1,-2) # optional - sage.libs.gap 43 - sage: lucas_number1(5,2,3/5) + sage: lucas_number1(5,2,3/5) # optional - sage.libs.gap 229/25 - sage: lucas_number1(5,2,1.5) + sage: lucas_number1(5,2,1.5) # optional - sage.libs.gap 1/4 There was a conjecture that the sequence `L_n` defined by @@ -776,8 +777,9 @@ def lucas_number1(n, P, Q): `L_2=3`, has the property that `n` prime implies that `L_n` is prime. :: - sage: lucas = lambda n : Integer((5/2)*lucas_number1(n,1,-1)+(1/2)*lucas_number2(n,1,-1)) - sage: [[lucas(n),is_prime(lucas(n)),n+1,is_prime(n+1)] for n in range(15)] + sage: def lucas(n): + ....: return Integer((5/2)*lucas_number1(n,1,-1) + (1/2)*lucas_number2(n,1,-1)) + sage: [[lucas(n), is_prime(lucas(n)), n+1, is_prime(n+1)] for n in range(15)] # optional - sage.libs.gap [[1, False, 1, False], [3, True, 2, True], [4, False, 3, True], @@ -825,26 +827,26 @@ def lucas_number2(n, P, Q): EXAMPLES:: - sage: [lucas_number2(i,1,-1) for i in range(10)] + sage: [lucas_number2(i,1,-1) for i in range(10)] # optional - sage.libs.gap [2, 1, 3, 4, 7, 11, 18, 29, 47, 76] - sage: [fibonacci(i-1)+fibonacci(i+1) for i in range(10)] + sage: [fibonacci(i-1)+fibonacci(i+1) for i in range(10)] # optional - sage.libs.pari [2, 1, 3, 4, 7, 11, 18, 29, 47, 76] :: - sage: n = lucas_number2(5,2,3); n + sage: n = lucas_number2(5,2,3); n # optional - sage.libs.gap 2 - sage: type(n) + sage: type(n) # optional - sage.libs.gap <class 'sage.rings.integer.Integer'> - sage: n = lucas_number2(5,2,-3/9); n + sage: n = lucas_number2(5,2,-3/9); n # optional - sage.libs.gap 418/9 - sage: type(n) + sage: type(n) # optional - sage.libs.gap <class 'sage.rings.rational.Rational'> The case `P=1`, `Q=-1` is the Lucas sequence in Brualdi's Introductory Combinatorics, 4th ed., Prentice-Hall, 2004:: - sage: [lucas_number2(n,1,-1) for n in range(10)] + sage: [lucas_number2(n,1,-1) for n in range(10)] # optional - sage.libs.gap [2, 1, 3, 4, 7, 11, 18, 29, 47, 76] """ n = ZZ(n) @@ -873,20 +875,20 @@ def stirling_number1(n, k, algorithm="gap") -> Integer: EXAMPLES:: - sage: stirling_number1(3,2) + sage: stirling_number1(3,2) # optional - sage.libs.gap 3 - sage: stirling_number1(5,2) + sage: stirling_number1(5,2) # optional - sage.libs.gap 50 - sage: 9*stirling_number1(9,5)+stirling_number1(9,4) + sage: 9*stirling_number1(9,5) + stirling_number1(9,4) # optional - sage.libs.gap 269325 - sage: stirling_number1(10,5) + sage: stirling_number1(10,5) # optional - sage.libs.gap 269325 Indeed, `S_1(n,k) = S_1(n-1,k-1) + (n-1)S_1(n-1,k)`. TESTS:: - sage: stirling_number1(10,5, algorithm='flint') + sage: stirling_number1(10,5, algorithm='flint') # optional - sage.libs.flint 269325 sage: s_sage = stirling_number1(50,3, algorithm="mutta") @@ -975,20 +977,17 @@ def stirling_number2(n, k, algorithm=None) -> Integer: 13707767141249454929449108424328432845001327479099713037876832759323918134840537229737624018908470350134593241314462032607787062188356702932169472820344473069479621239187226765307960899083230982112046605340713218483809366970996051181537181362810003701997334445181840924364501502386001705718466534614548056445414149016614254231944272872440803657763210998284198037504154374028831561296154209804833852506425742041757849726214683321363035774104866182331315066421119788248419742922490386531970053376982090046434022248364782970506521655684518998083846899028416459701847828711541840099891244700173707021989771147674432503879702222276268661726508226951587152781439224383339847027542755222936463527771486827849728880 sage: stirling_number2(500,31) 5832088795102666690960147007601603328246123996896731854823915012140005028360632199516298102446004084519955789799364757997824296415814582277055514048635928623579397278336292312275467402957402880590492241647229295113001728653772550743446401631832152281610081188041624848850056657889275564834450136561842528589000245319433225808712628826136700651842562516991245851618481622296716433577650218003181535097954294609857923077238362717189185577756446945178490324413383417876364657995818830270448350765700419876347023578011403646501685001538551891100379932684279287699677429566813471166558163301352211170677774072447414719380996777162087158124939742564291760392354506347716119002497998082844612434332155632097581510486912 - sage: n = stirling_number2(20,11) - sage: n + sage: n = stirling_number2(20,11); n 1900842429486 sage: type(n) <class 'sage.rings.integer.Integer'> - sage: n = stirling_number2(20,11,algorithm='gap') - sage: n + sage: n = stirling_number2(20, 11, algorithm='gap'); n # optional - sage.libs.gap 1900842429486 - sage: type(n) + sage: type(n) # optional - sage.libs.gap <class 'sage.rings.integer.Integer'> - sage: n = stirling_number2(20,11,algorithm='flint') - sage: n + sage: n = stirling_number2(20, 11, algorithm='flint'); n # optional - sage.libs.flint 1900842429486 - sage: type(n) + sage: type(n) # optional - sage.libs.flint <class 'sage.rings.integer.Integer'> Sage's implementation splitting the computation of the Stirling @@ -997,7 +996,7 @@ def stirling_number2(n, k, algorithm=None) -> Integer: For `n<200`:: - sage: for n in Subsets(range(100,200), 5).random_element(): + sage: for n in Subsets(range(100,200), 5).random_element(): # optional - sage.libs.flint sage.libs.gap ....: for k in Subsets(range(n), 5).random_element(): ....: s_sage = stirling_number2(n,k) ....: s_flint = stirling_number2(n,k, algorithm = "flint") @@ -1007,7 +1006,7 @@ def stirling_number2(n, k, algorithm=None) -> Integer: For `n\geq 200`:: - sage: for n in Subsets(range(200,300), 5).random_element(): + sage: for n in Subsets(range(200,300), 5).random_element(): # optional - sage.libs.flint sage.libs.gap ....: for k in Subsets(range(n), 5).random_element(): ....: s_sage = stirling_number2(n,k) ....: s_flint = stirling_number2(n,k, algorithm = "flint") @@ -1015,10 +1014,10 @@ def stirling_number2(n, k, algorithm=None) -> Integer: ....: if not (s_sage == s_flint and s_sage == s_gap): ....: print("Error with n<200") - sage: stirling_number2(20,3, algorithm="maxima") + sage: stirling_number2(20, 3, algorithm="maxima") # optional - sage.symbolic 580606446 - sage: s_sage = stirling_number2(5,3, algorithm="namba") + sage: s_sage = stirling_number2(5, 3, algorithm="namba") Traceback (most recent call last): ... ValueError: unknown algorithm: namba @@ -1174,11 +1173,11 @@ def __init__(self, l, copy=True): Test indirectly that we copy the input (see :trac:`18184`):: - sage: L = IntegerListsLex(element_class=Partition) - sage: x = [3, 2, 1] - sage: P = L(x) - sage: x[0] = 5 - sage: list(P) + sage: L = IntegerListsLex(element_class=Partition) # optional - sage.combinat + sage: x = [3, 2, 1] # optional - sage.combinat + sage: P = L(x) # optional - sage.combinat + sage: x[0] = 5 # optional - sage.combinat + sage: list(P) # optional - sage.combinat [3, 2, 1] """ if copy: @@ -1616,7 +1615,7 @@ def is_finite(self) -> bool: EXAMPLES:: - sage: Partitions(5).is_finite() + sage: Partitions(5).is_finite() # optional - sage.combinat True sage: Permutations().is_finite() False @@ -1650,7 +1649,7 @@ def __str__(self) -> str: EXAMPLES:: - sage: str(Partitions(5)) + sage: str(Partitions(5)) # optional - sage.combinat 'Partitions of the integer 5' """ return repr(self) @@ -1659,7 +1658,7 @@ def _repr_(self) -> str: """ EXAMPLES:: - sage: repr(Partitions(5)) # indirect doctest + sage: repr(Partitions(5)) # indirect doctest # optional - sage.combinat 'Partitions of the integer 5' """ if hasattr(self, '_name') and self._name: @@ -1682,7 +1681,7 @@ def __contains__(self, x) -> bool: EXAMPLES:: sage: C = CombinatorialClass() - sage: x in C + sage: x in C # optional - sage.symbolic Traceback (most recent call last): ... NotImplementedError @@ -1697,11 +1696,11 @@ def __eq__(self, other): EXAMPLES:: - sage: p5 = Partitions(5) - sage: p6 = Partitions(6) - sage: repr(p5) == repr(p6) + sage: p5 = Partitions(5) # optional - sage.combinat + sage: p6 = Partitions(6) # optional - sage.combinat + sage: repr(p5) == repr(p6) # optional - sage.combinat False - sage: p5 == p6 + sage: p5 == p6 # optional - sage.combinat False """ return repr(self) == repr(other) @@ -1712,9 +1711,9 @@ def __ne__(self, other): EXAMPLES:: - sage: p5 = Partitions(5) - sage: p6 = Partitions(6) - sage: p5 != p6 + sage: p5 = Partitions(5) # optional - sage.combinat + sage: p6 = Partitions(6) # optional - sage.combinat + sage: p5 != p6 # optional - sage.combinat True """ return not (self == other) @@ -1766,14 +1765,14 @@ def __call__(self, x): EXAMPLES:: - sage: p5 = Partitions(5) - sage: a = [2,2,1] - sage: type(a) + sage: p5 = Partitions(5) # optional - sage.combinat + sage: a = [2,2,1] # optional - sage.combinat + sage: type(a) # optional - sage.combinat <class 'list'> - sage: a = p5(a) - sage: type(a) + sage: a = p5(a) # optional - sage.combinat + sage: type(a) # optional - sage.combinat <class 'sage.combinat.partition.Partitions_n_with_category.element_class'> - sage: p5([2,1]) + sage: p5([2,1]) # optional - sage.combinat Traceback (most recent call last): ... ValueError: [2, 1] is not an element of Partitions of the integer 5 @@ -1795,8 +1794,8 @@ def element_class(self): TESTS:: - sage: P5 = Partitions(5) - sage: P5.element_class + sage: P5 = Partitions(5) # optional - sage.combinat + sage: P5.element_class # optional - sage.combinat <class 'sage.combinat.partition.Partitions_n_with_category.element_class'> """ # assert not isinstance(self, Parent) # Raises an alert if we override the proper definition from Parent @@ -1811,9 +1810,9 @@ def _element_constructor_(self, x): TESTS:: - sage: P5 = Partitions(5) - sage: p = P5([3,2]) # indirect doctest - sage: type(p) + sage: P5 = Partitions(5) # optional - sage.combinat + sage: p = P5([3,2]) # indirect doctest # optional - sage.combinat + sage: type(p) # optional - sage.combinat <class 'sage.combinat.partition.Partitions_n_with_category.element_class'> """ # assert not isinstance(self, Parent) # Raises an alert if we override the proper definition from Parent @@ -1829,7 +1828,7 @@ def __list_from_iterator(self): sage: class C(CombinatorialClass): ....: def __iter__(self): ....: return iter([1,2,3]) - sage: C().list() #indirect doctest + sage: C().list() #indirect doctest [1, 2, 3] """ return [x for x in self] @@ -1949,8 +1948,8 @@ def __iter__(self): EXAMPLES:: - sage: p5 = Partitions(5) - sage: [i for i in p5] + sage: p5 = Partitions(5) # optional - sage.combinat + sage: [i for i in p5] # optional - sage.combinat [[5], [4, 1], [3, 2], [3, 1, 1], [2, 2, 1], [2, 1, 1, 1], [1, 1, 1, 1, 1]] sage: C = CombinatorialClass() sage: iter(C) @@ -2117,7 +2116,7 @@ def filter(self, f, name=None): sage: from sage.combinat.combinat import Permutations_CC sage: P = Permutations_CC(3).filter(lambda x: x.avoids([1,2])) - sage: P.list() + sage: P.list() # optional - sage.combinat [[3, 2, 1]] """ return FilteredCombinatorialClass(self, f, name=name) @@ -2151,7 +2150,8 @@ class by `f`, as a combinatorial class. EXAMPLES:: sage: R = Permutations(3).map(attrcall('reduced_word')); R - Image of Standard permutations of 3 by The map *.reduced_word() from Standard permutations of 3 + Image of Standard permutations of 3 by + The map *.reduced_word() from Standard permutations of 3 sage: R.cardinality() 6 sage: R.list() @@ -2161,15 +2161,15 @@ class by `f`, as a combinatorial class. If the function is not injective, then there may be repeated elements:: - sage: P = Partitions(4) - sage: P.list() + sage: P = Partitions(4) # optional - sage.combinat + sage: P.list() # optional - sage.combinat [[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]] - sage: P.map(len).list() + sage: P.map(len).list() # optional - sage.combinat [1, 2, 2, 3, 4] Use ``is_injective=False`` to get a correct result in this case:: - sage: P.map(len, is_injective=False).list() + sage: P.map(len, is_injective=False).list() # optional - sage.combinat [1, 2, 3, 4] TESTS:: @@ -2238,7 +2238,7 @@ def cardinality(self) -> Integer: sage: from sage.combinat.combinat import Permutations_CC sage: P = Permutations_CC(3).filter(lambda x: x.avoids([1,2])) - sage: P.cardinality() + sage: P.cardinality() # optional - sage.combinat 1 """ c = 0 @@ -2252,7 +2252,7 @@ def __iter__(self) -> Iterator: sage: from sage.combinat.combinat import Permutations_CC sage: P = Permutations_CC(3).filter(lambda x: x.avoids([1,2])) - sage: list(P) + sage: list(P) # optional - sage.combinat [[3, 2, 1]] """ for x in self.combinatorial_class: @@ -2481,13 +2481,13 @@ class MapCombinatorialClass(ImageSubobject, CombinatorialClass): EXAMPLES:: - sage: R = SymmetricGroup(10).map(attrcall('reduced_word')) - sage: R.an_element() + sage: R = SymmetricGroup(10).map(attrcall('reduced_word')) # optional - sage.groups + sage: R.an_element() # optional - sage.groups [9, 8, 7, 6, 5, 4, 3, 2] - sage: R.cardinality() + sage: R.cardinality() # optional - sage.groups 3628800 - sage: i = iter(R) - sage: next(i), next(i), next(i) + sage: i = iter(R) # optional - sage.groups + sage: next(i), next(i), next(i) # optional - sage.groups ([], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1]) """ @@ -2625,9 +2625,9 @@ def tuples(S, k, algorithm='itertools'): :: - sage: K.<a> = GF(4, 'a') - sage: mset = [x for x in K if x != 0] - sage: tuples(mset, 2) + sage: K.<a> = GF(4, 'a') # optional - sage.rings.finite_rings + sage: mset = [x for x in K if x != 0] # optional - sage.rings.finite_rings + sage: tuples(mset, 2) # optional - sage.rings.finite_rings [(a, a), (a, a + 1), (a, 1), (a + 1, a), (a + 1, a + 1), (a + 1, 1), (1, a), (1, a + 1), (1, 1)] @@ -2711,16 +2711,16 @@ def number_of_tuples(S, k, algorithm='naive') -> Integer: sage: S = [1,2,3,4,5] sage: number_of_tuples(S,2) 25 - sage: number_of_tuples(S,2, algorithm="gap") + sage: number_of_tuples(S,2, algorithm="gap") # optional - sage.libs.gap 25 sage: S = [1,1,2,3,4,5] sage: number_of_tuples(S,2) 25 - sage: number_of_tuples(S,2, algorithm="gap") + sage: number_of_tuples(S,2, algorithm="gap") # optional - sage.libs.gap 25 sage: number_of_tuples(S,0) 1 - sage: number_of_tuples(S,0, algorithm="gap") + sage: number_of_tuples(S,0, algorithm="gap") # optional - sage.libs.gap 1 """ if algorithm == 'naive': @@ -2772,7 +2772,7 @@ def unordered_tuples(S, k, algorithm='itertools'): We check that this agrees with GAP:: - sage: unordered_tuples(S, 3, algorithm='gap') + sage: unordered_tuples(S, 3, algorithm='gap') # optional - sage.libs.gap [(1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)] We check the result on strings:: @@ -2780,13 +2780,13 @@ def unordered_tuples(S, k, algorithm='itertools'): sage: S = ["a","b","c"] sage: unordered_tuples(S, 2) [('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), ('c', 'c')] - sage: unordered_tuples(S, 2, algorithm='gap') + sage: unordered_tuples(S, 2, algorithm='gap') # optional - sage.libs.gap [('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), ('c', 'c')] Lastly we check on a multiset:: sage: S = [1,1,2] - sage: unordered_tuples(S, 3) == unordered_tuples(S, 3, 'gap') + sage: unordered_tuples(S, 3) == unordered_tuples(S, 3, 'gap') # optional - sage.libs.gap True sage: unordered_tuples(S, 3) [(1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)] @@ -2827,16 +2827,16 @@ def number_of_unordered_tuples(S, k, algorithm='naive') -> Integer: sage: S = [1,2,3,4,5] sage: number_of_unordered_tuples(S,2) 15 - sage: number_of_unordered_tuples(S,2, algorithm="gap") + sage: number_of_unordered_tuples(S,2, algorithm="gap") # optional - sage.libs.gap 15 sage: S = [1,1,2,3,4,5] sage: number_of_unordered_tuples(S,2) 15 - sage: number_of_unordered_tuples(S,2, algorithm="gap") + sage: number_of_unordered_tuples(S,2, algorithm="gap") # optional - sage.libs.gap 15 sage: number_of_unordered_tuples(S,0) 1 - sage: number_of_unordered_tuples(S,0, algorithm="gap") + sage: number_of_unordered_tuples(S,0, algorithm="gap") # optional - sage.libs.gap 1 """ if algorithm == 'naive': @@ -2936,19 +2936,19 @@ def bell_polynomial(n: Integer, k: Integer): EXAMPLES:: - sage: bell_polynomial(6,2) + sage: bell_polynomial(6,2) # optional - sage.combinat 10*x2^2 + 15*x1*x3 + 6*x0*x4 - sage: bell_polynomial(6,3) + sage: bell_polynomial(6,3) # optional - sage.combinat 15*x1^3 + 60*x0*x1*x2 + 15*x0^2*x3 TESTS: Check that :trac:`18338` is fixed:: - sage: bell_polynomial(0,0).parent() + sage: bell_polynomial(0,0).parent() # optional - sage.combinat Multivariate Polynomial Ring in x over Integer Ring - sage: for n in (0..4): + sage: for n in (0..4): # optional - sage.combinat ....: print([bell_polynomial(n,k).coefficients() for k in (0..n)]) [[1]] [[], [1]] @@ -2999,13 +2999,12 @@ def fibonacci_sequence(start, stop=None, algorithm=None) -> Iterator: EXAMPLES:: - sage: fibs = [i for i in fibonacci_sequence(10, 20)] - sage: fibs + sage: fibs = [i for i in fibonacci_sequence(10, 20)]; fibs # optional - sage.libs.pari [55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181] :: - sage: sum([i for i in fibonacci_sequence(100, 110)]) + sage: sum([i for i in fibonacci_sequence(100, 110)]) # optional - sage.libs.pari 69919376923075308730013 .. SEEALSO:: @@ -3039,26 +3038,25 @@ def fibonacci_xrange(start, stop=None, algorithm='pari') -> Iterator: EXAMPLES:: - sage: fibs_in_some_range = [i for i in fibonacci_xrange(10^7, 10^8)] - sage: len(fibs_in_some_range) + sage: fibs_in_some_range = [i for i in fibonacci_xrange(10^7, 10^8)] # optional - sage.libs.pari + sage: len(fibs_in_some_range) # optional - sage.libs.pari 4 - sage: fibs_in_some_range + sage: fibs_in_some_range # optional - sage.libs.pari [14930352, 24157817, 39088169, 63245986] :: - sage: fibs = [i for i in fibonacci_xrange(10, 100)] - sage: fibs + sage: fibs = [i for i in fibonacci_xrange(10, 100)]; fibs # optional - sage.libs.pari [13, 21, 34, 55, 89] :: - sage: list(fibonacci_xrange(13, 34)) + sage: list(fibonacci_xrange(13, 34)) # optional - sage.libs.pari [13, 21] A solution to the second Project Euler problem:: - sage: sum([i for i in fibonacci_xrange(10^6) if is_even(i)]) + sage: sum([i for i in fibonacci_xrange(10^6) if is_even(i)]) # optional - sage.libs.pari 1089154 .. SEEALSO:: @@ -3116,30 +3114,30 @@ def bernoulli_polynomial(x, n: Integer): EXAMPLES:: sage: y = QQ['y'].0 - sage: bernoulli_polynomial(y, 5) + sage: bernoulli_polynomial(y, 5) # optional - sage.libs.flint y^5 - 5/2*y^4 + 5/3*y^3 - 1/6*y - sage: bernoulli_polynomial(y, 5)(12) + sage: bernoulli_polynomial(y, 5)(12) # optional - sage.libs.flint 199870 - sage: bernoulli_polynomial(12, 5) + sage: bernoulli_polynomial(12, 5) # optional - sage.libs.flint 199870 - sage: bernoulli_polynomial(y^2 + 1, 5) + sage: bernoulli_polynomial(y^2 + 1, 5) # optional - sage.libs.flint y^10 + 5/2*y^8 + 5/3*y^6 - 1/6*y^2 sage: P.<t> = ZZ[] - sage: p = bernoulli_polynomial(t, 6) - sage: p.parent() + sage: p = bernoulli_polynomial(t, 6) # optional - sage.libs.flint + sage: p.parent() # optional - sage.libs.flint Univariate Polynomial Ring in t over Rational Field We verify an instance of the formula which is the origin of the Bernoulli polynomials (and numbers):: sage: power_sum = sum(k^4 for k in range(10)) - sage: 5*power_sum == bernoulli_polynomial(10, 5) - bernoulli(5) + sage: 5*power_sum == bernoulli_polynomial(10, 5) - bernoulli(5) # optional - sage.libs.flint True TESTS:: sage: x = polygen(QQ, 'x') - sage: bernoulli_polynomial(x, 0).parent() + sage: bernoulli_polynomial(x, 0).parent() # optional - sage.libs.flint Univariate Polynomial Ring in x over Rational Field REFERENCES: diff --git a/src/sage/combinat/combination.py b/src/sage/combinat/combination.py index 42e727c6877..fc8b044d89d 100644 --- a/src/sage/combinat/combination.py +++ b/src/sage/combinat/combination.py @@ -148,15 +148,15 @@ class of combinations of ``mset`` of size ``k``. It is possible to take combinations of Sage objects:: - sage: Combinations([vector([1,1]), vector([2,2]), vector([3,3])], 2).list() + sage: Combinations([vector([1,1]), vector([2,2]), vector([3,3])], 2).list() # optional - sage.modules [[(1, 1), (2, 2)], [(1, 1), (3, 3)], [(2, 2), (3, 3)]] TESTS: We check that the code works even for non mutable objects:: - sage: l = [vector((0,0)), vector((0,1))] - sage: Combinations(l).list() + sage: l = [vector((0,0)), vector((0,1))] # optional - sage.modules + sage: Combinations(l).list() # optional - sage.modules [[], [(0, 0)], [(0, 1)], [(0, 0), (0, 1)]] """ # Check to see if everything in mset is unique @@ -269,7 +269,7 @@ def cardinality(self): sage: Combinations([1,2,3]).cardinality() 8 - sage: Combinations(['a','a','b']).cardinality() + sage: Combinations(['a','a','b']).cardinality() # optional - sage.libs.gap 6 """ c = 0 @@ -431,7 +431,7 @@ def cardinality(self): EXAMPLES:: sage: mset = [1,1,2,3,4,4,5] - sage: Combinations(mset,2).cardinality() + sage: Combinations(mset,2).cardinality() # optional - sage.libs.gap 12 """ from sage.libs.gap.libgap import libgap diff --git a/src/sage/combinat/combinatorial_map.py b/src/sage/combinat/combinatorial_map.py index 01d552498ee..0ff4ffe34bc 100644 --- a/src/sage/combinat/combinatorial_map.py +++ b/src/sage/combinat/combinatorial_map.py @@ -302,9 +302,9 @@ def __call__(self, *args, **kwds): sage: p = Permutation([1,3,2,4]) sage: cm = type(p).left_tableau; cm Combinatorial map: Robinson-Schensted insertion tableau - sage: cm(p) + sage: cm(p) # optional - sage.combinat [[1, 2, 4], [3]] - sage: cm(Permutation([4,3,2,1])) + sage: cm(Permutation([4,3,2,1])) # optional - sage.combinat [[1], [2], [3], [4]] """ if self._inst is not None: diff --git a/src/sage/combinat/composition.py b/src/sage/combinat/composition.py index d030152605b..50f1ee26780 100644 --- a/src/sage/combinat/composition.py +++ b/src/sage/combinat/composition.py @@ -172,18 +172,18 @@ def _ascii_art_(self): """ TESTS:: - sage: ascii_art(Compositions(4).list()) + sage: ascii_art(Compositions(4).list()) # optional - sage.combinat [ * ] [ * ** * * ] [ * * ** *** * ** * ] [ *, * , * , * , **, ** , ***, **** ] - sage: Partitions.options(diagram_str='#', convention="French") - sage: ascii_art(Compositions(4).list()) + sage: Partitions.options(diagram_str='#', convention="French") # optional - sage.combinat + sage: ascii_art(Compositions(4).list()) # optional - sage.combinat [ # ] [ # # # ## ] [ # # ## # # ## ### ] [ #, ##, #, ###, #, ##, #, #### ] - sage: Partitions.options._reset() + sage: Partitions.options._reset() # optional - sage.combinat """ from sage.typeset.ascii_art import ascii_art return ascii_art(self.to_skew_partition()) @@ -192,20 +192,20 @@ def _unicode_art_(self): """ TESTS:: - sage: unicode_art(Compositions(4).list()) + sage: unicode_art(Compositions(4).list()) # optional - sage.combinat ⎡ ┌┐ ⎤ ⎢ ├┤ ┌┬┐ ┌┐ ┌┐ ⎥ ⎢ ├┤ ├┼┘ ┌┼┤ ┌┬┬┐ ├┤ ┌┬┐ ┌┐ ⎥ ⎢ ├┤ ├┤ ├┼┘ ├┼┴┘ ┌┼┤ ┌┼┼┘ ┌┬┼┤ ┌┬┬┬┐ ⎥ ⎣ └┘, └┘ , └┘ , └┘ , └┴┘, └┴┘ , └┴┴┘, └┴┴┴┘ ⎦ - sage: Partitions.options(diagram_str='#', convention="French") - sage: unicode_art(Compositions(4).list()) + sage: Partitions.options(diagram_str='#', convention="French") # optional - sage.combinat + sage: unicode_art(Compositions(4).list()) # optional - sage.combinat ⎡ ┌┐ ⎤ ⎢ ├┤ ┌┐ ┌┐ ┌┬┐ ⎥ ⎢ ├┤ ├┤ ├┼┐ ┌┐ └┼┤ ┌┬┐ ┌┬┬┐ ⎥ ⎢ ├┤ ├┼┐ └┼┤ ├┼┬┐ ├┤ └┼┼┐ └┴┼┤ ┌┬┬┬┐ ⎥ ⎣ └┘, └┴┘, └┘, └┴┴┘, └┘, └┴┘, └┘, └┴┴┴┘ ⎦ - sage: Partitions.options._reset() + sage: Partitions.options._reset() # optional - sage.combinat """ from sage.typeset.unicode_art import unicode_art return unicode_art(self.to_skew_partition()) @@ -254,7 +254,7 @@ def conjugate(self) -> Composition: The ribbon shape of the conjugate of `I` is the conjugate of the ribbon shape of `I`:: - sage: all( I.conjugate().to_skew_partition() + sage: all( I.conjugate().to_skew_partition() # optional - sage.combinat ....: == I.to_skew_partition().conjugate() ....: for I in Compositions(4) ) True @@ -1178,11 +1178,11 @@ def to_partition(self): EXAMPLES:: - sage: Composition([2,1,3]).to_partition() + sage: Composition([2,1,3]).to_partition() # optional - sage.combinat [3, 2, 1] - sage: Composition([4,2,2]).to_partition() + sage: Composition([4,2,2]).to_partition() # optional - sage.combinat [4, 2, 2] - sage: Composition([]).to_partition() + sage: Composition([]).to_partition() # optional - sage.combinat [] """ from sage.combinat.partition import Partition @@ -1202,15 +1202,15 @@ def to_skew_partition(self, overlap=1): EXAMPLES:: - sage: Composition([3,4,1]).to_skew_partition() + sage: Composition([3,4,1]).to_skew_partition() # optional - sage.combinat [6, 6, 3] / [5, 2] - sage: Composition([3,4,1]).to_skew_partition(overlap=0) + sage: Composition([3,4,1]).to_skew_partition(overlap=0) # optional - sage.combinat [8, 7, 3] / [7, 3] - sage: Composition([]).to_skew_partition() + sage: Composition([]).to_skew_partition() # optional - sage.combinat [] / [] - sage: Composition([1,2]).to_skew_partition() + sage: Composition([1,2]).to_skew_partition() # optional - sage.combinat [2, 1] / [] - sage: Composition([2,1]).to_skew_partition() + sage: Composition([2,1]).to_skew_partition() # optional - sage.combinat [2, 2] / [1] """ from sage.combinat.skew_partition import SkewPartition @@ -1264,32 +1264,40 @@ def shuffle_product(self, other, overlap=False): sage: alph = Composition([2,2]) sage: beta = Composition([1,1,3]) - sage: S = alph.shuffle_product(beta); S + sage: S = alph.shuffle_product(beta); S # optional - sage.combinat Shuffle product of [2, 2] and [1, 1, 3] - sage: S.list() - [[2, 2, 1, 1, 3], [2, 1, 2, 1, 3], [2, 1, 1, 2, 3], [2, 1, 1, 3, 2], [1, 2, 2, 1, 3], [1, 2, 1, 2, 3], [1, 2, 1, 3, 2], [1, 1, 2, 2, 3], [1, 1, 2, 3, 2], [1, 1, 3, 2, 2]] + sage: S.list() # optional - sage.combinat + [[2, 2, 1, 1, 3], [2, 1, 2, 1, 3], [2, 1, 1, 2, 3], [2, 1, 1, 3, 2], + [1, 2, 2, 1, 3], [1, 2, 1, 2, 3], [1, 2, 1, 3, 2], [1, 1, 2, 2, 3], + [1, 1, 2, 3, 2], [1, 1, 3, 2, 2]] The *overlapping* shuffle product of `[2,2]` and `[1,1,3]`:: sage: alph = Composition([2,2]) sage: beta = Composition([1,1,3]) - sage: O = alph.shuffle_product(beta, overlap=True); O + sage: O = alph.shuffle_product(beta, overlap=True); O # optional - sage.combinat Overlapping shuffle product of [2, 2] and [1, 1, 3] - sage: O.list() - [[2, 2, 1, 1, 3], [2, 1, 2, 1, 3], [2, 1, 1, 2, 3], [2, 1, 1, 3, 2], [1, 2, 2, 1, 3], [1, 2, 1, 2, 3], [1, 2, 1, 3, 2], [1, 1, 2, 2, 3], [1, 1, 2, 3, 2], [1, 1, 3, 2, 2], [3, 2, 1, 3], [2, 3, 1, 3], [3, 1, 2, 3], [2, 1, 3, 3], [3, 1, 3, 2], [2, 1, 1, 5], [1, 3, 2, 3], [1, 2, 3, 3], [1, 3, 3, 2], [1, 2, 1, 5], [1, 1, 5, 2], [1, 1, 2, 5], [3, 3, 3], [3, 1, 5], [1, 3, 5]] + sage: O.list() # optional - sage.combinat + [[2, 2, 1, 1, 3], [2, 1, 2, 1, 3], [2, 1, 1, 2, 3], [2, 1, 1, 3, 2], + [1, 2, 2, 1, 3], [1, 2, 1, 2, 3], [1, 2, 1, 3, 2], [1, 1, 2, 2, 3], + [1, 1, 2, 3, 2], [1, 1, 3, 2, 2], + [3, 2, 1, 3], [2, 3, 1, 3], [3, 1, 2, 3], [2, 1, 3, 3], [3, 1, 3, 2], + [2, 1, 1, 5], [1, 3, 2, 3], [1, 2, 3, 3], [1, 3, 3, 2], [1, 2, 1, 5], + [1, 1, 5, 2], [1, 1, 2, 5], + [3, 3, 3], [3, 1, 5], [1, 3, 5]] Note that the shuffle product of two compositions can include the same composition more than once since a composition can be a shuffle of two compositions in several ways. For example:: sage: w1 = Composition([1]) - sage: S = w1.shuffle_product(w1); S + sage: S = w1.shuffle_product(w1); S # optional - sage.combinat Shuffle product of [1] and [1] - sage: S.list() + sage: S.list() # optional - sage.combinat [[1, 1], [1, 1]] - sage: O = w1.shuffle_product(w1, overlap=True); O + sage: O = w1.shuffle_product(w1, overlap=True); O # optional - sage.combinat Overlapping shuffle product of [1] and [1] - sage: O.list() + sage: O.list() # optional - sage.combinat [[1, 1], [1, 1], [2]] TESTS:: @@ -1392,11 +1400,10 @@ def specht_module(self, base_ring=None): EXAMPLES:: - sage: SM = Composition([1,2,2]).specht_module(QQ) - sage: SM + sage: SM = Composition([1,2,2]).specht_module(QQ); SM # optional - sage.combinat sage.modules Specht module of [(0, 0), (1, 0), (1, 1), (2, 0), (2, 1)] over Rational Field - sage: s = SymmetricFunctions(QQ).s() - sage: s(SM.frobenius_image()) + sage: s = SymmetricFunctions(QQ).s() # optional - sage.combinat sage.modules + sage: s(SM.frobenius_image()) # optional - sage.combinat sage.modules s[2, 2, 1] """ from sage.combinat.specht_module import SpechtModule @@ -1421,9 +1428,9 @@ def specht_module_dimension(self, base_ring=None): EXAMPLES:: - sage: Composition([1,2,2]).specht_module_dimension() + sage: Composition([1,2,2]).specht_module_dimension() # optional - sage.combinat sage.modules 5 - sage: Composition([1,2,2]).specht_module_dimension(GF(2)) + sage: Composition([1,2,2]).specht_module_dimension(GF(2)) # optional - sage.combinat sage.modules sage.rings.finite_rings 5 """ from sage.combinat.specht_module import specht_module_rank diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index 9593055e9ed..de92bc8acf7 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -1188,14 +1188,14 @@ def to_matrix(self): EXAMPLES:: - sage: Permutation([1,2,3]).to_matrix() + sage: Permutation([1,2,3]).to_matrix() # optional - sage.modules [1 0 0] [0 1 0] [0 0 1] Alternatively:: - sage: matrix(Permutation([1,3,2])) + sage: matrix(Permutation([1,3,2])) # optional - sage.modules [1 0 0] [0 0 1] [0 1 0] @@ -1208,16 +1208,16 @@ def to_matrix(self): sage: Permutations.options.mult='r2l' sage: p = Permutation([2,1,3]) sage: q = Permutation([3,1,2]) - sage: (p*q).to_matrix() + sage: (p*q).to_matrix() # optional - sage.modules [0 0 1] [0 1 0] [1 0 0] - sage: p.to_matrix()*q.to_matrix() + sage: p.to_matrix()*q.to_matrix() # optional - sage.modules [0 0 1] [0 1 0] [1 0 0] sage: Permutations.options.mult='l2r' - sage: (p*q).to_matrix() + sage: (p*q).to_matrix() # optional - sage.modules [1 0 0] [0 0 1] [0 1 0] @@ -1238,11 +1238,11 @@ def to_alternating_sign_matrix(self): EXAMPLES:: - sage: m = Permutation([1,2,3]).to_alternating_sign_matrix(); m + sage: m = Permutation([1,2,3]).to_alternating_sign_matrix(); m # optional - sage.combinat sage.modules [1 0 0] [0 1 0] [0 0 1] - sage: parent(m) + sage: parent(m) # optional - sage.combinat sage.modules Alternating sign matrices of size 3 """ from sage.combinat.alternating_sign_matrix import AlternatingSignMatrix @@ -1252,12 +1252,12 @@ def __mul__(self, rp): """ TESTS:: - sage: SGA = SymmetricGroupAlgebra(QQ, 3) - sage: SM = SGA.specht_module([2,1]) - sage: p213 = Permutations(3)([2,1,3]) - sage: p213 * SGA.an_element() + sage: SGA = SymmetricGroupAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: SM = SGA.specht_module([2,1]) # optional - sage.combinat sage.modules + sage: p213 = Permutations(3)([2,1,3]) # optional - sage.combinat sage.modules + sage: p213 * SGA.an_element() # optional - sage.combinat sage.modules 3*[1, 2, 3] + [1, 3, 2] + [2, 1, 3] + 2*[3, 1, 2] - sage: p213 * SM.an_element() + sage: p213 * SM.an_element() # optional - sage.combinat sage.modules 2*B[0] - 4*B[1] """ if not isinstance(rp, Permutation) and isinstance(rp, Element): @@ -1297,8 +1297,8 @@ def __rmul__(self, lp) -> Permutation: [3, 2, 1] sage: Permutations.options.mult='l2r' - sage: SGA = SymmetricGroupAlgebra(QQ, 3) - sage: SGA.an_element() * Permutations(3)(p213) + sage: SGA = SymmetricGroupAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: SGA.an_element() * Permutations(3)(p213) # optional - sage.combinat sage.modules 3*[1, 2, 3] + [2, 1, 3] + 2*[2, 3, 1] + [3, 2, 1] """ if not isinstance(lp, Permutation) and isinstance(lp, Element): @@ -1678,18 +1678,19 @@ def to_digraph(self) -> DiGraph: EXAMPLES:: - sage: d = Permutation([3, 1, 2]).to_digraph() - sage: d.edges(sort=True, labels=False) + sage: d = Permutation([3, 1, 2]).to_digraph() # optional - sage.graphs + sage: d.edges(sort=True, labels=False) # optional - sage.graphs [(1, 3), (2, 1), (3, 2)] sage: P = Permutations(range(1, 10)) - sage: d = Permutation(P.random_element()).to_digraph() - sage: all(c.is_cycle() for c in d.strongly_connected_components_subgraphs()) + sage: d = Permutation(P.random_element()).to_digraph() # optional - sage.graphs + sage: all(c.is_cycle() # optional - sage.graphs + ....: for c in d.strongly_connected_components_subgraphs()) True TESTS:: - sage: d = Permutation([1]).to_digraph() - sage: d.edges(sort=True, labels=False) + sage: d = Permutation([1]).to_digraph() # optional - sage.graphs + sage: d.edges(sort=True, labels=False) # optional - sage.graphs [(1, 1)] """ return DiGraph([self, enumerate(self, start=1)], @@ -1720,14 +1721,15 @@ def show(self, representation="cycles", orientation="landscape", **args): EXAMPLES:: - sage: Permutations(20).random_element().show(representation = "cycles") - sage: Permutations(20).random_element().show(representation = "chord-diagram") - sage: Permutations(20).random_element().show(representation = "braid") - sage: Permutations(20).random_element().show(representation = "braid", orientation='portrait') + sage: Permutations(20).random_element().show(representation="cycles") + sage: Permutations(20).random_element().show(representation="chord-diagram") + sage: Permutations(20).random_element().show(representation="braid") + sage: Permutations(20).random_element().show(representation="braid", + ....: orientation='portrait') TESTS:: - sage: Permutations(20).random_element().show(representation = "modern_art") + sage: Permutations(20).random_element().show(representation="modern_art") Traceback (most recent call last): ... ValueError: The value of 'representation' must be equal to 'cycles', 'chord-diagram' or 'braid' @@ -2246,9 +2248,9 @@ def longest_increasing_subsequences(self): EXAMPLES:: - sage: Permutation([2,3,4,1]).longest_increasing_subsequences() + sage: Permutation([2,3,4,1]).longest_increasing_subsequences() # optional - sage.graphs [[2, 3, 4]] - sage: Permutation([5, 7, 1, 2, 6, 4, 3]).longest_increasing_subsequences() + sage: Permutation([5, 7, 1, 2, 6, 4, 3]).longest_increasing_subsequences() # optional - sage.graphs [[1, 2, 6], [1, 2, 4], [1, 2, 3]] .. NOTE:: @@ -2306,16 +2308,17 @@ def longest_increasing_subsequences_number(self): The algorithm is similar to :meth:`longest_increasing_subsequences`. Namely, the longest increasing subsequences are encoded as increasing sequences in a ranked poset from a smallest to a largest element. Their - number can be obtained via dynamic programming : for each `v` in the poset + number can be obtained via dynamic programming: for each `v` in the poset we compute the number of paths from a smallest element to `v`. EXAMPLES:: - sage: sum(p.longest_increasing_subsequences_number() for p in Permutations(8)) + sage: sum(p.longest_increasing_subsequences_number() + ....: for p in Permutations(8)) 120770 sage: p = Permutations(50).random_element() - sage: (len(p.longest_increasing_subsequences()) == + sage: (len(p.longest_increasing_subsequences()) == # optional - sage.graphs ....: p.longest_increasing_subsequences_number()) True """ @@ -2354,7 +2357,7 @@ def cycle_type(self): EXAMPLES:: - sage: Permutation([3,1,2,4]).cycle_type() + sage: Permutation([3,1,2,4]).cycle_type() # optional - sage.combinat [3, 1] """ cycle_type = [len(c) for c in self.to_cycles()] @@ -3019,9 +3022,9 @@ def rothe_diagram(self): EXAMPLES:: sage: p = Permutation([4,2,1,3]) - sage: D = p.rothe_diagram(); D + sage: D = p.rothe_diagram(); D # optional - sage.combinat [(0, 0), (0, 1), (0, 2), (1, 0)] - sage: D.pp() + sage: D.pp() # optional - sage.combinat O O O . O . . . . . . . @@ -3038,7 +3041,7 @@ def number_of_reduced_words(self): EXAMPLES:: sage: p = Permutation([6,4,2,5,1,8,3,7]) - sage: len(p.reduced_words()) == p.number_of_reduced_words() + sage: len(p.reduced_words()) == p.number_of_reduced_words() # optional - sage.combinat True """ Tx = self.rothe_diagram().peelable_tableaux() @@ -4221,8 +4224,10 @@ def right_permutohedron_interval_iterator(self, other): EXAMPLES:: - sage: Permutation([2, 1, 4, 5, 3]).right_permutohedron_interval(Permutation([2, 5, 4, 1, 3])) # indirect doctest - [[2, 4, 5, 1, 3], [2, 4, 1, 5, 3], [2, 1, 4, 5, 3], [2, 1, 5, 4, 3], [2, 5, 1, 4, 3], [2, 5, 4, 1, 3]] + sage: p = Permutation([2, 1, 4, 5, 3]); q = Permutation([2, 5, 4, 1, 3]) + sage: p.right_permutohedron_interval(q) # indirect doctest # optional - sage.graphs + [[2, 4, 5, 1, 3], [2, 4, 1, 5, 3], [2, 1, 4, 5, 3], + [2, 1, 5, 4, 3], [2, 5, 1, 4, 3], [2, 5, 4, 1, 3]] """ if len(self) != len(other): raise ValueError("len({}) and len({}) must be equal".format(self, other)) @@ -4246,24 +4251,28 @@ def right_permutohedron_interval(self, other): EXAMPLES:: - sage: Permutation([2, 1, 4, 5, 3]).right_permutohedron_interval(Permutation([2, 5, 4, 1, 3])) - [[2, 4, 5, 1, 3], [2, 4, 1, 5, 3], [2, 1, 4, 5, 3], [2, 1, 5, 4, 3], [2, 5, 1, 4, 3], [2, 5, 4, 1, 3]] + sage: p = Permutation([2, 1, 4, 5, 3]); q = Permutation([2, 5, 4, 1, 3]) + sage: p.right_permutohedron_interval(q) # optional - sage.graphs + [[2, 4, 5, 1, 3], [2, 4, 1, 5, 3], [2, 1, 4, 5, 3], + [2, 1, 5, 4, 3], [2, 5, 1, 4, 3], [2, 5, 4, 1, 3]] TESTS:: - sage: Permutation([]).right_permutohedron_interval(Permutation([])) + sage: Permutation([]).right_permutohedron_interval(Permutation([])) # optional - sage.graphs [[]] - sage: Permutation([3, 1, 2]).right_permutohedron_interval(Permutation([3, 1, 2])) + sage: Permutation([3, 1, 2]).right_permutohedron_interval(Permutation([3, 1, 2])) # optional - sage.graphs [[3, 1, 2]] - sage: Permutation([1, 3, 2, 4]).right_permutohedron_interval(Permutation([3, 4, 2, 1])) - [[3, 1, 4, 2], [3, 4, 1, 2], [3, 4, 2, 1], [1, 3, 4, 2], [1, 3, 2, 4], [3, 2, 4, 1], [3, 2, 1, 4], [3, 1, 2, 4]] - sage: Permutation([2, 1, 4, 5, 3]).right_permutohedron_interval(Permutation([2, 5, 4, 1, 3])) - [[2, 4, 5, 1, 3], [2, 4, 1, 5, 3], [2, 1, 4, 5, 3], [2, 1, 5, 4, 3], [2, 5, 1, 4, 3], [2, 5, 4, 1, 3]] - sage: Permutation([2, 5, 4, 1, 3]).right_permutohedron_interval(Permutation([2, 1, 4, 5, 3])) + sage: Permutation([1, 3, 2, 4]).right_permutohedron_interval(Permutation([3, 4, 2, 1])) # optional - sage.graphs + [[3, 1, 4, 2], [3, 4, 1, 2], [3, 4, 2, 1], [1, 3, 4, 2], + [1, 3, 2, 4], [3, 2, 4, 1], [3, 2, 1, 4], [3, 1, 2, 4]] + sage: Permutation([2, 1, 4, 5, 3]).right_permutohedron_interval(Permutation([2, 5, 4, 1, 3])) # optional - sage.graphs + [[2, 4, 5, 1, 3], [2, 4, 1, 5, 3], [2, 1, 4, 5, 3], + [2, 1, 5, 4, 3], [2, 5, 1, 4, 3], [2, 5, 4, 1, 3]] + sage: Permutation([2, 5, 4, 1, 3]).right_permutohedron_interval(Permutation([2, 1, 4, 5, 3])) # optional - sage.graphs Traceback (most recent call last): ... ValueError: [2, 5, 4, 1, 3] must be lower or equal than [2, 1, 4, 5, 3] for the right permutohedron order - sage: Permutation([2, 4, 1, 3]).right_permutohedron_interval(Permutation([2, 1, 4, 5, 3])) + sage: Permutation([2, 4, 1, 3]).right_permutohedron_interval(Permutation([2, 1, 4, 5, 3])) # optional - sage.graphs Traceback (most recent call last): ... ValueError: len([2, 4, 1, 3]) and len([2, 1, 4, 5, 3]) must be equal @@ -4502,7 +4511,7 @@ def has_pattern(self, patt) -> bool: EXAMPLES:: - sage: Permutation([3,5,1,4,6,2]).has_pattern([1,3,2]) + sage: Permutation([3,5,1,4,6,2]).has_pattern([1,3,2]) # optional - sage.combinat True """ p = self @@ -4522,11 +4531,11 @@ def avoids(self, patt) -> bool: EXAMPLES:: - sage: Permutation([6,2,5,4,3,1]).avoids([4,2,3,1]) + sage: Permutation([6,2,5,4,3,1]).avoids([4,2,3,1]) # optional - sage.combinat False - sage: Permutation([6,1,2,5,4,3]).avoids([4,2,3,1]) + sage: Permutation([6,1,2,5,4,3]).avoids([4,2,3,1]) # optional - sage.combinat True - sage: Permutation([6,1,2,5,4,3]).avoids([3,4,1,2]) + sage: Permutation([6,1,2,5,4,3]).avoids([3,4,1,2]) # optional - sage.combinat True """ return not self.has_pattern(patt) @@ -4538,7 +4547,7 @@ def pattern_positions(self, patt) -> list: EXAMPLES:: - sage: Permutation([3,5,1,4,6,2]).pattern_positions([1,3,2]) + sage: Permutation([3,5,1,4,6,2]).pattern_positions([1,3,2]) # optional - sage.combinat [[0, 1, 3], [2, 3, 5], [2, 4, 5]] """ p = self @@ -4563,7 +4572,7 @@ def simion_schmidt(self, avoid=[1,2,3]): sage: P = Permutations(6) sage: p = P([4,5,1,6,3,2]) sage: pl = [ [1,2,3], [1,3,2], [3,1,2], [3,2,1] ] - sage: for q in pl: + sage: for q in pl: # optional - sage.combinat ....: s = p.simion_schmidt(q) ....: print("{} {}".format(s, s.has_pattern(q))) [4, 6, 1, 5, 3, 2] False @@ -4647,20 +4656,23 @@ def permutation_poset(self): EXAMPLES:: - sage: Permutation([3,1,5,4,2]).permutation_poset().cover_relations() + sage: Permutation([3,1,5,4,2]).permutation_poset().cover_relations() # optional - sage.combinat sage.graphs [[(2, 1), (5, 2)], [(2, 1), (3, 5)], [(2, 1), (4, 4)], [(1, 3), (3, 5)], [(1, 3), (4, 4)]] - sage: Permutation([]).permutation_poset().cover_relations() + sage: Permutation([]).permutation_poset().cover_relations() # optional - sage.combinat sage.graphs [] - sage: Permutation([1,3,2]).permutation_poset().cover_relations() + sage: Permutation([1,3,2]).permutation_poset().cover_relations() # optional - sage.combinat sage.graphs [[(1, 1), (2, 3)], [(1, 1), (3, 2)]] - sage: Permutation([1,2]).permutation_poset().cover_relations() + sage: Permutation([1,2]).permutation_poset().cover_relations() # optional - sage.combinat sage.graphs [[(1, 1), (2, 2)]] - sage: P = Permutation([1,5,2,4,3]) - sage: P.permutation_poset().greene_shape() == P.RS_partition() # This should hold for any P. + sage: P = Permutation([1,5,2,4,3]) # optional - sage.combinat sage.graphs + + This should hold for any `P`:: + + sage: P.permutation_poset().greene_shape() == P.RS_partition() # optional - sage.combinat sage.graphs True """ from sage.combinat.posets.posets import Poset @@ -4732,7 +4744,7 @@ def robinson_schensted(self): EXAMPLES:: - sage: Permutation([6,2,3,1,7,5,4]).robinson_schensted() + sage: Permutation([6,2,3,1,7,5,4]).robinson_schensted() # optional - sage.combinat [[[1, 3, 4], [2, 5], [6, 7]], [[1, 3, 5], [2, 6], [4, 7]]] """ return RSK(self, check_standard=True) @@ -4764,7 +4776,7 @@ def left_tableau(self): EXAMPLES:: - sage: Permutation([1,4,3,2]).left_tableau() + sage: Permutation([1,4,3,2]).left_tableau() # optional - sage.combinat [[1, 2], [3], [4]] """ return RSK(self, check_standard=True)[0] @@ -4777,7 +4789,7 @@ def right_tableau(self): EXAMPLES:: - sage: Permutation([1,4,3,2]).right_tableau() + sage: Permutation([1,4,3,2]).right_tableau() # optional - sage.combinat [[1, 2], [3], [4]] """ return RSK(self, check_standard=True)[1] @@ -4788,17 +4800,17 @@ def increasing_tree(self, compare=min): EXAMPLES:: - sage: Permutation([1,4,3,2]).increasing_tree() + sage: Permutation([1,4,3,2]).increasing_tree() # optional - sage.combinat 1[., 2[3[4[., .], .], .]] - sage: Permutation([4,1,3,2]).increasing_tree() + sage: Permutation([4,1,3,2]).increasing_tree() # optional - sage.combinat 1[4[., .], 2[3[., .], .]] By passing the option ``compare=max`` one can have the decreasing tree instead:: - sage: Permutation([2,3,4,1]).increasing_tree(max) + sage: Permutation([2,3,4,1]).increasing_tree(max) # optional - sage.combinat 4[3[2[., .], .], 1[., .]] - sage: Permutation([2,3,1,4]).increasing_tree(max) + sage: Permutation([2,3,1,4]).increasing_tree(max) # optional - sage.combinat 4[3[2[., .], 1[., .]], .] """ from sage.combinat.binary_tree import LabelledBinaryTree as LBT @@ -4819,17 +4831,17 @@ def increasing_tree_shape(self, compare=min): EXAMPLES:: - sage: Permutation([1,4,3,2]).increasing_tree_shape() + sage: Permutation([1,4,3,2]).increasing_tree_shape() # optional - sage.combinat [., [[[., .], .], .]] - sage: Permutation([4,1,3,2]).increasing_tree_shape() + sage: Permutation([4,1,3,2]).increasing_tree_shape() # optional - sage.combinat [[., .], [[., .], .]] By passing the option ``compare=max`` one can have the decreasing tree instead:: - sage: Permutation([2,3,4,1]).increasing_tree_shape(max) + sage: Permutation([2,3,4,1]).increasing_tree_shape(max) # optional - sage.combinat [[[., .], .], [., .]] - sage: Permutation([2,3,1,4]).increasing_tree_shape(max) + sage: Permutation([2,3,1,4]).increasing_tree_shape(max) # optional - sage.combinat [[[., .], [., .]], .] """ return self.increasing_tree(compare).shape() @@ -4855,22 +4867,22 @@ def binary_search_tree(self, left_to_right=True): EXAMPLES:: - sage: Permutation([1,4,3,2]).binary_search_tree() + sage: Permutation([1,4,3,2]).binary_search_tree() # optional - sage.combinat 1[., 4[3[2[., .], .], .]] - sage: Permutation([4,1,3,2]).binary_search_tree() + sage: Permutation([4,1,3,2]).binary_search_tree() # optional - sage.combinat 4[1[., 3[2[., .], .]], .] By passing the option ``left_to_right=False`` one can have the insertion going from right to left:: - sage: Permutation([1,4,3,2]).binary_search_tree(False) + sage: Permutation([1,4,3,2]).binary_search_tree(False) # optional - sage.combinat 2[1[., .], 3[., 4[., .]]] - sage: Permutation([4,1,3,2]).binary_search_tree(False) + sage: Permutation([4,1,3,2]).binary_search_tree(False) # optional - sage.combinat 2[1[., .], 3[., 4[., .]]] TESTS:: - sage: Permutation([]).binary_search_tree() + sage: Permutation([]).binary_search_tree() # optional - sage.combinat . """ from sage.combinat.binary_tree import LabelledBinaryTree as LBT @@ -4891,17 +4903,17 @@ def binary_search_tree_shape(self, left_to_right=True): EXAMPLES:: - sage: Permutation([1,4,3,2]).binary_search_tree_shape() + sage: Permutation([1,4,3,2]).binary_search_tree_shape() # optional - sage.combinat [., [[[., .], .], .]] - sage: Permutation([4,1,3,2]).binary_search_tree_shape() + sage: Permutation([4,1,3,2]).binary_search_tree_shape() # optional - sage.combinat [[., [[., .], .]], .] By passing the option ``left_to_right=False`` one can have the insertion going from right to left:: - sage: Permutation([1,4,3,2]).binary_search_tree_shape(False) + sage: Permutation([1,4,3,2]).binary_search_tree_shape(False) # optional - sage.combinat [[., .], [., [., .]]] - sage: Permutation([4,1,3,2]).binary_search_tree_shape(False) + sage: Permutation([4,1,3,2]).binary_search_tree_shape(False) # optional - sage.combinat [[., .], [., [., .]]] """ from sage.combinat.binary_tree import binary_search_tree_shape @@ -4948,7 +4960,7 @@ def sylvester_class(self, left_to_right=False): The sylvester class of a permutation in `S_5`:: sage: p = Permutation([3, 5, 1, 2, 4]) - sage: sorted(p.sylvester_class()) + sage: sorted(p.sylvester_class()) # optional - sage.combinat [[1, 3, 2, 5, 4], [1, 3, 5, 2, 4], [1, 5, 3, 2, 4], @@ -4960,20 +4972,20 @@ def sylvester_class(self, left_to_right=False): The sylvester class of a permutation `p` contains `p`:: - sage: all( p in p.sylvester_class() for p in Permutations(4) ) + sage: all(p in p.sylvester_class() for p in Permutations(4)) # optional - sage.combinat True Small cases:: - sage: list(Permutation([]).sylvester_class()) + sage: list(Permutation([]).sylvester_class()) # optional - sage.combinat [[]] - sage: list(Permutation([1]).sylvester_class()) + sage: list(Permutation([1]).sylvester_class()) # optional - sage.combinat [[1]] The sylvester classes in `S_3`:: - sage: [sorted(p.sylvester_class()) for p in Permutations(3)] + sage: [sorted(p.sylvester_class()) for p in Permutations(3)] # optional - sage.combinat [[[1, 2, 3]], [[1, 3, 2], [3, 1, 2]], [[2, 1, 3]], @@ -4983,7 +4995,8 @@ def sylvester_class(self, left_to_right=False): The left sylvester classes in `S_3`:: - sage: [sorted(p.sylvester_class(left_to_right=True)) for p in Permutations(3)] + sage: [sorted(p.sylvester_class(left_to_right=True)) # optional - sage.combinat + ....: for p in Permutations(3)] [[[1, 2, 3]], [[1, 3, 2]], [[2, 1, 3], [2, 3, 1]], @@ -4994,7 +5007,7 @@ def sylvester_class(self, left_to_right=False): A left sylvester class in `S_5`:: sage: p = Permutation([4, 2, 1, 5, 3]) - sage: sorted(p.sylvester_class(left_to_right=True)) + sage: sorted(p.sylvester_class(left_to_right=True)) # optional - sage.combinat [[4, 2, 1, 3, 5], [4, 2, 1, 5, 3], [4, 2, 3, 1, 5], @@ -5017,7 +5030,7 @@ def RS_partition(self): EXAMPLES:: - sage: Permutation([1,4,3,2]).RS_partition() + sage: Permutation([1,4,3,2]).RS_partition() # optional - sage.combinat [2, 1, 1] """ return RSK(self)[1].shape() @@ -5239,15 +5252,16 @@ def hyperoctahedral_double_coset_type(self): EXAMPLES:: - sage: Permutation([3, 4, 6, 1, 5, 7, 2, 8]).hyperoctahedral_double_coset_type() + sage: p = Permutation([3, 4, 6, 1, 5, 7, 2, 8]) + sage: p.hyperoctahedral_double_coset_type() # optional - sage.combinat [3, 1] - sage: all(p.hyperoctahedral_double_coset_type() == + sage: all(p.hyperoctahedral_double_coset_type() == # optional - sage.combinat ....: p.inverse().hyperoctahedral_double_coset_type() ....: for p in Permutations(4)) True - sage: Permutation([]).hyperoctahedral_double_coset_type() + sage: Permutation([]).hyperoctahedral_double_coset_type() # optional - sage.combinat [] - sage: Permutation([3,1,2]).hyperoctahedral_double_coset_type() + sage: Permutation([3,1,2]).hyperoctahedral_double_coset_type() # optional - sage.combinat Traceback (most recent call last): ... ValueError: [3, 1, 2] is a permutation of odd size and has no coset-type @@ -5324,21 +5338,23 @@ def shifted_shuffle(self, other): EXAMPLES:: - sage: Permutation([]).shifted_shuffle(Permutation([])) + sage: Permutation([]).shifted_shuffle(Permutation([])) # optional - sage.graphs [[]] - sage: Permutation([1, 2, 3]).shifted_shuffle(Permutation([1])) + sage: Permutation([1, 2, 3]).shifted_shuffle(Permutation([1])) # optional - sage.graphs [[4, 1, 2, 3], [1, 2, 3, 4], [1, 2, 4, 3], [1, 4, 2, 3]] - sage: Permutation([1, 2]).shifted_shuffle(Permutation([2, 1])) - [[4, 1, 3, 2], [4, 3, 1, 2], [1, 4, 3, 2], [1, 4, 2, 3], [1, 2, 4, 3], [4, 1, 2, 3]] - sage: Permutation([1]).shifted_shuffle([1]) + sage: Permutation([1, 2]).shifted_shuffle(Permutation([2, 1])) # optional - sage.graphs + [[4, 1, 3, 2], [4, 3, 1, 2], [1, 4, 3, 2], + [1, 4, 2, 3], [1, 2, 4, 3], [4, 1, 2, 3]] + sage: Permutation([1]).shifted_shuffle([1]) # optional - sage.graphs [[2, 1], [1, 2]] - sage: len(Permutation([3, 1, 5, 4, 2]).shifted_shuffle(Permutation([2, 1, 4, 3]))) + sage: p = Permutation([3, 1, 5, 4, 2]) + sage: len(p.shifted_shuffle(Permutation([2, 1, 4, 3]))) # optional - sage.graphs 126 The shifted shuffle product is associative. We can test this on an admittedly toy example:: - sage: all( all( all( sorted(flatten([abs.shifted_shuffle(c) + sage: all( all( all( sorted(flatten([abs.shifted_shuffle(c) # optional - sage.graphs ....: for abs in a.shifted_shuffle(b)])) ....: == sorted(flatten([a.shifted_shuffle(bcs) ....: for bcs in b.shifted_shuffle(c)])) @@ -5351,7 +5367,7 @@ def shifted_shuffle(self, other): permutations as the ``shifted_shuffle`` method on words (but is faster):: - sage: all( all( sorted(p1.shifted_shuffle(p2)) + sage: all( all( sorted(p1.shifted_shuffle(p2)) # optional - sage.graphs ....: == sorted([Permutation(p) for p in ....: Word(p1).shifted_shuffle(Word(p2))]) ....: for p2 in Permutations(3) ) @@ -5368,9 +5384,9 @@ def _tableau_contribution(T): EXAMPLES:: - sage: T = Tableau([[1,1,1],[2]]) + sage: T = Tableau([[1,1,1],[2]]) # optional - sage.combinat sage: from sage.combinat.permutation import _tableau_contribution - sage: _tableau_contribution(T) + sage: _tableau_contribution(T) # optional - sage.combinat 3 """ from sage.combinat.tableau import StandardTableaux @@ -5460,7 +5476,7 @@ class Permutations(UniqueRepresentation, Parent): sage: p = Permutations(['c', 'a', 't'], 2); p Permutations of the set ['c', 'a', 't'] of length 2 - sage: p.list() + sage: p.list() # optional - sage.libs.gap [['c', 'a'], ['c', 't'], ['a', 'c'], ['a', 't'], ['t', 'c'], ['t', 'a']] :: @@ -5487,14 +5503,16 @@ class Permutations(UniqueRepresentation, Parent): :: sage: p = Permutations(bruhat_smaller=[1,3,2,4]); p - Standard permutations that are less than or equal to [1, 3, 2, 4] in the Bruhat order + Standard permutations that are less than or equal + to [1, 3, 2, 4] in the Bruhat order sage: p.list() [[1, 2, 3, 4], [1, 3, 2, 4]] :: sage: p = Permutations(bruhat_greater=[4,2,3,1]); p - Standard permutations that are greater than or equal to [4, 2, 3, 1] in the Bruhat order + Standard permutations that are greater than or equal + to [4, 2, 3, 1] in the Bruhat order sage: p.list() [[4, 2, 3, 1], [4, 3, 2, 1]] @@ -5892,14 +5910,14 @@ class Permutations_mset(Permutations): [2, 2, 1, 1, 2], [2, 2, 1, 2, 1], [2, 2, 2, 1, 1]] - sage: MS = MatrixSpace(GF(2),2,2) - sage: A = MS([1,0,1,1]) - sage: rows = A.rows() - sage: rows[0].set_immutable() - sage: rows[1].set_immutable() - sage: P = Permutations_mset(rows); P + sage: MS = MatrixSpace(GF(2), 2, 2) # optional - sage.modules sage.rings.finite_rings + sage: A = MS([1,0,1,1]) # optional - sage.modules sage.rings.finite_rings + sage: rows = A.rows() # optional - sage.modules sage.rings.finite_rings + sage: rows[0].set_immutable() # optional - sage.modules sage.rings.finite_rings + sage: rows[1].set_immutable() # optional - sage.modules sage.rings.finite_rings + sage: P = Permutations_mset(rows); P # optional - sage.modules sage.rings.finite_rings Permutations of the multi-set [(1, 0), (1, 1)] - sage: sorted(P) + sage: sorted(P) # optional - sage.modules sage.rings.finite_rings [[(1, 0), (1, 1)], [(1, 1), (1, 0)]] """ @staticmethod @@ -6442,7 +6460,7 @@ def _repr_(self): """ TESTS:: - sage: Permutations([1,2,2],2) + sage: Permutations([1,2,2], 2) Permutations of the multi-set [1, 2, 2] of length 2 """ return "Permutations of the multi-set %s of length %s" % (list(self.mset), self._k) @@ -6453,7 +6471,7 @@ def cardinality(self): EXAMPLES:: - sage: Permutations([1,2,2],2).cardinality() + sage: Permutations([1,2,2], 2).cardinality() # optional - sage.libs.gap 3 """ return ZZ.sum(1 for z in self) @@ -6462,7 +6480,7 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations([1,2,2],2).list() + sage: Permutations([1,2,2], 2).list() # optional - sage.libs.gap [[1, 2], [2, 1], [2, 2]] """ mset = self.mset @@ -6571,7 +6589,7 @@ class Arrangements(Permutations): EXAMPLES:: sage: mset = [1,1,2,3,4,4,5] - sage: Arrangements(mset,2).list() + sage: Arrangements(mset, 2).list() # optional - sage.libs.gap [[1, 1], [1, 2], [1, 3], @@ -6594,11 +6612,11 @@ class Arrangements(Permutations): [5, 2], [5, 3], [5, 4]] - sage: Arrangements(mset,2).cardinality() + sage: Arrangements(mset, 2).cardinality() # optional - sage.libs.gap 22 - sage: Arrangements( ["c","a","t"], 2 ).list() + sage: Arrangements( ["c","a","t"], 2 ).list() # optional - sage.libs.gap [['c', 'a'], ['c', 't'], ['a', 'c'], ['a', 't'], ['t', 'c'], ['t', 'a']] - sage: Arrangements( ["c","a","t"], 3 ).list() + sage: Arrangements( ["c","a","t"], 3 ).list() # optional - sage.libs.gap [['c', 'a', 't'], ['c', 't', 'a'], ['a', 'c', 't'], @@ -6630,7 +6648,7 @@ def cardinality(self): EXAMPLES:: sage: A = Arrangements([1,1,2,3,4,4,5], 2) - sage: A.cardinality() + sage: A.cardinality() # optional - sage.libs.gap 22 """ one = ZZ.one() @@ -6901,20 +6919,20 @@ def _coerce_map_from_(self, G): EXAMPLES:: sage: P = Permutations(6) - sage: P.has_coerce_map_from(SymmetricGroup(6)) + sage: P.has_coerce_map_from(SymmetricGroup(6)) # optional - sage.groups True - sage: P.has_coerce_map_from(SymmetricGroup(5)) + sage: P.has_coerce_map_from(SymmetricGroup(5)) # optional - sage.groups True - sage: P.has_coerce_map_from(SymmetricGroup(7)) + sage: P.has_coerce_map_from(SymmetricGroup(7)) # optional - sage.groups False sage: P.has_coerce_map_from(Permutations(5)) True sage: P.has_coerce_map_from(Permutations(7)) False - sage: P.has_coerce_map_from(groups.misc.Cactus(5)) + sage: P.has_coerce_map_from(groups.misc.Cactus(5)) # optional - sage.groups True - sage: P.has_coerce_map_from(groups.misc.Cactus(7)) + sage: P.has_coerce_map_from(groups.misc.Cactus(7)) # optional - sage.groups False """ if isinstance(G, SymmetricGroup): @@ -6936,9 +6954,9 @@ def _from_permutation_group_element(self, x): TESTS:: sage: P = Permutations(4) - sage: G = SymmetricGroup(4) - sage: x = G([4,3,1,2]) - sage: P._from_permutation_group_element(x) + sage: G = SymmetricGroup(4) # optional - sage.groups + sage: x = G([4,3,1,2]) # optional - sage.groups + sage: P._from_permutation_group_element(x) # optional - sage.groups [4, 3, 1, 2] """ return self(x.domain()) @@ -6949,11 +6967,11 @@ def _from_cactus_group_element(self, x): EXAMPLES:: - sage: J3 = groups.misc.Cactus(3) - sage: s12,s13,s23 = J3.gens() - sage: elt = s12 * s23 * s13 - sage: P5 = Permutations(5) - sage: P5._from_cactus_group_element(elt) + sage: J3 = groups.misc.Cactus(3) # optional - sage.groups + sage: s12,s13,s23 = J3.gens() # optional - sage.groups + sage: elt = s12 * s23 * s13 # optional - sage.groups + sage: P5 = Permutations(5) # optional - sage.groups + sage: P5._from_cactus_group_element(elt) # optional - sage.groups [1, 3, 2, 4, 5] """ return self(x.to_permutation()) @@ -6965,12 +6983,11 @@ def as_permutation_group(self): EXAMPLES:: sage: P = Permutations(4) - sage: PG = P.as_permutation_group() - sage: PG + sage: PG = P.as_permutation_group(); PG # optional - sage.groups Symmetric group of order 4! as a permutation group - sage: G = SymmetricGroup(4) - sage: PG is G + sage: G = SymmetricGroup(4) # optional - sage.groups + sage: PG is G # optional - sage.groups True """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -7119,7 +7136,7 @@ def element_in_conjugacy_classes(self, nu): EXAMPLES:: sage: PP = Permutations(5) - sage: PP.element_in_conjugacy_classes([2,2]) + sage: PP.element_in_conjugacy_classes([2,2]) # optional - sage.combinat [2, 1, 4, 3, 5] """ from sage.combinat.partition import Partition @@ -7151,7 +7168,7 @@ def conjugacy_classes_representatives(self): EXAMPLES:: sage: G = Permutations(5) - sage: G.conjugacy_classes_representatives() + sage: G.conjugacy_classes_representatives() # optional - sage.combinat [[1, 2, 3, 4, 5], [2, 1, 3, 4, 5], [2, 1, 4, 3, 5], @@ -7165,10 +7182,10 @@ def conjugacy_classes_representatives(self): Check some border cases:: sage: S = Permutations(0) - sage: S.conjugacy_classes_representatives() + sage: S.conjugacy_classes_representatives() # optional - sage.combinat [[]] sage: S = Permutations(1) - sage: S.conjugacy_classes_representatives() + sage: S.conjugacy_classes_representatives() # optional - sage.combinat [[1]] """ from sage.combinat.partition import Partitions_n @@ -7182,7 +7199,7 @@ def conjugacy_classes_iterator(self): EXAMPLES:: sage: G = Permutations(4) - sage: list(G.conjugacy_classes_iterator()) == G.conjugacy_classes() + sage: list(G.conjugacy_classes_iterator()) == G.conjugacy_classes() # optional - sage.combinat True """ from sage.combinat.partition import Partitions_n @@ -7197,7 +7214,7 @@ def conjugacy_classes(self): EXAMPLES:: sage: G = Permutations(4) - sage: G.conjugacy_classes() + sage: G.conjugacy_classes() # optional - sage.combinat [Conjugacy class of cycle type [1, 1, 1, 1] in Standard permutations of 4, Conjugacy class of cycle type [2, 1, 1] in Standard permutations of 4, Conjugacy class of cycle type [2, 2] in Standard permutations of 4, @@ -7218,9 +7235,9 @@ def conjugacy_class(self, g): sage: G = Permutations(5) sage: g = G([2,3,4,1,5]) - sage: G.conjugacy_class(g) + sage: G.conjugacy_class(g) # optional - sage.combinat Conjugacy class of cycle type [4, 1] in Standard permutations of 5 - sage: G.conjugacy_class(Partition([2, 1, 1, 1])) + sage: G.conjugacy_class(Partition([2, 1, 1, 1])) # optional - sage.combinat Conjugacy class of cycle type [2, 1, 1, 1] in Standard permutations of 5 """ from sage.groups.perm_gps.symgp_conjugacy_class import PermutationsConjugacyClass @@ -7238,15 +7255,16 @@ def algebra(self, base_ring, category=None): EXAMPLES:: sage: P = Permutations(4) - sage: A = P.algebra(QQ); A + sage: A = P.algebra(QQ); A # optional - sage.combinat sage.modules Symmetric group algebra of order 4 over Rational Field - sage: A.category() + sage: A.category() # optional - sage.combinat sage.modules Join of Category of coxeter group algebras over Rational Field and Category of finite group algebras over Rational Field - and Category of finite dimensional cellular algebras with basis over Rational Field - sage: A = P.algebra(QQ, category=Monoids()) - sage: A.category() + and Category of finite dimensional cellular algebras + with basis over Rational Field + sage: A = P.algebra(QQ, category=Monoids()) # optional - sage.combinat sage.modules + sage: A.category() # optional - sage.combinat sage.modules Category of finite dimensional cellular monoid algebras over Rational Field """ from sage.combinat.symmetric_group_algebra import SymmetricGroupAlgebra @@ -7275,9 +7293,9 @@ def cartan_type(self): EXAMPLES:: - sage: A = SymmetricGroup([2,3,7]); A.cartan_type() + sage: A = SymmetricGroup([2,3,7]); A.cartan_type() # optional - sage.combinat sage.groups ['A', 2] - sage: A = SymmetricGroup([]); A.cartan_type() + sage: A = SymmetricGroup([]); A.cartan_type() # optional - sage.combinat sage.groups ['A', 0] """ from sage.combinat.root_system.cartan_type import CartanType @@ -7542,8 +7560,8 @@ def from_permutation_group_element(pge, parent=None): EXAMPLES:: sage: import sage.combinat.permutation as permutation - sage: pge = PermutationGroupElement([(1,2),(3,4)]) - sage: permutation.from_permutation_group_element(pge) + sage: pge = PermutationGroupElement([(1,2),(3,4)]) # optional - sage.groups + sage: permutation.from_permutation_group_element(pge) # optional - sage.groups [2, 1, 4, 3] """ if not isinstance(pge, PermutationGroupElement): @@ -7852,25 +7870,26 @@ def bistochastic_as_sum_of_permutations(M, check = True): sage: L.append((6,Permutation([5, 3, 4, 1, 2]))) sage: L.append((3,Permutation([3, 1, 4, 2, 5]))) sage: L.append((2,Permutation([1, 4, 2, 3, 5]))) - sage: M = sum([c * p.to_matrix() for (c,p) in L]) - sage: decomp = bistochastic_as_sum_of_permutations(M) - sage: print(decomp) - 2*B[[1, 4, 2, 3, 5]] + 3*B[[3, 1, 4, 2, 5]] + 9*B[[4, 1, 3, 5, 2]] + 6*B[[5, 3, 4, 1, 2]] + sage: M = sum([c * p.to_matrix() for (c,p) in L]) # optional - sage.modules + sage: decomp = bistochastic_as_sum_of_permutations(M) # optional - sage.graphs sage.modules + sage: print(decomp) # optional - sage.graphs sage.modules + 2*B[[1, 4, 2, 3, 5]] + 3*B[[3, 1, 4, 2, 5]] + + 9*B[[4, 1, 3, 5, 2]] + 6*B[[5, 3, 4, 1, 2]] An exception is raised when the matrix is not positive and bistochastic:: sage: M = Matrix([[2,3],[2,2]]) - sage: decomp = bistochastic_as_sum_of_permutations(M) + sage: decomp = bistochastic_as_sum_of_permutations(M) # optional - sage.graphs sage.modules Traceback (most recent call last): ... ValueError: The matrix is not bistochastic - sage: bistochastic_as_sum_of_permutations(Matrix(GF(7), 2, [2,1,1,2])) + sage: bistochastic_as_sum_of_permutations(Matrix(GF(7), 2, [2,1,1,2])) # optional - sage.graphs sage.modules sage.rings.finite_rings Traceback (most recent call last): ... ValueError: The base ring of the matrix must have a coercion map to RR - sage: bistochastic_as_sum_of_permutations(Matrix(ZZ, 2, [2,-1,-1,2])) + sage: bistochastic_as_sum_of_permutations(Matrix(ZZ, 2, [2,-1,-1,2])) # optional - sage.graphs sage.modules Traceback (most recent call last): ... ValueError: The matrix should have nonnegative entries @@ -7937,12 +7956,12 @@ def bounded_affine_permutation(A): EXAMPLES:: sage: from sage.combinat.permutation import bounded_affine_permutation - sage: A = Matrix(ZZ, [[1,0,0,0], [0,1,0,0]]) - sage: bounded_affine_permutation(A) + sage: A = Matrix(ZZ, [[1,0,0,0], [0,1,0,0]]) # optional - sage.modules + sage: bounded_affine_permutation(A) # optional - sage.modules [5, 6, 3, 4] - sage: A = Matrix(ZZ, [[0,1,0,1,0], [0,0,1,1,0]]) - sage: bounded_affine_permutation(A) + sage: A = Matrix(ZZ, [[0,1,0,1,0], [0,0,1,1,0]]) # optional - sage.modules + sage: bounded_affine_permutation(A) # optional - sage.modules [1, 4, 7, 8, 5] REFERENCES: From 429577ded5e60bad3543f9d30f23ce343303a509 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Tue, 25 Apr 2023 22:56:36 -0700 Subject: [PATCH 049/228] sage.combinat: More # optional --- src/sage/combinat/combinat.py | 20 +-- src/sage/combinat/composition.py | 2 +- src/sage/combinat/permutation.py | 265 ++++++++++++++++--------------- src/sage/combinat/subset.py | 22 +-- 4 files changed, 156 insertions(+), 153 deletions(-) diff --git a/src/sage/combinat/combinat.py b/src/sage/combinat/combinat.py index c4128a176b8..22a314d2636 100644 --- a/src/sage/combinat/combinat.py +++ b/src/sage/combinat/combinat.py @@ -364,9 +364,9 @@ def bell_number(n, algorithm='flint', **options) -> Integer: TESTS:: - sage: all(bell_number(n) == bell_number(n,'dobinski') for n in range(100)) + sage: all(bell_number(n) == bell_number(n,'dobinski') for n in range(100)) # optional - sage.libs.flint True - sage: all(bell_number(n) == bell_number(n,'gap') for n in range(100)) # optional - sage.libs.gap + sage: all(bell_number(n) == bell_number(n,'gap') for n in range(100)) # optional - sage.libs.flint sage.libs.gap True sage: all(bell_number(n) == bell_number(n,'mpmath', prec=500) # optional - mpmath sage.libs.flint ....: for n in range(200, 220)) @@ -551,7 +551,7 @@ def euler_number(n, algorithm='flint') -> Integer: sage: [euler_number(i) for i in range(10)] # optional - sage.libs.flint [1, 0, -1, 0, 5, 0, -61, 0, 1385, 0] sage: x = PowerSeriesRing(QQ, 'x').gen().O(10) - sage: 2/(exp(x)+exp(-x)) + sage: 2/(exp(x)+exp(-x)) # optional - sage.symbolic 1 - 1/2*x^2 + 5/24*x^4 - 61/720*x^6 + 277/8064*x^8 + O(x^10) sage: [euler_number(i)/factorial(i) for i in range(11)] # optional - sage.libs.flint [1, 0, -1/2, 0, 5/24, 0, -61/720, 0, 277/8064, 0, -50521/3628800] @@ -1512,12 +1512,12 @@ class CombinatorialElement(CombinatorialObject, Element, EXAMPLES:: sage: from sage.combinat.combinat import CombinatorialElement - sage: e = CombinatorialElement(Partitions(6), [3,2,1]) - sage: e == loads(dumps(e)) + sage: e = CombinatorialElement(Partitions(6), [3,2,1]) # optional - sage.combinat + sage: e == loads(dumps(e)) # optional - sage.combinat True - sage: parent(e) + sage: parent(e) # optional - sage.combinat Partitions of the integer 6 - sage: list(e) + sage: list(e) # optional - sage.combinat [3, 2, 1] Check classcalls:: @@ -2225,9 +2225,9 @@ def __contains__(self, x) -> bool: False sage: [4,3,2,1] in P False - sage: Permutation([1,2,3]) in P + sage: Permutation([1,2,3]) in P # optional - sage.combinat False - sage: Permutation([3,2,1]) in P + sage: Permutation([3,2,1]) in P # optional - sage.combinat True """ return x in self.combinatorial_class and self.f(x) @@ -2495,7 +2495,7 @@ def __init__(self, cc, f, name=None, *, is_injective=True): """ TESTS:: - sage: Partitions(3).map(attrcall('conjugate')) + sage: Partitions(3).map(attrcall('conjugate')) # optional - sage.combinat Image of Partitions of the integer 3 by The map *.conjugate() from Partitions of the integer 3 """ diff --git a/src/sage/combinat/composition.py b/src/sage/combinat/composition.py index 50f1ee26780..3b6d51a1b6e 100644 --- a/src/sage/combinat/composition.py +++ b/src/sage/combinat/composition.py @@ -1303,7 +1303,7 @@ def shuffle_product(self, other, overlap=False): TESTS:: sage: empty = Composition([]) - sage: empty.shuffle_product(empty).list() + sage: empty.shuffle_product(empty).list() # optional - sage.combinat [[]] """ if overlap: diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index de92bc8acf7..465045b15d4 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -390,8 +390,8 @@ class Permutation(CombinatorialElement): We construct a :class:`Permutation` from a :class:`PermutationGroupElement`:: - sage: g = PermutationGroupElement([2,1,3]) - sage: Permutation(g) + sage: g = PermutationGroupElement([2,1,3]) # optional - sage.groups + sage: Permutation(g) # optional - sage.groups [2, 1, 3] From a pair of tableaux of the same shape. This uses the inverse @@ -399,15 +399,15 @@ class Permutation(CombinatorialElement): sage: p = [[1, 4, 7], [2, 5], [3], [6]] sage: q = [[1, 2, 5], [3, 6], [4], [7]] - sage: P = Tableau(p) - sage: Q = Tableau(q) - sage: Permutation( (p, q) ) + sage: P = Tableau(p) # optional - sage.combinat + sage: Q = Tableau(q) # optional - sage.combinat + sage: Permutation( (p, q) ) # optional - sage.combinat [3, 6, 5, 2, 7, 4, 1] - sage: Permutation( [p, q] ) + sage: Permutation( [p, q] ) # optional - sage.combinat [3, 6, 5, 2, 7, 4, 1] - sage: Permutation( (P, Q) ) + sage: Permutation( (P, Q) ) # optional - sage.combinat [3, 6, 5, 2, 7, 4, 1] - sage: Permutation( [P, Q] ) + sage: Permutation( [P, Q] ) # optional - sage.combinat [3, 6, 5, 2, 7, 4, 1] TESTS:: @@ -423,9 +423,9 @@ class Permutation(CombinatorialElement): From a pair of empty tableaux :: - sage: Permutation( ([], []) ) + sage: Permutation( ([], []) ) # optional - sage.combinat [] - sage: Permutation( [[], []] ) + sage: Permutation( [[], []] ) # optional - sage.combinat [] """ @staticmethod @@ -697,11 +697,11 @@ def _gap_(self, gap): EXAMPLES:: - sage: gap(Permutation([1,2,3])) + sage: gap(Permutation([1,2,3])) # optional - sage.libs.gap () - sage: gap(Permutation((1,2,3))) + sage: gap(Permutation((1,2,3))) # optional - sage.libs.gap (1,2,3) - sage: type(_) + sage: type(_) # optional - sage.libs.gap <class 'sage.interfaces.gap.GapElement'> """ return self.to_permutation_group_element()._gap_(gap) @@ -865,9 +865,9 @@ def to_tableau_by_shape(self, shape): EXAMPLES:: - sage: Permutation([3,4,1,2,5]).to_tableau_by_shape([3,2]) + sage: T = Permutation([3,4,1,2,5]).to_tableau_by_shape([3,2]); T # optional - sage.combinat [[1, 2, 5], [3, 4]] - sage: Permutation([3,4,1,2,5]).to_tableau_by_shape([3,2]).reading_word_permutation() + sage: T.reading_word_permutation() # optional - sage.combinat [3, 4, 1, 2, 5] """ import sage.combinat.tableau as tableau @@ -1137,9 +1137,9 @@ def to_permutation_group_element(self): EXAMPLES:: - sage: Permutation([2,1,4,3]).to_permutation_group_element() + sage: Permutation([2,1,4,3]).to_permutation_group_element() # optional - sage.groups (1,2)(3,4) - sage: Permutation([1,2,3]).to_permutation_group_element() + sage: Permutation([1,2,3]).to_permutation_group_element() # optional - sage.groups () """ grp = SymmetricGroup(len(self)) @@ -1721,15 +1721,16 @@ def show(self, representation="cycles", orientation="landscape", **args): EXAMPLES:: - sage: Permutations(20).random_element().show(representation="cycles") - sage: Permutations(20).random_element().show(representation="chord-diagram") - sage: Permutations(20).random_element().show(representation="braid") - sage: Permutations(20).random_element().show(representation="braid", - ....: orientation='portrait') + sage: P20 = Permutations(20) + sage: P20.random_element().show(representation="cycles") # optional - sage.graphs + sage: P20.random_element().show(representation="chord-diagram") # optional - sage.graphs + sage: P20.random_element().show(representation="braid") # optional - sage.plot + sage: P20.random_element().show(representation="braid", # optional - sage.plot + ....: orientation='portrait') TESTS:: - sage: Permutations(20).random_element().show(representation="modern_art") + sage: P20.random_element().show(representation="modern_art") Traceback (most recent call last): ... ValueError: The value of 'representation' must be equal to 'cycles', 'chord-diagram' or 'braid' @@ -1908,7 +1909,7 @@ def absolute_length(self) -> Integer: EXAMPLES:: - sage: Permutation([4,2,3,1]).absolute_length() + sage: Permutation([4,2,3,1]).absolute_length() # optional - sage.combinat 1 """ return self.size() - len(self.cycle_type()) @@ -2217,7 +2218,8 @@ def longest_increasing_subsequence_length(self) -> Integer: sage: Permutation([2,3,1,4]).longest_increasing_subsequence_length() 3 - sage: all(i.longest_increasing_subsequence_length() == len(RSK(i)[0][0]) for i in Permutations(5)) + sage: all(i.longest_increasing_subsequence_length() == len(RSK(i)[0][0]) # optional - sage.combinat + ....: for i in Permutations(5)) True sage: Permutation([]).longest_increasing_subsequence_length() 0 @@ -2415,9 +2417,9 @@ def forget_cycles(self): results as a poset under the Bruhat order:: sage: l = [p.forget_cycles().inverse() for p in l] - sage: B = Poset([l, lambda x,y: x.bruhat_lequal(y)]) + sage: B = Poset([l, lambda x,y: x.bruhat_lequal(y)]) # optional - sage.combinat sage.graphs sage: R.<q> = QQ[] - sage: sum(q^B.rank_function()(x) for x in B) + sage: sum(q^B.rank_function()(x) for x in B) # optional - sage.combinat sage.graphs q^5 + 2*q^4 + 3*q^3 + 3*q^2 + 2*q + 1 We check the statement in [CC2013]_ that the posets @@ -2425,8 +2427,8 @@ def forget_cycles(self): sage: l2 = [p for p in P if [len(t) for t in p.to_cycles()] == [1,3,1,1]] sage: l2 = [p.forget_cycles().inverse() for p in l2] - sage: B2 = Poset([l2, lambda x,y: x.bruhat_lequal(y)]) - sage: B.is_isomorphic(B2) + sage: B2 = Poset([l2, lambda x,y: x.bruhat_lequal(y)]) # optional - sage.combinat sage.graphs + sage: B.is_isomorphic(B2) # optional - sage.combinat sage.graphs True .. SEEALSO:: @@ -2737,7 +2739,7 @@ def destandardize(self, weight, ordered_alphabet=None): - ``weight`` -- list or tuple of nonnegative integers that sum to `n` if ``self`` is a permutation in `S_n`. - - ``ordered_alphabet`` -- (default: None) a list or tuple specifying the ordered alphabet the + - ``ordered_alphabet`` -- (default: ``None``) a list or tuple specifying the ordered alphabet the destandardized word is over OUTPUT: word over the ``ordered_alphabet`` which standardizes to ``self`` @@ -2752,7 +2754,7 @@ def destandardize(self, weight, ordered_alphabet=None): EXAMPLES:: sage: p = Permutation([1,2,5,3,6,4]) - sage: p.destandardize([3,1,2]) + sage: p.destandardize([3,1,2]) # optional - sage.combinat word: 113132 sage: p = Permutation([2,1,3]) sage: p.destandardize([2,1]) @@ -2763,7 +2765,7 @@ def destandardize(self, weight, ordered_alphabet=None): TESTS:: sage: p = Permutation([4,1,2,3,5,6]) - sage: p.destandardize([2,1,3], ordered_alphabet = [1,'a',3]) + sage: p.destandardize([2,1,3], ordered_alphabet = [1,'a',3]) # optional - sage.combinat word: 311a33 sage: p.destandardize([2,1,3], ordered_alphabet = [1,'a']) Traceback (most recent call last): @@ -5490,14 +5492,14 @@ class Permutations(UniqueRepresentation, Parent): sage: p = Permutations([1,1,2], 2); p Permutations of the multi-set [1, 1, 2] of length 2 - sage: p.list() + sage: p.list() # optional - sage.libs.gap [[1, 1], [1, 2], [2, 1]] :: sage: p = Permutations(descents=([1], 4)); p Standard permutations of 4 with descents [1] - sage: p.list() + sage: p.list() # optional - sage.graphs [[2, 4, 1, 3], [3, 4, 1, 2], [1, 4, 2, 3], [1, 3, 2, 4], [2, 3, 1, 4]] :: @@ -5520,28 +5522,28 @@ class Permutations(UniqueRepresentation, Parent): sage: p = Permutations(recoils_finer=[2,1]); p Standard permutations whose recoils composition is finer than [2, 1] - sage: p.list() + sage: p.list() # optional - sage.graphs [[3, 1, 2], [1, 2, 3], [1, 3, 2]] :: sage: p = Permutations(recoils_fatter=[2,1]); p Standard permutations whose recoils composition is fatter than [2, 1] - sage: p.list() + sage: p.list() # optional - sage.graphs [[3, 1, 2], [3, 2, 1], [1, 3, 2]] :: sage: p = Permutations(recoils=[2,1]); p Standard permutations whose recoils composition is [2, 1] - sage: p.list() + sage: p.list() # optional - sage.graphs [[3, 1, 2], [1, 3, 2]] :: sage: p = Permutations(4, avoiding=[1,3,2]); p Standard permutations of 4 avoiding [[1, 3, 2]] - sage: p.list() + sage: p.list() # optional - sage.combinat [[4, 1, 2, 3], [4, 2, 1, 3], [4, 2, 3, 1], @@ -5561,9 +5563,9 @@ class Permutations(UniqueRepresentation, Parent): sage: p = Permutations(5, avoiding=[[3,4,1,2], [4,2,3,1]]); p Standard permutations of 5 avoiding [[3, 4, 1, 2], [4, 2, 3, 1]] - sage: p.cardinality() + sage: p.cardinality() # optional - sage.combinat 88 - sage: p.random_element().parent() is p + sage: p.random_element().parent() is p # optional - sage.combinat True """ @staticmethod @@ -6427,7 +6429,7 @@ def __init__(self, mset, k): TESTS:: sage: P = Permutations([1,2,2],2) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.libs.gap """ Permutations_mset.__init__(self, mset) self._k = k @@ -6814,21 +6816,21 @@ def _element_constructor_(self, x, check=True): sage: P([2,3,1]) [2, 3, 1, 4, 5] - sage: G = SymmetricGroup(4) + sage: G = SymmetricGroup(4) # optional - sage.groups sage: P = Permutations(4) - sage: x = G([4,3,1,2]); x + sage: x = G([4,3,1,2]); x # optional - sage.groups (1,4,2,3) - sage: P(x) + sage: P(x) # optional - sage.groups [4, 3, 1, 2] - sage: G(P(x)) + sage: G(P(x)) # optional - sage.groups (1,4,2,3) - sage: P = PermutationGroup([[(1,3,5),(2,4)],[(1,3)]]) - sage: x = P([(3,5),(2,4)]); x + sage: P = PermutationGroup([[(1,3,5),(2,4)],[(1,3)]]) # optional - sage.groups + sage: x = P([(3,5),(2,4)]); x # optional - sage.groups (2,4)(3,5) - sage: Permutations(6)(SymmetricGroup(6)(x)) + sage: Permutations(6)(SymmetricGroup(6)(x)) # optional - sage.groups [1, 4, 5, 2, 3, 6] - sage: Permutations(6)(x) # known bug + sage: Permutations(6)(x) # known bug # optional - sage.groups [1, 4, 5, 2, 3, 6] """ if len(x) < self.n: @@ -7878,7 +7880,7 @@ def bistochastic_as_sum_of_permutations(M, check = True): An exception is raised when the matrix is not positive and bistochastic:: - sage: M = Matrix([[2,3],[2,2]]) + sage: M = Matrix([[2,3],[2,2]]) # optional - sage.modules sage: decomp = bistochastic_as_sum_of_permutations(M) # optional - sage.graphs sage.modules Traceback (most recent call last): ... @@ -8021,7 +8023,7 @@ def __init__(self, d, n): TESTS:: sage: P = Permutations(descents=([1,0,2], 5)) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.graphs """ StandardPermutations_n_abstract.__init__(self, n) self._d = d @@ -8123,7 +8125,7 @@ def __iter__(self): EXAMPLES:: - sage: Permutations(descents=([2,0],5)).list() + sage: Permutations(descents=([2,0],5)).list() # optional - sage.graphs [[5, 2, 4, 1, 3], [5, 3, 4, 1, 2], [4, 3, 5, 1, 2], @@ -8152,7 +8154,7 @@ def descents_composition_list(dc): EXAMPLES:: sage: import sage.combinat.permutation as permutation - sage: permutation.descents_composition_list([1,2,2]) + sage: permutation.descents_composition_list([1,2,2]) # optional - sage.graphs [[5, 2, 4, 1, 3], [5, 3, 4, 1, 2], [4, 3, 5, 1, 2], @@ -8245,7 +8247,7 @@ def __init__(self, recoils): TESTS:: sage: P = Permutations(recoils_finer=[2,2]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.graphs """ Permutations.__init__(self, category=FiniteEnumeratedSets()) self.recoils = recoils @@ -8266,7 +8268,7 @@ def __iter__(self): EXAMPLES:: - sage: Permutations(recoils_finer=[2,2]).list() + sage: Permutations(recoils_finer=[2,2]).list() # optional - sage.graphs [[3, 1, 4, 2], [3, 4, 1, 2], [1, 3, 4, 2], @@ -8313,7 +8315,7 @@ def __init__(self, recoils): TESTS:: sage: P = Permutations(recoils_fatter=[2,2]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.graphs """ Permutations.__init__(self, category=FiniteEnumeratedSets()) self.recoils = recoils @@ -8334,7 +8336,7 @@ def __iter__(self): EXAMPLES:: - sage: Permutations(recoils_fatter=[2,2]).list() + sage: Permutations(recoils_fatter=[2,2]).list() # optional - sage.graphs [[4, 3, 2, 1], [3, 2, 1, 4], [3, 2, 4, 1], @@ -8388,7 +8390,7 @@ def __init__(self, recoils): TESTS:: sage: P = Permutations(recoils=[2,2]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.graphs """ Permutations.__init__(self, category=FiniteEnumeratedSets()) self.recoils = recoils @@ -8409,7 +8411,7 @@ def __iter__(self): EXAMPLES:: - sage: Permutations(recoils=[2,2]).list() + sage: Permutations(recoils=[2,2]).list() # optional - sage.graphs [[3, 1, 4, 2], [3, 4, 1, 2], [1, 3, 4, 2], [1, 3, 2, 4], [3, 1, 2, 4]] """ recoils = self.recoils @@ -8717,15 +8719,15 @@ def to_standard(p, key=None): EXAMPLES:: sage: import sage.combinat.permutation as permutation - sage: permutation.to_standard([4,2,7]) + sage: permutation.to_standard([4,2,7]) # optional - sage.combinat [2, 1, 3] - sage: permutation.to_standard([1,2,3]) + sage: permutation.to_standard([1,2,3]) # optional - sage.combinat [1, 2, 3] - sage: permutation.to_standard([]) + sage: permutation.to_standard([]) # optional - sage.combinat [] - sage: permutation.to_standard([1,2,3], key=lambda x: -x) + sage: permutation.to_standard([1,2,3], key=lambda x: -x) # optional - sage.combinat [3, 2, 1] - sage: permutation.to_standard([5,8,2,5], key=lambda x: -x) + sage: permutation.to_standard([5,8,2,5], key=lambda x: -x) # optional - sage.combinat [2, 1, 4, 3] TESTS: @@ -8733,7 +8735,7 @@ def to_standard(p, key=None): Does not mutate the list:: sage: a = [1,2,4] - sage: permutation.to_standard(a) + sage: permutation.to_standard(a) # optional - sage.combinat [1, 2, 3] sage: a [1, 2, 4] @@ -8752,8 +8754,8 @@ def to_standard(p, key=None): ....: i += 1 ....: c[smallest_index] = biggest ....: return Permutations()(s) - sage: p = list(Words(100, 1000).random_element()) - sage: std(p) == permutation.to_standard(p) + sage: p = list(Words(100, 1000).random_element()) # optional - sage.combinat + sage: std(p) == permutation.to_standard(p) # optional - sage.combinat True """ ev_dict = evaluation_dict(p) @@ -8783,14 +8785,14 @@ class CyclicPermutations(Permutations_mset): EXAMPLES:: - sage: CyclicPermutations(range(4)).list() + sage: CyclicPermutations(range(4)).list() # optional - sage.combinat [[0, 1, 2, 3], [0, 1, 3, 2], [0, 2, 1, 3], [0, 2, 3, 1], [0, 3, 1, 2], [0, 3, 2, 1]] - sage: CyclicPermutations([1,1,1]).list() + sage: CyclicPermutations([1,1,1]).list() # optional - sage.combinat [[1, 1, 1]] """ @staticmethod @@ -8825,16 +8827,16 @@ def __iter__(self, distinct=False): """ EXAMPLES:: - sage: CyclicPermutations(range(4)).list() # indirect doctest + sage: CyclicPermutations(range(4)).list() # indirect doctest # optional - sage.combinat [[0, 1, 2, 3], [0, 1, 3, 2], [0, 2, 1, 3], [0, 2, 3, 1], [0, 3, 1, 2], [0, 3, 2, 1]] - sage: CyclicPermutations([1,1,1]).list() + sage: CyclicPermutations([1,1,1]).list() # optional - sage.combinat [[1, 1, 1]] - sage: CyclicPermutations([1,1,1]).list(distinct=True) + sage: CyclicPermutations([1,1,1]).list(distinct=True) # optional - sage.combinat [[1, 1, 1], [1, 1, 1]] """ if distinct: @@ -8855,7 +8857,7 @@ def list(self, distinct=False): """ EXAMPLES:: - sage: CyclicPermutations(range(4)).list() + sage: CyclicPermutations(range(4)).list() # optional - sage.combinat [[0, 1, 2, 3], [0, 1, 3, 2], [0, 2, 1, 3], @@ -8876,7 +8878,7 @@ class CyclicPermutationsOfPartition(Permutations): EXAMPLES:: - sage: CyclicPermutationsOfPartition([[1,2,3,4],[5,6,7]]).list() + sage: CyclicPermutationsOfPartition([[1,2,3,4],[5,6,7]]).list() # optional - sage.combinat [[[1, 2, 3, 4], [5, 6, 7]], [[1, 2, 4, 3], [5, 6, 7]], [[1, 3, 2, 4], [5, 6, 7]], @@ -8892,7 +8894,7 @@ class CyclicPermutationsOfPartition(Permutations): :: - sage: CyclicPermutationsOfPartition([[1,2,3,4],[4,4,4]]).list() + sage: CyclicPermutationsOfPartition([[1,2,3,4],[4,4,4]]).list() # optional - sage.combinat [[[1, 2, 3, 4], [4, 4, 4]], [[1, 2, 4, 3], [4, 4, 4]], [[1, 3, 2, 4], [4, 4, 4]], @@ -8902,12 +8904,12 @@ class CyclicPermutationsOfPartition(Permutations): :: - sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list() + sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list() # optional - sage.combinat [[[1, 2, 3], [4, 4, 4]], [[1, 3, 2], [4, 4, 4]]] :: - sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list(distinct=True) + sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list(distinct=True) # optional - sage.combinat [[[1, 2, 3], [4, 4, 4]], [[1, 3, 2], [4, 4, 4]], [[1, 2, 3], [4, 4, 4]], @@ -8935,7 +8937,7 @@ def __init__(self, partition): sage: CP = CyclicPermutationsOfPartition([[1,2,3,4],[5,6,7]]) sage: CP Cyclic permutations of partition [[1, 2, 3, 4], [5, 6, 7]] - sage: TestSuite(CP).run() + sage: TestSuite(CP).run() # optional - sage.combinat """ self.partition = partition Permutations.__init__(self, category=FiniteEnumeratedSets()) @@ -8952,8 +8954,8 @@ def check(self): EXAMPLES:: sage: CP = CyclicPermutationsOfPartition([[1,2,3,4],[5,6,7]]) - sage: elt = CP[0] - sage: elt.check() + sage: elt = CP[0] # optional - sage.combinat + sage: elt.check() # optional - sage.combinat """ if [sorted(_) for _ in self] != [sorted(_) for _ in self.parent().partition]: raise ValueError("Invalid cyclic permutation of the partition" % self.parent().partition) @@ -8976,7 +8978,8 @@ def __iter__(self, distinct=False): EXAMPLES:: - sage: CyclicPermutationsOfPartition([[1,2,3,4],[5,6,7]]).list() # indirect doctest + sage: CyclicPermutationsOfPartition([[1,2,3,4], # indirect doctest # optional - sage.combinat + ....: [5,6,7]]).list() [[[1, 2, 3, 4], [5, 6, 7]], [[1, 2, 4, 3], [5, 6, 7]], [[1, 3, 2, 4], [5, 6, 7]], @@ -8992,7 +8995,7 @@ def __iter__(self, distinct=False): :: - sage: CyclicPermutationsOfPartition([[1,2,3,4],[4,4,4]]).list() + sage: CyclicPermutationsOfPartition([[1,2,3,4],[4,4,4]]).list() # optional - sage.combinat [[[1, 2, 3, 4], [4, 4, 4]], [[1, 2, 4, 3], [4, 4, 4]], [[1, 3, 2, 4], [4, 4, 4]], @@ -9002,12 +9005,12 @@ def __iter__(self, distinct=False): :: - sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list() + sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list() # optional - sage.combinat [[[1, 2, 3], [4, 4, 4]], [[1, 3, 2], [4, 4, 4]]] :: - sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list(distinct=True) + sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list(distinct=True) # optional - sage.combinat [[[1, 2, 3], [4, 4, 4]], [[1, 3, 2], [4, 4, 4]], [[1, 2, 3], [4, 4, 4]], @@ -9027,9 +9030,9 @@ def list(self, distinct=False): """ EXAMPLES:: - sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list() + sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list() # optional - sage.combinat [[[1, 2, 3], [4, 4, 4]], [[1, 3, 2], [4, 4, 4]]] - sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list(distinct=True) + sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list(distinct=True) # optional - sage.combinat [[[1, 2, 3], [4, 4, 4]], [[1, 3, 2], [4, 4, 4]], [[1, 2, 3], [4, 4, 4]], @@ -9065,7 +9068,7 @@ def __init__(self, a): TESTS:: sage: P = Permutations(avoiding=[[2,1,3],[1,2,3]]) - sage: TestSuite(P).run(max_runs=25) + sage: TestSuite(P).run(max_runs=25) # optional - sage.combinat """ Permutations.__init__(self, category=InfiniteEnumeratedSets()) self._a = a @@ -9095,13 +9098,13 @@ def __contains__(self, x): """ TESTS:: - sage: [1,3,2] in Permutations(avoiding=[1,3,2]) + sage: [1,3,2] in Permutations(avoiding=[1,3,2]) # optional - sage.combinat False - sage: [1,3,2] in Permutations(avoiding=[[1,3,2]]) + sage: [1,3,2] in Permutations(avoiding=[[1,3,2]]) # optional - sage.combinat False - sage: [2,1,3] in Permutations(avoiding=[[1,3,2],[1,2,3]]) + sage: [2,1,3] in Permutations(avoiding=[[1,3,2],[1,2,3]]) # optional - sage.combinat True - sage: [2,1,3] in Permutations(avoiding=[]) + sage: [2,1,3] in Permutations(avoiding=[]) # optional - sage.combinat True """ if not super().__contains__(x): @@ -9116,7 +9119,7 @@ def __iter__(self): TESTS:: sage: it = iter(Permutations(avoiding=[[2,1,3],[1,2,3]])) - sage: [next(it) for i in range(10)] + sage: [next(it) for i in range(10)] # optional - sage.combinat [[], [1], [1, 2], @@ -9161,7 +9164,7 @@ def __init__(self, n, a): EXAMPLES:: sage: P = Permutations(3, avoiding=[[2,1,3],[1,2,3]]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat sage: type(P) <class 'sage.combinat.permutation.StandardPermutations_avoiding_generic_with_category'> """ @@ -9202,13 +9205,13 @@ def __contains__(self, x): """ TESTS:: - sage: [1,3,2] in Permutations(3, avoiding=[1,3,2]) + sage: [1,3,2] in Permutations(3, avoiding=[1,3,2]) # optional - sage.combinat False - sage: [1,3,2] in Permutations(3, avoiding=[[1,3,2]]) + sage: [1,3,2] in Permutations(3, avoiding=[[1,3,2]]) # optional - sage.combinat False - sage: [2,1,3] in Permutations(3, avoiding=[[1,3,2],[1,2,3]]) + sage: [2,1,3] in Permutations(3, avoiding=[[1,3,2],[1,2,3]]) # optional - sage.combinat True - sage: [2,1,3] in Permutations(3, avoiding=[]) + sage: [2,1,3] in Permutations(3, avoiding=[]) # optional - sage.combinat True """ if not super().__contains__(x): @@ -9229,9 +9232,9 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[[2, 1, 3],[1,2,3]]).list() + sage: Permutations(3, avoiding=[[2, 1, 3],[1,2,3]]).list() # optional - sage.combinat [[1, 3, 2], [3, 1, 2], [2, 3, 1], [3, 2, 1]] - sage: Permutations(0, avoiding=[[2, 1, 3],[1,2,3]]).list() + sage: Permutations(0, avoiding=[[2, 1, 3],[1,2,3]]).list() # optional - sage.combinat [[]] """ if self.n > 0: @@ -9245,7 +9248,7 @@ def cardinality(self): EXAMPLES:: sage: P = Permutations(3, avoiding=[[2, 1, 3],[1,2,3]]) - sage: P.cardinality() + sage: P.cardinality() # optional - sage.combinat 4 """ one = ZZ.one() @@ -9258,7 +9261,7 @@ def __init__(self, n): TESTS:: sage: P = Permutations(3, avoiding=[1, 2]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat """ super().__init__(n, (Permutations()([1, 2]),)) @@ -9266,7 +9269,7 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[1,2]).list() + sage: Permutations(3, avoiding=[1,2]).list() # optional - sage.combinat [[3, 2, 1]] """ yield self.element_class(self, range(self.n, 0, -1), check=False) @@ -9278,7 +9281,7 @@ def cardinality(self): EXAMPLES:: sage: P = Permutations(3, avoiding=[1, 2]) - sage: P.cardinality() + sage: P.cardinality() # optional - sage.combinat 1 """ return ZZ.one() @@ -9290,7 +9293,7 @@ def __init__(self, n): TESTS:: sage: P = Permutations(3, avoiding=[2, 1]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat """ super().__init__(n, (Permutations()([2, 1]),)) @@ -9298,7 +9301,7 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[2,1]).list() + sage: Permutations(3, avoiding=[2,1]).list() # optional - sage.combinat [[1, 2, 3]] """ yield self.element_class(self, range(1, self.n+1), check=False) @@ -9310,7 +9313,7 @@ def cardinality(self): EXAMPLES:: sage: P = Permutations(3, avoiding=[2, 1]) - sage: P.cardinality() + sage: P.cardinality() # optional - sage.combinat 1 """ return ZZ.one() @@ -9322,7 +9325,7 @@ def __init__(self, n): TESTS:: sage: P = Permutations(3, avoiding=[1, 3, 2]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat """ super().__init__(n, (Permutations()([1, 3, 2]),)) @@ -9332,7 +9335,7 @@ def cardinality(self): sage: Permutations(5, avoiding=[1, 3, 2]).cardinality() 42 - sage: len( Permutations(5, avoiding=[1, 3, 2]).list() ) + sage: len( Permutations(5, avoiding=[1, 3, 2]).list() ) # optional - sage.combinat 42 """ return catalan_number(self.n) @@ -9341,9 +9344,9 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[1,3,2]).list() # indirect doctest + sage: Permutations(3, avoiding=[1,3,2]).list() # indirect doctest # optional - sage.combinat [[1, 2, 3], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] - sage: Permutations(4, avoiding=[1,3,2]).list() + sage: Permutations(4, avoiding=[1,3,2]).list() # optional - sage.combinat [[4, 1, 2, 3], [4, 2, 1, 3], [4, 2, 3, 1], @@ -9399,7 +9402,7 @@ def __init__(self, n): TESTS:: sage: P = Permutations(3, avoiding=[2, 1, 3]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat """ super().__init__(n, (Permutations()([1, 2, 3]),)) @@ -9407,9 +9410,9 @@ def cardinality(self) -> Integer: """ EXAMPLES:: - sage: Permutations(5, avoiding=[1, 2, 3]).cardinality() + sage: Permutations(5, avoiding=[1, 2, 3]).cardinality() # optional - sage.combinat 42 - sage: len( Permutations(5, avoiding=[1, 2, 3]).list() ) + sage: len( Permutations(5, avoiding=[1, 2, 3]).list() ) # optional - sage.combinat 42 """ return catalan_number(self.n) @@ -9418,11 +9421,11 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[1, 2, 3]).list() # indirect doctest + sage: Permutations(3, avoiding=[1, 2, 3]).list() # indirect doctest # optional - sage.combinat [[1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] - sage: Permutations(2, avoiding=[1, 2, 3]).list() + sage: Permutations(2, avoiding=[1, 2, 3]).list() # optional - sage.combinat [[1, 2], [2, 1]] - sage: Permutations(3, avoiding=[1, 2, 3]).list() + sage: Permutations(3, avoiding=[1, 2, 3]).list() # optional - sage.combinat [[1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] """ if self.n == 0: @@ -9471,7 +9474,7 @@ def __init__(self, n): TESTS:: sage: P = Permutations(3, avoiding=[3, 2, 1]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat """ super().__init__(n, (Permutations()([3, 2, 1]),)) @@ -9479,9 +9482,9 @@ def cardinality(self): """ EXAMPLES:: - sage: Permutations(5, avoiding=[3, 2, 1]).cardinality() + sage: Permutations(5, avoiding=[3, 2, 1]).cardinality() # optional - sage.combinat 42 - sage: len( Permutations(5, avoiding=[3, 2, 1]).list() ) + sage: len( Permutations(5, avoiding=[3, 2, 1]).list() ) # optional - sage.combinat 42 """ return catalan_number(self.n) @@ -9490,7 +9493,7 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[3, 2, 1]).list() #indirect doctest + sage: Permutations(3, avoiding=[3, 2, 1]).list() # indirect doctest # optional - sage.combinat [[2, 3, 1], [3, 1, 2], [1, 3, 2], [2, 1, 3], [1, 2, 3]] """ for p in StandardPermutations_avoiding_123(self.n): @@ -9503,7 +9506,7 @@ def __init__(self, n): TESTS:: sage: P = Permutations(3, avoiding=[2, 3, 1]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat """ super().__init__(n, (Permutations()([2, 3, 1]),)) @@ -9511,9 +9514,9 @@ def cardinality(self): """ EXAMPLES:: - sage: Permutations(5, avoiding=[2, 3, 1]).cardinality() + sage: Permutations(5, avoiding=[2, 3, 1]).cardinality() # optional - sage.combinat 42 - sage: len( Permutations(5, avoiding=[2, 3, 1]).list() ) + sage: len( Permutations(5, avoiding=[2, 3, 1]).list() ) # optional - sage.combinat 42 """ return catalan_number(self.n) @@ -9522,7 +9525,7 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[2, 3, 1]).list() + sage: Permutations(3, avoiding=[2, 3, 1]).list() # optional - sage.combinat [[3, 2, 1], [3, 1, 2], [1, 3, 2], [2, 1, 3], [1, 2, 3]] """ for p in StandardPermutations_avoiding_132(self.n): @@ -9535,7 +9538,7 @@ def __init__(self, n): TESTS:: sage: P = Permutations(3, avoiding=[3, 1, 2]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat """ super().__init__(n, (Permutations()([3, 1, 2]),)) @@ -9545,7 +9548,7 @@ def cardinality(self): sage: Permutations(5, avoiding=[3, 1, 2]).cardinality() 42 - sage: len( Permutations(5, avoiding=[3, 1, 2]).list() ) + sage: len( Permutations(5, avoiding=[3, 1, 2]).list() ) # optional - sage.combinat 42 """ return catalan_number(self.n) @@ -9554,7 +9557,7 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[3, 1, 2]).list() + sage: Permutations(3, avoiding=[3, 1, 2]).list() # optional - sage.combinat [[3, 2, 1], [2, 3, 1], [2, 1, 3], [1, 3, 2], [1, 2, 3]] """ for p in StandardPermutations_avoiding_132(self.n): @@ -9567,7 +9570,7 @@ def __init__(self, n): TESTS:: sage: P = Permutations(3, avoiding=[2, 1, 3]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat """ super().__init__(n, (Permutations()([2, 1, 3]),)) @@ -9577,7 +9580,7 @@ def cardinality(self): sage: Permutations(5, avoiding=[2, 1, 3]).cardinality() 42 - sage: len( Permutations(5, avoiding=[2, 1, 3]).list() ) + sage: len( Permutations(5, avoiding=[2, 1, 3]).list() ) # optional - sage.combinat 42 """ return catalan_number(self.n) @@ -9586,7 +9589,7 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[2, 1, 3]).list() + sage: Permutations(3, avoiding=[2, 1, 3]).list() # optional - sage.combinat [[1, 2, 3], [1, 3, 2], [3, 1, 2], [2, 3, 1], [3, 2, 1]] """ for p in StandardPermutations_avoiding_132(self.n): @@ -9615,7 +9618,7 @@ def _rec(self, obj, state): sage: from sage.combinat.permutation import PatternAvoider sage: P = Permutations(4) sage: p = PatternAvoider(P, [[1,2]]) - sage: list(p._rec([1], 2)) + sage: list(p._rec([1], 2)) # optional - sage.combinat [([2, 1], 3, False)] """ i = state diff --git a/src/sage/combinat/subset.py b/src/sage/combinat/subset.py index c27b1eb04ed..8cb6edb1fc4 100644 --- a/src/sage/combinat/subset.py +++ b/src/sage/combinat/subset.py @@ -1,7 +1,7 @@ r""" Subsets -The set of subsets of a finite set. The set can be given as a list or a Set +The set of subsets of a finite set. The set can be given as a list or a :class:`Set` or else as an integer `n` which encodes the set `\{1,2,...,n\}`. See :class:`Subsets` for more information and examples. @@ -186,11 +186,11 @@ class Subsets_s(Parent): {1, 2, 3}, {1, 2, 4}, {1, 3, 4}, {2, 3, 4}, {1, 2, 3, 4}] - sage: S = Subsets(Subsets(Subsets(GF(3)))); S + sage: S = Subsets(Subsets(Subsets(GF(3)))); S # optional - sage.rings.finite_rings Subsets of Subsets of Subsets of Finite Field of size 3 - sage: S.cardinality() + sage: S.cardinality() # optional - sage.rings.finite_rings 115792089237316195423570985008687907853269984665640564039457584007913129639936 - sage: S.unrank(3149254230) # random + sage: S.unrank(3149254230) # random # optional - sage.rings.finite_rings {{{1}, {0, 2}}, {{0, 1, 2}, {0, 1}, {1}, {1, 2}}, {{2}, {1, 2}, {0, 1, 2}, {0, 2}, {1}, {}}, {{1, 2}, {0}}, @@ -248,7 +248,7 @@ def underlying_set(self): EXAMPLES:: - sage: Subsets(GF(13)).underlying_set() + sage: Subsets(GF(13)).underlying_set() # optional - sage.rings.finite_rings {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} """ return self.element_class(self._s) @@ -550,10 +550,10 @@ def lattice(self): EXAMPLES:: sage: X = Subsets([7,8,9]) - sage: X.lattice() + sage: X.lattice() # optional - sage.combinat sage.graphs Finite lattice containing 8 elements sage: Y = Subsets(0) - sage: Y.lattice() + sage: Y.lattice() # optional - sage.combinat sage.graphs Finite lattice containing 1 elements """ @@ -874,8 +874,8 @@ def an_element(self): def dict_to_list(d): r""" - Return a list whose elements are the elements of i of d repeated with - multiplicity d[i]. + Return a list whose elements are the elements of ``i`` of ``d`` repeated with + multiplicity ``d[i]``. EXAMPLES:: @@ -1168,7 +1168,7 @@ def _element_constructor_(self,X): class SubMultiset_sk(SubMultiset_s): """ - The combinatorial class of the subsets of size k of a multiset s. Note + The combinatorial class of the subsets of size ``k`` of a multiset ``s``. Note that each subset is represented by a list of the elements rather than a set since we can have multiplicities (no multiset data structure yet in sage). @@ -1291,7 +1291,7 @@ def __contains__(self, s): def random_element(self): r""" - Return a random submultiset of given length + Return a random submultiset of given length. EXAMPLES:: From c415d7acb117a4e769d5627f9a1c0da311846c5c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Wed, 26 Apr 2023 23:19:18 -0700 Subject: [PATCH 050/228] sage.combinat: More # optional --- src/sage/combinat/free_module.py | 8 ++++---- src/sage/combinat/permutation.py | 9 +++++---- src/sage/rings/polynomial/all__sagemath_polyhedra.py | 0 3 files changed, 9 insertions(+), 8 deletions(-) create mode 100644 src/sage/rings/polynomial/all__sagemath_polyhedra.py diff --git a/src/sage/combinat/free_module.py b/src/sage/combinat/free_module.py index 746b0079b9e..2db919f8931 100644 --- a/src/sage/combinat/free_module.py +++ b/src/sage/combinat/free_module.py @@ -252,11 +252,11 @@ class CombinatorialFreeModule(UniqueRepresentation, Module, IndexedGenerators): TESTS:: - sage: XQ = SchubertPolynomialRing(QQ) - sage: XZ = SchubertPolynomialRing(ZZ) - sage: XQ == XZ + sage: XQ = SchubertPolynomialRing(QQ) # optional - sage.combinat + sage: XZ = SchubertPolynomialRing(ZZ) # optional - sage.combinat + sage: XQ == XZ # optional - sage.combinat False - sage: XQ == XQ + sage: XQ == XQ # optional - sage.combinat True We check that issue :trac:`28681` is fixed:: diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index 465045b15d4..56944d57dae 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -8059,14 +8059,15 @@ def cardinality(self): sage: Permutations(descents=([1,4], 6)).cardinality() 40 - sage: P = lambda D, n: Permutations(descents=(D, n+1)) - sage: all(P(D, n).cardinality() == len(P(D, n).list()) + sage: def P(D, n): + ....: return Permutations(descents=(D, n + 1)) + sage: all(P(D, n).cardinality() == len(P(D, n).list()) # optional - sage.graphs ....: for n in range(5) for D in subsets(range(n))) True - sage: n = 20; + sage: n = 20 sage: D = [6, 8, 10, 11, 12, 13, 14, 15, 17, 19] - sage: P(D, n).cardinality() + sage: P(D, n).cardinality() # optional - sage.graphs 125291047596 """ diff --git a/src/sage/rings/polynomial/all__sagemath_polyhedra.py b/src/sage/rings/polynomial/all__sagemath_polyhedra.py new file mode 100644 index 00000000000..e69de29bb2d From 9e9f1f1bccb8499f5599475f2c465c0e3f95f500 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Fri, 28 Apr 2023 11:56:25 -0700 Subject: [PATCH 051/228] sage.combinat: More # optional --- src/sage/combinat/subsets_hereditary.py | 32 ++++++++++++++----------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/sage/combinat/subsets_hereditary.py b/src/sage/combinat/subsets_hereditary.py index 5a1347c5218..68fe53e98ea 100644 --- a/src/sage/combinat/subsets_hereditary.py +++ b/src/sage/combinat/subsets_hereditary.py @@ -57,13 +57,14 @@ def subsets_with_hereditary_property(f,X,max_obstruction_size=None,ncpus=1): Sets whose elements all have the same remainder mod 2:: sage: from sage.combinat.subsets_hereditary import subsets_with_hereditary_property - sage: f = lambda x: (not x) or all(xx%2 == x[0]%2 for xx in x) - sage: list(subsets_with_hereditary_property(f,range(4))) + sage: def f(x): + ....: return (not x) or all(xx % 2 == x[0] % 2 for xx in x) + sage: list(subsets_with_hereditary_property(f, range(4))) [[], [0], [1], [2], [3], [0, 2], [1, 3]] Same, on two threads:: - sage: sorted(subsets_with_hereditary_property(f,range(4),ncpus=2)) + sage: sorted(subsets_with_hereditary_property(f, range(4), ncpus=2)) [[], [0], [0, 2], [1], [1, 3], [2], [3]] One can use this function to compute the independent sets of a graph. We @@ -71,33 +72,35 @@ def subsets_with_hereditary_property(f,X,max_obstruction_size=None,ncpus=1): have size 2. We can thus set ``max_obstruction_size=2``, which reduces the number of calls to `f` from 91 to 56:: - sage: num_calls=0 + sage: num_calls = 0 sage: g = graphs.PetersenGraph() sage: def is_independent_set(S): ....: global num_calls - ....: num_calls+=1 - ....: return g.subgraph(S).size()==0 - sage: l1=list(subsets_with_hereditary_property(is_independent_set, g.vertices(sort=False))) + ....: num_calls += 1 + ....: return g.subgraph(S).size() == 0 + sage: l1 = list(subsets_with_hereditary_property(is_independent_set, + ....: g.vertices(sort=False))) sage: num_calls 91 - sage: num_calls=0 - sage: l2=list(subsets_with_hereditary_property(is_independent_set, g.vertices(sort=False), max_obstruction_size=2)) + sage: num_calls = 0 + sage: l2 = list(subsets_with_hereditary_property(is_independent_set, + ....: g.vertices(sort=False), + ....: max_obstruction_size=2)) sage: num_calls 56 - sage: l1==l2 + sage: l1 == l2 True TESTS:: - sage: list(subsets_with_hereditary_property(lambda x:False,range(4))) + sage: list(subsets_with_hereditary_property(lambda x: False, range(4))) [] - sage: list(subsets_with_hereditary_property(lambda x:len(x)<1,range(4))) + sage: list(subsets_with_hereditary_property(lambda x: len(x)<1, range(4))) [[]] - sage: list(subsets_with_hereditary_property(lambda x:True,range(2))) + sage: list(subsets_with_hereditary_property(lambda x: True, range(2))) [[], [0], [1], [0, 1]] """ from sage.data_structures.bitset import Bitset - from sage.parallel.decorate import parallel # About the implementation: # # 1) We work on X={0,...,n-1} but remember X to return correctly @@ -155,6 +158,7 @@ def explore_neighbors(s): return if ncpus != 1: + from sage.parallel.decorate import parallel explore_neighbors_paral = parallel(ncpus=ncpus)(explore_neighbors) # All sets of size 0, then size 1, then ... From 397ebd38b050ace0535498a1ff65f2b0f5c366f4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sun, 14 May 2023 21:30:55 -0700 Subject: [PATCH 052/228] sage.combinat: Add # optional, docstring cosmetics --- .../combinat/binary_recurrence_sequences.py | 23 +- .../cluster_algebra_quiver/cluster_seed.py | 517 +++++++++--------- .../cluster_algebra_quiver/interact.py | 6 +- .../combinat/cluster_algebra_quiver/quiver.py | 10 +- .../quiver_mutation_type.py | 8 +- src/sage/combinat/crystals/mv_polytopes.py | 2 +- src/sage/combinat/designs/block_design.py | 8 +- .../combinat/designs/difference_family.py | 6 +- .../combinat/designs/incidence_structures.py | 21 +- src/sage/combinat/diagram_algebras.py | 28 +- src/sage/combinat/finite_state_machine.py | 14 +- src/sage/combinat/k_tableau.py | 2 +- src/sage/combinat/partition.py | 25 +- src/sage/combinat/path_tableaux/frieze.py | 47 +- src/sage/combinat/perfect_matching.py | 8 +- src/sage/combinat/posets/posets.py | 4 +- src/sage/combinat/q_analogues.py | 12 +- src/sage/combinat/ribbon_tableau.py | 14 +- .../non_symmetric_macdonald_polynomials.py | 10 +- .../root_system/root_lattice_realizations.py | 164 +++--- src/sage/combinat/root_system/root_system.py | 2 +- src/sage/combinat/root_system/type_A.py | 8 +- src/sage/combinat/root_system/type_G.py | 8 +- src/sage/combinat/root_system/type_affine.py | 16 +- src/sage/combinat/rooted_tree.py | 6 +- src/sage/combinat/set_partition.py | 9 +- src/sage/combinat/sf/elementary.py | 4 +- src/sage/combinat/sf/homogeneous.py | 4 +- src/sage/combinat/sf/monomial.py | 4 +- src/sage/combinat/sf/ns_macdonald.py | 14 +- src/sage/combinat/sf/powersum.py | 10 +- src/sage/combinat/sf/schur.py | 6 +- src/sage/combinat/species/structure.py | 5 +- src/sage/combinat/tutorial.py | 122 ++--- src/sage/combinat/words/finite_word.py | 8 +- src/sage/combinat/words/word_generators.py | 56 +- 36 files changed, 623 insertions(+), 588 deletions(-) diff --git a/src/sage/combinat/binary_recurrence_sequences.py b/src/sage/combinat/binary_recurrence_sequences.py index 8c244342712..46c99fd24aa 100644 --- a/src/sage/combinat/binary_recurrence_sequences.py +++ b/src/sage/combinat/binary_recurrence_sequences.py @@ -19,12 +19,12 @@ sage: R.pthpowers(2, 10**10) # long time (7 seconds) -- in fact these are all squares, c.f. [BMS06] [0, 1, 2, 12] - sage: S = BinaryRecurrenceSequence(8,1) #a Lucas sequence + sage: S = BinaryRecurrenceSequence(8,1) #a Lucas sequence sage: S.period(73) 148 sage: S(5) % 73 == S(5 +148) %73 True - sage: S.pthpowers(3,10**10) # long time (3 seconds) -- provably finds the indices of all 3rd powers less than 10^10 + sage: S.pthpowers(3, 10**10) # long time (3 seconds) -- provably finds the indices of all 3rd powers less than 10^10 [0, 1, 2] sage: T = BinaryRecurrenceSequence(2,0,1,2) @@ -34,10 +34,11 @@ True sage: T.is_geometric() True - sage: T.pthpowers(7,10**30) + sage: T.pthpowers(7, 10**30) # optional - sage.symbolic Traceback (most recent call last): ... - ValueError: the degenerate binary recurrence sequence is geometric or quasigeometric and has many pth powers + ValueError: the degenerate binary recurrence sequence is geometric or quasigeometric + and has many pth powers AUTHORS: @@ -544,17 +545,18 @@ def pthpowers(self, p, Bound): True sage: T.is_geometric() True - sage: T.pthpowers(7,10**30) + sage: T.pthpowers(7, 10**30) # optional - sage.symbolic Traceback (most recent call last): ... - ValueError: the degenerate binary recurrence sequence is geometric or quasigeometric and has many pth powers + ValueError: the degenerate binary recurrence sequence is geometric or + quasigeometric and has many pth powers sage: L = BinaryRecurrenceSequence(4,0,2,2) sage: [L(i).factor() for i in range(10)] [2, 2, 2^3, 2^5, 2^7, 2^9, 2^11, 2^13, 2^15, 2^17] sage: L.is_quasigeometric() True - sage: L.pthpowers(2,10**30) + sage: L.pthpowers(2, 10**30) # optional - sage.symbolic [] .. NOTE:: @@ -1051,7 +1053,8 @@ def _estimated_time(M2, M1, length, p): EXAMPLES:: - sage: sage.combinat.binary_recurrence_sequences._estimated_time(2**4*3**2*5*7*11*13*17, 2**4*3**2*5*7*11*13, 20, 7) + sage: from sage.combinat.binary_recurrence_sequences import _estimated_time + sage: _estimated_time(2**4*3**2*5*7*11*13*17, 2**4*3**2*5*7*11*13, 20, 7) # optional - sage.symbolic 106.211159309421 """ @@ -1137,9 +1140,9 @@ def _is_p_power(a, p): EXAMPLES:: - sage: sage.combinat.binary_recurrence_sequences._is_p_power(2**7,7) + sage: sage.combinat.binary_recurrence_sequences._is_p_power(2**7, 7) # optional - sage.symbolic True - sage: sage.combinat.binary_recurrence_sequences._is_p_power(2**7*3**2,7) + sage: sage.combinat.binary_recurrence_sequences._is_p_power(2**7*3**2, 7) # optional - sage.symbolic False """ return int(a**(1/p))**p == a diff --git a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py index 1209bdcdbbc..31eac5999df 100644 --- a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py +++ b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py @@ -66,12 +66,12 @@ class ClusterSeed(SageObject): - ``data`` -- can be any of the following:: - * QuiverMutationType - * str - a string representing a QuiverMutationType or a common quiver type (see Examples) - * ClusterQuiver - * Matrix - a skew-symmetrizable matrix - * DiGraph - must be the input data for a quiver - * List of edges - must be the edge list of a digraph for a quiver + * :class:`QuiverMutationType` + * :class:`str` -- a string representing a :class:`QuiverMutationType` or a common quiver type (see Examples) + * :class:`ClusterQuiver` + * :class:`Matrix` -- a skew-symmetrizable matrix + * :class:`DiGraph` -- must be the input data for a quiver + * List of edges -- must be the edge list of a digraph for a quiver EXAMPLES:: @@ -110,24 +110,21 @@ class ClusterSeed(SageObject): sage: S = ClusterSeed(['A',4]); S._use_fpolys True - sage: S._use_d_vec True - sage: S._use_g_vec True - sage: S._use_c_vec True sage: S = ClusterSeed(['A', 4]); S.use_fpolys(False); S._use_fpolys False - sage: S = ClusterSeed(DiGraph([['a', 'b'], ['c', 'b'], ['c', 'd'], ['e', 'd']]), frozen = - ....: ['c']); S + sage: S = ClusterSeed(DiGraph([['a', 'b'], ['c', 'b'], ['c', 'd'], ['e', 'd']]), + ....: frozen=['c']); S A seed for a cluster algebra of rank 4 with 1 frozen variable - sage: S = ClusterSeed(['D', 4],user_labels = [-1, 0, 1, 2]);S + sage: S = ClusterSeed(['D', 4],user_labels = [-1, 0, 1, 2]); S A seed for a cluster algebra of rank 4 of type ['D', 4] """ @@ -367,14 +364,16 @@ def __init__(self, data, frozen=None, is_principal=False, user_labels=None, user def use_c_vectors(self, use=True, bot_is_c=False, force=False): r""" - Reconstruct c vectors from other data or initialize if no usable data exists. + Reconstruct c-vectors from other data or initialize if no usable data exists. Warning: Initialization may lead to inconsistent data. INPUT: - - ``use`` -- (default:True) If True, will use c vectors - - ``bot_is_c`` -- (default:False) If True and ClusterSeed self has self._m == self._n, then will assume bottom half of the extended exchange matrix is the c-matrix. If true, lets the ClusterSeed know c-vectors can be calculated. + - ``use`` -- (default: ``True``) If ``True``, will use c-vectors + - ``bot_is_c`` -- (default: ``False``) If ``True`` and :class:`ClusterSeed` ``self`` has ``self._m == self._n``, + then will assume bottom half of the extended exchange matrix is the c-matrix. + If ``True``, lets the :class:`ClusterSeed` know c-vectors can be calculated. EXAMPLES:: @@ -443,13 +442,13 @@ def use_c_vectors(self, use=True, bot_is_c=False, force=False): def use_g_vectors(self, use=True, force=False): r""" - Reconstruct g vectors from other data or initialize if no usable data exists. + Reconstruct g-vectors from other data or initialize if no usable data exists. Warning: Initialization may lead to inconsistent data. INPUT: - - ``use`` -- (default:True) If True, will use g vectors + - ``use`` -- (default: ``True``) If ``True``, will use g-vectors EXAMPLES:: @@ -524,13 +523,13 @@ def use_g_vectors(self, use=True, force=False): def use_d_vectors(self, use=True, force=False): r""" - Reconstruct d vectors from other data or initialize if no usable data exists. + Reconstruct d-vectors from other data or initialize if no usable data exists. Warning: Initialization may lead to inconsistent data. INPUT: - - ``use`` -- (default:True) If True, will use d vectors + - ``use`` -- (default: ``True``) If ``True``, will use d-vectors EXAMPLES:: @@ -542,7 +541,8 @@ def use_d_vectors(self, use=True, force=False): [ 0 0 -1 0] [ 0 0 0 -1] - sage: S = ClusterSeed(['A',4]); S.use_d_vectors(False); S.track_mutations(False); S.mutate(1); S.d_matrix() + sage: S = ClusterSeed(['A',4]); S.use_d_vectors(False) + sage: S.track_mutations(False); S.mutate(1); S.d_matrix() [-1 0 0 0] [ 0 1 0 0] [ 0 0 -1 0] @@ -553,14 +553,16 @@ def use_d_vectors(self, use=True, force=False): ... ValueError: Unable to calculate d-vectors. Need to use d vectors. - sage: S = ClusterSeed(['A',4]); S.use_d_vectors(False); S.track_mutations(False); S.mutate(1); S.d_matrix() + sage: S = ClusterSeed(['A',4]); S.use_d_vectors(False) + sage: S.track_mutations(False); S.mutate(1); S.d_matrix() [-1 0 0 0] [ 0 1 0 0] [ 0 0 -1 0] [ 0 0 0 -1] sage: S.use_fpolys(False) sage: S.use_d_vectors(True) - Warning: Initializing d-vectors at this point could lead to inconsistent seed data. + Warning: Initializing d-vectors at this point + could lead to inconsistent seed data. sage: S.use_d_vectors(True, force=True) sage: S.d_matrix() @@ -610,9 +612,9 @@ def use_fpolys(self, use=True, user_labels=None, user_labels_prefix=None): INPUT: - - ``use`` -- (default:True) If True, will use F-polynomials - - ``user_labels`` -- (default:None) If set will overwrite the default cluster variable labels - - ``user_labels_prefix`` -- (default:None) If set will overwrite the default + - ``use`` -- (default: ``True``) If ``True``, will use F-polynomials + - ``user_labels`` -- (default: ``None``) If set, will overwrite the default cluster variable labels + - ``user_labels_prefix`` -- (default: ``None``) If set, will overwrite the default EXAMPLES:: @@ -621,11 +623,13 @@ def use_fpolys(self, use=True, user_labels=None, user_labels_prefix=None): sage: S.cluster() [x0, x1, x2, x3] - sage: S = ClusterSeed(['A',4]); S.use_fpolys(False); S.track_mutations(False); S.mutate(1) + sage: S = ClusterSeed(['A',4]); S.use_fpolys(False); S.track_mutations(False) + sage: S.mutate(1) sage: S.use_fpolys(True) Traceback (most recent call last): ... - ValueError: F-polynomials and Cluster Variables cannot be reconstructed from given data. + ValueError: F-polynomials and Cluster Variables cannot be reconstructed + from given data. sage: S.cluster() Traceback (most recent call last): ... @@ -698,11 +702,11 @@ def track_mutations(self, use=True): r""" Begins tracking the mutation path. - Warning: May initialize all other data to ensure that all c, d, and g vectors agree on the start of mutations. + Warning: May initialize all other data to ensure that all c-, d-, and g-vectors agree on the start of mutations. INPUT: - - ``use`` -- (default:True) If True, will begin filling the mutation path + - ``use`` -- (default: ``True``) If ``True``, will begin filling the mutation path EXAMPLES:: @@ -758,7 +762,7 @@ def _sanitize_init_vars(self, user_labels, user_labels_prefix='x'): INPUT: - ``user_labels`` -- The labels that need sanitizing - - ``user_labels_prefix`` -- (default:'x') The prefix to use for labels if integers given for labels + - ``user_labels_prefix`` -- (default: ``'x'``) The prefix to use for labels if integers given for labels EXAMPLES:: @@ -821,12 +825,12 @@ def _sanitize_init_vars(self, user_labels, user_labels_prefix='x'): def set_c_matrix(self, data): r""" - Will force set the c matrix according to a matrix, a quiver, or a seed. + Will force set the c-matrix according to a matrix, a quiver, or a seed. INPUT: - - ``data`` -- The matrix to set the c matrix to. Also allowed - to be a quiver or cluster seed, in which case the b_matrix + - ``data`` -- The matrix to set the c-matrix to. Also allowed + to be a quiver or cluster seed, in which case the b-matrix is used. EXAMPLES:: @@ -841,7 +845,8 @@ def set_c_matrix(self, data): sage: Y = matrix([[-1,0,1],[0,1,0],[1,0,0]]) sage: S.set_c_matrix(Y) - C matrix does not look to be valid - there exists a column containing positive and negative entries. + C matrix does not look to be valid - there exists a column + containing positive and negative entries. Continuing... sage: Z = matrix([[1,0,1],[0,1,0],[2,0,2]]) @@ -872,7 +877,7 @@ def set_c_matrix(self, data): def __eq__(self, other): r""" - Returns True iff ``self`` represent the same cluster seed as ``other`` and all tracked data agrees. + Return ``True`` iff ``self`` represent the same cluster seed as ``other`` and all tracked data agrees. EXAMPLES:: @@ -945,7 +950,7 @@ def __hash__(self): def _repr_(self): r""" - Returns the description of ``self``. + Return the description of ``self``. EXAMPLES:: @@ -976,25 +981,25 @@ def _repr_(self): def plot(self, circular=False, mark=None, save_pos=False, force_c=False, with_greens=False, add_labels=False): r""" - Returns the plot of the quiver of ``self``. + Return the plot of the quiver of ``self``. INPUT: - - ``circular`` -- (default:False) if True, the circular plot is chosen, otherwise >>spring<< is used. - - ``mark`` -- (default: None) if set to i, the vertex i is highlighted. - - ``save_pos`` -- (default:False) if True, the positions of the vertices are saved. - - ``force_c`` -- (default:False) if True, will show the frozen vertices even if they were never initialized - - ``with_greens`` -- (default:False) if True, will display the green vertices in green - - ``add_labels`` -- (default:False) if True, will use the initial variables as labels + - ``circular`` -- (default: ``False``) if ``True``, the circular plot is chosen, otherwise >>spring<< is used. + - ``mark`` -- (default: ``None``) if set to i, the vertex i is highlighted. + - ``save_pos`` -- (default: ``False``) if ``True``, the positions of the vertices are saved. + - ``force_c`` -- (default: ``False``) if ``True``, will show the frozen vertices even if they were never initialized + - ``with_greens`` -- (default: ``False``) if ``True``, will display the green vertices in green + - ``add_labels`` -- (default: ``False``) if ``True``, will use the initial variables as labels EXAMPLES:: sage: S = ClusterSeed(['A',5]) - sage: S.plot() + sage: S.plot() # optional - sage.plot sage.symbolic Graphics object consisting of 15 graphics primitives - sage: S.plot(circular=True) + sage: S.plot(circular=True) # optional - sage.plot sage.symbolic Graphics object consisting of 15 graphics primitives - sage: S.plot(circular=True, mark=1) + sage: S.plot(circular=True, mark=1) # optional - sage.plot sage.symbolic Graphics object consisting of 15 graphics primitives """ greens = [] @@ -1019,17 +1024,17 @@ def show(self, fig_size=1, circular=False, mark=None, save_pos=False, force_c=Fa INPUT: - ``fig_size`` -- (default: 1) factor by which the size of the plot is multiplied. - - ``circular`` -- (default: False) if True, the circular plot is chosen, otherwise >>spring<< is used. - - ``mark`` -- (default: None) if set to i, the vertex i is highlighted. - - ``save_pos`` -- (default:False) if True, the positions of the vertices are saved. - - ``force_c`` -- (default:False) if True, will show the frozen vertices even if they were never initialized - - ``with_greens`` -- (default:False) if True, will display the green vertices in green - - ``add_labels`` -- (default:False) if True, will use the initial variables as labels + - ``circular`` -- (default: ``False``) if ``True``, the circular plot is chosen, otherwise >>spring<< is used. + - ``mark`` -- (default: ``None``) if set to i, the vertex i is highlighted. + - ``save_pos`` -- (default: ``False``) if ``True``, the positions of the vertices are saved. + - ``force_c`` -- (default: ``False``) if ``True``, will show the frozen vertices even if they were never initialized + - ``with_greens`` -- (default: ``False``) if ``True``, will display the green vertices in green + - ``add_labels`` -- (default: ``False``) if ``True``, will use the initial variables as labels TESTS:: sage: S = ClusterSeed(['A',5]) - sage: S.show() # long time + sage: S.show() # long time # optional - sage.plot sage.symbolic """ greens = [] if with_greens: @@ -1063,27 +1068,27 @@ def interact(self, fig_size=1, circular=True): TESTS:: sage: S = ClusterSeed(['A',4]) - sage: S.interact() + sage: S.interact() # optional - sage.plot sage.symbolic ...VBox(children=... """ return cluster_interact(self, fig_size, circular, kind='seed') def save_image(self, filename, circular=False, mark=None, save_pos=False): r""" - Saves the plot of the underlying digraph of the quiver of ``self``. + Save the plot of the underlying digraph of the quiver of ``self``. INPUT: - ``filename`` -- the filename the image is saved to. - - ``circular`` -- (default: False) if True, the circular plot is chosen, otherwise >>spring<< is used. - - ``mark`` -- (default: None) if set to i, the vertex i is highlighted. - - ``save_pos`` -- (default:False) if True, the positions of the vertices are saved. + - ``circular`` -- (default: ``False``) if ``True``, the circular plot is chosen, otherwise >>spring<< is used. + - ``mark`` -- (default: ``None``) if set to i, the vertex i is highlighted. + - ``save_pos`` -- (default: ``False``) if ``True``, the positions of the vertices are saved. EXAMPLES:: sage: S = ClusterSeed(['F',4,[1,2]]) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: + sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: # optional - sage.plot sage.symbolic ....: S.save_image(f.name) """ graph_plot = self.plot(circular=circular, mark=mark, save_pos=save_pos) @@ -1091,7 +1096,7 @@ def save_image(self, filename, circular=False, mark=None, save_pos=False): def b_matrix(self): r""" - Returns the `B` *-matrix* of ``self``. + Return the `B` *-matrix* of ``self``. EXAMPLES:: @@ -1123,7 +1128,7 @@ def b_matrix(self): def ground_field(self): r""" - Returns the *ground field* of the cluster of ``self``. + Return the *ground field* of the cluster of ``self``. EXAMPLES:: @@ -1136,7 +1141,7 @@ def ground_field(self): def x(self, k): r""" Return the `k` *-th initial cluster variable* for the associated cluster seed, - or the cluster variable of the corresponding vertex in self.quiver. + or the cluster variable of the corresponding vertex in ``self.quiver``. EXAMPLES:: @@ -1152,7 +1157,7 @@ def x(self, k): x2 sage: dg = DiGraph([['a', 'b'], ['b', 'c']], format="list_of_edges") - sage: S = ClusterSeed(dg, frozen = ['c']) + sage: S = ClusterSeed(dg, frozen=['c']) sage: S.x(0) a sage: S.x('a') @@ -1175,7 +1180,7 @@ def y(self, k): r""" Return the `k` *-th initial coefficient (frozen variable)* for the associated cluster seed, or the cluster variable of the corresponding - vertex in self.quiver. + vertex in ``self.quiver``. EXAMPLES:: @@ -1191,7 +1196,7 @@ def y(self, k): y2 sage: dg = DiGraph([['a', 'b'], ['b', 'c']], format="list_of_edges") - sage: S = ClusterSeed(dg, frozen = ['c']) + sage: S = ClusterSeed(dg, frozen=['c']) sage: S.y(0) c sage: S.y('c') @@ -1223,7 +1228,7 @@ def n(self): def m(self): r""" - Returns the number of *frozen variables* of ``self``. + Return the number of *frozen variables* of ``self``. EXAMPLES:: @@ -1247,7 +1252,7 @@ def free_vertices(self): EXAMPLES:: sage: S = ClusterSeed(DiGraph([['a', 'b'], ['c', 'b'], ['c', 'd'], ['e', 'd']]), - ....: frozen = ['b', 'd']) + ....: frozen=['b', 'd']) sage: S.free_vertices() ['a', 'c', 'e'] @@ -1264,7 +1269,7 @@ def frozen_vertices(self): EXAMPLES:: sage: S = ClusterSeed(DiGraph([['a', 'b'], ['c', 'b'], ['c', 'd'], ['e', 'd']]), - ....: frozen = ['b', 'd']) + ....: frozen=['b', 'd']) sage: sorted(S.frozen_vertices()) ['b', 'd'] """ @@ -1334,7 +1339,7 @@ def cluster_variable(self, k): def cluster(self): r""" - Returns a copy of the *cluster* of ``self``. + Return a copy of the *cluster* of ``self``. EXAMPLES:: @@ -1422,7 +1427,8 @@ def f_polynomial(self, k): sage: [S.f_polynomial(k) for k in range(3)] [1, y1*y2 + y2 + 1, y1 + 1] - sage: S = ClusterSeed(Matrix([[0,1],[-1,0],[1,0],[-1,1]])); S.use_c_vectors(bot_is_c=True); S + sage: S = ClusterSeed(Matrix([[0,1],[-1,0],[1,0],[-1,1]])) + sage: S.use_c_vectors(bot_is_c=True); S A seed for a cluster algebra of rank 2 with 2 frozen variables sage: T = ClusterSeed(Matrix([[0,1],[-1,0]])).principal_extension(); T A seed for a cluster algebra of rank 2 with principal coefficients @@ -1534,14 +1540,16 @@ def g_matrix(self, show_warnings=True): [ 1 0 0] [ 0 0 1] - sage: S = ClusterSeed(['A',4]); S.use_g_vectors(False); S.use_fpolys(False); S.g_matrix() + sage: S = ClusterSeed(['A',4]) + sage: S.use_g_vectors(False); S.use_fpolys(False); S.g_matrix() [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1] sage: S = ClusterSeed(['A',4]) - sage: S.use_g_vectors(False); S.use_c_vectors(False); S.use_fpolys(False); S.track_mutations(False); S.g_matrix() + sage: S.use_g_vectors(False); S.use_c_vectors(False); S.use_fpolys(False) + sage: S.track_mutations(False); S.g_matrix() Traceback (most recent call last): ... ValueError: Unable to calculate g-vectors. Need to use g vectors. @@ -1630,7 +1638,8 @@ def c_vector(self, k): sage: S.c_vector(0) (1, 0) - sage: S = ClusterSeed(Matrix([[0,1],[-1,0],[1,0],[-1,1]])); S.use_c_vectors(bot_is_c=True); S + sage: S = ClusterSeed(Matrix([[0,1],[-1,0],[1,0],[-1,1]])) + sage: S.use_c_vectors(bot_is_c=True); S A seed for a cluster algebra of rank 2 with 2 frozen variables sage: S.c_vector(0) (1, -1) @@ -1662,7 +1671,8 @@ def c_matrix(self, show_warnings=True): [ 0 -1 0] sage: S = ClusterSeed(['A',4]) - sage: S.use_g_vectors(False); S.use_fpolys(False); S.use_c_vectors(False); S.use_d_vectors(False); S.track_mutations(False); + sage: S.use_g_vectors(False); S.use_fpolys(False) + sage: S.use_c_vectors(False); S.use_d_vectors(False); S.track_mutations(False) sage: S.c_matrix() Traceback (most recent call last): ... @@ -1861,7 +1871,7 @@ def quiver(self): def is_acyclic(self) -> bool: r""" - Return True iff self is acyclic (i.e., if the underlying quiver is acyclic). + Return ``True`` iff ``self`` is acyclic (i.e., if the underlying quiver is acyclic). EXAMPLES:: @@ -1878,11 +1888,11 @@ def is_acyclic(self) -> bool: def is_bipartite(self, return_bipartition=False): r""" - Return True iff self is bipartite (i.e., if the underlying quiver is bipartite). + Return ``True`` iff ``self`` is bipartite (i.e., if the underlying quiver is bipartite). INPUT: - - return_bipartition -- (default:False) if True, the bipartition is returned in the case of ``self`` being bipartite. + - ``return_bipartition`` -- (default: ``False``) if ``True``, the bipartition is returned in the case of ``self`` being bipartite. EXAMPLES:: @@ -2014,7 +2024,7 @@ def urban_renewals(self, return_first=False): INPUT: - - ``return_first`` -- (default:False) if True, will return the first urban renewal + - ``return_first`` -- (default: ``False``) if ``True``, will return the first urban renewal OUTPUT: @@ -2056,7 +2066,7 @@ def highest_degree_denominator(self, filter=None): INPUT: - - ``filter`` - Filter should be a list or iterable + - ``filter`` -- a list or iterable OUTPUT: @@ -2064,7 +2074,8 @@ def highest_degree_denominator(self, filter=None): EXAMPLES:: - sage: B = matrix([[0,-1,0,-1,1,1],[1,0,1,0,-1,-1],[0,-1,0,-1,1,1],[1,0,1,0,-1,-1],[-1,1,-1,1,0,0],[-1,1,-1,1,0,0]]) + sage: B = matrix([[0,-1,0,-1,1,1], [1,0,1,0,-1,-1], [0,-1,0,-1,1,1], + ....: [1,0,1,0,-1,-1], [-1,1,-1,1,0,0], [-1,1,-1,1,0,0]]) sage: C = ClusterSeed(B).principal_extension(); C.mutate([0,1,2,4,3,2,5,4,3]) sage: C.highest_degree_denominator() 5 @@ -2102,20 +2113,17 @@ def highest_degree_denominator(self, filter=None): def smallest_c_vector(self): r""" - Return the vertex with the smallest c vector. - - OUTPUT: + Return the vertex with the smallest c-vector. - An integer. + OUTPUT: An integer. EXAMPLES:: - sage: B = matrix([[0,2],[-2,0]]) + sage: B = matrix([[0,2], [-2,0]]) sage: C = ClusterSeed(B).principal_extension() sage: C.mutate(0) sage: C.smallest_c_vector() 0 - """ min_sum = infinity vertex_to_mutate = [] @@ -2135,7 +2143,6 @@ def smallest_c_vector(self): def most_decreased_edge_after_mutation(self): r""" - Return the vertex that will produce the least degrees after mutation EXAMPLES:: @@ -2144,7 +2151,6 @@ def most_decreased_edge_after_mutation(self): sage: S.mutate([0,2,3,1,2,3,1,2,0,2,3]) sage: S.most_decreased_edge_after_mutation() 2 - """ analysis = self.mutation_analysis(['edge_diff']) least_edge = infinity @@ -2165,7 +2171,6 @@ def most_decreased_edge_after_mutation(self): def most_decreased_denominator_after_mutation(self): r""" - Return the vertex that will produce the most decrease in denominator degrees after mutation EXAMPLES:: @@ -2174,7 +2179,6 @@ def most_decreased_denominator_after_mutation(self): sage: S.mutate([0,2,3,1,2,3,1,2,0,2,3]) sage: S.most_decreased_denominator_after_mutation() 2 - """ analysis = self.mutation_analysis(['d_matrix']) least_change = infinity @@ -2639,13 +2643,13 @@ def mutation_sequence(self, sequence, show_sequence=False, INPUT: - ``sequence`` -- an iterable of vertices of self. - - ``show_sequence`` -- (default: False) if True, a png containing the associated quivers is shown. + - ``show_sequence`` -- (default: ``False``) if ``True``, a png containing the associated quivers is shown. - ``fig_size`` -- (default: 1.2) factor by which the size of the plot is multiplied. - ``return_output`` -- (default: 'seed') determines what output is to be returned:: - * if 'seed', outputs all the cluster seeds obtained by the ``sequence`` of mutations. - * if 'matrix', outputs a list of exchange matrices. - * if 'var', outputs a list of new cluster variables obtained at each step. + * if ``'seed'``, outputs all the cluster seeds obtained by the ``sequence`` of mutations. + * if ``'matrix'``, outputs a list of exchange matrices. + * if ``'var'``, outputs a list of new cluster variables obtained at each step. EXAMPLES:: @@ -2693,8 +2697,8 @@ def mutation_analysis(self, options=['all'], filter=None): INPUT: - - ``options`` -- (default: ['all']) a list of mutation options. - - ``filter`` -- (default: None) A vertex or interval of vertices to limit our search to + - ``options`` -- (default: [``'all'``]) a list of mutation options. + - ``filter`` -- (default: ``None``) A vertex or interval of vertices to limit our search to Possible options are: @@ -2717,7 +2721,7 @@ def mutation_analysis(self, options=['all'], filter=None): Outputs a dictionary indexed by the vertex numbers. Each vertex will itself also be a dictionary with each desired option included as a key in the dictionary. As an example - you would get something similar to: {0: {'edges': 1}, 1: {'edges': 2}}. This represents + you would get something similar to: ``{0: {'edges': 1}, 1: {'edges': 2}}``. This represents that if you were to do a mutation at the current seed then mutating at vertex 0 would result in a quiver with 1 edge and mutating at vertex 0 would result in a quiver with 2 edges. @@ -2727,118 +2731,118 @@ def mutation_analysis(self, options=['all'], filter=None): sage: S = ClusterSeed(matrix(B)); S.mutate([2,3,1,2,1,3,0,2]) sage: S.mutation_analysis() {0: {'d_matrix': [ 0 0 1 0] - [ 0 -1 0 0] - [ 0 0 0 -1] - [-1 0 0 0], - 'denominators': [1, 1, x0, 1], - 'edge_diff': 6, - 'edges': 13, - 'green_vertices': [0, 1, 3], - 'green_vertices_diff': {'added': [0], 'removed': []}, - 'red_vertices': [2], - 'red_vertices_diff': {'added': [], 'removed': [0]}, - 'sinks': [], - 'sinks_diff': {'added': [], 'removed': [2]}, - 'sources': [], - 'sources_diff': {'added': [], 'removed': []}, - 'urban_renewals': [], - 'urban_renewals_diff': {'added': [], 'removed': []}}, + [ 0 -1 0 0] + [ 0 0 0 -1] + [-1 0 0 0], + 'denominators': [1, 1, x0, 1], + 'edge_diff': 6, + 'edges': 13, + 'green_vertices': [0, 1, 3], + 'green_vertices_diff': {'added': [0], 'removed': []}, + 'red_vertices': [2], + 'red_vertices_diff': {'added': [], 'removed': [0]}, + 'sinks': [], + 'sinks_diff': {'added': [], 'removed': [2]}, + 'sources': [], + 'sources_diff': {'added': [], 'removed': []}, + 'urban_renewals': [], + 'urban_renewals_diff': {'added': [], 'removed': []}}, 1: {'d_matrix': [ 1 4 1 0] - [ 0 1 0 0] - [ 0 0 0 -1] - [ 1 4 0 0], - 'denominators': [x0*x3, x0^4*x1*x3^4, x0, 1], - 'edge_diff': 2, - 'edges': 9, - 'green_vertices': [0, 3], - 'green_vertices_diff': {'added': [0], 'removed': [1]}, - 'red_vertices': [1, 2], - 'red_vertices_diff': {'added': [1], 'removed': [0]}, - 'sinks': [2], - 'sinks_diff': {'added': [], 'removed': []}, - 'sources': [], - 'sources_diff': {'added': [], 'removed': []}, - 'urban_renewals': [], - 'urban_renewals_diff': {'added': [], 'removed': []}}, + [ 0 1 0 0] + [ 0 0 0 -1] + [ 1 4 0 0], + 'denominators': [x0*x3, x0^4*x1*x3^4, x0, 1], + 'edge_diff': 2, + 'edges': 9, + 'green_vertices': [0, 3], + 'green_vertices_diff': {'added': [0], 'removed': [1]}, + 'red_vertices': [1, 2], + 'red_vertices_diff': {'added': [1], 'removed': [0]}, + 'sinks': [2], + 'sinks_diff': {'added': [], 'removed': []}, + 'sources': [], + 'sources_diff': {'added': [], 'removed': []}, + 'urban_renewals': [], + 'urban_renewals_diff': {'added': [], 'removed': []}}, 2: {'d_matrix': [ 1 0 0 0] - [ 0 -1 0 0] - [ 0 0 0 -1] - [ 1 0 1 0], - 'denominators': [x0*x3, 1, x3, 1], - 'edge_diff': 0, - 'edges': 7, - 'green_vertices': [1, 2, 3], - 'green_vertices_diff': {'added': [2], 'removed': []}, - 'red_vertices': [0], - 'red_vertices_diff': {'added': [], 'removed': [2]}, - 'sinks': [], - 'sinks_diff': {'added': [], 'removed': [2]}, - 'sources': [2], - 'sources_diff': {'added': [2], 'removed': []}, - 'urban_renewals': [], - 'urban_renewals_diff': {'added': [], 'removed': []}}, + [ 0 -1 0 0] + [ 0 0 0 -1] + [ 1 0 1 0], + 'denominators': [x0*x3, 1, x3, 1], + 'edge_diff': 0, + 'edges': 7, + 'green_vertices': [1, 2, 3], + 'green_vertices_diff': {'added': [2], 'removed': []}, + 'red_vertices': [0], + 'red_vertices_diff': {'added': [], 'removed': [2]}, + 'sinks': [], + 'sinks_diff': {'added': [], 'removed': [2]}, + 'sources': [2], + 'sources_diff': {'added': [2], 'removed': []}, + 'urban_renewals': [], + 'urban_renewals_diff': {'added': [], 'removed': []}}, 3: {'d_matrix': [ 1 0 1 1] - [ 0 -1 0 0] - [ 0 0 0 1] - [ 1 0 0 1], - 'denominators': [x0*x3, 1, x0, x0*x2*x3], - 'edge_diff': -1, - 'edges': 6, - 'green_vertices': [1], - 'green_vertices_diff': {'added': [], 'removed': [3]}, - 'red_vertices': [0, 2, 3], - 'red_vertices_diff': {'added': [3], 'removed': []}, - 'sinks': [2], - 'sinks_diff': {'added': [], 'removed': []}, - 'sources': [1], - 'sources_diff': {'added': [1], 'removed': []}, - 'urban_renewals': [], - 'urban_renewals_diff': {'added': [], 'removed': []}}} + [ 0 -1 0 0] + [ 0 0 0 1] + [ 1 0 0 1], + 'denominators': [x0*x3, 1, x0, x0*x2*x3], + 'edge_diff': -1, + 'edges': 6, + 'green_vertices': [1], + 'green_vertices_diff': {'added': [], 'removed': [3]}, + 'red_vertices': [0, 2, 3], + 'red_vertices_diff': {'added': [3], 'removed': []}, + 'sinks': [2], + 'sinks_diff': {'added': [], 'removed': []}, + 'sources': [1], + 'sources_diff': {'added': [1], 'removed': []}, + 'urban_renewals': [], + 'urban_renewals_diff': {'added': [], 'removed': []}}} sage: S = ClusterSeed(['A',3]).principal_extension() sage: S.mutation_analysis() {0: {'d_matrix': [ 1 0 0] - [ 0 -1 0] - [ 0 0 -1], - 'denominators': [x0, 1, 1], - 'green_vertices': [1, 2], - 'green_vertices_diff': {'added': [], 'removed': [0]}, - 'red_vertices': [0], - 'red_vertices_diff': {'added': [0], 'removed': []}, - 'sinks': [], - 'sinks_diff': {'added': [], 'removed': [1]}, - 'sources': [4, 5], - 'sources_diff': {'added': [], 'removed': [3]}, - 'urban_renewals': [], - 'urban_renewals_diff': {'added': [], 'removed': []}}, + [ 0 -1 0] + [ 0 0 -1], + 'denominators': [x0, 1, 1], + 'green_vertices': [1, 2], + 'green_vertices_diff': {'added': [], 'removed': [0]}, + 'red_vertices': [0], + 'red_vertices_diff': {'added': [0], 'removed': []}, + 'sinks': [], + 'sinks_diff': {'added': [], 'removed': [1]}, + 'sources': [4, 5], + 'sources_diff': {'added': [], 'removed': [3]}, + 'urban_renewals': [], + 'urban_renewals_diff': {'added': [], 'removed': []}}, 1: {'d_matrix': [-1 0 0] - [ 0 1 0] - [ 0 0 -1], - 'denominators': [1, x1, 1], - 'green_vertices': [0, 2], - 'green_vertices_diff': {'added': [], 'removed': [1]}, - 'red_vertices': [1], - 'red_vertices_diff': {'added': [1], 'removed': []}, - 'sinks': [0, 2, 4], - 'sinks_diff': {'added': [0, 2, 4], 'removed': [1]}, - 'sources': [1, 3, 5], - 'sources_diff': {'added': [1], 'removed': [4]}, - 'urban_renewals': [], - 'urban_renewals_diff': {'added': [], 'removed': []}}, + [ 0 1 0] + [ 0 0 -1], + 'denominators': [1, x1, 1], + 'green_vertices': [0, 2], + 'green_vertices_diff': {'added': [], 'removed': [1]}, + 'red_vertices': [1], + 'red_vertices_diff': {'added': [1], 'removed': []}, + 'sinks': [0, 2, 4], + 'sinks_diff': {'added': [0, 2, 4], 'removed': [1]}, + 'sources': [1, 3, 5], + 'sources_diff': {'added': [1], 'removed': [4]}, + 'urban_renewals': [], + 'urban_renewals_diff': {'added': [], 'removed': []}}, 2: {'d_matrix': [-1 0 0] - [ 0 -1 0] - [ 0 0 1], - 'denominators': [1, 1, x2], - 'green_vertices': [0, 1], - 'green_vertices_diff': {'added': [], 'removed': [2]}, - 'red_vertices': [2], - 'red_vertices_diff': {'added': [2], 'removed': []}, - 'sinks': [], - 'sinks_diff': {'added': [], 'removed': [1]}, - 'sources': [3, 4], - 'sources_diff': {'added': [], 'removed': [5]}, - 'urban_renewals': [], - 'urban_renewals_diff': {'added': [], 'removed': []}}} + [ 0 -1 0] + [ 0 0 1], + 'denominators': [1, 1, x2], + 'green_vertices': [0, 1], + 'green_vertices_diff': {'added': [], 'removed': [2]}, + 'red_vertices': [2], + 'red_vertices_diff': {'added': [2], 'removed': []}, + 'sinks': [], + 'sinks_diff': {'added': [], 'removed': [1]}, + 'sources': [3, 4], + 'sources_diff': {'added': [], 'removed': [5]}, + 'urban_renewals': [], + 'urban_renewals_diff': {'added': [], 'removed': []}}} """ V = range(self._n) if filter is None: @@ -3243,7 +3247,8 @@ def reset_cluster(self): sage: T.cluster() [x0, x1, x2] - sage: S = ClusterSeed(['B',3],user_labels=[[1,2],[2,3],[3,4]],user_labels_prefix='p') + sage: S = ClusterSeed(['B',3], user_labels=[[1,2],[2,3],[3,4]], + ....: user_labels_prefix='p') sage: S.mutate([0,1]) sage: S.cluster() [(p_2_3 + 1)/p_1_2, (p_1_2*p_3_4^2 + p_2_3 + 1)/(p_1_2*p_2_3), p_3_4] @@ -3271,7 +3276,7 @@ def reset_coefficients(self): This raises an error if the number of frozen variables is different than the number of exchangeable variables. - WARNING: This command to be phased out since 'use_c_vectors() does this more effectively. + WARNING: This command to be phased out since :meth:`use_c_vectors` does this more effectively. EXAMPLES:: @@ -3326,10 +3331,10 @@ def mutation_class_iter(self, depth=infinity, show_depth=False, INPUT: - ``depth`` -- (default: infinity) integer or infinity, only seeds with distance at most ``depth`` from ``self`` are returned. - - ``show_depth`` -- (default: False) if True, the current depth of the mutation is shown while computing. - - ``return_paths`` -- (default: False) if True, a shortest path of mutations from ``self`` to the given quiver is returned as well. - - ``up_to_equivalence`` -- (default: True) if True, only one seed up to simultaneous permutation of rows and columns of the exchange matrix is recorded. - - ``sink_source`` -- (default: False) if True, only mutations at sinks and sources are applied. + - ``show_depth`` -- (default: ``False``) if ``True``, the current depth of the mutation is shown while computing. + - ``return_paths`` -- (default: ``False``) if ``True``, a shortest path of mutations from ``self`` to the given quiver is returned as well. + - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only one seed up to simultaneous permutation of rows and columns of the exchange matrix is recorded. + - ``sink_source`` -- (default: ``False``) if ``True``, only mutations at sinks and sources are applied. EXAMPLES: @@ -3387,7 +3392,8 @@ def mutation_class_iter(self, depth=infinity, show_depth=False, sage: len([T for T in it]) 84 - sage: it = ClusterSeed(['A',2]).mutation_class_iter(return_paths=True,up_to_equivalence=False) + sage: it = ClusterSeed(['A',2]).mutation_class_iter(return_paths=True, + ....: up_to_equivalence=False) sage: mutation_class = list(it) sage: len(mutation_class) 10 @@ -3549,13 +3555,13 @@ def mutation_class(self, depth=infinity, show_depth=False, return_paths=False, def cluster_class_iter(self, depth=infinity, show_depth=False, up_to_equivalence=True): r""" - Returns an iterator through all clusters in the mutation class of ``self``. + Return an iterator through all clusters in the mutation class of ``self``. INPUT: - - ``depth`` -- (default: infinity) integer or infinity, only seeds with distance at most depth from self are returned - - ``show_depth`` -- (default False) - if True, ignored if depth is set; returns the depth of the mutation class, i.e., the maximal distance from self of an element in the mutation class - - ``up_to_equivalence`` -- (default: True) if True, only clusters up to equivalence are considered. + - ``depth`` -- (default: infinity) integer or infinity, only seeds with distance at most ``depth`` from ``self`` are returned + - ``show_depth`` -- (default: ``False``) if ``True``, ignored if ``depth`` is set; returns the depth of the mutation class, i.e., the maximal distance from ``self`` of an element in the mutation class + - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only clusters up to equivalence are considered. EXAMPLES: @@ -3631,7 +3637,7 @@ def cluster_class_iter(self, depth=infinity, show_depth=False, up_to_equivalence For a cluster seed from an arbitrarily labelled digraph:: sage: dg = DiGraph([['a', 'b'], ['b', 'c']], format="list_of_edges") - sage: S = ClusterSeed(dg, frozen = ['b']) + sage: S = ClusterSeed(dg, frozen=['b']) sage: S.cluster_class() [[a, c], [a, (b + 1)/c], [(b + 1)/a, c], [(b + 1)/a, (b + 1)/c]] @@ -3649,9 +3655,9 @@ def cluster_class(self, depth=infinity, show_depth=False, up_to_equivalence=True INPUT: - - ``depth`` -- (default: infinity) integer, only seeds with distance at most depth from self are returned - - ``return_depth`` -- (default False) - if True, ignored if depth is set; returns the depth of the mutation class, i.e., the maximal distance from self of an element in the mutation class - - ``up_to_equivalence`` -- (default: True) if True, only clusters up to equivalence are considered. + - ``depth`` -- (default: infinity) integer, only seeds with distance at most ``depth`` from ``self`` are returned + - ``return_depth`` -- (default: ``False``) - if ``True``, ignored if ``depth`` is set; returns the depth of the mutation class, i.e., the maximal distance from ``self`` of an element in the mutation class + - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only clusters up to equivalence are considered. EXAMPLES: @@ -3668,12 +3674,12 @@ def cluster_class(self, depth=infinity, show_depth=False, up_to_equivalence=True def b_matrix_class_iter(self, depth=infinity, up_to_equivalence=True): r""" - Returns an iterator through all `B`-matrices in the mutation class of ``self``. + Return an iterator through all `B`-matrices in the mutation class of ``self``. INPUT: - - ``depth`` -- (default:infinity) integer or infinity, only seeds with distance at most depth from self are returned - - ``up_to_equivalence`` -- (default: True) if True, only 'B'-matrices up to equivalence are considered. + - ``depth`` -- (default:infinity) integer or infinity, only seeds with distance at most ``depth`` from ``self`` are returned + - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only `B`-matrices up to equivalence are considered. EXAMPLES: @@ -3772,12 +3778,12 @@ def b_matrix_class_iter(self, depth=infinity, up_to_equivalence=True): def b_matrix_class(self, depth=infinity, up_to_equivalence=True): r""" - Returns all `B`-matrices in the mutation class of ``self``. + Return all `B`-matrices in the mutation class of ``self``. INPUT: - - ``depth`` -- (default:infinity) integer or infinity, only seeds with distance at most depth from self are returned - - ``up_to_equivalence`` -- (default: True) if True, only 'B'-matrices up to equivalence are considered. + - ``depth`` -- (default: infinity) integer or infinity, only seeds with distance at most ``depth`` from ``self`` are returned + - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only `B`-matrices up to equivalence are considered. EXAMPLES: @@ -3795,12 +3801,12 @@ def b_matrix_class(self, depth=infinity, up_to_equivalence=True): def variable_class_iter(self, depth=infinity, ignore_bipartite_belt=False): r""" - Returns an iterator for all cluster variables in the mutation class of ``self``. + Return an iterator for all cluster variables in the mutation class of ``self``. INPUT: - - ``depth`` -- (default:infinity) integer, only seeds with distance at most depth from self are returned - - ``ignore_bipartite_belt`` -- (default:False) if True, the algorithms does not use the bipartite belt + - ``depth`` -- (default: infinity) integer, only seeds with distance at most ``depth`` from ``self`` are returned + - ``ignore_bipartite_belt`` -- (default: ``False``) if ``True``, the algorithm does not use the bipartite belt EXAMPLES: @@ -3921,12 +3927,12 @@ def variable_class_iter(self, depth=infinity, ignore_bipartite_belt=False): def variable_class(self, depth=infinity, ignore_bipartite_belt=False): r""" - Returns all cluster variables in the mutation class of ``self``. + Return all cluster variables in the mutation class of ``self``. INPUT: - - ``depth`` -- (default:infinity) integer, only seeds with distance at most depth from self are returned - - ``ignore_bipartite_belt`` -- (default:False) if True, the algorithms does not use the bipartite belt + - ``depth`` -- (default: infinity) integer, only seeds with distance at most ``depth`` from ``self`` are returned + - ``ignore_bipartite_belt`` -- (default: ``False``) if ``True``, the algorithms does not use the bipartite belt EXAMPLES: @@ -3970,12 +3976,13 @@ def is_finite(self) -> bool: def is_mutation_finite(self, nr_of_checks=None, return_path=False): r""" - Returns True if ``self`` is of finite mutation type. + Return True if ``self`` is of finite mutation type. INPUT: - - ``nr_of_checks`` -- (default: None) number of mutations applied. Standard is 500*(number of vertices of self). - - ``return_path`` -- (default: False) if True, in case of self not being mutation finite, a path from self to a quiver with an edge label (a,-b) and a*b > 4 is returned. + - ``nr_of_checks`` -- (default: ``None``) number of mutations applied. Standard is 500*(number of vertices of ``self``). + - ``return_path`` -- (default: ``False``) if ``True``, in case of ``self`` not being mutation finite, + a path from ``self`` to a quiver with an edge label `(a,-b)` and `a*b > 4` is returned. ALGORITHM: @@ -4005,7 +4012,7 @@ def is_mutation_finite(self, nr_of_checks=None, return_path=False): def mutation_type(self): r""" - Returns the mutation_type of each connected component of ``self``, if it can be determined. + Return the mutation_type of each connected component of ``self``, if it can be determined. Otherwise, the mutation type of this component is set to be unknown. The mutation types of the components are ordered by vertex labels. @@ -4031,7 +4038,8 @@ def mutation_type(self): sage: S.mutation_type() ['A', 5] - sage: S = ClusterSeed(DiGraph([['a','b'],['c','b'],['c','d'],['e','d']]), frozen = ['c']) + sage: S = ClusterSeed(DiGraph([['a','b'],['c','b'],['c','d'],['e','d']]), + ....: frozen=['c']) sage: S.mutation_type() [ ['A', 2], ['A', 2] ] @@ -4073,10 +4081,10 @@ def mutation_type(self): def greedy(self, a1, a2, algorithm='by_recursion'): r""" - Returns the greedy element `x[a_1,a_2]` assuming that self is rank two. + Return the greedy element `x[a_1,a_2]` assuming that self is rank two. - The third input can be 'by_recursion', 'by_combinatorics', or - 'just_numbers' to specify if the user wants the element + The third input can be ``'by_recursion'``, ``'by_combinatorics'``, or + ``'just_numbers'`` to specify if the user wants the element computed by the recurrence, combinatorial formula, or wants to set `x_1` and `x_2` to be one. @@ -4086,9 +4094,11 @@ def greedy(self, a1, a2, algorithm='by_recursion'): sage: S = ClusterSeed(['R2', [3, 3]]) sage: S.greedy(4, 4) - (x0^12 + x1^12 + 4*x0^9 + 4*x1^9 + 6*x0^6 + 4*x0^3*x1^3 + 6*x1^6 + 4*x0^3 + 4*x1^3 + 1)/(x0^4*x1^4) + (x0^12 + x1^12 + 4*x0^9 + 4*x1^9 + 6*x0^6 + + 4*x0^3*x1^3 + 6*x1^6 + 4*x0^3 + 4*x1^3 + 1)/(x0^4*x1^4) sage: S.greedy(4, 4, 'by_combinatorics') - (x0^12 + x1^12 + 4*x0^9 + 4*x1^9 + 6*x0^6 + 4*x0^3*x1^3 + 6*x1^6 + 4*x0^3 + 4*x1^3 + 1)/(x0^4*x1^4) + (x0^12 + x1^12 + 4*x0^9 + 4*x1^9 + 6*x0^6 + + 4*x0^3*x1^3 + 6*x1^6 + 4*x0^3 + 4*x1^3 + 1)/(x0^4*x1^4) sage: S.greedy(4, 4, 'just_numbers') 35 sage: S = ClusterSeed(['R2', [2, 2]]) @@ -4163,7 +4173,7 @@ def oriented_exchange_graph(self): The seed must be a cluster seed for a cluster algebra of finite type with principal coefficients (the corresponding - quiver must have mutable vertices 0,1,...,n-1). + quiver must have mutable vertices `0,1,...,n-1`). EXAMPLES:: @@ -4221,7 +4231,7 @@ def oriented_exchange_graph(self): def find_upper_bound(self, verbose=False): r""" - Return the upper bound of the given cluster algebra as a quotient_ring. + Return the upper bound of the given cluster algebra as a quotient ring. The upper bound is the intersection of the Laurent polynomial rings of the initial cluster and its neighboring clusters. As @@ -4254,15 +4264,24 @@ def find_upper_bound(self, verbose=False): sage: S = ClusterSeed(['A',3]) sage: S.find_upper_bound() - Quotient of Multivariate Polynomial Ring in x0, x1, x2, x0p, x1p, x2p, z0 over Rational Field by the ideal (x0*x0p - x1 - 1, x1*x1p - x0*x2 - 1, x2*x2p - x1 - 1, x0*z0 - x2p, x1*z0 + z0 - x0p*x2p, x2*z0 - x0p, x1p*z0 + z0 - x0p*x1p*x2p + x1 + 1) + Quotient of Multivariate Polynomial Ring in x0, x1, x2, x0p, x1p, x2p, z0 + over Rational Field + by the ideal (x0*x0p - x1 - 1, x1*x1p - x0*x2 - 1, x2*x2p - x1 - 1, + x0*z0 - x2p, x1*z0 + z0 - x0p*x2p, x2*z0 - x0p, + x1p*z0 + z0 - x0p*x1p*x2p + x1 + 1) - Markov:: sage: B = matrix([[0,2,-2],[-2,0,2],[2,-2,0]]) sage: S = ClusterSeed(B) sage: S.find_upper_bound() - Quotient of Multivariate Polynomial Ring in x0, x1, x2, x0p, x1p, x2p, z0 over Rational Field by the ideal (x0*x0p - x2^2 - x1^2, x1*x1p - x2^2 - x0^2, x2*x2p - x1^2 - x0^2, x0p*x1p*x2p - x0*x1*x2p - x0*x2*x1p - x1*x2*x0p - 2*x0*x1*x2, x0^3*z0 - x1p*x2p + x1*x2, x0*x1*z0 - x2p - x2, x1^3*z0 - x0p*x2p + x0*x2, x0*x2*z0 - x1p - x1, x1*x2*z0 - x0p - x0, x2^3*z0 - x0p*x1p + x0*x1) - + Quotient of Multivariate Polynomial Ring in x0, x1, x2, x0p, x1p, x2p, z0 + over Rational Field + by the ideal (x0*x0p - x2^2 - x1^2, x1*x1p - x2^2 - x0^2, x2*x2p - x1^2 - x0^2, + x0p*x1p*x2p - x0*x1*x2p - x0*x2*x1p - x1*x2*x0p - 2*x0*x1*x2, + x0^3*z0 - x1p*x2p + x1*x2, x0*x1*z0 - x2p - x2, + x1^3*z0 - x0p*x2p + x0*x2, x0*x2*z0 - x1p - x1, + x1*x2*z0 - x0p - x0, x2^3*z0 - x0p*x1p + x0*x1) """ rank = self.n() @@ -4327,18 +4346,18 @@ def find_upper_bound(self, verbose=False): def get_upper_cluster_algebra_element(self,a): r""" - Computes an element in the upper cluster algebra of `B` corresponding to the vector `a \in \ZZ^n`. + Compute an element in the upper cluster algebra of `B` corresponding to the vector `a \in \ZZ^n`. See [LLM2014]_ for more details. INPUT: - `B` -- a skew-symmetric matrix. Must have the same number of columns as the length of the vectors in `vd`. - - `a` -- a vector in `\ZZ^n` where `n` is the number of columns in `B`. + - ``a`` -- a vector in `\ZZ^n` where `n` is the number of columns in `B`. OUTPUT: - Returns an element in the upper cluster algebra. Depending on the input it may or may not be irreducible. + Return an element in the upper cluster algebra. Depending on the input it may or may not be irreducible. EXAMPLES:: @@ -4427,7 +4446,7 @@ def _compute_compatible_vectors(self, vd): - `B` -- a skew-symmetric matrix. Must have the same number of columns as the length of the vectors in ``vd``. - ``vd`` -- a collection of tuples `(v,z)` with `v \in \{0,1\}^n` and `z \in \ZZ`. - `n` must be the number of columns in `B`. Taken from the output of vector_decomposition. + `n` must be the number of columns in `B`. Taken from the output of vector_decomposition. OUTPUT: @@ -4758,7 +4777,7 @@ def get_green_vertices(C): INPUT: - - ``C`` -- The C matrix to check + - ``C`` -- The C-matrix to check EXAMPLES:: @@ -4779,7 +4798,7 @@ def get_red_vertices(C): INPUT: - - ``C`` -- The C matrix to check + - ``C`` -- The C-matrix to check EXAMPLES:: @@ -4804,7 +4823,7 @@ def _vector_decomposition(a, length): A decomposition of `a` into vectors `b_i \in \{0,1\}^n` such that `a= \sum c_i b_i` for `c_i \in \ZZ.` - Returns an array of tuples `\right[b_i,c_i\left].` + Return an array of tuples `\right[b_i,c_i\left].` EXAMPLES:: diff --git a/src/sage/combinat/cluster_algebra_quiver/interact.py b/src/sage/combinat/cluster_algebra_quiver/interact.py index 1c88e613b4c..f0225803be1 100644 --- a/src/sage/combinat/cluster_algebra_quiver/interact.py +++ b/src/sage/combinat/cluster_algebra_quiver/interact.py @@ -10,8 +10,8 @@ def cluster_interact(self, fig_size=1, circular=True, kind='seed'): Only in *Jupyter notebook mode*. - Not to be called directly. Use the interact methods - of ClusterSeed and ClusterQuiver instead. + Not to be called directly. Use the :meth:`interact` methods + of :class:`ClusterSeed` and :class:`ClusterQuiver` instead. INPUT: @@ -26,7 +26,7 @@ def cluster_interact(self, fig_size=1, circular=True, kind='seed'): TESTS:: sage: S = ClusterSeed(['A',4]) - sage: S.interact() # indirect doctest + sage: S.interact() # indirect doctest # optional - sage.symbolic ...VBox(children=... """ if kind not in ['seed', 'quiver']: diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver.py b/src/sage/combinat/cluster_algebra_quiver/quiver.py index 5a34fed2294..ba1168749b7 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver.py @@ -549,11 +549,11 @@ def plot(self, circular=True, center=(0, 0), directed=True, mark=None, EXAMPLES:: sage: Q = ClusterQuiver(['A',5]) - sage: Q.plot() + sage: Q.plot() # optional - sage.plot sage.symbolic Graphics object consisting of 15 graphics primitives - sage: Q.plot(circular=True) + sage: Q.plot(circular=True) # optional - sage.plot sage.symbolic Graphics object consisting of 15 graphics primitives - sage: Q.plot(circular=True, mark=1) + sage: Q.plot(circular=True, mark=1) # optional - sage.plot sage.symbolic Graphics object consisting of 15 graphics primitives """ from sage.plot.colors import rainbow @@ -699,7 +699,7 @@ def interact(self, fig_size=1, circular=True): TESTS:: sage: S = ClusterQuiver(['A',4]) - sage: S.interact() + sage: S.interact() # optional - sage.plot sage.symbolic ...VBox(children=... """ return cluster_interact(self, fig_size, circular, kind="quiver") @@ -717,7 +717,7 @@ def save_image(self, filename, circular=False): sage: Q = ClusterQuiver(['F',4,[1,2]]) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: + sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: # optional - sage.plot sage.symbolic ....: Q.save_image(f.name) """ graph_plot = self.plot(circular=circular) 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 13349acbb42..66b2385b3af 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py @@ -677,7 +677,7 @@ def plot(self, circular=False, directed=True): INPUT: - - ``circular`` -- (default:``False``) if ``True``, the + - ``circular`` -- (default: ``False``) if ``True``, the circular plot is chosen, otherwise >>spring<< is used. - ``directed`` -- (default: ``True``) if ``True``, the @@ -686,8 +686,8 @@ def plot(self, circular=False, directed=True): EXAMPLES:: sage: QMT = QuiverMutationType(['A',5]) - sage: pl = QMT.plot() - sage: pl = QMT.plot(circular=True) + sage: pl = QMT.plot() # optional - sage.plot sage.symbolic + sage: pl = QMT.plot(circular=True) # optional - sage.plot sage.symbolic """ return self.standard_quiver().plot(circular=circular, directed=directed) @@ -783,7 +783,7 @@ def b_matrix(self): EXAMPLES:: - sage: mut_type = QuiverMutationType( ['A',5] ); mut_type + sage: mut_type = QuiverMutationType(['A',5]); mut_type ['A', 5] sage: mut_type.b_matrix() [ 0 1 0 0 0] diff --git a/src/sage/combinat/crystals/mv_polytopes.py b/src/sage/combinat/crystals/mv_polytopes.py index ddcff43c6f4..bcb2654da60 100644 --- a/src/sage/combinat/crystals/mv_polytopes.py +++ b/src/sage/combinat/crystals/mv_polytopes.py @@ -85,7 +85,7 @@ def _latex_(self): sage: MV = crystals.infinity.MVPolytopes(['A',2]) sage: u = MV.highest_weight_vector() sage: b = u.f_string([1,2,2,1]) - sage: latex(b) + sage: latex(b) # optional - sage.symbolic \begin{tikzpicture} \draw (0, 0) -- (3/2, -989/1142) -- (3/2, -2967/1142) -- (0, -1978/571); \draw (0, 0) -- (-3/2, -989/1142) -- (-3/2, -2967/1142) -- (0, -1978/571); diff --git a/src/sage/combinat/designs/block_design.py b/src/sage/combinat/designs/block_design.py index 608a06581e1..cb81f997f3d 100644 --- a/src/sage/combinat/designs/block_design.py +++ b/src/sage/combinat/designs/block_design.py @@ -404,16 +404,16 @@ def q3_minus_one_matrix(K): sage: m.multiplicative_order() == 3**3 - 1 True - sage: m = q3_minus_one_matrix(GF(4,'a')) - sage: m.multiplicative_order() == 4**3 - 1 + sage: m = q3_minus_one_matrix(GF(4, 'a')) # optional - sage.symbolic + sage: m.multiplicative_order() == 4**3 - 1 # optional - sage.symbolic True sage: m = q3_minus_one_matrix(GF(5)) sage: m.multiplicative_order() == 5**3 - 1 True - sage: m = q3_minus_one_matrix(GF(9,'a')) - sage: m.multiplicative_order() == 9**3 - 1 + sage: m = q3_minus_one_matrix(GF(9, 'a')) # optional - sage.symbolic + sage: m.multiplicative_order() == 9**3 - 1 # optional - sage.symbolic True """ q = K.cardinality() diff --git a/src/sage/combinat/designs/difference_family.py b/src/sage/combinat/designs/difference_family.py index 52a95805ea5..51cbd1e0501 100644 --- a/src/sage/combinat/designs/difference_family.py +++ b/src/sage/combinat/designs/difference_family.py @@ -2040,9 +2040,6 @@ def skew_supplementary_difference_set_over_polynomial_ring(n, existence=False, c ... NotImplementedError: skew SDS of order 7 not yet implemented """ - from sage.symbolic.ring import SymbolicRing - from sage.rings.finite_rings.integer_mod_ring import Zmod - data = { 81: (3, lambda x: x**4 - x**3 - 1, 16, 5, [1, 2, 4, 6, 8, 10, 12, 14], [1, 2, 3, 4, 10, 11, 13], @@ -2060,6 +2057,9 @@ def skew_supplementary_difference_set_over_polynomial_ring(n, existence=False, c mod, poly, exp, order, ind1, ind2, ind3, ind4 = data[n] + from sage.symbolic.ring import SymbolicRing + from sage.rings.finite_rings.integer_mod_ring import Zmod + Z3 = Zmod(mod) R = SymbolicRing() x = R.var('x') diff --git a/src/sage/combinat/designs/incidence_structures.py b/src/sage/combinat/designs/incidence_structures.py index 1aa6c34d733..94f2e3f9c0d 100644 --- a/src/sage/combinat/designs/incidence_structures.py +++ b/src/sage/combinat/designs/incidence_structures.py @@ -433,20 +433,21 @@ def is_isomorphic(self, other, certificate=False): TESTS:: - sage: IS = IncidenceStructure([["A",5,pi],["A",5,"Wouhou"],["A","Wouhou",(9,9)],[pi,12]]) - sage: IS2 = IS.copy() - sage: IS2.relabel(IS2.canonical_label()) - sage: IS.is_isomorphic(IS2) + sage: IS = IncidenceStructure([["A",5,pi],["A",5,"Wouhou"], # optional - sage.symbolic + ....: ["A","Wouhou",(9,9)],[pi,12]]) + sage: IS2 = IS.copy() # optional - sage.symbolic + sage: IS2.relabel(IS2.canonical_label()) # optional - sage.symbolic + sage: IS.is_isomorphic(IS2) # optional - sage.symbolic True - sage: canon = IS.is_isomorphic(IS2,certificate=True) - sage: IS.relabel(canon) - sage: IS==IS2 + sage: canon = IS.is_isomorphic(IS2, certificate=True) # optional - sage.symbolic + sage: IS.relabel(canon) # optional - sage.symbolic + sage: IS==IS2 # optional - sage.symbolic True sage: IS2 = IncidenceStructure([[1,2]]) - sage: IS2.is_isomorphic(IS) + sage: IS2.is_isomorphic(IS) # optional - sage.symbolic False - sage: IS2.is_isomorphic(IS,certificate=True) + sage: IS2.is_isomorphic(IS, certificate=True) # optional - sage.symbolic {} Checking whether two :class:`IncidenceStructure` are isomorphic @@ -454,7 +455,7 @@ def is_isomorphic(self, other, certificate=False): subsequent calls to :meth:`is_isomorphic` will be faster:: sage: IS1 = designs.projective_plane(3) - sage: IS2 = IS1.relabel(Permutations(IS1.ground_set()).random_element(),inplace=False) + sage: IS2 = IS1.relabel(Permutations(IS1.ground_set()).random_element(), inplace=False) sage: IS2 = IncidenceStructure(IS2.blocks()) sage: IS1._canonical_label is None and IS2._canonical_label is None True diff --git a/src/sage/combinat/diagram_algebras.py b/src/sage/combinat/diagram_algebras.py index bd281fdbb77..4909dc33f09 100644 --- a/src/sage/combinat/diagram_algebras.py +++ b/src/sage/combinat/diagram_algebras.py @@ -2490,21 +2490,21 @@ class PartitionAlgebra(DiagramBasis, UnitDiagramMixin): Shorthands for working with basis elements are as follows:: sage: S = SymmetricGroupAlgebra(ZZ, 3) - sage: A = PartitionAlgebra(3, x, SR) + sage: A = PartitionAlgebra(3, x, SR) # optional - sage.symbolic - sage: A([[1,3],[-1],[-3]]) # pair up the omitted nodes as `{-i, i}`, if possible + sage: A([[1,3],[-1],[-3]]) # pair up the omitted nodes as `{-i, i}`, if possible # optional - sage.symbolic P{{-3}, {-2, 2}, {-1}, {1, 3}} - sage: A([[1,3],[-1],[-3]]) == A[[1,3],[-1],[-3]] + sage: A([[1,3],[-1],[-3]]) == A[[1,3],[-1],[-3]] # optional - sage.symbolic True - sage: A([[1,2]]) + sage: A([[1,2]]) # optional - sage.symbolic P{{-3, 3}, {-2}, {-1}, {1, 2}} - sage: A([[1,2]]) == A[[1,2]] + sage: A([[1,2]]) == A[[1,2]] # optional - sage.symbolic True - sage: A([2,3,1]) # permutations in one-line notation are imported as well + sage: A([2,3,1]) # permutations in one-line notation are imported as well # optional - sage.symbolic P{{-3, 2}, {-2, 1}, {-1, 3}} - sage: A([2,3,1]) == A(S([2,3,1])) + sage: A([2,3,1]) == A(S([2,3,1])) # optional - sage.symbolic True """ @staticmethod @@ -3592,9 +3592,9 @@ def ambient(self): EXAMPLES:: - sage: x = var('x') - sage: BA = BrauerAlgebra(2, x) - sage: BA.ambient() + sage: x = var('x') # optional - sage.symbolic + sage: BA = BrauerAlgebra(2, x) # optional - sage.symbolic + sage: BA.ambient() # optional - sage.symbolic Partition Algebra of rank 2 with parameter x over Symbolic Ring """ return self.lift.codomain() @@ -3833,11 +3833,11 @@ def jucys_murphy(self, j): EXAMPLES:: - sage: z = var('z') - sage: B = BrauerAlgebra(3,z) - sage: B.jucys_murphy(1) + sage: z = var('z') # optional - sage.symbolic + sage: B = BrauerAlgebra(3,z) # optional - sage.symbolic + sage: B.jucys_murphy(1) # optional - sage.symbolic (1/2*z-1/2)*B{{-3, 3}, {-2, 2}, {-1, 1}} - sage: B.jucys_murphy(3) + sage: B.jucys_murphy(3) # optional - sage.symbolic -B{{-3, -2}, {-1, 1}, {2, 3}} - B{{-3, -1}, {-2, 2}, {1, 3}} + B{{-3, 1}, {-2, 2}, {-1, 3}} + B{{-3, 2}, {-2, 3}, {-1, 1}} + (1/2*z-1/2)*B{{-3, 3}, {-2, 2}, {-1, 1}} diff --git a/src/sage/combinat/finite_state_machine.py b/src/sage/combinat/finite_state_machine.py index 2c1f52e9588..04106d2b7a3 100644 --- a/src/sage/combinat/finite_state_machine.py +++ b/src/sage/combinat/finite_state_machine.py @@ -10437,11 +10437,11 @@ def moments_waiting_time(self, test=bool, is_zero=None, and the variance are `\sum_{k\ge 1} k2^{-k}=2` and `\sum_{k\ge 1} (k-2)^2 2^{-k}=2`:: - sage: var('k') + sage: var('k') # optional - sage.symbolic k - sage: sum(k * 2^(-k), k, 1, infinity) + sage: sum(k * 2^(-k), k, 1, infinity) # optional - sage.symbolic 2 - sage: sum((k-2)^2 * 2^(-k), k, 1, infinity) + sage: sum((k-2)^2 * 2^(-k), k, 1, infinity) # optional - sage.symbolic 2 We now compute the same expectation and variance by using a @@ -11846,13 +11846,13 @@ def shannon_parry_markov_chain(self): sage: NAF = Automaton([(0, 0, 0), (0, 1, 1), (0, 1, -1), ....: (1, 0, 0)], initial_states=[0], ....: final_states=[0, 1]) - sage: P_NAF = NAF.shannon_parry_markov_chain() - sage: P_NAF.transitions() + sage: P_NAF = NAF.shannon_parry_markov_chain() # optional - sage.symbolic + sage: P_NAF.transitions() # optional - sage.symbolic [Transition from 0 to 0: 1/2|0, Transition from 0 to 1: 1/4|1, Transition from 0 to 1: 1/4|-1, Transition from 1 to 0: 1|0] - sage: for s in P_NAF.iter_states(): + sage: for s in P_NAF.iter_states(): # optional - sage.symbolic ....: print(s.color) 3/4 3/2 @@ -11860,7 +11860,7 @@ def shannon_parry_markov_chain(self): The stationary distribution is also computed and saved as the initial probabilities of the returned Markov chain:: - sage: for s in P_NAF.states(): + sage: for s in P_NAF.states(): # optional - sage.symbolic ....: print("{} {}".format(s, s.initial_probability)) 0 2/3 1 1/3 diff --git a/src/sage/combinat/k_tableau.py b/src/sage/combinat/k_tableau.py index 5fb1d56b82c..5beac7acb5e 100644 --- a/src/sage/combinat/k_tableau.py +++ b/src/sage/combinat/k_tableau.py @@ -205,7 +205,7 @@ def WeakTableaux(k, shape , weight, representation = "core"): for the 'bounded' representation, the shape is inputted as a `k`-bounded partition; for skew tableaux, the shape is inputted as a tuple of the outer and inner shape - ``weight`` -- the weight of the weak `k`-tableaux as a list or tuple - - ``representation`` -- 'core', 'bounded', or 'factorized_permutation' (default: 'core') + - ``representation`` -- ``'core'``, ``'bounded'``, or ``'factorized_permutation'`` (default: ``'core'``) EXAMPLES:: diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 8e3b777c35e..5513086de21 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -3279,9 +3279,9 @@ def hook_product(self, a): EXAMPLES:: - sage: Partition([3,2,1]).hook_product(x) + sage: Partition([3,2,1]).hook_product(x) # optional - sage.symbolic (2*x + 3)*(x + 2)^2 - sage: Partition([2,2]).hook_product(x) + sage: Partition([2,2]).hook_product(x) # optional - sage.symbolic 2*(x + 2)*(x + 1) """ @@ -3422,7 +3422,7 @@ def upper_hook(self, i, j, alpha): 3 sage: p.hook_length(0,0) 3 - sage: [ p.upper_hook(i,j,x) for i,j in p.cells() ] + sage: [ p.upper_hook(i,j,x) for i,j in p.cells() ] # optional - sage.symbolic [2*x + 1, x, x] """ p = self @@ -3444,7 +3444,7 @@ def upper_hook_lengths(self, alpha): EXAMPLES:: - sage: Partition([3,2,1]).upper_hook_lengths(x) + sage: Partition([3,2,1]).upper_hook_lengths(x) # optional - sage.symbolic [[3*x + 2, 2*x + 1, x], [2*x + 1, x], [x]] sage: Partition([3,2,1]).upper_hook_lengths(1) [[5, 3, 1], [3, 1], [1]] @@ -3474,7 +3474,7 @@ def lower_hook(self, i, j, alpha): 3 sage: p.hook_length(0,0) 3 - sage: [ p.lower_hook(i,j,x) for i,j in p.cells() ] + sage: [ p.lower_hook(i,j,x) for i,j in p.cells() ] # optional - sage.symbolic [x + 2, 1, 1] """ p = self @@ -3496,7 +3496,7 @@ def lower_hook_lengths(self, alpha): EXAMPLES:: - sage: Partition([3,2,1]).lower_hook_lengths(x) + sage: Partition([3,2,1]).lower_hook_lengths(x) # optional - sage.symbolic [[2*x + 3, x + 2, 1], [x + 2, 1], [1]] sage: Partition([3,2,1]).lower_hook_lengths(1) [[5, 3, 1], [3, 1], [1]] @@ -5310,18 +5310,19 @@ def outline(self, variable=None): EXAMPLES:: - sage: [Partition([5,4]).outline()(x=i) for i in range(-10,11)] + sage: [Partition([5,4]).outline()(x=i) for i in range(-10,11)] # optional - sage.symbolic [10, 9, 8, 7, 6, 5, 6, 5, 6, 5, 4, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10] - sage: Partition([]).outline() + sage: Partition([]).outline() # optional - sage.symbolic abs(x) - sage: Partition([1]).outline() + sage: Partition([1]).outline() # optional - sage.symbolic abs(x + 1) + abs(x - 1) - abs(x) - sage: y = SR.var("y") - sage: Partition([6,5,1]).outline(variable=y) - abs(y + 6) - abs(y + 5) + abs(y + 4) - abs(y + 3) + abs(y - 1) - abs(y - 2) + abs(y - 3) + sage: y = SR.var("y") # optional - sage.symbolic + sage: Partition([6,5,1]).outline(variable=y) # optional - sage.symbolic + abs(y + 6) - abs(y + 5) + abs(y + 4) - abs(y + 3) + + abs(y - 1) - abs(y - 2) + abs(y - 3) TESTS:: diff --git a/src/sage/combinat/path_tableaux/frieze.py b/src/sage/combinat/path_tableaux/frieze.py index fd33a72ff26..d63935a6a3b 100644 --- a/src/sage/combinat/path_tableaux/frieze.py +++ b/src/sage/combinat/path_tableaux/frieze.py @@ -84,9 +84,10 @@ class FriezePattern(PathTableau, metaclass=InheritComparisonClasscallMetaclass): This constructs the examples from [HJ18]_:: - sage: K.<sqrt3> = NumberField(x^2-3) - sage: t = path_tableaux.FriezePattern([1,sqrt3,2,sqrt3,1,1], field=K) - sage: path_tableaux.CylindricalDiagram(t) + sage: x = polygen(ZZ, 'x') + sage: K.<sqrt3> = NumberField(x^2 - 3) # optional - sage.rings.number_field + sage: t = path_tableaux.FriezePattern([1,sqrt3,2,sqrt3,1,1], field=K) # optional - sage.rings.number_field + sage: path_tableaux.CylindricalDiagram(t) # optional - sage.rings.number_field [ 0, 1, sqrt3, 2, sqrt3, 1, 1, 0] [ , 0, 1, sqrt3, 2, sqrt3, sqrt3 + 1, 1, 0] [ , , 0, 1, sqrt3, 2, sqrt3 + 2, sqrt3, 1, 0] @@ -96,11 +97,12 @@ class FriezePattern(PathTableau, metaclass=InheritComparisonClasscallMetaclass): [ , , , , , , 0, 1, sqrt3 + 1, sqrt3 + 2, sqrt3 + 2, sqrt3 + 1, 1, 0] [ , , , , , , , 0, 1, sqrt3, 2, sqrt3, 1, 1, 0] - sage: TestSuite(t).run() + sage: TestSuite(t).run() # optional - sage.rings.number_field - sage: K.<sqrt2> = NumberField(x^2-2) - sage: t = path_tableaux.FriezePattern([1,sqrt2,1,sqrt2,3,2*sqrt2,5,3*sqrt2,1], field=K) - sage: path_tableaux.CylindricalDiagram(t) + sage: K.<sqrt2> = NumberField(x^2 - 2) # optional - sage.rings.number_field + sage: t = path_tableaux.FriezePattern([1,sqrt2,1,sqrt2,3,2*sqrt2,5,3*sqrt2,1], # optional - sage.rings.number_field + ....: field=K) + sage: path_tableaux.CylindricalDiagram(t) # optional - sage.rings.number_field [ 0, 1, sqrt2, 1, sqrt2, 3, 2*sqrt2, 5, 3*sqrt2, 1, 0] [ , 0, 1, sqrt2, 3, 5*sqrt2, 7, 9*sqrt2, 11, 2*sqrt2, 1, 0] [ , , 0, 1, 2*sqrt2, 7, 5*sqrt2, 13, 8*sqrt2, 3, sqrt2, 1, 0] @@ -113,7 +115,7 @@ class FriezePattern(PathTableau, metaclass=InheritComparisonClasscallMetaclass): [ , , , , , , , , , 0, 1, 2*sqrt2, 3, sqrt2, 1, sqrt2, 1, sqrt2, 1, 0] [ , , , , , , , , , , 0, 1, sqrt2, 1, sqrt2, 3, 2*sqrt2, 5, 3*sqrt2, 1, 0] - sage: TestSuite(t).run() + sage: TestSuite(t).run() # optional - sage.rings.number_field """ @staticmethod def __classcall_private__(cls, fp, field=QQ): @@ -132,13 +134,14 @@ def __classcall_private__(cls, fp, field=QQ): ... ValueError: invalid input 2 - sage: K.<sqrt3> = NumberField(x^2-3) - sage: t = path_tableaux.FriezePattern([1,sqrt3,2,sqrt3,1,1]) + sage: x = polygen(ZZ, 'x') + sage: K.<sqrt3> = NumberField(x^2 - 3) # optional - sage.rings.number_field + sage: t = path_tableaux.FriezePattern([1,sqrt3,2,sqrt3,1,1]) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: [1, sqrt3, 2, sqrt3, 1, 1] is not a sequence in the field Rational Field - sage: path_tableaux.FriezePattern([1,2,1,2,3,1],field=Integers()) + sage: path_tableaux.FriezePattern([1,2,1,2,3,1], field=Integers()) Traceback (most recent call last): ... ValueError: Integer Ring must be a field @@ -274,8 +277,9 @@ def is_positive(self): sage: path_tableaux.FriezePattern([1,-3,4,5,1]).is_positive() False - sage: K.<sqrt3> = NumberField(x^2-3) - sage: path_tableaux.FriezePattern([1,sqrt3,1],K).is_positive() + sage: x = polygen(ZZ, 'x') + sage: K.<sqrt3> = NumberField(x^2 - 3) # optional - sage.rings.number_field + sage: path_tableaux.FriezePattern([1,sqrt3,1], K).is_positive() # optional - sage.rings.number_field True """ return all(a > 0 for a in self[1:-1]) @@ -312,14 +316,15 @@ def triangulation(self): EXAMPLES:: - sage: path_tableaux.FriezePattern([1,2,7,5,3,7,4,1]).triangulation() + sage: path_tableaux.FriezePattern([1,2,7,5,3,7,4,1]).triangulation() # optional - sage.plot sage.symbolic Graphics object consisting of 25 graphics primitives - sage: path_tableaux.FriezePattern([1,2,1/7,5,3]).triangulation() + sage: path_tableaux.FriezePattern([1,2,1/7,5,3]).triangulation() # optional - sage.plot sage.symbolic Graphics object consisting of 12 graphics primitives - sage: K.<sqrt2> = NumberField(x^2-2) - sage: path_tableaux.FriezePattern([1,sqrt2,1,sqrt2,3,2*sqrt2,5,3*sqrt2,1], field=K).triangulation() + sage: K.<sqrt2> = NumberField(x^2 - 2) # optional - sage.rings.number_field + sage: path_tableaux.FriezePattern([1,sqrt2,1,sqrt2,3,2*sqrt2,5,3*sqrt2,1], # optional - sage.plot sage.rings.number_field sage.symbolic + ....: field=K).triangulation() Graphics object consisting of 24 graphics primitives """ n = len(self)-1 @@ -372,17 +377,17 @@ def plot(self, model='UHP'): EXAMPLES:: sage: t = path_tableaux.FriezePattern([1,2,7,5,3,7,4,1]) - sage: t.plot() + sage: t.plot() # optional - sage.plot sage.symbolic Graphics object consisting of 18 graphics primitives - sage: t.plot(model='UHP') + sage: t.plot(model='UHP') # optional - sage.plot sage.symbolic Graphics object consisting of 18 graphics primitives - sage: t.plot(model='PD') + sage: t.plot(model='PD') # optional - sage.plot sage.symbolic Traceback (most recent call last): ... TypeError: '>' not supported between instances of 'NotANumber' and 'Pi' - sage: t.plot(model='KM') + sage: t.plot(model='KM') # optional - sage.plot sage.symbolic Graphics object consisting of 18 graphics primitives """ from sage.geometry.hyperbolic_space.hyperbolic_interface import HyperbolicPlane diff --git a/src/sage/combinat/perfect_matching.py b/src/sage/combinat/perfect_matching.py index 383f6522903..9d57f0b59ac 100644 --- a/src/sage/combinat/perfect_matching.py +++ b/src/sage/combinat/perfect_matching.py @@ -453,11 +453,11 @@ def Weingarten_function(self, d, other=None): EXAMPLES:: - sage: var('N') + sage: var('N') # optional - sage.symbolic N sage: m = PerfectMatching([(1,3),(2,4)]) sage: n = PerfectMatching([(1,2),(3,4)]) - sage: factor(m.Weingarten_function(N,n)) + sage: factor(m.Weingarten_function(N, n)) # optional - sage.symbolic -1/((N + 2)*(N - 1)*N) """ if other is None: @@ -764,8 +764,8 @@ def Weingarten_matrix(self, N): EXAMPLES:: - sage: M = PerfectMatchings(4).Weingarten_matrix(var('N')) - sage: N*(N-1)*(N+2)*M.apply_map(factor) + sage: M = PerfectMatchings(4).Weingarten_matrix(var('N')) # optional - sage.symbolic + sage: N*(N-1)*(N+2)*M.apply_map(factor) # optional - sage.symbolic [N + 1 -1 -1] [ -1 N + 1 -1] [ -1 -1 N + 1] diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index fe3385e7472..2217b59a7bc 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -2783,7 +2783,7 @@ def is_incomparable_chain_free(self, m, n=None) -> bool: sage: Q = Poset({0:[2], 1:[2], 2:[3], 3:[4], 4:[]}) sage: Q.is_incomparable_chain_free(2, 20/10) True - sage: Q.is_incomparable_chain_free(2, pi) + sage: Q.is_incomparable_chain_free(2, pi) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: 2 and pi must be integers @@ -8732,7 +8732,7 @@ def kazhdan_lusztig_polynomial(self, x=None, y=None, q=None, canonical_labels=No sage: y = '3421' sage: L.kazhdan_lusztig_polynomial(x, y) -q + 1 - sage: L.kazhdan_lusztig_polynomial(x, y, var('t')) + sage: L.kazhdan_lusztig_polynomial(x, y, var('t')) # optional - sage.symbolic -t + 1 AUTHORS: diff --git a/src/sage/combinat/q_analogues.py b/src/sage/combinat/q_analogues.py index 0b204630b93..541fc98353c 100644 --- a/src/sage/combinat/q_analogues.py +++ b/src/sage/combinat/q_analogues.py @@ -248,18 +248,18 @@ def q_binomial(n, k, q=None, algorithm='auto'): This also works for variables in the symbolic ring:: - sage: z = var('z') - sage: factor(q_binomial(4, 2, z)) + sage: z = var('z') # optional - sage.symbolic + sage: factor(q_binomial(4, 2, z)) # optional - sage.symbolic (z^2 + z + 1)*(z^2 + 1) This also works for complex roots of unity:: - sage: q_binomial(10, 4, QQbar(I)) + sage: q_binomial(10, 4, QQbar(I)) # optional - sage.rings.number_field 2 Note that the symbolic computation works (see :trac:`14982`):: - sage: q_binomial(10, 4, I) + sage: q_binomial(10, 4, I) # optional - sage.rings.number_field 2 Check that the algorithm does not matter:: @@ -578,7 +578,7 @@ def q_pochhammer(n, a, q=None): 1 sage: q_pochhammer(0, 1) 1 - sage: q_pochhammer(0, var('a')) + sage: q_pochhammer(0, var('a')) # optional - sage.symbolic 1 We check that :trac:`25715` is fixed:: @@ -637,7 +637,7 @@ def q_jordan(t, q=None): [615195, 40635, 5643, 2331, 1491, 515, 147, 87, 47, 11, 1] sage: q_jordan([3,2,1]) 16*q^4 + 24*q^3 + 14*q^2 + 5*q + 1 - sage: q_jordan([2,1], x) + sage: q_jordan([2,1], x) # optional - sage.symbolic 2*x + 1 If the partition is trivial (i.e. has only one part), we get diff --git a/src/sage/combinat/ribbon_tableau.py b/src/sage/combinat/ribbon_tableau.py index a2955884c7d..65b9b7079cd 100644 --- a/src/sage/combinat/ribbon_tableau.py +++ b/src/sage/combinat/ribbon_tableau.py @@ -664,19 +664,19 @@ def spin_polynomial(part, weight, length): EXAMPLES:: sage: from sage.combinat.ribbon_tableau import spin_polynomial - sage: spin_polynomial([6,6,6],[4,2],3) + sage: spin_polynomial([6,6,6],[4,2],3) # optional - sage.symbolic t^6 + t^5 + 2*t^4 + t^3 + t^2 - sage: spin_polynomial([6,6,6],[4,1,1],3) + sage: spin_polynomial([6,6,6],[4,1,1],3) # optional - sage.symbolic t^6 + 2*t^5 + 3*t^4 + 2*t^3 + t^2 - sage: spin_polynomial([3,3,3,2,1], [2,2], 3) + sage: spin_polynomial([3,3,3,2,1], [2,2], 3) # optional - sage.symbolic t^(7/2) + t^(5/2) - sage: spin_polynomial([3,3,3,2,1], [2,1,1], 3) + sage: spin_polynomial([3,3,3,2,1], [2,1,1], 3) # optional - sage.symbolic 2*t^(7/2) + 2*t^(5/2) + t^(3/2) - sage: spin_polynomial([3,3,3,2,1], [1,1,1,1], 3) + sage: spin_polynomial([3,3,3,2,1], [1,1,1,1], 3) # optional - sage.symbolic 3*t^(7/2) + 5*t^(5/2) + 3*t^(3/2) + sqrt(t) - sage: spin_polynomial([5,4,3,2,1,1,1], [2,2,1], 3) + sage: spin_polynomial([5,4,3,2,1,1,1], [2,2,1], 3) # optional - sage.symbolic 2*t^(9/2) + 6*t^(7/2) + 2*t^(5/2) - sage: spin_polynomial([[6]*6, [3,3]], [4,4,2], 3) + sage: spin_polynomial([[6]*6, [3,3]], [4,4,2], 3) # optional - sage.symbolic 3*t^9 + 5*t^8 + 9*t^7 + 6*t^6 + 3*t^5 """ from sage.symbolic.ring import SR diff --git a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py index ae39e62ce01..37fd54ce2f3 100644 --- a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +++ b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py @@ -1074,21 +1074,21 @@ class NonSymmetricMacdonaldPolynomials(CherednikOperatorsEigenvectors): sage: K = QQ['q','t'].fraction_field() sage: q,t = K.gens() sage: def to_SR(x): return x.expand([SR.var('x%s'%i) for i in range(1,x.parent().basis().keys().dimension()+1)]).subs(q=SR.var('q'), t=SR.var('t')) - sage: var('x1,x2,x3') + sage: var('x1,x2,x3') # optional - sage.symbolic (x1, x2, x3) sage: E = NonSymmetricMacdonaldPolynomials(["BC",2,2], q=q, q1=t^2,q2=-1) sage: omega=E.keys().fundamental_weights() sage: expected = (t-1)*(t+1)*(2+q^4+2*q^2-2*t^2-2*q^2*t^2-t^4*q^2-q^4*t^4+t^4-3*q^6*t^6-2*q^4*t^6+2*q^6*t^8+2*q^4*t^8+t^10*q^8)*q^4/((q^2*t^3-1)*(q^2*t^3+1)*(t*q-1)*(t*q+1)*(t^2*q^3+1)*(t^2*q^3-1))+(t-1)^2*(t+1)^2*(2*q^2+q^4+2+q^4*t^2)*q^3*x1/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1))+(t-1)^2*(t+1)^2*(q^2+1)*q^5/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1)*x1)+(t-1)^2*(t+1)^2*(q^2+1)*q^4*x2/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1)*x1)+(t-1)^2*(t+1)^2*(2*q^2+q^4+2+q^4*t^2)*q^3*x2/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1))+(t-1)^2*(t+1)^2*(q^2+1)*q^5/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1)*x2)+x1^2*x2^2+(t-1)*(t+1)*(-2*q^2-q^4-2+2*q^2*t^2+t^2+q^6*t^4+q^4*t^4)*q^2*x2*x1/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1))+(t-1)*(t+1)*(q^2+1+q^4*t^2)*q*x2^2*x1/((t^2*q^3-1)*(t^2*q^3+1))+(t-1)*(t+1)*q^3*x1^2/((t^2*q^3-1)*(t^2*q^3+1)*x2)+(t-1)*(t+1)*(q^2+1+q^4*t^2)*q*x2*x1^2/((t^2*q^3-1)*(t^2*q^3+1))+(t-1)*(t+1)*q^6/((t^2*q^3+1)*(t^2*q^3-1)*x1*x2)+(t-1)*(t+1)*(q^2+1+q^4*t^2)*q^2*x1^2/((t^2*q^3-1)*(t^2*q^3+1))+(t-1)*(t+1)*(q^2+1+q^4*t^2)*q^2*x2^2/((t^2*q^3-1)*(t^2*q^3+1))+(t-1)*(t+1)*q^3*x2^2/((t^2*q^3-1)*(t^2*q^3+1)*x1)+(t-1)^2*(t+1)^2*(q^2+1)*q^4*x1/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1)*x2) - sage: to_SR(E[2*omega[2]]) - expected # long time (3.5s) + sage: to_SR(E[2*omega[2]]) - expected # long time (3.5s) # optional - sage.symbolic 0 - sage: E = NonSymmetricMacdonaldPolynomials(["BC",3,2], q=q, q1=t^2,q2=-1) + sage: E = NonSymmetricMacdonaldPolynomials(["BC",3,2], q=q, q1=t^2, q2=-1) sage: omega=E.keys().fundamental_weights() sage: mu = -3*omega[1] + 3*omega[2] - omega[3]; mu (-1, 2, -1) sage: expected = (t-1)^2*(t+1)^2*(3*q^2+q^4+1+t^2*q^4+q^2*t^2-3*t^4*q^2-5*t^6*q^4+2*t^8*q^4-4*t^8*q^6-q^8*t^10+2*t^10*q^6-2*q^8*t^12+t^14*q^8-t^14*q^10+q^10*t^16+q^8*t^16+q^10*t^18+t^18*q^12)*x2*x1/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(q^2*t^6+2*t^6*q^4-q^4*t^4+t^4*q^2-q^2*t^2+t^2-2-q^2)*q^2*x1/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)^2*(t+1)^2*(-q^2-1+t^4*q^2-q^4*t^4+2*t^6*q^4)*x1^2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t+1)*(t-1)*x2^2*x3/((t*q-1)*(t*q+1)*x1)+(t-1)^2*(t+1)^2*(3*q^2+q^4+2+t^2*q^4+2*q^2*t^2-4*t^4*q^2+q^4*t^4-6*t^6*q^4+t^8*q^4-4*t^8*q^6-q^8*t^10+t^10*q^6-3*q^8*t^12-2*t^14*q^10+2*t^14*q^8+2*q^10*t^16+q^8*t^16+t^18*q^12+2*q^10*t^18)*q*x2/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(1+q^4+2*q^2+t^2*q^4-3*t^4*q^2+q^2*t^6-5*t^6*q^4+3*t^8*q^4-4*t^8*q^6+2*t^10*q^6-q^8*t^12-t^14*q^10+t^14*q^8+q^10*t^16+t^18*q^12)*x3*x1/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(2*q^2+1+q^4+t^2*q^4-t^2+q^2*t^2-4*t^4*q^2+q^4*t^4+q^2*t^6-5*t^6*q^4+3*t^8*q^4-4*t^8*q^6+2*t^10*q^6+q^6*t^12-2*q^8*t^12-2*t^14*q^10+2*t^14*q^8+q^10*t^16+t^18*q^12)*q*x3/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(1+t^2+t^4*q^2)*q*x3*x2^2/((t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1))+(t-1)^2*(t+1)^2*(-q^2-2-q^2*t^2+t^4-q^4*t^4-t^4*q^2+3*q^2*t^6-t^6*q^4-t^8*q^6+t^8*q^4+t^10*q^4+2*q^6*t^12-q^8*t^12+t^14*q^8)*q*x3*x2*x1/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t-1)*(t+1)*x1^2/((q^3*t^5-1)*(q^3*t^5+1)*x3*x2)+(t-1)*(t+1)*(-q^2-1+t^4*q^2-q^4*t^4+2*t^6*q^4)*x2^2/((t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1))+(t-1)*(t+1)*(t^3*q-1)*(t^3*q+1)*x3*x2^2*x1/((t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1))+(t-1)^2*(t+1)^2*(q^2+1)*q*x1/((t*q+1)*(t*q-1)*(q^3*t^5+1)*(q^3*t^5-1)*x3*x2)+(t-1)^2*(t+1)^2*(t^3*q-1)*(t^3*q+1)*x3*x2*x1^2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t-1)^2*(t+1)^2*q^3*x3/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x1*x2)+(t-1)*(t+1)*(-1-q^2+q^2*t^2+t^10*q^6)*q*x2/((t*q+1)*(t*q-1)*(q^3*t^5+1)*(q^3*t^5-1)*x3*x1)+x2^2/(x1*x3)+(t-1)*(t+1)*q*x2^2/((t*q-1)*(t*q+1)*x3)+(t-1)^3*(t+1)^3*(1+t^2+t^4*q^2)*q*x2*x1^2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t-1)^2*(t+1)^2*q*x1^2/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t-1)^2*(t+1)^2*(q^2*t^6+2*t^6*q^4-q^4*t^4+t^4*q^2-q^2*t^2+t^2-2-q^2)*q^3/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)*(t+1)*(q^2+2-t^2+q^4*t^4-t^4*q^2-3*t^6*q^4+t^8*q^4-2*t^10*q^6-q^8*t^12+q^6*t^12+q^8*t^16+q^10*t^16)*q^2*x2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x1)+(t-1)^2*(t+1)^2*(q^2+1)*q^2/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3*x2)+(t-1)*(t+1)*(1+q^4+2*q^2-2*q^2*t^2+t^4*q^6-q^4*t^4-3*q^6*t^6-t^6*q^4+2*t^8*q^6-t^10*q^6-q^8*t^10-t^14*q^10+t^14*q^8+2*q^10*t^16)*x2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t-1)^2*(t+1)^2*(-q^2-2-q^2*t^2-q^4*t^4+2*t^6*q^4+t^10*q^6+q^8*t^12+t^14*q^8)*q^3/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x1)+(t-1)^2*(t+1)^2*(-1-q^2-q^2*t^2+t^2+t^4*q^2-q^4*t^4+2*t^6*q^4)*q^2*x3/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)*(t+1)*q*x2^2/((t*q-1)*(t*q+1)*x1)+(t-1)^2*(t+1)^2*(1+t^2+t^4*q^2)*q*x2^2*x1/((t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1))+(t-1)^2*(t+1)^2*q*x1^2/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)^2*(t+1)^2*(-1-q^4-2*q^2-t^2*q^4-q^2*t^2+t^4*q^2-t^4*q^6-2*q^4*t^4+3*t^6*q^4-q^6*t^6-t^8*q^8+t^8*q^6+2*t^10*q^6-q^10*t^12+3*q^8*t^12+2*t^14*q^10)*x3*x2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t-1)*(t+1)*(q^2+1-t^2+q^4*t^4-t^4*q^2+q^2*t^6-3*t^6*q^4+t^8*q^4-t^10*q^6+q^6*t^12-q^8*t^12+q^10*t^16)*q^2*x3/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x1)+(t-1)*(t+1)*(-1-q^2+q^2*t^2+t^10*q^6)*q^2/((t*q-1)*(t*q+1)*(q^3*t^5+1)*(q^3*t^5-1)*x1*x3)+(t-1)*(t+1)*(1+q^4+2*q^2-3*q^2*t^2+t^4*q^6-q^4*t^4-3*q^6*t^6-t^6*q^4+t^8*q^4+2*t^8*q^6-t^10*q^6+t^14*q^8-t^14*q^10+q^10*t^16)*x1/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t-1)^2*(t+1)^2*(3*q^2+q^4+2+q^2*t^2-t^2+t^2*q^4-6*t^4*q^2+q^4*t^4-7*t^6*q^4+q^2*t^6+3*t^8*q^4-4*t^8*q^6+t^10*q^4+3*t^10*q^6-q^8*t^12-t^14*q^10+t^14*q^8+q^8*t^16+q^10*t^18)*q*x1/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(-q^2-2-q^2*t^2-q^4*t^4+2*t^6*q^4+t^10*q^6+q^6*t^12+t^14*q^8)*q*x2*x1/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t+1)*(t-1)*x2^2*x1/((t*q-1)*(t*q+1)*x3)+(t-1)^3*(t+1)^3*(1+t^2+t^4*q^2)*q*x3*x1^2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t-1)*(t+1)*q^3/((q^3*t^5+1)*(q^3*t^5-1)*x1*x2*x3)+(t-1)^2*(t+1)^2*(3+3*q^2+q^4+2*q^2*t^2-t^2+t^2*q^4-6*t^4*q^2+q^4*t^4-8*t^6*q^4+q^2*t^6+2*t^8*q^4-4*t^8*q^6+t^10*q^4+2*t^10*q^6-2*q^8*t^12-t^14*q^10+t^14*q^8+q^8*t^16+q^10*t^16+2*q^10*t^18)*q^2/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(-q^4-2*q^2-1-t^2*q^4-t^4*q^6+2*q^6*t^6+t^6*q^4+t^10*q^6+q^8*t^12+t^14*q^10)*q/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t-1)^2*(t+1)^2*(-1-q^2-q^2*t^2+t^2+t^4*q^2-q^4*t^4+2*t^6*q^4)*q*x3*x1/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)^2*(t+1)^2*x2*x1^2/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t-1)^2*(t+1)^2*x3*x1^2/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)^2*(t+1)^2*q^4/((t*q+1)*(t*q-1)*(q^3*t^5+1)*(q^3*t^5-1)*x1*x2)+(t-1)^2*(t+1)^2*(-q^2-1-q^2*t^2-q^4*t^4+t^6*q^4+t^10*q^6+q^8*t^12+t^14*q^10)*q*x3*x2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x1) - sage: to_SR(E[mu]) - expected # long time (20s) + sage: to_SR(E[mu]) - expected # long time (20s) # optional - sage.symbolic 0 sage: E = NonSymmetricMacdonaldPolynomials(["BC",1,2], q=q, q1=t^2,q2=-1) @@ -1096,7 +1096,7 @@ class NonSymmetricMacdonaldPolynomials(CherednikOperatorsEigenvectors): sage: mu = -4*omega[1]; mu (-4) sage: expected = (t-1)*(t+1)*(-1+q^2*t^2-q^2-3*q^10-7*q^26*t^8+5*t^2*q^6-q^16-3*q^4+4*t^10*q^30-4*t^6*q^22-10*q^20*t^6+2*q^32*t^10-3*q^6-4*q^8+q^34*t^10-4*t^8*q^24-2*q^12-q^14+2*q^22*t^10+4*q^26*t^10+4*q^28*t^10+t^6*q^30-2*q^32*t^8-2*t^8*q^22+2*q^24*t^10-q^20*t^2-2*t^6*q^12+t^8*q^14+2*t^4*q^24-4*t^8*q^30+2*t^8*q^20-9*t^6*q^16+3*q^26*t^6+q^28*t^6+3*t^2*q^4+2*q^18*t^8-6*t^6*q^14+4*t^4*q^22-2*q^24*t^6+3*t^2*q^12+7*t^4*q^20-t^2*q^16+11*q^18*t^4-2*t^2*q^18+9*q^16*t^4-t^4*q^6+6*q^8*t^2+5*q^10*t^2-6*q^28*t^8+q^12*t^4+8*t^4*q^14-10*t^6*q^18-q^4*t^4+q^16*t^8-2*t^4*q^8)/((t*q^4-1)*(t*q^4+1)*(q^7*t^2-1)*(q^7*t^2+1)*(t*q^3-1)*(t*q^3+1)*(q^5*t^2+1)*(q^5*t^2-1))+(q^2+1)*(q^4+1)*(t-1)*(t+1)*(-1+q^2*t^2-q^2+t^2*q^6-q^4+t^6*q^22+3*q^10*t^4+t^2-q^8-2*t^8*q^24+q^22*t^10+q^26*t^10-2*t^8*q^22+q^24*t^10-4*t^6*q^12-2*t^8*q^20-3*t^6*q^16+2*t^2*q^4-t^6*q^10-2*t^6*q^14+t^8*q^12-t^2*q^12+2*q^16*t^4+q^8*t^2-q^10*t^2+3*q^12*t^4+2*t^4*q^14+t^6*q^18-2*q^4*t^4+q^16*t^8+q^20*t^10)*q*x1/((t*q^4-1)*(t*q^4+1)*(q^7*t^2-1)*(q^7*t^2+1)*(t*q^3-1)*(t*q^3+1)*(q^5*t^2+1)*(q^5*t^2-1))+(q^2+1)*(q^4+1)*(t-1)*(t+1)*(1+q^8+q^4+q^2-q^8*t^2-2*t^2*q^4-t^2*q^6+t^2*q^12-t^2+t^4*q^6-2*q^16*t^4-t^4*q^14-2*q^12*t^4+t^6*q^12+t^6*q^16+t^6*q^18+t^6*q^14)*q/((t*q^4-1)*(t*q^4+1)*(q^7*t^2-1)*(q^7*t^2+1)*(t*q^3-1)*(t*q^3+1)*x1)+(t-1)*(t+1)*(-1-q^2-q^6-q^4-q^8+t^2*q^4-t^2*q^14+t^2*q^6-q^10*t^2+q^8*t^2-t^2*q^12+q^12*t^4+q^10*t^4+q^16*t^4+2*t^4*q^14)*(q^4+1)/((q^7*t^2+1)*(q^7*t^2-1)*(t*q^4-1)*(t*q^4+1)*x1^2)+(t-1)*(t+1)*(q^4+1)*(q^2+1)*q/((t*q^4-1)*(t*q^4+1)*x1^3)+(q^4+1)*(t-1)*(t+1)*(1+q^6+q^8+q^2+q^4-q^2*t^2-3*t^2*q^4+q^10*t^2+t^2*q^12-2*t^2*q^6-q^8*t^2-2*q^16*t^4+q^4*t^4+t^4*q^6-q^10*t^4-2*q^12*t^4-2*t^4*q^14+t^6*q^12+t^6*q^18+2*t^6*q^16+t^6*q^14)*x1^2/((t*q^4-1)*(t*q^4+1)*(q^7*t^2-1)*(q^7*t^2+1)*(t*q^3-1)*(t*q^3+1))+(t-1)*(t+1)*(-1-t^2*q^6+t^2+t^4*q^8)*(q^4+1)*(q^2+1)*q*x1^3/((q^7*t^2+1)*(q^7*t^2-1)*(t*q^4-1)*(t*q^4+1))+1/x1^4+(t-1)*(t+1)*x1^4/((t*q^4-1)*(t*q^4+1)) - sage: to_SR(E[mu]) - expected + sage: to_SR(E[mu]) - expected # optional - sage.symbolic 0 Type `BC` dual, comparison with hand calculations by Bogdan Ion:: diff --git a/src/sage/combinat/root_system/root_lattice_realizations.py b/src/sage/combinat/root_system/root_lattice_realizations.py index faadbe3ea21..2e2b2d2f3a9 100644 --- a/src/sage/combinat/root_system/root_lattice_realizations.py +++ b/src/sage/combinat/root_system/root_lattice_realizations.py @@ -2094,8 +2094,7 @@ def plot_parse_options(self, **args): EXAMPLES:: sage: L = RootSystem(["A",2,1]).ambient_space() - sage: options = L.plot_parse_options() - sage: options + sage: options = L.plot_parse_options(); options # optional - sage.symbolic <sage.combinat.root_system.plot.PlotOptions object at ...> .. SEEALSO:: @@ -2120,7 +2119,7 @@ def _plot_projection(self, x): sage: L = RootSystem(["B",3]).root_lattice() sage: l = L.an_element(); l 2*alpha[1] + 2*alpha[2] + 3*alpha[3] - sage: L._plot_projection(l) + sage: L._plot_projection(l) # optional - sage.symbolic 2*alpha[1] + 2*alpha[2] + 3*alpha[3] In the ambient space of type `A_2`, this is the @@ -2154,22 +2153,22 @@ def _plot_projection_barycentric_matrix(self): EXAMPLES:: - sage: RootSystem(["A",0]).ambient_space()._plot_projection_barycentric_matrix() + sage: RootSystem(["A",0]).ambient_space()._plot_projection_barycentric_matrix() # optional - sage.symbolic [] - sage: m = RootSystem(["A",1]).ambient_space()._plot_projection_barycentric_matrix(); m + sage: m = RootSystem(["A",1]).ambient_space()._plot_projection_barycentric_matrix(); m # optional - sage.symbolic [ 1 -1] - sage: sum(m.columns()) + sage: sum(m.columns()) # optional - sage.symbolic (0) - sage: m = RootSystem(["A",2]).ambient_space()._plot_projection_barycentric_matrix(); m + sage: m = RootSystem(["A",2]).ambient_space()._plot_projection_barycentric_matrix(); m # optional - sage.symbolic [ 1/2 -1 1/2] [ 989/1142 0 -989/1142] - sage: sum(m.columns()) + sage: sum(m.columns()) # optional - sage.symbolic (0, 0) - sage: m = RootSystem(["A",3]).ambient_space()._plot_projection_barycentric_matrix(); m + sage: m = RootSystem(["A",3]).ambient_space()._plot_projection_barycentric_matrix(); m # optional - sage.symbolic [ 1277/1564 -1277/1564 0 0] [1009460/2141389 849/1801 -1121/1189 0] [ 1/3 1/3 1/3 -1] - sage: sum(m.columns()) + sage: sum(m.columns()) # optional - sage.symbolic (0, 0, 0) """ @@ -2197,11 +2196,11 @@ def _plot_projection_barycentric(self, x): sage: L = RootSystem(["A",2]).ambient_space() sage: e = L.basis() - sage: L._plot_projection_barycentric(e[0]) + sage: L._plot_projection_barycentric(e[0]) # optional - sage.symbolic (1/2, 989/1142) - sage: L._plot_projection_barycentric(e[1]) + sage: L._plot_projection_barycentric(e[1]) # optional - sage.symbolic (-1, 0) - sage: L._plot_projection_barycentric(e[2]) + sage: L._plot_projection_barycentric(e[2]) # optional - sage.symbolic (1/2, -989/1142) .. SEEALSO:: @@ -2235,36 +2234,36 @@ def plot_roots(self, collection="simple", **options): EXAMPLES:: - sage: RootSystem(["B",3]).ambient_space().plot_roots() + sage: RootSystem(["B",3]).ambient_space().plot_roots() # optional - sage.plot Graphics3d Object - sage: RootSystem(["B",3]).ambient_space().plot_roots("all") + sage: RootSystem(["B",3]).ambient_space().plot_roots("all") # optional - sage.plot Graphics3d Object TESTS:: - sage: list(RootSystem(["A",2]).root_lattice().plot_roots()) + sage: list(RootSystem(["A",2]).root_lattice().plot_roots()) # optional - sage.plot sage.symbolic [Arrow from (0.0,0.0) to (1.0,0.0), Text '$\alpha_{1}$' at the point (1.05,0.0), Arrow from (0.0,0.0) to (0.0,1.0), Text '$\alpha_{2}$' at the point (0.0,1.05)] - sage: list(RootSystem(["A",2]).weight_lattice().plot_roots(labels=False)) + sage: list(RootSystem(["A",2]).weight_lattice().plot_roots(labels=False)) # optional - sage.plot sage.symbolic [Arrow from (0.0,0.0) to (2.0,-1.0), Arrow from (0.0,0.0) to (-1.0,2.0)] - sage: list(RootSystem(["A",2]).ambient_lattice().plot_roots()) + sage: list(RootSystem(["A",2]).ambient_lattice().plot_roots()) # optional - sage.plot sage.symbolic [Arrow from (0.0,0.0) to (1.5,0.86...), Text '$\alpha_{1}$' at the point (1.575...,0.90...), Arrow from (0.0,0.0) to (-1.5,0.86...), Text '$\alpha_{2}$' at the point (-1.575...,0.90...)] - sage: list(RootSystem(["B",2]).ambient_space().plot_roots()) + sage: list(RootSystem(["B",2]).ambient_space().plot_roots()) # optional - sage.plot sage.symbolic [Arrow from (0.0,0.0) to (1.0,-1.0), Text '$\alpha_{1}$' at the point (1.05,-1.05), Arrow from (0.0,0.0) to (0.0,1.0), Text '$\alpha_{2}$' at the point (0.0,1.05)] - sage: list(RootSystem(["A",2]).root_lattice().plot_roots("all")) + sage: list(RootSystem(["A",2]).root_lattice().plot_roots("all")) # optional - sage.plot sage.symbolic [Arrow from (0.0,0.0) to (1.0,0.0), Text '$\alpha_{1}$' at the point (1.05,0.0), Arrow from (0.0,0.0) to (0.0,1.0), @@ -2370,18 +2369,18 @@ def plot_fundamental_weights(self, **options): EXAMPLES:: - sage: RootSystem(["B",3]).ambient_space().plot_fundamental_weights() + sage: RootSystem(["B",3]).ambient_space().plot_fundamental_weights() # optional - sage.plot Graphics3d Object TESTS:: - sage: sorted(RootSystem(["A",2]).weight_lattice().plot_fundamental_weights(), key=str) + sage: sorted(RootSystem(["A",2]).weight_lattice().plot_fundamental_weights(), key=str) # optional - sage.plot sage.symbolic [Arrow from (0.0,0.0) to (0.0,1.0), Arrow from (0.0,0.0) to (1.0,0.0), Text '$\Lambda_{1}$' at the point (1.05,0.0), Text '$\Lambda_{2}$' at the point (0.0,1.05)] - sage: sorted(RootSystem(["A",2]).ambient_lattice().plot_fundamental_weights(), key=str) + sage: sorted(RootSystem(["A",2]).ambient_lattice().plot_fundamental_weights(), key=str) # optional - sage.plot sage.symbolic [Arrow from (0.0,0.0) to (-0.5,0.86602451838...), Arrow from (0.0,0.0) to (0.5,0.86602451838...), Text '$\Lambda_{1}$' at the point (0.525,0.909325744308...), @@ -2423,21 +2422,21 @@ def plot_reflection_hyperplanes(self, collection="simple", **options): EXAMPLES:: - sage: RootSystem(["A",2,1]).ambient_space().plot_reflection_hyperplanes() + sage: RootSystem(["A",2,1]).ambient_space().plot_reflection_hyperplanes() # optional - sage.plot sage.symbolic Graphics object consisting of 6 graphics primitives - sage: RootSystem(["G",2,1]).ambient_space().plot_reflection_hyperplanes() + sage: RootSystem(["G",2,1]).ambient_space().plot_reflection_hyperplanes() # optional - sage.plot sage.symbolic Graphics object consisting of 6 graphics primitives - sage: RootSystem(["A",3]).weight_space().plot_reflection_hyperplanes() + sage: RootSystem(["A",3]).weight_space().plot_reflection_hyperplanes() # optional - sage.plot sage.symbolic Graphics3d Object - sage: RootSystem(["B",3]).ambient_space().plot_reflection_hyperplanes() + sage: RootSystem(["B",3]).ambient_space().plot_reflection_hyperplanes() # optional - sage.plot sage.symbolic Graphics3d Object - sage: RootSystem(["A",3,1]).weight_space().plot_reflection_hyperplanes() + sage: RootSystem(["A",3,1]).weight_space().plot_reflection_hyperplanes() # optional - sage.plot sage.symbolic Graphics3d Object - sage: RootSystem(["B",3,1]).ambient_space().plot_reflection_hyperplanes() + sage: RootSystem(["B",3,1]).ambient_space().plot_reflection_hyperplanes() # optional - sage.plot sage.symbolic Graphics3d Object - sage: RootSystem(["A",2,1]).weight_space().plot_reflection_hyperplanes(affine=False, level=1) + sage: RootSystem(["A",2,1]).weight_space().plot_reflection_hyperplanes(affine=False, level=1) # optional - sage.plot sage.symbolic Graphics3d Object - sage: RootSystem(["A",2]).root_lattice().plot_reflection_hyperplanes() + sage: RootSystem(["A",2]).root_lattice().plot_reflection_hyperplanes() # optional - sage.plot sage.symbolic Graphics object consisting of 4 graphics primitives TESTS:: @@ -2507,27 +2506,27 @@ def plot_hedron(self, **options): EXAMPLES:: - sage: RootSystem(["A",2]).ambient_space().plot_hedron() + sage: RootSystem(["A",2]).ambient_space().plot_hedron() # optional - sage.plot sage.symbolic Graphics object consisting of 8 graphics primitives - sage: RootSystem(["A",3]).ambient_space().plot_hedron() + sage: RootSystem(["A",3]).ambient_space().plot_hedron() # optional - sage.plot sage.symbolic Graphics3d Object - sage: RootSystem(["B",3]).ambient_space().plot_hedron() + sage: RootSystem(["B",3]).ambient_space().plot_hedron() # optional - sage.plot sage.symbolic Graphics3d Object - sage: RootSystem(["C",3]).ambient_space().plot_hedron() + sage: RootSystem(["C",3]).ambient_space().plot_hedron() # optional - sage.plot sage.symbolic Graphics3d Object - sage: RootSystem(["D",3]).ambient_space().plot_hedron() + sage: RootSystem(["D",3]).ambient_space().plot_hedron() # optional - sage.plot sage.symbolic Graphics3d Object Surprise: polyhedra of large dimension know how to project themselves nicely:: - sage: RootSystem(["F",4]).ambient_space().plot_hedron() # long time + sage: RootSystem(["F",4]).ambient_space().plot_hedron() # long time # optional - sage.plot sage.symbolic Graphics3d Object TESTS:: sage: L = RootSystem(["B",2]).ambient_space() - sage: print(L.plot_hedron().description()) + sage: print(L.plot_hedron().description()) # optional - sage.plot sage.symbolic Polygon defined by 8 points: [(1.5, 0.5), (0.5, 1.5), (-0.5, 1.5), (-1.5, 0.5), (-1.5, -0.5), (-0.5, -1.5), (0.5, -1.5), (1.5, -0.5)] Line defined by 2 points: [(-0.5, -1.5), (0.5, -1.5)] Line defined by 2 points: [(-0.5, 1.5), (0.5, 1.5)] @@ -2567,18 +2566,18 @@ def plot_fundamental_chamber(self, style="normal", **options): 2D plots:: - sage: RootSystem(["B",2]).ambient_space().plot_fundamental_chamber() + sage: RootSystem(["B",2]).ambient_space().plot_fundamental_chamber() # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: RootSystem(["B",2,1]).ambient_space().plot_fundamental_chamber() + sage: RootSystem(["B",2,1]).ambient_space().plot_fundamental_chamber() # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: RootSystem(["B",2,1]).ambient_space().plot_fundamental_chamber("classical") + sage: RootSystem(["B",2,1]).ambient_space().plot_fundamental_chamber("classical") # optional - sage.plot Graphics object consisting of 1 graphics primitive 3D plots:: - sage: RootSystem(["A",3,1]).weight_space() .plot_fundamental_chamber() + sage: RootSystem(["A",3,1]).weight_space() .plot_fundamental_chamber() # optional - sage.plot Graphics3d Object - sage: RootSystem(["B",3,1]).ambient_space().plot_fundamental_chamber() + sage: RootSystem(["B",3,1]).ambient_space().plot_fundamental_chamber() # optional - sage.plot Graphics3d Object This feature is currently not available in the root lattice/space:: @@ -2591,10 +2590,10 @@ def plot_fundamental_chamber(self, style="normal", **options): TESTS:: sage: L = RootSystem(["B",2,1]).ambient_space() - sage: print(L.plot_fundamental_chamber().description()) + sage: print(L.plot_fundamental_chamber().description()) # optional - sage.plot Polygon defined by 3 points: [(0.5, 0.5), (1.0, 0.0), (0.0, 0.0)] - sage: print(L.plot_fundamental_chamber(style="classical").description()) + sage: print(L.plot_fundamental_chamber(style="classical").description()) # optional - sage.plot Polygon defined by 3 points: [(0.0, 0.0), (3.0, 3.0), (3.0, 0.0)] """ plot_options = self.plot_parse_options(**options) @@ -2639,28 +2638,28 @@ def plot_alcoves(self, alcoves=True, alcove_labels=False, wireframe=False, **opt 2D plots:: - sage: RootSystem(["B",2,1]).ambient_space().plot_alcoves() # long time (3s) + sage: RootSystem(["B",2,1]).ambient_space().plot_alcoves() # long time (3s) # optional - sage.plot sage.symbolic Graphics object consisting of 228 graphics primitives 3D plots:: - sage: RootSystem(["A",2,1]).weight_space() .plot_alcoves(affine=False) # long time (3s) + sage: RootSystem(["A",2,1]).weight_space() .plot_alcoves(affine=False) # long time (3s) # optional - sage.plot sage.symbolic Graphics3d Object - sage: RootSystem(["G",2,1]).ambient_space().plot_alcoves(affine=False, level=1) # long time (3s) + sage: RootSystem(["G",2,1]).ambient_space().plot_alcoves(affine=False, level=1) # long time (3s) # optional - sage.plot sage.symbolic Graphics3d Object Here we plot a single alcove:: sage: L = RootSystem(["A",3,1]).ambient_space() sage: W = L.weyl_group() - sage: L.plot(alcoves=[W.one()], reflection_hyperplanes=False, bounding_box=2) + sage: L.plot(alcoves=[W.one()], reflection_hyperplanes=False, bounding_box=2) # optional - sage.plot sage.symbolic Graphics3d Object TESTS:: sage: L = RootSystem(["A",2,1]).weight_space() - sage: p = L.plot_alcoves(alcoves=[[0,0]]) - sage: print(p.description()) + sage: p = L.plot_alcoves(alcoves=[[0,0]]) # optional - sage.plot sage.symbolic + sage: print(p.description()) # optional - sage.plot sage.symbolic Line defined by 2 points: [(-1.0, 0.0), (0.0, -1.0)] Line defined by 2 points: [(-1.0, 1.0), (-1.0, 0.0)] Line defined by 2 points: [(-1.0, 1.0), (0.0, 0.0)] @@ -2673,7 +2672,7 @@ def plot_alcoves(self, alcoves=True, alcove_labels=False, wireframe=False, **opt Line defined by 2 points: [(1.0, -1.0), (0.0, -1.0)] Line defined by 2 points: [(1.0, 0.0), (0.0, 0.0)] Line defined by 2 points: [(1.0, 0.0), (1.0, -1.0)] - sage: sorted((line.options()['rgbcolor'], line.options()['thickness']) for line in p) + sage: sorted((line.options()['rgbcolor'], line.options()['thickness']) for line in p) # optional - sage.plot sage.symbolic [('black', 2), ('black', 2), ('black', 2), ('black', 2), ('black', 2), ('black', 2), ('blue', 1), ('blue', 1), ('blue', 1), @@ -2867,32 +2866,34 @@ def plot_alcove_walk(self, word, start=None, foldings=None, color="orange", **op sage: L = RootSystem(["A",2,1]).ambient_space() sage: w1 = [0,2,1,2,0,2,1,0,2,1,2,1,2,0,2,0,1,2,0] - sage: p = L.plot_alcoves(bounding_box=5) # long time (5s) - sage: p += L.plot_alcove_walk(w1) # long time - sage: p # long time + sage: p = L.plot_alcoves(bounding_box=5) # long time (5s) # optional - sage.plot sage.symbolic + sage: p += L.plot_alcove_walk(w1) # long time # optional - sage.plot sage.symbolic + sage: p # long time # optional - sage.plot sage.symbolic Graphics object consisting of 375 graphics primitives The same plot with another alcove walk:: sage: w2 = [2,1,2,0,2,0,2,1,2,0,1,2,1,2,1,0,1,2,0,2,0,1,2,0,2] - sage: p += L.plot_alcove_walk(w2, color="orange") # long time + sage: p += L.plot_alcove_walk(w2, color="orange") # long time # optional - sage.plot sage.symbolic And another with some foldings:: - sage: pic = L.plot_alcoves(bounding_box=3) # long time - sage: pic += L.plot_alcove_walk([0,1,2,0,2,0,1,2,0,1], # long time (3s) - ....: foldings = [False, False, True, False, False, False, True, False, True, False], + sage: pic = L.plot_alcoves(bounding_box=3) # long time # optional - sage.plot sage.symbolic + sage: pic += L.plot_alcove_walk([0,1,2,0,2,0,1,2,0,1], # long time (3s), optional - sage.plot sage.symbolic + ....: foldings=[False, False, True, False, False, + ....: False, True, False, True, False], ....: color="green"); pic Graphics object consisting of 155 graphics primitives TESTS:: sage: L = RootSystem(["A",2,1]).weight_space() - sage: p = L.plot_alcove_walk([0,1,2,0,2,0,1,2,0,1], - ....: foldings = [False, False, True, False, False, False, True, False, True, False], + sage: p = L.plot_alcove_walk([0,1,2,0,2,0,1,2,0,1], # optional - sage.plot sage.symbolic + ....: foldings=[False, False, True, False, False, + ....: False, True, False, True, False], ....: color="green", ....: start=L.rho()) - sage: print(p.description()) + sage: print(p.description()) # optional - sage.plot sage.symbolic Line defined by 2 points: [(-1.0, 8.0), (-1.5, 9.0)] Line defined by 2 points: [(1.0, 4.0), (1.5, 4.5)] Line defined by 2 points: [(1.0, 7.0), (1.5, 6.0)] @@ -2982,14 +2983,14 @@ def plot_ls_paths(self, paths, plot_labels=None, colored_labels=True, **options) sage: B = crystals.LSPaths(['A',2], [1,1]) sage: L = RootSystem(['A',2]).ambient_space() - sage: L.plot_fundamental_weights() + L.plot_ls_paths(B) + sage: L.plot_fundamental_weights() + L.plot_ls_paths(B) # optional - sage.plot sage.symbolic Graphics object consisting of 14 graphics primitives This also works in 3 dimensions:: sage: B = crystals.LSPaths(['B',3], [2,0,0]) sage: L = RootSystem(['B',3]).ambient_space() - sage: L.plot_ls_paths(B) + sage: L.plot_ls_paths(B) # optional - sage.plot sage.symbolic Graphics3d Object """ if not isinstance(paths, (list, tuple, set)): @@ -3050,7 +3051,7 @@ def plot_mv_polytope(self, mv_polytope, mark_endpoints=True, sage: B = crystals.infinity.MVPolytopes(['C',2]) sage: L = RootSystem(['C',2]).ambient_space() sage: p = B.highest_weight_vector().f_string([1,2,1,2]) - sage: L.plot_fundamental_weights() + L.plot_mv_polytope(p) + sage: L.plot_fundamental_weights() + L.plot_mv_polytope(p) # optional - sage.geometry.polyhedron sage.plot sage.symbolic Graphics object consisting of 14 graphics primitives This also works in 3 dimensions:: @@ -3058,7 +3059,7 @@ def plot_mv_polytope(self, mv_polytope, mark_endpoints=True, sage: B = crystals.infinity.MVPolytopes(['A',3]) sage: L = RootSystem(['A',3]).ambient_space() sage: p = B.highest_weight_vector().f_string([2,1,3,2]) - sage: L.plot_mv_polytope(p) + sage: L.plot_mv_polytope(p) # optional - sage.geometry.polyhedron sage.plot sage.symbolic Graphics3d Object """ from sage.geometry.polyhedron.all import Polyhedron @@ -3128,17 +3129,18 @@ def plot_crystal(self, crystal, sage: L = RootSystem(['A',2]).ambient_space() sage: C = crystals.Tableaux(['A',2], shape=[2,1]) - sage: L.plot_crystal(C, plot_labels='multiplicities') + sage: L.plot_crystal(C, plot_labels='multiplicities') # optional - sage.plot sage.symbolic Graphics object consisting of 15 graphics primitives sage: C = crystals.Tableaux(['A',2], shape=[8,4]) - sage: p = L.plot_crystal(C, plot_labels='circles') - sage: p.show(figsize=15) + sage: p = L.plot_crystal(C, plot_labels='circles') # optional - sage.plot sage.symbolic + sage: p.show(figsize=15) # optional - sage.plot sage.symbolic A 3-dimensional example:: sage: L = RootSystem(['B',3]).ambient_space() sage: C = crystals.Tableaux(['B',3], shape=[2,1]) - sage: L.plot_crystal(C, plot_labels='circles', edge_labels=True) # long time + sage: L.plot_crystal(C, plot_labels='circles', # long time # optional - sage.plot sage.symbolic + ....: edge_labels=True) Graphics3d Object TESTS: @@ -3232,7 +3234,8 @@ def dual_type_cospace(self): sage: CartanType(['B',2]).root_system().root_lattice().dual_type_cospace() Coroot lattice of the Root system of type ['C', 2] sage: CartanType(['F',4]).root_system().coweight_lattice().dual_type_cospace() - Weight lattice of the Root system of type ['F', 4] relabelled by {1: 4, 2: 3, 3: 2, 4: 1} + Weight lattice of the Root system of type ['F', 4] + relabelled by {1: 4, 2: 3, 3: 2, 4: 1} """ from .root_space import RootSpace @@ -3257,18 +3260,19 @@ def to_ambient_space_morphism(self): EXAMPLES:: - sage: CartanType(['B',2]).root_system().root_lattice().to_ambient_space_morphism() + sage: B2rs = CartanType(['B',2]).root_system() + sage: B2rs.root_lattice().to_ambient_space_morphism() Generic morphism: - From: Root lattice of the Root system of type ['B', 2] - To: Ambient space of the Root system of type ['B', 2] - sage: CartanType(['B',2]).root_system().coroot_lattice().to_ambient_space_morphism() + From: Root lattice of the Root system of type ['B', 2] + To: Ambient space of the Root system of type ['B', 2] + sage: B2rs.coroot_lattice().to_ambient_space_morphism() Generic morphism: - From: Coroot lattice of the Root system of type ['B', 2] - To: Ambient space of the Root system of type ['B', 2] - sage: CartanType(['B',2]).root_system().weight_lattice().to_ambient_space_morphism() + From: Coroot lattice of the Root system of type ['B', 2] + To: Ambient space of the Root system of type ['B', 2] + sage: B2rs.weight_lattice().to_ambient_space_morphism() Generic morphism: - From: Weight lattice of the Root system of type ['B', 2] - To: Ambient space of the Root system of type ['B', 2] + From: Weight lattice of the Root system of type ['B', 2] + To: Ambient space of the Root system of type ['B', 2] """ diff --git a/src/sage/combinat/root_system/root_system.py b/src/sage/combinat/root_system/root_system.py index fc84a35b4c1..039be92e684 100644 --- a/src/sage/combinat/root_system/root_system.py +++ b/src/sage/combinat/root_system/root_system.py @@ -218,7 +218,7 @@ class RootSystem(UniqueRepresentation, SageObject): We can also plot various components of the ambient spaces:: sage: L = RootSystem(['A',2]).ambient_space() - sage: L.plot() + sage: L.plot() # optional - sage.plot sage.symbolic Graphics object consisting of 13 graphics primitives For more on plotting, see :ref:`sage.combinat.root_system.plot`. diff --git a/src/sage/combinat/root_system/type_A.py b/src/sage/combinat/root_system/type_A.py index c1134668507..f3cb037d644 100644 --- a/src/sage/combinat/root_system/type_A.py +++ b/src/sage/combinat/root_system/type_A.py @@ -28,16 +28,16 @@ class AmbientSpace(ambient_space.AmbientSpace): sage: L = RootSystem(["A",2]).ambient_space() sage: e = L.basis() - sage: L._plot_projection(e[0]) + sage: L._plot_projection(e[0]) # optional - sage.symbolic (1/2, 989/1142) - sage: L._plot_projection(e[1]) + sage: L._plot_projection(e[1]) # optional - sage.symbolic (-1, 0) - sage: L._plot_projection(e[2]) + sage: L._plot_projection(e[2]) # optional - sage.symbolic (1/2, -989/1142) sage: L = RootSystem(["A",3]).ambient_space() sage: l = L.an_element(); l (2, 2, 3, 0) - sage: L._plot_projection(l) + sage: L._plot_projection(l) # optional - sage.symbolic (0, -1121/1189, 7/3) .. SEEALSO:: diff --git a/src/sage/combinat/root_system/type_G.py b/src/sage/combinat/root_system/type_G.py index ce953036dc1..8bc189ef756 100644 --- a/src/sage/combinat/root_system/type_G.py +++ b/src/sage/combinat/root_system/type_G.py @@ -34,16 +34,16 @@ class AmbientSpace(ambient_space.AmbientSpace): sage: L = RootSystem(["G",2]).ambient_space() sage: e = L.basis() - sage: L._plot_projection(e[0]) + sage: L._plot_projection(e[0]) # optional - sage.symbolic (1/2, 989/1142) - sage: L._plot_projection(e[1]) + sage: L._plot_projection(e[1]) # optional - sage.symbolic (-1, 0) - sage: L._plot_projection(e[2]) + sage: L._plot_projection(e[2]) # optional - sage.symbolic (1/2, -989/1142) sage: L = RootSystem(["A",3]).ambient_space() sage: l = L.an_element(); l (2, 2, 3, 0) - sage: L._plot_projection(l) + sage: L._plot_projection(l) # optional - sage.symbolic (0, -1121/1189, 7/3) .. SEEALSO:: diff --git a/src/sage/combinat/root_system/type_affine.py b/src/sage/combinat/root_system/type_affine.py index b24f2d2afa5..50caa62f259 100644 --- a/src/sage/combinat/root_system/type_affine.py +++ b/src/sage/combinat/root_system/type_affine.py @@ -405,24 +405,24 @@ def _plot_projection(self, x): sage: L = RootSystem(["B",2,1]).ambient_space() sage: e = L.basis() - sage: L._plot_projection(e[0]) + sage: L._plot_projection(e[0]) # optional - sage.symbolic (1, 0, 0) - sage: L._plot_projection(e[1]) + sage: L._plot_projection(e[1]) # optional - sage.symbolic (0, 1, 0) - sage: L._plot_projection(e["delta"]) + sage: L._plot_projection(e["delta"]) # optional - sage.symbolic (0, 0, 0) - sage: L._plot_projection(e["deltacheck"]) + sage: L._plot_projection(e["deltacheck"]) # optional - sage.symbolic (0, 0, 1) sage: L = RootSystem(["A",2,1]).ambient_space() sage: e = L.basis() - sage: L._plot_projection(e[0]) + sage: L._plot_projection(e[0]) # optional - sage.symbolic (1/2, 989/1142, 0) - sage: L._plot_projection(e[1]) + sage: L._plot_projection(e[1]) # optional - sage.symbolic (-1, 0, 0) - sage: L._plot_projection(e["delta"]) + sage: L._plot_projection(e["delta"]) # optional - sage.symbolic (0, 0, 0) - sage: L._plot_projection(e["deltacheck"]) + sage: L._plot_projection(e["deltacheck"]) # optional - sage.symbolic (0, 0, 1) """ from sage.modules.free_module_element import vector diff --git a/src/sage/combinat/rooted_tree.py b/src/sage/combinat/rooted_tree.py index fa260e70343..abb96594d2a 100644 --- a/src/sage/combinat/rooted_tree.py +++ b/src/sage/combinat/rooted_tree.py @@ -522,10 +522,10 @@ def __init__(self): """ TESTS:: - sage: sum(x**len(t) for t in - ....: set(RootedTree(t) for t in OrderedTrees(6))) + sage: sum(x**len(t) # optional - sage.symbolic + ....: for t in set(RootedTree(t) for t in OrderedTrees(6))) x^5 + x^4 + 3*x^3 + 6*x^2 + 9*x - sage: sum(x**len(t) for t in RootedTrees(6)) + sage: sum(x**len(t) for t in RootedTrees(6)) # optional - sage.symbolic x^5 + x^4 + 3*x^3 + 6*x^2 + 9*x sage: TestSuite(RootedTrees()).run() # long time diff --git a/src/sage/combinat/set_partition.py b/src/sage/combinat/set_partition.py index 6edf7d963da..fa95061a4df 100644 --- a/src/sage/combinat/set_partition.py +++ b/src/sage/combinat/set_partition.py @@ -1891,7 +1891,7 @@ def plot(self, angle=None, color='black', base_set_dict=None): EXAMPLES:: sage: p = SetPartition([[1,10,11],[2,3,7],[4,5,6],[8,9]]) - sage: p.plot() + sage: p.plot() # optional - sage.plot sage.symbolic Graphics object consisting of 29 graphics primitives .. PLOT:: @@ -1902,7 +1902,7 @@ def plot(self, angle=None, color='black', base_set_dict=None): :: sage: p = SetPartition([[1,3,4],[2,5]]) - sage: print(p.plot().description()) + sage: print(p.plot().description()) # optional - sage.plot sage.symbolic Point set defined by 1 point(s): [(0.0, 0.0)] Point set defined by 1 point(s): [(1.0, 0.0)] Point set defined by 1 point(s): [(2.0, 0.0)] @@ -1920,7 +1920,7 @@ def plot(self, angle=None, color='black', base_set_dict=None): Arc with center (2.5,-1.5) radii (2.1213203435...,2.1213203435...) angle 0.0 inside the sector (0.785398163397...,2.35619449019...) sage: p = SetPartition([['a','c'],['b','d'],['e']]) - sage: print(p.plot().description()) + sage: print(p.plot().description()) # optional - sage.plot sage.symbolic Point set defined by 1 point(s): [(0.0, 0.0)] Point set defined by 1 point(s): [(1.0, 0.0)] Point set defined by 1 point(s): [(2.0, 0.0)] @@ -1936,7 +1936,8 @@ def plot(self, angle=None, color='black', base_set_dict=None): Arc with center (2.0,-1.0) radii (1.41421356237...,1.41421356237...) angle 0.0 inside the sector (0.785398163397...,2.35619449019...) sage: p = SetPartition([['a','c'],['b','d'],['e']]) - sage: print(p.plot(base_set_dict={'a':0,'b':1,'c':2,'d':-2.3,'e':5.4}).description()) + sage: print(p.plot(base_set_dict={'a':0,'b':1,'c':2, # optional - sage.plot sage.symbolic + ....: 'd':-2.3,'e':5.4}).description()) Point set defined by 1 point(s): [(-2.3, 0.0)] Point set defined by 1 point(s): [(0.0, 0.0)] Point set defined by 1 point(s): [(1.0, 0.0)] diff --git a/src/sage/combinat/sf/elementary.py b/src/sage/combinat/sf/elementary.py index 8d242f55b84..a7e5d9cf44c 100644 --- a/src/sage/combinat/sf/elementary.py +++ b/src/sage/combinat/sf/elementary.py @@ -370,7 +370,7 @@ def principal_specialization(self, n=infinity, q=None): By default, we return a rational functions in `q`. Sometimes it is better to obtain an element of the symbolic ring:: - sage: x.principal_specialization(q=var("q")) + sage: x.principal_specialization(q=var("q")) # optional - sage.symbolic -3*q/((q^2 - 1)*(q - 1)^2) - 5/(q - 1)^3 + 1 TESTS:: @@ -468,7 +468,7 @@ def exponential_specialization(self, t=None, q=1): sage: x.exponential_specialization() 1/12*t^5 sage: x = 5*e[2] + 3*e[1] + 1 - sage: x.exponential_specialization(t=var("t"), q=var("q")) + sage: x.exponential_specialization(t=var("t"), q=var("q")) # optional - sage.symbolic 5*q*t^2/(q + 1) + 3*t + 1 TESTS:: diff --git a/src/sage/combinat/sf/homogeneous.py b/src/sage/combinat/sf/homogeneous.py index b97bfae074c..da55fef0426 100644 --- a/src/sage/combinat/sf/homogeneous.py +++ b/src/sage/combinat/sf/homogeneous.py @@ -280,7 +280,7 @@ def principal_specialization(self, n=infinity, q=None): sage: x.principal_specialization(3) q^6 + 2*q^5 + 4*q^4 + 4*q^3 + 4*q^2 + 2*q + 1 sage: x = 3*h[2] + 2*h[1] + 1 - sage: x.principal_specialization(3, q=var("q")) + sage: x.principal_specialization(3, q=var("q")) # optional - sage.symbolic 2*(q^3 - 1)/(q - 1) + 3*(q^4 - 1)*(q^3 - 1)/((q^2 - 1)*(q - 1)) + 1 TESTS:: @@ -384,7 +384,7 @@ def exponential_specialization(self, t=None, q=1): We also support the `q`-exponential_specialization:: - sage: factor(h[3].exponential_specialization(q=var("q"), t=var("t"))) + sage: factor(h[3].exponential_specialization(q=var("q"), t=var("t"))) # optional - sage.symbolic t^3/((q^2 + q + 1)*(q + 1)) TESTS:: diff --git a/src/sage/combinat/sf/monomial.py b/src/sage/combinat/sf/monomial.py index ea1b9da133d..588d8154add 100644 --- a/src/sage/combinat/sf/monomial.py +++ b/src/sage/combinat/sf/monomial.py @@ -365,7 +365,7 @@ def principal_specialization(self, n=infinity, q=None): q^7 + q^6 + q^5 + q^3 + q^2 + q sage: x = 5*m[2] + 3*m[1] + 1 - sage: x.principal_specialization(3, q=var("q")) + sage: x.principal_specialization(3, q=var("q")) # optional - sage.symbolic -10*(q^3 - 1)*q/(q - 1) + 5*(q^3 - 1)^2/(q - 1)^2 + 3*(q^3 - 1)/(q - 1) + 1 TESTS:: @@ -451,7 +451,7 @@ def exponential_specialization(self, t=None, q=1): We also support the `q`-exponential_specialization:: - sage: factor(m[3].exponential_specialization(q=var("q"), t=var("t"))) + sage: factor(m[3].exponential_specialization(q=var("q"), t=var("t"))) # optional - sage.symbolic (q - 1)^2*t^3/(q^2 + q + 1) TESTS:: diff --git a/src/sage/combinat/sf/ns_macdonald.py b/src/sage/combinat/sf/ns_macdonald.py index 1013718d4b5..44075c054cf 100644 --- a/src/sage/combinat/sf/ns_macdonald.py +++ b/src/sage/combinat/sf/ns_macdonald.py @@ -533,8 +533,8 @@ def coeff(self, q, t): EXAMPLES:: sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) - sage: q,t = var('q,t') - sage: a.coeff(q,t) + sage: q,t = var('q,t') # optional - sage.symbolic + sage: a.coeff(q,t) # optional - sage.symbolic (t - 1)^4/((q^2*t^3 - 1)^2*(q*t^2 - 1)^2) """ res = 1 @@ -554,8 +554,8 @@ def coeff_integral(self, q, t): EXAMPLES:: sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) - sage: q,t = var('q,t') - sage: a.coeff_integral(q,t) + sage: q,t = var('q,t') # optional - sage.symbolic + sage: a.coeff_integral(q,t) # optional - sage.symbolic (q^2*t^3 - 1)^2*(q*t^2 - 1)^2*(t - 1)^4 """ res = 1 @@ -806,15 +806,15 @@ def _check_muqt(mu, q, t, pi=None): :: - sage: q,t = var('q,t') - sage: P, q, t, n, R, x = _check_muqt([0,0,1],q,None) + sage: q,t = var('q,t') # optional - sage.symbolic + sage: P, q, t, n, R, x = _check_muqt([0,0,1],q,None) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: you must specify either both q and t or neither of them :: - sage: P, q, t, n, R, x = _check_muqt([0,0,1],q,2) + sage: P, q, t, n, R, x = _check_muqt([0,0,1],q,2) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: the parents of q and t must be the same diff --git a/src/sage/combinat/sf/powersum.py b/src/sage/combinat/sf/powersum.py index 22a277b1ef8..fb9ecb31e91 100644 --- a/src/sage/combinat/sf/powersum.py +++ b/src/sage/combinat/sf/powersum.py @@ -760,11 +760,11 @@ def principal_specialization(self, n=infinity, q=None): sage: p = SymmetricFunctions(QQ).p() sage: x = p[8,7,3,1] - sage: x.principal_specialization(3, q=var("q")) + sage: x.principal_specialization(3, q=var("q")) # optional - sage.symbolic (q^24 - 1)*(q^21 - 1)*(q^9 - 1)/((q^8 - 1)*(q^7 - 1)*(q - 1)) sage: x = 5*p[1,1,1] + 3*p[2,1] + 1 - sage: x.principal_specialization(3, q=var("q")) + sage: x.principal_specialization(3, q=var("q")) # optional - sage.symbolic 5*(q^3 - 1)^3/(q - 1)^3 + 3*(q^6 - 1)*(q^3 - 1)/((q^2 - 1)*(q - 1)) + 1 By default, we return a rational function in `q`:: @@ -774,7 +774,7 @@ def principal_specialization(self, n=infinity, q=None): If ``n`` is not given we return the stable principal specialization:: - sage: x.principal_specialization(q=var("q")) + sage: x.principal_specialization(q=var("q")) # optional - sage.symbolic 3/((q^2 - 1)*(q - 1)) - 5/(q - 1)^3 + 1 TESTS:: @@ -881,12 +881,12 @@ def exponential_specialization(self, t=None, q=1): sage: x.exponential_specialization() 0 sage: x = p[3] + 5*p[1,1] + 2*p[1] + 1 - sage: x.exponential_specialization(t=var("t")) + sage: x.exponential_specialization(t=var("t")) # optional - sage.symbolic 5*t^2 + 2*t + 1 We also support the `q`-exponential_specialization:: - sage: factor(p[3].exponential_specialization(q=var("q"), t=var("t"))) + sage: factor(p[3].exponential_specialization(q=var("q"), t=var("t"))) # optional - sage.symbolic (q - 1)^2*t^3/(q^2 + q + 1) TESTS:: diff --git a/src/sage/combinat/sf/schur.py b/src/sage/combinat/sf/schur.py index 914d5aef8d6..202c31d7cee 100644 --- a/src/sage/combinat/sf/schur.py +++ b/src/sage/combinat/sf/schur.py @@ -661,10 +661,10 @@ def principal_specialization(self, n=infinity, q=None): q^4 + q^3 + 2*q^2 + q + 1 sage: x = 3*s[2,2] + 2*s[1] + 1 - sage: x.principal_specialization(3, q=var("q")) + sage: x.principal_specialization(3, q=var("q")) # optional - sage.symbolic 3*(q^4 - 1)*(q^3 - 1)*q^2/((q^2 - 1)*(q - 1)) + 2*(q^3 - 1)/(q - 1) + 1 - sage: x.principal_specialization(q=var("q")) + sage: x.principal_specialization(q=var("q")) # optional - sage.symbolic -2/(q - 1) + 3*q^2/((q^3 - 1)*(q^2 - 1)^2*(q - 1)) + 1 TESTS:: @@ -805,7 +805,7 @@ def exponential_specialization(self, t=None, q=1): We also support the `q`-exponential_specialization:: - sage: factor(s[3].exponential_specialization(q=var("q"), t=var("t"))) + sage: factor(s[3].exponential_specialization(q=var("q"), t=var("t"))) # optional - sage.symbolic t^3/((q^2 + q + 1)*(q + 1)) TESTS:: diff --git a/src/sage/combinat/species/structure.py b/src/sage/combinat/species/structure.py index 371d78eef9d..a4de6349c6d 100644 --- a/src/sage/combinat/species/structure.py +++ b/src/sage/combinat/species/structure.py @@ -12,11 +12,12 @@ Here we define this species using the default structures:: - sage: ball = species.SingletonSpecies(); o = var('o') + sage: ball = species.SingletonSpecies() sage: bar = species.EmptySetSpecies() sage: BB = CombinatorialSpecies() sage: BB.define(ball + ball*BB + ball*bar*BB) - sage: BB.isotypes([o]*3).list() + sage: o = var('o') # optional - sage.symbolic + sage: BB.isotypes([o]*3).list() # optional - sage.symbolic [o*(o*o), o*((o*{})*o), (o*{})*(o*o), (o*{})*((o*{})*o)] If we ignore the parentheses, we can read off that the integer diff --git a/src/sage/combinat/tutorial.py b/src/sage/combinat/tutorial.py index 6422d920378..904c7c3339c 100644 --- a/src/sage/combinat/tutorial.py +++ b/src/sage/combinat/tutorial.py @@ -275,37 +275,37 @@ introduce two variables, `C` and `z`, and we define the equation:: - sage: C, z = var('C,z') - sage: sys = [ C == z + C*C ] + sage: C, z = var('C,z') # optional - sage.symbolic + sage: sys = [ C == z + C*C ] # optional - sage.symbolic There are two solutions, which happen to have closed forms:: - sage: sol = solve(sys, C, solution_dict=True); sol + sage: sol = solve(sys, C, solution_dict=True); sol # optional - sage.symbolic [{C: -1/2*sqrt(-4*z + 1) + 1/2}, {C: 1/2*sqrt(-4*z + 1) + 1/2}] - sage: s0 = sol[0][C]; s1 = sol[1][C] + sage: s0 = sol[0][C]; s1 = sol[1][C] # optional - sage.symbolic and whose Taylor series begin as follows:: - sage: s0.series(z, 6) + sage: s0.series(z, 6) # optional - sage.symbolic 1*z + 1*z^2 + 2*z^3 + 5*z^4 + 14*z^5 + Order(z^6) - sage: s1.series(z, 6) + sage: s1.series(z, 6) # optional - sage.symbolic 1 + (-1)*z + (-1)*z^2 + (-2)*z^3 + (-5)*z^4 + (-14)*z^5 + Order(z^6) The second solution is clearly aberrant, while the first one gives the expected coefficients. Therefore, we set:: - sage: C = s0 + sage: C = s0 # optional - sage.symbolic We can now calculate the next terms:: - sage: C.series(z, 11) + sage: C.series(z, 11) # optional - sage.symbolic 1*z + 1*z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + 429*z^8 + 1430*z^9 + 4862*z^10 + Order(z^11) or calculate, more or less instantaneously, the 100-th coefficient:: - sage: C.series(z, 101).coefficient(z,100) + sage: C.series(z, 101).coefficient(z,100) # optional - sage.symbolic 227508830794229349661819540395688853956041682601541047340 It is unfortunate to have to recalculate everything if at some point we @@ -321,7 +321,7 @@ define by a recursive equation:: sage: C = L.undefined(valuation=1) - sage: C.define( z + C * C ) + sage: C.define(z + C * C) :: @@ -338,19 +338,19 @@ We now return to the closed form of `C(z)`:: - sage: z = var('z') - sage: C = s0; C + sage: z = var('z') # optional - sage.symbolic + sage: C = s0; C # optional - sage.symbolic -1/2*sqrt(-4*z + 1) + 1/2 The `n`-th coefficient in the Taylor series for `C(z)` being given by `\frac{1}{n!} C(z)^{(n)}(0)`, we look at the successive derivatives `C(z)^{(n)}(z)`:: - sage: derivative(C, z, 1) + sage: derivative(C, z, 1) # optional - sage.symbolic 1/sqrt(-4*z + 1) - sage: derivative(C, z, 2) + sage: derivative(C, z, 2) # optional - sage.symbolic 2/(-4*z + 1)^(3/2) - sage: derivative(C, z, 3) + sage: derivative(C, z, 3) # optional - sage.symbolic 12/(-4*z + 1)^(5/2) This suggests the existence of a simple explicit formula, which we will @@ -373,9 +373,9 @@ We check this:: - sage: n = var('n') - sage: c = 1/n*binomial(2*(n-1),n-1) - sage: [c.subs(n=k) for k in range(1, 11)] + sage: n = var('n') # optional - sage.symbolic + sage: c = 1/n*binomial(2*(n-1),n-1) # optional - sage.symbolic + sage: [c.subs(n=k) for k in range(1, 11)] # optional - sage.symbolic [1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862] sage: [catalan_number(k-1) for k in range(1, 11)] [1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862] @@ -383,14 +383,14 @@ We can now calculate coefficients much further; here we calculate `c_{100000}` which has more than `60000` digits:: - sage: cc = c(n = 100000) + sage: cc = c(n=100000) # optional - sage.symbolic This takes a couple of seconds:: - sage: %time cc = c(100000) # not tested + sage: %time cc = c(100000) # not tested # optional - sage.symbolic CPU times: user 2.34 s, sys: 0.00 s, total: 2.34 s Wall time: 2.34 s - sage: ZZ(cc).ndigits() + sage: ZZ(cc).ndigits() # optional - sage.symbolic 60198 The methods which we have used generalize to all recursively defined @@ -417,11 +417,11 @@ In the present case, `P=y^2-y+x`. We formally differentiate this equation with respect to `z`:: - sage: x, y, z = var('x, y, z') - sage: P = function('P')(x, y) - sage: C = function('C')(z) - sage: equation = P(x=z, y=C) == 0 - sage: diff(equation, z) + sage: x, y, z = var('x, y, z') # optional - sage.symbolic + sage: P = function('P')(x, y) # optional - sage.symbolic + sage: C = function('C')(z) # optional - sage.symbolic + sage: equation = P(x=z, y=C) == 0 # optional - sage.symbolic + sage: diff(equation, z) # optional - sage.symbolic diff(C(z), z)*D[1](P)(z, C(z)) + D[0](P)(z, C(z)) == 0 or, in a more readable format, @@ -434,9 +434,9 @@ In the case of complete binary trees, this gives:: - sage: P = y^2 - y + x - sage: Px = diff(P, x); Py = diff(P, y) - sage: - Px / Py + sage: P = y^2 - y + x # optional - sage.symbolic + sage: Px = diff(P, x); Py = diff(P, y) # optional - sage.symbolic + sage: - Px / Py # optional - sage.symbolic -1/(2*y - 1) Recall that `P(z, C(z))=0`. Thus, we can calculate this fraction @@ -476,7 +476,7 @@ sage: fraction = fraction.lift(); fraction (1/2/(x - 1/4))*y - 1/4/(x - 1/4) - sage: fraction(x=z, y=C) + sage: fraction(x=z, y=C) # optional - sage.symbolic 2*C(z)/(4*z - 1) - 1/(4*z - 1) or, more legibly, @@ -486,13 +486,13 @@ In this simple case, we can directly deduce from this expression a linear differential equation with coefficients in `\QQ[z]`:: - sage: equadiff = diff(C,z) == fraction(x=z, y=C) - sage: equadiff + sage: equadiff = diff(C,z) == fraction(x=z, y=C) # optional - sage.symbolic + sage: equadiff # optional - sage.symbolic diff(C(z), z) == 2*C(z)/(4*z - 1) - 1/(4*z - 1) - sage: equadiff = equadiff.simplify_rational() - sage: equadiff = equadiff * equadiff.rhs().denominator() - sage: equadiff = equadiff - equadiff.rhs() - sage: equadiff + sage: equadiff = equadiff.simplify_rational() # optional - sage.symbolic + sage: equadiff = equadiff * equadiff.rhs().denominator() # optional - sage.symbolic + sage: equadiff = equadiff - equadiff.rhs() # optional - sage.symbolic + sage: equadiff # optional - sage.symbolic (4*z - 1)*diff(C(z), z) - 2*C(z) + 1 == 0 or, more legibly, @@ -501,10 +501,10 @@ It is trivial to verify this equation on the closed form:: - sage: Cf = sage.symbolic.function_factory.function('C') - sage: equadiff.substitute_function(Cf, s0.function(z)) + sage: Cf = sage.symbolic.function_factory.function('C') # optional - sage.symbolic + sage: equadiff.substitute_function(Cf, s0.function(z)) # optional - sage.symbolic (4*z - 1)/sqrt(-4*z + 1) + sqrt(-4*z + 1) == 0 - sage: bool(equadiff.substitute_function(Cf, s0.function(z))) + sage: bool(equadiff.substitute_function(Cf, s0.function(z))) # optional - sage.symbolic True .. On veut non seulement remplacer les occurrences de C(z), mais @@ -774,14 +774,14 @@ formula. We look at the number of compositions of `n` ranging from `0` to `9`:: - sage: [ Compositions(n).cardinality() for n in range(10) ] + sage: [Compositions(n).cardinality() for n in range(10)] [1, 1, 2, 4, 8, 16, 32, 64, 128, 256] Similarly, if we consider the number of compositions of `5` by length, we find a line of Pascal’s triangle:: - sage: x = var('x') - sage: sum( x^len(c) for c in C5 ) + sage: x = var('x') # optional - sage.symbolic + sage: sum(x^len(c) for c in C5) # optional - sage.symbolic x^5 + 4*x^4 + 6*x^3 + 4*x^2 + x The above example uses a functionality which we have not seen yet: @@ -893,8 +893,8 @@ or the algebra of `2\times 2` matrices over the finite field `\ZZ/2\ZZ`:: - sage: C = MatrixSpace(GF(2), 2) - sage: C.list() + sage: C = MatrixSpace(GF(2), 2) # optional - sage.modules sage.rings.finite_rings + sage: C.list() # optional - sage.modules sage.rings.finite_rings [ [0 0] [1 0] [0 1] [0 0] [0 0] [1 1] [1 0] [1 0] [0 1] [0 1] [0 0], [0 0], [0 0], [1 0], [0 1], [0 0], [1 0], [0 1], [1 0], [0 1], @@ -902,7 +902,7 @@ [0 0] [1 1] [1 1] [1 0] [0 1] [1 1] [1 1], [1 0], [0 1], [1 1], [1 1], [1 1] ] - sage: C.cardinality() + sage: C.cardinality() # optional - sage.modules sage.rings.finite_rings 16 .. topic:: Exercise @@ -1146,24 +1146,24 @@ :: - sage: x = var('x') - sage: sum( x^len(s) for s in Subsets(8) ) + sage: x = var('x') # optional - sage.symbolic + sage: sum(x^len(s) for s in Subsets(8)) # optional - sage.symbolic x^8 + 8*x^7 + 28*x^6 + 56*x^5 + 70*x^4 + 56*x^3 + 28*x^2 + 8*x + 1 :: - sage: sum( x^p.length() for p in Permutations(3) ) + sage: sum(x^p.length() for p in Permutations(3)) # optional - sage.symbolic x^3 + 2*x^2 + 2*x + 1 :: - sage: factor(sum( x^p.length() for p in Permutations(3) )) + sage: factor(sum(x^p.length() for p in Permutations(3))) # optional - sage.symbolic (x^2 + x + 1)*(x + 1) :: sage: P = Permutations(5) - sage: all( p in P for p in P ) + sage: all(p in P for p in P) True :: @@ -1238,7 +1238,7 @@ ^^^^^^^^^^^^^^^^^^^^^^^ ``Python`` provides numerous tools for manipulating iterators; most of them -are in the ``itertools`` library, which can be imported by:: +are in the :mod:`itertools` library, which can be imported by:: sage: import itertools @@ -1375,15 +1375,15 @@ to define a formal variable ``Leaf`` for the leaves and a formal 2-ary function ``Node``:: - sage: var('Leaf') + sage: var('Leaf') # optional - sage.symbolic Leaf - sage: function('Node', nargs=2) + sage: function('Node', nargs=2) # optional - sage.symbolic Node The second tree in :ref:`figure-examples-catalan-trees` can be represented by the expression:: - sage: tr = Node(Node(Leaf, Node(Leaf, Leaf)), Leaf) + sage: tr = Node(Node(Leaf, Node(Leaf, Leaf)), Leaf) # optional - sage.symbolic .. _section-constructions: @@ -1666,7 +1666,7 @@ combinatorial species:: sage: from sage.combinat.species.library import * - sage: o = var('o') + sage: o = var('o') # optional - sage.symbolic We begin by redefining the complete binary trees; to do so, we stipulate the recurrence relation directly on the sets:: @@ -1678,10 +1678,10 @@ Now we can construct the set of trees with five nodes, list them, count them...:: - sage: BT5 = BT.isotypes([o]*5) - sage: BT5.cardinality() + sage: BT5 = BT.isotypes([o]*5) # optional - sage.symbolic + sage: BT5.cardinality() # optional - sage.symbolic 14 - sage: BT5.list() + sage: BT5.list() # optional - sage.symbolic [o*(o*(o*(o*o))), o*(o*((o*o)*o)), o*((o*o)*(o*o)), o*((o*(o*o))*o), o*(((o*o)*o)*o), (o*o)*(o*(o*o)), (o*o)*((o*o)*o), (o*(o*o))*(o*o), ((o*o)*o)*(o*o), @@ -1730,8 +1730,8 @@ :: - sage: FW3 = FW.isotypes([o]*3) - sage: FW3.list() + sage: FW3 = FW.isotypes([o]*3) # optional - sage.symbolic + sage: FW3.list() # optional - sage.symbolic [o*(o*(o*{})), o*(o*(({}*o)*{})), o*((({}*o)*o)*{}), (({}*o)*o)*(o*{}), (({}*o)*o)*(({}*o)*{})] @@ -1819,7 +1819,7 @@ them, exactly the same algorithm can be used, selecting only the children which are planar:: - sage: [len(list(graphs(n, property = lambda G: G.is_planar()))) + sage: [len(list(graphs(n, property=lambda G: G.is_planar()))) ....: for n in range(7)] [1, 1, 2, 4, 11, 33, 142] diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index d1aeb7c5b8a..ab639164b5a 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -1461,16 +1461,16 @@ def topological_entropy(self, n): sage: W = Words([0, 1]) sage: w = W([0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1]) - sage: t = w.topological_entropy(3); t + sage: t = w.topological_entropy(3); t # optional - sage.symbolic 1/3*log(7)/log(2) - sage: n(t) + sage: n(t) # optional - sage.symbolic 0.935784974019201 :: sage: w = words.ThueMorseWord()[:100] sage: topo = w.topological_entropy - sage: for i in range(0, 41, 5): + sage: for i in range(0, 41, 5): # optional - sage.symbolic ....: print("{} {}".format(i, n(topo(i), digits=5))) 0 1.0000 5 0.71699 @@ -1494,7 +1494,7 @@ def topological_entropy(self, n): sage: W = Words(range(20)) sage: w = W(range(20)) - sage: w.topological_entropy(3) + sage: w.topological_entropy(3) # optional - sage.symbolic 1/3*log(18)/log(20) """ d = self.parent().alphabet().cardinality() diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index 9c42e379cd4..07b504b2a78 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -540,9 +540,9 @@ def FibonacciWord(self, alphabet=(0, 1), construction_method="recursive"): :: - sage: words.FibonacciWord([0,1], 'function') + sage: words.FibonacciWord([0,1], 'function') # optional - sage.symbolic word: 0100101001001010010100100101001001010010... - sage: words.FibonacciWord('ab', 'function') + sage: words.FibonacciWord('ab', 'function') # optional - sage.symbolic word: abaababaabaababaababaabaababaabaababaaba... TESTS:: @@ -555,7 +555,7 @@ def FibonacciWord(self, alphabet=(0, 1), construction_method="recursive"): word: 0100101001001010010100100101001001010010... sage: f[:10000] == w[:10000] True - sage: f[:10000] == u[:10000] #long time + sage: f[:10000] == u[:10000] #long time True sage: words.FibonacciWord("abc") Traceback (most recent call last): @@ -745,17 +745,17 @@ def CharacteristicSturmianWord(self, slope, alphabet=(0, 1), bits=None): INPUT: - - ``slope`` - the slope of the word. It can be one of the following: + - ``slope`` -- the slope of the word. It can be one of the following: - real number in `]0, 1[` - iterable over the continued fraction expansion of a real number in `]0, 1[` - - ``alphabet`` - any container of length two that is suitable to + - ``alphabet`` -- any container of length two that is suitable to build an instance of OrderedAlphabet (list, tuple, str, ...) - - ``bits`` - integer (optional and considered only if ``slope`` is + - ``bits`` -- integer (optional and considered only if ``slope`` is a real number) the number of bits to consider when computing the continued fraction. @@ -774,7 +774,7 @@ def CharacteristicSturmianWord(self, slope, alphabet=(0, 1), bits=None): From real slope:: - sage: words.CharacteristicSturmianWord(1/golden_ratio^2) + sage: words.CharacteristicSturmianWord(1/golden_ratio^2) # optional - sage.symbolic word: 0100101001001010010100100101001001010010... sage: words.CharacteristicSturmianWord(4/5) word: 11110 @@ -927,19 +927,19 @@ def _CharacteristicSturmianWord_LetterIterator(self, cf, alphabet=(0,1)): EXAMPLES:: - sage: continued_fraction(1/golden_ratio^2)[:8] + sage: continued_fraction(1/golden_ratio^2)[:8] # optional - sage.symbolic [0; 2, 1, 1, 1, 1, 2] - sage: cf = iter(_) - sage: Word(words._CharacteristicSturmianWord_LetterIterator(cf)) + sage: cf = iter(_) # optional - sage.symbolic + sage: Word(words._CharacteristicSturmianWord_LetterIterator(cf)) # optional - sage.symbolic word: 0100101001001010010100100101001010 :: - sage: alpha = (sqrt(3)-1)/2 - sage: continued_fraction(alpha)[:10] + sage: alpha = (sqrt(3)-1)/2 # optional - sage.symbolic + sage: continued_fraction(alpha)[:10] # optional - sage.symbolic [0; 2, 1, 2, 1, 2, 1, 2, 1, 2] - sage: cf = iter(_) - sage: Word(words._CharacteristicSturmianWord_LetterIterator(cf)) + sage: cf = iter(_) # optional - sage.symbolic + sage: Word(words._CharacteristicSturmianWord_LetterIterator(cf)) # optional - sage.symbolic word: 0100100101001001001010010010010100100101... """ try: @@ -1133,23 +1133,23 @@ def LowerMechanicalWord(self, alpha, rho=0, alphabet=None): EXAMPLES:: - sage: words.LowerMechanicalWord(1/golden_ratio^2) + sage: words.LowerMechanicalWord(1/golden_ratio^2) # optional - sage.symbolic word: 0010010100100101001010010010100100101001... - sage: words.LowerMechanicalWord(1/5) + sage: words.LowerMechanicalWord(1/5) # optional - sage.symbolic word: 0000100001000010000100001000010000100001... - sage: words.LowerMechanicalWord(1/pi) + sage: words.LowerMechanicalWord(1/pi) # optional - sage.symbolic word: 0001001001001001001001000100100100100100... TESTS:: - sage: m = words.LowerMechanicalWord(1/golden_ratio^2)[1:] - sage: s = words.CharacteristicSturmianWord(1/golden_ratio^2) - sage: m[:500] == s[:500] + sage: m = words.LowerMechanicalWord(1/golden_ratio^2)[1:] # optional - sage.symbolic + sage: s = words.CharacteristicSturmianWord(1/golden_ratio^2) # optional - sage.symbolic + sage: m[:500] == s[:500] # optional - sage.symbolic True Check that this returns a word in an alphabet (:trac:`10054`):: - sage: words.UpperMechanicalWord(1/golden_ratio^2).parent() + sage: words.UpperMechanicalWord(1/golden_ratio^2).parent() # optional - sage.symbolic Infinite words over {0, 1} """ if not 0 <= alpha <= 1: @@ -1193,23 +1193,23 @@ def UpperMechanicalWord(self, alpha, rho=0, alphabet=None): EXAMPLES:: - sage: words.UpperMechanicalWord(1/golden_ratio^2) + sage: words.UpperMechanicalWord(1/golden_ratio^2) # optional - sage.symbolic word: 1010010100100101001010010010100100101001... - sage: words.UpperMechanicalWord(1/5) + sage: words.UpperMechanicalWord(1/5) # optional - sage.symbolic word: 1000010000100001000010000100001000010000... - sage: words.UpperMechanicalWord(1/pi) + sage: words.UpperMechanicalWord(1/pi) # optional - sage.symbolic word: 1001001001001001001001000100100100100100... TESTS:: - sage: m = words.UpperMechanicalWord(1/golden_ratio^2)[1:] - sage: s = words.CharacteristicSturmianWord(1/golden_ratio^2) - sage: m[:500] == s[:500] + sage: m = words.UpperMechanicalWord(1/golden_ratio^2)[1:] # optional - sage.symbolic + sage: s = words.CharacteristicSturmianWord(1/golden_ratio^2) # optional - sage.symbolic + sage: m[:500] == s[:500] # optional - sage.symbolic True Check that this returns a word in an alphabet (:trac:`10054`):: - sage: words.UpperMechanicalWord(1/golden_ratio^2).parent() + sage: words.UpperMechanicalWord(1/golden_ratio^2).parent() # optional - sage.symbolic Infinite words over {0, 1} """ if not 0 <= alpha <= 1: From 672a986a6648c9f4cb84e2cad409c5f5cc67bb2b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Mon, 15 May 2023 13:39:01 -0700 Subject: [PATCH 053/228] sage.combinat: Add # optional --- .../cluster_algebra_quiver/cluster_seed.py | 4 +- src/sage/combinat/k_regular_sequence.py | 242 +++++++++--------- src/sage/combinat/parallelogram_polyomino.py | 28 +- src/sage/combinat/partition.py | 2 +- src/sage/combinat/path_tableaux/frieze.py | 2 + src/sage/combinat/plane_partition.py | 3 +- src/sage/combinat/root_system/plot.py | 155 +++++------ .../root_system/reflection_group_complex.py | 2 +- .../root_system/root_lattice_realizations.py | 12 +- src/sage/combinat/sf/sfa.py | 12 +- src/sage/combinat/six_vertex_model.py | 2 +- src/sage/combinat/words/alphabet.py | 6 +- src/sage/combinat/words/word_generators.py | 2 +- 13 files changed, 242 insertions(+), 230 deletions(-) diff --git a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py index 31eac5999df..8f8a2a9fb3c 100644 --- a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py +++ b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py @@ -124,7 +124,7 @@ class ClusterSeed(SageObject): ....: frozen=['c']); S A seed for a cluster algebra of rank 4 with 1 frozen variable - sage: S = ClusterSeed(['D', 4],user_labels = [-1, 0, 1, 2]); S + sage: S = ClusterSeed(['D', 4], user_labels=[-1, 0, 1, 2]); S A seed for a cluster algebra of rank 4 of type ['D', 4] """ @@ -3019,7 +3019,7 @@ def universal_extension(self): [ 0 1] [ 0 -1] - sage: S = ClusterSeed(['A', 5], user_labels = [-2, -1, 0, 1 ,2]) + sage: S = ClusterSeed(['A', 5], user_labels=[-2, -1, 0, 1 ,2]) sage: U = S.universal_extension() sage: U.b_matrix() == ClusterSeed(['A', 5]).universal_extension().b_matrix() True diff --git a/src/sage/combinat/k_regular_sequence.py b/src/sage/combinat/k_regular_sequence.py index 596b6adb2a7..5b5f2398cc0 100644 --- a/src/sage/combinat/k_regular_sequence.py +++ b/src/sage/combinat/k_regular_sequence.py @@ -330,17 +330,17 @@ def subsequence(self, a, b): We check if the linear representation of the subsequences above indeed represent the correct vector valued sequences:: - sage: var('n') + sage: var('n') # optional - sage.symbolic n sage: def v(n): ....: return vector([3*n + 1, 6*n + 1]) - sage: S31.mu[0] * v(n) == v(2*n) + sage: S31.mu[0] * v(n) == v(2*n) # optional - sage.symbolic True - sage: S31.mu[1] * v(n) == v(2*n + 1) + sage: S31.mu[1] * v(n) == v(2*n + 1) # optional - sage.symbolic True - sage: function('delta_0') + sage: function('delta_0') # optional - sage.symbolic delta_0 sage: def simplify_delta(expr): @@ -348,17 +348,17 @@ def subsequence(self, a, b): sage: def v(n): ....: return vector([n -1 + delta_0(n), 2*n - 1 + delta_0(n), 4*n + 1]) - sage: simplify_delta(v(2*n) - Srs.mu[0]*v(n)).is_zero() + sage: simplify_delta(v(2*n) - Srs.mu[0]*v(n)).is_zero() # optional - sage.symbolic True - sage: simplify_delta(v(2*n + 1) - Srs.mu[1]*v(n)).is_zero() + sage: simplify_delta(v(2*n + 1) - Srs.mu[1]*v(n)).is_zero() # optional - sage.symbolic True sage: def v(n): ....: return vector([1 - delta_0(n), 1]) - sage: simplify_delta(v(2*n) - Sbd.mu[0]*v(n)).is_zero() + sage: simplify_delta(v(2*n) - Sbd.mu[0]*v(n)).is_zero() # optional - sage.symbolic True - sage: simplify_delta(v(2*n + 1) - Sbd.mu[1]*v(n)).is_zero() + sage: simplify_delta(v(2*n + 1) - Sbd.mu[1]*v(n)).is_zero() # optional - sage.symbolic True We check some corner-cases:: @@ -933,11 +933,11 @@ def from_recurrence(self, *args, **kwds): :: sage: Seq2 = kRegularSequenceSpace(2, ZZ) - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: Seq2.from_recurrence([ + sage: Seq2.from_recurrence([ # optional - sage.symbolic ....: f(2*n) == 2*f(n), f(2*n + 1) == 3*f(n) + 4*f(n - 1), ....: f(0) == 0, f(1) == 1], f, n) 2-regular sequence 0, 0, 0, 1, 2, 3, 4, 10, 6, 17, ... @@ -1021,26 +1021,26 @@ def from_recurrence(self, *args, **kwds): Stern--Brocot Sequence:: sage: Seq2 = kRegularSequenceSpace(2, ZZ) - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: SB = Seq2.from_recurrence([ + sage: SB = Seq2.from_recurrence([ # optional - sage.symbolic ....: f(2*n) == f(n), f(2*n + 1) == f(n) + f(n + 1), ....: f(0) == 0, f(1) == 1], f, n) - sage: SB + sage: SB # optional - sage.symbolic 2-regular sequence 0, 1, 1, 2, 1, 3, 2, 3, 1, 4, ... Number of Odd Entries in Pascal's Triangle:: - sage: Seq2.from_recurrence([ + sage: Seq2.from_recurrence([ # optional - sage.symbolic ....: f(2*n) == 3*f(n), f(2*n + 1) == 2*f(n) + f(n + 1), ....: f(0) == 0, f(1) == 1], f, n) 2-regular sequence 0, 1, 3, 5, 9, 11, 15, 19, 27, 29, ... Number of Unbordered Factors in the Thue--Morse Sequence:: - sage: UB = Seq2.from_recurrence([ + sage: UB = Seq2.from_recurrence([ # optional - sage.symbolic ....: f(8*n) == 2*f(4*n), ....: f(8*n + 1) == f(4*n + 1), ....: f(8*n + 2) == f(4*n + 1) + f(4*n + 3), @@ -1054,20 +1054,20 @@ def from_recurrence(self, *args, **kwds): ....: f(10) == 4, f(11) == 4, f(12) == 12, f(13) == 0, f(14) == 4, ....: f(15) == 4, f(16) == 8, f(17) == 4, f(18) == 8, f(19) == 0, ....: f(20) == 8, f(21) == 4, f(22) == 4, f(23) == 8], f, n, offset=3) - sage: UB + sage: UB # optional - sage.symbolic 2-regular sequence 1, 2, 2, 4, 2, 4, 6, 0, 4, 4, ... Binary sum of digits `S(n)`, characterized by the recurrence relations `S(4n) = S(2n)`, `S(4n + 1) = S(2n + 1)`, `S(4n + 2) = S(2n + 1)` and `S(4n + 3) = -S(2n) + 2S(2n + 1)`:: - sage: S = Seq2.from_recurrence([ + sage: S = Seq2.from_recurrence([ # optional - sage.symbolic ....: f(4*n) == f(2*n), ....: f(4*n + 1) == f(2*n + 1), ....: f(4*n + 2) == f(2*n + 1), ....: f(4*n + 3) == -f(2*n) + 2*f(2*n + 1), ....: f(0) == 0, f(1) == 1], f, n) - sage: S + sage: S # optional - sage.symbolic 2-regular sequence 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, ... In order to check if this sequence is indeed the binary sum of digits, @@ -1077,7 +1077,7 @@ def from_recurrence(self, *args, **kwds): sage: S2 = Seq2( ....: (Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [1, 1]])), ....: left=vector([0, 1]), right=vector([1, 0])) - sage: (S - S2).is_trivial_zero() + sage: (S - S2).is_trivial_zero() # optional - sage.symbolic True Alternatively, we can also use the simpler but inhomogeneous recurrence relations @@ -1095,13 +1095,13 @@ def from_recurrence(self, *args, **kwds): Number of Non-Zero Elements in the Generalized Pascal's Triangle (see [LRS2017]_):: sage: Seq2 = kRegularSequenceSpace(2, QQ) - sage: P = Seq2.from_recurrence([ + sage: P = Seq2.from_recurrence([ # optional - sage.symbolic ....: f(4*n) == 5/3*f(2*n) - 1/3*f(2*n + 1), ....: f(4*n + 1) == 4/3*f(2*n) + 1/3*f(2*n + 1), ....: f(4*n + 2) == 1/3*f(2*n) + 4/3*f(2*n + 1), ....: f(4*n + 3) == -1/3*f(2*n) + 5/3*f(2*n + 1), ....: f(0) == 1, f(1) == 2], f, n) - sage: P + sage: P # optional - sage.symbolic 2-regular sequence 1, 2, 3, 3, 4, 5, 5, 4, 5, 7, ... Finally, the same sequence can also be obtained via direct parameters @@ -1117,7 +1117,7 @@ def from_recurrence(self, *args, **kwds): TESTS:: - sage: Seq2.from_recurrence([ # long time + sage: Seq2.from_recurrence([ # long time # optional - sage.symbolic ....: f(4*n) == f(2*n), ....: f(4*n + 1) == f(2*n), ....: f(4*n + 2) == f(2*n), @@ -1129,7 +1129,7 @@ def from_recurrence(self, *args, **kwds): :: - sage: S = Seq2.from_recurrence([ + sage: S = Seq2.from_recurrence([ # optional - sage.symbolic ....: f(4*n) == f(2*n), ....: f(4*n + 1) == f(2*n), ....: f(4*n + 2) == f(2*n), @@ -1138,7 +1138,7 @@ def from_recurrence(self, *args, **kwds): ....: f(5) == 5, f(6) == 6, f(7) == 7, f(16) == 4, f(18) == 4, ....: f(20) == 4, f(22) == 4, f(24) == 6, f(26) == 6, f(28) == 6], ....: f, n, offset=2) - sage: all([S[4*i] == S[2*i] and + sage: all([S[4*i] == S[2*i] and # optional - sage.symbolic ....: S[4*i + 1] == S[2*i] and ....: S[4*i + 2] == S[2*i] and ....: S[4*i + 3] == S[2*i + 16] for i in srange(2, 100)]) @@ -1146,7 +1146,7 @@ def from_recurrence(self, *args, **kwds): :: - sage: S = Seq2.from_recurrence([ + sage: S = Seq2.from_recurrence([ # optional - sage.symbolic ....: f(4*n) == f(2*n), ....: f(4*n + 1) == f(2*n), ....: f(4*n + 2) == f(2*n), @@ -1159,7 +1159,7 @@ def from_recurrence(self, *args, **kwds): ....: f(22) == 22, f(23) == 23, f(24) == 24, f(25) == 25, ....: f(26) == 26, f(27) == 27, f(28) == 28, f(29) == 29, ....: f(30) == 30, f(31) == 31], f, n, offset=8) - sage: all([S[4*i] == S[2*i] and + sage: all([S[4*i] == S[2*i] and # optional - sage.symbolic ....: S[4*i + 1] == S[2*i] and ....: S[4*i + 2] == S[2*i] and ....: S[4*i + 3] == S[2*i - 16] for i in srange(8, 100)]) @@ -1167,11 +1167,11 @@ def from_recurrence(self, *args, **kwds): Same test with different variable and function names:: - sage: var('m') + sage: var('m') # optional - sage.symbolic m - sage: function('g') + sage: function('g') # optional - sage.symbolic g - sage: T = Seq2.from_recurrence([ + sage: T = Seq2.from_recurrence([ # optional - sage.symbolic ....: g(4*m) == g(2*m), ....: g(4*m + 1) == g(2*m), ....: g(4*m + 2) == g(2*m), @@ -1184,12 +1184,12 @@ def from_recurrence(self, *args, **kwds): ....: g(22) == 22, g(23) == 23, g(24) == 24, g(25) == 25, ....: g(26) == 26, g(27) == 27, g(28) == 28, g(29) == 29, ....: g(30) == 30, g(31) == 31], g, m, offset=8) - sage: (S - T).is_trivial_zero() # long time + sage: (S - T).is_trivial_zero() # long time # optional - sage.symbolic True Zero-sequence with non-zero initial values:: - sage: Seq2.from_recurrence([ + sage: Seq2.from_recurrence([ # optional - sage.symbolic ....: f(2*n) == 0, f(2*n + 1) == 0, ....: f(0) == 1, f(1) == 1, f(2) == 2, f(3) == 3], f, n) Traceback (most recent call last): @@ -1198,14 +1198,14 @@ def from_recurrence(self, *args, **kwds): :: - sage: Seq2.from_recurrence([ + sage: Seq2.from_recurrence([ # optional - sage.symbolic ....: f(2*n) == 0, f(2*n + 1) == 0, ....: f(0) == 1, f(1) == 1, f(2) == 2, f(3) == 3], f, n, offset=2) 2-regular sequence 1, 1, 2, 3, 0, 0, 0, 0, 0, 0, ... Check if inhomogeneities `0` do not change the sequence:: - sage: Seq2.from_recurrence([ + sage: Seq2.from_recurrence([ # optional - sage.symbolic ....: f(2*n) == 0, f(2*n + 1) == 0, ....: f(0) == 1, f(1) == 1, f(2) == 2, f(3) == 3], f, n, offset=2, ....: inhomogeneities={0: 0, 1: Seq2.zero()}) @@ -1247,7 +1247,7 @@ def from_recurrence(self, *args, **kwds): Number of Unbordered Factors in the Thue--Morse Sequence, but partly encoded with inhomogeneities:: - sage: UB2 = Seq2.from_recurrence([ + sage: UB2 = Seq2.from_recurrence([ # optional - sage.symbolic ....: f(8*n) == 2*f(4*n), ....: f(8*n + 1) == f(4*n + 1), ....: f(8*n + 2) == f(4*n + 1), @@ -1263,7 +1263,7 @@ def from_recurrence(self, *args, **kwds): ....: f(20) == 8, f(21) == 4, f(22) == 4, f(23) == 8], f, n, offset=3, ....: inhomogeneities={2: UB.subsequence(4, 3), 3: -UB.subsequence(4, 1), ....: 6: UB.subsequence(4, 2) + UB.subsequence(4, 3)}) - sage: (UB2 - Seq2(UB)).is_trivial_zero() + sage: (UB2 - Seq2(UB)).is_trivial_zero() # optional - sage.symbolic True """ RP = RecurrenceParser(self.k, self.coefficient_ring()) @@ -1324,11 +1324,11 @@ def parse_recurrence(self, equations, function, var): sage: from sage.combinat.k_regular_sequence import RecurrenceParser sage: RP = RecurrenceParser(2, ZZ) - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: RP.parse_recurrence([ + sage: RP.parse_recurrence([ # optional - sage.symbolic ....: f(4*n) == f(2*n) + 2*f(2*n + 1) + 3*f(2*n - 2), ....: f(4*n + 1) == 4*f(2*n) + 5*f(2*n + 1) + 6*f(2*n - 2), ....: f(4*n + 2) == 7*f(2*n) + 8*f(2*n + 1) + 9*f(2*n - 2), @@ -1340,7 +1340,7 @@ def parse_recurrence(self, equations, function, var): Stern--Brocot Sequence:: - sage: RP.parse_recurrence([ + sage: RP.parse_recurrence([ # optional - sage.symbolic ....: f(2*n) == f(n), f(2*n + 1) == f(n) + f(n + 1), ....: f(0) == 0, f(1) == 1], f, n) (1, 0, {(0, 0): 1, (1, 0): 1, (1, 1): 1}, {0: 0, 1: 1}) @@ -1353,28 +1353,28 @@ def parse_recurrence(self, equations, function, var): The following tests check that the equations are well-formed:: - sage: RP.parse_recurrence([], f, n) + sage: RP.parse_recurrence([], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: List of recurrence equations is empty. :: - sage: RP.parse_recurrence([f(4*n + 1)], f, n) + sage: RP.parse_recurrence([f(4*n + 1)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: f(4*n + 1) is not an equation with ==. :: - sage: RP.parse_recurrence([42], f, n) + sage: RP.parse_recurrence([42], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: 42 is not a symbolic expression. :: - sage: RP.parse_recurrence([f(2*n) + 1 == f(n)], f, n) + sage: RP.parse_recurrence([f(2*n) + 1 == f(n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(2*n) + 1 in the equation f(2*n) + 1 == f(n) is @@ -1382,7 +1382,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n, 5) == 3], f, n) + sage: RP.parse_recurrence([f(2*n, 5) == 3], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(2*n, 5) in the equation f(2*n, 5) == 3 does not @@ -1390,7 +1390,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f() == 3], f, n) + sage: RP.parse_recurrence([f() == 3], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f() in the equation f() == 3 does not have one @@ -1398,7 +1398,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(1/n + 1) == f(n)], f, n) + sage: RP.parse_recurrence([f(1/n + 1) == f(n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(1/n + 1) in the equation f(1/n + 1) == f(n): @@ -1406,7 +1406,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n + 1/2) == f(n)], f, n) + sage: RP.parse_recurrence([f(2*n + 1/2) == f(n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(2*n + 1/2) in the equation f(2*n + 1/2) == f(n): @@ -1414,7 +1414,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(4*n^2) == f(2*n^2)], f, n) + sage: RP.parse_recurrence([f(4*n^2) == f(2*n^2)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(4*n^2) in the equation f(4*n^2) == f(2*n^2): @@ -1422,7 +1422,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(42) == 1/2], f, n) + sage: RP.parse_recurrence([f(42) == 1/2], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Initial value 1/2 given by the equation f(42) == (1/2) @@ -1430,14 +1430,14 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(42) == 0, f(42) == 1], f, n) + sage: RP.parse_recurrence([f(42) == 0, f(42) == 1], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Initial value f(42) is given twice. :: - sage: RP.parse_recurrence([f(42) == f(n)], f, n) + sage: RP.parse_recurrence([f(42) == f(n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Initial value f(n) given by the equation f(42) == f(n) @@ -1445,7 +1445,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(4*n) == f(n), f(2*n) == f(n)], f, n) + sage: RP.parse_recurrence([f(4*n) == f(n), f(2*n) == f(n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(2*n) in the equation f(2*n) == f(n): 2 does not @@ -1454,7 +1454,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(3*n + 1) == f(n)], f, n) + sage: RP.parse_recurrence([f(3*n + 1) == f(n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(3*n + 1) in the equation f(3*n + 1) == f(n): @@ -1462,7 +1462,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(n + 1) == f(n)], f, n) + sage: RP.parse_recurrence([f(n + 1) == f(n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(n + 1) in the equation f(n + 1) == f(n): @@ -1470,14 +1470,14 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == f(n), f(2*n) == 0], f, n) + sage: RP.parse_recurrence([f(2*n) == f(n), f(2*n) == 0], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: There are more than one recurrence relation for f(2*n). :: - sage: RP.parse_recurrence([f(2*n + 2) == f(n)], f, n) + sage: RP.parse_recurrence([f(2*n + 2) == f(n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(2*n + 2) in the equation f(2*n + 2) == f(n): @@ -1485,7 +1485,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n - 1) == f(n)], f, n) + sage: RP.parse_recurrence([f(2*n - 1) == f(n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(2*n - 1) in the equation f(2*n - 1) == f(n): @@ -1493,7 +1493,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == 2*n], f, n) + sage: RP.parse_recurrence([f(2*n) == 2*n], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term 2*n in the equation f(2*n) == 2*n does not @@ -1501,7 +1501,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == 1/2*f(n)], f, n) + sage: RP.parse_recurrence([f(2*n) == 1/2*f(n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term 1/2*f(n) in the equation f(2*n) == 1/2*f(n): @@ -1509,21 +1509,21 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == 1/f(n)], f, n) + sage: RP.parse_recurrence([f(2*n) == 1/f(n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: 1/f(n) is not a valid right hand side. :: - sage: RP.parse_recurrence([f(2*n) == 2*n*f(n)], f, n) + sage: RP.parse_recurrence([f(2*n) == 2*n*f(n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: 2*n*f(n) is not a valid right hand side. :: - sage: RP.parse_recurrence([f(2*n) == 2*f(n, 5)], f, n) + sage: RP.parse_recurrence([f(2*n) == 2*f(n, 5)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(n, 5) in the equation f(2*n) == 2*f(n, 5) @@ -1531,14 +1531,14 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == 2*f()], f, n) + sage: RP.parse_recurrence([f(2*n) == 2*f()], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f() in the equation f(2*n) == 2*f() has no argument. :: - sage: RP.parse_recurrence([f(2*n) == 1/f(n) + 2*f(n)], f, n) + sage: RP.parse_recurrence([f(2*n) == 1/f(n) + 2*f(n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term 1/f(n) in the equation f(2*n) == 1/f(n) + 2*f(n) @@ -1546,7 +1546,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == 2*f(1/n)], f, n) + sage: RP.parse_recurrence([f(2*n) == 2*f(1/n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(1/n) in the equation f(2*n) == 2*f(1/n): @@ -1554,7 +1554,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == f(n + 1/2)], f, n) + sage: RP.parse_recurrence([f(2*n) == f(n + 1/2)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(n + 1/2) in the equation f(2*n) == f(n + 1/2): @@ -1562,7 +1562,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == f(1/2*n)], f, n) + sage: RP.parse_recurrence([f(2*n) == f(1/2*n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(1/2*n) in the equation f(2*n) == f(1/2*n): @@ -1570,7 +1570,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == f(n^2 + 1)], f, n) + sage: RP.parse_recurrence([f(2*n) == f(n^2 + 1)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(n^2 + 1) in the equation f(2*n) == f(n^2 + 1): @@ -1578,7 +1578,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == f(1)], f, n) + sage: RP.parse_recurrence([f(2*n) == f(1)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(1) in the equation f(2*n) == f(1): @@ -1586,7 +1586,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(4*n) == f(2*n) + f(n)], f, n) + sage: RP.parse_recurrence([f(4*n) == f(2*n) + f(n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(n) in the equation f(4*n) == f(2*n) + f(n): @@ -1595,7 +1595,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(4*n) == f(2*n), f(4*n + 1) == f(n)], + sage: RP.parse_recurrence([f(4*n) == f(2*n), f(4*n + 1) == f(n)], # optional - sage.symbolic ....: f, n) Traceback (most recent call last): ... @@ -1605,7 +1605,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(4*n) == f(3*n)], f, n) + sage: RP.parse_recurrence([f(4*n) == f(3*n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(3*n) in the equation f(4*n) == f(3*n): 3 is not @@ -1613,7 +1613,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == f(4*n)], f, n) + sage: RP.parse_recurrence([f(2*n) == f(4*n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(4*n) in the equation f(2*n) == f(4*n): @@ -1621,7 +1621,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == f(2*n)], f, n) + sage: RP.parse_recurrence([f(2*n) == f(2*n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Term f(2*n) in the equation f(2*n) == f(2*n): @@ -1629,14 +1629,14 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == f(n)], f, n) + sage: RP.parse_recurrence([f(2*n) == f(n)], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Recurrence relations for [f(2*n + 1)] are missing. :: - sage: RP.parse_recurrence([f(4*n) == f(n), f(4*n + 3) == 0], f, n) + sage: RP.parse_recurrence([f(4*n) == f(n), f(4*n + 3) == 0], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Recurrence relations for [f(4*n + 1), f(4*n + 2)] @@ -1644,20 +1644,20 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(42) == 0], f, n) + sage: RP.parse_recurrence([f(42) == 0], f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: No recurrence relations are given. :: - sage: RP.parse_recurrence( + sage: RP.parse_recurrence( # optional - sage.symbolic ....: [f(4*n + r) == f(n) for r in srange(4)], f, n) (2, 0, {(0, 0): 1, (1, 0): 1, (2, 0): 1, (3, 0): 1}, {}) :: - sage: RP.parse_recurrence( + sage: RP.parse_recurrence( # optional - sage.symbolic ....: [f(8*n) == f(n)] + ....: [f(8*n + r) == f(2*n) for r in srange(1,8)], f, n) Traceback (most recent call last): @@ -1668,35 +1668,35 @@ def parse_recurrence(self, equations, function, var): Finally, also for the zero-sequence the output is as expected:: - sage: RP.parse_recurrence([f(2*n) == 0, f(2*n + 1) == 0], f, n) + sage: RP.parse_recurrence([f(2*n) == 0, f(2*n + 1) == 0], f, n) # optional - sage.symbolic (1, 0, {}, {}) We check that the output is of the correct type (:trac:`33158`):: sage: RP = RecurrenceParser(2, QQ) - sage: equations = [ + sage: equations = [ # optional - sage.symbolic ....: f(4*n) == 5/3*f(2*n) - 1/3*f(2*n + 1), ....: f(4*n + 1) == 4/3*f(2*n) + 1/3*f(2*n + 1), ....: f(4*n + 2) == 1/3*f(2*n) + 4/3*f(2*n + 1), ....: f(4*n + 3) == -1/3*f(2*n) + 5/3*f(2*n + 1), ....: f(0) == 1, f(1) == 2] - sage: M, m, coeffs, initial_values = RP.parse_recurrence(equations, f, n) - sage: M.parent() + sage: M, m, coeffs, initial_values = RP.parse_recurrence(equations, f, n) # optional - sage.symbolic + sage: M.parent() # optional - sage.symbolic Integer Ring - sage: m.parent() + sage: m.parent() # optional - sage.symbolic Integer Ring - sage: all(v.parent() == QQ for v in coeffs.values()) + sage: all(v.parent() == QQ for v in coeffs.values()) # optional - sage.symbolic True - sage: all(v.parent() == QQ for v in initial_values.values()) + sage: all(v.parent() == QQ for v in initial_values.values()) # optional - sage.symbolic True This results in giving the correct (see :trac:`33158`) minimization in:: sage: Seq2 = kRegularSequenceSpace(2, QQ) - sage: P = Seq2.from_recurrence(equations, f, n) - sage: P + sage: P = Seq2.from_recurrence(equations, f, n) # optional - sage.symbolic + sage: P # optional - sage.symbolic 2-regular sequence 1, 2, 3, 3, 4, 5, 5, 4, 5, 7, ... - sage: P.minimized() + sage: P.minimized() # optional - sage.symbolic 2-regular sequence 1, 2, 3, 3, 4, 5, 5, 4, 5, 7, ... """ from sage.arith.srange import srange @@ -2118,9 +2118,9 @@ def parameters(self, M, m, coeffs, initial_values, offset=0, inhomogeneities={}) TESTS:: - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: RP.parameters(1, 0, {(0, 0): 1}, {}, 0, + sage: RP.parameters(1, 0, {(0, 0): 1}, {}, 0, # optional - sage.symbolic ....: {-1: 0, 1: 0, 10: 0, I: 0, n: 0}) Traceback (most recent call last): ... @@ -2129,7 +2129,7 @@ def parameters(self, M, m, coeffs, initial_values, offset=0, inhomogeneities={}) :: - sage: RP.parameters(1, 0, {(0, 0): 1}, {}, 0, + sage: RP.parameters(1, 0, {(0, 0): 1}, {}, 0, # optional - sage.symbolic ....: {0: n}) Traceback (most recent call last): ... @@ -2584,11 +2584,11 @@ def shifted_inhomogeneities(self, recurrence_rules): TESTS:: sage: Seq2 = kRegularSequenceSpace(2, ZZ) - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: UB = Seq2.from_recurrence([ + sage: UB = Seq2.from_recurrence([ # optional - sage.symbolic ....: f(8*n) == 2*f(4*n), ....: f(8*n + 1) == f(4*n + 1), ....: f(8*n + 2) == f(4*n + 1) + f(4*n + 3), @@ -2602,16 +2602,16 @@ def shifted_inhomogeneities(self, recurrence_rules): ....: f(10) == 4, f(11) == 4, f(12) == 12, f(13) == 0, f(14) == 4, ....: f(15) == 4, f(16) == 8, f(17) == 4, f(18) == 8, f(19) == 0, ....: f(20) == 8, f(21) == 4, f(22) == 4, f(23) == 8], f, n, offset=3) - sage: inhomogeneities={2: UB.subsequence(4, 3), 3: -UB.subsequence(4, 1), + sage: inhomogeneities={2: UB.subsequence(4, 3), 3: -UB.subsequence(4, 1), # optional - sage.symbolic ....: 6: UB.subsequence(4, 2) + UB.subsequence(4, 3)} - sage: recurrence_rules_UB = RR(M=3, m=2, ll=0, uu=9, + sage: recurrence_rules_UB = RR(M=3, m=2, ll=0, uu=9, # optional - sage.symbolic ....: inhomogeneities=inhomogeneities) - sage: shifted_inhomog = RP.shifted_inhomogeneities(recurrence_rules_UB) - sage: shifted_inhomog + sage: shifted_inhomog = RP.shifted_inhomogeneities(recurrence_rules_UB) # optional - sage.symbolic + sage: shifted_inhomog # optional - sage.symbolic {2: 2-regular sequence 8, 8, 8, 12, 12, 16, 12, 16, 12, 24, ..., 3: 2-regular sequence -10, -8, -8, -8, -8, -8, -8, -8, -8, -12, ..., 6: 2-regular sequence 20, 22, 24, 28, 28, 32, 28, 32, 32, 48, ...} - sage: shifted_inhomog[2].mu[0].ncols() == 3*inhomogeneities[2].mu[0].ncols() + sage: shifted_inhomog[2].mu[0].ncols() == 3*inhomogeneities[2].mu[0].ncols() # optional - sage.symbolic True .. SEEALSO:: @@ -2718,11 +2718,11 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): sage: from sage.combinat.k_regular_sequence import RecurrenceParser sage: RP = RecurrenceParser(2, ZZ) - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: M, m, coeffs, initial_values = RP.parse_recurrence([ + sage: M, m, coeffs, initial_values = RP.parse_recurrence([ # optional - sage.symbolic ....: f(8*n) == -1*f(2*n - 1) + 1*f(2*n + 1), ....: f(8*n + 1) == -11*f(2*n - 1) + 10*f(2*n) + 11*f(2*n + 1), ....: f(8*n + 2) == -21*f(2*n - 1) + 20*f(2*n) + 21*f(2*n + 1), @@ -2733,9 +2733,9 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): ....: f(8*n + 7) == -71*f(2*n - 1) + 70*f(2*n) + 71*f(2*n + 1), ....: f(0) == 0, f(1) == 1, f(2) == 2, f(3) == 3, f(4) == 4, ....: f(5) == 5, f(6) == 6, f(7) == 7], f, n) - sage: rules = RP.parameters( + sage: rules = RP.parameters( # optional - sage.symbolic ....: M, m, coeffs, initial_values, 0) - sage: RP.matrix(rules, 0, False) + sage: RP.matrix(rules, 0, False) # optional - sage.symbolic [ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0] @@ -2753,7 +2753,7 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): [ 0 0 0 -31 30 31 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 -41 40 41 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 -51 50 51 0 0 0 0 0 0 0 0 0 0 0] - sage: RP.matrix(rules, 1, False) + sage: RP.matrix(rules, 1, False) # optional - sage.symbolic [ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0] @@ -2788,7 +2788,7 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): Number of Unbordered Factors in the Thue--Morse Sequence:: - sage: M, m, coeffs, initial_values = RP.parse_recurrence([ + sage: M, m, coeffs, initial_values = RP.parse_recurrence([ # optional - sage.symbolic ....: f(8*n) == 2*f(4*n), ....: f(8*n + 1) == f(4*n + 1), ....: f(8*n + 2) == f(4*n + 1) + f(4*n + 3), @@ -2802,9 +2802,9 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): ....: f(10) == 4, f(11) == 4, f(12) == 12, f(13) == 0, f(14) == 4, ....: f(15) == 4, f(16) == 8, f(17) == 4, f(18) == 8, f(19) == 0, ....: f(20) == 8, f(21) == 4, f(22) == 4, f(23) == 8], f, n) - sage: UB_rules = RP.parameters( + sage: UB_rules = RP.parameters( # optional - sage.symbolic ....: M, m, coeffs, initial_values, 3) - sage: RP.matrix(UB_rules, 0) + sage: RP.matrix(UB_rules, 0) # optional - sage.symbolic [ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0] @@ -2821,7 +2821,7 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): [ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0] - sage: RP.matrix(UB_rules, 1) + sage: RP.matrix(UB_rules, 1) # optional - sage.symbolic [ 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0] @@ -3015,9 +3015,9 @@ def right(self, recurrence_rules): sage: from sage.combinat.k_regular_sequence import RecurrenceParser sage: RP = RecurrenceParser(2, ZZ) - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: function('f') + sage: function('f') # optional - sage.symbolic f sage: SB_rules = RP.parameters( ....: 1, 0, {(0, 0): 1, (1, 0): 1, (1, 1): 1}, @@ -3027,7 +3027,7 @@ def right(self, recurrence_rules): Number of Unbordered Factors in the Thue--Morse Sequence:: - sage: M, m, coeffs, initial_values = RP.parse_recurrence([ + sage: M, m, coeffs, initial_values = RP.parse_recurrence([ # optional - sage.symbolic ....: f(8*n) == 2*f(4*n), ....: f(8*n + 1) == f(4*n + 1), ....: f(8*n + 2) == f(4*n + 1) + f(4*n + 3), @@ -3041,9 +3041,9 @@ def right(self, recurrence_rules): ....: f(10) == 4, f(11) == 4, f(12) == 12, f(13) == 0, f(14) == 4, ....: f(15) == 4, f(16) == 8, f(17) == 4, f(18) == 8, f(19) == 0, ....: f(20) == 8, f(21) == 4, f(22) == 4, f(23) == 8], f, n) - sage: UB_rules = RP.parameters( + sage: UB_rules = RP.parameters( # optional - sage.symbolic ....: M, m, coeffs, initial_values, 3) - sage: RP.right(UB_rules) + sage: RP.right(UB_rules) # optional - sage.symbolic (1, 1, 2, 1, 2, 2, 4, 2, 4, 6, 0, 4, 4, 1, 0, 0) """ from sage.modules.free_module_element import vector @@ -3079,12 +3079,12 @@ def __call__(self, *args, **kwds): sage: from sage.combinat.k_regular_sequence import RecurrenceParser sage: RP = RecurrenceParser(2, ZZ) - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: RP([f(2*n) == f(n), f(2*n + 1) == f(n) + f(n + 1), + sage: RP([f(2*n) == f(n), f(2*n + 1) == f(n) + f(n + 1), # optional - sage.symbolic ....: f(0) == 0, f(1) == 1], f, n) ([ [1 0 0] [1 1 0] @@ -3094,7 +3094,7 @@ def __call__(self, *args, **kwds): (1, 0, 0), (0, 1, 1)) - sage: RP(equations=[f(2*n) == f(n), f(2*n + 1) == f(n) + f(n + 1), + sage: RP(equations=[f(2*n) == f(n), f(2*n + 1) == f(n) + f(n + 1), # optional - sage.symbolic ....: f(0) == 0, f(1) == 1], function=f, var=n) ([ [1 0 0] [1 1 0] diff --git a/src/sage/combinat/parallelogram_polyomino.py b/src/sage/combinat/parallelogram_polyomino.py index bb73b09df96..9c4ceedfd19 100644 --- a/src/sage/combinat/parallelogram_polyomino.py +++ b/src/sage/combinat/parallelogram_polyomino.py @@ -3703,14 +3703,14 @@ def _plot_diagram(self): sage: pp = ParallelogramPolyomino( ....: [[0, 1, 1, 1, 1], [1, 1, 1, 1, 0]] ....: ) - sage: pp._plot_diagram() + sage: pp._plot_diagram() # optional - sage.plot Graphics object consisting of 7 graphics primitives sage: pp = ParallelogramPolyomino([ ....: [0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], ....: [1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0] ....: ]) - sage: pp._plot_diagram() + sage: pp._plot_diagram() # optional - sage.plot Graphics object consisting of 25 graphics primitives """ G = Graphics() @@ -3755,14 +3755,14 @@ def _plot_bounce(self, directions=None): sage: pp = ParallelogramPolyomino( ....: [[0, 1, 1, 1, 1], [1, 1, 1, 1, 0]] ....: ) - sage: pp._plot_bounce(directions=[1]) + sage: pp._plot_bounce(directions=[1]) # optional - sage.plot Graphics object consisting of 1 graphics primitive sage: pp = ParallelogramPolyomino([ ....: [0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], ....: [1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0] ....: ]) - sage: pp._plot_bounce(directions=[0,1]) + sage: pp._plot_bounce(directions=[0,1]) # optional - sage.plot Graphics object consisting of 9 graphics primitives """ @@ -3798,14 +3798,14 @@ def _plot_bounce_values(self, bounce=0): sage: pp = ParallelogramPolyomino( ....: [[0, 1, 1, 1, 1], [1, 1, 1, 1, 0]] ....: ) - sage: pp._plot_bounce_values() + sage: pp._plot_bounce_values() # optional - sage.plot Graphics object consisting of 4 graphics primitives sage: pp = ParallelogramPolyomino([ ....: [0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], ....: [1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0] ....: ]) - sage: pp._plot_bounce_values(bounce=1) + sage: pp._plot_bounce_values(bounce=1) # optional - sage.plot Graphics object consisting of 10 graphics primitives """ G = Graphics() @@ -3847,14 +3847,14 @@ def _plot_tree(self): sage: pp = ParallelogramPolyomino( ....: [[0, 1, 1, 1, 1], [1, 1, 1, 1, 0]] ....: ) - sage: pp._plot_tree() + sage: pp._plot_tree() # optional - sage.plot Graphics object consisting of 2 graphics primitives sage: pp = ParallelogramPolyomino([ ....: [0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], ....: [1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0] ....: ]) - sage: pp._plot_tree() + sage: pp._plot_tree() # optional - sage.plot Graphics object consisting of 2 graphics primitives """ G = Graphics() @@ -3869,17 +3869,17 @@ def plot(self): EXAMPLES:: sage: pp = ParallelogramPolyomino([[0,1],[1,0]]) - sage: pp.plot() + sage: pp.plot() # optional - sage.plot Graphics object consisting of 4 graphics primitives sage: pp.set_options( ....: drawing_components=dict( - ....: diagram = True - ....: , bounce_0 = True - ....: , bounce_1 = True - ....: , bounce_values = 0 + ....: diagram=True, + ....: bounce_0=True, + ....: bounce_1=True, + ....: bounce_values=0, ....: ) ....: ) - sage: pp.plot() + sage: pp.plot() # optional - sage.plot Graphics object consisting of 7 graphics primitives """ G = Graphics() diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 5513086de21..3470e41cc77 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -5326,7 +5326,7 @@ def outline(self, variable=None): TESTS:: - sage: integrate(Partition([1]).outline()-abs(x),(x,-10,10)) + sage: integrate(Partition([1]).outline()-abs(x),(x,-10,10)) # optional - sage.symbolic 2 """ if variable is None: diff --git a/src/sage/combinat/path_tableaux/frieze.py b/src/sage/combinat/path_tableaux/frieze.py index d63935a6a3b..23ff179039c 100644 --- a/src/sage/combinat/path_tableaux/frieze.py +++ b/src/sage/combinat/path_tableaux/frieze.py @@ -322,6 +322,8 @@ def triangulation(self): sage: path_tableaux.FriezePattern([1,2,1/7,5,3]).triangulation() # optional - sage.plot sage.symbolic Graphics object consisting of 12 graphics primitives + + sage: x = polygen(ZZ, 'x') sage: K.<sqrt2> = NumberField(x^2 - 2) # optional - sage.rings.number_field sage: path_tableaux.FriezePattern([1,sqrt2,1,sqrt2,3,2*sqrt2,5,3*sqrt2,1], # optional - sage.plot sage.rings.number_field sage.symbolic ....: field=K).triangulation() diff --git a/src/sage/combinat/plane_partition.py b/src/sage/combinat/plane_partition.py index af96a0659fc..31ef06d95fa 100644 --- a/src/sage/combinat/plane_partition.py +++ b/src/sage/combinat/plane_partition.py @@ -38,8 +38,7 @@ from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation from sage.rings.integer_ring import ZZ -from sage.arith.misc import Sigma -from sage.functions.other import floor, ceil, binomial, factorial +from sage.arith.misc import Sigma, integer_floor as floor, integer_ceil as ceil, binomial, factorial from sage.sets.disjoint_union_enumerated_sets import DisjointUnionEnumeratedSets from sage.sets.family import Family from sage.sets.non_negative_integers import NonNegativeIntegers diff --git a/src/sage/combinat/root_system/plot.py b/src/sage/combinat/root_system/plot.py index ee23f9fe836..2c7a0bfbe45 100644 --- a/src/sage/combinat/root_system/plot.py +++ b/src/sage/combinat/root_system/plot.py @@ -29,7 +29,7 @@ angle:: sage: L = RootSystem(["A",2]).ambient_space() - sage: L.plot() + sage: L.plot() # optional - sage.plot sage.symbolic Graphics object consisting of 13 graphics primitives .. PLOT:: @@ -56,7 +56,7 @@ full picture in 3D:: sage: L = RootSystem(["A",2]).ambient_space() - sage: L.plot(projection=False) + sage: L.plot(projection=False) # optional - sage.plot sage.symbolic Graphics3d Object .. PLOT:: @@ -72,7 +72,7 @@ `G_2`:: sage: L = RootSystem(["G",2]).ambient_space() - sage: L.plot(reflection_hyperplanes="all") + sage: L.plot(reflection_hyperplanes="all") # optional - sage.plot sage.symbolic Graphics object consisting of 21 graphics primitives .. PLOT:: @@ -107,7 +107,7 @@ its corresponding reflection hyperplane:: sage: L = RootSystem(["A",2]).weight_space() - sage: L.plot(roots="all", reflection_hyperplanes="all").show(figsize=15) + sage: L.plot(roots="all", reflection_hyperplanes="all").show(figsize=15) # optional - sage.plot sage.symbolic .. NOTE:: @@ -128,7 +128,7 @@ sage: Q = RootSystem(["G",2]).root_space() sage: L = RootSystem(["G",2]).ambient_space() - sage: L.plot(roots=list(Q.positive_roots()), fundamental_weights=False) + sage: L.plot(roots=list(Q.positive_roots()), fundamental_weights=False) # optional - sage.plot sage.symbolic Graphics object consisting of 17 graphics primitives .. PLOT:: @@ -149,7 +149,8 @@ sage: L = RootSystem(["E",8]).ambient_space() sage: L.dimension() 8 - sage: L.plot(roots="all", reflection_hyperplanes=False, projection=lambda v: M*vector(v), labels=False) # long time + sage: L.plot(roots="all", reflection_hyperplanes=False, # long time # optional - sage.plot sage.symbolic + ....: projection=lambda v: M*vector(v), labels=False) Graphics3d Object .. PLOT:: @@ -184,7 +185,8 @@ elements of the Weyl group. We enlarge a bit the bounding box to make sure everything fits in the picture:: - sage: RootSystem(["G",2]).ambient_space().plot(alcoves=True, alcove_labels=True, bounding_box=5) + sage: RootSystem(["G",2]).ambient_space().plot(alcoves=True, # optional - sage.plot sage.symbolic +....: alcove_labels=True, bounding_box=5) Graphics object consisting of 37 graphics primitives .. PLOT:: @@ -194,7 +196,7 @@ The same picture in 3D, for type `B_3`:: - sage: RootSystem(["B",3]).ambient_space().plot(alcoves=True, alcove_labels=True) + sage: RootSystem(["B",3]).ambient_space().plot(alcoves=True, alcove_labels=True) # optional - sage.plot sage.symbolic Graphics3d Object .. PLOT:: @@ -213,7 +215,7 @@ We now draw the usual alcove picture for affine type `A_2^{(1)}`:: sage: L = RootSystem(["A",2,1]).ambient_space() - sage: L.plot() # long time + sage: L.plot() # long time # optional - sage.plot sage.symbolic Graphics object consisting of 160 graphics primitives .. PLOT:: @@ -231,7 +233,7 @@ we are visualizing here what's happening at level `1`. Here is the full picture in 3D:: - sage: L.plot(bounding_box=[[-3,3],[-3,3],[-1,1]], affine=False) # long time + sage: L.plot(bounding_box=[[-3,3],[-3,3],[-1,1]], affine=False) # long time # optional - sage.plot sage.symbolic Graphics3d Object .. PLOT:: @@ -246,7 +248,7 @@ It's usually more readable to only draw the intersection of the reflection hyperplanes with the level `1` hyperplane:: - sage: L.plot(affine=False, level=1) # long time + sage: L.plot(affine=False, level=1) # long time # optional - sage.plot sage.symbolic Graphics3d Object .. PLOT:: @@ -259,7 +261,7 @@ level 1:: sage: L = RootSystem(["G",2,1]).ambient_space() - sage: L.plot(affine=False, level=1) + sage: L.plot(affine=False, level=1) # optional - sage.plot sage.symbolic Graphics3d Object .. PLOT:: @@ -274,8 +276,8 @@ options of the :meth:`~sage.plot.plot3d.base.Graphics3d.show` method:: - sage: p = L.plot(affine=False, level=1) - sage: p.show(aspect_ratio=[1,1,2], frame=False) + sage: p = L.plot(affine=False, level=1) # optional - sage.plot sage.symbolic + sage: p.show(aspect_ratio=[1,1,2], frame=False) # optional - sage.plot sage.symbolic .. TOPIC:: Exercise @@ -289,7 +291,7 @@ `u = vs_i`; the color of that wall is given by `i`:: sage: L = RootSystem(["C",2,1]).ambient_space() - sage: L.plot(coroots="simple", alcove_labels=True) # long time + sage: L.plot(coroots="simple", alcove_labels=True) # long time # optional - sage.plot sage.symbolic Graphics object consisting of 216 graphics primitives .. PLOT:: @@ -308,7 +310,7 @@ sage: positive_roots = RecursivelyEnumeratedSet(seed, succ, structure='graded') sage: it = iter(positive_roots) sage: first_positive_roots = [next(it) for i in range(10)] - sage: L.plot(roots=first_positive_roots, affine=False, alcoves=False) + sage: L.plot(roots=first_positive_roots, affine=False, alcoves=False) # optional - sage.plot sage.symbolic Graphics object consisting of 24 graphics primitives .. PLOT:: @@ -346,11 +348,12 @@ sage: positive_coroots = RecursivelyEnumeratedSet(seed, succ, structure='graded') sage: it = iter(positive_coroots) sage: first_positive_coroots = [next(it) for i in range(20)] - sage: p = L.plot(fundamental_chamber=True, reflection_hyperplanes=first_positive_coroots, + sage: p = L.plot(fundamental_chamber=True, # optional - sage.plot sage.symbolic + ....: reflection_hyperplanes=first_positive_coroots, ....: affine=False, alcove_labels=1, ....: bounding_box=[[-9,9],[-1,2]], ....: projection=lambda x: matrix([[1,-1],[1,1]])*vector(x)) - sage: p.show(figsize=20) # long time + sage: p.show(figsize=20) # long time # optional - sage.plot sage.symbolic Higher dimension affine pictures @@ -360,7 +363,7 @@ tiled by the alcoves, each of which is a 3D simplex:: sage: L = RootSystem(["A",3,1]).ambient_space() - sage: L.plot(reflection_hyperplanes=False, bounding_box=85/100) # long time + sage: L.plot(reflection_hyperplanes=False, bounding_box=85/100) # long time # optional - sage.plot sage.symbolic Graphics3d Object .. PLOT:: @@ -376,7 +379,7 @@ the Weyl group:: sage: W = L.weyl_group() - sage: L.plot(reflection_hyperplanes=False, alcoves=[W.one()], bounding_box=2) + sage: L.plot(reflection_hyperplanes=False, alcoves=[W.one()], bounding_box=2) # optional - sage.plot sage.symbolic Graphics3d Object .. PLOT:: @@ -390,7 +393,7 @@ center in the root lattice:: sage: W = L.weyl_group() - sage: L.plot(reflection_hyperplanes=False, alcoves=[[0,0]], bounding_box=2) + sage: L.plot(reflection_hyperplanes=False, alcoves=[[0,0]], bounding_box=2) # optional - sage.plot sage.symbolic Graphics3d Object .. PLOT:: @@ -409,11 +412,12 @@ sage: L = RootSystem(["B",3,1]).ambient_space() sage: W = L.weyl_group() - sage: alcoves = [~w for d in range(12) for w in W.affine_grassmannian_elements_of_given_length(d)] - sage: p = L.plot_fundamental_chamber("classical") - sage: p += L.plot_alcoves(alcoves=alcoves, wireframe=True) - sage: p += L.plot_fundamental_weights() - sage: p.show(frame=False) + sage: alcoves = [~w for d in range(12) + ....: for w in W.affine_grassmannian_elements_of_given_length(d)] + sage: p = L.plot_fundamental_chamber("classical") # optional - sage.plot sage.symbolic + sage: p += L.plot_alcoves(alcoves=alcoves, wireframe=True) # optional - sage.plot sage.symbolic + sage: p += L.plot_fundamental_weights() # optional - sage.plot sage.symbolic + sage: p.show(frame=False) # optional - sage.plot sage.symbolic .. PLOT:: :width: 300 px @@ -448,7 +452,7 @@ sage: L = RootSystem(["A",2,1]).ambient_space() sage: w1 = [0,2,1,2,0,2,1,0,2,1,2,1,2,0,2,0,1,2,0] - sage: L.plot(alcove_walk=w1, bounding_box=6) # long time + sage: L.plot(alcove_walk=w1, bounding_box=6) # long time # optional - sage.plot sage.symbolic Graphics object consisting of 535 graphics primitives .. PLOT:: @@ -463,7 +467,7 @@ instead, it is actually built on top of many methods (see the list below) that can be called independently and combined at will:: - sage: L.plot_roots() + L.plot_reflection_hyperplanes() + sage: L.plot_roots() + L.plot_reflection_hyperplanes() # optional - sage.plot sage.symbolic Graphics object consisting of 12 graphics primitives .. PLOT:: @@ -479,9 +483,9 @@ tend to pollute the picture. Annoyingly they come back when combining them. Here is a workaround:: - sage: p = L.plot_roots() + L.plot_reflection_hyperplanes() - sage: p.axes(False) - sage: p + sage: p = L.plot_roots() + L.plot_reflection_hyperplanes() # optional - sage.plot sage.symbolic + sage: p.axes(False) # optional - sage.plot sage.symbolic + sage: p # optional - sage.plot sage.symbolic Graphics object consisting of 12 graphics primitives .. PLOT:: @@ -500,10 +504,12 @@ sage: plot_options = L.plot_parse_options(bounding_box=[[-2,5],[-2,6]]) sage: w2 = [2,1,2,0,2,0,2,1,2,0,1,2,1,2,1,0,1,2,0,2,0,1,2,0,2] - sage: p = L.plot_alcoves(plot_options=plot_options) # long time - sage: p += L.plot_alcove_walk(w1, color="green", plot_options=plot_options) # long time - sage: p += L.plot_alcove_walk(w2, color="orange", plot_options=plot_options) # long time - sage: p # long time + sage: p = L.plot_alcoves(plot_options=plot_options) # long time # optional - sage.plot sage.symbolic + sage: p += L.plot_alcove_walk(w1, color="green", # long time # optional - sage.plot sage.symbolic + ....: plot_options=plot_options) + sage: p += L.plot_alcove_walk(w2, color="orange", # long time # optional - sage.plot sage.symbolic + ....: plot_options=plot_options) + sage: p # long time # optional - sage.plot sage.symbolic Graphics object consisting of ... graphics primitives .. PLOT:: @@ -519,11 +525,12 @@ And another with some foldings:: - sage: p += L.plot_alcove_walk([0,1,2,0,2,0,1,2,0,1], - ....: foldings=[False, False, True, False, False, False, True, False, True, False], + sage: p += L.plot_alcove_walk([0,1,2,0,2,0,1,2,0,1], # optional - sage.plot sage.symbolic + ....: foldings=[False, False, True, False, False, + ....: False, True, False, True, False], ....: color="purple") - sage: p.axes(False) - sage: p.show(figsize=20) + sage: p.axes(False) # optional - sage.plot sage.symbolic + sage: p.show(figsize=20) # optional - sage.plot sage.symbolic .. PLOT:: :width: 300 px @@ -550,12 +557,13 @@ sage: t = 6*Lambda[1] - 2*Lambda[2] - 4*Lambda[0] sage: walk = L.reduced_word_of_translation(L(t)) sage: plot_options = L.plot_parse_options(bounding_box=[[-2,5],[-2,5]]) - sage: p = L.plot(plot_options=plot_options) # long time - sage: p += L.plot_alcove_walk(walk, color="green", plot_options=plot_options) # long time - sage: p += plot_options.family_of_vectors({t: L(t)}) # long time - sage: plot_options.finalize(p) # long time + sage: p = L.plot(plot_options=plot_options) # long time # optional - sage.plot sage.symbolic + sage: p += L.plot_alcove_walk(walk, color="green", # long time # optional - sage.plot sage.symbolic + ....: plot_options=plot_options) + sage: p += plot_options.family_of_vectors({t: L(t)}) # long time # optional - sage.plot sage.symbolic + sage: plot_options.finalize(p) # long time # optional - sage.plot sage.symbolic Graphics object consisting of ... graphics primitives - sage: p # long time + sage: p # long time # optional - sage.plot sage.symbolic Graphics object consisting of ... graphics primitives .. PLOT:: @@ -583,7 +591,8 @@ sage: L = RootSystem(["B",3,1]).ambient_space() sage: w3 = [0,2,1,3,2,0,2,1,0,2,3,1,2,1,3,2,0,2,0,1,2,0] - sage: L.plot_fundamental_weights() + L.plot_reflection_hyperplanes(bounding_box=2) + L.plot_alcove_walk(w3) + sage: (L.plot_fundamental_weights() # optional - sage.plot sage.symbolic + ....: + L.plot_reflection_hyperplanes(bounding_box=2) + L.plot_alcove_walk(w3) Graphics3d Object .. PLOT:: @@ -610,7 +619,8 @@ sage: L = RootSystem(["A",3,1]).ambient_space() sage: alcoves = cartesian_product([[0,1],[0,1],[0,1]]) sage: color = lambda i: "black" if i==0 else None - sage: L.plot_alcoves(alcoves=alcoves, color=color, bounding_box=10,wireframe=True).show(frame=False) # long time + sage: L.plot_alcoves(alcoves=alcoves, color=color, # long time # optional - sage.plot sage.symbolic + ....: bounding_box=10, wireframe=True).show(frame=False) .. PLOT:: :width: 300 px @@ -635,8 +645,9 @@ Now you can create your own customized color Coxeter graph paper:: sage: L = RootSystem(["C",2,1]).ambient_space() - sage: p = L.plot(bounding_box=[[-8,9],[-5,7]], coroots="simple") # long time (10 s) - sage: p # long time + sage: p = L.plot(bounding_box=[[-8,9],[-5,7]], # long time (10 s) # optional - sage.plot sage.symbolic + ....: coroots="simple") + sage: p # long time # optional - sage.plot sage.symbolic Graphics object consisting of ... graphics primitives .. PLOT:: @@ -649,7 +660,7 @@ if printed on paper. Instead, we recommend saving the picture in postscript or svg before printing it:: - sage: p.save("C21paper.eps") # not tested + sage: p.save("C21paper.eps") # not tested # optional - sage.plot sage.symbolic .. NOTE:: @@ -676,11 +687,11 @@ sage: W = L.weyl_group() sage: g = W.cayley_graph(side="right") sage: positions = {w: plot_options.projection(w.action(rho)) for w in W} - sage: p = L.plot_alcoves() - sage: p += g.plot(pos = positions, vertex_size=0, + sage: p = L.plot_alcoves() # optional - sage.plot sage.symbolic + sage: p += g.plot(pos=positions, vertex_size=0, # optional - sage.plot sage.symbolic ....: color_by_label=plot_options.color) - sage: p.axes(False) - sage: p + sage: p.axes(False) # optional - sage.plot sage.symbolic + sage: p # optional - sage.plot sage.symbolic Graphics object consisting of 30 graphics primitives .. PLOT:: @@ -707,9 +718,9 @@ sage: W = L.weyl_group() sage: g = W.cayley_graph(side="right") sage: positions = {w: plot_options.projection(w.action(rho)) for w in W} - sage: p = L.plot_roots() - sage: p += g.plot3d(pos3d=positions, color_by_label=plot_options.color) - sage: p + sage: p = L.plot_roots() # optional - sage.plot sage.symbolic + sage: p += g.plot3d(pos3d=positions, color_by_label=plot_options.color) # optional - sage.plot sage.symbolic + sage: p # optional - sage.plot sage.symbolic Graphics3d Object .. PLOT:: @@ -747,11 +758,11 @@ sage: g = C.digraph() sage: positions = {x: plot_options.projection(x.weight()) for x in C} - sage: p = L.plot() - sage: p += g.plot(pos=positions, + sage: p = L.plot() # optional - sage.plot sage.symbolic + sage: p += g.plot(pos=positions, # optional - sage.plot sage.symbolic ....: color_by_label=plot_options.color, vertex_size=0) - sage: p.axes(False) - sage: p.show(figsize=15) + sage: p.axes(False) # optional - sage.plot sage.symbolic + sage: p.show(figsize=15) # optional - sage.plot sage.symbolic .. PLOT:: :width: 300 px @@ -781,11 +792,11 @@ sage: L = C.weight_lattice_realization() sage: plot_options = L.plot_parse_options() sage: g = C.digraph() - sage: positions = {x:plot_options.projection(x.weight()) for x in C} - sage: p = L.plot(reflection_hyperplanes=False, fundamental_weights=False) - sage: p += g.plot3d(pos3d=positions, vertex_labels=True, + sage: positions = {x: plot_options.projection(x.weight()) for x in C} # optional - sage.plot sage.symbolic + sage: p = L.plot(reflection_hyperplanes=False, fundamental_weights=False) # optional - sage.plot sage.symbolic + sage: p += g.plot3d(pos3d=positions, vertex_labels=True, # optional - sage.plot sage.symbolic ....: color_by_label=plot_options.color, edge_labels=True) - sage: p + sage: p # optional - sage.plot sage.symbolic Graphics3d Object .. TOPIC:: Exercise @@ -1496,7 +1507,7 @@ def reflection_hyperplane(self, coroot, as_polyhedron=False): @cached_function def barycentric_projection_matrix(n, angle=0): r""" - Returns a family of `n+1` vectors evenly spaced in a real vector space of dimension `n` + Return a family of `n+1` vectors evenly spaced in a real vector space of dimension `n`. Those vectors are of norm `1`, the scalar product between any two vector is `1/n`, thus the distance between two tips is constant. @@ -1530,25 +1541,25 @@ def barycentric_projection_matrix(n, angle=0): Three vectors in dimension 2:: - sage: barycentric_projection_matrix(2) + sage: barycentric_projection_matrix(2) # optional - sage.symbolic [ 1/2*sqrt(3) -1/2*sqrt(3) 0] [ 1/2 1/2 -1] Four vectors in dimension 3:: - sage: m = barycentric_projection_matrix(3); m + sage: m = barycentric_projection_matrix(3); m # optional - sage.symbolic [ 1/3*sqrt(3)*sqrt(2) -1/3*sqrt(3)*sqrt(2) 0 0] [ 1/3*sqrt(2) 1/3*sqrt(2) -2/3*sqrt(2) 0] [ 1/3 1/3 1/3 -1] The columns give four vectors that sum up to zero:: - sage: sum(m.columns()) + sage: sum(m.columns()) # optional - sage.symbolic (0, 0, 0) and have regular mutual angles:: - sage: m.transpose()*m + sage: m.transpose()*m # optional - sage.symbolic [ 1 -1/3 -1/3 -1/3] [-1/3 1 -1/3 -1/3] [-1/3 -1/3 1 -1/3] @@ -1556,19 +1567,19 @@ def barycentric_projection_matrix(n, angle=0): Here is a plot of them:: - sage: sum(arrow((0,0,0),x) for x in m.columns()) + sage: sum(arrow((0,0,0),x) for x in m.columns()) # optional - sage.plot sage.symbolic Graphics3d Object For 2D drawings of root systems, it is desirable to rotate the result to match with the usual conventions:: - sage: barycentric_projection_matrix(2, angle=2*pi/3) + sage: barycentric_projection_matrix(2, angle=2*pi/3) # optional - sage.symbolic [ 1/2 -1 1/2] [ 1/2*sqrt(3) 0 -1/2*sqrt(3)] TESTS:: - sage: for n in range(1, 7): + sage: for n in range(1, 7): # optional - sage.symbolic ....: m = barycentric_projection_matrix(n) ....: assert sum(m.columns()).is_zero() ....: assert matrix(QQ, n+1,n+1, lambda i,j: 1 if i==j else -1/n) == m.transpose()*m diff --git a/src/sage/combinat/root_system/reflection_group_complex.py b/src/sage/combinat/root_system/reflection_group_complex.py index 346cb59061b..87424491233 100644 --- a/src/sage/combinat/root_system/reflection_group_complex.py +++ b/src/sage/combinat/root_system/reflection_group_complex.py @@ -1737,7 +1737,7 @@ def invariant_value(i,j): coeffs = [] for i in self.index_set(): - coeff = 1-E(S[i].order()) + coeff = 1 - E(S[i].order()) if coeff in QQ: coeff = QQ(coeff) coeffs.append(coeff) diff --git a/src/sage/combinat/root_system/root_lattice_realizations.py b/src/sage/combinat/root_system/root_lattice_realizations.py index 2e2b2d2f3a9..70814864cd6 100644 --- a/src/sage/combinat/root_system/root_lattice_realizations.py +++ b/src/sage/combinat/root_system/root_lattice_realizations.py @@ -2442,13 +2442,13 @@ def plot_reflection_hyperplanes(self, collection="simple", **options): TESTS:: sage: L = RootSystem(["A",2]).ambient_space() - sage: print(L.plot_reflection_hyperplanes().description()) + sage: print(L.plot_reflection_hyperplanes().description()) # optional - sage.plot sage.symbolic Text '$H_{\alpha^\vee_{1}}$' at the point (-1.81...,3.15...) Text '$H_{\alpha^\vee_{2}}$' at the point (1.81...,3.15...) Line defined by 2 points: [(-1.73..., 3.0), (1.73..., -3.0)] Line defined by 2 points: [(1.73..., 3.0), (-1.73..., -3.0)] - sage: print(L.plot_reflection_hyperplanes("all").description()) + sage: print(L.plot_reflection_hyperplanes("all").description()) # optional - sage.plot sage.symbolic Text '$H_{\alpha^\vee_{1} + \alpha^\vee_{2}}$' at the point (3.15...,0.0) Text '$H_{\alpha^\vee_{1}}$' at the point (-1.81...,3.15...) Text '$H_{\alpha^\vee_{2}}$' at the point (1.81...,3.15...) @@ -2457,7 +2457,7 @@ def plot_reflection_hyperplanes(self, collection="simple", **options): Line defined by 2 points: [(3.0, 0.0), (-3.0, 0.0)] sage: L = RootSystem(["A",2,1]).ambient_space() - sage: print(L.plot_reflection_hyperplanes().description()) + sage: print(L.plot_reflection_hyperplanes().description()) # optional - sage.plot sage.symbolic Text '$H_{\alpha^\vee_{0}}$' at the point (3.15...,0.90...) Text '$H_{\alpha^\vee_{1}}$' at the point (-1.81...,3.15...) Text '$H_{\alpha^\vee_{2}}$' at the point (1.81...,3.15...) @@ -2832,12 +2832,12 @@ def plot_bounding_box(self, **options): EXAMPLES:: sage: L = RootSystem(["A",2,1]).ambient_space() - sage: L.plot_bounding_box() + sage: L.plot_bounding_box() # optional - sage.plot sage.symbolic Graphics object consisting of 1 graphics primitive TESTS:: - sage: list(L.plot_bounding_box()) + sage: list(L.plot_bounding_box()) # optional - sage.plot sage.symbolic [Polygon defined by 4 points] """ plot_options = self.plot_parse_options(**options) @@ -3149,7 +3149,7 @@ def plot_crystal(self, crystal, sage: LS = crystals.LSPaths(['A',2], [1,1]) sage: L = RootSystem(['A',2]).ambient_space() - sage: L.plot_crystal(LS) + sage: L.plot_crystal(LS) # optional - sage.plot sage.symbolic Graphics object consisting of 16 graphics primitives """ from sage.plot.arrow import arrow diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index a39e6358709..d32397c2879 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -4915,8 +4915,8 @@ def scalar_qt(self, x, q=None, t=None): -q^3 + 2*q^2 - 2*q + 1 sage: a.scalar_qt(a,5,7) # q=5 and t=7 490/1539 - sage: (x,y) = var('x,y') - sage: a.scalar_qt(a,q=x,t=y) + sage: (x,y) = var('x,y') # optional - sage.symbolic + sage: a.scalar_qt(a, q=x, t=y) # optional - sage.symbolic 1/3*(x^3 - 1)/(y^3 - 1) + 2/3*(x - 1)^3/(y - 1)^3 sage: Rn = QQ['q','t','y','z'].fraction_field() sage: (q,t,y,z) = Rn.gens() @@ -6029,7 +6029,7 @@ def principal_specialization(self, n=infinity, q=None): it is better to obtain an element of the symbolic ring:: sage: h = SymmetricFunctions(QQ).h() - sage: (h[3]+h[2]).principal_specialization(q=var("q")) + sage: (h[3]+h[2]).principal_specialization(q=var("q")) # optional - sage.symbolic 1/((q^2 - 1)*(q - 1)) - 1/((q^3 - 1)*(q^2 - 1)*(q - 1)) In case ``q`` is in the base ring, it must be passed explicitly:: @@ -6290,11 +6290,11 @@ def exponential_specialization(self, t=None, q=1): sage: x = m[3]+m[2,1]+m[1,1,1] sage: d = x.homogeneous_degree() - sage: var("q t") + sage: var("q t") # optional - sage.symbolic (q, t) - sage: factor((x.principal_specialization()*(1-q)^d*t^d)) + sage: factor((x.principal_specialization()*(1-q)^d*t^d)) # optional - sage.symbolic t^3/((q^2 + q + 1)*(q + 1)) - sage: factor(x.exponential_specialization(q=q, t=t)) + sage: factor(x.exponential_specialization(q=q, t=t)) # optional - sage.symbolic t^3/((q^2 + q + 1)*(q + 1)) TESTS:: diff --git a/src/sage/combinat/six_vertex_model.py b/src/sage/combinat/six_vertex_model.py index 9bd289ff221..b688bdecb53 100644 --- a/src/sage/combinat/six_vertex_model.py +++ b/src/sage/combinat/six_vertex_model.py @@ -650,7 +650,7 @@ def partition_function(self, beta, epsilon): EXAMPLES:: sage: M = SixVertexModel(3, boundary_conditions='ice') - sage: M.partition_function(2, [1,2,1,2,1,2]) + sage: M.partition_function(2, [1,2,1,2,1,2]) # optional - sage.symbolic e^(-24) + 2*e^(-28) + e^(-30) + 2*e^(-32) + e^(-36) REFERENCES: diff --git a/src/sage/combinat/words/alphabet.py b/src/sage/combinat/words/alphabet.py index 3286eb8b3b4..5d1b0d5468a 100644 --- a/src/sage/combinat/words/alphabet.py +++ b/src/sage/combinat/words/alphabet.py @@ -193,15 +193,15 @@ def build_alphabet(data=None, names=None, name=None): Traceback (most recent call last): ... ValueError: invalid value for names - sage: Alphabet(8, x) + sage: Alphabet(8, x) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: invalid value for names - sage: Alphabet(name=x, names="punctuation") + sage: Alphabet(name=x, names="punctuation") # optional - sage.symbolic Traceback (most recent call last): ... ValueError: name cannot be specified with any other argument - sage: Alphabet(x) + sage: Alphabet(x) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: unable to construct an alphabet from the given parameters diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index 07b504b2a78..3a0fb332d51 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -780,7 +780,7 @@ def CharacteristicSturmianWord(self, slope, alphabet=(0, 1), bits=None): word: 11110 sage: words.CharacteristicSturmianWord(5/14) word: 01001001001001 - sage: words.CharacteristicSturmianWord(pi-3) + sage: words.CharacteristicSturmianWord(pi - 3) # optional - sage.symbolic word: 0000001000000100000010000001000000100000... From an iterator of the continued fraction expansion of a real:: From 917030bcf721650658ce50ba23050aa77a21b142 Mon Sep 17 00:00:00 2001 From: Antonio Rojas <arojas@archlinux.org> Date: Wed, 7 Jun 2023 20:35:46 +0200 Subject: [PATCH 054/228] Modify tests so they give the same answer with maxima 5.46/47 --- src/sage/interfaces/interface.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index bacbbfe87f9..f8237d3ad94 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -1579,20 +1579,20 @@ def _mul_(self, right): :: sage: f = maxima.function('x','sin(x)') - sage: g = maxima('-cos(x)') # not a function! + sage: g = maxima('cos(x)') # not a function! sage: f*g - -...cos(x)*sin(x)... + cos(x)*sin(x) sage: _(2) - -...cos(2)*sin(2)... + cos(2)*sin(2) :: sage: f = maxima.function('x','sin(x)') - sage: g = maxima('-cos(x)') + sage: g = maxima('cos(x)') sage: g*f - -...cos(x)*sin(x)... + cos(x)*sin(x) sage: _(2) - -...cos(2)*sin(2)... + cos(2)*sin(2) sage: 2*f 2*sin(x) """ @@ -1612,20 +1612,20 @@ def _div_(self, right): :: sage: f = maxima.function('x','sin(x)') - sage: g = maxima('-cos(x)') + sage: g = maxima('cos(x)') sage: f/g - -...sin(x)/cos(x)... + sin(x)/cos(x) sage: _(2) - -...sin(2)/cos(2)... + sin(2)/cos(2) :: sage: f = maxima.function('x','sin(x)') - sage: g = maxima('-cos(x)') + sage: g = maxima('cos(x)') sage: g/f - -...cos(x)/sin(x)... + cos(x)/sin(x) sage: _(2) - -...cos(2)/sin(2)... + cos(2)/sin(2) sage: 2/f 2/sin(x) """ From 72b17739083d7b1d09d02598e50cff94afdb297b Mon Sep 17 00:00:00 2001 From: Antonio Rojas <arojas@archlinux.org> Date: Wed, 7 Jun 2023 20:44:14 +0200 Subject: [PATCH 055/228] Make some tests less verbose --- src/doc/de/tutorial/interfaces.rst | 9 +++------ src/doc/fr/tutorial/interfaces.rst | 9 +++------ src/doc/ja/tutorial/interfaces.rst | 9 +++------ src/doc/pt/tutorial/interfaces.rst | 9 +++------ src/doc/ru/tutorial/interfaces.rst | 9 +++------ 5 files changed, 15 insertions(+), 30 deletions(-) diff --git a/src/doc/de/tutorial/interfaces.rst b/src/doc/de/tutorial/interfaces.rst index 3b5bde7df15..67c94708924 100644 --- a/src/doc/de/tutorial/interfaces.rst +++ b/src/doc/de/tutorial/interfaces.rst @@ -332,12 +332,9 @@ Und der letzte ist die berühmte Kleinsche Flasche: :: - sage: maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") - 5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0 - sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() - -5*(cos(1/2*x)*cos(y) + sin(1/2*x)*sin(2*y) + 3.0)*sin(x) - sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") - 5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y)) + sage: _ = maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") + sage: _ = maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() + sage: _ = maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested ....: "[y, -%pi, %pi]", "['grid, 40, 40]", ....: '[plot_format, openmath]') diff --git a/src/doc/fr/tutorial/interfaces.rst b/src/doc/fr/tutorial/interfaces.rst index 807ab6d8ee2..1fb97e27fa7 100644 --- a/src/doc/fr/tutorial/interfaces.rst +++ b/src/doc/fr/tutorial/interfaces.rst @@ -334,12 +334,9 @@ Et la fameuse bouteille de Klein (n'entrez pas les ``....:``): :: - sage: maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") - 5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0 - sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() - -5*(cos(1/2*x)*cos(y) + sin(1/2*x)*sin(2*y) + 3.0)*sin(x) - sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") - 5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y)) + sage: _ = maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") + sage: _ = maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() + sage: _ = maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested ....: "[y, -%pi, %pi]", "['grid, 40, 40]", ....: '[plot_format, openmath]') diff --git a/src/doc/ja/tutorial/interfaces.rst b/src/doc/ja/tutorial/interfaces.rst index b48087c7bca..ec3ee16afe6 100644 --- a/src/doc/ja/tutorial/interfaces.rst +++ b/src/doc/ja/tutorial/interfaces.rst @@ -299,11 +299,8 @@ Sage/Maximaインターフェイスの使い方を例示するため,ここで :: - sage: maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") - 5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0 - sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() - -5*(cos(1/2*x)*cos(y) + sin(1/2*x)*sin(2*y) + 3.0)*sin(x) - sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") - 5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y)) + sage: _ = maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") + sage: _ = maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() + sage: _ = maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested ....: "[y, -%pi, %pi]", "['grid, 40, 40]", '[plot_format, openmath]') diff --git a/src/doc/pt/tutorial/interfaces.rst b/src/doc/pt/tutorial/interfaces.rst index b993b304a35..fa1e426e4b4 100644 --- a/src/doc/pt/tutorial/interfaces.rst +++ b/src/doc/pt/tutorial/interfaces.rst @@ -330,13 +330,10 @@ E agora a famosa garrafa de Klein: :: - sage: maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)" + sage: _ =maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)" ....: "- 10.0") - 5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0 - sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() - -5*(cos(1/2*x)*cos(y) + sin(1/2*x)*sin(2*y) + 3.0)*sin(x) - sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") - 5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y)) + sage: _ = maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() + sage: _ = maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") sage: maxima.plot3d("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested ....: "[y, -%pi, %pi]", "['grid, 40, 40]", ....: '[plot_format, openmath]') diff --git a/src/doc/ru/tutorial/interfaces.rst b/src/doc/ru/tutorial/interfaces.rst index 7d7886b26cf..07d4e5b63d7 100644 --- a/src/doc/ru/tutorial/interfaces.rst +++ b/src/doc/ru/tutorial/interfaces.rst @@ -323,12 +323,9 @@ gnuplot, имеет методы решения и манипуляции мат :: - sage: maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") - 5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0 - sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() - -5*(cos(1/2*x)*cos(y) + sin(1/2*x)*sin(2*y) + 3.0)*sin(x) - sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") - 5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y)) + sage: _ = maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") + sage: _ = maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() + sage: _ = maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested ....: "[y, -%pi, %pi]", "['grid, 40, 40]", ....: '[plot_format, openmath]') From d67a2a1349e3ccf4bb9866b2d6f9f310565332cf Mon Sep 17 00:00:00 2001 From: Antonio Rojas <arojas@archlinux.org> Date: Wed, 7 Jun 2023 20:46:27 +0200 Subject: [PATCH 056/228] Drop no longer needed sage conversion --- src/doc/de/tutorial/interfaces.rst | 2 +- src/doc/fr/tutorial/interfaces.rst | 2 +- src/doc/ja/tutorial/interfaces.rst | 2 +- src/doc/pt/tutorial/interfaces.rst | 4 ++-- src/doc/ru/tutorial/interfaces.rst | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/doc/de/tutorial/interfaces.rst b/src/doc/de/tutorial/interfaces.rst index 67c94708924..d83225b5315 100644 --- a/src/doc/de/tutorial/interfaces.rst +++ b/src/doc/de/tutorial/interfaces.rst @@ -333,7 +333,7 @@ Und der letzte ist die berühmte Kleinsche Flasche: :: sage: _ = maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") - sage: _ = maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() + sage: _ = maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)") sage: _ = maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested ....: "[y, -%pi, %pi]", "['grid, 40, 40]", diff --git a/src/doc/fr/tutorial/interfaces.rst b/src/doc/fr/tutorial/interfaces.rst index 1fb97e27fa7..2cb14e772eb 100644 --- a/src/doc/fr/tutorial/interfaces.rst +++ b/src/doc/fr/tutorial/interfaces.rst @@ -335,7 +335,7 @@ Et la fameuse bouteille de Klein (n'entrez pas les ``....:``): :: sage: _ = maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") - sage: _ = maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() + sage: _ = maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)") sage: _ = maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested ....: "[y, -%pi, %pi]", "['grid, 40, 40]", diff --git a/src/doc/ja/tutorial/interfaces.rst b/src/doc/ja/tutorial/interfaces.rst index ec3ee16afe6..892fc6f852f 100644 --- a/src/doc/ja/tutorial/interfaces.rst +++ b/src/doc/ja/tutorial/interfaces.rst @@ -300,7 +300,7 @@ Sage/Maximaインターフェイスの使い方を例示するため,ここで :: sage: _ = maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") - sage: _ = maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() + sage: _ = maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)") sage: _ = maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested ....: "[y, -%pi, %pi]", "['grid, 40, 40]", '[plot_format, openmath]') diff --git a/src/doc/pt/tutorial/interfaces.rst b/src/doc/pt/tutorial/interfaces.rst index fa1e426e4b4..5badb31ab35 100644 --- a/src/doc/pt/tutorial/interfaces.rst +++ b/src/doc/pt/tutorial/interfaces.rst @@ -330,9 +330,9 @@ E agora a famosa garrafa de Klein: :: - sage: _ =maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)" + sage: _ = maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)" ....: "- 10.0") - sage: _ = maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() + sage: _ = maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)") sage: _ = maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") sage: maxima.plot3d("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested ....: "[y, -%pi, %pi]", "['grid, 40, 40]", diff --git a/src/doc/ru/tutorial/interfaces.rst b/src/doc/ru/tutorial/interfaces.rst index 07d4e5b63d7..061818ca4a5 100644 --- a/src/doc/ru/tutorial/interfaces.rst +++ b/src/doc/ru/tutorial/interfaces.rst @@ -324,7 +324,7 @@ gnuplot, имеет методы решения и манипуляции мат :: sage: _ = maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0) - 10.0") - sage: _ = maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)").sage() + sage: _ = maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)") sage: _ = maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))") sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]", # not tested ....: "[y, -%pi, %pi]", "['grid, 40, 40]", From 6ee8482fe37eb4eaf01a84adf2dcbae937c347c7 Mon Sep 17 00:00:00 2001 From: Antonio Rojas <arojas@archlinux.org> Date: Wed, 7 Jun 2023 21:23:40 +0200 Subject: [PATCH 057/228] Improve some tests --- src/sage/functions/bessel.py | 10 +++++----- src/sage/functions/other.py | 6 +++--- src/sage/interfaces/maxima.py | 24 +++++++++++++++--------- src/sage/interfaces/maxima_abstract.py | 5 +++-- src/sage/modules/free_module_element.pyx | 4 ++-- src/sage/symbolic/relation.py | 4 ++-- 6 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/sage/functions/bessel.py b/src/sage/functions/bessel.py index c53935d60fe..2dacd014e6f 100644 --- a/src/sage/functions/bessel.py +++ b/src/sage/functions/bessel.py @@ -1118,11 +1118,11 @@ def Bessel(*args, **kwds): Conversion to other systems:: sage: x,y = var('x,y') - sage: f = maxima(Bessel(typ='K')(x,y)) - sage: f.derivative('_SAGE_VAR_x') - (%pi*csc(%pi*_SAGE_VAR_x) *('diff(bessel_i(-_SAGE_VAR_x,_SAGE_VAR_y),_SAGE_VAR_x,1) -'diff(bessel_i(_SAGE_VAR_x,_SAGE_VAR_y),_SAGE_VAR_x,1))) /2 -%pi*bessel_k(_SAGE_VAR_x,_SAGE_VAR_y)*cot(%pi*_SAGE_VAR_x) - sage: f.derivative('_SAGE_VAR_y').sage() - -1/2*bessel_K(x + 1, y) - 1/2*bessel_K(x - 1, y) + sage: f = Bessel(typ='K')(x,y) + sage: expected = f.derivative(y) + sage: actual = maxima(f).derivative('_SAGE_VAR_y').sage() + sage: bool(actual == expected) + True Compute the particular solution to Bessel's Differential Equation that satisfies `y(1) = 1` and `y'(1) = 1`, then verify the initial conditions diff --git a/src/sage/functions/other.py b/src/sage/functions/other.py index 39e144d9ca2..5a0f06a27f8 100644 --- a/src/sage/functions/other.py +++ b/src/sage/functions/other.py @@ -498,10 +498,10 @@ def __init__(self): <class 'sage.rings.integer.Integer'> sage: var('x') x - sage: a = floor(5.4 + x); a - floor(x + 5.40000000000000) + sage: a = floor(5.25 + x); a + floor(x + 5.25000000000000) sage: a.simplify() - floor(x + 0.400000000000000...) + 5 + floor(x + 0.25) + 5 sage: a(x=2) 7 diff --git a/src/sage/interfaces/maxima.py b/src/sage/interfaces/maxima.py index ebbd9133734..959e75459a2 100644 --- a/src/sage/interfaces/maxima.py +++ b/src/sage/interfaces/maxima.py @@ -49,9 +49,14 @@ :: + sage: x,y = SR.var('x,y') sage: F = maxima.factor('x^5 - y^5') - sage: F - -...(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)... + sage: F # not tested - depends on maxima version + -((y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)) + sage: actual = F.sage() + sage: expected = -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4) + sage: bool(actual == expected) + True sage: type(F) <class 'sage.interfaces.maxima.MaximaElement'> @@ -71,18 +76,19 @@ :: + sage: F = maxima('x * y') sage: repr(F) - '-...(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)...' + 'x*y' sage: F.str() - '-...(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)...' + 'x*y' The ``maxima.eval`` command evaluates an expression in maxima and returns the result as a *string* not a maxima object. :: - sage: print(maxima.eval('factor(x^5 - y^5)')) - -...(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)... + sage: print(maxima.eval('factor(x^5 - 1)')) + (x-1)*(x^4+x^3+x^2+x+1) We can create the polynomial `f` as a Maxima polynomial, then call the factor method on it. Notice that the notation @@ -91,11 +97,11 @@ :: - sage: f = maxima('x^5 - y^5') + sage: f = maxima('x^5 + y^5') sage: f^2 - (x^5-y^5)^2 + (y^5+x^5)^2 sage: f.factor() - -...(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)... + (y+x)*(y^4-x*y^3+x^2*y^2-x^3*y+x^4) Control-C interruption works well with the maxima interface, because of the excellent implementation of maxima. For example, try diff --git a/src/sage/interfaces/maxima_abstract.py b/src/sage/interfaces/maxima_abstract.py index a5b5f35d188..aecfcba5e23 100644 --- a/src/sage/interfaces/maxima_abstract.py +++ b/src/sage/interfaces/maxima_abstract.py @@ -1572,8 +1572,9 @@ def integral(self, var='x', min=None, max=None): :: - sage: f = maxima('exp(x^2)').integral('x',0,1); f - -...(sqrt(%pi)*%i*erf(%i))/2... + sage: f = maxima('exp(x^2)').integral('x',0,1) + sage: f.sage() + -1/2*I*sqrt(pi)*erf(I) sage: f.numer() 1.46265174590718... """ diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 94e63fdc5f8..6ea2bd4473d 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -4053,8 +4053,8 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: t=var('t') sage: r=vector([t,t^2,sin(t)]) sage: vec,answers=r.nintegral(t,0,1) - sage: vec - (0.5, 0.333333333333333..., 0.4596976941318602...) + sage: vec # abs tol 1e-15 + (0.5, 0.3333333333333334, 0.4596976941318602) sage: type(vec) <class 'sage.modules.vector_real_double_dense.Vector_real_double_dense'> sage: answers diff --git a/src/sage/symbolic/relation.py b/src/sage/symbolic/relation.py index e0a3692a8ab..51dcaf8d847 100644 --- a/src/sage/symbolic/relation.py +++ b/src/sage/symbolic/relation.py @@ -657,9 +657,9 @@ def solve(f, *args, **kwds): equations, at times approximations will be given by Maxima, due to the underlying algorithm:: - sage: sols = solve([x^3==y,y^2==x], [x,y]); sols[-1], sols[0] + sage: sols = solve([x^3==y,y^2==x], [x,y]); sols[-1], sols[0] # abs tol 1e-15 ([x == 0, y == 0], - [x == (0.309016994374947... + 0.9510565162951535*I), + [x == (0.3090169943749475 + 0.9510565162951535*I), y == (-0.8090169943749475 - 0.5877852522924731*I)]) sage: sols[0][0].rhs().pyobject().parent() Complex Double Field From 0edead8dc4f1e8b30c7885acf3e7748fe0af98ce Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Mon, 15 May 2023 17:10:33 -0700 Subject: [PATCH 058/228] sage.combinat: Add # optional - sage.plot --- src/sage/combinat/binary_tree.py | 2 +- .../combinat/cluster_algebra_quiver/quiver.py | 16 ++-- src/sage/combinat/crystals/crystals.py | 2 +- src/sage/combinat/crystals/letters.pyx | 6 +- src/sage/combinat/crystals/mv_polytopes.py | 2 +- src/sage/combinat/dyck_word.py | 2 +- src/sage/combinat/finite_state_machine.py | 2 +- .../combinat/fully_commutative_elements.py | 2 +- src/sage/combinat/fully_packed_loop.py | 13 +-- src/sage/combinat/interval_posets.py | 4 +- src/sage/combinat/k_regular_sequence.py | 8 +- src/sage/combinat/nu_dyck_word.py | 2 +- src/sage/combinat/ordered_tree.py | 4 +- src/sage/combinat/permutation.py | 4 +- src/sage/combinat/plane_partition.py | 4 +- src/sage/combinat/posets/posets.py | 44 +++++----- .../rigged_configurations/kleber_tree.py | 2 +- .../non_symmetric_macdonald_polynomials.py | 8 +- src/sage/combinat/root_system/plot.py | 2 +- .../root_system/reflection_group_complex.py | 6 +- .../root_system/root_lattice_realizations.py | 4 +- src/sage/combinat/root_system/weyl_group.py | 4 +- src/sage/combinat/six_vertex_model.py | 2 +- .../symmetric_group_representations.py | 58 +++++++------- src/sage/combinat/tableau.py | 8 +- src/sage/combinat/words/finite_word.py | 24 +++--- src/sage/combinat/words/morphism.py | 80 +++++++++++-------- src/sage/combinat/words/paths.py | 78 +++++++++--------- src/sage/combinat/words/suffix_trees.py | 18 ++--- src/sage/combinat/words/word_generators.py | 14 ++-- src/sage/combinat/yang_baxter_graph.py | 12 +-- 31 files changed, 229 insertions(+), 208 deletions(-) diff --git a/src/sage/combinat/binary_tree.py b/src/sage/combinat/binary_tree.py index da0585e29ff..26923650782 100644 --- a/src/sage/combinat/binary_tree.py +++ b/src/sage/combinat/binary_tree.py @@ -867,7 +867,7 @@ def show(self, with_leaves=False): TESTS:: sage: t1 = BinaryTree([[], [[], None]]) - sage: t1.show() + sage: t1.show() # optional - sage.plot """ try: self.graph(with_leaves=with_leaves).show(layout='tree', tree_root=0, tree_orientation="down") diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver.py b/src/sage/combinat/cluster_algebra_quiver/quiver.py index ba1168749b7..c02b38073ef 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver.py @@ -742,7 +742,7 @@ def qmu_save(self, filename=None): sage: Q = ClusterQuiver(['F',4,[1,2]]) sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".qmu") as f: + sage: with tempfile.NamedTemporaryFile(suffix=".qmu") as f: # optional - sage.plot sage.symbolic ....: Q.qmu_save(f.name) Make sure we can save quivers with `m != n` frozen variables, see :trac:`14851`:: @@ -751,7 +751,7 @@ def qmu_save(self, filename=None): sage: T1 = S.principal_extension() sage: Q = T1.quiver() sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".qmu") as f: + sage: with tempfile.NamedTemporaryFile(suffix=".qmu") as f: # optional - sage.plot sage.symbolic ....: Q.qmu_save(f.name) """ M = self.b_matrix() @@ -1475,14 +1475,16 @@ def mutation_sequence(self, sequence, show_sequence=False, fig_size=1.2 ): INPUT: - ``sequence`` -- a list or tuple of vertices of ``self``. - - ``show_sequence`` -- (default: False) if True, a png containing the mutation sequence is shown. + - ``show_sequence`` -- (default: ``False``) if ``True``, a png containing the mutation sequence is shown. - ``fig_size`` -- (default: 1.2) factor by which the size of the sequence is expanded. EXAMPLES:: sage: Q = ClusterQuiver(['A',4]) sage: seq = Q.mutation_sequence([0,1]); seq - [Quiver on 4 vertices of type ['A', 4], Quiver on 4 vertices of type ['A', 4], Quiver on 4 vertices of type ['A', 4]] + [Quiver on 4 vertices of type ['A', 4], + Quiver on 4 vertices of type ['A', 4], + Quiver on 4 vertices of type ['A', 4]] sage: [T.b_matrix() for T in seq] [ [ 0 1 0 0] [ 0 -1 0 0] [ 0 1 -1 0] @@ -1491,8 +1493,6 @@ def mutation_sequence(self, sequence, show_sequence=False, fig_size=1.2 ): [ 0 0 -1 0], [ 0 0 -1 0], [ 0 0 -1 0] ] """ - from sage.plot.plot import Graphics - from sage.plot.text import text n = self._n m = self._m if m == 0: @@ -1520,9 +1520,13 @@ def mutation_sequence(self, sequence, show_sequence=False, fig_size=1.2 ): quiver_sequence.append( copy( quiver ) ) if show_sequence: + from sage.plot.plot import Graphics + from sage.plot.text import text + def _plot_arrow( v, k, center=(0,0) ): return text(r"$\longleftrightarrow$",(center[0],center[1]), fontsize=25) + text(r"$\mu_"+str(v)+"$",(center[0],center[1]+0.15), fontsize=15) \ + text("$"+str(k)+"$",(center[0],center[1]-0.2), fontsize=15) + plot_sequence = [ quiver_sequence[i].plot( circular=True, center=(i*width_factor,0) ) for i in range(len(quiver_sequence)) ] arrow_sequence = [ _plot_arrow( sequence[i],i+1,center=((i+0.5)*width_factor,0) ) for i in range(len(sequence)) ] sequence = [] diff --git a/src/sage/combinat/crystals/crystals.py b/src/sage/combinat/crystals/crystals.py index 8b965b79c09..dbc2e9a211f 100644 --- a/src/sage/combinat/crystals/crystals.py +++ b/src/sage/combinat/crystals/crystals.py @@ -103,7 +103,7 @@ One can get (currently) crude plotting via:: - sage: Tab.plot() + sage: Tab.plot() # optional - sage.plot Graphics object consisting of 52 graphics primitives If dot2tex is installed, one can obtain nice latex pictures via:: diff --git a/src/sage/combinat/crystals/letters.pyx b/src/sage/combinat/crystals/letters.pyx index 29ca6086c57..36edb9c8f86 100644 --- a/src/sage/combinat/crystals/letters.pyx +++ b/src/sage/combinat/crystals/letters.pyx @@ -1494,7 +1494,7 @@ cdef class Crystal_of_letters_type_E6_element(LetterTuple): sage: all(b.e(i).f(i) == b for i in C.index_set() for b in C if b.e(i) is not None) True sage: G = C.digraph() - sage: G.show(edge_labels=true, figsize=12, vertex_size=1) + sage: G.show(edge_labels=true, figsize=12, vertex_size=1) # optional - sage.plot """ def _repr_(self): @@ -1751,7 +1751,7 @@ cdef class Crystal_of_letters_type_E6_element_dual(LetterTuple): sage: all(b.e(i).f(i) == b for i in C.index_set() for b in C if b.e(i) is not None) True sage: G = C.digraph() - sage: G.show(edge_labels=true, figsize=12, vertex_size=1) + sage: G.show(edge_labels=true, figsize=12, vertex_size=1) # optional - sage.plot """ def _repr_(self): @@ -1911,7 +1911,7 @@ cdef class Crystal_of_letters_type_E7_element(LetterTuple): sage: all(b.e(i).f(i) == b for i in C.index_set() for b in C if b.e(i) is not None) True sage: G = C.digraph() - sage: G.show(edge_labels=true, figsize=12, vertex_size=1) + sage: G.show(edge_labels=true, figsize=12, vertex_size=1) # optional - sage.plot """ def weight(self): diff --git a/src/sage/combinat/crystals/mv_polytopes.py b/src/sage/combinat/crystals/mv_polytopes.py index bcb2654da60..cd6a4497d8e 100644 --- a/src/sage/combinat/crystals/mv_polytopes.py +++ b/src/sage/combinat/crystals/mv_polytopes.py @@ -218,7 +218,7 @@ def plot(self, P=None, **options): sage: MV = crystals.infinity.MVPolytopes(['C', 2]) sage: b = MV.highest_weight_vector().f_string([1,2,1,2,2,2,1,1,1,1,2,1]) - sage: b.plot() + sage: b.plot() # optional - sage.plot Graphics object consisting of 12 graphics primitives Here is the above example placed inside the ambient space diff --git a/src/sage/combinat/dyck_word.py b/src/sage/combinat/dyck_word.py index e4d2138e699..a6620735321 100644 --- a/src/sage/combinat/dyck_word.py +++ b/src/sage/combinat/dyck_word.py @@ -957,7 +957,7 @@ def plot(self, **kwds): EXAMPLES:: sage: w = DyckWords(100).random_element() - sage: w.plot() + sage: w.plot() # optional - sage.plot Graphics object consisting of 1 graphics primitive """ from sage.plot.plot import list_plot diff --git a/src/sage/combinat/finite_state_machine.py b/src/sage/combinat/finite_state_machine.py index 04106d2b7a3..decef1d4479 100644 --- a/src/sage/combinat/finite_state_machine.py +++ b/src/sage/combinat/finite_state_machine.py @@ -9708,7 +9708,7 @@ def plot(self): TESTS:: - sage: FiniteStateMachine([('A', 'A', 0)]).plot() + sage: FiniteStateMachine([('A', 'A', 0)]).plot() # optional - sage.plot Graphics object consisting of 3 graphics primitives """ return self.graph(edge_labels='words_in_out').plot() diff --git a/src/sage/combinat/fully_commutative_elements.py b/src/sage/combinat/fully_commutative_elements.py index bb46692a8b7..5b338912e6c 100644 --- a/src/sage/combinat/fully_commutative_elements.py +++ b/src/sage/combinat/fully_commutative_elements.py @@ -268,7 +268,7 @@ def plot_heap(self): EXAMPLES:: sage: FC = CoxeterGroup(['B', 5]).fully_commutative_elements() - sage: FC([3,2,4,3,1]).plot_heap() + sage: FC([3,2,4,3,1]).plot_heap() # optional - sage.plot Graphics object consisting of 15 graphics primitives .. PLOT:: diff --git a/src/sage/combinat/fully_packed_loop.py b/src/sage/combinat/fully_packed_loop.py index 070275077cd..a16c2c369e3 100644 --- a/src/sage/combinat/fully_packed_loop.py +++ b/src/sage/combinat/fully_packed_loop.py @@ -157,7 +157,7 @@ class FullyPackedLoop(Element, metaclass=InheritComparisonClasscallMetaclass): The class also has a plot method:: - sage: fpl.plot() + sage: fpl.plot() # optional - sage.plot Graphics object consisting of 3 graphics primitives which gives: @@ -781,7 +781,7 @@ def plot(self, **options): sage: A = AlternatingSignMatrix([[0, 1, 0], [1, -1, 1], [0, 1, 0]]) sage: fpl = FullyPackedLoop(A) - sage: fpl.plot() + sage: fpl.plot() # optional - sage.plot Graphics object consisting of 3 graphics primitives The resulting graphics is as follows @@ -798,7 +798,7 @@ def plot(self, **options): sage: A = AlternatingSignMatrix([[0, 1, 0], [1, -1, 1], [0, 1, 0]]) sage: fpl = FullyPackedLoop(A) - sage: fpl.plot(link_color_map='rainbow') + sage: fpl.plot(link_color_map='rainbow') # optional - sage.plot Graphics object consisting of 3 graphics primitives .. PLOT:: @@ -811,8 +811,9 @@ def plot(self, **options): You can plot the 42 fully packed loops of size `4 \times 4` using:: - sage: G = [fpl.plot(link_color_map='winter', loop_color='black') for fpl in FullyPackedLoops(4)] - sage: graphics_array(G, 7, 6) + sage: G = [fpl.plot(link_color_map='winter', loop_color='black') # optional - sage.plot + ....: for fpl in FullyPackedLoops(4)] + sage: graphics_array(G, 7, 6) # optional - sage.plot Graphics Array of size 7 x 6 .. PLOT:: @@ -833,7 +834,7 @@ def plot(self, **options): ....: 00000000+-0000+00000000000000+0000000000" sage: a = matrix(20, [{'0':0, '+':1, '-': -1}[i] for i in s]) sage: fpl = FullyPackedLoop(a) - sage: fpl.plot(loop_fill=True, loop_color_map='rainbow') + sage: fpl.plot(loop_fill=True, loop_color_map='rainbow') # optional - sage.plot Graphics object consisting of 27 graphics primitives .. PLOT:: diff --git a/src/sage/combinat/interval_posets.py b/src/sage/combinat/interval_posets.py index a2d4f6e607c..346cd954e21 100644 --- a/src/sage/combinat/interval_posets.py +++ b/src/sage/combinat/interval_posets.py @@ -437,13 +437,13 @@ def plot(self, **kwds): EXAMPLES:: sage: ti = TamariIntervalPosets(4)[2] - sage: ti.plot() + sage: ti.plot() # optional - sage.plot Graphics object consisting of 6 graphics primitives TESTS:: sage: ti = TamariIntervalPoset(3, [[2,1], [2,3]]) - sage: ti.plot() + sage: ti.plot() # optional - sage.plot Graphics object consisting of 6 graphics primitives """ c0 = 'blue' # self.latex_options()["color_increasing"] diff --git a/src/sage/combinat/k_regular_sequence.py b/src/sage/combinat/k_regular_sequence.py index 5b5f2398cc0..74329d1f794 100644 --- a/src/sage/combinat/k_regular_sequence.py +++ b/src/sage/combinat/k_regular_sequence.py @@ -1228,20 +1228,20 @@ def from_recurrence(self, *args, **kwds): of non-zero elements in the generalized Pascal's triangle (see [LRS2017]_):: - sage: U = Seq2.from_recurrence(M=1, m=0, + sage: U = Seq2.from_recurrence(M=1, m=0, # optional - sage.symbolic ....: coeffs={(0, 0): 1}, ....: initial_values={0: 0, 1: 1}, ....: inhomogeneities={1: P}) - sage: (U - Seq2(SB)).is_trivial_zero() + sage: (U - Seq2(SB)).is_trivial_zero() # optional - sage.symbolic True :: - sage: U = Seq2.from_recurrence(M=1, m=0, + sage: U = Seq2.from_recurrence(M=1, m=0, # optional - sage.symbolic ....: coeffs={}, ....: initial_values={0: 0, 1: 1}, ....: inhomogeneities={0: SB, 1: P}) - sage: (U - Seq2(SB)).is_trivial_zero() + sage: (U - Seq2(SB)).is_trivial_zero() # optional - sage.symbolic True Number of Unbordered Factors in the Thue--Morse Sequence, but partly diff --git a/src/sage/combinat/nu_dyck_word.py b/src/sage/combinat/nu_dyck_word.py index b319f1326fe..efb0af7f572 100644 --- a/src/sage/combinat/nu_dyck_word.py +++ b/src/sage/combinat/nu_dyck_word.py @@ -873,7 +873,7 @@ def plot(self, **kwds): EXAMPLES:: sage: NDW = NuDyckWord('010','010') - sage: NDW.plot() + sage: NDW.plot() # optional - sage.plot Graphics object consisting of 1 graphics primitive """ from sage.plot.plot import list_plot diff --git a/src/sage/combinat/ordered_tree.py b/src/sage/combinat/ordered_tree.py index e874f5ccdf6..6a8f1206ff7 100644 --- a/src/sage/combinat/ordered_tree.py +++ b/src/sage/combinat/ordered_tree.py @@ -674,7 +674,7 @@ def plot(self): o o o | o - sage: p.plot() + sage: p.plot() # optional - sage.plot Graphics object consisting of 10 graphics primitives .. PLOT:: @@ -691,7 +691,7 @@ def plot(self): 2 3 5 | 4 - sage: g.plot() + sage: g.plot() # optional - sage.plot Graphics object consisting of 10 graphics primitives .. PLOT:: diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index 56944d57dae..b9c0be15ee6 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -1722,8 +1722,8 @@ def show(self, representation="cycles", orientation="landscape", **args): EXAMPLES:: sage: P20 = Permutations(20) - sage: P20.random_element().show(representation="cycles") # optional - sage.graphs - sage: P20.random_element().show(representation="chord-diagram") # optional - sage.graphs + sage: P20.random_element().show(representation="cycles") # optional - sage.graphs sage.plot + sage: P20.random_element().show(representation="chord-diagram") # optional - sage.graphs sage.plot sage: P20.random_element().show(representation="braid") # optional - sage.plot sage: P20.random_element().show(representation="braid", # optional - sage.plot ....: orientation='portrait') diff --git a/src/sage/combinat/plane_partition.py b/src/sage/combinat/plane_partition.py index 31ef06d95fa..e7cb63842b9 100644 --- a/src/sage/combinat/plane_partition.py +++ b/src/sage/combinat/plane_partition.py @@ -667,7 +667,7 @@ def plot(self, show_box=False, colors=None): EXAMPLES:: sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) - sage: PP.plot() + sage: PP.plot() # optional - sage.plot Graphics object consisting of 27 graphics primitives """ from sage.functions.trig import cos, sin @@ -764,7 +764,7 @@ def plot3d(self, colors=None): EXAMPLES:: sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) - sage: PP.plot3d() + sage: PP.plot3d() # optional - sage.plot Graphics3d Object """ if colors is None: diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 2217b59a7bc..0812da9a83c 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -1932,24 +1932,24 @@ def plot(self, label_elements=True, element_labels=None, This function can be used without any parameters:: sage: D12 = posets.DivisorLattice(12) - sage: D12.plot() + sage: D12.plot() # optional - sage.plot Graphics object consisting of 14 graphics primitives Just the abstract form of the poset; examples of relabeling:: - sage: D12.plot(label_elements=False) + sage: D12.plot(label_elements=False) # optional - sage.plot Graphics object consisting of 8 graphics primitives sage: d = {1: 0, 2: 'a', 3: 'b', 4: 'c', 6: 'd', 12: 1} - sage: D12.plot(element_labels=d) + sage: D12.plot(element_labels=d) # optional - sage.plot Graphics object consisting of 14 graphics primitives - sage: d = {i:str(factor(i)) for i in D12} - sage: D12.plot(element_labels=d) + sage: d = {i: str(factor(i)) for i in D12} + sage: D12.plot(element_labels=d) # optional - sage.plot Graphics object consisting of 14 graphics primitives Some settings for coverings:: sage: d = {(a, b): b/a for a, b in D12.cover_relations()} - sage: D12.plot(cover_labels=d, cover_color='gray', cover_style='dotted') + sage: D12.plot(cover_labels=d, cover_color='gray', cover_style='dotted') # optional - sage.plot Graphics object consisting of 21 graphics primitives To emphasize some elements and show some options:: @@ -1960,7 +1960,7 @@ def plot(self, label_elements=True, element_labels=None, ....: 10: [12], 11: [12], 12: [13]}) sage: F = L.frattini_sublattice() sage: F_internal = [c for c in F.cover_relations() if c in L.cover_relations()] - sage: L.plot(figsize=12, border=True, element_shape='s', + sage: L.plot(figsize=12, border=True, element_shape='s', # optional - sage.plot ....: element_size=400, element_color='white', ....: element_colors={'blue': F, 'green': L.double_irreducibles()}, ....: cover_color='lightgray', cover_colors={'black': F_internal}, @@ -1971,7 +1971,9 @@ def plot(self, label_elements=True, element_labels=None, We check that ``label_elements`` and ``element_labels`` are honored:: - sage: def get_plot_labels(P): return sorted(t.string for t in P if isinstance(t, sage.plot.text.Text)) + sage: def get_plot_labels(P): + ....: return sorted(t.string for t in P + ....: if isinstance(t, sage.plot.text.Text)) sage: P1 = Poset({ 0:[1,2], 1:[3], 2:[3,4] }) sage: P2 = Poset({ 0:[1,2], 1:[3], 2:[3,4] }, facade=True) sage: get_plot_labels(P1.plot(label_elements=False)) @@ -1991,25 +1993,23 @@ def plot(self, label_elements=True, element_labels=None, sage: P.plot(heights=heights) Graphics object consisting of 8 graphics primitives sage: elem_labels = {0 : 'a', 1 : 'b', 2 : 'c', 3 : 'd'} - sage: P.plot(element_labels=elem_labels, heights=heights) + sage: P.plot(element_labels=elem_labels, heights=heights) # optional - sage.plot Graphics object consisting of 8 graphics primitives The following checks that equal labels are allowed (:trac:`15206`):: sage: P = Poset({1: [2,3]}) - sage: labs = {i: P.rank(i) for i in range(1, 4)} - sage: labs + sage: labs = {i: P.rank(i) for i in range(1, 4)}; labs {1: 0, 2: 1, 3: 1} - sage: P.plot(element_labels=labs) + sage: P.plot(element_labels=labs) # optional - sage.plot Graphics object consisting of 6 graphics primitives The following checks that non-hashable labels are allowed (:trac:`15206`):: sage: P = Poset({1: [2,3]}) - sage: labs = {1: [2, 3], 2: [], 3: []} - sage: labs + sage: labs = {1: [2, 3], 2: [], 3: []}; labs {1: [2, 3], 2: [], 3: []} - sage: P.plot(element_labels=labs) + sage: P.plot(element_labels=labs) # optional - sage.plot Graphics object consisting of 6 graphics primitives Plot of the empty poset:: @@ -2102,16 +2102,16 @@ def show(self, label_elements=True, element_labels=None, EXAMPLES:: sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] }) - sage: D.plot(label_elements=False) + sage: D.plot(label_elements=False) # optional - sage.plot Graphics object consisting of 6 graphics primitives - sage: D.show() + sage: D.show() # optional - sage.plot sage: elm_labs = {0:'a', 1:'b', 2:'c', 3:'d', 4:'e'} - sage: D.show(element_labels=elm_labs) + sage: D.show(element_labels=elm_labs) # optional - sage.plot One more example with cover labels:: sage: P = posets.PentagonPoset() - sage: P.show(cover_labels=lambda a, b: a - b) + sage: P.show(cover_labels=lambda a, b: a - b) # optional - sage.plot """ # We split the arguments into those meant for plot() and those meant for show() @@ -6704,16 +6704,16 @@ def order_ideal_plot(self, elements): EXAMPLES:: sage: P = Poset((divisors(1000), attrcall("divides"))) - sage: P.order_ideal_plot([20, 25]) + sage: P.order_ideal_plot([20, 25]) # optional - sage.plot Graphics object consisting of 41 graphics primitives TESTS:: sage: P = Poset() # Test empty poset - sage: P.order_ideal_plot([]) + sage: P.order_ideal_plot([]) # optional - sage.plot Graphics object consisting of 0 graphics primitives sage: C = posets.ChainPoset(5) - sage: C.order_ideal_plot([]) + sage: C.order_ideal_plot([]) # optional - sage.plot Graphics object consisting of 10 graphics primitives """ order_ideal = self.order_ideal(elements) diff --git a/src/sage/combinat/rigged_configurations/kleber_tree.py b/src/sage/combinat/rigged_configurations/kleber_tree.py index 82c99e8ad73..22768d9caad 100644 --- a/src/sage/combinat/rigged_configurations/kleber_tree.py +++ b/src/sage/combinat/rigged_configurations/kleber_tree.py @@ -1045,7 +1045,7 @@ def plot(self, **options): sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['D', 4, 1], [[2, 2]]) - sage: print(KT.plot()) + sage: print(KT.plot()) # optional - sage.plot Graphics object consisting of 8 graphics primitives """ return self.digraph().plot(edge_labels=True, vertex_size=0, **options) diff --git a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py index 37fd54ce2f3..a7cad09cdb5 100644 --- a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +++ b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py @@ -1078,8 +1078,8 @@ class NonSymmetricMacdonaldPolynomials(CherednikOperatorsEigenvectors): (x1, x2, x3) sage: E = NonSymmetricMacdonaldPolynomials(["BC",2,2], q=q, q1=t^2,q2=-1) - sage: omega=E.keys().fundamental_weights() - sage: expected = (t-1)*(t+1)*(2+q^4+2*q^2-2*t^2-2*q^2*t^2-t^4*q^2-q^4*t^4+t^4-3*q^6*t^6-2*q^4*t^6+2*q^6*t^8+2*q^4*t^8+t^10*q^8)*q^4/((q^2*t^3-1)*(q^2*t^3+1)*(t*q-1)*(t*q+1)*(t^2*q^3+1)*(t^2*q^3-1))+(t-1)^2*(t+1)^2*(2*q^2+q^4+2+q^4*t^2)*q^3*x1/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1))+(t-1)^2*(t+1)^2*(q^2+1)*q^5/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1)*x1)+(t-1)^2*(t+1)^2*(q^2+1)*q^4*x2/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1)*x1)+(t-1)^2*(t+1)^2*(2*q^2+q^4+2+q^4*t^2)*q^3*x2/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1))+(t-1)^2*(t+1)^2*(q^2+1)*q^5/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1)*x2)+x1^2*x2^2+(t-1)*(t+1)*(-2*q^2-q^4-2+2*q^2*t^2+t^2+q^6*t^4+q^4*t^4)*q^2*x2*x1/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1))+(t-1)*(t+1)*(q^2+1+q^4*t^2)*q*x2^2*x1/((t^2*q^3-1)*(t^2*q^3+1))+(t-1)*(t+1)*q^3*x1^2/((t^2*q^3-1)*(t^2*q^3+1)*x2)+(t-1)*(t+1)*(q^2+1+q^4*t^2)*q*x2*x1^2/((t^2*q^3-1)*(t^2*q^3+1))+(t-1)*(t+1)*q^6/((t^2*q^3+1)*(t^2*q^3-1)*x1*x2)+(t-1)*(t+1)*(q^2+1+q^4*t^2)*q^2*x1^2/((t^2*q^3-1)*(t^2*q^3+1))+(t-1)*(t+1)*(q^2+1+q^4*t^2)*q^2*x2^2/((t^2*q^3-1)*(t^2*q^3+1))+(t-1)*(t+1)*q^3*x2^2/((t^2*q^3-1)*(t^2*q^3+1)*x1)+(t-1)^2*(t+1)^2*(q^2+1)*q^4*x1/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1)*x2) + sage: omega = E.keys().fundamental_weights() + sage: expected = (t-1)*(t+1)*(2+q^4+2*q^2-2*t^2-2*q^2*t^2-t^4*q^2-q^4*t^4+t^4-3*q^6*t^6-2*q^4*t^6+2*q^6*t^8+2*q^4*t^8+t^10*q^8)*q^4/((q^2*t^3-1)*(q^2*t^3+1)*(t*q-1)*(t*q+1)*(t^2*q^3+1)*(t^2*q^3-1))+(t-1)^2*(t+1)^2*(2*q^2+q^4+2+q^4*t^2)*q^3*x1/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1))+(t-1)^2*(t+1)^2*(q^2+1)*q^5/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1)*x1)+(t-1)^2*(t+1)^2*(q^2+1)*q^4*x2/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1)*x1)+(t-1)^2*(t+1)^2*(2*q^2+q^4+2+q^4*t^2)*q^3*x2/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1))+(t-1)^2*(t+1)^2*(q^2+1)*q^5/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1)*x2)+x1^2*x2^2+(t-1)*(t+1)*(-2*q^2-q^4-2+2*q^2*t^2+t^2+q^6*t^4+q^4*t^4)*q^2*x2*x1/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1))+(t-1)*(t+1)*(q^2+1+q^4*t^2)*q*x2^2*x1/((t^2*q^3-1)*(t^2*q^3+1))+(t-1)*(t+1)*q^3*x1^2/((t^2*q^3-1)*(t^2*q^3+1)*x2)+(t-1)*(t+1)*(q^2+1+q^4*t^2)*q*x2*x1^2/((t^2*q^3-1)*(t^2*q^3+1))+(t-1)*(t+1)*q^6/((t^2*q^3+1)*(t^2*q^3-1)*x1*x2)+(t-1)*(t+1)*(q^2+1+q^4*t^2)*q^2*x1^2/((t^2*q^3-1)*(t^2*q^3+1))+(t-1)*(t+1)*(q^2+1+q^4*t^2)*q^2*x2^2/((t^2*q^3-1)*(t^2*q^3+1))+(t-1)*(t+1)*q^3*x2^2/((t^2*q^3-1)*(t^2*q^3+1)*x1)+(t-1)^2*(t+1)^2*(q^2+1)*q^4*x1/((t^2*q^3+1)*(t^2*q^3-1)*(t*q-1)*(t*q+1)*x2) # optional - sage.symbolic sage: to_SR(E[2*omega[2]]) - expected # long time (3.5s) # optional - sage.symbolic 0 @@ -1087,7 +1087,7 @@ class NonSymmetricMacdonaldPolynomials(CherednikOperatorsEigenvectors): sage: omega=E.keys().fundamental_weights() sage: mu = -3*omega[1] + 3*omega[2] - omega[3]; mu (-1, 2, -1) - sage: expected = (t-1)^2*(t+1)^2*(3*q^2+q^4+1+t^2*q^4+q^2*t^2-3*t^4*q^2-5*t^6*q^4+2*t^8*q^4-4*t^8*q^6-q^8*t^10+2*t^10*q^6-2*q^8*t^12+t^14*q^8-t^14*q^10+q^10*t^16+q^8*t^16+q^10*t^18+t^18*q^12)*x2*x1/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(q^2*t^6+2*t^6*q^4-q^4*t^4+t^4*q^2-q^2*t^2+t^2-2-q^2)*q^2*x1/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)^2*(t+1)^2*(-q^2-1+t^4*q^2-q^4*t^4+2*t^6*q^4)*x1^2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t+1)*(t-1)*x2^2*x3/((t*q-1)*(t*q+1)*x1)+(t-1)^2*(t+1)^2*(3*q^2+q^4+2+t^2*q^4+2*q^2*t^2-4*t^4*q^2+q^4*t^4-6*t^6*q^4+t^8*q^4-4*t^8*q^6-q^8*t^10+t^10*q^6-3*q^8*t^12-2*t^14*q^10+2*t^14*q^8+2*q^10*t^16+q^8*t^16+t^18*q^12+2*q^10*t^18)*q*x2/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(1+q^4+2*q^2+t^2*q^4-3*t^4*q^2+q^2*t^6-5*t^6*q^4+3*t^8*q^4-4*t^8*q^6+2*t^10*q^6-q^8*t^12-t^14*q^10+t^14*q^8+q^10*t^16+t^18*q^12)*x3*x1/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(2*q^2+1+q^4+t^2*q^4-t^2+q^2*t^2-4*t^4*q^2+q^4*t^4+q^2*t^6-5*t^6*q^4+3*t^8*q^4-4*t^8*q^6+2*t^10*q^6+q^6*t^12-2*q^8*t^12-2*t^14*q^10+2*t^14*q^8+q^10*t^16+t^18*q^12)*q*x3/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(1+t^2+t^4*q^2)*q*x3*x2^2/((t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1))+(t-1)^2*(t+1)^2*(-q^2-2-q^2*t^2+t^4-q^4*t^4-t^4*q^2+3*q^2*t^6-t^6*q^4-t^8*q^6+t^8*q^4+t^10*q^4+2*q^6*t^12-q^8*t^12+t^14*q^8)*q*x3*x2*x1/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t-1)*(t+1)*x1^2/((q^3*t^5-1)*(q^3*t^5+1)*x3*x2)+(t-1)*(t+1)*(-q^2-1+t^4*q^2-q^4*t^4+2*t^6*q^4)*x2^2/((t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1))+(t-1)*(t+1)*(t^3*q-1)*(t^3*q+1)*x3*x2^2*x1/((t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1))+(t-1)^2*(t+1)^2*(q^2+1)*q*x1/((t*q+1)*(t*q-1)*(q^3*t^5+1)*(q^3*t^5-1)*x3*x2)+(t-1)^2*(t+1)^2*(t^3*q-1)*(t^3*q+1)*x3*x2*x1^2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t-1)^2*(t+1)^2*q^3*x3/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x1*x2)+(t-1)*(t+1)*(-1-q^2+q^2*t^2+t^10*q^6)*q*x2/((t*q+1)*(t*q-1)*(q^3*t^5+1)*(q^3*t^5-1)*x3*x1)+x2^2/(x1*x3)+(t-1)*(t+1)*q*x2^2/((t*q-1)*(t*q+1)*x3)+(t-1)^3*(t+1)^3*(1+t^2+t^4*q^2)*q*x2*x1^2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t-1)^2*(t+1)^2*q*x1^2/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t-1)^2*(t+1)^2*(q^2*t^6+2*t^6*q^4-q^4*t^4+t^4*q^2-q^2*t^2+t^2-2-q^2)*q^3/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)*(t+1)*(q^2+2-t^2+q^4*t^4-t^4*q^2-3*t^6*q^4+t^8*q^4-2*t^10*q^6-q^8*t^12+q^6*t^12+q^8*t^16+q^10*t^16)*q^2*x2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x1)+(t-1)^2*(t+1)^2*(q^2+1)*q^2/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3*x2)+(t-1)*(t+1)*(1+q^4+2*q^2-2*q^2*t^2+t^4*q^6-q^4*t^4-3*q^6*t^6-t^6*q^4+2*t^8*q^6-t^10*q^6-q^8*t^10-t^14*q^10+t^14*q^8+2*q^10*t^16)*x2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t-1)^2*(t+1)^2*(-q^2-2-q^2*t^2-q^4*t^4+2*t^6*q^4+t^10*q^6+q^8*t^12+t^14*q^8)*q^3/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x1)+(t-1)^2*(t+1)^2*(-1-q^2-q^2*t^2+t^2+t^4*q^2-q^4*t^4+2*t^6*q^4)*q^2*x3/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)*(t+1)*q*x2^2/((t*q-1)*(t*q+1)*x1)+(t-1)^2*(t+1)^2*(1+t^2+t^4*q^2)*q*x2^2*x1/((t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1))+(t-1)^2*(t+1)^2*q*x1^2/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)^2*(t+1)^2*(-1-q^4-2*q^2-t^2*q^4-q^2*t^2+t^4*q^2-t^4*q^6-2*q^4*t^4+3*t^6*q^4-q^6*t^6-t^8*q^8+t^8*q^6+2*t^10*q^6-q^10*t^12+3*q^8*t^12+2*t^14*q^10)*x3*x2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t-1)*(t+1)*(q^2+1-t^2+q^4*t^4-t^4*q^2+q^2*t^6-3*t^6*q^4+t^8*q^4-t^10*q^6+q^6*t^12-q^8*t^12+q^10*t^16)*q^2*x3/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x1)+(t-1)*(t+1)*(-1-q^2+q^2*t^2+t^10*q^6)*q^2/((t*q-1)*(t*q+1)*(q^3*t^5+1)*(q^3*t^5-1)*x1*x3)+(t-1)*(t+1)*(1+q^4+2*q^2-3*q^2*t^2+t^4*q^6-q^4*t^4-3*q^6*t^6-t^6*q^4+t^8*q^4+2*t^8*q^6-t^10*q^6+t^14*q^8-t^14*q^10+q^10*t^16)*x1/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t-1)^2*(t+1)^2*(3*q^2+q^4+2+q^2*t^2-t^2+t^2*q^4-6*t^4*q^2+q^4*t^4-7*t^6*q^4+q^2*t^6+3*t^8*q^4-4*t^8*q^6+t^10*q^4+3*t^10*q^6-q^8*t^12-t^14*q^10+t^14*q^8+q^8*t^16+q^10*t^18)*q*x1/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(-q^2-2-q^2*t^2-q^4*t^4+2*t^6*q^4+t^10*q^6+q^6*t^12+t^14*q^8)*q*x2*x1/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t+1)*(t-1)*x2^2*x1/((t*q-1)*(t*q+1)*x3)+(t-1)^3*(t+1)^3*(1+t^2+t^4*q^2)*q*x3*x1^2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t-1)*(t+1)*q^3/((q^3*t^5+1)*(q^3*t^5-1)*x1*x2*x3)+(t-1)^2*(t+1)^2*(3+3*q^2+q^4+2*q^2*t^2-t^2+t^2*q^4-6*t^4*q^2+q^4*t^4-8*t^6*q^4+q^2*t^6+2*t^8*q^4-4*t^8*q^6+t^10*q^4+2*t^10*q^6-2*q^8*t^12-t^14*q^10+t^14*q^8+q^8*t^16+q^10*t^16+2*q^10*t^18)*q^2/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(-q^4-2*q^2-1-t^2*q^4-t^4*q^6+2*q^6*t^6+t^6*q^4+t^10*q^6+q^8*t^12+t^14*q^10)*q/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t-1)^2*(t+1)^2*(-1-q^2-q^2*t^2+t^2+t^4*q^2-q^4*t^4+2*t^6*q^4)*q*x3*x1/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)^2*(t+1)^2*x2*x1^2/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t-1)^2*(t+1)^2*x3*x1^2/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)^2*(t+1)^2*q^4/((t*q+1)*(t*q-1)*(q^3*t^5+1)*(q^3*t^5-1)*x1*x2)+(t-1)^2*(t+1)^2*(-q^2-1-q^2*t^2-q^4*t^4+t^6*q^4+t^10*q^6+q^8*t^12+t^14*q^10)*q*x3*x2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x1) + sage: expected = (t-1)^2*(t+1)^2*(3*q^2+q^4+1+t^2*q^4+q^2*t^2-3*t^4*q^2-5*t^6*q^4+2*t^8*q^4-4*t^8*q^6-q^8*t^10+2*t^10*q^6-2*q^8*t^12+t^14*q^8-t^14*q^10+q^10*t^16+q^8*t^16+q^10*t^18+t^18*q^12)*x2*x1/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(q^2*t^6+2*t^6*q^4-q^4*t^4+t^4*q^2-q^2*t^2+t^2-2-q^2)*q^2*x1/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)^2*(t+1)^2*(-q^2-1+t^4*q^2-q^4*t^4+2*t^6*q^4)*x1^2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t+1)*(t-1)*x2^2*x3/((t*q-1)*(t*q+1)*x1)+(t-1)^2*(t+1)^2*(3*q^2+q^4+2+t^2*q^4+2*q^2*t^2-4*t^4*q^2+q^4*t^4-6*t^6*q^4+t^8*q^4-4*t^8*q^6-q^8*t^10+t^10*q^6-3*q^8*t^12-2*t^14*q^10+2*t^14*q^8+2*q^10*t^16+q^8*t^16+t^18*q^12+2*q^10*t^18)*q*x2/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(1+q^4+2*q^2+t^2*q^4-3*t^4*q^2+q^2*t^6-5*t^6*q^4+3*t^8*q^4-4*t^8*q^6+2*t^10*q^6-q^8*t^12-t^14*q^10+t^14*q^8+q^10*t^16+t^18*q^12)*x3*x1/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(2*q^2+1+q^4+t^2*q^4-t^2+q^2*t^2-4*t^4*q^2+q^4*t^4+q^2*t^6-5*t^6*q^4+3*t^8*q^4-4*t^8*q^6+2*t^10*q^6+q^6*t^12-2*q^8*t^12-2*t^14*q^10+2*t^14*q^8+q^10*t^16+t^18*q^12)*q*x3/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(1+t^2+t^4*q^2)*q*x3*x2^2/((t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1))+(t-1)^2*(t+1)^2*(-q^2-2-q^2*t^2+t^4-q^4*t^4-t^4*q^2+3*q^2*t^6-t^6*q^4-t^8*q^6+t^8*q^4+t^10*q^4+2*q^6*t^12-q^8*t^12+t^14*q^8)*q*x3*x2*x1/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t-1)*(t+1)*x1^2/((q^3*t^5-1)*(q^3*t^5+1)*x3*x2)+(t-1)*(t+1)*(-q^2-1+t^4*q^2-q^4*t^4+2*t^6*q^4)*x2^2/((t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1))+(t-1)*(t+1)*(t^3*q-1)*(t^3*q+1)*x3*x2^2*x1/((t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1))+(t-1)^2*(t+1)^2*(q^2+1)*q*x1/((t*q+1)*(t*q-1)*(q^3*t^5+1)*(q^3*t^5-1)*x3*x2)+(t-1)^2*(t+1)^2*(t^3*q-1)*(t^3*q+1)*x3*x2*x1^2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t-1)^2*(t+1)^2*q^3*x3/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x1*x2)+(t-1)*(t+1)*(-1-q^2+q^2*t^2+t^10*q^6)*q*x2/((t*q+1)*(t*q-1)*(q^3*t^5+1)*(q^3*t^5-1)*x3*x1)+x2^2/(x1*x3)+(t-1)*(t+1)*q*x2^2/((t*q-1)*(t*q+1)*x3)+(t-1)^3*(t+1)^3*(1+t^2+t^4*q^2)*q*x2*x1^2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t-1)^2*(t+1)^2*q*x1^2/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t-1)^2*(t+1)^2*(q^2*t^6+2*t^6*q^4-q^4*t^4+t^4*q^2-q^2*t^2+t^2-2-q^2)*q^3/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)*(t+1)*(q^2+2-t^2+q^4*t^4-t^4*q^2-3*t^6*q^4+t^8*q^4-2*t^10*q^6-q^8*t^12+q^6*t^12+q^8*t^16+q^10*t^16)*q^2*x2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x1)+(t-1)^2*(t+1)^2*(q^2+1)*q^2/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3*x2)+(t-1)*(t+1)*(1+q^4+2*q^2-2*q^2*t^2+t^4*q^6-q^4*t^4-3*q^6*t^6-t^6*q^4+2*t^8*q^6-t^10*q^6-q^8*t^10-t^14*q^10+t^14*q^8+2*q^10*t^16)*x2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t-1)^2*(t+1)^2*(-q^2-2-q^2*t^2-q^4*t^4+2*t^6*q^4+t^10*q^6+q^8*t^12+t^14*q^8)*q^3/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x1)+(t-1)^2*(t+1)^2*(-1-q^2-q^2*t^2+t^2+t^4*q^2-q^4*t^4+2*t^6*q^4)*q^2*x3/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)*(t+1)*q*x2^2/((t*q-1)*(t*q+1)*x1)+(t-1)^2*(t+1)^2*(1+t^2+t^4*q^2)*q*x2^2*x1/((t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1))+(t-1)^2*(t+1)^2*q*x1^2/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)^2*(t+1)^2*(-1-q^4-2*q^2-t^2*q^4-q^2*t^2+t^4*q^2-t^4*q^6-2*q^4*t^4+3*t^6*q^4-q^6*t^6-t^8*q^8+t^8*q^6+2*t^10*q^6-q^10*t^12+3*q^8*t^12+2*t^14*q^10)*x3*x2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t-1)*(t+1)*(q^2+1-t^2+q^4*t^4-t^4*q^2+q^2*t^6-3*t^6*q^4+t^8*q^4-t^10*q^6+q^6*t^12-q^8*t^12+q^10*t^16)*q^2*x3/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x1)+(t-1)*(t+1)*(-1-q^2+q^2*t^2+t^10*q^6)*q^2/((t*q-1)*(t*q+1)*(q^3*t^5+1)*(q^3*t^5-1)*x1*x3)+(t-1)*(t+1)*(1+q^4+2*q^2-3*q^2*t^2+t^4*q^6-q^4*t^4-3*q^6*t^6-t^6*q^4+t^8*q^4+2*t^8*q^6-t^10*q^6+t^14*q^8-t^14*q^10+q^10*t^16)*x1/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t-1)^2*(t+1)^2*(3*q^2+q^4+2+q^2*t^2-t^2+t^2*q^4-6*t^4*q^2+q^4*t^4-7*t^6*q^4+q^2*t^6+3*t^8*q^4-4*t^8*q^6+t^10*q^4+3*t^10*q^6-q^8*t^12-t^14*q^10+t^14*q^8+q^8*t^16+q^10*t^18)*q*x1/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(-q^2-2-q^2*t^2-q^4*t^4+2*t^6*q^4+t^10*q^6+q^6*t^12+t^14*q^8)*q*x2*x1/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t+1)*(t-1)*x2^2*x1/((t*q-1)*(t*q+1)*x3)+(t-1)^3*(t+1)^3*(1+t^2+t^4*q^2)*q*x3*x1^2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1))+(t-1)*(t+1)*q^3/((q^3*t^5+1)*(q^3*t^5-1)*x1*x2*x3)+(t-1)^2*(t+1)^2*(3+3*q^2+q^4+2*q^2*t^2-t^2+t^2*q^4-6*t^4*q^2+q^4*t^4-8*t^6*q^4+q^2*t^6+2*t^8*q^4-4*t^8*q^6+t^10*q^4+2*t^10*q^6-2*q^8*t^12-t^14*q^10+t^14*q^8+q^8*t^16+q^10*t^16+2*q^10*t^18)*q^2/((q^3*t^5+1)*(q^3*t^5-1)*(t*q-1)*(t*q+1)*(t^3*q^2+1)*(t^3*q^2-1)*(t^2*q-1)*(t^2*q+1))+(t-1)^2*(t+1)^2*(-q^4-2*q^2-1-t^2*q^4-t^4*q^6+2*q^6*t^6+t^6*q^4+t^10*q^6+q^8*t^12+t^14*q^10)*q/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t-1)^2*(t+1)^2*(-1-q^2-q^2*t^2+t^2+t^4*q^2-q^4*t^4+2*t^6*q^4)*q*x3*x1/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)^2*(t+1)^2*x2*x1^2/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x3)+(t-1)^2*(t+1)^2*x3*x1^2/((t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x2)+(t-1)^2*(t+1)^2*q^4/((t*q+1)*(t*q-1)*(q^3*t^5+1)*(q^3*t^5-1)*x1*x2)+(t-1)^2*(t+1)^2*(-q^2-1-q^2*t^2-q^4*t^4+t^6*q^4+t^10*q^6+q^8*t^12+t^14*q^10)*q*x3*x2/((t^3*q^2-1)*(t^3*q^2+1)*(t*q+1)*(t*q-1)*(q^3*t^5-1)*(q^3*t^5+1)*x1) # optional - sage.symbolic sage: to_SR(E[mu]) - expected # long time (20s) # optional - sage.symbolic 0 @@ -1095,7 +1095,7 @@ class NonSymmetricMacdonaldPolynomials(CherednikOperatorsEigenvectors): sage: omega=E.keys().fundamental_weights() sage: mu = -4*omega[1]; mu (-4) - sage: expected = (t-1)*(t+1)*(-1+q^2*t^2-q^2-3*q^10-7*q^26*t^8+5*t^2*q^6-q^16-3*q^4+4*t^10*q^30-4*t^6*q^22-10*q^20*t^6+2*q^32*t^10-3*q^6-4*q^8+q^34*t^10-4*t^8*q^24-2*q^12-q^14+2*q^22*t^10+4*q^26*t^10+4*q^28*t^10+t^6*q^30-2*q^32*t^8-2*t^8*q^22+2*q^24*t^10-q^20*t^2-2*t^6*q^12+t^8*q^14+2*t^4*q^24-4*t^8*q^30+2*t^8*q^20-9*t^6*q^16+3*q^26*t^6+q^28*t^6+3*t^2*q^4+2*q^18*t^8-6*t^6*q^14+4*t^4*q^22-2*q^24*t^6+3*t^2*q^12+7*t^4*q^20-t^2*q^16+11*q^18*t^4-2*t^2*q^18+9*q^16*t^4-t^4*q^6+6*q^8*t^2+5*q^10*t^2-6*q^28*t^8+q^12*t^4+8*t^4*q^14-10*t^6*q^18-q^4*t^4+q^16*t^8-2*t^4*q^8)/((t*q^4-1)*(t*q^4+1)*(q^7*t^2-1)*(q^7*t^2+1)*(t*q^3-1)*(t*q^3+1)*(q^5*t^2+1)*(q^5*t^2-1))+(q^2+1)*(q^4+1)*(t-1)*(t+1)*(-1+q^2*t^2-q^2+t^2*q^6-q^4+t^6*q^22+3*q^10*t^4+t^2-q^8-2*t^8*q^24+q^22*t^10+q^26*t^10-2*t^8*q^22+q^24*t^10-4*t^6*q^12-2*t^8*q^20-3*t^6*q^16+2*t^2*q^4-t^6*q^10-2*t^6*q^14+t^8*q^12-t^2*q^12+2*q^16*t^4+q^8*t^2-q^10*t^2+3*q^12*t^4+2*t^4*q^14+t^6*q^18-2*q^4*t^4+q^16*t^8+q^20*t^10)*q*x1/((t*q^4-1)*(t*q^4+1)*(q^7*t^2-1)*(q^7*t^2+1)*(t*q^3-1)*(t*q^3+1)*(q^5*t^2+1)*(q^5*t^2-1))+(q^2+1)*(q^4+1)*(t-1)*(t+1)*(1+q^8+q^4+q^2-q^8*t^2-2*t^2*q^4-t^2*q^6+t^2*q^12-t^2+t^4*q^6-2*q^16*t^4-t^4*q^14-2*q^12*t^4+t^6*q^12+t^6*q^16+t^6*q^18+t^6*q^14)*q/((t*q^4-1)*(t*q^4+1)*(q^7*t^2-1)*(q^7*t^2+1)*(t*q^3-1)*(t*q^3+1)*x1)+(t-1)*(t+1)*(-1-q^2-q^6-q^4-q^8+t^2*q^4-t^2*q^14+t^2*q^6-q^10*t^2+q^8*t^2-t^2*q^12+q^12*t^4+q^10*t^4+q^16*t^4+2*t^4*q^14)*(q^4+1)/((q^7*t^2+1)*(q^7*t^2-1)*(t*q^4-1)*(t*q^4+1)*x1^2)+(t-1)*(t+1)*(q^4+1)*(q^2+1)*q/((t*q^4-1)*(t*q^4+1)*x1^3)+(q^4+1)*(t-1)*(t+1)*(1+q^6+q^8+q^2+q^4-q^2*t^2-3*t^2*q^4+q^10*t^2+t^2*q^12-2*t^2*q^6-q^8*t^2-2*q^16*t^4+q^4*t^4+t^4*q^6-q^10*t^4-2*q^12*t^4-2*t^4*q^14+t^6*q^12+t^6*q^18+2*t^6*q^16+t^6*q^14)*x1^2/((t*q^4-1)*(t*q^4+1)*(q^7*t^2-1)*(q^7*t^2+1)*(t*q^3-1)*(t*q^3+1))+(t-1)*(t+1)*(-1-t^2*q^6+t^2+t^4*q^8)*(q^4+1)*(q^2+1)*q*x1^3/((q^7*t^2+1)*(q^7*t^2-1)*(t*q^4-1)*(t*q^4+1))+1/x1^4+(t-1)*(t+1)*x1^4/((t*q^4-1)*(t*q^4+1)) + sage: expected = (t-1)*(t+1)*(-1+q^2*t^2-q^2-3*q^10-7*q^26*t^8+5*t^2*q^6-q^16-3*q^4+4*t^10*q^30-4*t^6*q^22-10*q^20*t^6+2*q^32*t^10-3*q^6-4*q^8+q^34*t^10-4*t^8*q^24-2*q^12-q^14+2*q^22*t^10+4*q^26*t^10+4*q^28*t^10+t^6*q^30-2*q^32*t^8-2*t^8*q^22+2*q^24*t^10-q^20*t^2-2*t^6*q^12+t^8*q^14+2*t^4*q^24-4*t^8*q^30+2*t^8*q^20-9*t^6*q^16+3*q^26*t^6+q^28*t^6+3*t^2*q^4+2*q^18*t^8-6*t^6*q^14+4*t^4*q^22-2*q^24*t^6+3*t^2*q^12+7*t^4*q^20-t^2*q^16+11*q^18*t^4-2*t^2*q^18+9*q^16*t^4-t^4*q^6+6*q^8*t^2+5*q^10*t^2-6*q^28*t^8+q^12*t^4+8*t^4*q^14-10*t^6*q^18-q^4*t^4+q^16*t^8-2*t^4*q^8)/((t*q^4-1)*(t*q^4+1)*(q^7*t^2-1)*(q^7*t^2+1)*(t*q^3-1)*(t*q^3+1)*(q^5*t^2+1)*(q^5*t^2-1))+(q^2+1)*(q^4+1)*(t-1)*(t+1)*(-1+q^2*t^2-q^2+t^2*q^6-q^4+t^6*q^22+3*q^10*t^4+t^2-q^8-2*t^8*q^24+q^22*t^10+q^26*t^10-2*t^8*q^22+q^24*t^10-4*t^6*q^12-2*t^8*q^20-3*t^6*q^16+2*t^2*q^4-t^6*q^10-2*t^6*q^14+t^8*q^12-t^2*q^12+2*q^16*t^4+q^8*t^2-q^10*t^2+3*q^12*t^4+2*t^4*q^14+t^6*q^18-2*q^4*t^4+q^16*t^8+q^20*t^10)*q*x1/((t*q^4-1)*(t*q^4+1)*(q^7*t^2-1)*(q^7*t^2+1)*(t*q^3-1)*(t*q^3+1)*(q^5*t^2+1)*(q^5*t^2-1))+(q^2+1)*(q^4+1)*(t-1)*(t+1)*(1+q^8+q^4+q^2-q^8*t^2-2*t^2*q^4-t^2*q^6+t^2*q^12-t^2+t^4*q^6-2*q^16*t^4-t^4*q^14-2*q^12*t^4+t^6*q^12+t^6*q^16+t^6*q^18+t^6*q^14)*q/((t*q^4-1)*(t*q^4+1)*(q^7*t^2-1)*(q^7*t^2+1)*(t*q^3-1)*(t*q^3+1)*x1)+(t-1)*(t+1)*(-1-q^2-q^6-q^4-q^8+t^2*q^4-t^2*q^14+t^2*q^6-q^10*t^2+q^8*t^2-t^2*q^12+q^12*t^4+q^10*t^4+q^16*t^4+2*t^4*q^14)*(q^4+1)/((q^7*t^2+1)*(q^7*t^2-1)*(t*q^4-1)*(t*q^4+1)*x1^2)+(t-1)*(t+1)*(q^4+1)*(q^2+1)*q/((t*q^4-1)*(t*q^4+1)*x1^3)+(q^4+1)*(t-1)*(t+1)*(1+q^6+q^8+q^2+q^4-q^2*t^2-3*t^2*q^4+q^10*t^2+t^2*q^12-2*t^2*q^6-q^8*t^2-2*q^16*t^4+q^4*t^4+t^4*q^6-q^10*t^4-2*q^12*t^4-2*t^4*q^14+t^6*q^12+t^6*q^18+2*t^6*q^16+t^6*q^14)*x1^2/((t*q^4-1)*(t*q^4+1)*(q^7*t^2-1)*(q^7*t^2+1)*(t*q^3-1)*(t*q^3+1))+(t-1)*(t+1)*(-1-t^2*q^6+t^2+t^4*q^8)*(q^4+1)*(q^2+1)*q*x1^3/((q^7*t^2+1)*(q^7*t^2-1)*(t*q^4-1)*(t*q^4+1))+1/x1^4+(t-1)*(t+1)*x1^4/((t*q^4-1)*(t*q^4+1)) # optional - sage.symbolic sage: to_SR(E[mu]) - expected # optional - sage.symbolic 0 diff --git a/src/sage/combinat/root_system/plot.py b/src/sage/combinat/root_system/plot.py index 2c7a0bfbe45..2789540d238 100644 --- a/src/sage/combinat/root_system/plot.py +++ b/src/sage/combinat/root_system/plot.py @@ -186,7 +186,7 @@ sure everything fits in the picture:: sage: RootSystem(["G",2]).ambient_space().plot(alcoves=True, # optional - sage.plot sage.symbolic -....: alcove_labels=True, bounding_box=5) + ....: alcove_labels=True, bounding_box=5) Graphics object consisting of 37 graphics primitives .. PLOT:: diff --git a/src/sage/combinat/root_system/reflection_group_complex.py b/src/sage/combinat/root_system/reflection_group_complex.py index 87424491233..3adeea5d5c7 100644 --- a/src/sage/combinat/root_system/reflection_group_complex.py +++ b/src/sage/combinat/root_system/reflection_group_complex.py @@ -212,10 +212,8 @@ from sage.matrix.special import identity_matrix from sage.structure.element import is_Matrix from sage.interfaces.gap3 import gap3 -from sage.rings.universal_cyclotomic_field import E from sage.modules.free_module_element import vector from sage.combinat.root_system.cartan_matrix import CartanMatrix -from sage.rings.universal_cyclotomic_field import UniversalCyclotomicField from sage.misc.sage_eval import sage_eval @@ -1710,6 +1708,8 @@ def _invariant_form_brute_force(self): [1 0] [0 1] """ + from sage.rings.universal_cyclotomic_field import E + base_change = self.base_change_matrix() Delta = tuple(self.independent_roots()) basis_is_Delta = base_change.is_one() @@ -2194,6 +2194,8 @@ def is_regular(self, h, is_class_representative=False): sage: len([w for w in W if w.is_regular(w.order())]) # optional - gap3 18 """ + from sage.rings.universal_cyclotomic_field import UniversalCyclotomicField, E + evs = self.reflection_eigenvalues(is_class_representative=is_class_representative) P = self.parent() I = identity_matrix(P.rank()) diff --git a/src/sage/combinat/root_system/root_lattice_realizations.py b/src/sage/combinat/root_system/root_lattice_realizations.py index 70814864cd6..e7f0e87807f 100644 --- a/src/sage/combinat/root_system/root_lattice_realizations.py +++ b/src/sage/combinat/root_system/root_lattice_realizations.py @@ -2319,12 +2319,12 @@ def plot_coroots(self, collection="simple", **options): EXAMPLES:: - sage: RootSystem(["B",3]).ambient_space().plot_coroots() + sage: RootSystem(["B",3]).ambient_space().plot_coroots() # optional - sage.plot sage.symbolic Graphics3d Object TESTS:: - sage: list(RootSystem(["B",2]).ambient_space().plot_coroots()) + sage: list(RootSystem(["B",2]).ambient_space().plot_coroots()) # optional - sage.plot sage.symbolic [Arrow from (0.0,0.0) to (1.0,-1.0), Text '$\alpha^\vee_{1}$' at the point (1.05,-1.05), Arrow from (0.0,0.0) to (0.0,2.0), diff --git a/src/sage/combinat/root_system/weyl_group.py b/src/sage/combinat/root_system/weyl_group.py index 6842f0467fa..1e032d45ad9 100644 --- a/src/sage/combinat/root_system/weyl_group.py +++ b/src/sage/combinat/root_system/weyl_group.py @@ -16,14 +16,14 @@ sage: w = WeylGroup(['A',3]) sage: d = w.cayley_graph(); d Digraph on 24 vertices - sage: d.show3d(color_by_label=True, edge_size=0.01, vertex_size=0.03) + sage: d.show3d(color_by_label=True, edge_size=0.01, vertex_size=0.03) # optional - sage.plot The Cayley graph of the Weyl Group of type ['D', 4]:: sage: w = WeylGroup(['D',4]) sage: d = w.cayley_graph(); d Digraph on 192 vertices - sage: d.show3d(color_by_label=True, edge_size=0.01, vertex_size=0.03) #long time (less than one minute) + sage: d.show3d(color_by_label=True, edge_size=0.01, vertex_size=0.03) # long time (less than one minute) # optional - sage.plot .. TODO:: diff --git a/src/sage/combinat/six_vertex_model.py b/src/sage/combinat/six_vertex_model.py index b688bdecb53..cbfd004ca35 100644 --- a/src/sage/combinat/six_vertex_model.py +++ b/src/sage/combinat/six_vertex_model.py @@ -149,7 +149,7 @@ def plot(self, color='sign'): EXAMPLES:: sage: M = SixVertexModel(2, boundary_conditions='ice') - sage: print(M[0].plot().description()) + sage: print(M[0].plot().description()) # optional - sage.plot Arrow from (-1.0,0.0) to (0.0,0.0) Arrow from (-1.0,1.0) to (0.0,1.0) Arrow from (0.0,0.0) to (0.0,-1.0) diff --git a/src/sage/combinat/symmetric_group_representations.py b/src/sage/combinat/symmetric_group_representations.py index 8a6b58ae87c..23f310b89ea 100644 --- a/src/sage/combinat/symmetric_group_representations.py +++ b/src/sage/combinat/symmetric_group_representations.py @@ -75,28 +75,28 @@ def SymmetricGroupRepresentation(partition, implementation="specht", :: - sage: orth = SymmetricGroupRepresentation([2,1], "orthogonal"); orth + sage: orth = SymmetricGroupRepresentation([2,1], "orthogonal"); orth # optional - sage.symbolic Orthogonal representation of the symmetric group corresponding to [2, 1] - sage: all(a*a.transpose() == a.parent().identity_matrix() for a in orth) + sage: all(a*a.transpose() == a.parent().identity_matrix() for a in orth) # optional - sage.symbolic True :: - sage: orth = SymmetricGroupRepresentation([3,2], "orthogonal"); orth + sage: orth = SymmetricGroupRepresentation([3,2], "orthogonal"); orth # optional - sage.symbolic Orthogonal representation of the symmetric group corresponding to [3, 2] - sage: orth([2,1,3,4,5]) + sage: orth([2,1,3,4,5]) # optional - sage.symbolic [ 1 0 0 0 0] [ 0 1 0 0 0] [ 0 0 -1 0 0] [ 0 0 0 1 0] [ 0 0 0 0 -1] - sage: orth([1,3,2,4,5]) + sage: orth([1,3,2,4,5]) # optional - sage.symbolic [ 1 0 0 0 0] [ 0 -1/2 1/2*sqrt(3) 0 0] [ 0 1/2*sqrt(3) 1/2 0 0] [ 0 0 0 -1/2 1/2*sqrt(3)] [ 0 0 0 1/2*sqrt(3) 1/2] - sage: orth([1,2,4,3,5]) + sage: orth([1,2,4,3,5]) # optional - sage.symbolic [ -1/3 2/3*sqrt(2) 0 0 0] [2/3*sqrt(2) 1/3 0 0 0] [ 0 0 1 0 0] @@ -200,13 +200,13 @@ def SymmetricGroupRepresentations(n, implementation="specht", ring=None, :: - sage: orth = SymmetricGroupRepresentations(3, "orthogonal"); orth + sage: orth = SymmetricGroupRepresentations(3, "orthogonal"); orth # optional - sage.symbolic Orthogonal representations of the symmetric group of order 3! over Symbolic Ring - sage: orth.list() + sage: orth.list() # optional - sage.symbolic [Orthogonal representation of the symmetric group corresponding to [3], Orthogonal representation of the symmetric group corresponding to [2, 1], Orthogonal representation of the symmetric group corresponding to [1, 1, 1]] - sage: orth([2,1])([1,2,3]) + sage: orth([2,1])([1,2,3]) # optional - sage.symbolic [1 0] [0 1] @@ -516,8 +516,8 @@ def __iter__(self): EXAMPLES:: - sage: orth = SymmetricGroupRepresentations(3, "orthogonal") - sage: for x in orth: print(x) + sage: orth = SymmetricGroupRepresentations(3, "orthogonal") # optional - sage.symbolic + sage: for x in orth: print(x) # optional - sage.symbolic Orthogonal representation of the symmetric group corresponding to [3] Orthogonal representation of the symmetric group corresponding to [2, 1] Orthogonal representation of the symmetric group corresponding to [1, 1, 1] @@ -540,8 +540,8 @@ def _yang_baxter_graph(self): EXAMPLES:: - sage: orth = SymmetricGroupRepresentation([3,2], "orthogonal") - sage: orth._yang_baxter_graph + sage: orth = SymmetricGroupRepresentation([3,2], "orthogonal") # optional - sage.symbolic + sage: orth._yang_baxter_graph # optional - sage.symbolic Yang-Baxter graph of [3, 2], with top vertex (0, -1, 2, 1, 0) """ Y = YangBaxterGraph_partition(self._partition) @@ -565,8 +565,8 @@ def _tableau_dict(self): EXAMPLES:: - sage: orth = SymmetricGroupRepresentation([3,2], "orthogonal") - sage: orth._tableau_dict + sage: orth = SymmetricGroupRepresentation([3,2], "orthogonal") # optional - sage.symbolic + sage: orth._tableau_dict # optional - sage.symbolic {(0, -1, 2, 1, 0): [[1, 2, 3], [4, 5]], (0, 2, -1, 1, 0): [[1, 2, 4], [3, 5]], (0, 2, 1, -1, 0): [[1, 3, 4], [2, 5]], @@ -591,8 +591,8 @@ def _word_dict(self): EXAMPLES:: - sage: orth = SymmetricGroupRepresentation([3,2], "orthogonal") - sage: orth._word_dict + sage: orth = SymmetricGroupRepresentation([3,2], "orthogonal") # optional - sage.symbolic + sage: orth._word_dict # optional - sage.symbolic {(0, -1, 2, 1, 0): (4, 5, 1, 2, 3), (0, 2, -1, 1, 0): (3, 5, 1, 2, 4), (0, 2, 1, -1, 0): (2, 5, 1, 3, 4), @@ -610,11 +610,11 @@ def representation_matrix_for_simple_transposition(self, i): EXAMPLES:: - sage: orth = SymmetricGroupRepresentation([2,1], "orthogonal") - sage: orth.representation_matrix_for_simple_transposition(1) + sage: orth = SymmetricGroupRepresentation([2,1], "orthogonal") # optional - sage.symbolic + sage: orth.representation_matrix_for_simple_transposition(1) # optional - sage.symbolic [ 1 0] [ 0 -1] - sage: orth.representation_matrix_for_simple_transposition(2) + sage: orth.representation_matrix_for_simple_transposition(2) # optional - sage.symbolic [ -1/2 1/2*sqrt(3)] [1/2*sqrt(3) 1/2] @@ -663,11 +663,11 @@ def _representation_matrix_uncached(self, permutation): EXAMPLES:: - sage: orth = SymmetricGroupRepresentation([2,1], "orthogonal") - sage: orth._representation_matrix_uncached(Permutation([2,1,3])) + sage: orth = SymmetricGroupRepresentation([2,1], "orthogonal") # optional - sage.symbolic + sage: orth._representation_matrix_uncached(Permutation([2,1,3])) # optional - sage.symbolic [ 1 0] [ 0 -1] - sage: orth._representation_matrix_uncached(Permutation([1,3,2])) + sage: orth._representation_matrix_uncached(Permutation([1,3,2])) # optional - sage.symbolic [ -1/2 1/2*sqrt(3)] [1/2*sqrt(3) 1/2] @@ -696,11 +696,11 @@ def representation_matrix(self, permutation): EXAMPLES:: - sage: orth = SymmetricGroupRepresentation([2,1], "orthogonal") - sage: orth.representation_matrix(Permutation([2,1,3])) + sage: orth = SymmetricGroupRepresentation([2,1], "orthogonal") # optional - sage.symbolic + sage: orth.representation_matrix(Permutation([2,1,3])) # optional - sage.symbolic [ 1 0] [ 0 -1] - sage: orth.representation_matrix(Permutation([1,3,2])) + sage: orth.representation_matrix(Permutation([1,3,2])) # optional - sage.symbolic [ -1/2 1/2*sqrt(3)] [1/2*sqrt(3) 1/2] @@ -779,7 +779,7 @@ def _repr_(self): EXAMPLES:: - sage: SymmetricGroupRepresentation([2,1], "orthogonal") + sage: SymmetricGroupRepresentation([2,1], "orthogonal") # optional - sage.symbolic Orthogonal representation of the symmetric group corresponding to [2, 1] """ return "Orthogonal representation of the symmetric group corresponding to {}".format(self._partition) @@ -796,8 +796,8 @@ def _2x2_matrix_entries(self, beta): EXAMPLES:: - sage: orth = SymmetricGroupRepresentation([2,1], "orthogonal") - sage: orth._2x2_matrix_entries(1/2) + sage: orth = SymmetricGroupRepresentation([2,1], "orthogonal") # optional - sage.symbolic + sage: orth._2x2_matrix_entries(1/2) # optional - sage.symbolic (-1/2, 1/2*sqrt(3), 1/2*sqrt(3), 1/2) """ return (-beta, sqrt(1 - beta**2), sqrt(1 - beta**2), beta) diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 4df26efd41d..719f2260608 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -890,15 +890,15 @@ def plot(self, descents=False): EXAMPLES:: sage: t = Tableau([[1,2,4],[3]]) - sage: t.plot() + sage: t.plot() # optional - sage.plot Graphics object consisting of 11 graphics primitives - sage: t.plot(descents=True) + sage: t.plot(descents=True) # optional - sage.plot Graphics object consisting of 12 graphics primitives sage: t = Tableau([[2,2,4],[3]]) - sage: t.plot() + sage: t.plot() # optional - sage.plot Graphics object consisting of 11 graphics primitives - sage: t.plot(descents=True) + sage: t.plot(descents=True) # optional - sage.plot Traceback (most recent call last): ... ValueError: the tableau must be standard for 'descents=True' diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index ab639164b5a..53e04002cf6 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -136,7 +136,7 @@ sage: st = w.suffix_tree() sage: st Implicit Suffix Tree of the word: abaabbba - sage: st.show(word_labels=True) + sage: st.show(word_labels=True) # optional - sage.plot :: @@ -6824,18 +6824,18 @@ def colored_vector(self, x=0, y=0, width='default', height=1, cmap='hsv', thickn EXAMPLES:: - sage: Word(range(20)).colored_vector() + sage: Word(range(20)).colored_vector() # optional - sage.plot Graphics object consisting of 21 graphics primitives - sage: Word(range(100)).colored_vector(0,0,10,1) + sage: Word(range(100)).colored_vector(0,0,10,1) # optional - sage.plot Graphics object consisting of 101 graphics primitives - sage: Words(range(100))(range(10)).colored_vector() + sage: Words(range(100))(range(10)).colored_vector() # optional - sage.plot Graphics object consisting of 11 graphics primitives sage: w = Word('abbabaab') - sage: w.colored_vector() + sage: w.colored_vector() # optional - sage.plot Graphics object consisting of 9 graphics primitives - sage: w.colored_vector(cmap='autumn') + sage: w.colored_vector(cmap='autumn') # optional - sage.plot Graphics object consisting of 9 graphics primitives - sage: Word(range(20)).colored_vector(label='Rainbow') + sage: Word(range(20)).colored_vector(label='Rainbow') # optional - sage.plot Graphics object consisting of 23 graphics primitives When two words are defined under the same parent, same letters are @@ -6844,25 +6844,25 @@ def colored_vector(self, x=0, y=0, width='default', height=1, cmap='hsv', thickn sage: W = Words(range(20)) sage: w = W(range(20)) sage: y = W(range(10,20)) - sage: y.colored_vector(y=1, x=10) + w.colored_vector() + sage: y.colored_vector(y=1, x=10) + w.colored_vector() # optional - sage.plot Graphics object consisting of 32 graphics primitives TESTS: The empty word:: - sage: Word().colored_vector() + sage: Word().colored_vector() # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: Word().colored_vector(label='empty') + sage: Word().colored_vector(label='empty') # optional - sage.plot Graphics object consisting of 3 graphics primitives Unknown cmap:: - sage: Word(range(100)).colored_vector(cmap='jolies') + sage: Word(range(100)).colored_vector(cmap='jolies') # optional - sage.plot Traceback (most recent call last): ... RuntimeError: Color map jolies not known - sage: Word(range(100)).colored_vector(cmap='__doc__') + sage: Word(range(100)).colored_vector(cmap='__doc__') # optional - sage.plot Traceback (most recent call last): ... RuntimeError: Color map __doc__ not known diff --git a/src/sage/combinat/words/morphism.py b/src/sage/combinat/words/morphism.py index 0b8e99ce5c5..33a76127699 100644 --- a/src/sage/combinat/words/morphism.py +++ b/src/sage/combinat/words/morphism.py @@ -2790,113 +2790,127 @@ def rauzy_fractal_plot(self, n=None, exchange=False, eig=None, #. The Rauzy fractal of the Tribonacci substitution:: sage: s = WordMorphism('1->12,2->13,3->1') - sage: s.rauzy_fractal_plot() # long time + sage: s.rauzy_fractal_plot() # long time # optional - sage.plot Graphics object consisting of 3 graphics primitives #. The "Hokkaido" fractal. We tweak the plot using the plotting options to get a nice reusable picture, in which we mark the origin by a black dot:: sage: s = WordMorphism('a->ab,b->c,c->d,d->e,e->a') - sage: G = s.rauzy_fractal_plot(n=100000, point_size=3, plot_origin=(50,"black")) # not tested + sage: G = s.rauzy_fractal_plot(n=100000, point_size=3, # not tested + ....: plot_origin=(50,"black")) sage: G.show(figsize=10, axes=false) # not tested #. Another "Hokkaido" fractal and its domain exchange:: sage: s = WordMorphism({1:[2], 2:[4,3], 3:[4], 4:[5,3], 5:[6], 6:[1]}) - sage: s.rauzy_fractal_plot() # not tested takes > 1 second - sage: s.rauzy_fractal_plot(exchange=True) # not tested takes > 1 second + sage: s.rauzy_fractal_plot() # not tested (> 1 second) + sage: s.rauzy_fractal_plot(exchange=True) # not tested (> 1 second) #. A three-dimensional Rauzy fractal:: sage: s = WordMorphism('1->12,2->13,3->14,4->1') - sage: s.rauzy_fractal_plot() # not tested takes > 1 second + sage: s.rauzy_fractal_plot() # not tested (> 1 second) #. A one-dimensional Rauzy fractal (very scattered):: sage: s = WordMorphism('1->2122,2->1') - sage: s.rauzy_fractal_plot().show(figsize=20) # not tested takes > 1 second + sage: s.rauzy_fractal_plot().show(figsize=20) # not tested (> 1 second) #. A high resolution plot of a complicated fractal:: sage: s = WordMorphism('1->23,2->123,3->1122233') - sage: G = s.rauzy_fractal_plot(n=300000) # not tested takes > 1 second - sage: G.show(axes=false, figsize=20) # not tested takes > 1 second + sage: G = s.rauzy_fractal_plot(n=300000) # not tested (> 1 second) + sage: G.show(axes=false, figsize=20) # not tested (> 1 second) #. A nice colorful animation of a domain exchange:: sage: s = WordMorphism('1->21,2->3,3->4,4->25,5->6,6->7,7->1') - sage: L = [s.rauzy_fractal_plot(), s.rauzy_fractal_plot(exchange=True)] # not tested takes > 1 second - sage: animate(L, axes=false).show(delay=100) # not tested takes > 1 second + sage: L = [s.rauzy_fractal_plot(), # not tested (> 1 second) + ....: s.rauzy_fractal_plot(exchange=True)] + sage: animate(L, axes=false).show(delay=100) # not tested (> 1 second) #. Plotting with only one color:: sage: s = WordMorphism('1->12,2->31,3->1') - sage: s.rauzy_fractal_plot(colormap={'1':'black', '2':'black', '3':'black'}) # not tested takes > 1 second + sage: cm = {'1':'black', '2':'black', '3':'black'} + sage: s.rauzy_fractal_plot(colormap=cm) # not tested (> 1 second) #. Different fractals can be obtained by choosing another (non-Pisot) eigenvalue:: sage: s = WordMorphism('1->12,2->3,3->45,4->5,5->6,6->7,7->8,8->1') sage: E = s.incidence_matrix().eigenvalues() sage: x = [x for x in E if -0.8 < x < -0.7][0] - sage: s.rauzy_fractal_plot() # not tested takes > 1 second - sage: s.rauzy_fractal_plot(eig=x) # not tested takes > 1 second + sage: s.rauzy_fractal_plot() # not tested (> 1 second) + sage: s.rauzy_fractal_plot(eig=x) # not tested (> 1 second) #. A Pisot reducible substitution with seemingly overlapping tiles:: - sage: s = WordMorphism({1:[1,2], 2:[2,3], 3:[4], 4:[5], 5:[6], 6:[7], 7:[8], 8:[9], 9:[10], 10:[1]}) - sage: s.rauzy_fractal_plot() # not tested takes > 1 second + sage: s = WordMorphism({1:[1,2], 2:[2,3], 3:[4], 4:[5], 5:[6], + ....: 6:[7], 7:[8], 8:[9], 9:[10], 10:[1]}) + sage: s.rauzy_fractal_plot() # not tested (> 1 second) #. A non-Pisot reducible substitution with a strange Rauzy fractal:: sage: s = WordMorphism({1:[3,2], 2:[3,3], 3:[4], 4:[1]}) - sage: s.rauzy_fractal_plot() # not tested takes > 1 second + sage: s.rauzy_fractal_plot() # not tested (> 1 second) #. A substitution with overlapping tiles. We use the options ``colormap`` and ``opacity`` to study how the tiles overlap:: sage: s = WordMorphism('1->213,2->4,3->5,4->1,5->21') - sage: s.rauzy_fractal_plot() # not tested takes > 1 second - sage: s.rauzy_fractal_plot(colormap={'1':'red', '4':'purple'}) # not tested takes > 1 second - sage: s.rauzy_fractal_plot(opacity={'1':0.1,'2':1,'3':0.1,'4':0.1,'5':0.1}, n=150000) # not tested takes > 1 second + sage: s.rauzy_fractal_plot() # not tested (> 1 second) + sage: s.rauzy_fractal_plot(colormap={'1':'red', '4':'purple'}) # not tested (> 1 second) + sage: s.rauzy_fractal_plot(n=150000, # not tested (> 1 second) + ....: opacity={'1':0.1,'2':1,'3':0.1,'4':0.1,'5':0.1}) #. Funny experiments by playing with the precision of the float numbers used to plot the fractal:: sage: s = WordMorphism('1->12,2->13,3->1') - sage: s.rauzy_fractal_plot(prec=6) # not tested - sage: s.rauzy_fractal_plot(prec=9) # not tested - sage: s.rauzy_fractal_plot(prec=15) # not tested - sage: s.rauzy_fractal_plot(prec=19) # not tested - sage: s.rauzy_fractal_plot(prec=25) # not tested + sage: s.rauzy_fractal_plot(prec=6) # not tested + sage: s.rauzy_fractal_plot(prec=9) # not tested + sage: s.rauzy_fractal_plot(prec=15) # not tested + sage: s.rauzy_fractal_plot(prec=19) # not tested + sage: s.rauzy_fractal_plot(prec=25) # not tested #. Using the ``translate`` option to plot periodic tilings:: sage: s = WordMorphism('1->12,2->13,3->1') - sage: s.rauzy_fractal_plot(n=10000, translate=[(0,0,0),(-1,0,1),(0,-1,1),(1,-1,0),(1,0,-1),(0,1,-1),(-1,1,0)]) # not tested takes > 1 second + sage: s.rauzy_fractal_plot(n=10000, # not tested (> 1 second) + ....: translate=[(0,0,0),(-1,0,1),(0,-1,1),(1,-1,0), + ....: (1,0,-1),(0,1,-1),(-1,1,0)]) :: sage: t = WordMorphism("a->aC,b->d,C->de,d->a,e->ab") # substitution found by Julien Bernat sage: V = [vector((0,0,1,0,-1)), vector((0,0,1,-1,0))] - sage: S = set(map(tuple, [i*V[0] + j*V[1] for i in [-1,0,1] for j in [-1,0,1]])) - sage: t.rauzy_fractal_plot(n=10000, translate=S, exchange=true) # not tested takes > 1 second + sage: S = set(map(tuple, [i*V[0] + j*V[1] + ....: for i in [-1,0,1] for j in [-1,0,1]])) + sage: t.rauzy_fractal_plot(n=10000, # not tested (> 1 second) + ....: translate=S, exchange=true) #. Using the ``translate`` option to plot arbitrary tilings with the fractal pieces. This can be used for example to plot the self-replicating tiling of the Rauzy fractal:: sage: s = WordMorphism({1:[1,2], 2:[3], 3:[4,3], 4:[5], 5:[6], 6:[1]}) - sage: s.rauzy_fractal_plot() # not tested takes > 1 second - sage: D = {1:[(0,0,0,0,0,0), (0,1,0,0,0,0)], 3:[(0,0,0,0,0,0), (0,1,0,0,0,0)], 6:[(0,1,0,0,0,0)]} - sage: s.rauzy_fractal_plot(n=30000, translate=D) # not tested takes > 1 second + sage: s.rauzy_fractal_plot() # not tested (> 1 second) + sage: D = {1: [(0,0,0,0,0,0), (0,1,0,0,0,0)], + ....: 3: [(0,0,0,0,0,0), (0,1,0,0,0,0)], 6: [(0,1,0,0,0,0)]} + sage: s.rauzy_fractal_plot(n=30000, translate=D) # not tested (> 1 second) #. Plot the projection of the canonical basis with the fractal:: - sage: s = WordMorphism({1:[2,1], 2:[3], 3:[6,4], 4:[5,1], 5:[6], 6:[7], 7:[8], 8:[9], 9:[1]}) - sage: s.rauzy_fractal_plot(plot_basis=True) # not tested takes > 1 second + sage: s = WordMorphism({1:[2,1], 2:[3], 3:[6,4], 4:[5,1], + ....: 5:[6], 6:[7], 7:[8], 8:[9], 9:[1]}) + sage: s.rauzy_fractal_plot(plot_basis=True) # not tested (> 1 second) TESTS:: sage: s = WordMorphism('a->ab,b->c,c->d,d->e,e->a') - sage: s.rauzy_fractal_plot(n=1000, colormap='Set1', opacity={'a':0.5,'b':1,'c':0.7,'d':0,'e':0.2}, plot_origin=(100,"black"), plot_basis=True, point_size=2.5) + sage: s.rauzy_fractal_plot(n=1000, colormap='Set1', # optional - sage.plot + ....: opacity={'a':0.5,'b':1,'c':0.7,'d':0,'e':0.2}, + ....: plot_origin=(100,"black"), plot_basis=True, + ....: point_size=2.5) Graphics object consisting of 10 graphics primitives REFERENCES: diff --git a/src/sage/combinat/words/paths.py b/src/sage/combinat/words/paths.py index 07db12ec123..a924eb45c03 100644 --- a/src/sage/combinat/words/paths.py +++ b/src/sage/combinat/words/paths.py @@ -45,7 +45,7 @@ [(0, 0), (1, 2), (-2, 6), (-1, 8), (-1, 5), (-1, 2), (-4, 6), (-3, 8)] sage: p.is_closed() False - sage: p.plot() + sage: p.plot() # optional - sage.plot Graphics object consisting of 3 graphics primitives To obtain a list of all the available word path specific functions, @@ -1365,15 +1365,15 @@ def plot_projection(self, v=None, letters=None, color=None, ring=None, To remove the axis, do like this:: - sage: r = w.plot_projection(v) - sage: r.axes(False) - sage: r # long time (2s) + sage: r = w.plot_projection(v) # optional - sage.plot + sage: r.axes(False) # optional - sage.plot + sage: r # long time (2s) # optional - sage.plot Graphics object consisting of 200 graphics primitives You can assign different colors to each letter:: - sage: color = {'1':'purple', '2':(.2,.3,.4), '3': 'magenta'} - sage: w.plot_projection(v, color=color) # long time (2s) + sage: color = {'1': 'purple', '2': (.2,.3,.4), '3': 'magenta'} + sage: w.plot_projection(v, color=color) # long time (2s) # optional - sage.plot Graphics object consisting of 200 graphics primitives The 3d-Rauzy fractal:: @@ -1383,14 +1383,14 @@ def plot_projection(self, v=None, letters=None, color=None, ring=None, sage: v = s.pisot_eigenvector_right() sage: P = WordPaths('1234',[(1,0,0,0), (0,1,0,0), (0,0,1,0), (0,0,0,1)]) sage: w = P(D[:200]) - sage: w.plot_projection(v) + sage: w.plot_projection(v) # optional - sage.plot Graphics3d Object The dimension of vector space of the parent must be 3 or 4:: sage: P = WordPaths('ab', [(1, 0), (0, 1)]) sage: p = P('aabbabbab') - sage: p.plot_projection() + sage: p.plot_projection() # optional - sage.plot Traceback (most recent call last): ... TypeError: The dimension of the vector space (=2) must be 3 or 4 @@ -1444,7 +1444,7 @@ def projected_path(self, v=None, ring=None): sage: p = w.projected_path(v) sage: p Path: 1213121121312121312112131213121121312121... - sage: p[:20].plot() + sage: p[:20].plot() # optional - sage.plot Graphics object consisting of 3 graphics primitives The ``ring`` argument allows to change the precision of the @@ -1530,42 +1530,42 @@ def plot(self, pathoptions=dict(rgbcolor='red',thickness=3), A non closed path on the square grid:: sage: P = WordPaths('abAB') - sage: P('abababAABAB').plot() + sage: P('abababAABAB').plot() # optional - sage.plot Graphics object consisting of 3 graphics primitives A closed path on the square grid:: - sage: P('abababAABABB').plot() + sage: P('abababAABABB').plot() # optional - sage.plot Graphics object consisting of 4 graphics primitives A Dyck path:: sage: P = WordPaths('()', steps='dyck') - sage: P('()()()((()))').plot() + sage: P('()()()((()))').plot() # optional - sage.plot Graphics object consisting of 3 graphics primitives A path in the triangle grid:: sage: P = WordPaths('abcdef', steps='triangle_grid') - sage: P('abcdedededefab').plot() + sage: P('abcdedededefab').plot() # optional - sage.plot Graphics object consisting of 3 graphics primitives A polygon of length 220 that tiles the plane in two ways:: sage: P = WordPaths('abAB') - sage: P('aBababAbabaBaBABaBabaBaBABAbABABaBabaBaBABaBababAbabaBaBABaBabaBaBABAbABABaBABAbAbabAbABABaBABAbABABaBabaBaBABAbABABaBABAbAbabAbABAbAbabaBababAbABAbAbabAbABABaBABAbAbabAbABAbAbabaBababAbabaBaBABaBababAbabaBababAbABAbAbab').plot() + sage: P('aBababAbabaBaBABaBabaBaBABAbABABaBabaBaBABaBababAbabaBaBABaBabaBaBABAbABABaBABAbAbabAbABABaBABAbABABaBabaBaBABAbABABaBABAbAbabAbABAbAbabaBababAbABAbAbabAbABABaBABAbAbabAbABAbAbabaBababAbabaBaBABaBababAbabaBababAbABAbAbab').plot() # optional - sage.plot Graphics object consisting of 4 graphics primitives With gridlines:: - sage: P('ababababab').plot(gridlines=True) + sage: P('ababababab').plot(gridlines=True) # optional - sage.plot TESTS:: sage: P = WordPaths('abAB') - sage: P().plot() + sage: P().plot() # optional - sage.plot Graphics object consisting of 3 graphics primitives - sage: sum(map(plot,map(P,['a','A','b','B']))) + sage: sum(map(plot,map(P,['a','A','b','B']))) # optional - sage.plot Graphics object consisting of 12 graphics primitives """ G = Graphics() @@ -1614,44 +1614,44 @@ def animate(self): sage: P = WordPaths('abAB') sage: p = P('aaababbb') - sage: a = p.animate(); print(a) + sage: a = p.animate(); print(a) # optional - sage.plot Animation with 9 frames - sage: show(a) # long time # optional -- ImageMagick - sage: show(a, delay=35, iterations=3) # long time # optional -- ImageMagick + sage: show(a) # long time # optional -- ImageMagick sage.plot + sage: show(a, delay=35, iterations=3) # long time # optional -- ImageMagick sage.plot :: sage: P = WordPaths('abcdef',steps='triangle') sage: p = P('abcdef') - sage: a = p.animate(); print(a) + sage: a = p.animate(); print(a) # optional - sage.plot Animation with 8 frames - sage: show(a) # long time # optional -- ImageMagick + sage: show(a) # long time # optional -- ImageMagick sage.plot If the path is closed, the plain polygon is added at the end of the animation:: sage: P = WordPaths('abAB') sage: p = P('ababAbABABaB') - sage: a = p.animate(); print(a) + sage: a = p.animate(); print(a) # optional - sage.plot Animation with 14 frames - sage: show(a) # long time # optional -- ImageMagick + sage: show(a) # long time # optional -- ImageMagick sage.plot Another example illustrating a Fibonacci tile:: sage: w = words.fibonacci_tile(2) - sage: a = w.animate(); print(a) + sage: a = w.animate(); print(a) # optional - sage.plot Animation with 54 frames - sage: show(a) # long time # optional -- ImageMagick + sage: show(a) # long time # optional -- ImageMagick sage.plot The first 4 Fibonacci tiles in an animation:: - sage: a = words.fibonacci_tile(0).animate() - sage: b = words.fibonacci_tile(1).animate() - sage: c = words.fibonacci_tile(2).animate() - sage: d = words.fibonacci_tile(3).animate() - sage: print(a*b*c*d) + sage: a = words.fibonacci_tile(0).animate() # optional - sage.plot + sage: b = words.fibonacci_tile(1).animate() # optional - sage.plot + sage: c = words.fibonacci_tile(2).animate() # optional - sage.plot + sage: d = words.fibonacci_tile(3).animate() # optional - sage.plot + sage: print(a*b*c*d) # optional - sage.plot Animation with 296 frames - sage: show(a*b*c*d) # long time # optional -- ImageMagick + sage: show(a*b*c*d) # long time # optional -- ImageMagick sage.plot .. note:: @@ -1713,17 +1713,17 @@ def plot_directive_vector(self, options=dict(rgbcolor='blue')): Word Paths on the square grid sage: p = P('aaaccaccacacacaccccccbbdd'); p Path: aaaccaccacacacaccccccbbdd - sage: R = p.plot() + p.plot_directive_vector() - sage: R.axes(False) - sage: R.set_aspect_ratio(1) - sage: R.plot() + sage: R = p.plot() + p.plot_directive_vector() # optional - sage.plot + sage: R.axes(False) # optional - sage.plot + sage: R.set_aspect_ratio(1) # optional - sage.plot + sage: R.plot() # optional - sage.plot Graphics object consisting of 4 graphics primitives TESTS: A closed path:: - sage: P('acbd').plot_directive_vector() + sage: P('acbd').plot_directive_vector() # optional - sage.plot Graphics object consisting of 1 graphics primitive """ start = self.start_point() @@ -2020,12 +2020,12 @@ def plot(self, pathoptions=dict(rgbcolor='red',arrow_head=True,thickness=3), Word Paths over 2 steps sage: p = P('ababab'); p Path: ababab - sage: p.plot() + sage: p.plot() # optional - sage.plot Graphics3d Object sage: P = WordPaths('abcABC', steps='cube_grid') sage: p = P('abcabcAABBC') - sage: p.plot() + sage: p.plot() # optional - sage.plot Graphics3d Object """ diff --git a/src/sage/combinat/words/suffix_trees.py b/src/sage/combinat/words/suffix_trees.py index 9815645fbf8..c7ae4af2aaf 100644 --- a/src/sage/combinat/words/suffix_trees.py +++ b/src/sage/combinat/words/suffix_trees.py @@ -461,13 +461,13 @@ def plot(self, layout='tree', tree_root=0, tree_orientation='up', EXAMPLES:: sage: from sage.combinat.words.suffix_trees import SuffixTrie - sage: SuffixTrie(Word("cacao")).plot() + sage: SuffixTrie(Word("cacao")).plot() # optional - sage.plot Graphics object consisting of 38 graphics primitives TESTS:: sage: from sage.combinat.words.suffix_trees import SuffixTrie - sage: type(SuffixTrie(Word("cacao")).plot()) + sage: type(SuffixTrie(Word("cacao")).plot()) # optional - sage.plot <class 'sage.plot.graphics.Graphics'> """ tree = self.to_digraph() @@ -491,7 +491,7 @@ def show(self, *args, **kwds): sage: from sage.combinat.words.suffix_trees import SuffixTrie sage: w = Words("cao")("cac") sage: t = SuffixTrie(w) - sage: t.show() + sage: t.show() # optional - sage.plot """ self.plot(*args, **kwds).show() return @@ -865,17 +865,17 @@ def plot(self, word_labels=False, layout='tree', tree_root=0, EXAMPLES:: sage: from sage.combinat.words.suffix_trees import ImplicitSuffixTree - sage: ImplicitSuffixTree(Word('cacao')).plot(word_labels=True) + sage: ImplicitSuffixTree(Word('cacao')).plot(word_labels=True) # optional - sage.plot Graphics object consisting of 23 graphics primitives - sage: ImplicitSuffixTree(Word('cacao')).plot(word_labels=False) + sage: ImplicitSuffixTree(Word('cacao')).plot(word_labels=False) # optional - sage.plot Graphics object consisting of 23 graphics primitives TESTS:: sage: from sage.combinat.words.suffix_trees import ImplicitSuffixTree - sage: type(ImplicitSuffixTree(Word('cacao')).plot(word_labels=True)) + sage: type(ImplicitSuffixTree(Word('cacao')).plot(word_labels=True)) # optional - sage.plot <class 'sage.plot.graphics.Graphics'> - sage: type(ImplicitSuffixTree(Word('cacao')).plot(word_labels=False)) + sage: type(ImplicitSuffixTree(Word('cacao')).plot(word_labels=False)) # optional - sage.plot <class 'sage.plot.graphics.Graphics'> """ tree = self.to_digraph(word_labels=word_labels) @@ -904,8 +904,8 @@ def show(self, word_labels=None, *args, **kwds): sage: from sage.combinat.words.suffix_trees import ImplicitSuffixTree sage: w = Words("cao")("cacao") sage: t = ImplicitSuffixTree(w) - sage: t.show(word_labels=True) - sage: t.show(word_labels=False) + sage: t.show(word_labels=True) # optional - sage.plot + sage: t.show(word_labels=False) # optional - sage.plot """ self.plot(word_labels=word_labels, *args, **kwds).show() return diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index 3a0fb332d51..f046db3c46e 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -803,7 +803,7 @@ def CharacteristicSturmianWord(self, slope, alphabet=(0, 1), bits=None): The characteristic sturmian word of slope `(\sqrt{3}-1)/2`:: - sage: words.CharacteristicSturmianWord((sqrt(3)-1)/2) + sage: words.CharacteristicSturmianWord((sqrt(3)-1)/2) # optional - sage.symbolic word: 0100100101001001001010010010010100100101... The same word defined from the continued fraction expansion of @@ -846,17 +846,17 @@ def CharacteristicSturmianWord(self, slope, alphabet=(0, 1), bits=None): :: - sage: words.CharacteristicSturmianWord(1/golden_ratio^2) + sage: words.CharacteristicSturmianWord(1/golden_ratio^2) # optional - sage.symbolic word: 0100101001001010010100100101001001010010... - sage: _.length() + sage: _.length() # optional - sage.symbolic +Infinity :: - sage: a = words.LowerMechanicalWord(1/pi)[1:] - sage: b = words.UpperMechanicalWord(1/pi)[1:] - sage: c = words.CharacteristicSturmianWord(1/pi) - sage: n = 500; a[:n] == b[:n] == c[:n] + sage: a = words.LowerMechanicalWord(1/pi)[1:] # optional - sage.symbolic + sage: b = words.UpperMechanicalWord(1/pi)[1:] # optional - sage.symbolic + sage: c = words.CharacteristicSturmianWord(1/pi) # optional - sage.symbolic + sage: n = 500; a[:n] == b[:n] == c[:n] # optional - sage.symbolic True :: diff --git a/src/sage/combinat/yang_baxter_graph.py b/src/sage/combinat/yang_baxter_graph.py index 426095f6332..f5e5646c633 100644 --- a/src/sage/combinat/yang_baxter_graph.py +++ b/src/sage/combinat/yang_baxter_graph.py @@ -79,25 +79,25 @@ def YangBaxterGraph(partition=None, root=None, operators=None): sage: swappers = [SwapIncreasingOperator(i) for i in range(3)] sage: Y = YangBaxterGraph(root=(1,2,3,4), operators=swappers); Y Yang-Baxter graph with root vertex (1, 2, 3, 4) - sage: Y.plot() + sage: Y.plot() # optional - sage.plot Graphics object consisting of 97 graphics primitives The Cayley graph of a finite group can be realized as a Yang-Baxter graph:: sage: def left_multiplication_by(g): - ....: return lambda h : h*g + ....: return lambda h: h*g sage: G = CyclicPermutationGroup(4) sage: operators = [ left_multiplication_by(gen) for gen in G.gens() ] sage: Y = YangBaxterGraph(root=G.identity(), operators=operators); Y Yang-Baxter graph with root vertex () - sage: Y.plot(edge_labels=False) + sage: Y.plot(edge_labels=False) # optional - sage.plot Graphics object consisting of 9 graphics primitives sage: G = SymmetricGroup(4) sage: operators = [left_multiplication_by(gen) for gen in G.gens()] sage: Y = YangBaxterGraph(root=G.identity(), operators=operators); Y Yang-Baxter graph with root vertex () - sage: Y.plot(edge_labels=False) + sage: Y.plot(edge_labels=False) # optional - sage.plot Graphics object consisting of 96 graphics primitives AUTHORS: @@ -392,9 +392,9 @@ def plot(self, *args, **kwds): sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator sage: ops = [SwapIncreasingOperator(i) for i in range(4)] sage: Y = YangBaxterGraph(root=(1,0,2,1,0), operators=ops) - sage: Y.plot() + sage: Y.plot() # optional - sage.plot Graphics object consisting of 16 graphics primitives - sage: Y.plot(edge_labels=False) + sage: Y.plot(edge_labels=False) # optional - sage.plot Graphics object consisting of 11 graphics primitives """ if "edge_labels" not in kwds: From 0cff99e0c898aac6d665c141e55d2459541c4779 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Wed, 17 May 2023 15:45:12 -0700 Subject: [PATCH 059/228] sage.combinat: More # optional --- .../finite_dimensional_algebras_with_basis.py | 24 +- src/sage/categories/group_algebras.py | 2 +- src/sage/categories/homset.py | 6 +- src/sage/categories/map.pyx | 2 + src/sage/categories/primer.py | 20 +- src/sage/categories/pushout.py | 20 +- src/sage/categories/quotient_fields.py | 20 +- src/sage/categories/rings.py | 2 +- src/sage/categories/sets_cat.py | 2 +- src/sage/categories/simplicial_sets.py | 2 +- src/sage/combinat/cartesian_product.py | 24 +- src/sage/combinat/designs/block_design.py | 4 +- src/sage/combinat/diagram_algebras.py | 40 ++-- .../finite_state_machine_generators.py | 144 ++++++------ src/sage/combinat/free_module.py | 207 +++++++++--------- src/sage/combinat/integer_lists/invlex.pyx | 2 +- src/sage/combinat/integer_vector.py | 79 ++++--- src/sage/combinat/ranker.py | 2 +- src/sage/combinat/tutorial.py | 2 +- 19 files changed, 311 insertions(+), 293 deletions(-) diff --git a/src/sage/categories/finite_dimensional_algebras_with_basis.py b/src/sage/categories/finite_dimensional_algebras_with_basis.py index ec4a65b8db1..ce2bf641d7f 100644 --- a/src/sage/categories/finite_dimensional_algebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_algebras_with_basis.py @@ -482,8 +482,8 @@ def orthogonal_idempotents_central_mod_radical(self): sage: Z12 = Monoids().Finite().example(); Z12 An example of a finite multiplicative monoid: the integers modulo 12 sage: A = Z12.algebra(QQ) - sage: idempotents = A.orthogonal_idempotents_central_mod_radical() - sage: sorted(idempotents, key=str) + sage: idempotents = A.orthogonal_idempotents_central_mod_radical() # optional - sage.rings.number_field + sage: sorted(idempotents, key=str) # optional - sage.rings.number_field [-B[0] + 1/2*B[4] + 1/2*B[8], 1/2*B[4] - 1/2*B[8], 1/2*B[9] + 1/2*B[3] - B[0], @@ -493,26 +493,26 @@ def orthogonal_idempotents_central_mod_radical(self): 1/4*B[1] - 1/2*B[9] - 1/2*B[3] + 1/4*B[11] + 1/4*B[5] + 1/4*B[7] + B[0] - 1/2*B[4] - 1/2*B[8], 1/4*B[1] - 1/4*B[5] + 1/4*B[7] - 1/4*B[11] - 1/2*B[4] + 1/2*B[8], B[0]] - sage: sum(idempotents) == 1 + sage: sum(idempotents) == 1 # optional - sage.rings.number_field True - sage: all(e*e == e for e in idempotents) + sage: all(e*e == e for e in idempotents) # optional - sage.rings.number_field True - sage: all(e*f == 0 and f*e == 0 + sage: all(e*f == 0 and f*e == 0 # optional - sage.rings.number_field ....: for e in idempotents for f in idempotents if e != f) True This is best tested with:: - sage: A.is_identity_decomposition_into_orthogonal_idempotents(idempotents) + sage: A.is_identity_decomposition_into_orthogonal_idempotents(idempotents) # optional - sage.rings.number_field True We construct orthogonal idempotents for the algebra of the `0`-Hecke monoid:: - sage: from sage.monoids.hecke_monoid import HeckeMonoid - sage: A = HeckeMonoid(SymmetricGroup(4)).algebra(QQ) - sage: idempotents = A.orthogonal_idempotents_central_mod_radical() - sage: A.is_identity_decomposition_into_orthogonal_idempotents(idempotents) + sage: from sage.monoids.hecke_monoid import HeckeMonoid # optional - sage.groups + sage: A = HeckeMonoid(SymmetricGroup(4)).algebra(QQ) # optional - sage.groups + sage: idempotents = A.orthogonal_idempotents_central_mod_radical() # optional - sage.groups + sage: A.is_identity_decomposition_into_orthogonal_idempotents(idempotents) # optional - sage.groups True """ one = self.one() @@ -666,7 +666,7 @@ def cartan_invariants_matrix(self): sage: Z12 = Monoids().Finite().example(); Z12 An example of a finite multiplicative monoid: the integers modulo 12 sage: A = Z12.algebra(QQ) # optional - sage.modules - sage: A.cartan_invariants_matrix() # optional - sage.modules + sage: A.cartan_invariants_matrix() # optional - sage.modules sage.rings.number_fields [1 0 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0 0] [0 0 2 0 0 0 0 0 0] @@ -681,7 +681,7 @@ def cartan_invariants_matrix(self): sage: from sage.monoids.hecke_monoid import HeckeMonoid # optional - sage.groups sage.modules sage: A = HeckeMonoid(SymmetricGroup(4)).algebra(QQ) # optional - sage.groups sage.modules - sage: A.cartan_invariants_matrix() # optional - sage.groups sage.modules + sage: A.cartan_invariants_matrix() # optional - sage.groups sage.modules sage.rings.number_field [1 0 0 0 0 0 0 0] [0 2 1 0 1 1 0 0] [0 1 1 0 1 0 0 0] diff --git a/src/sage/categories/group_algebras.py b/src/sage/categories/group_algebras.py index 1bc40687c4f..36c7e069f34 100644 --- a/src/sage/categories/group_algebras.py +++ b/src/sage/categories/group_algebras.py @@ -315,7 +315,7 @@ def is_integral_domain(self, proof=True): sage: S2 = SymmetricGroup(2) # optional - sage.groups sage: GroupAlgebra(S2).is_integral_domain() # optional - sage.groups sage.modules False - sage: S1 = SymmetricGroup(1) + sage: S1 = SymmetricGroup(1) # optional - sage.groups sage: GroupAlgebra(S1).is_integral_domain() # optional - sage.groups sage.modules True sage: GroupAlgebra(S1, IntegerModRing(4)).is_integral_domain() # optional - sage.groups sage.modules diff --git a/src/sage/categories/homset.py b/src/sage/categories/homset.py index 6554c895ff4..a5a438f8727 100644 --- a/src/sage/categories/homset.py +++ b/src/sage/categories/homset.py @@ -584,10 +584,10 @@ class Homset(Set_generic): Homsets of unique parents are unique as well:: - sage: H = End(AffineSpace(2, names='x,y')) - sage: loads(dumps(AffineSpace(2, names='x,y'))) is AffineSpace(2, names='x,y') + sage: H = End(AffineSpace(2, names='x,y')) # optional - sage.modules + sage: loads(dumps(AffineSpace(2, names='x,y'))) is AffineSpace(2, names='x,y') # optional - sage.modules True - sage: loads(dumps(H)) is H + sage: loads(dumps(H)) is H # optional - sage.modules True Conversely, homsets of non-unique parents are non-unique:: diff --git a/src/sage/categories/map.pyx b/src/sage/categories/map.pyx index 39d37acc2ae..50853348b53 100644 --- a/src/sage/categories/map.pyx +++ b/src/sage/categories/map.pyx @@ -279,6 +279,7 @@ cdef class Map(Element): sage: import gc sage: _ = gc.collect() sage: C = Q.__class__.__base__ # optional - sage.rings.number_field + sage: x = None sage: numberQuadFields = len([x for x in gc.get_objects() # optional - sage.rings.number_field ....: if isinstance(x, C)]) sage: del Q, x # optional - sage.rings.number_field @@ -344,6 +345,7 @@ cdef class Map(Element): sage: import gc sage: _ = gc.collect() sage: C = Q.__class__.__base__ # optional - sage.rings.number_field + sage: x = None sage: numberQuadFields = len([x for x in gc.get_objects() # optional - sage.rings.number_field ....: if isinstance(x, C)]) sage: del Q, x # optional - sage.rings.number_field diff --git a/src/sage/categories/primer.py b/src/sage/categories/primer.py index 84ab37f34b7..8b71d5c3a94 100644 --- a/src/sage/categories/primer.py +++ b/src/sage/categories/primer.py @@ -82,8 +82,8 @@ 6 sage: A = random_matrix(ZZ, 6, 3, x=7) # optional - sage.modules - sage: L = LatticePolytope(A.rows()) # optional - sage.geometry.polyhedron - sage: L.npoints() # oops! # random # optional - sage.geometry.polyhedron + sage: L = LatticePolytope(A.rows()) # optional - sage.geometry.polyhedron sage.modules + sage: L.npoints() # oops! # random # optional - sage.geometry.polyhedron sage.modules 37 - How to ensure robustness? @@ -415,16 +415,16 @@ class implements: 6*(x + 1)^2 sage: R.<x> = PolynomialRing(QQ, sparse=True) - sage: pQ = R ( p ) - sage: type(pQ) + sage: pQ = R(p) # optional - sage.symbolic + sage: type(pQ) # optional - sage.symbolic <class 'sage.rings.polynomial.polynomial_ring.PolynomialRing_field_with_category.element_class'> - sage: pQ.factor() + sage: pQ.factor() # optional - sage.symbolic (6) * (x + 1)^2 - sage: pZ = ZZ['x'] ( p ) - sage: type(pZ) + sage: pZ = ZZ['x'](p) # optional - sage.symbolic + sage: type(pZ) # optional - sage.symbolic <class 'sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint'> - sage: pZ.factor() + sage: pZ.factor() # optional - sage.symbolic 2 * 3 * (x + 1)^2 Factoring integers, expressions, or polynomials are distinct tasks, @@ -444,9 +444,9 @@ class implements: sage: i._pow_.__module__ # not tested (Issue #24275) 'sage.categories.semigroups' - sage: pQ._mul_.__module__ + sage: pQ._mul_.__module__ # optional - sage.symbolic 'sage.rings.polynomial.polynomial_element_generic' - sage: pQ._pow_.__module__ # not tested (Issue #24275) + sage: pQ._pow_.__module__ # not tested (Issue #24275) # optional - sage.symbolic 'sage.categories.semigroups' We see that integers and polynomials have each their own diff --git a/src/sage/categories/pushout.py b/src/sage/categories/pushout.py index 69b936bb3ff..7f0a20bbd0a 100644 --- a/src/sage/categories/pushout.py +++ b/src/sage/categories/pushout.py @@ -1758,10 +1758,11 @@ def __init__(self, var, multi_variate=False): sage: F2 = LaurentPolynomialFunctor('s', multi_variate=True) sage: F3 = LaurentPolynomialFunctor(['s','t']) sage: F1(F2(QQ)) - Univariate Laurent Polynomial Ring in t over Univariate Laurent Polynomial Ring in s over Rational Field - sage: F2(F1(QQ)) + Univariate Laurent Polynomial Ring in t over + Univariate Laurent Polynomial Ring in s over Rational Field + sage: F2(F1(QQ)) # optional - sage.modules Multivariate Laurent Polynomial Ring in t, s over Rational Field - sage: F3(QQ) + sage: F3(QQ) # optional - sage.modules Multivariate Laurent Polynomial Ring in s, t over Rational Field """ @@ -1782,10 +1783,11 @@ def _apply_functor(self, R): sage: F2 = LaurentPolynomialFunctor('s', multi_variate=True) sage: F3 = LaurentPolynomialFunctor(['s','t']) sage: F1(F2(QQ)) # indirect doctest - Univariate Laurent Polynomial Ring in t over Univariate Laurent Polynomial Ring in s over Rational Field - sage: F2(F1(QQ)) + Univariate Laurent Polynomial Ring in t over + Univariate Laurent Polynomial Ring in s over Rational Field + sage: F2(F1(QQ)) # optional - sage.modules Multivariate Laurent Polynomial Ring in t, s over Rational Field - sage: F3(QQ) + sage: F3(QQ) # optional - sage.modules Multivariate Laurent Polynomial Ring in s, t over Rational Field """ @@ -3945,7 +3947,7 @@ def __init__(self, box): sage: from sage.categories.pushout import BlackBoxConstructionFunctor sage: FG = BlackBoxConstructionFunctor(gap) # optional - sage.libs.gap sage: FM = BlackBoxConstructionFunctor(maxima) # optional - sage.symbolic - sage: FM == FG # optional - sage.symbolic + sage: FM == FG # optional - sage.libs.gap sage.symbolic False sage: FM == loads(dumps(FM)) # optional - sage.symbolic True @@ -3977,7 +3979,7 @@ def __eq__(self, other): sage: from sage.categories.pushout import BlackBoxConstructionFunctor sage: FG = BlackBoxConstructionFunctor(gap) # optional - sage.libs.gap sage: FM = BlackBoxConstructionFunctor(maxima) # optional - sage.symbolic - sage: FM == FG # indirect doctest # optional - sage.symbolic + sage: FM == FG # indirect doctest # optional - sage.libs.gap sage.symbolic False sage: FM == loads(dumps(FM)) # optional - sage.symbolic True @@ -3996,7 +3998,7 @@ def __ne__(self, other): sage: from sage.categories.pushout import BlackBoxConstructionFunctor sage: FG = BlackBoxConstructionFunctor(gap) # optional - sage.libs.gap sage: FM = BlackBoxConstructionFunctor(maxima) # optional - sage.symbolic - sage: FM != FG # indirect doctest # optional - sage.symbolic + sage: FM != FG # indirect doctest # optional - sage.libs.gap sage.symbolic True sage: FM != loads(dumps(FM)) # optional - sage.symbolic False diff --git a/src/sage/categories/quotient_fields.py b/src/sage/categories/quotient_fields.py index c62c79ee11f..181cd0ff611 100644 --- a/src/sage/categories/quotient_fields.py +++ b/src/sage/categories/quotient_fields.py @@ -408,9 +408,9 @@ def partial_fraction_decomposition(self, decompose_powers=True): We can decompose over a given algebraic extension:: - sage: R.<x> = QQ[sqrt(2)][] # optional - sage.rings.number_field - sage: r = 1/(x^4+1) # optional - sage.rings.number_field - sage: r.partial_fraction_decomposition() # optional - sage.rings.number_field + sage: R.<x> = QQ[sqrt(2)][] # optional - sage.rings.number_field sage.symbolic + sage: r = 1/(x^4+1) # optional - sage.rings.number_field sage.symbolic + sage: r.partial_fraction_decomposition() # optional - sage.rings.number_field sage.symbolic (0, [(-1/4*sqrt2*x + 1/2)/(x^2 - sqrt2*x + 1), (1/4*sqrt2*x + 1/2)/(x^2 + sqrt2*x + 1)]) @@ -425,8 +425,7 @@ def partial_fraction_decomposition(self, decompose_powers=True): sage: R.<x> = QQ[] sage: r = 1/(x^4+2) - sage: N = r.denominator().splitting_field('a') # optional - sage.rings.number_field - sage: N # optional - sage.rings.number_field + sage: N = r.denominator().splitting_field('a'); N # optional - sage.rings.number_field Number Field in a with defining polynomial x^8 - 8*x^6 + 28*x^4 + 16*x^2 + 36 sage: R1.<x1> = N[] # optional - sage.rings.number_field sage: r1 = 1/(x1^4+2) # optional - sage.rings.number_field @@ -452,11 +451,14 @@ def partial_fraction_decomposition(self, decompose_powers=True): sage: R.<x> = RealField(20)[] sage: q = 1/(x^2 + x + 2)^2 + 1/(x-1); q - (x^4 + 2.0000*x^3 + 5.0000*x^2 + 5.0000*x + 3.0000)/(x^5 + x^4 + 3.0000*x^3 - x^2 - 4.0000) + (x^4 + 2.0000*x^3 + + 5.0000*x^2 + 5.0000*x + 3.0000)/(x^5 + x^4 + 3.0000*x^3 - x^2 - 4.0000) sage: whole, parts = q.partial_fraction_decomposition(); parts # optional - sage.rings.number_field - [1.0000/(x - 1.0000), 1.0000/(x^4 + 2.0000*x^3 + 5.0000*x^2 + 4.0000*x + 4.0000)] - sage: sum(parts) - (x^4 + 2.0000*x^3 + 5.0000*x^2 + 5.0000*x + 3.0000)/(x^5 + x^4 + 3.0000*x^3 - x^2 - 4.0000) + [1.0000/(x - 1.0000), + 1.0000/(x^4 + 2.0000*x^3 + 5.0000*x^2 + 4.0000*x + 4.0000)] + sage: sum(parts) # optional - sage.rings.number_field + (x^4 + 2.0000*x^3 + + 5.0000*x^2 + 5.0000*x + 3.0000)/(x^5 + x^4 + 3.0000*x^3 - x^2 - 4.0000) TESTS: diff --git a/src/sage/categories/rings.py b/src/sage/categories/rings.py index 07ffd95d02b..1449333d973 100644 --- a/src/sage/categories/rings.py +++ b/src/sage/categories/rings.py @@ -218,7 +218,7 @@ def extend_to_fraction_field(self): Ring endomorphism of Univariate Polynomial Ring in x over Rational Field Defn: x |--> x + 1 - sage: g = f.extend_to_fraction_field(); g + sage: g = f.extend_to_fraction_field(); g # optional - sage.libs.singular Ring endomorphism of Fraction Field of Univariate Polynomial Ring in x over Rational Field Defn: x |--> x + 1 diff --git a/src/sage/categories/sets_cat.py b/src/sage/categories/sets_cat.py index 069ebc5337c..c2d87e43b0c 100644 --- a/src/sage/categories/sets_cat.py +++ b/src/sage/categories/sets_cat.py @@ -2796,7 +2796,7 @@ def _register_realization(self, realization): over Univariate Polynomial Ring in x over Rational Field sage: class ANewRealizationOfA(CombinatorialFreeModule): # optional - sage.combinat sage.modules ....: pass - sage: category = A.Realizations() & Algebras(QQ[x]).WithBasis() # optional - sage.combinat sage.modules + sage: category = A.Realizations() & Algebras(QQ['x']).WithBasis() # optional - sage.combinat sage.modules sage: R = ANewRealizationOfA(A.base_ring(), A.F().basis().keys(), # optional - sage.combinat sage.modules ....: category=category) sage: R in A.realizations() # indirect doctest # optional - sage.combinat sage.modules diff --git a/src/sage/categories/simplicial_sets.py b/src/sage/categories/simplicial_sets.py index 952053b907d..43a13dfe473 100644 --- a/src/sage/categories/simplicial_sets.py +++ b/src/sage/categories/simplicial_sets.py @@ -560,7 +560,7 @@ def universal_cover(self): (f * f, e): ((f, 1), s_0 (1, e), (f, e)), (f * f * f, 1): ((f * f, e), s_0 (f, 1), s_1 (f, 1), (f * f, 1)), (f * f * f, e): ((f * f, 1), s_0 (f, e), s_1 (f, e), (f * f, e))} - sage: C.fundamental_group() + sage: C.fundamental_group() # optional - sage.groups Finitely presented group < | > """ return self.universal_cover_map().domain() diff --git a/src/sage/combinat/cartesian_product.py b/src/sage/combinat/cartesian_product.py index b15185685c7..7ab49439557 100644 --- a/src/sage/combinat/cartesian_product.py +++ b/src/sage/combinat/cartesian_product.py @@ -51,27 +51,27 @@ class for ``cartesian_product``; sage: F1 = ['a', 'b'] sage: F2 = [1, 2, 3, 4] - sage: F3 = Permutations(3) + sage: F3 = Permutations(3) # optional - sage.combinat sage: from sage.combinat.cartesian_product import CartesianProduct_iters - sage: C = CartesianProduct_iters(F1, F2, F3) - sage: c = cartesian_product([F1, F2, F3]) + sage: C = CartesianProduct_iters(F1, F2, F3) # optional - sage.combinat + sage: c = cartesian_product([F1, F2, F3]) # optional - sage.combinat - sage: type(C.an_element()) + sage: type(C.an_element()) # optional - sage.combinat <class 'list'> - sage: type(c.an_element()) + sage: type(c.an_element()) # optional - sage.combinat <class 'sage.sets.cartesian_product.CartesianProduct_with_category.element_class'> - sage: l = ['a', 1, Permutation([3,2,1])] - sage: l in C + sage: l = ['a', 1, Permutation([3,2,1])] # optional - sage.combinat + sage: l in C # optional - sage.combinat True - sage: l in c + sage: l in c # optional - sage.combinat False - sage: elt = c(l) - sage: elt + sage: elt = c(l) # optional - sage.combinat + sage: elt # optional - sage.combinat ('a', 1, [3, 2, 1]) - sage: elt in c + sage: elt in c # optional - sage.combinat True - sage: elt.parent() is c + sage: elt.parent() is c # optional - sage.combinat True """ diff --git a/src/sage/combinat/designs/block_design.py b/src/sage/combinat/designs/block_design.py index cb81f997f3d..1d189fdd409 100644 --- a/src/sage/combinat/designs/block_design.py +++ b/src/sage/combinat/designs/block_design.py @@ -401,7 +401,7 @@ def q3_minus_one_matrix(K): sage: from sage.combinat.designs.block_design import q3_minus_one_matrix sage: m = q3_minus_one_matrix(GF(3)) - sage: m.multiplicative_order() == 3**3 - 1 + sage: m.multiplicative_order() == 3**3 - 1 # optional - sage.symbolic True sage: m = q3_minus_one_matrix(GF(4, 'a')) # optional - sage.symbolic @@ -409,7 +409,7 @@ def q3_minus_one_matrix(K): True sage: m = q3_minus_one_matrix(GF(5)) - sage: m.multiplicative_order() == 5**3 - 1 + sage: m.multiplicative_order() == 5**3 - 1 # optional - sage.symbolic True sage: m = q3_minus_one_matrix(GF(9, 'a')) # optional - sage.symbolic diff --git a/src/sage/combinat/diagram_algebras.py b/src/sage/combinat/diagram_algebras.py index 4909dc33f09..6dcba8094ec 100644 --- a/src/sage/combinat/diagram_algebras.py +++ b/src/sage/combinat/diagram_algebras.py @@ -2053,9 +2053,9 @@ def order(self): EXAMPLES:: - sage: q = var('q') - sage: PA = PartitionAlgebra(2, q) - sage: PA.order() + sage: q = var('q') # optional - sage.symbolic + sage: PA = PartitionAlgebra(2, q) # optional - sage.symbolic + sage: PA.order() # optional - sage.symbolic 2 """ return self._k @@ -2412,23 +2412,24 @@ class PartitionAlgebra(DiagramBasis, UnitDiagramMixin): :: - sage: q = var('q') - sage: PA = PartitionAlgebra(2, q); PA + sage: q = var('q') # optional - sage.symbolic + sage: PA = PartitionAlgebra(2, q); PA # optional - sage.symbolic Partition Algebra of rank 2 with parameter q over Symbolic Ring - sage: PA([[1,2],[-2,-1]])^2 == q*PA([[1,2],[-2,-1]]) + sage: PA([[1,2],[-2,-1]])^2 == q*PA([[1,2],[-2,-1]]) # optional - sage.symbolic True - sage: (PA([[2, -2], [1, -1]]) - 2*PA([[-2, -1], [1, 2]]))^2 == (4*q-4)*PA([[1, 2], [-2, -1]]) + PA([[2, -2], [1, -1]]) + sage: ((PA([[2, -2], [1, -1]]) - 2*PA([[-2, -1], [1, 2]]))^2 # optional - sage.symbolic + ....: == (4*q-4)*PA([[1, 2], [-2, -1]]) + PA([[2, -2], [1, -1]])) True The identity element of the partition algebra is the set partition `\{\{1,-1\}, \{2,-2\}, \ldots, \{k,-k\}\}`:: - sage: P = PA.basis().list() - sage: PA.one() + sage: P = PA.basis().list() # optional - sage.symbolic + sage: PA.one() # optional - sage.symbolic P{{-2, 2}, {-1, 1}} - sage: PA.one() * P[7] == P[7] + sage: PA.one() * P[7] == P[7] # optional - sage.symbolic True - sage: P[7] * PA.one() == P[7] + sage: P[7] * PA.one() == P[7] # optional - sage.symbolic True We now give some further examples of the use of the other arguments. @@ -2445,21 +2446,22 @@ class PartitionAlgebra(DiagramBasis, UnitDiagramMixin): sage: PA = PartitionAlgebra(2, 5, base_ring=ZZ, prefix='B') sage: PA Partition Algebra of rank 2 with parameter 5 over Integer Ring - sage: (PA([[2, -2], [1, -1]]) - 2*PA([[-2, -1], [1, 2]]))^2 == 16*PA([[-2, -1], [1, 2]]) + PA([[2, -2], [1, -1]]) + sage: ((PA([[2, -2], [1, -1]]) - 2*PA([[-2, -1], [1, 2]]))^2 + ....: == 16*PA([[-2, -1], [1, 2]]) + PA([[2, -2], [1, -1]])) True Symmetric group algebra elements and elements from other subalgebras of the partition algebra (e.g., ``BrauerAlgebra`` and ``TemperleyLiebAlgebra``) can also be coerced into the partition algebra:: - sage: S = SymmetricGroupAlgebra(SR, 2) - sage: B = BrauerAlgebra(2, x, SR) - sage: A = PartitionAlgebra(2, x, SR) - sage: S([2,1])*A([[1,-1],[2,-2]]) + sage: S = SymmetricGroupAlgebra(SR, 2) # optional - sage.symbolic + sage: B = BrauerAlgebra(2, x, SR) # optional - sage.symbolic + sage: A = PartitionAlgebra(2, x, SR) # optional - sage.symbolic + sage: S([2,1]) * A([[1,-1],[2,-2]]) # optional - sage.symbolic P{{-2, 1}, {-1, 2}} - sage: B([[-1,-2],[2,1]]) * A([[1],[-1],[2,-2]]) + sage: B([[-1,-2],[2,1]]) * A([[1],[-1],[2,-2]]) # optional - sage.symbolic P{{-2}, {-1}, {1, 2}} - sage: A([[1],[-1],[2,-2]]) * B([[-1,-2],[2,1]]) + sage: A([[1],[-1],[2,-2]]) * B([[-1,-2],[2,1]]) # optional - sage.symbolic P{{-2, -1}, {1}, {2}} The same is true if the elements come from a subalgebra of a partition @@ -2470,7 +2472,7 @@ class PartitionAlgebra(DiagramBasis, UnitDiagramMixin): sage: S = SymmetricGroupAlgebra(ZZ, 2) sage: B = BrauerAlgebra(2, q, ZZ[q]) sage: A = PartitionAlgebra(3, q, R) - sage: S([2,1])*A([[1,-1],[2,-3],[3,-2]]) + sage: S([2,1]) * A([[1,-1],[2,-3],[3,-2]]) P{{-3, 1}, {-2, 3}, {-1, 2}} sage: A(B([[-1,-2],[2,1]])) P{{-3, 3}, {-2, -1}, {1, 2}} diff --git a/src/sage/combinat/finite_state_machine_generators.py b/src/sage/combinat/finite_state_machine_generators.py index ed5cca2588b..b5b8abbbd9e 100644 --- a/src/sage/combinat/finite_state_machine_generators.py +++ b/src/sage/combinat/finite_state_machine_generators.py @@ -1079,15 +1079,15 @@ def _parse_recursion_equation_(self, equation, base, function, var, EXAMPLES:: - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: transducers._parse_recursion_equation_( + sage: transducers._parse_recursion_equation_( # optional - sage.symbolic ....: f(8*n + 7) == f(2*n + 3) + 5, ....: 2, f, n) RecursionRule(K=3, r=7, k=1, s=3, t=[5]) - sage: transducers._parse_recursion_equation_( + sage: transducers._parse_recursion_equation_( # optional - sage.symbolic ....: f(42) == 5, ....: 2, f, n) {42: [5]} @@ -1096,14 +1096,14 @@ def _parse_recursion_equation_(self, equation, base, function, var, The following tests check that the equations are well-formed:: - sage: transducers._parse_recursion_equation_(f(4*n + 1), 2, f, n) + sage: transducers._parse_recursion_equation_(f(4*n + 1), 2, f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: f(4*n + 1) is not an equation with ==. :: - sage: transducers._parse_recursion_equation_(f(n) + 1 == f(2*n), + sage: transducers._parse_recursion_equation_(f(n) + 1 == f(2*n), # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1111,7 +1111,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n, 5) == 3, + sage: transducers._parse_recursion_equation_(f(2*n, 5) == 3, # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1119,7 +1119,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(1/n) == f(n) + 3, + sage: transducers._parse_recursion_equation_(f(1/n) == f(n) + 3, # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1127,7 +1127,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(n^2 + 5) == 3, + sage: transducers._parse_recursion_equation_(f(n^2 + 5) == 3, # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1135,7 +1135,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(3*n + 5) == f(n) + 7, + sage: transducers._parse_recursion_equation_(f(3*n + 5) == f(n) + 7, # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1143,7 +1143,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(n + 5) == f(n) + 7, + sage: transducers._parse_recursion_equation_(f(n + 5) == f(n) + 7, # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1151,7 +1151,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_( + sage: transducers._parse_recursion_equation_( # optional - sage.symbolic ....: f(2*n + 1) == f(n + 1) + f(n) + 2, ....: 2, f, n) Traceback (most recent call last): @@ -1161,7 +1161,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == sin(n) + 2, + sage: transducers._parse_recursion_equation_(f(2*n + 1) == sin(n) + 2, # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1170,7 +1170,8 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(n) + n + 2, + sage: transducers._parse_recursion_equation_( # optional - sage.symbolic + ....: f(2*n + 1) == f(n) + n + 2, ....: 2, f, n) Traceback (most recent call last): ... @@ -1178,7 +1179,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == sin(n), + sage: transducers._parse_recursion_equation_(f(2*n + 1) == sin(n), # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1186,7 +1187,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(n, 2), + sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(n, 2), # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1194,7 +1195,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(1/n), + sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(1/n), # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1202,7 +1203,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(n^2 + 5), + sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(n^2 + 5), # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1210,7 +1211,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(3*n + 5), + sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(3*n + 5), # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1218,7 +1219,8 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == f((1/2)*n + 5), + sage: transducers._parse_recursion_equation_( # optional - sage.symbolic + ....: f(2*n + 1) == f((1/2)*n + 5), ....: QQ(2), f, n) Traceback (most recent call last): ... @@ -1226,7 +1228,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(2*n + 5), + sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(2*n + 5), # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1432,17 +1434,17 @@ def Recursion(self, recursions, base, function=None, var=None, - The following example computes the Hamming weight of the ternary expansion of integers. :: - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.symbolic ....: f(3*n + 1) == f(n) + 1, ....: f(3*n + 2) == f(n) + 1, ....: f(3*n) == f(n), ....: f(0) == 0], ....: 3, f, n) - sage: T.transitions() + sage: T.transitions() # optional - sage.symbolic [Transition from (0, 0) to (0, 0): 0|-, Transition from (0, 0) to (0, 0): 1|1, Transition from (0, 0) to (0, 0): 2|1] @@ -1450,13 +1452,13 @@ def Recursion(self, recursions, base, function=None, var=None, To illustrate what this transducer does, we consider the example of `n=601`:: - sage: ternary_expansion = 601.digits(base=3) - sage: ternary_expansion + sage: ternary_expansion = 601.digits(base=3) # optional - sage.symbolic + sage: ternary_expansion # optional - sage.symbolic [1, 2, 0, 1, 1, 2] - sage: weight_sequence = T(ternary_expansion) - sage: weight_sequence + sage: weight_sequence = T(ternary_expansion) # optional - sage.symbolic + sage: weight_sequence # optional - sage.symbolic [1, 1, 1, 1, 1] - sage: sum(weight_sequence) + sage: sum(weight_sequence) # optional - sage.symbolic 5 Note that the digit zero does not show up in the output because @@ -1466,24 +1468,24 @@ def Recursion(self, recursions, base, function=None, var=None, - The following example computes the Hamming weight of the non-adjacent form, cf. the :wikipedia:`Non-adjacent_form`. :: - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.symbolic ....: f(4*n + 1) == f(n) + 1, ....: f(4*n - 1) == f(n) + 1, ....: f(2*n) == f(n), ....: f(0) == 0], ....: 2, f, n) - sage: T.transitions() + sage: T.transitions() # optional - sage.symbolic [Transition from (0, 0) to (0, 0): 0|-, Transition from (0, 0) to (1, 1): 1|-, Transition from (1, 1) to (0, 0): 0|1, Transition from (1, 1) to (1, 0): 1|1, Transition from (1, 0) to (1, 1): 0|-, Transition from (1, 0) to (1, 0): 1|-] - sage: [(s.label(), s.final_word_out) + sage: [(s.label(), s.final_word_out) # optional - sage.symbolic ....: for s in T.iter_final_states()] [((0, 0), []), ((1, 1), [1]), @@ -1505,9 +1507,9 @@ def Recursion(self, recursions, base, function=None, var=None, sage: binary_expansion = 29.digits(base=2) sage: binary_expansion [1, 0, 1, 1, 1] - sage: T(binary_expansion) + sage: T(binary_expansion) # optional - sage.symbolic [1, 1, 1] - sage: sum(T(binary_expansion)) + sage: sum(T(binary_expansion)) # optional - sage.symbolic 3 Indeed, the given non-adjacent form has three non-zero @@ -1533,11 +1535,11 @@ def Recursion(self, recursions, base, function=None, var=None, the point of view of this method---is a contradicting recursion. We override this by the parameter ``is_zero``. :: - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: function('f w') + sage: function('f w') # optional - sage.symbolic (f, w) - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.symbolic ....: f(2*n) == f(n) + w(0), ....: f(4*n + 1) == f(n) + w(1, 0), ....: f(4*n - 1) == f(n) + w(-1, 0), @@ -1545,14 +1547,14 @@ def Recursion(self, recursions, base, function=None, var=None, ....: 2, f, n, ....: word_function=w, ....: is_zero=lambda x: sum(x).is_zero()) - sage: T.transitions() + sage: T.transitions() # optional - sage.symbolic [Transition from (0, 0) to (0, 0): 0|0, Transition from (0, 0) to (1, 1): 1|-, Transition from (1, 1) to (0, 0): 0|1,0, Transition from (1, 1) to (1, 0): 1|-1,0, Transition from (1, 0) to (1, 1): 0|-, Transition from (1, 0) to (1, 0): 1|0] - sage: for s in T.iter_states(): + sage: for s in T.iter_states(): # optional - sage.symbolic ....: print("{} {}".format(s, s.final_word_out)) (0, 0) [] (1, 1) [1, 0] @@ -1560,7 +1562,7 @@ def Recursion(self, recursions, base, function=None, var=None, We again consider the example of `n=29`:: - sage: T(29.digits(base=2)) + sage: T(29.digits(base=2)) # optional - sage.symbolic [1, 0, -1, 0, 0, 1, 0] The same transducer can also be entered bypassing the @@ -1574,22 +1576,22 @@ def Recursion(self, recursions, base, function=None, var=None, ....: (0, [])], ....: 2, ....: is_zero=lambda x: sum(x).is_zero()) - sage: TR == T + sage: TR == T # optional - sage.symbolic True - Here is an artificial example where some of the `s` are negative:: - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.symbolic ....: f(2*n + 1) == f(n-1) + 1, ....: f(2*n) == f(n), ....: f(1) == 1, ....: f(0) == 0], 2, f, n) - sage: T.transitions() + sage: T.transitions() # optional - sage.symbolic [Transition from (0, 0) to (0, 0): 0|-, Transition from (0, 0) to (1, 1): 1|-, Transition from (1, 1) to (-1, 1): 0|1, @@ -1600,7 +1602,7 @@ def Recursion(self, recursions, base, function=None, var=None, Transition from (-1, 2) to (0, 0): 1|1, Transition from (1, 2) to (-1, 2): 0|1, Transition from (1, 2) to (1, 2): 1|1] - sage: [(s.label(), s.final_word_out) + sage: [(s.label(), s.final_word_out) # optional - sage.symbolic ....: for s in T.iter_final_states()] [((0, 0), []), ((1, 1), [1]), @@ -1611,7 +1613,7 @@ def Recursion(self, recursions, base, function=None, var=None, - Abelian complexity of the paperfolding sequence (cf. [HKP2015]_, Example 2.8):: - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.symbolic ....: f(4*n) == f(2*n), ....: f(4*n+2) == f(2*n+1)+1, ....: f(16*n+1) == f(8*n+1), @@ -1621,7 +1623,7 @@ def Recursion(self, recursions, base, function=None, var=None, ....: f(1) == 2, f(0) == 0] ....: + [f(16*n+jj) == f(2*n+1)+2 for jj in [3,7,9,13]], ....: 2, f, n) - sage: T.transitions() + sage: T.transitions() # optional - sage.symbolic [Transition from (0, 0) to (0, 1): 0|-, Transition from (0, 0) to (1, 1): 1|-, Transition from (0, 1) to (0, 1): 0|-, @@ -1642,7 +1644,7 @@ def Recursion(self, recursions, base, function=None, var=None, Transition from (7, 3) to (2, 1): 1|1, Transition from (2, 1) to (1, 1): 0|1, Transition from (2, 1) to (2, 1): 1|-] - sage: for s in T.iter_states(): + sage: for s in T.iter_states(): # optional - sage.symbolic ....: print("{} {}".format(s, s.final_word_out)) (0, 0) [] (0, 1) [] @@ -1654,52 +1656,52 @@ def Recursion(self, recursions, base, function=None, var=None, (3, 3) [2, 2] (7, 3) [2, 2] (2, 1) [1, 2] - sage: list(sum(T(n.bits())) for n in srange(1, 21)) + sage: list(sum(T(n.bits())) for n in srange(1, 21)) # optional - sage.symbolic [2, 3, 4, 3, 4, 5, 4, 3, 4, 5, 6, 5, 4, 5, 4, 3, 4, 5, 6, 5] - We now demonstrate the use of the ``output_rings`` parameter. If no ``output_rings`` are specified, the output labels are converted into ``ZZ``:: - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.symbolic ....: f(2*n + 1) == f(n) + 1, ....: f(2*n) == f(n), ....: f(0) == 2], ....: 2, f, n) - sage: for t in T.transitions(): + sage: for t in T.transitions(): # optional - sage.symbolic ....: print([x.parent() for x in t.word_out]) [] [Integer Ring] - sage: [x.parent() for x in T.states()[0].final_word_out] + sage: [x.parent() for x in T.states()[0].final_word_out] # optional - sage.symbolic [Integer Ring] In contrast, if ``output_rings`` is set to the empty list, the results are not converted:: - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.symbolic ....: f(2*n + 1) == f(n) + 1, ....: f(2*n) == f(n), ....: f(0) == 2], ....: 2, f, n, output_rings=[]) - sage: for t in T.transitions(): + sage: for t in T.transitions(): # optional - sage.symbolic ....: print([x.parent() for x in t.word_out]) [] [Symbolic Ring] - sage: [x.parent() for x in T.states()[0].final_word_out] + sage: [x.parent() for x in T.states()[0].final_word_out] # optional - sage.symbolic [Symbolic Ring] Finally, we use a somewhat questionable conversion:: - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.rings.finite_rings sage.symbolic ....: f(2*n + 1) == f(n) + 1, ....: f(2*n) == f(n), ....: f(0) == 0], ....: 2, f, n, output_rings=[GF(5)]) - sage: for t in T.transitions(): + sage: for t in T.transitions(): # optional - sage.rings.finite_rings sage.symbolic ....: print([x.parent() for x in t.word_out]) [] [Finite Field of size 5] @@ -1726,11 +1728,11 @@ def Recursion(self, recursions, base, function=None, var=None, The following tests fail due to missing or superfluous recursions or initial conditions. :: - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: transducers.Recursion([f(2*n) == f(n)], + sage: transducers.Recursion([f(2*n) == f(n)], # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1739,9 +1741,9 @@ def Recursion(self, recursions, base, function=None, var=None, :: - sage: transducers.Recursion([f(2*n + 1) == f(n), + sage: transducers.Recursion([f(2*n + 1) == f(n), # optional - sage.symbolic ....: f(4*n) == f(2*n) + 1, - ....: f(2*n) == f(n) +1], + ....: f(2*n) == f(n) + 1], ....: 2, f, n) Traceback (most recent call last): ... @@ -1749,7 +1751,7 @@ def Recursion(self, recursions, base, function=None, var=None, :: - sage: transducers.Recursion([f(2*n + 1) == f(n) + 1, + sage: transducers.Recursion([f(2*n + 1) == f(n) + 1, # optional - sage.symbolic ....: f(2*n) == f(n), ....: f(0) == 0, ....: f(42) == 42], 2, f, n) @@ -1759,7 +1761,7 @@ def Recursion(self, recursions, base, function=None, var=None, :: - sage: transducers.Recursion([f(2*n + 1) == f(n) + 1, + sage: transducers.Recursion([f(2*n + 1) == f(n) + 1, # optional - sage.symbolic ....: f(2*n) == f(n - 2) + 4, ....: f(0) == 0], 2, f, n) Traceback (most recent call last): @@ -1769,7 +1771,7 @@ def Recursion(self, recursions, base, function=None, var=None, Here is an example of a transducer with a conflicting rule (it cannot hold for `n = 0`):: - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.symbolic ....: f(2*n + 1) == f(n - 1), ....: f(2*n) == f(n) + 1, ....: f(1) == 1, diff --git a/src/sage/combinat/free_module.py b/src/sage/combinat/free_module.py index 2db919f8931..4887720d1c1 100644 --- a/src/sage/combinat/free_module.py +++ b/src/sage/combinat/free_module.py @@ -151,7 +151,7 @@ class CombinatorialFreeModule(UniqueRepresentation, Module, IndexedGenerators): The constructed module is in the category of modules with basis over the base ring:: - sage: CombinatorialFreeModule(QQ, Partitions()).category() + sage: CombinatorialFreeModule(QQ, Partitions()).category() # optional - sage.combinat Category of vector spaces with basis over Rational Field If furthermore the index set is finite (i.e. in the category @@ -160,7 +160,7 @@ class CombinatorialFreeModule(UniqueRepresentation, Module, IndexedGenerators): sage: CombinatorialFreeModule(QQ, [1,2,3,4]).category() Category of finite dimensional vector spaces with basis over Rational Field - sage: CombinatorialFreeModule(QQ, Partitions(3), + sage: CombinatorialFreeModule(QQ, Partitions(3), # optional - sage.combinat ....: category=Algebras(QQ).WithBasis()).category() Category of finite dimensional algebras with basis over Rational Field @@ -288,16 +288,16 @@ def __classcall_private__(cls, base_ring, basis_keys=None, category=None, We check that the category is properly straightened:: sage: F = CombinatorialFreeModule(QQ, ['a','b']) - sage: F1 = CombinatorialFreeModule(QQ, ['a','b'], category = ModulesWithBasis(QQ)) - sage: F2 = CombinatorialFreeModule(QQ, ['a','b'], category = [ModulesWithBasis(QQ)]) - sage: F3 = CombinatorialFreeModule(QQ, ['a','b'], category = (ModulesWithBasis(QQ),)) - sage: F4 = CombinatorialFreeModule(QQ, ['a','b'], category = (ModulesWithBasis(QQ),CommutativeAdditiveSemigroups())) - sage: F5 = CombinatorialFreeModule(QQ, ['a','b'], category = (ModulesWithBasis(QQ),Category.join((LeftModules(QQ), RightModules(QQ))))) + sage: F1 = CombinatorialFreeModule(QQ, ['a','b'], category=ModulesWithBasis(QQ)) + sage: F2 = CombinatorialFreeModule(QQ, ['a','b'], category=[ModulesWithBasis(QQ)]) + sage: F3 = CombinatorialFreeModule(QQ, ['a','b'], category=(ModulesWithBasis(QQ),)) + sage: F4 = CombinatorialFreeModule(QQ, ['a','b'], category=(ModulesWithBasis(QQ),CommutativeAdditiveSemigroups())) + sage: F5 = CombinatorialFreeModule(QQ, ['a','b'], category=(ModulesWithBasis(QQ),Category.join((LeftModules(QQ), RightModules(QQ))))) sage: F6 = CombinatorialFreeModule(QQ, ['a','b'], category=ModulesWithBasis(QQ).FiniteDimensional()) sage: F1 is F, F2 is F, F3 is F, F4 is F, F5 is F, F6 is F (True, True, True, True, True, True) - sage: G = CombinatorialFreeModule(QQ, ['a','b'], category = AlgebrasWithBasis(QQ)) + sage: G = CombinatorialFreeModule(QQ, ['a','b'], category=AlgebrasWithBasis(QQ)) sage: F is G False """ @@ -347,21 +347,21 @@ def element_class(self): EXAMPLES:: - sage: A = Algebras(QQ).WithBasis().example(); A + sage: A = Algebras(QQ).WithBasis().example(); A # optional - sage.combinat An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field - sage: A.element_class.mro() + sage: A.element_class.mro() # optional - sage.combinat [<class 'sage.categories.examples.algebras_with_basis.FreeAlgebra_with_category.element_class'>, <class 'sage.modules.with_basis.indexed_element.IndexedFreeModuleElement'>, ...] - sage: a,b,c = A.algebra_generators() - sage: a * b + sage: a,b,c = A.algebra_generators() # optional - sage.combinat + sage: a * b # optional - sage.combinat B[word: ab] TESTS:: - sage: A.__class__.element_class.__module__ + sage: A.__class__.element_class.__module__ # optional - sage.combinat 'sage.combinat.free_module' """ return self.__make_element_class__(self.Element, @@ -385,12 +385,13 @@ def __init__(self, R, basis_keys=None, element_class=None, category=None, sage: F.category() Category of finite dimensional algebras with basis over Rational Field - sage: F = CombinatorialFreeModule(GF(3), ['a','b','c'], - ....: category=(Modules(GF(3)).WithBasis(), Semigroups())) - sage: F.category() - Join of Category of finite semigroups and Category of finite dimensional vector spaces with basis over Finite Field of size 3 + sage: F = CombinatorialFreeModule(GF(3), ['a','b','c'], # optional - sage.rings.finite_rings + ....: category=(Modules(GF(3)).WithBasis(), Semigroups())) + sage: F.category() # optional - sage.rings.finite_rings + Join of Category of finite semigroups + and Category of finite dimensional vector spaces with basis over Finite Field of size 3 - sage: F = CombinatorialFreeModule(QQ, ['a','b','c'], category = FiniteDimensionalModulesWithBasis(QQ)) + sage: F = CombinatorialFreeModule(QQ, ['a','b','c'], category=FiniteDimensionalModulesWithBasis(QQ)) sage: F.basis() Finite family {'a': B['a'], 'b': B['b'], 'c': B['c']} sage: F.category() @@ -518,8 +519,8 @@ def _ascii_art_term(self, m): TESTS:: - sage: R = NonCommutativeSymmetricFunctions(QQ).R() - sage: ascii_art(R.one()) # indirect doctest + sage: R = NonCommutativeSymmetricFunctions(QQ).R() # optional - sage.combinat + sage: ascii_art(R.one()) # indirect doctest # optional - sage.combinat 1 """ try: @@ -535,8 +536,8 @@ def _unicode_art_term(self, m): TESTS:: - sage: R = NonCommutativeSymmetricFunctions(QQ).R() - sage: unicode_art(R.one()) # indirect doctest + sage: R = NonCommutativeSymmetricFunctions(QQ).R() # optional - sage.combinat + sage: unicode_art(R.one()) # indirect doctest # optional - sage.combinat 1 """ try: @@ -620,26 +621,26 @@ def _element_constructor_(self, x): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ,["a", "b"]) + sage: F = CombinatorialFreeModule(QQ, ["a", "b"]) sage: F(F.monomial("a")) # indirect doctest B['a'] Do not rely on the following feature which may be removed in the future:: - sage: QS3 = SymmetricGroupAlgebra(QQ,3) - sage: QS3([2,3,1]) # indirect doctest + sage: QS3 = SymmetricGroupAlgebra(QQ,3) # optional - sage.combinat + sage: QS3([2,3,1]) # indirect doctest # optional - sage.combinat [2, 3, 1] instead, use:: - sage: P = QS3.basis().keys() - sage: QS3.monomial(P([2,3,1])) # indirect doctest + sage: P = QS3.basis().keys() # optional - sage.combinat + sage: QS3.monomial(P([2,3,1])) # indirect doctest # optional - sage.combinat [2, 3, 1] or:: - sage: B = QS3.basis() - sage: B[P([2,3,1])] + sage: B = QS3.basis() # optional - sage.combinat + sage: B[P([2,3,1])] # optional - sage.combinat [2, 3, 1] TODO: The symmetric group algebra (and in general, @@ -691,17 +692,17 @@ def _element_constructor_(self, x): Here is a real life example illustrating that this yielded mathematically wrong results:: - sage: S = SymmetricFunctions(QQ) - sage: s = S.s(); p = S.p() - sage: ss = tensor([s,s]); pp = tensor([p,p]) - sage: a = tensor((s[2],s[2])) + sage: S = SymmetricFunctions(QQ) # optional - sage.combinat + sage: s = S.s(); p = S.p() # optional - sage.combinat + sage: ss = tensor([s,s]); pp = tensor([p,p]) # optional - sage.combinat + sage: a = tensor((s[2],s[2])) # optional - sage.combinat The following originally used to yield ``p[[2]] # p[[2]]``, and if there was no natural coercion between ``s`` and ``p``, this would raise a ``NotImplementedError``. Since :trac:`15305`, this takes the coercion between ``s`` and ``p`` and lifts it to the tensor product. :: - sage: pp(a) + sage: pp(a) # optional - sage.combinat 1/4*p[1, 1] # p[1, 1] + 1/4*p[1, 1] # p[2] + 1/4*p[2] # p[1, 1] + 1/4*p[2] # p[2] General extensions of the ground ring should probably be reintroduced @@ -715,8 +716,8 @@ def _element_constructor_(self, x): Conversion from the ground ring is implemented for algebras:: - sage: QS3 = SymmetricGroupAlgebra(QQ,3) - sage: QS3(2) + sage: QS3 = SymmetricGroupAlgebra(QQ,3) # optional - sage.combinat + sage: QS3(2) # optional - sage.combinat 2*[1, 2, 3] """ R = self.base_ring() @@ -797,8 +798,8 @@ def _first_ngens(self, n): sage: C._first_ngens(3) (B[0], B[1], B[-1]) - sage: R.<x,y> = FreeAlgebra(QQ, 2) - sage: x,y + sage: R.<x,y> = FreeAlgebra(QQ, 2) # optional - sage.combinat + sage: x,y # optional - sage.combinat (x, y) """ try: @@ -834,13 +835,13 @@ def _coerce_map_from_(self, R): sage: C.has_coerce_map_from(CQ) False - sage: CF2 = CombinatorialFreeModule(GF(2), Set([1,2])) - sage: CF2.has_coerce_map_from(C) + sage: CF2 = CombinatorialFreeModule(GF(2), Set([1,2])) # optional - sage.rings.finite_rings + sage: CF2.has_coerce_map_from(C) # optional - sage.rings.finite_rings True - sage: c = C.monomial(1) - sage: CF2(2*c) + sage: c = C.monomial(1) # optional - sage.rings.finite_rings + sage: CF2(2*c) # optional - sage.rings.finite_rings 0 - sage: CF2(3*c) + sage: CF2(3*c) # optional - sage.rings.finite_rings B[1] """ if isinstance(R, CombinatorialFreeModule): @@ -876,8 +877,8 @@ def dimension(self): :: - sage: s = SymmetricFunctions(QQ).schur() - sage: s.dimension() + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: s.dimension() # optional - sage.combinat +Infinity """ return self._indices.cardinality() @@ -892,11 +893,11 @@ def is_exact(self): EXAMPLES:: - sage: GroupAlgebra(GL(3, GF(7))).is_exact() + sage: GroupAlgebra(GL(3, GF(7))).is_exact() # optional - sage.groups sage.rings.finite_rings True - sage: GroupAlgebra(GL(3, GF(7)), RR).is_exact() + sage: GroupAlgebra(GL(3, GF(7)), RR).is_exact() # optional - sage.groups sage.rings.finite_rings False - sage: GroupAlgebra(GL(3, pAdicRing(7))).is_exact() # not implemented correctly (not my fault)! + sage: GroupAlgebra(GL(3, pAdicRing(7))).is_exact() # not implemented correctly (not my fault)! # optional - sage.groups sage.rings.padics False """ # The index set may not have a check for exactness @@ -926,11 +927,11 @@ def set_order(self, order): EXAMPLES:: - sage: QS2 = SymmetricGroupAlgebra(QQ,2) - sage: b = list(QS2.basis().keys()) - sage: b.reverse() - sage: QS2.set_order(b) - sage: QS2.get_order() + sage: QS2 = SymmetricGroupAlgebra(QQ,2) # optional - sage.combinat + sage: b = list(QS2.basis().keys()) # optional - sage.combinat + sage: b.reverse() # optional - sage.combinat + sage: QS2.set_order(b) # optional - sage.combinat + sage: QS2.get_order() # optional - sage.combinat [[2, 1], [1, 2]] """ self._order = order @@ -944,8 +945,8 @@ def get_order(self): EXAMPLES:: - sage: QS2 = SymmetricGroupAlgebra(QQ,2) - sage: QS2.get_order() # note: order changed on 2009-03-13 + sage: QS2 = SymmetricGroupAlgebra(QQ,2) # optional - sage.combinat + sage: QS2.get_order() # note: order changed on 2009-03-13 # optional - sage.combinat [[2, 1], [1, 2]] """ if self._order is None: @@ -1001,11 +1002,11 @@ def from_vector(self, vector, order=None, coerce=True): EXAMPLES:: - sage: QS3 = SymmetricGroupAlgebra(QQ, 3) - sage: b = QS3.from_vector(vector((2, 0, 0, 0, 0, 4))); b + sage: QS3 = SymmetricGroupAlgebra(QQ, 3) # optional - sage.combinat + sage: b = QS3.from_vector(vector((2, 0, 0, 0, 0, 4))); b # optional - sage.combinat 2*[1, 2, 3] + 4*[3, 2, 1] - sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1]) - sage: a == b + sage: a = 2*QS3([1,2,3]) + 4*QS3([3,2,1]) # optional - sage.combinat + sage: a == b # optional - sage.combinat True """ if order is None: @@ -1057,7 +1058,7 @@ def linear_combination(self, iter_of_elements_coeff, factor_on_left=True): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ,[1,2]) + sage: F = CombinatorialFreeModule(QQ, [1,2]) sage: f = F.an_element(); f 2*B[1] + 2*B[2] sage: F.linear_combination( (f,i) for i in range(5) ) @@ -1132,8 +1133,8 @@ def _sum_of_monomials(self, indices): sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) sage: F._sum_of_monomials(['a', 'b', 'b']) B['a'] + 2*B['b'] - sage: F = CombinatorialFreeModule(GF(3), ['a', 'b', 'c']) - sage: F._sum_of_monomials(['a', 'b', 'b', 'b']) + sage: F = CombinatorialFreeModule(GF(3), ['a', 'b', 'c']) # optional - sage.rings.finite_rings + sage: F._sum_of_monomials(['a', 'b', 'b', 'b']) # optional - sage.rings.finite_rings B['a'] """ R = self.base_ring() @@ -1208,26 +1209,26 @@ def _from_dict(self, d, coerce=False, remove_zeros=True): EXAMPLES:: - sage: e = SymmetricFunctions(QQ).elementary() - sage: s = SymmetricFunctions(QQ).schur() - sage: a = e([2,1]) + e([1,1,1]); a + sage: e = SymmetricFunctions(QQ).elementary() # optional - sage.combinat + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: a = e([2,1]) + e([1,1,1]); a # optional - sage.combinat e[1, 1, 1] + e[2, 1] - sage: s._from_dict(a.monomial_coefficients()) + sage: s._from_dict(a.monomial_coefficients()) # optional - sage.combinat s[1, 1, 1] + s[2, 1] If the optional argument ``coerce`` is ``True``, then the coefficients are coerced into the base ring of ``self``:: - sage: part = Partition([2,1]) - sage: d = {part:1} - sage: a = s._from_dict(d,coerce=True); a + sage: part = Partition([2,1]) # optional - sage.combinat + sage: d = {part: 1} # optional - sage.combinat + sage: a = s._from_dict(d, coerce=True); a # optional - sage.combinat s[2, 1] - sage: a.coefficient(part).parent() + sage: a.coefficient(part).parent() # optional - sage.combinat Rational Field With ``remove_zeros=True``, zero coefficients are removed:: - sage: s._from_dict({part:0}) + sage: s._from_dict({part: 0}) # optional - sage.combinat 0 .. WARNING:: @@ -1236,7 +1237,7 @@ def _from_dict(self, d, coerce=False, remove_zeros=True): coefficient of the dictionary is zero. Otherwise, this may lead to illegal results:: - sage: list(s._from_dict({part:0}, remove_zeros=False)) + sage: list(s._from_dict({part: 0}, remove_zeros=False)) # optional - sage.combinat [([2, 1], 0)] """ assert isinstance(d, dict) @@ -1262,7 +1263,8 @@ class CombinatorialFreeModule_Tensor(CombinatorialFreeModule): F # G sage: T.category() - Category of tensor products of finite dimensional modules with basis over Integer Ring + Category of tensor products of + finite dimensional modules with basis over Integer Ring sage: T.construction() # todo: not implemented [tensor, ] @@ -1275,7 +1277,8 @@ class CombinatorialFreeModule_Tensor(CombinatorialFreeModule): The basis of T is indexed by tuples of basis indices of F and G:: sage: T.basis().keys() - Image of Cartesian product of {1, 2}, {3, 4} by The map <class 'tuple'> from Cartesian product of {1, 2}, {3, 4} + Image of Cartesian product of {1, 2}, {3, 4} + by The map <class 'tuple'> from Cartesian product of {1, 2}, {3, 4} sage: T.basis().keys().list() [(1, 3), (1, 4), (2, 3), (2, 4)] @@ -1424,9 +1427,9 @@ def _ascii_art_(self, term): """ TESTS:: - sage: R = NonCommutativeSymmetricFunctions(QQ).R() - sage: Partitions.options(diagram_str="#", convention="french") - sage: s = ascii_art(tensor((R[1,2], R[3,1,2]))); s + sage: R = NonCommutativeSymmetricFunctions(QQ).R() # optional - sage.combinat + sage: Partitions.options(diagram_str="#", convention="french") # optional - sage.combinat + sage: s = ascii_art(tensor((R[1,2], R[3,1,2]))); s # optional - sage.combinat R # R # ### ## # @@ -1434,7 +1437,7 @@ def _ascii_art_(self, term): Check that the breakpoints are correct (:trac:`29202`):: - sage: s._breakpoints + sage: s._breakpoints # optional - sage.combinat [6] """ if hasattr(self, "_print_options"): @@ -1453,9 +1456,9 @@ def _unicode_art_(self, term): """ TESTS:: - sage: R = NonCommutativeSymmetricFunctions(QQ).R() - sage: Partitions.options(diagram_str="#", convention="french") - sage: s = unicode_art(tensor((R[1,2], R[3,1,2]))); s + sage: R = NonCommutativeSymmetricFunctions(QQ).R() # optional - sage.combinat + sage: Partitions.options(diagram_str="#", convention="french") # optional - sage.combinat + sage: s = unicode_art(tensor((R[1,2], R[3,1,2]))); s # optional - sage.combinat R ⊗ R ┌┐ ┌┬┬┐ ├┼┐ └┴┼┤ @@ -1464,7 +1467,7 @@ def _unicode_art_(self, term): Check that the breakpoints are correct (:trac:`29202`):: - sage: s._breakpoints + sage: s._breakpoints # optional - sage.combinat [7] """ if hasattr(self, "_print_options"): @@ -1548,22 +1551,26 @@ def tensor_constructor(self, modules): sage: G = CombinatorialFreeModule(ZZ, [3,4]); G.rename("G") sage: H = CombinatorialFreeModule(ZZ, [5,6]); H.rename("H") - sage: f = F.monomial(1) + 2 * F.monomial(2) - sage: g = 2*G.monomial(3) + G.monomial(4) - sage: h = H.monomial(5) + H.monomial(6) - sage: FG = tensor([F, G ]) + sage: f = F.monomial(1) + 2*F.monomial(2) + sage: g = 2*G.monomial(3) + G.monomial(4) + sage: h = H.monomial(5) + H.monomial(6) + sage: FG = tensor([F, G]) sage: phi_fg = FG.tensor_constructor((F, G)) - sage: phi_fg(f,g) + sage: phi_fg(f, g) 2*B[1] # B[3] + B[1] # B[4] + 4*B[2] # B[3] + 2*B[2] # B[4] sage: FGH = tensor([F, G, H]) sage: phi_fgh = FGH.tensor_constructor((F, G, H)) sage: phi_fgh(f, g, h) - 2*B[1] # B[3] # B[5] + 2*B[1] # B[3] # B[6] + B[1] # B[4] # B[5] + B[1] # B[4] # B[6] + 4*B[2] # B[3] # B[5] + 4*B[2] # B[3] # B[6] + 2*B[2] # B[4] # B[5] + 2*B[2] # B[4] # B[6] + 2*B[1] # B[3] # B[5] + 2*B[1] # B[3] # B[6] + B[1] # B[4] # B[5] + + B[1] # B[4] # B[6] + 4*B[2] # B[3] # B[5] + 4*B[2] # B[3] # B[6] + + 2*B[2] # B[4] # B[5] + 2*B[2] # B[4] # B[6] sage: phi_fg_h = FGH.tensor_constructor((FG, H)) sage: phi_fg_h(phi_fg(f, g), h) - 2*B[1] # B[3] # B[5] + 2*B[1] # B[3] # B[6] + B[1] # B[4] # B[5] + B[1] # B[4] # B[6] + 4*B[2] # B[3] # B[5] + 4*B[2] # B[3] # B[6] + 2*B[2] # B[4] # B[5] + 2*B[2] # B[4] # B[6] + 2*B[1] # B[3] # B[5] + 2*B[1] # B[3] # B[6] + B[1] # B[4] # B[5] + + B[1] # B[4] # B[6] + 4*B[2] # B[3] # B[5] + 4*B[2] # B[3] # B[6] + + 2*B[2] # B[4] # B[5] + 2*B[2] # B[4] # B[6] """ assert(module in ModulesWithBasis(self.base_ring()) for module in modules) assert(tensor(modules) == self) @@ -1727,7 +1734,9 @@ class CombinatorialFreeModule_CartesianProduct(CombinatorialFreeModule): sage: S F (+) G sage: S.basis() - Lazy family (Term map from Disjoint union of Family ({4, 5}, {4, 6}) to F (+) G(i))_{i in Disjoint union of Family ({4, 5}, {4, 6})} + Lazy family (Term map + from Disjoint union of Family ({4, 5}, {4, 6}) + to F (+) G(i))_{i in Disjoint union of Family ({4, 5}, {4, 6})} Note that the indices of the basis elements of F and G intersect non trivially. This is handled by forcing the union to be disjoint:: @@ -1737,19 +1746,19 @@ class CombinatorialFreeModule_CartesianProduct(CombinatorialFreeModule): We now compute the Cartesian product of elements of free modules:: - sage: f = F.monomial(4) + 2 * F.monomial(5) - sage: g = 2*G.monomial(4) + G.monomial(6) - sage: h = H.monomial(4) + H.monomial(7) - sage: cartesian_product([f,g]) + sage: f = F.monomial(4) + 2*F.monomial(5) + sage: g = 2*G.monomial(4) + G.monomial(6) + sage: h = H.monomial(4) + H.monomial(7) + sage: cartesian_product([f, g]) B[(0, 4)] + 2*B[(0, 5)] + 2*B[(1, 4)] + B[(1, 6)] - sage: cartesian_product([f,g,h]) + sage: cartesian_product([f, g, h]) B[(0, 4)] + 2*B[(0, 5)] + 2*B[(1, 4)] + B[(1, 6)] + B[(2, 4)] + B[(2, 7)] - sage: cartesian_product([f,g,h]).parent() + sage: cartesian_product([f, g, h]).parent() F (+) G (+) H TODO: choose an appropriate semantic for Cartesian products of Cartesian products (associativity?):: - sage: S = cartesian_product([cartesian_product([F, G]), H]) # todo: not implemented + sage: S = cartesian_product([cartesian_product([F, G]), H]) # todo: not implemented F (+) G (+) H """ @@ -1881,8 +1890,8 @@ def _cartesian_product_of_elements(self, elements): sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename("F") sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename("G") sage: S = cartesian_product([F, G]) - sage: f = F.monomial(4) + 2 * F.monomial(5) - sage: g = 2*G.monomial(4) + G.monomial(6) + sage: f = F.monomial(4) + 2*F.monomial(5) + sage: g = 2*G.monomial(4) + G.monomial(6) sage: S._cartesian_product_of_elements([f, g]) B[(0, 4)] + 2*B[(0, 5)] + 2*B[(1, 4)] + B[(1, 6)] sage: S._cartesian_product_of_elements([f, g]).parent() == S diff --git a/src/sage/combinat/integer_lists/invlex.pyx b/src/sage/combinat/integer_lists/invlex.pyx index a168491ede7..c94a024c040 100644 --- a/src/sage/combinat/integer_lists/invlex.pyx +++ b/src/sage/combinat/integer_lists/invlex.pyx @@ -560,7 +560,7 @@ class IntegerListsLex(IntegerLists, metaclass=ClasscallMetaclass): :: - sage: Partitions(2, max_slope=-1, length=2).list() + sage: Partitions(2, max_slope=-1, length=2).list() # optional - sage.combinat [] sage: list(IntegerListsLex(0, floor=ConstantFunction(1), min_slope=0)) [[]] diff --git a/src/sage/combinat/integer_vector.py b/src/sage/combinat/integer_vector.py index 9f01bfd787d..9e62a27d47f 100644 --- a/src/sage/combinat/integer_vector.py +++ b/src/sage/combinat/integer_vector.py @@ -92,11 +92,11 @@ def is_gale_ryser(r,s): EXAMPLES:: sage: from sage.combinat.integer_vector import is_gale_ryser - sage: is_gale_ryser([4,2,2],[3,3,1,1]) + sage: is_gale_ryser([4,2,2], [3,3,1,1]) # optional - sage.combinat True - sage: is_gale_ryser([4,2,1,1],[3,3,1,1]) + sage: is_gale_ryser([4,2,1,1], [3,3,1,1]) # optional - sage.combinat True - sage: is_gale_ryser([3,2,1,1],[3,3,1,1]) + sage: is_gale_ryser([3,2,1,1], [3,3,1,1]) # optional - sage.combinat False REMARK: In the literature, what we are calling a @@ -207,14 +207,14 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", sage: from sage.combinat.integer_vector import gale_ryser_theorem sage: p1 = [2,2,1] sage: p2 = [2,2,1] - sage: print(gale_ryser_theorem(p1, p2)) # not tested + sage: print(gale_ryser_theorem(p1, p2)) # not tested # optional - sage.combinat [1 1 0] [1 0 1] [0 1 0] - sage: A = gale_ryser_theorem(p1, p2) - sage: rs = [sum(x) for x in A.rows()] - sage: cs = [sum(x) for x in A.columns()] - sage: p1 == rs; p2 == cs + sage: A = gale_ryser_theorem(p1, p2) # optional - sage.combinat + sage: rs = [sum(x) for x in A.rows()] # optional - sage.combinat + sage: cs = [sum(x) for x in A.columns()] # optional - sage.combinat + sage: p1 == rs; p2 == cs # optional - sage.combinat True True @@ -224,27 +224,27 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", sage: from sage.combinat.integer_vector import gale_ryser_theorem sage: p1 = [3,3,1,1] sage: p2 = [3,3,1,1] - sage: gale_ryser_theorem(p1, p2, algorithm = "ryser") + sage: gale_ryser_theorem(p1, p2, algorithm="ryser") # optional - sage.combinat [1 1 1 0] [1 1 0 1] [1 0 0 0] [0 1 0 0] sage: p1 = [4,2,2] sage: p2 = [3,3,1,1] - sage: gale_ryser_theorem(p1, p2, algorithm = "ryser") + sage: gale_ryser_theorem(p1, p2, algorithm="ryser") # optional - sage.combinat [1 1 1 1] [1 1 0 0] [1 1 0 0] sage: p1 = [4,2,2,0] sage: p2 = [3,3,1,1,0,0] - sage: gale_ryser_theorem(p1, p2, algorithm = "ryser") + sage: gale_ryser_theorem(p1, p2, algorithm="ryser") # optional - sage.combinat [1 1 1 1 0 0] [1 1 0 0 0 0] [1 1 0 0 0 0] [0 0 0 0 0 0] sage: p1 = [3,3,2,1] sage: p2 = [3,2,2,1,1] - sage: print(gale_ryser_theorem(p1, p2, algorithm="gale")) # not tested + sage: print(gale_ryser_theorem(p1, p2, algorithm="gale")) # not tested # optional - sage.combinat [1 1 1 0 0] [1 1 0 0 1] [1 0 1 0 0] @@ -253,7 +253,7 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", With `0` in the sequences, and with unordered inputs:: sage: from sage.combinat.integer_vector import gale_ryser_theorem - sage: gale_ryser_theorem([3,3,0,1,1,0], [3,1,3,1,0], algorithm="ryser") + sage: gale_ryser_theorem([3,3,0,1,1,0], [3,1,3,1,0], algorithm="ryser") # optional - sage.combinat [1 1 1 0 0] [1 0 1 1 0] [0 0 0 0 0] @@ -261,7 +261,7 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", [0 0 1 0 0] [0 0 0 0 0] sage: p1 = [3,1,1,1,1]; p2 = [3,2,2,0] - sage: gale_ryser_theorem(p1, p2, algorithm="ryser") + sage: gale_ryser_theorem(p1, p2, algorithm="ryser") # optional - sage.combinat [1 1 1 0] [1 0 0 0] [1 0 0 0] @@ -288,17 +288,17 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", ....: print("Algorithm %s failed with this input:" % algorithm) ....: print(s1, s2) - sage: for algorithm in ["gale", "ryser"]: # long time + sage: for algorithm in ["gale", "ryser"]: # long time # optional - sage.combinat ....: for i in range(50): ....: test_algorithm(algorithm, 3, 10) Null matrix:: - sage: gale_ryser_theorem([0,0,0],[0,0,0,0], algorithm="gale") + sage: gale_ryser_theorem([0,0,0],[0,0,0,0], algorithm="gale") # optional - sage.combinat [0 0 0 0] [0 0 0 0] [0 0 0 0] - sage: gale_ryser_theorem([0,0,0],[0,0,0,0], algorithm="ryser") + sage: gale_ryser_theorem([0,0,0],[0,0,0,0], algorithm="ryser") # optional - sage.combinat [0 0 0 0] [0 0 0 0] [0 0 0 0] @@ -517,11 +517,10 @@ def specht_module(self, base_ring=None): EXAMPLES:: - sage: SM = IntegerVectors()([2,0,1,0,2]).specht_module(QQ) - sage: SM + sage: SM = IntegerVectors()([2,0,1,0,2]).specht_module(QQ); SM # optional - sage.combinat Specht module of [(0, 0), (0, 1), (2, 0), (4, 0), (4, 1)] over Rational Field - sage: s = SymmetricFunctions(QQ).s() - sage: s(SM.frobenius_image()) + sage: s = SymmetricFunctions(QQ).s() # optional - sage.combinat + sage: s(SM.frobenius_image()) # optional - sage.combinat s[2, 2, 1] """ from sage.combinat.specht_module import SpechtModule @@ -542,9 +541,9 @@ def specht_module_dimension(self, base_ring=None): EXAMPLES:: - sage: IntegerVectors()([2,0,1,0,2]).specht_module_dimension() + sage: IntegerVectors()([2,0,1,0,2]).specht_module_dimension() # optional - sage.combinat 5 - sage: IntegerVectors()([2,0,1,0,2]).specht_module_dimension(GF(2)) + sage: IntegerVectors()([2,0,1,0,2]).specht_module_dimension(GF(2)) # optional - sage.combinat sage.rings.finite_rings 5 """ from sage.combinat.specht_module import specht_module_rank @@ -595,7 +594,7 @@ class IntegerVectors(Parent, metaclass=ClasscallMetaclass): Note that trailing zeros are ignored so that ``[3, 0]`` does not show up in the following list (since ``[3]`` does):: - sage: IntegerVectors(3, max_length=2).list() + sage: IntegerVectors(3, max_length=2).list() # optional - sage.combinat [[3], [2, 1], [1, 2], [0, 3]] If ``n`` and ``k`` are both specified, then it returns the class @@ -614,9 +613,9 @@ class IntegerVectors(Parent, metaclass=ClasscallMetaclass): Further examples:: - sage: IntegerVectors(-1, 0, min_part = 1).list() + sage: IntegerVectors(-1, 0, min_part=1).list() [] - sage: IntegerVectors(-1, 2, min_part = 1).list() + sage: IntegerVectors(-1, 2, min_part=1).list() [] sage: IntegerVectors(0, 0, min_part=1).list() [[]] @@ -667,9 +666,9 @@ class IntegerVectors(Parent, metaclass=ClasscallMetaclass): An example showing the same output by using IntegerListsLex:: - sage: IntegerVectors(4, max_length=2).list() + sage: IntegerVectors(4, max_length=2).list() # optional - sage.combinat [[4], [3, 1], [2, 2], [1, 3], [0, 4]] - sage: list(IntegerListsLex(4, max_length=2)) + sage: list(IntegerListsLex(4, max_length=2)) # optional - sage.combinat [[4], [3, 1], [2, 2], [1, 3], [0, 4]] .. SEEALSO:: @@ -1392,12 +1391,12 @@ def __contains__(self, x): """ TESTS:: - sage: [3,2,2,1] in IntegerVectors(8,4, min_part = 1) + sage: [3,2,2,1] in IntegerVectors(8, 4, min_part=1) # optional - sage.combinat True - sage: [3,2,2,1] in IntegerVectors(8,4, min_part = 2) + sage: [3,2,2,1] in IntegerVectors(8, 4, min_part=2) # optional - sage.combinat False - sage: [0,3,0,1,2] in IntegerVectors(6, max_length=3) + sage: [0,3,0,1,2] in IntegerVectors(6, max_length=3) # optional - sage.combinat False """ if isinstance(x, IntegerVector) and x.parent() is self: @@ -1421,17 +1420,17 @@ def cardinality(self): EXAMPLES:: - sage: IntegerVectors(3, 3, min_part=1).cardinality() + sage: IntegerVectors(3, 3, min_part=1).cardinality() # optional - sage.combinat 1 - sage: IntegerVectors(5, 3, min_part=1).cardinality() + sage: IntegerVectors(5, 3, min_part=1).cardinality() # optional - sage.combinat 6 - sage: IntegerVectors(13, 4, max_part=4).cardinality() + sage: IntegerVectors(13, 4, max_part=4).cardinality() # optional - sage.combinat 20 - sage: IntegerVectors(k=4, max_part=3).cardinality() + sage: IntegerVectors(k=4, max_part=3).cardinality() # optional - sage.combinat 256 - sage: IntegerVectors(k=3, min_part=2, max_part=4).cardinality() + sage: IntegerVectors(k=3, min_part=2, max_part=4).cardinality() # optional - sage.combinat 27 - sage: IntegerVectors(13, 4, min_part=2, max_part=4).cardinality() + sage: IntegerVectors(13, 4, min_part=2, max_part=4).cardinality() # optional - sage.combinat 16 """ if self.k is None: @@ -1465,9 +1464,9 @@ def __iter__(self): """ EXAMPLES:: - sage: IntegerVectors(-1, 0, min_part = 1).list() + sage: IntegerVectors(-1, 0, min_part=1).list() [] - sage: IntegerVectors(-1, 2, min_part = 1).list() + sage: IntegerVectors(-1, 2, min_part=1).list() [] sage: IntegerVectors(0, 0, min_part=1).list() [[]] @@ -1512,7 +1511,7 @@ def __iter__(self): sage: all(map(lambda x: x.cardinality() == len(x.list()), iv)) True sage: essai = [[1,1,1], [2,5,6], [6,5,2]] - sage: iv = [ IntegerVectors(x[0], x[1], max_part = x[2]-1) for x in essai ] + sage: iv = [ IntegerVectors(x[0], x[1], max_part=x[2]-1) for x in essai ] sage: all(map(lambda x: x.cardinality() == len(x.list()), iv)) True """ diff --git a/src/sage/combinat/ranker.py b/src/sage/combinat/ranker.py index bcb5c967dcb..6d7fb2998a2 100644 --- a/src/sage/combinat/ranker.py +++ b/src/sage/combinat/ranker.py @@ -207,7 +207,7 @@ def unrank(L, i): Enumerated sets:: - sage: unrank(GF(7), 2) + sage: unrank(GF(7), 2) # optional - sage.rings.finite_rings 2 sage: unrank(IntegerModRing(29), 10) 10 diff --git a/src/sage/combinat/tutorial.py b/src/sage/combinat/tutorial.py index 904c7c3339c..afcdccc1729 100644 --- a/src/sage/combinat/tutorial.py +++ b/src/sage/combinat/tutorial.py @@ -360,7 +360,7 @@ Taking successive quotients:: - sage: [ (d(n+1) / d(n)) for n in range(1,17) ] + sage: [ (d(n+1) / d(n)) for n in range(1,17) ] # optional - sage.symbolic [2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54, 58, 62] we observe that `d_n` satisfies the recurrence relation From f93a484eb4ee2a1709c05a99a83341962e7c2267 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sat, 20 May 2023 15:35:26 -0700 Subject: [PATCH 060/228] sage.combinat: More # optional --- src/sage/combinat/root_system/plot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/root_system/plot.py b/src/sage/combinat/root_system/plot.py index 2789540d238..90bab1e8ac0 100644 --- a/src/sage/combinat/root_system/plot.py +++ b/src/sage/combinat/root_system/plot.py @@ -754,10 +754,10 @@ sage: C = crystals.Tableaux(["A",2], shape=[4,2]) sage: L = C.weight_lattice_realization() - sage: plot_options = L.plot_parse_options() + sage: plot_options = L.plot_parse_options() # optional - sage.plot sage.symbolic sage: g = C.digraph() - sage: positions = {x: plot_options.projection(x.weight()) for x in C} + sage: positions = {x: plot_options.projection(x.weight()) for x in C} # optional - sage.plot sage.symbolic sage: p = L.plot() # optional - sage.plot sage.symbolic sage: p += g.plot(pos=positions, # optional - sage.plot sage.symbolic ....: color_by_label=plot_options.color, vertex_size=0) From 3ef1b0222af28492b161e29697ce0480aca7fbe5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sat, 20 May 2023 22:37:59 -0700 Subject: [PATCH 061/228] sage.combinat: More # optional --- src/sage/combinat/tutorial.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/tutorial.py b/src/sage/combinat/tutorial.py index afcdccc1729..dfab1793474 100644 --- a/src/sage/combinat/tutorial.py +++ b/src/sage/combinat/tutorial.py @@ -474,7 +474,7 @@ `z` and `C(z)` to obtain an expression for `\frac{d}{dz}C(z)`:: - sage: fraction = fraction.lift(); fraction + sage: fraction = fraction.lift(); fraction # optional - sage.symbolic (1/2/(x - 1/4))*y - 1/4/(x - 1/4) sage: fraction(x=z, y=C) # optional - sage.symbolic 2*C(z)/(4*z - 1) - 1/(4*z - 1) From 1b5460881521a2fbbf805e30676c142e453310f7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Wed, 7 Jun 2023 11:01:45 -0700 Subject: [PATCH 062/228] src/sage/combinat/k_regular_sequence.py: Fix alignment of # optional --- src/sage/combinat/k_regular_sequence.py | 38 ++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/sage/combinat/k_regular_sequence.py b/src/sage/combinat/k_regular_sequence.py index 74329d1f794..3a9afd84ddc 100644 --- a/src/sage/combinat/k_regular_sequence.py +++ b/src/sage/combinat/k_regular_sequence.py @@ -2718,11 +2718,11 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): sage: from sage.combinat.k_regular_sequence import RecurrenceParser sage: RP = RecurrenceParser(2, ZZ) - sage: var('n') # optional - sage.symbolic + sage: var('n') # optional - sage.symbolic n - sage: function('f') # optional - sage.symbolic + sage: function('f') # optional - sage.symbolic f - sage: M, m, coeffs, initial_values = RP.parse_recurrence([ # optional - sage.symbolic + sage: M, m, coeffs, initial_values = RP.parse_recurrence([ # optional - sage.symbolic ....: f(8*n) == -1*f(2*n - 1) + 1*f(2*n + 1), ....: f(8*n + 1) == -11*f(2*n - 1) + 10*f(2*n) + 11*f(2*n + 1), ....: f(8*n + 2) == -21*f(2*n - 1) + 20*f(2*n) + 21*f(2*n + 1), @@ -2733,9 +2733,9 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): ....: f(8*n + 7) == -71*f(2*n - 1) + 70*f(2*n) + 71*f(2*n + 1), ....: f(0) == 0, f(1) == 1, f(2) == 2, f(3) == 3, f(4) == 4, ....: f(5) == 5, f(6) == 6, f(7) == 7], f, n) - sage: rules = RP.parameters( # optional - sage.symbolic + sage: rules = RP.parameters( # optional - sage.symbolic ....: M, m, coeffs, initial_values, 0) - sage: RP.matrix(rules, 0, False) # optional - sage.symbolic + sage: RP.matrix(rules, 0, False) # optional - sage.symbolic [ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0] @@ -2753,7 +2753,7 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): [ 0 0 0 -31 30 31 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 -41 40 41 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 -51 50 51 0 0 0 0 0 0 0 0 0 0 0] - sage: RP.matrix(rules, 1, False) # optional - sage.symbolic + sage: RP.matrix(rules, 1, False) # optional - sage.symbolic [ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0] @@ -2788,7 +2788,7 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): Number of Unbordered Factors in the Thue--Morse Sequence:: - sage: M, m, coeffs, initial_values = RP.parse_recurrence([ # optional - sage.symbolic + sage: M, m, coeffs, initial_values = RP.parse_recurrence([ # optional - sage.symbolic ....: f(8*n) == 2*f(4*n), ....: f(8*n + 1) == f(4*n + 1), ....: f(8*n + 2) == f(4*n + 1) + f(4*n + 3), @@ -2802,9 +2802,9 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): ....: f(10) == 4, f(11) == 4, f(12) == 12, f(13) == 0, f(14) == 4, ....: f(15) == 4, f(16) == 8, f(17) == 4, f(18) == 8, f(19) == 0, ....: f(20) == 8, f(21) == 4, f(22) == 4, f(23) == 8], f, n) - sage: UB_rules = RP.parameters( # optional - sage.symbolic + sage: UB_rules = RP.parameters( # optional - sage.symbolic ....: M, m, coeffs, initial_values, 3) - sage: RP.matrix(UB_rules, 0) # optional - sage.symbolic + sage: RP.matrix(UB_rules, 0) # optional - sage.symbolic [ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0] @@ -2821,7 +2821,7 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): [ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0] - sage: RP.matrix(UB_rules, 1) # optional - sage.symbolic + sage: RP.matrix(UB_rules, 1) # optional - sage.symbolic [ 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0] @@ -3015,9 +3015,9 @@ def right(self, recurrence_rules): sage: from sage.combinat.k_regular_sequence import RecurrenceParser sage: RP = RecurrenceParser(2, ZZ) - sage: var('n') # optional - sage.symbolic + sage: var('n') # optional - sage.symbolic n - sage: function('f') # optional - sage.symbolic + sage: function('f') # optional - sage.symbolic f sage: SB_rules = RP.parameters( ....: 1, 0, {(0, 0): 1, (1, 0): 1, (1, 1): 1}, @@ -3027,7 +3027,7 @@ def right(self, recurrence_rules): Number of Unbordered Factors in the Thue--Morse Sequence:: - sage: M, m, coeffs, initial_values = RP.parse_recurrence([ # optional - sage.symbolic + sage: M, m, coeffs, initial_values = RP.parse_recurrence([ # optional - sage.symbolic ....: f(8*n) == 2*f(4*n), ....: f(8*n + 1) == f(4*n + 1), ....: f(8*n + 2) == f(4*n + 1) + f(4*n + 3), @@ -3041,9 +3041,9 @@ def right(self, recurrence_rules): ....: f(10) == 4, f(11) == 4, f(12) == 12, f(13) == 0, f(14) == 4, ....: f(15) == 4, f(16) == 8, f(17) == 4, f(18) == 8, f(19) == 0, ....: f(20) == 8, f(21) == 4, f(22) == 4, f(23) == 8], f, n) - sage: UB_rules = RP.parameters( # optional - sage.symbolic + sage: UB_rules = RP.parameters( # optional - sage.symbolic ....: M, m, coeffs, initial_values, 3) - sage: RP.right(UB_rules) # optional - sage.symbolic + sage: RP.right(UB_rules) # optional - sage.symbolic (1, 1, 2, 1, 2, 2, 4, 2, 4, 6, 0, 4, 4, 1, 0, 0) """ from sage.modules.free_module_element import vector @@ -3079,12 +3079,12 @@ def __call__(self, *args, **kwds): sage: from sage.combinat.k_regular_sequence import RecurrenceParser sage: RP = RecurrenceParser(2, ZZ) - sage: var('n') # optional - sage.symbolic + sage: var('n') # optional - sage.symbolic n - sage: function('f') # optional - sage.symbolic + sage: function('f') # optional - sage.symbolic f - sage: RP([f(2*n) == f(n), f(2*n + 1) == f(n) + f(n + 1), # optional - sage.symbolic + sage: RP([f(2*n) == f(n), f(2*n + 1) == f(n) + f(n + 1), # optional - sage.symbolic ....: f(0) == 0, f(1) == 1], f, n) ([ [1 0 0] [1 1 0] @@ -3094,7 +3094,7 @@ def __call__(self, *args, **kwds): (1, 0, 0), (0, 1, 1)) - sage: RP(equations=[f(2*n) == f(n), f(2*n + 1) == f(n) + f(n + 1), # optional - sage.symbolic + sage: RP(equations=[f(2*n) == f(n), f(2*n + 1) == f(n) + f(n + 1), # optional - sage.symbolic ....: f(0) == 0, f(1) == 1], function=f, var=n) ([ [1 0 0] [1 1 0] From d516993dd1d784966d99b32b74fd481cc4cbd504 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Wed, 7 Jun 2023 11:21:57 -0700 Subject: [PATCH 063/228] src/sage/combinat/{k_regular_sequence,recognizable_series}.py: Add module level # optional --- src/sage/combinat/k_regular_sequence.py | 1 + src/sage/combinat/recognizable_series.py | 1 + 2 files changed, 2 insertions(+) diff --git a/src/sage/combinat/k_regular_sequence.py b/src/sage/combinat/k_regular_sequence.py index 3a9afd84ddc..a170582116f 100644 --- a/src/sage/combinat/k_regular_sequence.py +++ b/src/sage/combinat/k_regular_sequence.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" `k`-regular Sequences diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index f717393edf0..c19b1cf680f 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Recognizable Series From a2ceb72cdf6acf8260478cb5bb4dd5ba51e56d92 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Wed, 7 Jun 2023 11:28:18 -0700 Subject: [PATCH 064/228] sage.combinat: More # optional --- .../combinat/binary_recurrence_sequences.py | 2 +- src/sage/combinat/binary_tree.py | 132 ++-- .../cluster_algebra_quiver/interact.py | 4 +- src/sage/combinat/combinat.py | 2 +- src/sage/combinat/combinat_cython.pyx | 2 +- src/sage/combinat/designs/bibd.py | 10 +- src/sage/combinat/designs/block_design.py | 132 ++-- src/sage/combinat/designs/database.py | 184 ++--- src/sage/combinat/designs/designs_pyx.pyx | 71 +- .../combinat/designs/difference_family.py | 253 +++---- .../designs/evenly_distributed_sets.pyx | 20 +- src/sage/combinat/designs/twographs.py | 40 +- src/sage/combinat/diagram.py | 12 +- src/sage/combinat/dlx.py | 16 +- src/sage/combinat/e_one_star.py | 18 +- .../combinat/integer_vectors_mod_permgroup.py | 1 + src/sage/combinat/interval_posets.py | 170 +++-- src/sage/combinat/matrices/dlxcpp.py | 16 +- .../multiset_partition_into_sets_ordered.py | 124 ++-- src/sage/combinat/ordered_tree.py | 38 +- src/sage/combinat/partition.py | 210 +++--- src/sage/combinat/perfect_matching.py | 22 +- src/sage/combinat/permutation.py | 96 +-- src/sage/combinat/posets/d_complete.py | 14 +- src/sage/combinat/posets/elements.py | 30 +- src/sage/combinat/posets/hasse_diagram.py | 336 ++++----- src/sage/combinat/posets/linear_extensions.py | 47 +- src/sage/combinat/posets/mobile.py | 8 +- src/sage/combinat/posets/poset_examples.py | 162 ++--- src/sage/combinat/posets/posets.py | 675 +++++++++--------- src/sage/combinat/quickref.py | 2 +- src/sage/combinat/rooted_tree.py | 14 +- src/sage/combinat/skew_partition.py | 12 +- src/sage/combinat/skew_tableau.py | 26 +- .../combinat/species/generating_series.py | 58 +- src/sage/combinat/subsets_hereditary.py | 12 +- src/sage/combinat/subword_complex.py | 14 +- src/sage/combinat/symmetric_group_algebra.py | 1 + .../symmetric_group_representations.py | 2 +- src/sage/combinat/tableau.py | 126 ++-- src/sage/combinat/tiling.py | 49 +- src/sage/combinat/triangles_FHM.py | 32 +- src/sage/combinat/tuple.py | 12 +- src/sage/combinat/tutorial.py | 4 +- src/sage/combinat/words/abstract_word.py | 10 +- src/sage/combinat/words/finite_word.py | 60 +- src/sage/combinat/words/morphic.py | 28 +- src/sage/combinat/words/morphism.py | 102 +-- src/sage/combinat/words/paths.py | 8 +- src/sage/combinat/words/suffix_trees.py | 16 +- src/sage/combinat/words/word.py | 2 +- src/sage/combinat/words/word_generators.py | 14 +- src/sage/combinat/words/words.py | 46 +- src/sage/combinat/yang_baxter_graph.py | 80 +-- 54 files changed, 1828 insertions(+), 1749 deletions(-) diff --git a/src/sage/combinat/binary_recurrence_sequences.py b/src/sage/combinat/binary_recurrence_sequences.py index 46c99fd24aa..49ddfe13fc0 100644 --- a/src/sage/combinat/binary_recurrence_sequences.py +++ b/src/sage/combinat/binary_recurrence_sequences.py @@ -1090,7 +1090,7 @@ def _find_cong1(p, R, ell): EXAMPLES:: sage: R = BinaryRecurrenceSequence(1,1) - sage: sage.combinat.binary_recurrence_sequences._find_cong1(7, R, 29) + sage: sage.combinat.binary_recurrence_sequences._find_cong1(7, R, 29) # optional - sage.rings.finite_rings ([0, 1, 2, 12, 13], 14) """ F = GF(ell) diff --git a/src/sage/combinat/binary_tree.py b/src/sage/combinat/binary_tree.py index 26923650782..8e876ab137a 100644 --- a/src/sage/combinat/binary_tree.py +++ b/src/sage/combinat/binary_tree.py @@ -988,13 +988,13 @@ def to_dyck_word_tamari(self): EXAMPLES:: - sage: BinaryTree().to_dyck_word_tamari() + sage: BinaryTree().to_dyck_word_tamari() # optional - sage.combinat [] - sage: BinaryTree([]).to_dyck_word_tamari() + sage: BinaryTree([]).to_dyck_word_tamari() # optional - sage.combinat [1, 0] - sage: BinaryTree([[None,[]],None]).to_dyck_word_tamari() + sage: BinaryTree([[None,[]],None]).to_dyck_word_tamari() # optional - sage.combinat [1, 1, 0, 0, 1, 0] - sage: BinaryTree([[[], [[], None]], [[], []]]).to_dyck_word_tamari() + sage: BinaryTree([[[], [[], None]], [[], []]]).to_dyck_word_tamari() # optional - sage.combinat [1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0] """ return self.to_dyck_word("L1R0") @@ -1128,7 +1128,9 @@ def tamari_join(self, other): ....: return True sage: all( test_uni_join(p, q) for p in BinaryTrees(3) for q in BinaryTrees(3) ) True - sage: p = BinaryTrees(6).random_element(); q = BinaryTrees(6).random_element(); test_uni_join(p, q) + sage: p = BinaryTrees(6).random_element() # optional - sage.combinat + sage: q = BinaryTrees(6).random_element() # optional - sage.combinat + sage: test_uni_join(p, q) # optional - sage.combinat True Border cases:: @@ -1215,7 +1217,9 @@ def tamari_meet(self, other, side="right"): ....: return True sage: all( test_uni_meet(p, q) for p in BinaryTrees(3) for q in BinaryTrees(3) ) True - sage: p = BinaryTrees(6).random_element(); q = BinaryTrees(6).random_element(); test_uni_meet(p, q) + sage: p = BinaryTrees(6).random_element() # optional - sage.combinat + sage: q = BinaryTrees(6).random_element() # optional - sage.combinat + sage: test_uni_meet(p, q) # optional - sage.combinat True Border cases:: @@ -1251,21 +1255,21 @@ def to_dyck_word(self, usemap="1L0R"): EXAMPLES:: - sage: BinaryTree().to_dyck_word() + sage: BinaryTree().to_dyck_word() # optional - sage.combinat [] - sage: BinaryTree([]).to_dyck_word() + sage: BinaryTree([]).to_dyck_word() # optional - sage.combinat [1, 0] - sage: BinaryTree([[[], [[], None]], [[], []]]).to_dyck_word() + sage: BinaryTree([[[], [[], None]], [[], []]]).to_dyck_word() # optional - sage.combinat [1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0] - sage: BinaryTree([[None,[]],None]).to_dyck_word() + sage: BinaryTree([[None,[]],None]).to_dyck_word() # optional - sage.combinat [1, 1, 0, 1, 0, 0] - sage: BinaryTree([[None,[]],None]).to_dyck_word("1R0L") + sage: BinaryTree([[None,[]],None]).to_dyck_word("1R0L") # optional - sage.combinat [1, 0, 1, 1, 0, 0] - sage: BinaryTree([[None,[]],None]).to_dyck_word("L1R0") + sage: BinaryTree([[None,[]],None]).to_dyck_word("L1R0") # optional - sage.combinat [1, 1, 0, 0, 1, 0] - sage: BinaryTree([[None,[]],None]).to_dyck_word("R1L0") + sage: BinaryTree([[None,[]],None]).to_dyck_word("R1L0") # optional - sage.combinat [1, 1, 0, 1, 0, 0] - sage: BinaryTree([[None,[]],None]).to_dyck_word("R10L") + sage: BinaryTree([[None,[]],None]).to_dyck_word("R10L") # optional - sage.combinat Traceback (most recent call last): ... ValueError: R10L is not a correct map @@ -1273,13 +1277,13 @@ def to_dyck_word(self, usemap="1L0R"): TESTS:: sage: bt = BinaryTree([[[], [[], None]], [[], []]]) - sage: bt == bt.to_dyck_word().to_binary_tree() + sage: bt == bt.to_dyck_word().to_binary_tree() # optional - sage.combinat True - sage: bt == bt.to_dyck_word("1R0L").to_binary_tree("1R0L") + sage: bt == bt.to_dyck_word("1R0L").to_binary_tree("1R0L") # optional - sage.combinat True - sage: bt == bt.to_dyck_word("L1R0").to_binary_tree("L1R0") + sage: bt == bt.to_dyck_word("L1R0").to_binary_tree("L1R0") # optional - sage.combinat True - sage: bt == bt.to_dyck_word("R1L0").to_binary_tree("R1L0") + sage: bt == bt.to_dyck_word("R1L0").to_binary_tree("R1L0") # optional - sage.combinat True """ from sage.combinat.dyck_word import DyckWord @@ -1443,9 +1447,9 @@ def tamari_sorting_tuple(self, reverse=False): ((1, 0, 0), 3), ((0, 0, 0), 3)] - sage: t = BinaryTrees(10).random_element() - sage: u = t.left_right_symmetry() - sage: t.tamari_sorting_tuple(True) == u.tamari_sorting_tuple() + sage: t = BinaryTrees(10).random_element() # optional - sage.combinat + sage: u = t.left_right_symmetry() # optional - sage.combinat + sage: t.tamari_sorting_tuple(True) == u.tamari_sorting_tuple() # optional - sage.combinat True REFERENCES: @@ -1612,8 +1616,9 @@ def to_tilting(self): [(0, 1), (2, 3), (4, 5), (6, 7), (4, 7), (8, 9), (10, 11), (8, 11), (4, 11), (12, 13), (4, 13), (2, 13), (0, 13)] - sage: t2 = DyckWord([1,1,1,1,0,1,1,0,0,0,1,1,0,1,0,1,1,0,1,1,0,0,0,0,0,0]).to_binary_tree() - sage: len(t2.to_tilting()) == t2.node_number() + sage: w = DyckWord([1,1,1,1,0,1,1,0,0,0,1,1,0,1,0,1,1,0,1,1,0,0,0,0,0,0]) # optional - sage.combinat + sage: t2 = w.to_binary_tree() # optional - sage.combinat + sage: len(t2.to_tilting()) == t2.node_number() # optional - sage.combinat True """ if not self: @@ -2827,36 +2832,36 @@ def q_hook_length_fraction(self, q=None, q_factor=False): only one vertex (which is a leaf):: sage: b = BinaryTree() - sage: b.q_hook_length_fraction() + sage: b.q_hook_length_fraction() # optional - sage.combinat 1 - sage: b.q_hook_length_fraction(q_factor=True) + sage: b.q_hook_length_fraction(q_factor=True) # optional - sage.combinat 1 Nothing different for a tree with one node and two leaves:: sage: b = BinaryTree([]); b [., .] - sage: b.q_hook_length_fraction() + sage: b.q_hook_length_fraction() # optional - sage.combinat 1 - sage: b.q_hook_length_fraction(q_factor=True) + sage: b.q_hook_length_fraction(q_factor=True) # optional - sage.combinat 1 Let us get to a more interesting tree:: sage: b = BinaryTree([[[],[]],[[],None]]); b [[[., .], [., .]], [[., .], .]] - sage: b.q_hook_length_fraction()(q=1) + sage: b.q_hook_length_fraction()(q=1) # optional - sage.combinat 20 - sage: b.q_hook_length_fraction() + sage: b.q_hook_length_fraction() # optional - sage.combinat q^7 + 2*q^6 + 3*q^5 + 4*q^4 + 4*q^3 + 3*q^2 + 2*q + 1 - sage: b.q_hook_length_fraction(q_factor=True) + sage: b.q_hook_length_fraction(q_factor=True) # optional - sage.combinat q^10 + 2*q^9 + 3*q^8 + 4*q^7 + 4*q^6 + 3*q^5 + 2*q^4 + q^3 - sage: b.q_hook_length_fraction(q=2) + sage: b.q_hook_length_fraction(q=2) # optional - sage.combinat 465 - sage: b.q_hook_length_fraction(q=2, q_factor=True) + sage: b.q_hook_length_fraction(q=2, q_factor=True) # optional - sage.combinat 3720 sage: q = PolynomialRing(ZZ, 'q').gen() - sage: b.q_hook_length_fraction(q=q**2) + sage: b.q_hook_length_fraction(q=q**2) # optional - sage.combinat q^14 + 2*q^12 + 3*q^10 + 4*q^8 + 4*q^6 + 3*q^4 + 2*q^2 + 1 Let us check the fact that `f_{q} (T)` is the generating function @@ -2875,7 +2880,7 @@ def q_hook_length_fraction(self, q=None, q_factor=False): ....: return all( q_hook_length_fraction_2(T) ....: == T.q_hook_length_fraction(q_factor=True) ....: for T in BinaryTrees(i) ) - sage: test_genfun(4) + sage: test_genfun(4) # optional - sage.combinat True """ from sage.combinat.q_analogues import q_binomial @@ -3394,29 +3399,29 @@ def dendriform_shuffle(self, other): sage: l = BinaryTree([g, u]) sage: r = BinaryTree([u, g]) - sage: list(g.dendriform_shuffle(g)) + sage: list(g.dendriform_shuffle(g)) # optional - sage.combinat [[[., .], .], [., [., .]]] - sage: list(l.dendriform_shuffle(l)) + sage: list(l.dendriform_shuffle(l)) # optional - sage.combinat [[[[[., .], .], .], .], [[[., .], [., .]], .], [[., .], [[., .], .]]] - sage: list(l.dendriform_shuffle(r)) + sage: list(l.dendriform_shuffle(r)) # optional - sage.combinat [[[[., .], .], [., .]], [[., .], [., [., .]]]] TESTS:: - sage: list(u.dendriform_shuffle(u)) + sage: list(u.dendriform_shuffle(u)) # optional - sage.combinat [.] - sage: list(u.dendriform_shuffle(g)) + sage: list(u.dendriform_shuffle(g)) # optional - sage.combinat [[., .]] - sage: list(u.dendriform_shuffle(l)) + sage: list(u.dendriform_shuffle(l)) # optional - sage.combinat [[[., .], .]] - sage: list(u.dendriform_shuffle(r)) + sage: list(u.dendriform_shuffle(r)) # optional - sage.combinat [[., [., .]]] - sage: list(r.dendriform_shuffle(u)) + sage: list(r.dendriform_shuffle(u)) # optional - sage.combinat [[., [., .]]] - sage: list(l.dendriform_shuffle(u)) + sage: list(l.dendriform_shuffle(u)) # optional - sage.combinat [[[., .], .]] """ from sage.combinat.words.shuffle_product import ShuffleProduct_w1w2 @@ -3526,32 +3531,32 @@ def sylvester_class(self, left_to_right=False): ....: if not BinaryTree(tree) == t: ....: return False ....: return True - sage: test_bst_of_sc(4, False) + sage: test_bst_of_sc(4, False) # optional - sage.combinat True - sage: test_bst_of_sc(5, False) # long time + sage: test_bst_of_sc(5, False) # long time # optional - sage.combinat True The same with the left-to-right version of binary search:: - sage: test_bst_of_sc(4, True) + sage: test_bst_of_sc(4, True) # optional - sage.combinat True - sage: test_bst_of_sc(5, True) # long time + sage: test_bst_of_sc(5, True) # long time # optional - sage.combinat True Checking that the sylvester class is the set of linear extensions of the poset of the tree:: - sage: all( sorted(t.canonical_labelling().sylvester_class()) + sage: all( sorted(t.canonical_labelling().sylvester_class()) # optional - sage.combinat ....: == sorted(list(v) for v in t.canonical_labelling().to_poset().linear_extensions()) ....: for t in BinaryTrees(4) ) True TESTS:: - sage: list(BinaryTree([[],[]]).sylvester_class()) + sage: list(BinaryTree([[],[]]).sylvester_class()) # optional - sage.combinat [[1, 3, 2], [3, 1, 2]] sage: bt = BinaryTree([[[],None],[[],[]]]) - sage: l = list(bt.sylvester_class()); l + sage: l = list(bt.sylvester_class()); l # optional - sage.combinat [[1, 2, 4, 6, 5, 3], [1, 4, 2, 6, 5, 3], [1, 4, 6, 2, 5, 3], @@ -3572,14 +3577,14 @@ def sylvester_class(self, left_to_right=False): [6, 4, 1, 2, 5, 3], [6, 4, 1, 5, 2, 3], [6, 4, 5, 1, 2, 3]] - sage: len(l) == Integer(bt.q_hook_length_fraction()(q=1)) + sage: len(l) == Integer(bt.q_hook_length_fraction()(q=1)) # optional - sage.combinat True Border cases:: - sage: list(BinaryTree().sylvester_class()) + sage: list(BinaryTree().sylvester_class()) # optional - sage.combinat [[]] - sage: list(BinaryTree([]).sylvester_class()) + sage: list(BinaryTree([]).sylvester_class()) # optional - sage.combinat [[1]] """ if self.is_empty(): @@ -4045,8 +4050,8 @@ def from_tamari_sorting_tuple(key): EXAMPLES:: sage: from sage.combinat.binary_tree import from_tamari_sorting_tuple - sage: t = BinaryTrees(60).random_element() - sage: from_tamari_sorting_tuple(t.tamari_sorting_tuple()[0]) == t + sage: t = BinaryTrees(60).random_element() # optional - sage.combinat + sage: from_tamari_sorting_tuple(t.tamari_sorting_tuple()[0]) == t # optional - sage.combinat True """ if not key: @@ -4250,16 +4255,17 @@ def random_element(self): EXAMPLES:: - sage: BinaryTrees(5).random_element() # random + sage: BinaryTrees(5).random_element() # random # optional - sage.combinat [., [., [., [., [., .]]]]] - sage: BinaryTrees(0).random_element() + sage: BinaryTrees(0).random_element() # optional - sage.combinat . - sage: BinaryTrees(1).random_element() + sage: BinaryTrees(1).random_element() # optional - sage.combinat [., .] TESTS:: - sage: all(BinaryTrees(10).random_element() in BinaryTrees(10) for i in range(20)) + sage: all(BinaryTrees(10).random_element() in BinaryTrees(10) # optional - sage.combinat + ....: for i in range(20)) True """ from sage.combinat.dyck_word import CompleteDyckWords_size @@ -4504,17 +4510,17 @@ def random_element(self): EXAMPLES:: - sage: BinaryTrees(5, full=True).random_element() # random + sage: BinaryTrees(5, full=True).random_element() # random # optional - sage.combinat [[], [[], []]] - sage: BinaryTrees(0, full=True).random_element() + sage: BinaryTrees(0, full=True).random_element() # optional - sage.combinat . - sage: BinaryTrees(1, full=True).random_element() + sage: BinaryTrees(1, full=True).random_element() # optional - sage.combinat [., .] TESTS:: sage: B = BinaryTrees(19, full=True) - sage: all(B.random_element() in B for i in range(20)) + sage: all(B.random_element() in B for i in range(20)) # optional - sage.combinat True """ from sage.combinat.dyck_word import CompleteDyckWords_size diff --git a/src/sage/combinat/cluster_algebra_quiver/interact.py b/src/sage/combinat/cluster_algebra_quiver/interact.py index f0225803be1..bf4bb87aba3 100644 --- a/src/sage/combinat/cluster_algebra_quiver/interact.py +++ b/src/sage/combinat/cluster_algebra_quiver/interact.py @@ -25,8 +25,8 @@ def cluster_interact(self, fig_size=1, circular=True, kind='seed'): TESTS:: - sage: S = ClusterSeed(['A',4]) - sage: S.interact() # indirect doctest # optional - sage.symbolic + sage: S = ClusterSeed(['A',4]) # optional - sage.graphs + sage: S.interact() # indirect doctest # optional - sage.graphs sage.symbolic ...VBox(children=... """ if kind not in ['seed', 'quiver']: diff --git a/src/sage/combinat/combinat.py b/src/sage/combinat/combinat.py index 22a314d2636..1f43062827b 100644 --- a/src/sage/combinat/combinat.py +++ b/src/sage/combinat/combinat.py @@ -359,7 +359,7 @@ def bell_number(n, algorithm='flint', **options) -> Integer: sage: k = bell_number(30, 'mpmath', prec=15); k # optional - mpmath 846749014511809388871680 - sage: k == bell_number(30) # optional - mpmath + sage: k == bell_number(30) # optional - mpmath sage.libs.flint False TESTS:: diff --git a/src/sage/combinat/combinat_cython.pyx b/src/sage/combinat/combinat_cython.pyx index 1f8c56cc16d..af9c901e6a9 100644 --- a/src/sage/combinat/combinat_cython.pyx +++ b/src/sage/combinat/combinat_cython.pyx @@ -711,7 +711,7 @@ def set_partition_composition(tuple sp1, tuple sp2): sage: sp1 = ((1,-2),(2,-1)) sage: sp2 = ((1,-2),(2,-1)) sage: p, c = set_partition_composition(sp1, sp2) - sage: (SetPartition(p), c) == (SetPartition([[1,-1],[2,-2]]), 0) + sage: (SetPartition(p), c) == (SetPartition([[1,-1],[2,-2]]), 0) # optional - sage.combinat True """ cdef int num_loops = 0 # The number of loops removed diff --git a/src/sage/combinat/designs/bibd.py b/src/sage/combinat/designs/bibd.py index 2265e113040..2155f42be02 100644 --- a/src/sage/combinat/designs/bibd.py +++ b/src/sage/combinat/designs/bibd.py @@ -84,7 +84,7 @@ def biplane(n, existence=False): EXAMPLES:: - sage: designs.biplane(4) + sage: designs.biplane(4) # optional - sage.rings.finite_rings (16,6,2)-Balanced Incomplete Block Design sage: designs.biplane(7, existence=True) True @@ -1314,14 +1314,14 @@ def BIBD_from_arc_in_desarguesian_projective_plane(n,k,existence=False): sage: from sage.combinat.designs.bibd import BIBD_from_arc_in_desarguesian_projective_plane sage: from sage.combinat.designs.bibd import BalancedIncompleteBlockDesign - sage: D = BIBD_from_arc_in_desarguesian_projective_plane(232,8) - sage: BalancedIncompleteBlockDesign(232,D) + sage: D = BIBD_from_arc_in_desarguesian_projective_plane(232,8) # optional - sage.libs.gap sage.modules sage.rings.finite_rings + sage: BalancedIncompleteBlockDesign(232,D) # optional - sage.libs.gap sage.modules sage.rings.finite_rings (232,8,1)-Balanced Incomplete Block Design A `(120,8,1)`-BIBD:: - sage: D = BIBD_from_arc_in_desarguesian_projective_plane(120,8) - sage: BalancedIncompleteBlockDesign(120,D) + sage: D = BIBD_from_arc_in_desarguesian_projective_plane(120,8) # optional - sage.libs.gap sage.modules sage.rings.finite_rings + sage: BalancedIncompleteBlockDesign(120,D) # optional - sage.libs.gap sage.modules sage.rings.finite_rings (120,8,1)-Balanced Incomplete Block Design Other parameters:: diff --git a/src/sage/combinat/designs/block_design.py b/src/sage/combinat/designs/block_design.py index 1d189fdd409..6e618e36d89 100644 --- a/src/sage/combinat/designs/block_design.py +++ b/src/sage/combinat/designs/block_design.py @@ -318,15 +318,15 @@ def DesarguesianProjectivePlaneDesign(n, point_coordinates=True, check=True): EXAMPLES:: - sage: designs.DesarguesianProjectivePlaneDesign(2) + sage: designs.DesarguesianProjectivePlaneDesign(2) # optional - sage.rings.finite_rings (7,3,1)-Balanced Incomplete Block Design - sage: designs.DesarguesianProjectivePlaneDesign(3) + sage: designs.DesarguesianProjectivePlaneDesign(3) # optional - sage.rings.finite_rings (13,4,1)-Balanced Incomplete Block Design - sage: designs.DesarguesianProjectivePlaneDesign(4) + sage: designs.DesarguesianProjectivePlaneDesign(4) # optional - sage.rings.finite_rings (21,5,1)-Balanced Incomplete Block Design - sage: designs.DesarguesianProjectivePlaneDesign(5) + sage: designs.DesarguesianProjectivePlaneDesign(5) # optional - sage.rings.finite_rings (31,6,1)-Balanced Incomplete Block Design - sage: designs.DesarguesianProjectivePlaneDesign(6) + sage: designs.DesarguesianProjectivePlaneDesign(6) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: the order of a finite field must be a prime power @@ -400,20 +400,20 @@ def q3_minus_one_matrix(K): EXAMPLES:: sage: from sage.combinat.designs.block_design import q3_minus_one_matrix - sage: m = q3_minus_one_matrix(GF(3)) - sage: m.multiplicative_order() == 3**3 - 1 # optional - sage.symbolic + sage: m = q3_minus_one_matrix(GF(3)) # optional - sage.rings.finite_rings + sage: m.multiplicative_order() == 3**3 - 1 # optional - sage.rings.finite_rings True - sage: m = q3_minus_one_matrix(GF(4, 'a')) # optional - sage.symbolic - sage: m.multiplicative_order() == 4**3 - 1 # optional - sage.symbolic + sage: m = q3_minus_one_matrix(GF(4, 'a')) # optional - sage.rings.finite_rings + sage: m.multiplicative_order() == 4**3 - 1 # optional - sage.rings.finite_rings True - sage: m = q3_minus_one_matrix(GF(5)) - sage: m.multiplicative_order() == 5**3 - 1 # optional - sage.symbolic + sage: m = q3_minus_one_matrix(GF(5)) # optional - sage.rings.finite_rings + sage: m.multiplicative_order() == 5**3 - 1 # optional - sage.rings.finite_rings True - sage: m = q3_minus_one_matrix(GF(9, 'a')) # optional - sage.symbolic - sage: m.multiplicative_order() == 9**3 - 1 # optional - sage.symbolic + sage: m = q3_minus_one_matrix(GF(9, 'a')) # optional - sage.rings.finite_rings + sage: m.multiplicative_order() == 9**3 - 1 # optional - sage.rings.finite_rings True """ q = K.cardinality() @@ -457,17 +457,17 @@ def normalize_hughes_plane_point(p, q): EXAMPLES:: sage: from sage.combinat.designs.block_design import normalize_hughes_plane_point - sage: K = FiniteField(9,'x') - sage: x = K.gen() - sage: normalize_hughes_plane_point((x, x+1, x), 9) + sage: K = FiniteField(9,'x') # optional - sage.rings.finite_rings + sage: x = K.gen() # optional - sage.rings.finite_rings + sage: normalize_hughes_plane_point((x, x+1, x), 9) # optional - sage.rings.finite_rings (1, x, 1) - sage: normalize_hughes_plane_point(vector((x,x,x)), 9) + sage: normalize_hughes_plane_point(vector((x,x,x)), 9) # optional - sage.rings.finite_rings (1, 1, 1) - sage: zero = K.zero() - sage: normalize_hughes_plane_point((2*x+2, zero, zero), 9) + sage: zero = K.zero() # optional - sage.rings.finite_rings + sage: normalize_hughes_plane_point((2*x+2, zero, zero), 9) # optional - sage.rings.finite_rings (1, 0, 0) - sage: one = K.one() - sage: normalize_hughes_plane_point((2*x, one, zero), 9) + sage: one = K.one() # optional - sage.rings.finite_rings + sage: normalize_hughes_plane_point((2*x, one, zero), 9) # optional - sage.rings.finite_rings (2*x, 1, 0) """ for i in [2,1,0]: @@ -526,8 +526,7 @@ def HughesPlane(q2, check=True): EXAMPLES:: - sage: H = designs.HughesPlane(9) - sage: H + sage: H = designs.HughesPlane(9); H # optional - sage.rings.finite_rings (91,10,1)-Balanced Incomplete Block Design We prove in the following computations that the Desarguesian plane ``H`` is @@ -536,45 +535,45 @@ def HughesPlane(q2, check=True): `D_{1,10} \cap D_{70,59}` and `D_{10,0} \cap D_{59,57}` are on the same line while `D_{0,70}`, `D_{1,59}` and `D_{10,57}` are not concurrent:: - sage: blocks = H.blocks() - sage: line = lambda p,q: next(b for b in blocks if p in b and q in b) + sage: blocks = H.blocks() # optional - sage.rings.finite_rings + sage: line = lambda p,q: next(b for b in blocks if p in b and q in b) # optional - sage.rings.finite_rings - sage: b_0_1 = line(0, 1) - sage: b_1_10 = line(1, 10) - sage: b_10_0 = line(10, 0) - sage: b_57_70 = line(57, 70) - sage: b_70_59 = line(70, 59) - sage: b_59_57 = line(59, 57) + sage: b_0_1 = line(0, 1) # optional - sage.rings.finite_rings + sage: b_1_10 = line(1, 10) # optional - sage.rings.finite_rings + sage: b_10_0 = line(10, 0) # optional - sage.rings.finite_rings + sage: b_57_70 = line(57, 70) # optional - sage.rings.finite_rings + sage: b_70_59 = line(70, 59) # optional - sage.rings.finite_rings + sage: b_59_57 = line(59, 57) # optional - sage.rings.finite_rings - sage: set(b_0_1).intersection(b_57_70) + sage: set(b_0_1).intersection(b_57_70) # optional - sage.rings.finite_rings {2} - sage: set(b_1_10).intersection(b_70_59) + sage: set(b_1_10).intersection(b_70_59) # optional - sage.rings.finite_rings {73} - sage: set(b_10_0).intersection(b_59_57) + sage: set(b_10_0).intersection(b_59_57) # optional - sage.rings.finite_rings {60} - sage: line(2, 73) == line(73, 60) + sage: line(2, 73) == line(73, 60) # optional - sage.rings.finite_rings True - sage: b_0_57 = line(0, 57) - sage: b_1_70 = line(1, 70) - sage: b_10_59 = line(10, 59) + sage: b_0_57 = line(0, 57) # optional - sage.rings.finite_rings + sage: b_1_70 = line(1, 70) # optional - sage.rings.finite_rings + sage: b_10_59 = line(10, 59) # optional - sage.rings.finite_rings - sage: p = set(b_0_57).intersection(b_1_70) - sage: q = set(b_1_70).intersection(b_10_59) - sage: p == q + sage: p = set(b_0_57).intersection(b_1_70) # optional - sage.rings.finite_rings + sage: q = set(b_1_70).intersection(b_10_59) # optional - sage.rings.finite_rings + sage: p == q # optional - sage.rings.finite_rings False TESTS: Some wrong input:: - sage: designs.HughesPlane(5) + sage: designs.HughesPlane(5) # optional - sage.rings.finite_rings Traceback (most recent call last): ... EmptySetError: No Hughes plane of non-square order exists. - sage: designs.HughesPlane(16) + sage: designs.HughesPlane(16) # optional - sage.rings.finite_rings Traceback (most recent call last): ... EmptySetError: No Hughes plane of even order exists. @@ -645,11 +644,13 @@ def projective_plane_to_OA(pplane, pt=None, check=True): EXAMPLES:: sage: from sage.combinat.designs.block_design import projective_plane_to_OA - sage: p2 = designs.DesarguesianProjectivePlaneDesign(2,point_coordinates=False) - sage: projective_plane_to_OA(p2) + sage: p2 = designs.DesarguesianProjectivePlaneDesign(2, # optional - sage.rings.finite_rings + ....: point_coordinates=False) + sage: projective_plane_to_OA(p2) # optional - sage.rings.finite_rings [[0, 0, 0], [0, 1, 1], [1, 0, 1], [1, 1, 0]] - sage: p3 = designs.DesarguesianProjectivePlaneDesign(3,point_coordinates=False) - sage: projective_plane_to_OA(p3) + sage: p3 = designs.DesarguesianProjectivePlaneDesign(3, # optional - sage.rings.finite_rings + ....: point_coordinates=False) + sage: projective_plane_to_OA(p3) # optional - sage.rings.finite_rings [[0, 0, 0, 0], [0, 1, 2, 1], [0, 2, 1, 2], @@ -660,10 +661,11 @@ def projective_plane_to_OA(pplane, pt=None, check=True): [2, 1, 0, 2], [2, 2, 2, 0]] - sage: pp = designs.DesarguesianProjectivePlaneDesign(16,point_coordinates=False) - sage: _ = projective_plane_to_OA(pp, pt=0) - sage: _ = projective_plane_to_OA(pp, pt=3) - sage: _ = projective_plane_to_OA(pp, pt=7) + sage: pp = designs.DesarguesianProjectivePlaneDesign(16, # optional - sage.rings.finite_rings + ....: point_coordinates=False) + sage: _ = projective_plane_to_OA(pp, pt=0) # optional - sage.rings.finite_rings + sage: _ = projective_plane_to_OA(pp, pt=3) # optional - sage.rings.finite_rings + sage: _ = projective_plane_to_OA(pp, pt=7) # optional - sage.rings.finite_rings """ from .bibd import _relabel_bibd pplane = pplane.blocks() @@ -811,27 +813,29 @@ def AffineGeometryDesign(n, d, F, point_coordinates=True, check=True): EXAMPLES:: - sage: BD = designs.AffineGeometryDesign(3, 1, GF(2)) - sage: BD.is_t_design(return_parameters=True) + sage: BD = designs.AffineGeometryDesign(3, 1, GF(2)) # optional - sage.rings.finite_rings + sage: BD.is_t_design(return_parameters=True) # optional - sage.rings.finite_rings (True, (2, 8, 2, 1)) - sage: BD = designs.AffineGeometryDesign(3, 2, GF(4)) - sage: BD.is_t_design(return_parameters=True) + sage: BD = designs.AffineGeometryDesign(3, 2, GF(4)) # optional - sage.rings.finite_rings + sage: BD.is_t_design(return_parameters=True) # optional - sage.rings.finite_rings (True, (2, 64, 16, 5)) - sage: BD = designs.AffineGeometryDesign(4, 2, GF(3)) - sage: BD.is_t_design(return_parameters=True) + sage: BD = designs.AffineGeometryDesign(4, 2, GF(3)) # optional - sage.rings.finite_rings + sage: BD.is_t_design(return_parameters=True) # optional - sage.rings.finite_rings (True, (2, 81, 9, 13)) With ``F`` an integer instead of a finite field:: - sage: BD = designs.AffineGeometryDesign(3, 2, 4) - sage: BD.is_t_design(return_parameters=True) + sage: BD = designs.AffineGeometryDesign(3, 2, 4) # optional - sage.rings.finite_rings + sage: BD.is_t_design(return_parameters=True) # optional - sage.rings.finite_rings (True, (2, 64, 16, 5)) Testing the option ``point_coordinates``:: - sage: designs.AffineGeometryDesign(3, 1, GF(2), point_coordinates=True).blocks()[0] + sage: designs.AffineGeometryDesign(3, 1, GF(2), # optional - sage.rings.finite_rings + ....: point_coordinates=True).blocks()[0] [(0, 0, 0), (0, 0, 1)] - sage: designs.AffineGeometryDesign(3, 1, GF(2), point_coordinates=False).blocks()[0] + sage: designs.AffineGeometryDesign(3, 1, GF(2), # optional - sage.rings.finite_rings + ....: point_coordinates=False).blocks()[0] [0, 1] """ try: @@ -894,10 +898,10 @@ def CremonaRichmondConfiguration(): EXAMPLES:: - sage: H = designs.CremonaRichmondConfiguration(); H + sage: H = designs.CremonaRichmondConfiguration(); H # optional - networkx Incidence structure with 15 points and 15 blocks - sage: g = graphs.TutteCoxeterGraph() - sage: H.incidence_graph().is_isomorphic(g) + sage: g = graphs.TutteCoxeterGraph() # optional - networkx + sage: H.incidence_graph().is_isomorphic(g) # optional - networkx True """ from sage.graphs.generators.smallgraphs import TutteCoxeterGraph diff --git a/src/sage/combinat/designs/database.py b/src/sage/combinat/designs/database.py index 57060962e69..21039998b45 100644 --- a/src/sage/combinat/designs/database.py +++ b/src/sage/combinat/designs/database.py @@ -81,7 +81,7 @@ def _MOLS_from_string(s,k): EXAMPLES:: - sage: _ = designs.mutually_orthogonal_latin_squares(2,10) # indirect doctest + sage: _ = designs.mutually_orthogonal_latin_squares(2,10) # indirect doctest # optional - sage.modules """ from sage.matrix.constructor import Matrix matrices = [[] for _ in range(k)] @@ -101,13 +101,13 @@ def MOLS_10_2(): sage: from sage.combinat.designs.latin_squares import are_mutually_orthogonal_latin_squares sage: from sage.combinat.designs.database import MOLS_10_2 - sage: MOLS = MOLS_10_2() - sage: print(are_mutually_orthogonal_latin_squares(MOLS)) + sage: MOLS = MOLS_10_2() # optional - sage.modules + sage: print(are_mutually_orthogonal_latin_squares(MOLS)) # optional - sage.modules True The design is available from the general constructor:: - sage: designs.orthogonal_arrays.is_available(2,10) + sage: designs.orthogonal_arrays.is_available(2,10) # optional - sage.modules True """ from sage.matrix.constructor import Matrix @@ -143,8 +143,8 @@ def MOLS_12_5(): sage: from sage.combinat.designs.latin_squares import are_mutually_orthogonal_latin_squares sage: from sage.combinat.designs.database import MOLS_12_5 - sage: MOLS = MOLS_12_5() - sage: print(are_mutually_orthogonal_latin_squares(MOLS)) + sage: MOLS = MOLS_12_5() # optional - sage.modules + sage: print(are_mutually_orthogonal_latin_squares(MOLS)) # optional - sage.modules True """ M = """ @@ -175,8 +175,8 @@ def MOLS_14_4(): sage: from sage.combinat.designs.latin_squares import are_mutually_orthogonal_latin_squares sage: from sage.combinat.designs.database import MOLS_14_4 - sage: MOLS = MOLS_14_4() - sage: print(are_mutually_orthogonal_latin_squares(MOLS)) + sage: MOLS = MOLS_14_4() # optional - sage.modules + sage: print(are_mutually_orthogonal_latin_squares(MOLS)) # optional - sage.modules True The design is available from the general constructor:: @@ -219,8 +219,8 @@ def MOLS_15_4(): sage: from sage.combinat.designs.latin_squares import are_mutually_orthogonal_latin_squares sage: from sage.combinat.designs.database import MOLS_15_4 - sage: MOLS = MOLS_15_4() - sage: print(are_mutually_orthogonal_latin_squares(MOLS)) + sage: MOLS = MOLS_15_4() # optional - sage.modules + sage: print(are_mutually_orthogonal_latin_squares(MOLS)) # optional - sage.modules True The design is available from the general constructor:: @@ -258,8 +258,8 @@ def MOLS_18_3(): sage: from sage.combinat.designs.latin_squares import are_mutually_orthogonal_latin_squares sage: from sage.combinat.designs.database import MOLS_18_3 - sage: MOLS = MOLS_18_3() - sage: print(are_mutually_orthogonal_latin_squares(MOLS)) + sage: MOLS = MOLS_18_3() # optional - sage.modules + sage: print(are_mutually_orthogonal_latin_squares(MOLS)) # optional - sage.modules True The design is available from the general constructor:: @@ -377,8 +377,8 @@ def OA_9_40(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_9_40 - sage: OA = OA_9_40() - sage: is_orthogonal_array(OA,9,40,2) + sage: OA = OA_9_40() # optional - sage.rings.finite_rings + sage: is_orthogonal_array(OA,9,40,2) # optional - sage.rings.finite_rings True The design is available from the general constructor:: @@ -676,8 +676,8 @@ def OA_11_80(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_11_80 - sage: OA = OA_11_80() - sage: is_orthogonal_array(OA,11,80,2) + sage: OA = OA_11_80() # optional - sage.rings.finite_rings + sage: is_orthogonal_array(OA,11,80,2) # optional - sage.rings.finite_rings True The design is available from the general constructor:: @@ -718,8 +718,8 @@ def OA_15_112(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_15_112 - sage: OA = OA_15_112() - sage: is_orthogonal_array(OA,15,112,2) + sage: OA = OA_15_112() # optional - sage.rings.finite_rings + sage: is_orthogonal_array(OA,15,112,2) # optional - sage.rings.finite_rings True The design is available from the general constructor:: @@ -768,8 +768,8 @@ def OA_9_120(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_9_120 - sage: OA = OA_9_120() - sage: is_orthogonal_array(OA,9,120,2) + sage: OA = OA_9_120() # optional - sage.modules + sage: is_orthogonal_array(OA,9,120,2) # optional - sage.modules True The design is available from the general constructor:: @@ -816,8 +816,8 @@ def OA_9_135(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_9_135 - sage: OA = OA_9_135() - sage: is_orthogonal_array(OA,9,135,2) + sage: OA = OA_9_135() # optional - sage.rings.finite_rings + sage: is_orthogonal_array(OA,9,135,2) # optional - sage.rings.finite_rings True The design is available from the general constructor:: @@ -896,8 +896,8 @@ def OA_11_160(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_11_160 - sage: OA = OA_11_160() - sage: is_orthogonal_array(OA,11,160,2) + sage: OA = OA_11_160() # optional - sage.rings.finite_rings + sage: is_orthogonal_array(OA,11,160,2) # optional - sage.rings.finite_rings True The design is available from the general constructor:: @@ -939,8 +939,8 @@ def OA_16_176(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_16_176 - sage: OA = OA_16_176() - sage: is_orthogonal_array(OA,16,176,2) + sage: OA = OA_16_176() # optional - sage.rings.finite_rings + sage: is_orthogonal_array(OA,16,176,2) # optional - sage.rings.finite_rings True The design is available from the general constructor:: @@ -998,8 +998,8 @@ def OA_11_185(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_11_185 - sage: OA = OA_11_185() - sage: is_orthogonal_array(OA,11,185,2) + sage: OA = OA_11_185() # optional - sage.rings.finite_rings + sage: is_orthogonal_array(OA,11,185,2) # optional - sage.rings.finite_rings True The design is available from the general constructor:: @@ -1138,8 +1138,8 @@ def OA_16_208(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_16_208 - sage: OA = OA_16_208() # not tested -- too long - sage: is_orthogonal_array(OA,16,208,2) # not tested -- too long + sage: OA = OA_16_208() # not tested -- too long # optional - sage.rings.finite_rings + sage: is_orthogonal_array(OA,16,208,2) # not tested -- too long # optional - sage.rings.finite_rings True The design is available from the general constructor:: @@ -1197,8 +1197,8 @@ def OA_15_224(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_15_224 - sage: OA = OA_15_224() # not tested -- too long - sage: is_orthogonal_array(OA,15,224,2) # not tested -- too long + sage: OA = OA_15_224() # not tested -- too long # optional - sage.rings.finite_rings + sage: is_orthogonal_array(OA,15,224,2) # not tested -- too long # optional - sage.rings.finite_rings True The design is available from the general constructor:: @@ -1283,8 +1283,8 @@ def OA_20_352(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_20_352 - sage: OA = OA_20_352() # not tested (~25s) - sage: is_orthogonal_array(OA,20,352,2) # not tested (~25s) + sage: OA = OA_20_352() # not tested (~25s) # optional - sage.rings.finite_rings + sage: is_orthogonal_array(OA,20,352,2) # not tested (~25s) # optional - sage.rings.finite_rings True The design is available from the general constructor:: @@ -1342,8 +1342,8 @@ def OA_20_416(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_20_416 - sage: OA = OA_20_416() # not tested (~35s) - sage: is_orthogonal_array(OA,20,416,2) # not tested + sage: OA = OA_20_416() # not tested (~35s) # optional - sage.rings.finite_rings + sage: is_orthogonal_array(OA,20,416,2) # not tested # optional - sage.rings.finite_rings True The design is available from the general constructor:: @@ -1402,8 +1402,8 @@ def OA_20_544(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_20_544 - sage: OA = OA_20_544() # not tested (too long ~1mn) - sage: is_orthogonal_array(OA,20,544,2) # not tested + sage: OA = OA_20_544() # not tested (too long ~1mn) # optional - sage.rings.finite_rings + sage: is_orthogonal_array(OA,20,544,2) # not tested # optional - sage.rings.finite_rings True The design is available from the general constructor:: @@ -1466,8 +1466,8 @@ def OA_17_560(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_17_560 - sage: OA = OA_17_560() - sage: is_orthogonal_array(OA,17,560,2) + sage: OA = OA_17_560() # optional - sage.rings.finite_rings + sage: is_orthogonal_array(OA,17,560,2) # optional - sage.rings.finite_rings True The design is available from the general constructor:: @@ -1530,8 +1530,8 @@ def OA_11_640(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_11_640 - sage: OA = OA_11_640() # not tested (too long) - sage: is_orthogonal_array(OA,11,640,2) # not tested (too long) + sage: OA = OA_11_640() # not tested (too long) # optional - sage.rings.finite_rings + sage: is_orthogonal_array(OA,11,640,2) # not tested (too long) # optional - sage.rings.finite_rings True The design is available from the general constructor:: @@ -1857,8 +1857,8 @@ def OA_15_896(): sage: from sage.combinat.designs.designs_pyx import is_orthogonal_array sage: from sage.combinat.designs.database import OA_15_896 - sage: OA = OA_15_896() # not tested -- too long (~2min) - sage: is_orthogonal_array(OA,15,896,2) # not tested -- too long + sage: OA = OA_15_896() # not tested -- too long (~2min) # optional - sage.rings.finite_rings + sage: is_orthogonal_array(OA,15,896,2) # not tested -- too long # optional - sage.rings.finite_rings True The design is available from the general constructor:: @@ -2194,8 +2194,8 @@ def QDM_25_6_1_1_5(): sage: from sage.combinat.designs.database import QDM_25_6_1_1_5 sage: from sage.combinat.designs.designs_pyx import is_quasi_difference_matrix - sage: G,M = QDM_25_6_1_1_5() - sage: is_quasi_difference_matrix(M,G,6,1,1,5) + sage: G,M = QDM_25_6_1_1_5() # optional - sage.modules + sage: is_quasi_difference_matrix(M,G,6,1,1,5) # optional - sage.modules True """ M = [ @@ -2718,7 +2718,7 @@ def QDM_57_9_1_1_8(): sage: from sage.combinat.designs.designs_pyx import is_quasi_difference_matrix sage: from sage.combinat.designs.orthogonal_arrays import QDM_from_Vmt sage: from sage.combinat.designs.database import Vmt_vectors - sage: for (m,t),(vec,source) in sorted(Vmt_vectors.items()): + sage: for (m,t),(vec,source) in sorted(Vmt_vectors.items()): # optional - sage.rings.finite_rings ....: G,M = QDM_from_Vmt(m,t,vec) ....: if m*t < 600: ....: assert is_quasi_difference_matrix(M,G,m+2,1,1,t,verbose=1),(m,t) @@ -3147,7 +3147,7 @@ def DM_12_6_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(12,6) + sage: _ = designs.difference_matrix(12,6) # optional - sage.rings.finite_rings REFERENCES: @@ -3189,7 +3189,7 @@ def DM_21_6_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(21,6) + sage: _ = designs.difference_matrix(21,6) # optional - sage.rings.finite_rings """ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing as AdditiveCyclic M = [[ 8, 17, 20, 2], @@ -3224,7 +3224,7 @@ def DM_24_8_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(24,8) + sage: _ = designs.difference_matrix(24,8) # optional - sage.rings.finite_rings """ M = ("0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 "+ "0000 0010 0100 0110 1000 1010 1100 1110 2000 2010 2100 2110 "+ @@ -3265,13 +3265,13 @@ def DM_28_6_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_28_6_1 - sage: G,M = DM_28_6_1() - sage: is_difference_matrix(M,G,6,1) + sage: G,M = DM_28_6_1() # optional - sage.modules + sage: is_difference_matrix(M,G,6,1) # optional - sage.modules True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(28,6) + sage: _ = designs.difference_matrix(28,6) # optional - sage.modules """ z=2 M = [ @@ -3314,7 +3314,7 @@ def DM_33_6_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(33,6) + sage: _ = designs.difference_matrix(33,6) # optional - sage.rings.finite_rings """ M = [ [ 0, 0, 0, 0, 0, 0], @@ -3356,7 +3356,7 @@ def DM_35_6_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(35,6) + sage: _ = designs.difference_matrix(35,6) # optional - sage.rings.finite_rings """ M = [ [ 0, 15, 30, 10, 25, 1, 16, 31, 11, 26, 2, 17, 32, 12, 6, 3, 18, 33, 27, 21, 4, 19, 13, 7, 22, 5, 34, 28, 8, 23, 20, 14, 29, 9, 24], @@ -3382,13 +3382,13 @@ def DM_36_9_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_36_9_1 - sage: G,M = DM_36_9_1() - sage: is_difference_matrix(M,G,9,1) + sage: G,M = DM_36_9_1() # optional - sage.modules + sage: is_difference_matrix(M,G,9,1) # optional - sage.modules True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(36,9) + sage: _ = designs.difference_matrix(36,9) # optional - sage.modules """ M = [ [(0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0), (0,0,0,0)], @@ -3441,7 +3441,7 @@ def DM_39_6_1(): The design is available from the general constructor:: - sage: designs.difference_matrix(39,6,existence=True) + sage: designs.difference_matrix(39,6,existence=True) # optional - sage.rings.finite_rings True """ M = [ @@ -3485,7 +3485,7 @@ def DM_44_6_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(44,6) + sage: _ = designs.difference_matrix(44,6) # optional - sage.rings.finite_rings """ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing as AdditiveCyclic from sage.categories.cartesian_product import cartesian_product @@ -3541,13 +3541,13 @@ def DM_45_7_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_45_7_1 - sage: G,M = DM_45_7_1() - sage: is_difference_matrix(M,G,7,1) + sage: G,M = DM_45_7_1() # optional - sage.rings.finite_rings + sage: is_difference_matrix(M,G,7,1) # optional - sage.rings.finite_rings True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(45,7) + sage: _ = designs.difference_matrix(45,7) # optional - sage.rings.finite_rings """ from sage.rings.finite_rings.finite_field_constructor import FiniteField from sage.categories.cartesian_product import cartesian_product @@ -3594,13 +3594,13 @@ def DM_48_9_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_48_9_1 - sage: G,M = DM_48_9_1() - sage: is_difference_matrix(M,G,9,1) + sage: G,M = DM_48_9_1() # optional - sage.rings.finite_rings + sage: is_difference_matrix(M,G,9,1) # optional - sage.rings.finite_rings True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(48,9) + sage: _ = designs.difference_matrix(48,9) # optional - sage.rings.finite_rings """ from sage.rings.finite_rings.finite_field_constructor import FiniteField F16 = FiniteField(16,'x') @@ -3649,7 +3649,7 @@ def DM_51_6_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(51,6) + sage: _ = designs.difference_matrix(51,6) # optional - sage.rings.finite_rings """ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing as AdditiveCyclic G = AdditiveCyclic(51) @@ -3685,13 +3685,13 @@ def DM_52_6_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_52_6_1 - sage: G,M = DM_52_6_1() - sage: is_difference_matrix(M,G,6,1) + sage: G,M = DM_52_6_1() # optional - sage.rings.finite_rings + sage: is_difference_matrix(M,G,6,1) # optional - sage.rings.finite_rings True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(52,6) + sage: _ = designs.difference_matrix(52,6) # optional - sage.rings.finite_rings """ from sage.rings.finite_rings.finite_field_constructor import FiniteField F4 = FiniteField(4,'z') @@ -3763,7 +3763,7 @@ def DM_55_7_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(55,7) + sage: _ = designs.difference_matrix(55,7) # optional - sage.rings.finite_rings """ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing as AdditiveCyclic G = AdditiveCyclic(55) @@ -3796,13 +3796,13 @@ def DM_56_8_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_56_8_1 - sage: G,M = DM_56_8_1() - sage: is_difference_matrix(M,G,8,1) + sage: G,M = DM_56_8_1() # optional - sage.rings.finite_rings + sage: is_difference_matrix(M,G,8,1) # optional - sage.rings.finite_rings True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(56,8) + sage: _ = designs.difference_matrix(56,8) # optional - sage.rings.finite_rings """ from sage.rings.finite_rings.finite_field_constructor import FiniteField F8 = FiniteField(8,'z') @@ -3843,13 +3843,13 @@ def DM_57_8_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_57_8_1 - sage: G,M = DM_57_8_1() - sage: is_difference_matrix(M,G,8,1) + sage: G,M = DM_57_8_1() # optional - sage.rings.finite_rings + sage: is_difference_matrix(M,G,8,1) # optional - sage.rings.finite_rings True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(57,8) + sage: _ = designs.difference_matrix(57,8) # optional - sage.rings.finite_rings """ M = orthogonal_array(8,8) M = [R for R in M if any(x!=R[0] for x in R)] # removing the 0..0, 1..1, 7..7 rows. @@ -3887,7 +3887,7 @@ def DM_60_6_1(): Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(60,6) + sage: _ = designs.difference_matrix(60,6) # optional - sage.rings.finite_rings """ M60 = [[(0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)], [(1, 10), (1, 6), (0, 17), (0, 7), (1, 5), (0, 9), (0, 3), (1, 13), (1, 17), (0, 13)], @@ -3923,13 +3923,13 @@ def DM_75_8_1(): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: from sage.combinat.designs.database import DM_75_8_1 - sage: G,M = DM_75_8_1() - sage: is_difference_matrix(M,G,8,1) + sage: G,M = DM_75_8_1() # optional - sage.rings.finite_rings + sage: is_difference_matrix(M,G,8,1) # optional - sage.rings.finite_rings True Can be obtained from the constructor:: - sage: _ = designs.difference_matrix(75,8) + sage: _ = designs.difference_matrix(75,8) # optional - sage.rings.finite_rings """ from sage.rings.finite_rings.finite_field_constructor import FiniteField from sage.categories.cartesian_product import cartesian_product @@ -4080,19 +4080,19 @@ def RBIBD_120_8_1(): sage: from sage.combinat.designs.database import RBIBD_120_8_1 sage: from sage.combinat.designs.bibd import is_pairwise_balanced_design - sage: RBIBD = RBIBD_120_8_1() - sage: is_pairwise_balanced_design(RBIBD,120,[8]) + sage: RBIBD = RBIBD_120_8_1() # optional - sage.modules + sage: is_pairwise_balanced_design(RBIBD,120,[8]) # optional - sage.modules True It is indeed resolvable, and the parallel classes are given by 17 slices of consecutive 15 blocks:: - sage: for i in range(17): + sage: for i in range(17): # optional - sage.modules ....: assert len(set(sum(RBIBD[i*15:(i+1)*15],[]))) == 120 The BIBD is available from the constructor:: - sage: _ = designs.balanced_incomplete_block_design(120,8) + sage: _ = designs.balanced_incomplete_block_design(120,8) # optional - sage.modules """ from .incidence_structures import IncidenceStructure n=273 @@ -4148,15 +4148,15 @@ def BIBD_45_9_8(from_code=False): sage: from sage.combinat.designs.database import BIBD_45_9_8 sage: from sage.combinat.designs.bibd import BalancedIncompleteBlockDesign - sage: B = BalancedIncompleteBlockDesign(45, BIBD_45_9_8(),lambd=8); B + sage: B = BalancedIncompleteBlockDesign(45, BIBD_45_9_8(), lambd=8); B # optional - sage.rings.finite_rings (45,9,8)-Balanced Incomplete Block Design TESTS: From the definition (takes around 12s):: - sage: B2 = Hypergraph(BIBD_45_9_8(from_code=True)) # not tested - sage: B2.is_isomorphic(B) # not tested + sage: B2 = Hypergraph(BIBD_45_9_8(from_code=True)) # not tested # optional - sage.rings.finite_rings + sage: B2.is_isomorphic(B) # not tested # optional - sage.rings.finite_rings True REFERENCE: @@ -4580,8 +4580,8 @@ def BIBD_79_13_2(): EXAMPLES: sage: from sage.combinat.designs.database import BIBD_79_13_2 - sage: D = IncidenceStructure(BIBD_79_13_2()) - sage: D.is_t_design(t=2, v=79, k=13, l=2) + sage: D = IncidenceStructure(BIBD_79_13_2()) # optional - sage.libs.gap + sage: D.is_t_design(t=2, v=79, k=13, l=2) # optional - sage.libs.gap True """ from sage.libs.gap.libgap import libgap @@ -4658,8 +4658,8 @@ def BIBD_56_11_2(): EXAMPLES: sage: from sage.combinat.designs.database import BIBD_56_11_2 - sage: D = IncidenceStructure(BIBD_56_11_2()) - sage: D.is_t_design(t=2, v=56, k=11, l=2) + sage: D = IncidenceStructure(BIBD_56_11_2()) # optional - sage.libs.gap + sage: D.is_t_design(t=2, v=56, k=11, l=2) # optional - sage.libs.gap True """ from sage.libs.gap.libgap import libgap diff --git a/src/sage/combinat/designs/designs_pyx.pyx b/src/sage/combinat/designs/designs_pyx.pyx index 8d3e63f7e0e..55cfbca19b1 100644 --- a/src/sage/combinat/designs/designs_pyx.pyx +++ b/src/sage/combinat/designs/designs_pyx.pyx @@ -183,16 +183,16 @@ def is_group_divisible_design(groups,blocks,v,G=None,K=None,lambd=1,verbose=Fals EXAMPLES:: sage: from sage.combinat.designs.designs_pyx import is_group_divisible_design - sage: TD = designs.transversal_design(4,10) - sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] - sage: is_group_divisible_design(groups,TD,40,lambd=1) + sage: TD = designs.transversal_design(4,10) # optional - sage.matrix + sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] # optional - sage.matrix + sage: is_group_divisible_design(groups,TD,40,lambd=1) # optional - sage.matrix True TESTS:: - sage: TD = designs.transversal_design(4,10) - sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] - sage: is_group_divisible_design(groups,TD,40,lambd=2,verbose=True) + sage: TD = designs.transversal_design(4,10) # optional - sage.matrix + sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] # optional - sage.matrix + sage: is_group_divisible_design(groups, TD, 40, lambd=2, verbose=True) # optional - sage.matrix the pair (0,10) has been seen 1 times but lambda=2 False sage: is_group_divisible_design([[1,2],[3,4]],[[1,2]],40,lambd=1,verbose=True) @@ -362,18 +362,18 @@ def is_pairwise_balanced_design(blocks,v,K=None,lambd=1,verbose=False): sage: sts = designs.steiner_triple_system(9) sage: is_pairwise_balanced_design(sts,9,[3],1) True - sage: TD = designs.transversal_design(4,10).blocks() - sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] - sage: is_pairwise_balanced_design(TD+groups,40,[4,10],1,verbose=True) + sage: TD = designs.transversal_design(4,10).blocks() # optional - sage.matrix + sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] # optional - sage.matrix + sage: is_pairwise_balanced_design(TD + groups, 40, [4,10], 1, verbose=True) # optional - sage.matrix True TESTS:: sage: from sage.combinat.designs.designs_pyx import is_pairwise_balanced_design - sage: is_pairwise_balanced_design(TD+groups,40,[4,10],2,verbose=True) + sage: is_pairwise_balanced_design(TD + groups, 40, [4,10], 2, verbose=True) # optional - sage.matrix the pair (0,1) has been seen 1 times but lambda=2 False - sage: is_pairwise_balanced_design(TD+groups,40,[10],1,verbose=True) + sage: is_pairwise_balanced_design(TD + groups, 40, [10], 1, verbose=True) # optional - sage.matrix a block has size 4 while K=[10] False sage: is_pairwise_balanced_design([[2,2]],40,[2],1,verbose=True) @@ -486,39 +486,40 @@ def is_difference_matrix(M,G,k,lmbda=1,verbose=False): sage: from sage.combinat.designs.designs_pyx import is_difference_matrix sage: q = 3**3 - sage: F = GF(q,'x') - sage: M = [[x*y for y in F] for x in F] - sage: is_difference_matrix(M,F,q,verbose=1) + sage: F = GF(q,'x') # optional - sage.rings.finite_rings + sage: M = [[x*y for y in F] for x in F] # optional - sage.rings.finite_rings + sage: is_difference_matrix(M,F,q,verbose=1) # optional - sage.rings.finite_rings True sage: B = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ....: [0, 1, 2, 3, 4, 2, 3, 4, 0, 1], ....: [0, 2, 4, 1, 3, 3, 0, 2, 4, 1]] - sage: G = GF(5) - sage: B = [[G(b) for b in R] for R in B] - sage: is_difference_matrix(list(zip(*B)),G,3,2) + sage: G = GF(5) # optional - sage.rings.finite_rings + sage: B = [[G(b) for b in R] for R in B] # optional - sage.rings.finite_rings + sage: is_difference_matrix(list(zip(*B)),G,3,2) # optional - sage.rings.finite_rings True Bad input:: - sage: for R in M: R.append(None) - sage: is_difference_matrix(M,F,q,verbose=1) + sage: for R in M: R.append(None) # optional - sage.rings.finite_rings + sage: is_difference_matrix(M,F,q,verbose=1) # optional - sage.rings.finite_rings The matrix has 28 columns but k=27 False - sage: for R in M: _=R.pop(-1) - sage: M.append([None]*3**3) - sage: is_difference_matrix(M,F,q,verbose=1) + sage: for R in M: _=R.pop(-1) # optional - sage.rings.finite_rings + sage: M.append([None]*3**3) # optional - sage.rings.finite_rings + sage: is_difference_matrix(M,F,q,verbose=1) # optional - sage.rings.finite_rings The matrix has 28 rows instead of lambda(|G|-1+2u)+mu=1(27-1+2.0)+1=27 False - sage: _= M.pop(-1) - sage: for R in M: R[-1] = 0 - sage: is_difference_matrix(M,F,q,verbose=1) + sage: _= M.pop(-1) # optional - sage.rings.finite_rings + sage: for R in M: R[-1] = 0 # optional - sage.rings.finite_rings + sage: is_difference_matrix(M,F,q,verbose=1) # optional - sage.rings.finite_rings Columns 0 and 26 generate 0 exactly 27 times instead of the expected mu(=1) False - sage: for R in M: R[-1] = 1 - sage: M[-1][-1] = 0 - sage: is_difference_matrix(M,F,q,verbose=1) - Columns 0 and 26 do not generate all elements of G exactly lambda(=1) times. The element x appeared 0 times as a difference. + sage: for R in M: R[-1] = 1 # optional - sage.rings.finite_rings + sage: M[-1][-1] = 0 # optional - sage.rings.finite_rings + sage: is_difference_matrix(M,F,q,verbose=1) # optional - sage.rings.finite_rings + Columns 0 and 26 do not generate all elements of G exactly lambda(=1) times. + The element x appeared 0 times as a difference. False """ return is_quasi_difference_matrix(M,G,k,lmbda=lmbda,mu=lmbda,u=0,verbose=verbose) @@ -559,17 +560,17 @@ def is_quasi_difference_matrix(M,G,int k,int lmbda,int mu,int u,verbose=False): sage: from sage.combinat.designs.designs_pyx import is_quasi_difference_matrix sage: q = 3**3 - sage: F = GF(q,'x') - sage: M = [[x*y for y in F] for x in F] - sage: is_quasi_difference_matrix(M,F,q,1,1,0,verbose=1) + sage: F = GF(q,'x') # optional - sage.rings.finite_rings + sage: M = [[x*y for y in F] for x in F] # optional - sage.rings.finite_rings + sage: is_quasi_difference_matrix(M,F,q,1,1,0,verbose=1) # optional - sage.rings.finite_rings True sage: B = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ....: [0, 1, 2, 3, 4, 2, 3, 4, 0, 1], ....: [0, 2, 4, 1, 3, 3, 0, 2, 4, 1]] - sage: G = GF(5) - sage: B = [[G(b) for b in R] for R in B] - sage: is_quasi_difference_matrix(list(zip(*B)),G,3,2,2,0) + sage: G = GF(5) # optional - sage.rings.finite_rings + sage: B = [[G(b) for b in R] for R in B] # optional - sage.rings.finite_rings + sage: is_quasi_difference_matrix(list(zip(*B)),G,3,2,2,0) # optional - sage.rings.finite_rings True A quasi-difference matrix from the database:: diff --git a/src/sage/combinat/designs/difference_family.py b/src/sage/combinat/designs/difference_family.py index 51cbd1e0501..3001e912234 100644 --- a/src/sage/combinat/designs/difference_family.py +++ b/src/sage/combinat/designs/difference_family.py @@ -5,7 +5,7 @@ This module gathers everything related to difference families. One can build a difference family (or check that it can be built) with :func:`difference_family`:: - sage: G,F = designs.difference_family(13,4,1) + sage: G,F = designs.difference_family(13,4,1) # optional - sage.modules It defines the following functions: @@ -70,9 +70,9 @@ def group_law(G): sage: from sage.combinat.designs.difference_family import group_law sage: group_law(Zmod(3)) (0, <built-in function add>, <built-in function neg>) - sage: group_law(SymmetricGroup(5)) + sage: group_law(SymmetricGroup(5)) # optional - sage.groups ((), <built-in function mul>, <built-in function inv>) - sage: group_law(VectorSpace(QQ,3)) + sage: group_law(VectorSpace(QQ, 3)) # optional - sage.modules ((0, 0, 0), <built-in function add>, <built-in function neg>) """ import operator @@ -176,13 +176,13 @@ def is_difference_family(G, D, v=None, k=None, l=None, verbose=False): sage: is_difference_family(G, D) True - sage: G = AdditiveAbelianGroup([3]*4) - sage: a,b,c,d = G.gens() - sage: D = [[d, -a+d, -c+d, a-b-d, b+c+d], + sage: G = AdditiveAbelianGroup([3]*4) # optional - sage.modules + sage: a,b,c,d = G.gens() # optional - sage.modules + sage: D = [[d, -a+d, -c+d, a-b-d, b+c+d], # optional - sage.modules ....: [c, a+b-d, -b+c, a-b+d, a+b+c], ....: [-a-b+c+d, a-b-c-d, -a+c-d, b-c+d, a+b], ....: [-b-d, a+b+d, a-b+c-d, a-b+c, -b+c+d]] - sage: is_difference_family(G, D) + sage: is_difference_family(G, D) # optional - sage.modules True The following example has a third block with a non-trivial stabilizer:: @@ -195,23 +195,23 @@ def is_difference_family(G, D, v=None, k=None, l=None, verbose=False): The function also supports multiplicative groups (non necessarily Abelian):: - sage: G = DihedralGroup(8) - sage: x,y = G.gens() - sage: i = G.one() - sage: D1 = [[i,x,x^4], [i,x^2, y*x], [i,x^5,y], [i,x^6,y*x^2], [i,x^7,y*x^5]] - sage: is_difference_family(G, D1, 16, 3, 2) + sage: G = DihedralGroup(8) # optional - sage.groups + sage: x,y = G.gens() # optional - sage.groups + sage: i = G.one() # optional - sage.groups + sage: D1 = [[i,x,x^4], [i,x^2, y*x], [i,x^5,y], [i,x^6,y*x^2], [i,x^7,y*x^5]] # optional - sage.groups + sage: is_difference_family(G, D1, 16, 3, 2) # optional - sage.groups True sage: from sage.combinat.designs.bibd import BIBD_from_difference_family - sage: bibd = BIBD_from_difference_family(G,D1,lambd=2) + sage: bibd = BIBD_from_difference_family(G, D1, lambd=2) # optional - sage.groups TESTS:: - sage: K = GF(3^2,'z') - sage: z = K.gen() - sage: D = [[1,z+1,2]] - sage: _ = is_difference_family(K, D, verbose=True) + sage: K = GF(3^2,'z') # optional - sage.rings.finite_rings + sage: z = K.gen() # optional - sage.rings.finite_rings + sage: D = [[1,z+1,2]] # optional - sage.rings.finite_rings + sage: _ = is_difference_family(K, D, verbose=True) # optional - sage.rings.finite_rings the number of differences (=6) must be a multiple of v-1=8 - sage: _ + sage: _ # optional - sage.rings.finite_rings False """ identity, mul, inv = group_law(G) @@ -353,23 +353,23 @@ def singer_difference_set(q,d): EXAMPLES:: sage: from sage.combinat.designs.difference_family import singer_difference_set, is_difference_family - sage: G,D = singer_difference_set(3,2) - sage: is_difference_family(G,D,verbose=True) + sage: G,D = singer_difference_set(3,2) # optional - sage.rings.finite_rings + sage: is_difference_family(G, D, verbose=True) # optional - sage.rings.finite_rings It is a (13,4,1)-difference family True - sage: G,D = singer_difference_set(4,2) - sage: is_difference_family(G,D,verbose=True) + sage: G,D = singer_difference_set(4,2) # optional - sage.rings.finite_rings + sage: is_difference_family(G, D, verbose=True) # optional - sage.rings.finite_rings It is a (21,5,1)-difference family True - sage: G,D = singer_difference_set(3,3) - sage: is_difference_family(G,D,verbose=True) + sage: G,D = singer_difference_set(3,3) # optional - sage.rings.finite_rings + sage: is_difference_family(G, D, verbose=True) # optional - sage.rings.finite_rings It is a (40,13,4)-difference family True - sage: G,D = singer_difference_set(9,3) - sage: is_difference_family(G,D,verbose=True) + sage: G,D = singer_difference_set(9,3) # optional - sage.rings.finite_rings + sage: is_difference_family(G, D, verbose=True) # optional - sage.rings.finite_rings It is a (820,91,10)-difference family True """ @@ -418,11 +418,12 @@ def df_q_6_1(K, existence=False, check=True): EXAMPLES:: sage: from sage.combinat.designs.difference_family import is_difference_family, df_q_6_1 - sage: prime_powers = [v for v in range(31,500,30) if is_prime_power(v)] - sage: parameters = [v for v in prime_powers if df_q_6_1(GF(v,'a'), existence=True) is True] - sage: parameters + sage: prime_powers = [v for v in range(31,500,30) if is_prime_power(v)] # optional - sage.rings.finite_rings + sage: parameters = [v for v in prime_powers # optional - sage.rings.finite_rings + ....: if df_q_6_1(GF(v,'a'), existence=True) is True] + sage: parameters # optional - sage.rings.finite_rings [31, 151, 181, 211, 241, 271, 331, 361, 421] - sage: for v in parameters: + sage: for v in parameters: # optional - sage.rings.finite_rings ....: K = GF(v, 'a') ....: df = df_q_6_1(K, check=True) ....: assert is_difference_family(K, df, v, 6, 1) @@ -478,13 +479,13 @@ def radical_difference_set(K, k, l=1, existence=False, check=True): sage: from sage.combinat.designs.difference_family import radical_difference_set - sage: D = radical_difference_set(GF(7), 3, 1); D + sage: D = radical_difference_set(GF(7), 3, 1); D # optional - sage.rings.finite_rings [[1, 2, 4]] - sage: sorted(x-y for x in D[0] for y in D[0] if x != y) + sage: sorted(x-y for x in D[0] for y in D[0] if x != y) # optional - sage.rings.finite_rings [1, 2, 3, 4, 5, 6] - sage: D = radical_difference_set(GF(16,'a'), 6, 2) - sage: sorted(x-y for x in D[0] for y in D[0] if x != y) + sage: D = radical_difference_set(GF(16,'a'), 6, 2) # optional - sage.rings.finite_rings + sage: sorted(x-y for x in D[0] for y in D[0] if x != y) # optional - sage.rings.finite_rings [1, 1, a, @@ -497,7 +498,7 @@ def radical_difference_set(K, k, l=1, existence=False, check=True): a^3 + a^2 + a + 1, a^3 + a^2 + a + 1] - sage: for k in range(2,50): + sage: for k in range(2,50): # optional - sage.rings.finite_rings ....: for l in reversed(divisors(k*(k-1))): ....: v = k*(k-1)//l + 1 ....: if is_prime_power(v) and radical_difference_set(GF(v,'a'),k,l,existence=True) is True: @@ -756,12 +757,12 @@ def one_radical_difference_family(K, k): ....: one_radical_difference_family, ....: is_difference_family) - sage: one_radical_difference_family(GF(13),4) + sage: one_radical_difference_family(GF(13),4) # optional - sage.rings.finite_rings [[0, 1, 3, 9]] The parameters that appear in [Bu95]_:: - sage: df = one_radical_difference_family(GF(449), 8); df + sage: df = one_radical_difference_family(GF(449), 8); df # optional - sage.rings.finite_rings [[0, 1, 18, 25, 176, 324, 359, 444], [0, 9, 88, 162, 222, 225, 237, 404], [0, 11, 140, 198, 275, 357, 394, 421], @@ -770,7 +771,7 @@ def one_radical_difference_family(K, k): [0, 70, 99, 197, 230, 362, 403, 435], [0, 121, 141, 193, 293, 331, 335, 382], [0, 191, 285, 295, 321, 371, 390, 392]] - sage: is_difference_family(GF(449), df, 449, 8, 1) + sage: is_difference_family(GF(449), df, 449, 8, 1) # optional - sage.rings.finite_rings True """ q = K.cardinality() @@ -842,10 +843,10 @@ def radical_difference_family(K, k, l=1, existence=False, check=True): sage: from sage.combinat.designs.difference_family import radical_difference_family - sage: radical_difference_family(GF(73),9) + sage: radical_difference_family(GF(73), 9) # optional - sage.rings.finite_rings [[1, 2, 4, 8, 16, 32, 37, 55, 64]] - sage: radical_difference_family(GF(281),5) + sage: radical_difference_family(GF(281), 5) # optional - sage.rings.finite_rings [[1, 86, 90, 153, 232], [4, 50, 63, 79, 85], [5, 36, 149, 169, 203], @@ -861,7 +862,7 @@ def radical_difference_family(K, k, l=1, existence=False, check=True): [111, 123, 155, 181, 273], [156, 209, 224, 264, 271]] - sage: for k in range(5,10): + sage: for k in range(5,10): # optional - sage.rings.finite_rings ....: print("k = {}".format(k)) ....: list_q = [] ....: for q in range(k*(k-1)+1, 2000, k*(k-1)): @@ -945,10 +946,10 @@ def twin_prime_powers_difference_set(p, check=True): EXAMPLES:: sage: from sage.combinat.designs.difference_family import twin_prime_powers_difference_set - sage: G,D = twin_prime_powers_difference_set(3) - sage: G + sage: G, D = twin_prime_powers_difference_set(3) # optional - sage.rings.finite_rings + sage: G # optional - sage.rings.finite_rings The Cartesian product of (Finite Field of size 3, Finite Field of size 5) - sage: D + sage: D # optional - sage.rings.finite_rings [[(1, 1), (1, 4), (2, 2), (2, 3), (0, 0), (1, 0), (2, 0)]] """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -997,19 +998,19 @@ def are_mcfarland_1973_parameters(v, k, lmbda, return_parameters=False): EXAMPLES:: sage: from sage.combinat.designs.difference_family import are_mcfarland_1973_parameters - sage: are_mcfarland_1973_parameters(64, 28, 12) + sage: are_mcfarland_1973_parameters(64, 28, 12) # optional - sage.rings.finite_rings True - sage: are_mcfarland_1973_parameters(64, 28, 12, return_parameters=True) + sage: are_mcfarland_1973_parameters(64, 28, 12, return_parameters=True) # optional - sage.rings.finite_rings (True, (2, 2)) - sage: are_mcfarland_1973_parameters(60, 13, 5) + sage: are_mcfarland_1973_parameters(60, 13, 5) # optional - sage.rings.finite_rings False - sage: are_mcfarland_1973_parameters(98125, 19500, 3875) + sage: are_mcfarland_1973_parameters(98125, 19500, 3875) # optional - sage.rings.finite_rings True - sage: are_mcfarland_1973_parameters(98125, 19500, 3875, True) + sage: are_mcfarland_1973_parameters(98125, 19500, 3875, True) # optional - sage.rings.finite_rings (True, (5, 3)) sage: from sage.combinat.designs.difference_family import are_mcfarland_1973_parameters - sage: for v in range(1, 100): + sage: for v in range(1, 100): # optional - sage.rings.finite_rings ....: for k in range(1,30): ....: for l in range(1,15): ....: if are_mcfarland_1973_parameters(v,k,l): @@ -1087,11 +1088,11 @@ def mcfarland_1973_construction(q, s): sage: from sage.combinat.designs.difference_family import ( ....: mcfarland_1973_construction, is_difference_family) - sage: G,D = mcfarland_1973_construction(3, 1) - sage: assert is_difference_family(G, D, 45, 12, 3) + sage: G,D = mcfarland_1973_construction(3, 1) # optional - sage.modules sage.rings.finite_rings + sage: assert is_difference_family(G, D, 45, 12, 3) # optional - sage.modules sage.rings.finite_rings - sage: G,D = mcfarland_1973_construction(2, 2) - sage: assert is_difference_family(G, D, 64, 28, 12) + sage: G,D = mcfarland_1973_construction(2, 2) # optional - sage.modules sage.rings.finite_rings + sage: assert is_difference_family(G, D, 64, 28, 12) # optional - sage.modules sage.rings.finite_rings """ from sage.rings.finite_rings.finite_field_constructor import GF from sage.modules.free_module import VectorSpace @@ -1150,7 +1151,7 @@ def hadamard_difference_set_product_parameters(N): EXAMPLES:: sage: from sage.combinat.designs.difference_family import hadamard_difference_set_product_parameters - sage: hadamard_difference_set_product_parameters(8) + sage: hadamard_difference_set_product_parameters(8) # optional - sage.rings.finite_rings (2, 2) """ if N % 2: @@ -1190,16 +1191,16 @@ def hadamard_difference_set_product(G1, D1, G2, D2): sage: from sage.combinat.designs.difference_family import hadamard_difference_set_product sage: from sage.combinat.designs.difference_family import is_difference_family - sage: G1,D1 = designs.difference_family(16,6,2) - sage: G2,D2 = designs.difference_family(36,15,6) + sage: G1,D1 = designs.difference_family(16,6,2) # optional - sage.rings.finite_rings + sage: G2,D2 = designs.difference_family(36,15,6) # optional - sage.rings.finite_rings - sage: G11,D11 = hadamard_difference_set_product(G1,D1,G1,D1) - sage: assert is_difference_family(G11, D11, 256, 120, 56) - sage: assert designs.difference_family(256, 120, 56, existence=True) is True + sage: G11,D11 = hadamard_difference_set_product(G1,D1,G1,D1) # optional - sage.rings.finite_rings + sage: assert is_difference_family(G11, D11, 256, 120, 56) # optional - sage.rings.finite_rings + sage: assert designs.difference_family(256, 120, 56, existence=True) is True # optional - sage.rings.finite_rings - sage: G12,D12 = hadamard_difference_set_product(G1,D1,G2,D2) - sage: assert is_difference_family(G12, D12, 576, 276, 132) - sage: assert designs.difference_family(576, 276, 132, existence=True) is True + sage: G12,D12 = hadamard_difference_set_product(G1,D1,G2,D2) # optional - sage.rings.finite_rings + sage: assert is_difference_family(G12, D12, 576, 276, 132) # optional - sage.rings.finite_rings + sage: assert designs.difference_family(576, 276, 132, existence=True) is True # optional - sage.rings.finite_rings """ from sage.categories.cartesian_product import cartesian_product @@ -1316,11 +1317,11 @@ def _create_m_sequence(q, n, check=True): EXAMPLES:: sage: from sage.combinat.designs.difference_family import _create_m_sequence - sage: _create_m_sequence(3, 2) #random + sage: _create_m_sequence(3, 2) # random # optional - sage.rings.finite_rings [1, 0, 1, 2, 2, 0, 2, 1] - sage: _create_m_sequence(4, 2, check=False) #random + sage: _create_m_sequence(4, 2, check=False) # random # optional - sage.rings.finite_rings [1, 0, a, a + 1, a, a, 0, a + 1, 1, a + 1, a + 1, 0, 1, a, 1] - sage: _create_m_sequence(6, 2) + sage: _create_m_sequence(6, 2) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: q must be a prime power @@ -1371,11 +1372,11 @@ def _get_submodule_of_order(G, order): TESTS: sage: from sage.combinat.designs.difference_family import _get_submodule_of_order - sage: G = AdditiveAbelianGroup([48]) - sage: _get_submodule_of_order(G, 6).order() + sage: G = AdditiveAbelianGroup([48]) # optional - sage.modules + sage: _get_submodule_of_order(G, 6).order() # optional - sage.modules 6 - sage: G = AdditiveAbelianGroup([13^2-1]) - sage: _get_submodule_of_order(G, 12).order() + sage: G = AdditiveAbelianGroup([13^2 - 1]) # optional - sage.modules + sage: _get_submodule_of_order(G, 12).order() # optional - sage.modules 12 """ for el in G: @@ -1409,12 +1410,13 @@ def relative_difference_set_from_m_sequence(q, N, check=True, return_group=False EXAMPLES:: sage: from sage.combinat.designs.difference_family import relative_difference_set_from_m_sequence - sage: relative_difference_set_from_m_sequence(2, 4, return_group=True) #random + sage: relative_difference_set_from_m_sequence(2, 4, # random # optional - sage.modules sage.rings.finite_rings + ....: return_group=True) (Additive abelian group isomorphic to Z/15, [(0), (4), (5), (6), (7), (9), (11), (12)]) - sage: relative_difference_set_from_m_sequence(8, 2, check=False) #random + sage: relative_difference_set_from_m_sequence(8, 2, check=False) # random # optional - sage.modules sage.rings.finite_rings [(0), (6), (30), (40), (41), (44), (56), (61)] - sage: relative_difference_set_from_m_sequence(6, 2) + sage: relative_difference_set_from_m_sequence(6, 2) # optional - sage.modules sage.rings.finite_rings Traceback (most recent call last): ... ValueError: q must be a prime power @@ -1423,14 +1425,18 @@ def relative_difference_set_from_m_sequence(q, N, check=True, return_group=False sage: from sage.combinat.designs.difference_family import is_relative_difference_set, _get_submodule_of_order sage: q, N = 5, 3 - sage: G, D = relative_difference_set_from_m_sequence(q, N, check=False, return_group=True) - sage: H = _get_submodule_of_order(G, q-1) - sage: is_relative_difference_set(D, G, H, ((q^N-1)//(q-1), q-1, q^(N-1), q^(N-2))) + sage: G, D = relative_difference_set_from_m_sequence(q, N, check=False, # optional - sage.modules sage.rings.finite_rings + ....: return_group=True) + sage: H = _get_submodule_of_order(G, q-1) # optional - sage.modules sage.rings.finite_rings + sage: is_relative_difference_set(D, G, H, # optional - sage.modules sage.rings.finite_rings + ....: ((q^N-1)//(q-1), q-1, q^(N-1), q^(N-2))) True sage: q, N = 13, 2 - sage: G, D = relative_difference_set_from_m_sequence(q, N, check=False, return_group=True) - sage: H = _get_submodule_of_order(G, q-1) - sage: is_relative_difference_set(D, G, H, ((q^N-1)//(q-1), q-1, q^(N-1), q^(N-2))) + sage: G, D = relative_difference_set_from_m_sequence(q, N, check=False, # optional - sage.modules sage.rings.finite_rings + ....: return_group=True) + sage: H = _get_submodule_of_order(G, q-1) # optional - sage.modules sage.rings.finite_rings + sage: is_relative_difference_set(D, G, H, # optional - sage.modules sage.rings.finite_rings + ....: ((q^N-1)//(q-1), q-1, q^(N-1), q^(N-2))) True """ from sage.groups.additive_abelian.additive_abelian_group import AdditiveAbelianGroup @@ -1484,7 +1490,7 @@ def relative_difference_set_from_homomorphism(q, N, d, check=True, return_group= sage: relative_difference_set_from_homomorphism(9, 2, 4, check=False, return_group=True) #random (Additive abelian group isomorphic to Z/80, [(0), (4), (6), (13), (7), (12), (15), (8), (9)]) - sage: relative_difference_set_from_homomorphism(9, 2, 5) + sage: relative_difference_set_from_homomorphism(9, 2, 5) # optional - sage.modules sage.rings.finite_rings Traceback (most recent call last): ... ValueError: q-1 must be a multiple of d @@ -1493,14 +1499,18 @@ def relative_difference_set_from_homomorphism(q, N, d, check=True, return_group= sage: from sage.combinat.designs.difference_family import is_relative_difference_set, _get_submodule_of_order sage: q, N, d = 11, 2, 5 - sage: G, D = relative_difference_set_from_homomorphism(q, N, d, check=False, return_group=True) - sage: H = _get_submodule_of_order(G, (q-1)//d) - sage: is_relative_difference_set(D, G, H, ((q**N-1)//(q-1), (q-1)//d, q**(N-1), q**(N-2)*d)) + sage: G, D = relative_difference_set_from_homomorphism(q, N, d, check=False, # optional - sage.modules sage.rings.finite_rings + ....: return_group=True) + sage: H = _get_submodule_of_order(G, (q-1)//d) # optional - sage.modules sage.rings.finite_rings + sage: is_relative_difference_set(D, G, H, # optional - sage.modules sage.rings.finite_rings + ....: ((q**N-1)//(q-1), (q-1)//d, q**(N-1), q**(N-2)*d)) True sage: q, N, d = 9, 2, 4 - sage: G, D = relative_difference_set_from_homomorphism(q, N, d, check=False, return_group=True) - sage: H = _get_submodule_of_order(G, (q-1)//d) - sage: is_relative_difference_set(D, G, H, ((q**N-1)//(q-1), (q-1)//d, q**(N-1), q**(N-2)*d)) + sage: G, D = relative_difference_set_from_homomorphism(q, N, d, check=False, # optional - sage.modules sage.rings.finite_rings + ....: return_group=True) + sage: H = _get_submodule_of_order(G, (q-1)//d) # optional - sage.modules sage.rings.finite_rings + sage: is_relative_difference_set(D, G, H, # optional - sage.modules sage.rings.finite_rings + ....: ((q**N-1)//(q-1), (q-1)//d, q**(N-1), q**(N-2)*d)) True """ from sage.groups.additive_abelian.additive_abelian_group import AdditiveAbelianGroup @@ -1554,15 +1564,15 @@ def is_relative_difference_set(R, G, H, params, verbose=False): sage: from sage.combinat.designs.difference_family import _get_submodule_of_order, relative_difference_set_from_m_sequence, is_relative_difference_set sage: q, N = 5, 2 sage: params = ((q^N-1) // (q-1), q - 1, q^(N-1), q^(N-2)) - sage: G, R = relative_difference_set_from_m_sequence(q, N, return_group=True) - sage: H = _get_submodule_of_order(G, q - 1) - sage: is_relative_difference_set(R, G, H, params) + sage: G, R = relative_difference_set_from_m_sequence(q, N, return_group=True) # optional - sage.modules + sage: H = _get_submodule_of_order(G, q - 1) # optional - sage.modules + sage: is_relative_difference_set(R, G, H, params) # optional - sage.modules True If we pass the ``verbose`` argument, the function will explain why it failed:: - sage: R2 = [G[1], G[2], G[3], G[5], G[6]] - sage: is_relative_difference_set(R2, G, H, params, verbose=True) + sage: R2 = [G[1], G[2], G[3], G[5], G[6]] # optional - sage.modules + sage: is_relative_difference_set(R2, G, H, params, verbose=True) # optional - sage.modules There is a value in the difference set which is not repeated d times False """ @@ -1632,32 +1642,33 @@ def is_supplementary_difference_set(Ks, v=None, lmbda=None, G=None, verbose=Fals EXAMPLES:: sage: from sage.combinat.designs.difference_family import supplementary_difference_set_from_rel_diff_set, is_supplementary_difference_set - sage: G, [S1, S2, S3, S4] = supplementary_difference_set_from_rel_diff_set(17) - sage: is_supplementary_difference_set([S1, S2, S3, S4], lmbda=16, G=G) + sage: G, [S1, S2, S3, S4] = supplementary_difference_set_from_rel_diff_set(17) # optional - sage.modules sage.rings.finite_rings + sage: is_supplementary_difference_set([S1, S2, S3, S4], lmbda=16, G=G) # optional - sage.modules sage.rings.finite_rings True The parameter ``v`` can be given instead of ``G``:: - sage: is_supplementary_difference_set([S1, S2, S3, S4], v=16, lmbda=16) + sage: is_supplementary_difference_set([S1, S2, S3, S4], v=16, lmbda=16) # optional - sage.modules sage.rings.finite_rings True - sage: is_supplementary_difference_set([S1, S2, S3, S4], v=20, lmbda=16) + sage: is_supplementary_difference_set([S1, S2, S3, S4], v=20, lmbda=16) # optional - sage.modules sage.rings.finite_rings False If ``verbose=True``, the function will be verbose:: - sage: is_supplementary_difference_set([S1, S2, S3, S4], lmbda=14, G=G, verbose=True) + sage: is_supplementary_difference_set([S1, S2, S3, S4], lmbda=14, G=G, # optional - sage.modules sage.rings.finite_rings + ....: verbose=True) Number of pairs with difference (1) is 16, but lambda is 14 False TESTS:: - sage: is_supplementary_difference_set([[1], [1]], lmbda=0, G=Zmod(3)) + sage: is_supplementary_difference_set([[1], [1]], lmbda=0, G=Zmod(3)) # optional - sage.modules sage.rings.finite_rings True - sage: is_supplementary_difference_set([S1, S2, S3, S4], v=17, lmbda=16, G=G) + sage: is_supplementary_difference_set([S1, S2, S3, S4], v=17, lmbda=16, G=G) # optional - sage.modules sage.rings.finite_rings False - sage: is_supplementary_difference_set([S1, S2, S3, S4], G=G) + sage: is_supplementary_difference_set([S1, S2, S3, S4], G=G) # optional - sage.modules sage.rings.finite_rings True - sage: is_supplementary_difference_set([S1, S2, S3, S4], lmbda=16) + sage: is_supplementary_difference_set([S1, S2, S3, S4], lmbda=16) # optional - sage.modules sage.rings.finite_rings Traceback (most recent call last): ... ValueError: one of G or v must be specified @@ -1912,30 +1923,30 @@ def get_fixed_relative_difference_set(G, rel_diff_set, as_elements=False): EXAMPLES:: sage: from sage.combinat.designs.difference_family import relative_difference_set_from_m_sequence, get_fixed_relative_difference_set - sage: G, s1 = relative_difference_set_from_m_sequence(5, 2, return_group=True) - sage: get_fixed_relative_difference_set(G, s1) #random + sage: G, s1 = relative_difference_set_from_m_sequence(5, 2, return_group=True) # optional - sage.modules + sage: get_fixed_relative_difference_set(G, s1) # random # optional - sage.modules [2, 10, 19, 23, 0] If ``as_elements=True``, the result will contain elements of the group:: - sage: get_fixed_relative_difference_set(G, s1, as_elements=True) #random + sage: get_fixed_relative_difference_set(G, s1, as_elements=True) # random # optional - sage.modules [(2), (10), (19), (23), (0)] TESTS:: sage: from sage.combinat.designs.difference_family import is_fixed_relative_difference_set - sage: G, s1 = relative_difference_set_from_m_sequence(5, 2, return_group=True) - sage: s2 = get_fixed_relative_difference_set(G, s1, as_elements=True) - sage: is_fixed_relative_difference_set(s2, len(s2)) + sage: G, s1 = relative_difference_set_from_m_sequence(5, 2, return_group=True) # optional - sage.modules + sage: s2 = get_fixed_relative_difference_set(G, s1, as_elements=True) # optional - sage.modules + sage: is_fixed_relative_difference_set(s2, len(s2)) # optional - sage.modules True - sage: G, s1 = relative_difference_set_from_m_sequence(9, 2, return_group=True) - sage: s2 = get_fixed_relative_difference_set(G, s1, as_elements=True) - sage: is_fixed_relative_difference_set(s2, len(s2)) + sage: G, s1 = relative_difference_set_from_m_sequence(9, 2, return_group=True) # optional - sage.modules + sage: s2 = get_fixed_relative_difference_set(G, s1, as_elements=True) # optional - sage.modules + sage: is_fixed_relative_difference_set(s2, len(s2)) # optional - sage.modules True - sage: type(s2[0]) + sage: type(s2[0]) # optional - sage.modules <class 'sage.groups.additive_abelian.additive_abelian_group.AdditiveAbelianGroup_fixed_gens_with_category.element_class'> - sage: s2 = get_fixed_relative_difference_set(G, s1) - sage: type(s2[0]) + sage: s2 = get_fixed_relative_difference_set(G, s1) # optional - sage.modules + sage: type(s2[0]) # optional - sage.modules <class 'sage.rings.integer.Integer'> """ q = len(rel_diff_set) @@ -1976,20 +1987,20 @@ def is_fixed_relative_difference_set(R, q): EXAMPLES:: sage: from sage.combinat.designs.difference_family import relative_difference_set_from_m_sequence, get_fixed_relative_difference_set, is_fixed_relative_difference_set - sage: G, s1 = relative_difference_set_from_m_sequence(7, 2, return_group=True) - sage: s2 = get_fixed_relative_difference_set(G, s1, as_elements=True) - sage: is_fixed_relative_difference_set(s2, len(s2)) + sage: G, s1 = relative_difference_set_from_m_sequence(7, 2, return_group=True) # optional - sage.modules + sage: s2 = get_fixed_relative_difference_set(G, s1, as_elements=True) # optional - sage.modules + sage: is_fixed_relative_difference_set(s2, len(s2)) # optional - sage.modules True - sage: G = AdditiveAbelianGroup([15]) - sage: s3 = [G[1], G[2], G[3], G[4]] - sage: is_fixed_relative_difference_set(s3, len(s3)) + sage: G = AdditiveAbelianGroup([15]) # optional - sage.modules + sage: s3 = [G[1], G[2], G[3], G[4]] # optional - sage.modules + sage: is_fixed_relative_difference_set(s3, len(s3)) # optional - sage.modules False If the relative difference set does not contain elements of the group, the method returns false:: - sage: G, s1 = relative_difference_set_from_m_sequence(7, 2, return_group=True) - sage: s2 = get_fixed_relative_difference_set(G, s1, as_elements=False) - sage: is_fixed_relative_difference_set(s2, len(s2)) + sage: G, s1 = relative_difference_set_from_m_sequence(7, 2, return_group=True) # optional - sage.modules + sage: s2 = get_fixed_relative_difference_set(G, s1, as_elements=False) # optional - sage.modules + sage: is_fixed_relative_difference_set(s2, len(s2)) # optional - sage.modules False """ for el in R: diff --git a/src/sage/combinat/designs/evenly_distributed_sets.pyx b/src/sage/combinat/designs/evenly_distributed_sets.pyx index 493d48d2ad5..a19267a4bdb 100644 --- a/src/sage/combinat/designs/evenly_distributed_sets.pyx +++ b/src/sage/combinat/designs/evenly_distributed_sets.pyx @@ -111,7 +111,7 @@ cdef class EvenlyDistributedSetsBacktracker: Or only count them:: - sage: for k in range(13, 200, 12): + sage: for k in range(13, 200, 12): # optional - sage.rings.finite_rings ....: if is_prime_power(k): ....: K = GF(k,'a') ....: E1 = EvenlyDistributedSetsBacktracker(K, 4, False) @@ -357,9 +357,10 @@ cdef class EvenlyDistributedSetsBacktracker: sage: from sage.combinat.designs.evenly_distributed_sets import EvenlyDistributedSetsBacktracker - sage: EvenlyDistributedSetsBacktracker(GF(25,'a'), 4) + sage: EvenlyDistributedSetsBacktracker(GF(25,'a'), 4) # optional - sage.rings.finite_rings 4-evenly distributed sets (up to isomorphism) in Finite Field in a of size 5^2 - sage: EvenlyDistributedSetsBacktracker(GF(25,'a'), 4, up_to_isomorphism=False) + sage: EvenlyDistributedSetsBacktracker(GF(25,'a'), 4, # optional - sage.rings.finite_rings + ....: up_to_isomorphism=False) 4-evenly distributed sets in Finite Field in a of size 5^2 """ return "{}-evenly distributed sets {} in {}".format( @@ -378,14 +379,15 @@ cdef class EvenlyDistributedSetsBacktracker: sage: from sage.combinat.designs.evenly_distributed_sets import EvenlyDistributedSetsBacktracker - sage: E = EvenlyDistributedSetsBacktracker(GF(25,'a'),4) - sage: E - 4-evenly distributed sets (up to isomorphism) in Finite Field in a of size 5^2 - sage: E.cardinality() + sage: E = EvenlyDistributedSetsBacktracker(GF(25,'a'), 4); E # optional - sage.rings.finite_rings + 4-evenly distributed sets (up to isomorphism) + in Finite Field in a of size 5^2 + sage: E.cardinality() # optional - sage.rings.finite_rings 4 - sage: E = EvenlyDistributedSetsBacktracker(GF(25,'a'), 4, up_to_isomorphism=False) - sage: E.cardinality() + sage: E = EvenlyDistributedSetsBacktracker(GF(25,'a'), 4, # optional - sage.rings.finite_rings + ....: up_to_isomorphism=False) + sage: E.cardinality() # optional - sage.rings.finite_rings 40 """ cdef n = 0 diff --git a/src/sage/combinat/designs/twographs.py b/src/sage/combinat/designs/twographs.py index 56c01c4bc5e..32a844083b9 100644 --- a/src/sage/combinat/designs/twographs.py +++ b/src/sage/combinat/designs/twographs.py @@ -84,8 +84,8 @@ def __init__(self, points=None, blocks=None, incidence_matrix=None, Traceback (most recent call last): ... AssertionError: the structure is not a 2-graph! - sage: p=graphs.PetersenGraph().twograph() - sage: TwoGraph(p, check=True) + sage: p = graphs.PetersenGraph().twograph() # optional - sage.modules + sage: TwoGraph(p, check=True) # optional - sage.modules Incidence structure with 10 points and 60 blocks """ IncidenceStructure.__init__(self, points=points, blocks=blocks, @@ -108,15 +108,15 @@ def is_regular_twograph(self, alpha=False): EXAMPLES:: - sage: p=graphs.PetersenGraph().twograph() - sage: p.is_regular_twograph(alpha=True) + sage: p = graphs.PetersenGraph().twograph() # optional - sage.modules + sage: p.is_regular_twograph(alpha=True) # optional - sage.modules 4 - sage: p.is_regular_twograph() + sage: p.is_regular_twograph() # optional - sage.modules True - sage: p=graphs.PathGraph(5).twograph() - sage: p.is_regular_twograph(alpha=True) + sage: p = graphs.PathGraph(5).twograph() # optional - sage.modules + sage: p.is_regular_twograph(alpha=True) # optional - sage.modules False - sage: p.is_regular_twograph() + sage: p.is_regular_twograph() # optional - sage.modules False """ r, (_, _, _, a) = self.is_t_design(t=2, k=3, return_parameters=True) @@ -139,8 +139,8 @@ def descendant(self, v): EXAMPLES:: - sage: p = graphs.PetersenGraph().twograph().descendant(0) - sage: p.is_strongly_regular(parameters=True) + sage: p = graphs.PetersenGraph().twograph().descendant(0) # optional - sage.modules + sage: p.is_strongly_regular(parameters=True) # optional - sage.modules (9, 4, 1, 2) """ from sage.graphs.graph import Graph @@ -159,14 +159,14 @@ def complement(self): EXAMPLES:: - sage: p = graphs.CompleteGraph(8).line_graph().twograph() - sage: pc = p.complement(); pc + sage: p = graphs.CompleteGraph(8).line_graph().twograph() # optional - sage.modules + sage: pc = p.complement(); pc # optional - sage.modules Incidence structure with 28 points and 1260 blocks TESTS:: sage: from sage.combinat.designs.twographs import is_twograph - sage: is_twograph(pc) + sage: is_twograph(pc) # optional - sage.modules True """ return super().complement(uniform=True) @@ -192,7 +192,7 @@ def taylor_twograph(q): EXAMPLES:: sage: from sage.combinat.designs.twographs import taylor_twograph - sage: T=taylor_twograph(3); T + sage: T = taylor_twograph(3); T # optional - sage.rings.finite_rings Incidence structure with 28 points and 1260 blocks """ from sage.graphs.generators.classical_geometries import TaylorTwographSRG @@ -211,13 +211,13 @@ def is_twograph(T): a two-graph from a graph:: sage: from sage.combinat.designs.twographs import (is_twograph, TwoGraph) - sage: p=graphs.PetersenGraph().twograph() - sage: is_twograph(p) + sage: p = graphs.PetersenGraph().twograph() # optional - sage.modules + sage: is_twograph(p) # optional - sage.modules True a non-regular 2-uniform hypergraph which is a two-graph:: - sage: is_twograph(TwoGraph([[1,2,3],[1,2,4]])) + sage: is_twograph(TwoGraph([[1,2,3],[1,2,4]])) # optional - sage.modules True TESTS: @@ -277,15 +277,15 @@ def twograph_descendant(G, v, name=None): one of s.r.g.'s from the :mod:`database <sage.graphs.strongly_regular_db>`:: sage: from sage.combinat.designs.twographs import twograph_descendant - sage: A=graphs.strongly_regular_graph(280,135,70) # optional - gap_packages internet - sage: twograph_descendant(A, 0).is_strongly_regular(parameters=True) # optional - gap_packages internet + sage: A = graphs.strongly_regular_graph(280,135,70) # optional - gap_packages internet + sage: twograph_descendant(A, 0).is_strongly_regular(parameters=True) # optional - gap_packages internet (279, 150, 85, 75) TESTS:: sage: T8 = graphs.CompleteGraph(8).line_graph() sage: v = T8.vertices(sort=True)[0] - sage: twograph_descendant(T8, v)==T8.twograph().descendant(v) + sage: twograph_descendant(T8, v) == T8.twograph().descendant(v) # optional - sage.modules True sage: twograph_descendant(T8, v).is_strongly_regular(parameters=True) (27, 16, 10, 8) diff --git a/src/sage/combinat/diagram.py b/src/sage/combinat/diagram.py index dcde71bff63..e51b7b0f871 100644 --- a/src/sage/combinat/diagram.py +++ b/src/sage/combinat/diagram.py @@ -777,17 +777,17 @@ def from_zero_one_matrix(self, M, check=True): EXAMPLES:: - sage: M = matrix([[1,0,1,1],[0,1,1,0]]) + sage: M = matrix([[1,0,1,1],[0,1,1,0]]) # optional - sage.modules sage: from sage.combinat.diagram import Diagrams - sage: Diagrams()(M).pp() + sage: Diagrams()(M).pp() # optional - sage.modules O . O O . O O . - sage: Diagrams().from_zero_one_matrix(M).pp() + sage: Diagrams().from_zero_one_matrix(M).pp() # optional - sage.modules O . O O . O O . - sage: M = matrix([[1, 0, 0], [1, 0, 0], [0, 0, 0]]) - sage: Diagrams()(M).pp() + sage: M = matrix([[1, 0, 0], [1, 0, 0], [0, 0, 0]]) # optional - sage.modules + sage: Diagrams()(M).pp() # optional - sage.modules O . . O . . . . . @@ -1435,7 +1435,7 @@ def from_parallelogram_polyomino(self, p): EXAMPLES:: - sage: p = ParallelogramPolyomino([[0, 0, 1, 0, 0, 0, 1, 1], + sage: p = ParallelogramPolyomino([[0, 0, 1, 0, 0, 0, 1, 1], # optional - sage.modules ....: [1, 1, 0, 1, 0, 0, 0, 0]]) sage: from sage.combinat.diagram import NorthwestDiagrams sage: NorthwestDiagrams().from_parallelogram_polyomino(p).pp() diff --git a/src/sage/combinat/dlx.py b/src/sage/combinat/dlx.py index 6a6d0d15c11..d243abbc9c2 100644 --- a/src/sage/combinat/dlx.py +++ b/src/sage/combinat/dlx.py @@ -474,11 +474,11 @@ def AllExactCovers(M): EXAMPLES:: - sage: M = Matrix([[1,1,0],[1,0,1],[0,1,1]]) #no exact covers - sage: for cover in AllExactCovers(M): + sage: M = Matrix([[1,1,0],[1,0,1],[0,1,1]]) # no exact covers # optional - sage.modules + sage: for cover in AllExactCovers(M): # optional - sage.modules ....: print(cover) - sage: M = Matrix([[1,1,0],[1,0,1],[0,0,1],[0,1,0]]) #two exact covers - sage: for cover in AllExactCovers(M): + sage: M = Matrix([[1,1,0],[1,0,1],[0,0,1],[0,1,0]]) # two exact covers # optional - sage.modules + sage: for cover in AllExactCovers(M): # optional - sage.modules ....: print(cover) [(1, 1, 0), (0, 0, 1)] [(1, 0, 1), (0, 1, 0)] @@ -503,11 +503,11 @@ def OneExactCover(M): EXAMPLES:: - sage: M = Matrix([[1,1,0],[1,0,1],[0,1,1]]) # no exact covers - sage: OneExactCover(M) + sage: M = Matrix([[1,1,0],[1,0,1],[0,1,1]]) # no exact covers # optional - sage.modules + sage: OneExactCover(M) # optional - sage.modules - sage: M = Matrix([[1,1,0],[1,0,1],[0,0,1],[0,1,0]]) # two exact covers - sage: OneExactCover(M) + sage: M = Matrix([[1,1,0],[1,0,1],[0,0,1],[0,1,0]]) # two exact covers # optional - sage.modules + sage: OneExactCover(M) # optional - sage.modules [(1, 1, 0), (0, 0, 1)] """ for s in AllExactCovers(M): diff --git a/src/sage/combinat/e_one_star.py b/src/sage/combinat/e_one_star.py index 9bf37df14a6..a688cc04c4a 100644 --- a/src/sage/combinat/e_one_star.py +++ b/src/sage/combinat/e_one_star.py @@ -159,9 +159,9 @@ sage: P = Patch([Face([0,0], 1), Face([0,0], 2)]) sage: E = E1Star(WordMorphism({1:[1,2],2:[1]})) sage: F = E1Star(WordMorphism({1:[1,1,2],2:[2,1]})) - sage: E(P,5).plot() + sage: E(P,5).plot() # optional - sage.plot Graphics object consisting of 21 graphics primitives - sage: F(P,3).plot() + sage: F(P,3).plot() # optional - sage.plot Graphics object consisting of 34 graphics primitives Everything works in any dimension (except for the plotting features @@ -490,12 +490,12 @@ def _plot(self, projmat, face_contour, opacity) -> Graphics: sage: face_contour[1] = map(vector, [(0,0,0),(0,1,0),(0,1,1),(0,0,1)]) sage: face_contour[2] = map(vector, [(0,0,0),(0,0,1),(1,0,1),(1,0,0)]) sage: face_contour[3] = map(vector, [(0,0,0),(1,0,0),(1,1,0),(0,1,0)]) - sage: G = f._plot(projmat, face_contour, 0.75) + sage: G = f._plot(projmat, face_contour, 0.75) # optional - sage.plot :: sage: f = Face((0,0), 2) - sage: f._plot(None, None, 1) + sage: f._plot(None, None, 1) # optional - sage.plot Graphics object consisting of 1 graphics primitive """ v = self.vector() @@ -1102,7 +1102,7 @@ def plot(self, projmat=None, opacity=0.75) -> Graphics: sage: from sage.combinat.e_one_star import E1Star, Face, Patch sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]]) - sage: P.plot() + sage: P.plot() # optional - sage.plot Graphics object consisting of 3 graphics primitives :: @@ -1111,7 +1111,7 @@ def plot(self, projmat=None, opacity=0.75) -> Graphics: sage: E = E1Star(sigma) sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]]) sage: P = E(P, 5) - sage: P.plot() + sage: P.plot() # optional - sage.plot Graphics object consisting of 57 graphics primitives Plot with a different projection matrix:: @@ -1121,7 +1121,7 @@ def plot(self, projmat=None, opacity=0.75) -> Graphics: sage: P = Patch([Face((0,0,0),t) for t in [1,2,3]]) sage: M = matrix(2, 3, [1,0,-1,0.3,1,-3]) sage: P = E(P, 3) - sage: P.plot(projmat=M) + sage: P.plot(projmat=M) # optional - sage.plot Graphics object consisting of 17 graphics primitives Plot patches made of unit segments:: @@ -1129,9 +1129,9 @@ def plot(self, projmat=None, opacity=0.75) -> Graphics: sage: P = Patch([Face([0,0], 1), Face([0,0], 2)]) sage: E = E1Star(WordMorphism({1:[1,2],2:[1]})) sage: F = E1Star(WordMorphism({1:[1,1,2],2:[2,1]})) - sage: E(P,5).plot() + sage: E(P,5).plot() # optional - sage.plot Graphics object consisting of 21 graphics primitives - sage: F(P,3).plot() + sage: F(P,3).plot() # optional - sage.plot Graphics object consisting of 34 graphics primitives """ if self.dimension() == 2: diff --git a/src/sage/combinat/integer_vectors_mod_permgroup.py b/src/sage/combinat/integer_vectors_mod_permgroup.py index 539fc59b9c0..490e809694c 100644 --- a/src/sage/combinat/integer_vectors_mod_permgroup.py +++ b/src/sage/combinat/integer_vectors_mod_permgroup.py @@ -1,3 +1,4 @@ +# optional - sage.combinat sage.groups r""" Integer vectors modulo the action of a permutation group """ diff --git a/src/sage/combinat/interval_posets.py b/src/sage/combinat/interval_posets.py index 346cd954e21..989548ba328 100644 --- a/src/sage/combinat/interval_posets.py +++ b/src/sage/combinat/interval_posets.py @@ -611,11 +611,11 @@ def factor(self) -> list[TamariIntervalPoset]: TESTS:: - sage: T = TamariIntervalPosets(20).random_element() - sage: facs = factor(T) - sage: all(U.is_connected() for U in facs) + sage: T = TamariIntervalPosets(20).random_element() # optional - sage.combinat + sage: facs = factor(T) # optional - sage.combinat + sage: all(U.is_connected() for U in facs) # optional - sage.combinat True - sage: T == prod(facs) + sage: T == prod(facs) # optional - sage.combinat True """ hasse = self.poset().hasse_diagram() @@ -1030,10 +1030,10 @@ def cubical_coordinates(self) -> tuple[int, ...]: sage: ip = TamariIntervalPoset(3,[]) sage: ip.cubical_coordinates() (0, 0) - sage: ip = TamariIntervalPosets(10).random_element() - sage: len(ip.cubical_coordinates()) + sage: ip = TamariIntervalPosets(10).random_element() # optional - sage.combinat + sage: len(ip.cubical_coordinates()) # optional - sage.combinat 9 - sage: sorted(ip.cubical_coordinates() for ip in TamariIntervalPosets(2)) + sage: sorted(ip.cubical_coordinates() for ip in TamariIntervalPosets(2)) # optional - sage.combinat [(-1,), (0,), (1,)] REFERENCES: @@ -1136,7 +1136,8 @@ def rise_contact_involution(self) -> TIP: (4, 3), (3, 2), (2, 1)] sage: t.rise_contact_involution() == tip True - sage: tip.lower_dyck_word().number_of_touch_points() == t.upper_dyck_word().number_of_initial_rises() + sage: (tip.lower_dyck_word().number_of_touch_points() # optional - sage.combinat + ....: == t.upper_dyck_word().number_of_initial_rises()) True sage: tip.number_of_tamari_inversions() == t.number_of_tamari_inversions() True @@ -1232,7 +1233,7 @@ def insertion(self, i) -> TIP: ....: print(T, i) ....: return False ....: return True - sage: test_equivalence(3) + sage: test_equivalence(3) # optional - sage.combinat True sage: ti = TamariIntervalPosets(3).an_element() @@ -1674,17 +1675,17 @@ def contains_dyck_word(self, dyck_word) -> bool: EXAMPLES:: sage: ip = TamariIntervalPoset(4,[(2,4),(3,4),(2,1),(3,1)]) - sage: ip.contains_dyck_word(DyckWord([1,1,1,0,0,0,1,0])) + sage: ip.contains_dyck_word(DyckWord([1,1,1,0,0,0,1,0])) # optional - sage.combinat True - sage: ip.contains_dyck_word(DyckWord([1,1,0,1,0,1,0,0])) + sage: ip.contains_dyck_word(DyckWord([1,1,0,1,0,1,0,0])) # optional - sage.combinat True - sage: ip.contains_dyck_word(DyckWord([1,0,1,1,0,1,0,0])) + sage: ip.contains_dyck_word(DyckWord([1,0,1,1,0,1,0,0])) # optional - sage.combinat False - sage: ip.contains_dyck_word(ip.lower_dyck_word()) + sage: ip.contains_dyck_word(ip.lower_dyck_word()) # optional - sage.combinat True - sage: ip.contains_dyck_word(ip.upper_dyck_word()) + sage: ip.contains_dyck_word(ip.upper_dyck_word()) # optional - sage.combinat True - sage: all(ip.contains_dyck_word(bt) for bt in ip.dyck_words()) + sage: all(ip.contains_dyck_word(bt) for bt in ip.dyck_words()) # optional - sage.combinat True """ return self.contains_binary_tree(dyck_word.to_binary_tree_tamari()) @@ -1779,14 +1780,16 @@ def is_initial_interval(self) -> bool: sage: ip = TamariIntervalPoset(4, [(1, 2), (2, 4), (3, 4)]) sage: ip.is_initial_interval() True - sage: ip.lower_dyck_word() + sage: ip.lower_dyck_word() # optional - sage.combinat [1, 0, 1, 0, 1, 0, 1, 0] sage: ip = TamariIntervalPoset(4, [(1, 2), (2, 4), (3, 4), (3, 2)]) sage: ip.is_initial_interval() False - sage: ip.lower_dyck_word() + sage: ip.lower_dyck_word() # optional - sage.combinat [1, 0, 1, 1, 0, 0, 1, 0] - sage: all(DyckWord([1,0,1,0,1,0]).tamari_interval(dw).is_initial_interval() for dw in DyckWords(3)) + sage: all(DyckWord([1,0,1,0,1,0]).tamari_interval(dw) # optional - sage.combinat + ....: .is_initial_interval() + ....: for dw in DyckWords(3)) True """ return not self.decreasing_cover_relations() @@ -1807,14 +1810,16 @@ def is_final_interval(self) -> bool: sage: ip = TamariIntervalPoset(4, [(4, 3), (3, 1), (2, 1)]) sage: ip.is_final_interval() True - sage: ip.upper_dyck_word() + sage: ip.upper_dyck_word() # optional - sage.combinat [1, 1, 1, 1, 0, 0, 0, 0] sage: ip = TamariIntervalPoset(4, [(4, 3), (3, 1), (2, 1), (2, 3)]) sage: ip.is_final_interval() False - sage: ip.upper_dyck_word() + sage: ip.upper_dyck_word() # optional - sage.combinat [1, 1, 0, 1, 1, 0, 0, 0] - sage: all(dw.tamari_interval(DyckWord([1, 1, 1, 0, 0, 0])).is_final_interval() for dw in DyckWords(3)) + sage: all(dw.tamari_interval(DyckWord([1, 1, 1, 0, 0, 0])) # optional - sage.combinat + ....: .is_final_interval() + ....: for dw in DyckWords(3)) True """ return not self.increasing_cover_relations() @@ -1854,13 +1859,16 @@ def lower_dyck_word(self): EXAMPLES:: - sage: ip = TamariIntervalPoset(6,[(3,2),(4,3),(5,2),(6,5),(1,2),(4,5)]); ip - The Tamari interval of size 6 induced by relations [(1, 2), (4, 5), (6, 5), (5, 2), (4, 3), (3, 2)] - sage: ip.lower_dyck_word() + sage: ip = TamariIntervalPoset(6, [(3,2),(4,3),(5,2),(6,5),(1,2),(4,5)]); ip + The Tamari interval of size 6 induced by relations + [(1, 2), (4, 5), (6, 5), (5, 2), (4, 3), (3, 2)] + sage: ip.lower_dyck_word() # optional - sage.combinat [1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0] - sage: TamariIntervalPosets.final_forest(ip.lower_dyck_word()) == ip.final_forest() + sage: ldw_ff = TamariIntervalPosets.final_forest(ip.lower_dyck_word()) # optional - sage.combinat + sage: ldw_ff == ip.final_forest() # optional - sage.combinat True - sage: ip == TamariIntervalPosets.from_dyck_words(ip.lower_dyck_word(),ip.upper_dyck_word()) + sage: ip == TamariIntervalPosets.from_dyck_words(ip.lower_dyck_word(), # optional - sage.combinat + ....: ip.upper_dyck_word()) True """ return self.lower_binary_tree().to_dyck_word_tamari() @@ -1901,12 +1909,15 @@ def upper_dyck_word(self): EXAMPLES:: sage: ip = TamariIntervalPoset(6,[(3,2),(4,3),(5,2),(6,5),(1,2),(4,5)]); ip - The Tamari interval of size 6 induced by relations [(1, 2), (4, 5), (6, 5), (5, 2), (4, 3), (3, 2)] - sage: ip.upper_dyck_word() + The Tamari interval of size 6 induced by relations + [(1, 2), (4, 5), (6, 5), (5, 2), (4, 3), (3, 2)] + sage: ip.upper_dyck_word() # optional - sage.combinat [1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0] - sage: TamariIntervalPosets.initial_forest(ip.upper_dyck_word()) == ip.initial_forest() + sage: udw_if = TamariIntervalPosets.initial_forest(ip.upper_dyck_word()) # optional - sage.combinat + sage: udw_if == ip.initial_forest() # optional - sage.combinat True - sage: ip == TamariIntervalPosets.from_dyck_words(ip.lower_dyck_word(),ip.upper_dyck_word()) + sage: ip == TamariIntervalPosets.from_dyck_words(ip.lower_dyck_word(), # optional - sage.combinat + ....: ip.upper_dyck_word()) True """ return self.upper_binary_tree().to_dyck_word_tamari() @@ -2074,11 +2085,11 @@ def linear_extensions(self) -> Iterator[Permutation]: EXAMPLES:: - sage: ip = TamariIntervalPoset(3,[(1,2),(3,2)]) - sage: list(ip.linear_extensions()) + sage: ip = TamariIntervalPoset(3, [(1,2),(3,2)]) + sage: list(ip.linear_extensions()) # optional - sage.rings.finite_rings sage.modules [[3, 1, 2], [1, 3, 2]] - sage: ip = TamariIntervalPoset(4,[(1,2),(2,3),(4,3)]) - sage: list(ip.linear_extensions()) + sage: ip = TamariIntervalPoset(4, [(1,2),(2,3),(4,3)]) + sage: list(ip.linear_extensions()) # optional - sage.rings.finite_rings sage.modules [[4, 1, 2, 3], [1, 2, 4, 3], [1, 4, 2, 3]] """ for ext in self._poset.linear_extensions(): @@ -2220,12 +2231,12 @@ def dyck_words(self) -> Iterator: EXAMPLES:: - sage: list(TamariIntervalPoset(4,[(2,4),(3,4),(2,1),(3,1)]).dyck_words()) + sage: list(TamariIntervalPoset(4,[(2,4),(3,4),(2,1),(3,1)]).dyck_words()) # optional - sage.combinat [[1, 1, 1, 0, 0, 1, 0, 0], [1, 1, 1, 0, 0, 0, 1, 0], [1, 1, 0, 1, 0, 1, 0, 0], [1, 1, 0, 1, 0, 0, 1, 0]] - sage: set(TamariIntervalPoset(4,[]).dyck_words()) == set(DyckWords(4)) + sage: set(TamariIntervalPoset(4,[]).dyck_words()) == set(DyckWords(4)) # optional - sage.combinat True """ for ip in self.lower_contained_intervals(): @@ -2302,10 +2313,10 @@ def maximal_chain_dyck_words(self) -> Iterator: EXAMPLES:: sage: ip = TamariIntervalPoset(4,[(2,4),(3,4),(2,1),(3,1)]) - sage: list(ip.maximal_chain_dyck_words()) + sage: list(ip.maximal_chain_dyck_words()) # optional - sage.combinat [[1, 1, 0, 1, 0, 0, 1, 0], [1, 1, 0, 1, 0, 1, 0, 0], [1, 1, 1, 0, 0, 1, 0, 0]] sage: ip = TamariIntervalPoset(4,[]) - sage: list(ip.maximal_chain_dyck_words()) + sage: list(ip.maximal_chain_dyck_words()) # optional - sage.combinat [[1, 0, 1, 0, 1, 0, 1, 0], [1, 1, 0, 0, 1, 0, 1, 0], [1, 1, 0, 1, 0, 0, 1, 0], @@ -2371,9 +2382,13 @@ def tamari_inversions(self) -> list[tuple[int, int]]: sage: ip = TamariIntervalPoset(4,[]) sage: ip.tamari_inversions() [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)] - sage: all(len(TamariIntervalPosets.from_binary_trees(bt,bt).tamari_inversions())==0 for bt in BinaryTrees(3)) + sage: all(not TamariIntervalPosets.from_binary_trees(bt,bt) # optional - sage.combinat + ....: .tamari_inversions() + ....: for bt in BinaryTrees(3)) True - sage: all(len(TamariIntervalPosets.from_binary_trees(bt,bt).tamari_inversions())==0 for bt in BinaryTrees(4)) + sage: all(not TamariIntervalPosets.from_binary_trees(bt,bt) # optional - sage.combinat + ....: .tamari_inversions() + ....: for bt in BinaryTrees(4)) True """ return list(self.tamari_inversions_iter()) @@ -2494,18 +2509,18 @@ def new_decomposition(self) -> list[TIP]: sage: ex = TamariIntervalPosets(4)[11] sage: ex.number_of_new_components() 3 - sage: ex.new_decomposition() + sage: ex.new_decomposition() # optional - sage.combinat [The Tamari interval of size 1 induced by relations [], The Tamari interval of size 2 induced by relations [], The Tamari interval of size 1 induced by relations []] TESTS:: - sage: ex = TamariIntervalPosets(4).random_element() - sage: dec = ex.new_decomposition() - sage: len(dec) == ex.number_of_new_components() + sage: ex = TamariIntervalPosets(4).random_element() # optional - sage.combinat + sage: dec = ex.new_decomposition() # optional - sage.combinat + sage: len(dec) == ex.number_of_new_components() # optional - sage.combinat True - sage: all(u.is_new() for u in dec) + sage: all(u.is_new() for u in dec) # optional - sage.combinat True """ from sage.combinat.binary_tree import BinaryTree @@ -3026,11 +3041,11 @@ def final_forest(element) -> TIP: From Dyck words:: - sage: dw = DyckWord([1,0]) - sage: TamariIntervalPosets.final_forest(dw) + sage: dw = DyckWord([1,0]) # optional - sage.combinat + sage: TamariIntervalPosets.final_forest(dw) # optional - sage.combinat The Tamari interval of size 1 induced by relations [] - sage: dw = DyckWord([1,1,0,1,0,0,1,1,0,0]) - sage: TamariIntervalPosets.final_forest(dw) + sage: dw = DyckWord([1,1,0,1,0,0,1,1,0,0]) # optional - sage.combinat + sage: TamariIntervalPosets.final_forest(dw) # optional - sage.combinat The Tamari interval of size 5 induced by relations [(5, 4), (3, 1), (2, 1)] TESTS:: @@ -3133,11 +3148,11 @@ def initial_forest(element) -> TIP: from Dyck words:: - sage: dw = DyckWord([1,0]) - sage: TamariIntervalPosets.initial_forest(dw) + sage: dw = DyckWord([1,0]) # optional - sage.combinat + sage: TamariIntervalPosets.initial_forest(dw) # optional - sage.combinat The Tamari interval of size 1 induced by relations [] - sage: dw = DyckWord([1,1,0,1,0,0,1,1,0,0]) - sage: TamariIntervalPosets.initial_forest(dw) + sage: dw = DyckWord([1,1,0,1,0,0,1,1,0,0]) # optional - sage.combinat + sage: TamariIntervalPosets.initial_forest(dw) # optional - sage.combinat The Tamari interval of size 5 induced by relations [(1, 4), (2, 3), (3, 4)] TESTS:: @@ -3252,26 +3267,27 @@ def from_dyck_words(dw1, dw2) -> TIP: EXAMPLES:: - sage: dw1 = DyckWord([1,0,1,0]) - sage: dw2 = DyckWord([1,1,0,0]) - sage: TamariIntervalPosets.from_dyck_words(dw1,dw2) + sage: dw1 = DyckWord([1,0,1,0]) # optional - sage.combinat + sage: dw2 = DyckWord([1,1,0,0]) # optional - sage.combinat + sage: TamariIntervalPosets.from_dyck_words(dw1, dw2) # optional - sage.combinat The Tamari interval of size 2 induced by relations [] - sage: TamariIntervalPosets.from_dyck_words(dw1,dw1) + sage: TamariIntervalPosets.from_dyck_words(dw1,dw1) # optional - sage.combinat The Tamari interval of size 2 induced by relations [(1, 2)] - sage: TamariIntervalPosets.from_dyck_words(dw2,dw2) + sage: TamariIntervalPosets.from_dyck_words(dw2,dw2) # optional - sage.combinat The Tamari interval of size 2 induced by relations [(2, 1)] - sage: dw1 = DyckWord([1,0,1,1,1,0,0,1,1,0,0,0]) - sage: dw2 = DyckWord([1,1,1,1,0,1,1,0,0,0,0,0]) - sage: TamariIntervalPosets.from_dyck_words(dw1,dw2) - The Tamari interval of size 6 induced by relations [(4, 5), (6, 5), (5, 2), (4, 3), (3, 2)] + sage: dw1 = DyckWord([1,0,1,1,1,0,0,1,1,0,0,0]) # optional - sage.combinat + sage: dw2 = DyckWord([1,1,1,1,0,1,1,0,0,0,0,0]) # optional - sage.combinat + sage: TamariIntervalPosets.from_dyck_words(dw1,dw2) # optional - sage.combinat + The Tamari interval of size 6 induced by relations + [(4, 5), (6, 5), (5, 2), (4, 3), (3, 2)] - sage: dw3 = DyckWord([1,1,1,0,1,1,1,0,0,0,0,0]) - sage: TamariIntervalPosets.from_dyck_words(dw1,dw3) + sage: dw3 = DyckWord([1,1,1,0,1,1,1,0,0,0,0,0]) # optional - sage.combinat + sage: TamariIntervalPosets.from_dyck_words(dw1,dw3) # optional - sage.combinat Traceback (most recent call last): ... ValueError: the two Dyck words are not comparable on the Tamari lattice - sage: TamariIntervalPosets.from_dyck_words(dw1,DyckWord([1,0])) + sage: TamariIntervalPosets.from_dyck_words(dw1,DyckWord([1,0])) # optional - sage.combinat Traceback (most recent call last): ... ValueError: the two Dyck words are not comparable on the Tamari lattice @@ -3380,7 +3396,7 @@ def from_minimal_schnyder_wood(graph) -> TIP: sage: TIP = TamariIntervalPosets sage: G = DiGraph([(0,-1,0),(0,-2,1),(0,-3,2)], format='list_of_edges') sage: G.set_embedding({-1:[0],-2:[0],-3:[0],0:[-1,-2,-3]}) - sage: TIP.from_minimal_schnyder_wood(G) + sage: TIP.from_minimal_schnyder_wood(G) # optional - sage.combinat The Tamari interval of size 1 induced by relations [] An example from page 14 of [BeBo2009]_:: @@ -3398,8 +3414,9 @@ def from_minimal_schnyder_wood(graph) -> TIP: sage: for k in range(6): ....: embed[k] = data_emb[k] sage: G.set_embedding(embed) - sage: TIP.from_minimal_schnyder_wood(G) - The Tamari interval of size 6 induced by relations [(1, 4), (2, 4), (3, 4), (5, 6), (6, 4), (5, 4), (3, 1), (2, 1)] + sage: TIP.from_minimal_schnyder_wood(G) # optional - sage.combinat + The Tamari interval of size 6 induced by relations + [(1, 4), (2, 4), (3, 4), (5, 6), (6, 4), (5, 4), (3, 1), (2, 1)] An example from page 18 of [BeBo2009]_:: @@ -3416,8 +3433,9 @@ def from_minimal_schnyder_wood(graph) -> TIP: sage: for k in range(6): ....: embed[k] = data_emb[k] sage: G.set_embedding(embed) - sage: TIP.from_minimal_schnyder_wood(G) - The Tamari interval of size 6 induced by relations [(1, 3), (2, 3), (4, 5), (5, 3), (4, 3), (2, 1)] + sage: TIP.from_minimal_schnyder_wood(G) # optional - sage.combinat + The Tamari interval of size 6 induced by relations + [(1, 3), (2, 3), (4, 5), (5, 3), (4, 3), (2, 1)] Another small example:: @@ -3433,7 +3451,7 @@ def from_minimal_schnyder_wood(graph) -> TIP: sage: for k in range(3): ....: embed[k] = data_emb[k] sage: G.set_embedding(embed) - sage: TIP.from_minimal_schnyder_wood(G) + sage: TIP.from_minimal_schnyder_wood(G) # optional - sage.combinat The Tamari interval of size 3 induced by relations [(2, 3), (2, 1)] """ from sage.combinat.dyck_word import DyckWord @@ -3797,14 +3815,14 @@ def random_element(self) -> TIP: EXAMPLES:: - sage: T = TamariIntervalPosets(4).random_element() - sage: T.parent() + sage: T = TamariIntervalPosets(4).random_element() # optional - sage.combinat + sage: T.parent() # optional - sage.combinat Interval-posets - sage: u = T.lower_dyck_word(); u # random + sage: u = T.lower_dyck_word(); u # random # optional - sage.combinat [1, 1, 0, 1, 0, 0, 1, 0] - sage: v = T.lower_dyck_word(); v # random + sage: v = T.lower_dyck_word(); v # random # optional - sage.combinat [1, 1, 0, 1, 0, 0, 1, 0] - sage: len(u) + sage: len(u) # optional - sage.combinat 8 """ from sage.graphs.schnyder import minimal_schnyder_wood diff --git a/src/sage/combinat/matrices/dlxcpp.py b/src/sage/combinat/matrices/dlxcpp.py index 4e12b98e325..e235f885188 100644 --- a/src/sage/combinat/matrices/dlxcpp.py +++ b/src/sage/combinat/matrices/dlxcpp.py @@ -92,14 +92,14 @@ def AllExactCovers(M): EXAMPLES: No exact covers:: - sage: M = Matrix([[1,1,0],[1,0,1],[0,1,1]]) - sage: [cover for cover in AllExactCovers(M)] + sage: M = Matrix([[1,1,0],[1,0,1],[0,1,1]]) # optional - sage.modules + sage: [cover for cover in AllExactCovers(M)] # optional - sage.modules [] Two exact covers:: - sage: M = Matrix([[1,1,0],[1,0,1],[0,0,1],[0,1,0]]) - sage: [cover for cover in AllExactCovers(M)] + sage: M = Matrix([[1,1,0],[1,0,1],[0,0,1],[0,1,0]]) # optional - sage.modules + sage: [cover for cover in AllExactCovers(M)] # optional - sage.modules [[(1, 1, 0), (0, 0, 1)], [(1, 0, 1), (0, 1, 0)]] """ rows = [] @@ -119,11 +119,11 @@ def OneExactCover(M): EXAMPLES:: - sage: M = Matrix([[1,1,0],[1,0,1],[0,1,1]]) #no exact covers - sage: print(OneExactCover(M)) + sage: M = Matrix([[1,1,0],[1,0,1],[0,1,1]]) # no exact covers # optional - sage.modules + sage: print(OneExactCover(M)) # optional - sage.modules None - sage: M = Matrix([[1,1,0],[1,0,1],[0,0,1],[0,1,0]]) #two exact covers - sage: OneExactCover(M) + sage: M = Matrix([[1,1,0],[1,0,1],[0,0,1],[0,1,0]]) # two exact covers # optional - sage.modules + sage: OneExactCover(M) # optional - sage.modules [(1, 1, 0), (0, 0, 1)] """ diff --git a/src/sage/combinat/multiset_partition_into_sets_ordered.py b/src/sage/combinat/multiset_partition_into_sets_ordered.py index 462b52cd447..7775f33ad93 100755 --- a/src/sage/combinat/multiset_partition_into_sets_ordered.py +++ b/src/sage/combinat/multiset_partition_into_sets_ordered.py @@ -45,7 +45,7 @@ Crystal of ordered multiset partitions into sets on the alphabet `\{1,2,3\}` with 4 letters divided into 2 blocks:: - sage: crystals.Minimaj(3, 4, 2).list() + sage: crystals.Minimaj(3, 4, 2).list() # optional - sage.modules [((2, 3, 1), (1,)), ((2, 3), (1, 2)), ((2, 3), (1, 3)), ((2, 1), (1, 2)), ((3, 1), (1, 2)), ((3, 1, 2), (2,)), ((3, 1), (1, 3)), ((3, 1), (2, 3)), ((3, 2), (2, 3)), ((2, 1), (1, 3)), ((2,), (1, 2, 3)), ((3,), (1, 2, 3)), @@ -3200,14 +3200,14 @@ class MinimajCrystal(UniqueRepresentation, Parent): EXAMPLES:: - sage: list(crystals.Minimaj(2,3,2)) + sage: list(crystals.Minimaj(2,3,2)) # optional - sage.modules [((2, 1), (1,)), ((2,), (1, 2)), ((1,), (1, 2)), ((1, 2), (2,))] - sage: b = crystals.Minimaj(3, 5, 2).an_element(); b + sage: b = crystals.Minimaj(3, 5, 2).an_element(); b # optional - sage.modules ((2, 3, 1), (1, 2)) - sage: b.f(2) + sage: b.f(2) # optional - sage.modules ((2, 3, 1), (1, 3)) - sage: b.e(2) + sage: b.e(2) # optional - sage.modules """ def __init__(self, n, ell, k): @@ -3216,17 +3216,17 @@ def __init__(self, n, ell, k): TESTS:: - sage: B = crystals.Minimaj(2,3,2) - sage: TestSuite(B).run() + sage: B = crystals.Minimaj(2,3,2) # optional - sage.modules + sage: TestSuite(B).run() # optional - sage.modules - sage: B = crystals.Minimaj(3, 5, 2) - sage: TestSuite(B).run() + sage: B = crystals.Minimaj(3, 5, 2) # optional - sage.modules + sage: TestSuite(B).run() # optional - sage.modules - sage: list(crystals.Minimaj(2,6,3)) + sage: list(crystals.Minimaj(2,6,3)) # optional - sage.modules [((1, 2), (2, 1), (1, 2))] - sage: list(crystals.Minimaj(2,5,2)) # blocks too fat for alphabet + sage: list(crystals.Minimaj(2,5,2)) # blocks too fat for alphabet # optional - sage.modules [] - sage: list(crystals.Minimaj(4,2,3)) # more blocks than letters + sage: list(crystals.Minimaj(4,2,3)) # more blocks than letters # optional - sage.modules Traceback (most recent call last): ... ValueError: n (=4), ell (=2), and k (=3) must all be positive integers @@ -3259,7 +3259,7 @@ def _repr_(self): EXAMPLES:: - sage: B = crystals.Minimaj(3,4,2); B + sage: B = crystals.Minimaj(3,4,2); B # optional - sage.modules Minimaj Crystal of type A_2 of words of length 4 into 2 blocks """ return ("Minimaj Crystal of type A_%s of words of length %s into %s blocks" @@ -3271,14 +3271,14 @@ def _an_element_(self): EXAMPLES:: - sage: B = crystals.Minimaj(4,5,3) - sage: B.an_element() + sage: B = crystals.Minimaj(4,5,3) # optional - sage.modules + sage: B.an_element() # optional - sage.modules ((2, 3, 1), (1,), (1,)) - sage: B = crystals.Minimaj(2,2,1) - sage: B.an_element() + sage: B = crystals.Minimaj(2,2,1) # optional - sage.modules + sage: B.an_element() # optional - sage.modules ((1, 2),) - sage: B = crystals.Minimaj(1,2,1) - sage: B.an_element() + sage: B = crystals.Minimaj(1,2,1) # optional - sage.modules + sage: B.an_element() # optional - sage.modules Traceback (most recent call last): ... EmptySetError @@ -3294,14 +3294,14 @@ def _element_constructor_(self, x): EXAMPLES:: - sage: B1 = crystals.Minimaj(4,5,3); b = B1.an_element(); b + sage: B1 = crystals.Minimaj(4,5,3); b = B1.an_element(); b # optional - sage.modules ((2, 3, 1), (1,), (1,)) - sage: B1._element_constructor_(list(b)) + sage: B1._element_constructor_(list(b)) # optional - sage.modules ((2, 3, 1), (1,), (1,)) - sage: B1._element_constructor_([[1,2,3], [2], [2]]) + sage: B1._element_constructor_([[1,2,3], [2], [2]]) # optional - sage.modules ((3, 1, 2), (2,), (2,)) - sage: B2 = crystals.Minimaj(5,5,3) - sage: B2._element_constructor_(b) + sage: B2 = crystals.Minimaj(5,5,3) # optional - sage.modules + sage: B2._element_constructor_(b) # optional - sage.modules ((2, 3, 1), (1,), (1,)) """ # Allow ``x`` to be either of: @@ -3325,17 +3325,17 @@ def __contains__(self, x): EXAMPLES:: - sage: B1 = crystals.Minimaj(2,5,3); b1 = B1.an_element(); b1 + sage: B1 = crystals.Minimaj(2,5,3); b1 = B1.an_element(); b1 # optional - sage.modules ((1, 2), (2, 1), (1,)) - sage: B2 = crystals.Minimaj(5,5,3); b2 = B2.an_element(); b2 + sage: B2 = crystals.Minimaj(5,5,3); b2 = B2.an_element(); b2 # optional - sage.modules ((2, 3, 1), (1,), (1,)) - sage: b2a = B2(((1,2), (1,), (1,2))); b2a + sage: b2a = B2(((1,2), (1,), (1,2))); b2a # optional - sage.modules ((2, 1), (1,), (1, 2)) - sage: b1 in B2 + sage: b1 in B2 # optional - sage.modules True - sage: b2 in B1 + sage: b2 in B1 # optional - sage.modules False - sage: b2a in B1 + sage: b2a in B1 # optional - sage.modules True """ if isinstance(x, MinimajCrystal.Element): @@ -3356,24 +3356,24 @@ def from_tableau(self, t): EXAMPLES:: - sage: B = crystals.Minimaj(3,6,3) - sage: b = B.an_element(); b + sage: B = crystals.Minimaj(3,6,3) # optional - sage.modules + sage: b = B.an_element(); b # optional - sage.modules ((3, 1, 2), (2, 1), (1,)) - sage: t = b.to_tableaux_words(); t + sage: t = b.to_tableaux_words(); t # optional - sage.modules [[1], [2, 1], [], [3, 2, 1]] - sage: B.from_tableau(t) + sage: B.from_tableau(t) # optional - sage.modules ((3, 1, 2), (2, 1), (1,)) - sage: B.from_tableau(t) == b + sage: B.from_tableau(t) == b # optional - sage.modules True TESTS:: - sage: B = crystals.Minimaj(3,6,3) - sage: all(mu == B.from_tableau(mu.to_tableaux_words()) for mu in B) + sage: B = crystals.Minimaj(3,6,3) # optional - sage.modules + sage: all(mu == B.from_tableau(mu.to_tableaux_words()) for mu in B) # optional - sage.modules True - sage: t = B.an_element().to_tableaux_words() - sage: B1 = crystals.Minimaj(3,6,2) - sage: B1.from_tableau(t) + sage: t = B.an_element().to_tableaux_words() # optional - sage.modules + sage: B1 = crystals.Minimaj(3,6,2) # optional - sage.modules + sage: B1.from_tableau(t) # optional - sage.modules Traceback (most recent call last): ... ValueError: ((3, 1, 2), (2, 1), (1,)) is not an element of @@ -3393,8 +3393,8 @@ def val(self, q='q'): Verifying Example 4.5 from [BCHOPSY2017]_:: - sage: B = crystals.Minimaj(3, 4, 2) # for `Val_{4,1}^{(3)}` - sage: B.val() + sage: B = crystals.Minimaj(3, 4, 2) # for `Val_{4,1}^{(3)}` # optional - sage.modules + sage: B.val() # optional - sage.modules (q^2+q+1)*s[2, 1, 1] + q*s[2, 2] """ H = [self._OMPs(list(b)) for b in self.highest_weight_vectors()] @@ -3428,7 +3428,7 @@ def _repr_(self): EXAMPLES:: - sage: crystals.Minimaj(4,5,3).an_element() + sage: crystals.Minimaj(4,5,3).an_element() # optional - sage.modules ((2, 3, 1), (1,), (1,)) """ return repr(self._minimaj_blocks_from_word_pair()) @@ -3439,11 +3439,11 @@ def __iter__(self): EXAMPLES:: - sage: b = crystals.Minimaj(4,5,3).an_element(); b + sage: b = crystals.Minimaj(4,5,3).an_element(); b # optional - sage.modules ((2, 3, 1), (1,), (1,)) - sage: b.value + sage: b.value # optional - sage.modules ([1, 3, 2, 1, 1], (0, 1, 2, 5)) - sage: list(b) + sage: list(b) # optional - sage.modules [(2, 3, 1), (1,), (1,)] """ return self._minimaj_blocks_from_word_pair().__iter__() @@ -3454,9 +3454,9 @@ def _latex_(self): EXAMPLES:: - sage: b = crystals.Minimaj(4,5,3).an_element(); b + sage: b = crystals.Minimaj(4,5,3).an_element(); b # optional - sage.modules ((2, 3, 1), (1,), (1,)) - sage: latex(b) + sage: latex(b) # optional - sage.modules \left(\left(2, 3, 1\right), \left(1\right), \left(1\right)\right) """ return latex(self._minimaj_blocks_from_word_pair()) @@ -3468,10 +3468,10 @@ def _minimaj_blocks_from_word_pair(self): EXAMPLES:: - sage: B = crystals.Minimaj(4,5,3) - sage: b = B.an_element(); b.value + sage: B = crystals.Minimaj(4,5,3) # optional - sage.modules + sage: b = B.an_element(); b.value # optional - sage.modules ([1, 3, 2, 1, 1], (0, 1, 2, 5)) - sage: b._minimaj_blocks_from_word_pair() + sage: b._minimaj_blocks_from_word_pair() # optional - sage.modules ((2, 3, 1), (1,), (1,)) """ return _to_minimaj_blocks(self.to_tableaux_words()) @@ -3483,15 +3483,15 @@ def to_tableaux_words(self): EXAMPLES:: - sage: B = crystals.Minimaj(4,5,3) - sage: b = B.an_element(); b + sage: B = crystals.Minimaj(4,5,3) # optional - sage.modules + sage: b = B.an_element(); b # optional - sage.modules ((2, 3, 1), (1,), (1,)) - sage: b.to_tableaux_words() + sage: b.to_tableaux_words() # optional - sage.modules [[1], [3], [2, 1, 1]] - sage: b = B([[1,3,4], [3], [3]]); b + sage: b = B([[1,3,4], [3], [3]]); b # optional - sage.modules ((4, 1, 3), (3,), (3,)) - sage: b.to_tableaux_words() + sage: b.to_tableaux_words() # optional - sage.modules [[3, 1], [], [4, 3, 3]] """ w, breaks = self.value @@ -3504,10 +3504,10 @@ def e(self, i): EXAMPLES:: - sage: B = crystals.Minimaj(4,3,2) - sage: b = B([[2,3], [3]]); b + sage: B = crystals.Minimaj(4,3,2) # optional - sage.modules + sage: b = B([[2,3], [3]]); b # optional - sage.modules ((2, 3), (3,)) - sage: [b.e(i) for i in range(1,4)] + sage: [b.e(i) for i in range(1,4)] # optional - sage.modules [((1, 3), (3,)), ((2,), (2, 3)), None] """ P = self.parent() @@ -3523,10 +3523,10 @@ def f(self,i): EXAMPLES:: - sage: B = crystals.Minimaj(4,3,2) - sage: b = B([[2,3], [3]]); b + sage: B = crystals.Minimaj(4,3,2) # optional - sage.modules + sage: b = B([[2,3], [3]]); b # optional - sage.modules ((2, 3), (3,)) - sage: [b.f(i) for i in range(1,4)] + sage: [b.f(i) for i in range(1,4)] # optional - sage.modules [None, None, ((2, 3), (4,))] """ P = self.parent() diff --git a/src/sage/combinat/ordered_tree.py b/src/sage/combinat/ordered_tree.py index 6a8f1206ff7..8faea2f248b 100644 --- a/src/sage/combinat/ordered_tree.py +++ b/src/sage/combinat/ordered_tree.py @@ -360,19 +360,20 @@ def to_parallelogram_polyomino(self, bijection=None): EXAMPLES:: sage: T = OrderedTree([[[], [[], [[]]]], [], [[[],[]]], [], []]) - sage: T.to_parallelogram_polyomino( bijection='Boussicault-Socci' ) - [[0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1], [1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0]] + sage: T.to_parallelogram_polyomino(bijection='Boussicault-Socci') # optional - sage.combinat + [[0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1], + [1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0]] sage: T = OrderedTree( [] ) - sage: T.to_parallelogram_polyomino() + sage: T.to_parallelogram_polyomino() # optional - sage.combinat [[1], [1]] sage: T = OrderedTree( [[]] ) - sage: T.to_parallelogram_polyomino() + sage: T.to_parallelogram_polyomino() # optional - sage.combinat [[0, 1], [1, 0]] sage: T = OrderedTree( [[],[]] ) - sage: T.to_parallelogram_polyomino() + sage: T.to_parallelogram_polyomino() # optional - sage.combinat [[0, 1, 1], [1, 1, 0]] sage: T = OrderedTree( [[[]]] ) - sage: T.to_parallelogram_polyomino() + sage: T.to_parallelogram_polyomino() # optional - sage.combinat [[0, 0, 1], [1, 0, 0]] """ if (bijection is None) or (bijection == 'Boussicault-Socci'): @@ -391,19 +392,19 @@ def _to_parallelogram_polyomino_Boussicault_Socci(self): sage: T = OrderedTree( ....: [[[], [[], [[]]]], [], [[[],[]]], [], []] ....: ) - sage: T._to_parallelogram_polyomino_Boussicault_Socci() + sage: T._to_parallelogram_polyomino_Boussicault_Socci() # optional - sage.combinat [[0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1], [1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0]] sage: T = OrderedTree( [] ) - sage: T._to_parallelogram_polyomino_Boussicault_Socci() + sage: T._to_parallelogram_polyomino_Boussicault_Socci() # optional - sage.combinat [[1], [1]] sage: T = OrderedTree( [[]] ) - sage: T._to_parallelogram_polyomino_Boussicault_Socci() + sage: T._to_parallelogram_polyomino_Boussicault_Socci() # optional - sage.combinat [[0, 1], [1, 0]] sage: T = OrderedTree( [[],[]] ) - sage: T._to_parallelogram_polyomino_Boussicault_Socci() + sage: T._to_parallelogram_polyomino_Boussicault_Socci() # optional - sage.combinat [[0, 1, 1], [1, 1, 0]] sage: T = OrderedTree( [[[]]] ) - sage: T._to_parallelogram_polyomino_Boussicault_Socci() + sage: T._to_parallelogram_polyomino_Boussicault_Socci() # optional - sage.combinat [[0, 0, 1], [1, 0, 0]] """ from sage.combinat.parallelogram_polyomino import ParallelogramPolyomino @@ -500,13 +501,13 @@ def to_dyck_word(self): EXAMPLES:: sage: T = OrderedTree([[],[]]) - sage: T.to_dyck_word() + sage: T.to_dyck_word() # optional - sage.combinat [1, 0, 1, 0] sage: T = OrderedTree([[],[[]]]) - sage: T.to_dyck_word() + sage: T.to_dyck_word() # optional - sage.combinat [1, 0, 1, 1, 0, 0] sage: T = OrderedTree([[], [[], []], [[], [[]]]]) - sage: T.to_dyck_word() + sage: T.to_dyck_word() # optional - sage.combinat [1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0] """ word = [] @@ -1087,18 +1088,19 @@ def random_element(self): EXAMPLES:: - sage: OrderedTrees(5).random_element() # random + sage: OrderedTrees(5).random_element() # random # optional - sage.combinat [[[], []], []] - sage: OrderedTrees(0).random_element() + sage: OrderedTrees(0).random_element() # optional - sage.combinat Traceback (most recent call last): ... EmptySetError: there are no ordered trees of size 0 - sage: OrderedTrees(1).random_element() + sage: OrderedTrees(1).random_element() # optional - sage.combinat [] TESTS:: - sage: all(OrderedTrees(10).random_element() in OrderedTrees(10) for i in range(20)) + sage: all(OrderedTrees(10).random_element() in OrderedTrees(10) # optional - sage.combinat + ....: for i in range(20)) True """ if self._size == 0: diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 3470e41cc77..7ed1da6de1c 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -1088,15 +1088,14 @@ def power(self, k): Now let us compare this to the power map on `S_8`:: - sage: G = SymmetricGroup(8) - sage: g = G([(1,2,3,4,5),(6,7,8)]) - sage: g + sage: G = SymmetricGroup(8) # optional - sage.groups + sage: g = G([(1,2,3,4,5),(6,7,8)]); g # optional - sage.groups (1,2,3,4,5)(6,7,8) - sage: g^2 + sage: g^2 # optional - sage.groups (1,3,5,2,4)(6,8,7) - sage: g^3 + sage: g^3 # optional - sage.groups (1,4,2,5,3) - sage: g^4 + sage: g^4 # optional - sage.groups (1,5,4,3,2)(6,7,8) :: @@ -1215,10 +1214,10 @@ def sign(self): :: - sage: F = GF(11) - sage: a = F.multiplicative_generator();a + sage: F = GF(11) # optional - sage.rings.finite_rings + sage: a = F.multiplicative_generator();a # optional - sage.rings.finite_rings 2 - sage: plist = [int(a*F(x)) for x in range(1,11)]; plist + sage: plist = [int(a*F(x)) for x in range(1,11)]; plist # optional - sage.rings.finite_rings [2, 4, 6, 8, 10, 1, 3, 5, 7, 9] This corresponds to the permutation (1, 2, 4, 8, 5, 10, 9, 7, 3, 6) @@ -1227,8 +1226,8 @@ def sign(self): :: - sage: p = PermutationGroupElement('(1, 2, 4, 8, 5, 10, 9, 7, 3, 6)') - sage: p.sign() + sage: p = PermutationGroupElement('(1, 2, 4, 8, 5, 10, 9, 7, 3, 6)') # optional - sage.groups + sage: p.sign() # optional - sage.groups -1 sage: Partition([10]).sign() -1 @@ -1237,12 +1236,12 @@ def sign(self): Now replace `2` by `3`:: - sage: plist = [int(F(3*x)) for x in range(1,11)]; plist + sage: plist = [int(F(3*x)) for x in range(1,11)]; plist # optional - sage.rings.finite_rings [3, 6, 9, 1, 4, 7, 10, 2, 5, 8] sage: list(range(1, 11)) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - sage: p = PermutationGroupElement('(3,4,8,7,9)') - sage: p.sign() + sage: p = PermutationGroupElement('(3,4,8,7,9)') # optional - sage.groups + sage: p.sign() # optional - sage.groups 1 sage: kronecker_symbol(3,11) 1 @@ -1885,55 +1884,55 @@ def cell_poset(self, orientation="SE"): EXAMPLES:: sage: p = Partition([3,3,1]) - sage: Q = p.cell_poset(); Q + sage: Q = p.cell_poset(); Q # optional - sage.graphs Finite poset containing 7 elements - sage: sorted(Q) + sage: sorted(Q) # optional - sage.graphs [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0)] - sage: sorted(Q.maximal_elements()) + sage: sorted(Q.maximal_elements()) # optional - sage.graphs [(1, 2), (2, 0)] - sage: Q.minimal_elements() + sage: Q.minimal_elements() # optional - sage.graphs [(0, 0)] - sage: sorted(Q.upper_covers((1, 0))) + sage: sorted(Q.upper_covers((1, 0))) # optional - sage.graphs [(1, 1), (2, 0)] - sage: Q.upper_covers((1, 1)) + sage: Q.upper_covers((1, 1)) # optional - sage.graphs [(1, 2)] - sage: P = p.cell_poset(orientation="NW"); P + sage: P = p.cell_poset(orientation="NW"); P # optional - sage.graphs Finite poset containing 7 elements - sage: sorted(P) + sage: sorted(P) # optional - sage.graphs [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0)] - sage: sorted(P.minimal_elements()) + sage: sorted(P.minimal_elements()) # optional - sage.graphs [(1, 2), (2, 0)] - sage: P.maximal_elements() + sage: P.maximal_elements() # optional - sage.graphs [(0, 0)] - sage: P.upper_covers((2, 0)) + sage: P.upper_covers((2, 0)) # optional - sage.graphs [(1, 0)] - sage: sorted(P.upper_covers((1, 2))) + sage: sorted(P.upper_covers((1, 2))) # optional - sage.graphs [(0, 2), (1, 1)] - sage: sorted(P.upper_covers((1, 1))) + sage: sorted(P.upper_covers((1, 1))) # optional - sage.graphs [(0, 1), (1, 0)] - sage: sorted([len(P.upper_covers(v)) for v in P]) + sage: sorted([len(P.upper_covers(v)) for v in P]) # optional - sage.graphs [0, 1, 1, 1, 1, 2, 2] - sage: R = p.cell_poset(orientation="NE"); R + sage: R = p.cell_poset(orientation="NE"); R # optional - sage.graphs Finite poset containing 7 elements - sage: sorted(R) + sage: sorted(R) # optional - sage.graphs [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0)] - sage: R.maximal_elements() + sage: R.maximal_elements() # optional - sage.graphs [(0, 2)] - sage: R.minimal_elements() + sage: R.minimal_elements() # optional - sage.graphs [(2, 0)] - sage: sorted([len(R.upper_covers(v)) for v in R]) + sage: sorted([len(R.upper_covers(v)) for v in R]) # optional - sage.graphs [0, 1, 1, 1, 1, 2, 2] - sage: R.is_isomorphic(P) + sage: R.is_isomorphic(P) # optional - sage.graphs False - sage: R.is_isomorphic(P.dual()) + sage: R.is_isomorphic(P.dual()) # optional - sage.graphs False Linear extensions of ``p.cell_poset()`` are in 1-to-1 correspondence with standard Young tableaux of shape `p`:: - sage: all( len(p.cell_poset().linear_extensions()) + sage: all( len(p.cell_poset().linear_extensions()) # optional - sage.graphs ....: == len(p.standard_tableaux()) ....: for n in range(8) for p in Partitions(n) ) True @@ -1941,7 +1940,7 @@ def cell_poset(self, orientation="SE"): This is not the case for northeast orientation:: sage: q = Partition([3, 1]) - sage: q.cell_poset(orientation="NE").is_chain() + sage: q.cell_poset(orientation="NE").is_chain() # optional - sage.graphs True TESTS: @@ -1958,7 +1957,7 @@ def cell_poset(self, orientation="SE"): ....: and c[1] >= d[1]): ....: return False ....: return True - sage: all( check_NW(n) for n in range(8) ) + sage: all( check_NW(n) for n in range(8) ) # optional - sage.graphs True sage: def check_NE(n): @@ -1970,7 +1969,7 @@ def cell_poset(self, orientation="SE"): ....: and c[1] <= d[1]): ....: return False ....: return True - sage: all( check_NE(n) for n in range(8) ) + sage: all( check_NE(n) for n in range(8) ) # optional - sage.graphs True sage: def test_duality(n, ori1, ori2): @@ -1982,11 +1981,11 @@ def cell_poset(self, orientation="SE"): ....: if P.lt(c, d) != Q.lt(d, c): ....: return False ....: return True - sage: all( test_duality(n, "NW", "SE") for n in range(8) ) + sage: all( test_duality(n, "NW", "SE") for n in range(8) ) # optional - sage.graphs True - sage: all( test_duality(n, "NE", "SW") for n in range(8) ) + sage: all( test_duality(n, "NE", "SW") for n in range(8) ) # optional - sage.graphs True - sage: all( test_duality(n, "NE", "SE") for n in range(4) ) + sage: all( test_duality(n, "NE", "SE") for n in range(4) ) # optional - sage.graphs False """ from sage.combinat.posets.posets import Poset @@ -2853,7 +2852,7 @@ def young_subgroup(self): EXAMPLES:: - sage: Partition([4,2]).young_subgroup() + sage: Partition([4,2]).young_subgroup() # optional - sage.groups Permutation Group with generators [(), (5,6), (3,4), (2,3), (1,2)] """ gens=[] @@ -4623,12 +4622,12 @@ def from_kbounded_to_grassmannian(self, k): EXAMPLES:: sage: p = Partition([2,1,1]) - sage: p.from_kbounded_to_grassmannian(2) + sage: p.from_kbounded_to_grassmannian(2) # optional - sage.modules [-1 1 1] [-2 2 1] [-2 1 2] sage: p = Partition([]) - sage: p.from_kbounded_to_grassmannian(2) + sage: p.from_kbounded_to_grassmannian(2) # optional - sage.modules [1 0 0] [0 1 0] [0 0 1] @@ -5069,15 +5068,15 @@ def jacobi_trudi(self): EXAMPLES:: sage: part = Partition([3,2,1]) - sage: jt = part.jacobi_trudi(); jt + sage: jt = part.jacobi_trudi(); jt # optional - sage.modules [h[3] h[1] 0] [h[4] h[2] h[]] [h[5] h[3] h[1]] - sage: s = SymmetricFunctions(QQ).schur() - sage: h = SymmetricFunctions(QQ).homogeneous() - sage: h( s(part) ) + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.modules + sage: h = SymmetricFunctions(QQ).homogeneous() # optional - sage.modules + sage: h( s(part) ) # optional - sage.modules h[3, 2, 1] - h[3, 3] - h[4, 1, 1] + h[5, 1] - sage: jt.det() + sage: jt.det() # optional - sage.modules h[3, 2, 1] - h[3, 3] - h[4, 1, 1] + h[5, 1] """ return SkewPartition([ self, [] ]).jacobi_trudi() @@ -5108,11 +5107,11 @@ def character_polynomial(self): EXAMPLES:: - sage: Partition([1]).character_polynomial() + sage: Partition([1]).character_polynomial() # optional - sage.modules x - 1 - sage: Partition([1,1]).character_polynomial() + sage: Partition([1,1]).character_polynomial() # optional - sage.modules 1/2*x0^2 - 3/2*x0 - x1 + 1 - sage: Partition([2,1]).character_polynomial() + sage: Partition([2,1]).character_polynomial() # optional - sage.modules 1/3*x0^3 - 2*x0^2 + 8/3*x0 - x2 """ # Create the polynomial ring we will use @@ -5390,16 +5389,16 @@ def dual_equivalence_graph(self, directed=False, coloring=None): EXAMPLES:: sage: P = Partition([3,1,1]) - sage: G = P.dual_equivalence_graph() - sage: G.edges(sort=True) + sage: G = P.dual_equivalence_graph() # optional - sage.graphs + sage: G.edges(sort=True) # optional - sage.graphs [([[1, 2, 3], [4], [5]], [[1, 2, 4], [3], [5]], 3), ([[1, 2, 4], [3], [5]], [[1, 2, 5], [3], [4]], 4), ([[1, 2, 4], [3], [5]], [[1, 3, 4], [2], [5]], 2), ([[1, 2, 5], [3], [4]], [[1, 3, 5], [2], [4]], 2), ([[1, 3, 4], [2], [5]], [[1, 3, 5], [2], [4]], 4), ([[1, 3, 5], [2], [4]], [[1, 4, 5], [2], [3]], 3)] - sage: G = P.dual_equivalence_graph(directed=True) - sage: G.edges(sort=True) + sage: G = P.dual_equivalence_graph(directed=True) # optional - sage.graphs + sage: G.edges(sort=True) # optional - sage.graphs [([[1, 2, 4], [3], [5]], [[1, 2, 3], [4], [5]], 3), ([[1, 2, 5], [3], [4]], [[1, 2, 4], [3], [5]], 4), ([[1, 3, 4], [2], [5]], [[1, 2, 4], [3], [5]], 2), @@ -5409,19 +5408,20 @@ def dual_equivalence_graph(self, directed=False, coloring=None): TESTS:: - sage: G = Partition([1]).dual_equivalence_graph() - sage: G.vertices(sort=False) + sage: G = Partition([1]).dual_equivalence_graph() # optional - sage.graphs + sage: G.vertices(sort=False) # optional - sage.graphs [[[1]]] - sage: G = Partition([]).dual_equivalence_graph() - sage: G.vertices(sort=False) + sage: G = Partition([]).dual_equivalence_graph() # optional - sage.graphs + sage: G.vertices(sort=False) # optional - sage.graphs [[]] sage: P = Partition([3,1,1]) - sage: G = P.dual_equivalence_graph(coloring=lambda x: 'red') - sage: G2 = P.dual_equivalence_graph(coloring={2: 'black', 3: 'blue', 4: 'cyan', 5: 'grey'}) - sage: G is G2 + sage: G = P.dual_equivalence_graph(coloring=lambda x: 'red') # optional - sage.graphs + sage: G2 = P.dual_equivalence_graph(coloring={2: 'black', 3: 'blue', # optional - sage.graphs + ....: 4: 'cyan', 5: 'grey'}) + sage: G is G2 # optional - sage.graphs False - sage: G == G2 + sage: G == G2 # optional - sage.graphs True """ # We do some custom caching to not recreate the graph, but to make @@ -5490,11 +5490,10 @@ def specht_module(self, base_ring=None): EXAMPLES:: - sage: SM = Partition([2,2,1]).specht_module(QQ) - sage: SM + sage: SM = Partition([2,2,1]).specht_module(QQ); SM # optional - sage.modules Specht module of [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0)] over Rational Field - sage: s = SymmetricFunctions(QQ).s() - sage: s(SM.frobenius_image()) + sage: s = SymmetricFunctions(QQ).s() # optional - sage.modules + sage: s(SM.frobenius_image()) # optional - sage.modules s[2, 2, 1] """ from sage.combinat.specht_module import SpechtModule @@ -5520,7 +5519,7 @@ def specht_module_dimension(self, base_ring=None): sage: Partition([2,2,1]).specht_module_dimension() 5 - sage: Partition([2,2,1]).specht_module_dimension(GF(2)) + sage: Partition([2,2,1]).specht_module_dimension(GF(2)) # optional - sage.rings.finite_rings 5 """ from sage.categories.fields import Fields @@ -5640,16 +5639,20 @@ class Partitions(UniqueRepresentation, Parent): The number of partitions of `n` into odd parts equals the number of partitions into distinct parts. Let's test that for `n` from 10 to 20:: - sage: test = lambda n: Partitions(n, max_slope=-1).cardinality() == Partitions(n, parts_in=[1,3..n]).cardinality() - sage: all(test(n) for n in [10..20]) + sage: def test(n): + ....: return (Partitions(n, max_slope=-1).cardinality() + ....: == Partitions(n, parts_in=[1,3..n]).cardinality()) + sage: all(test(n) for n in [10..20]) # optional - sage.libs.gap True The number of partitions of `n` into distinct parts that differ by at least 2 equals the number of partitions into parts that equal 1 or 4 modulo 5; this is one of the Rogers-Ramanujan identities:: - sage: test = lambda n: Partitions(n, max_slope=-2).cardinality() == Partitions(n, parts_in=([1,6..n] + [4,9..n])).cardinality() - sage: all(test(n) for n in [10..20]) + sage: def test(n): + ....: return (Partitions(n, max_slope=-2).cardinality() + ....: == Partitions(n, parts_in=([1,6..n] + [4,9..n])).cardinality()) + sage: all(test(n) for n in [10..20]) # optional - sage.libs.gap True Here are some more examples illustrating ``min_part``, ``max_part``, @@ -7113,7 +7116,7 @@ class Partitions_parts_in(Partitions): TESTS:: - sage: TestSuite( sage.combinat.partition.Partitions_parts_in(6, parts=[2,1]) ).run() + sage: TestSuite( sage.combinat.partition.Partitions_parts_in(6, parts=[2,1]) ).run() # optional - sage.libs.gap """ @staticmethod @@ -7137,7 +7140,7 @@ def __init__(self, n, parts): TESTS:: - sage: TestSuite(Partitions(5, parts_in=[1,2,3])).run() + sage: TestSuite(Partitions(5, parts_in=[1,2,3])).run() # optional - sage.libs.gap """ Partitions.__init__(self) self.n = n @@ -7172,12 +7175,13 @@ def cardinality(self): EXAMPLES:: - sage: Partitions(15, parts_in=[2,3,7]).cardinality() + sage: Partitions(15, parts_in=[2,3,7]).cardinality() # optional - sage.libs.gap 5 If you can use all parts 1 through `n`, we'd better get `p(n)`:: - sage: Partitions(20, parts_in=[1..20]).cardinality() == Partitions(20).cardinality() + sage: (Partitions(20, parts_in=[1..20]).cardinality() # optional - sage.libs.gap + ....: == Partitions(20).cardinality()) True TESTS: @@ -7186,19 +7190,19 @@ def cardinality(self): algorithm that actually generates the partitions:: sage: ps = Partitions(15, parts_in=[1,2,3]) - sage: ps.cardinality() == len(ps.list()) + sage: ps.cardinality() == len(ps.list()) # optional - sage.libs.gap True sage: ps = Partitions(15, parts_in=[]) - sage: ps.cardinality() == len(ps.list()) + sage: ps.cardinality() == len(ps.list()) # optional - sage.libs.gap True sage: ps = Partitions(3000, parts_in=[50,100,500,1000]) - sage: ps.cardinality() == len(ps.list()) + sage: ps.cardinality() == len(ps.list()) # optional - sage.libs.gap True sage: ps = Partitions(10, parts_in=[3,6,9]) - sage: ps.cardinality() == len(ps.list()) + sage: ps.cardinality() == len(ps.list()) # optional - sage.libs.gap True sage: ps = Partitions(0, parts_in=[1,2]) - sage: ps.cardinality() == len(ps.list()) + sage: ps.cardinality() == len(ps.list()) # optional - sage.libs.gap True """ # GAP complains if you give it an empty list @@ -8361,16 +8365,16 @@ class OrderedPartitions(Partitions): sage: OrderedPartitions(3) Ordered partitions of 3 - sage: OrderedPartitions(3).list() + sage: OrderedPartitions(3).list() # optional - sage.libs.gap [[3], [2, 1], [1, 2], [1, 1, 1]] sage: OrderedPartitions(3,2) Ordered partitions of 3 of length 2 - sage: OrderedPartitions(3,2).list() + sage: OrderedPartitions(3,2).list() # optional - sage.libs.gap [[2, 1], [1, 2]] - sage: OrderedPartitions(10,k=2).list() + sage: OrderedPartitions(10, k=2).list() # optional - sage.libs.gap [[9, 1], [8, 2], [7, 3], [6, 4], [5, 5], [4, 6], [3, 7], [2, 8], [1, 9]] - sage: OrderedPartitions(4).list() + sage: OrderedPartitions(4).list() # optional - sage.libs.gap [[4], [3, 1], [2, 2], [2, 1, 1], [1, 3], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]] """ @@ -8401,7 +8405,7 @@ def __init__(self, n, k): TESTS:: - sage: TestSuite( OrderedPartitions(5,3) ).run() + sage: TestSuite( OrderedPartitions(5,3) ).run() # optional - sage.libs.gap """ Partitions.__init__(self) self.n = n @@ -8446,9 +8450,9 @@ def list(self): EXAMPLES:: - sage: OrderedPartitions(3).list() + sage: OrderedPartitions(3).list() # optional - sage.libs.gap [[3], [2, 1], [1, 2], [1, 1, 1]] - sage: OrderedPartitions(3,2).list() + sage: OrderedPartitions(3,2).list() # optional - sage.libs.gap [[2, 1], [1, 2]] """ from sage.libs.gap.libgap import libgap @@ -8468,13 +8472,13 @@ def cardinality(self): EXAMPLES:: - sage: OrderedPartitions(3).cardinality() + sage: OrderedPartitions(3).cardinality() # optional - sage.libs.gap 4 - sage: OrderedPartitions(3,2).cardinality() + sage: OrderedPartitions(3,2).cardinality() # optional - sage.libs.gap 2 - sage: OrderedPartitions(10,2).cardinality() + sage: OrderedPartitions(10,2).cardinality() # optional - sage.libs.gap 9 - sage: OrderedPartitions(15).cardinality() + sage: OrderedPartitions(15).cardinality() # optional - sage.libs.gap 16384 """ from sage.libs.gap.libgap import libgap @@ -8548,12 +8552,12 @@ def cardinality(self): EXAMPLES:: - sage: PartitionsGreatestLE(9, 5).cardinality() + sage: PartitionsGreatestLE(9, 5).cardinality() # optional - sage.libs.gap 23 TESTS:: - sage: all(PartitionsGreatestLE(n, a).cardinality() == + sage: all(PartitionsGreatestLE(n, a).cardinality() == # optional - sage.libs.gap ....: len(PartitionsGreatestLE(n, a).list()) ....: for n in range(20) for a in range(6)) True @@ -9064,19 +9068,19 @@ def number_of_partitions_length(n, k, algorithm='hybrid'): EXAMPLES:: sage: from sage.combinat.partition import number_of_partitions_length - sage: number_of_partitions_length(5, 2) + sage: number_of_partitions_length(5, 2) # optional - sage.libs.gap 2 - sage: number_of_partitions_length(10, 2) + sage: number_of_partitions_length(10, 2) # optional - sage.libs.gap 5 - sage: number_of_partitions_length(10, 4) + sage: number_of_partitions_length(10, 4) # optional - sage.libs.gap 9 - sage: number_of_partitions_length(10, 0) + sage: number_of_partitions_length(10, 0) # optional - sage.libs.gap 0 - sage: number_of_partitions_length(10, 1) + sage: number_of_partitions_length(10, 1) # optional - sage.libs.gap 1 - sage: number_of_partitions_length(0, 0) + sage: number_of_partitions_length(0, 0) # optional - sage.libs.gap 1 - sage: number_of_partitions_length(0, 1) + sage: number_of_partitions_length(0, 1) # optional - sage.libs.gap 0 """ if algorithm == 'hybrid': diff --git a/src/sage/combinat/perfect_matching.py b/src/sage/combinat/perfect_matching.py index 9d57f0b59ac..c663a689f31 100644 --- a/src/sage/combinat/perfect_matching.py +++ b/src/sage/combinat/perfect_matching.py @@ -224,7 +224,7 @@ def _latex_(self): EXAMPLES:: sage: P = PerfectMatching([(1,3),(2,5),(4,6)]) - sage: latex(P) # random + sage: latex(P) # random # optional - sage.graphs \begin{tikzpicture} ... \end{tikzpicture} @@ -234,7 +234,7 @@ def _latex_(self): Above we added ``random`` since warnings might be displayed once. The second time, there should be no warnings:: - sage: print(P._latex_()) + sage: print(P._latex_()) # optional - sage.graphs \begin{tikzpicture} ... \end{tikzpicture} @@ -377,10 +377,12 @@ def loops(self, other=None): sage: loops = sorted(loops, key=len) sage: sorted(loops[0]) ['d', 'f'] - sage: G = SymmetricGroup(4) - sage: g = G([(1,2,3,4)]) - sage: ((loops[1] in [permutation_action(g**i, ['a', 'e', 'c', 'b']) for i in range(4)]) - ....: or (loops[1] in [permutation_action(g**i, ['a', 'b', 'c', 'e']) for i in range(4)])) + sage: G = SymmetricGroup(4) # optional - sage.groups + sage: g = G([(1,2,3,4)]) # optional - sage.groups + sage: ((loops[1] in [permutation_action(g**i, ['a', 'e', 'c', 'b']) # optional - sage.groups + ....: for i in range(4)]) + ....: or (loops[1] in [permutation_action(g**i, ['a', 'b', 'c', 'e']) + ....: for i in range(4)])) True """ return list(self.loops_iterator(other)) @@ -475,11 +477,13 @@ def to_graph(self): EXAMPLES:: - sage: PerfectMatching([[1,3], [4,2]]).to_graph().edges(sort=True, labels=False) + sage: PerfectMatching([[1,3], [4,2]]).to_graph().edges(sort=True, # optional - sage.graphs + ....: labels=False) [(1, 3), (2, 4)] - sage: PerfectMatching([[1,4], [3,2]]).to_graph().edges(sort=True, labels=False) + sage: PerfectMatching([[1,4], [3,2]]).to_graph().edges(sort=True, # optional - sage.graphs + ....: labels=False) [(1, 4), (2, 3)] - sage: PerfectMatching([]).to_graph().edges(sort=True, labels=False) + sage: PerfectMatching([]).to_graph().edges(sort=True, labels=False) # optional - sage.graphs [] """ from sage.graphs.graph import Graph diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index b9c0be15ee6..babbc4d9def 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -4227,7 +4227,7 @@ def right_permutohedron_interval_iterator(self, other): EXAMPLES:: sage: p = Permutation([2, 1, 4, 5, 3]); q = Permutation([2, 5, 4, 1, 3]) - sage: p.right_permutohedron_interval(q) # indirect doctest # optional - sage.graphs + sage: p.right_permutohedron_interval(q) # indirect doctest # optional - sage.graphs sage.modules sage.rings.finite_rings [[2, 4, 5, 1, 3], [2, 4, 1, 5, 3], [2, 1, 4, 5, 3], [2, 1, 5, 4, 3], [2, 5, 1, 4, 3], [2, 5, 4, 1, 3]] """ @@ -4254,27 +4254,27 @@ def right_permutohedron_interval(self, other): EXAMPLES:: sage: p = Permutation([2, 1, 4, 5, 3]); q = Permutation([2, 5, 4, 1, 3]) - sage: p.right_permutohedron_interval(q) # optional - sage.graphs + sage: p.right_permutohedron_interval(q) # optional - sage.graphs sage.modules sage.rings.finite_rings [[2, 4, 5, 1, 3], [2, 4, 1, 5, 3], [2, 1, 4, 5, 3], [2, 1, 5, 4, 3], [2, 5, 1, 4, 3], [2, 5, 4, 1, 3]] TESTS:: - sage: Permutation([]).right_permutohedron_interval(Permutation([])) # optional - sage.graphs + sage: Permutation([]).right_permutohedron_interval(Permutation([])) # optional - sage.graphs sage.modules sage.rings.finite_rings [[]] - sage: Permutation([3, 1, 2]).right_permutohedron_interval(Permutation([3, 1, 2])) # optional - sage.graphs + sage: Permutation([3, 1, 2]).right_permutohedron_interval(Permutation([3, 1, 2])) # optional - sage.graphs sage.modules sage.rings.finite_rings [[3, 1, 2]] - sage: Permutation([1, 3, 2, 4]).right_permutohedron_interval(Permutation([3, 4, 2, 1])) # optional - sage.graphs + sage: Permutation([1, 3, 2, 4]).right_permutohedron_interval(Permutation([3, 4, 2, 1])) # optional - sage.graphs sage.modules sage.rings.finite_rings [[3, 1, 4, 2], [3, 4, 1, 2], [3, 4, 2, 1], [1, 3, 4, 2], [1, 3, 2, 4], [3, 2, 4, 1], [3, 2, 1, 4], [3, 1, 2, 4]] - sage: Permutation([2, 1, 4, 5, 3]).right_permutohedron_interval(Permutation([2, 5, 4, 1, 3])) # optional - sage.graphs + sage: Permutation([2, 1, 4, 5, 3]).right_permutohedron_interval(Permutation([2, 5, 4, 1, 3])) # optional - sage.graphs sage.modules sage.rings.finite_rings [[2, 4, 5, 1, 3], [2, 4, 1, 5, 3], [2, 1, 4, 5, 3], [2, 1, 5, 4, 3], [2, 5, 1, 4, 3], [2, 5, 4, 1, 3]] - sage: Permutation([2, 5, 4, 1, 3]).right_permutohedron_interval(Permutation([2, 1, 4, 5, 3])) # optional - sage.graphs + sage: Permutation([2, 5, 4, 1, 3]).right_permutohedron_interval(Permutation([2, 1, 4, 5, 3])) # optional - sage.graphs sage.modules sage.rings.finite_rings Traceback (most recent call last): ... ValueError: [2, 5, 4, 1, 3] must be lower or equal than [2, 1, 4, 5, 3] for the right permutohedron order - sage: Permutation([2, 4, 1, 3]).right_permutohedron_interval(Permutation([2, 1, 4, 5, 3])) # optional - sage.graphs + sage: Permutation([2, 4, 1, 3]).right_permutohedron_interval(Permutation([2, 1, 4, 5, 3])) # optional - sage.graphs sage.modules sage.rings.finite_rings Traceback (most recent call last): ... ValueError: len([2, 4, 1, 3]) and len([2, 1, 4, 5, 3]) must be equal @@ -4802,17 +4802,17 @@ def increasing_tree(self, compare=min): EXAMPLES:: - sage: Permutation([1,4,3,2]).increasing_tree() # optional - sage.combinat + sage: Permutation([1,4,3,2]).increasing_tree() # optional - sage.graphs 1[., 2[3[4[., .], .], .]] - sage: Permutation([4,1,3,2]).increasing_tree() # optional - sage.combinat + sage: Permutation([4,1,3,2]).increasing_tree() # optional - sage.graphs 1[4[., .], 2[3[., .], .]] By passing the option ``compare=max`` one can have the decreasing tree instead:: - sage: Permutation([2,3,4,1]).increasing_tree(max) # optional - sage.combinat + sage: Permutation([2,3,4,1]).increasing_tree(max) # optional - sage.graphs 4[3[2[., .], .], 1[., .]] - sage: Permutation([2,3,1,4]).increasing_tree(max) # optional - sage.combinat + sage: Permutation([2,3,1,4]).increasing_tree(max) # optional - sage.graphs 4[3[2[., .], 1[., .]], .] """ from sage.combinat.binary_tree import LabelledBinaryTree as LBT @@ -4833,17 +4833,17 @@ def increasing_tree_shape(self, compare=min): EXAMPLES:: - sage: Permutation([1,4,3,2]).increasing_tree_shape() # optional - sage.combinat + sage: Permutation([1,4,3,2]).increasing_tree_shape() # optional - sage.graphs [., [[[., .], .], .]] - sage: Permutation([4,1,3,2]).increasing_tree_shape() # optional - sage.combinat + sage: Permutation([4,1,3,2]).increasing_tree_shape() # optional - sage.graphs [[., .], [[., .], .]] By passing the option ``compare=max`` one can have the decreasing tree instead:: - sage: Permutation([2,3,4,1]).increasing_tree_shape(max) # optional - sage.combinat + sage: Permutation([2,3,4,1]).increasing_tree_shape(max) # optional - sage.graphs [[[., .], .], [., .]] - sage: Permutation([2,3,1,4]).increasing_tree_shape(max) # optional - sage.combinat + sage: Permutation([2,3,1,4]).increasing_tree_shape(max) # optional - sage.graphs [[[., .], [., .]], .] """ return self.increasing_tree(compare).shape() @@ -4869,22 +4869,22 @@ def binary_search_tree(self, left_to_right=True): EXAMPLES:: - sage: Permutation([1,4,3,2]).binary_search_tree() # optional - sage.combinat + sage: Permutation([1,4,3,2]).binary_search_tree() # optional - sage.graphs 1[., 4[3[2[., .], .], .]] - sage: Permutation([4,1,3,2]).binary_search_tree() # optional - sage.combinat + sage: Permutation([4,1,3,2]).binary_search_tree() # optional - sage.graphs 4[1[., 3[2[., .], .]], .] By passing the option ``left_to_right=False`` one can have the insertion going from right to left:: - sage: Permutation([1,4,3,2]).binary_search_tree(False) # optional - sage.combinat + sage: Permutation([1,4,3,2]).binary_search_tree(False) # optional - sage.graphs 2[1[., .], 3[., 4[., .]]] - sage: Permutation([4,1,3,2]).binary_search_tree(False) # optional - sage.combinat + sage: Permutation([4,1,3,2]).binary_search_tree(False) # optional - sage.graphs 2[1[., .], 3[., 4[., .]]] TESTS:: - sage: Permutation([]).binary_search_tree() # optional - sage.combinat + sage: Permutation([]).binary_search_tree() # optional - sage.graphs . """ from sage.combinat.binary_tree import LabelledBinaryTree as LBT @@ -4905,17 +4905,17 @@ def binary_search_tree_shape(self, left_to_right=True): EXAMPLES:: - sage: Permutation([1,4,3,2]).binary_search_tree_shape() # optional - sage.combinat + sage: Permutation([1,4,3,2]).binary_search_tree_shape() # optional - sage.graphs [., [[[., .], .], .]] - sage: Permutation([4,1,3,2]).binary_search_tree_shape() # optional - sage.combinat + sage: Permutation([4,1,3,2]).binary_search_tree_shape() # optional - sage.graphs [[., [[., .], .]], .] By passing the option ``left_to_right=False`` one can have the insertion going from right to left:: - sage: Permutation([1,4,3,2]).binary_search_tree_shape(False) # optional - sage.combinat + sage: Permutation([1,4,3,2]).binary_search_tree_shape(False) # optional - sage.graphs [[., .], [., [., .]]] - sage: Permutation([4,1,3,2]).binary_search_tree_shape(False) # optional - sage.combinat + sage: Permutation([4,1,3,2]).binary_search_tree_shape(False) # optional - sage.graphs [[., .], [., [., .]]] """ from sage.combinat.binary_tree import binary_search_tree_shape @@ -4974,20 +4974,20 @@ def sylvester_class(self, left_to_right=False): The sylvester class of a permutation `p` contains `p`:: - sage: all(p in p.sylvester_class() for p in Permutations(4)) # optional - sage.combinat + sage: all(p in p.sylvester_class() for p in Permutations(4)) # optional - sage.combinat sage.graphs True Small cases:: - sage: list(Permutation([]).sylvester_class()) # optional - sage.combinat + sage: list(Permutation([]).sylvester_class()) # optional - sage.combinat sage.graphs [[]] - sage: list(Permutation([1]).sylvester_class()) # optional - sage.combinat + sage: list(Permutation([1]).sylvester_class()) # optional - sage.combinat sage.graphs [[1]] The sylvester classes in `S_3`:: - sage: [sorted(p.sylvester_class()) for p in Permutations(3)] # optional - sage.combinat + sage: [sorted(p.sylvester_class()) for p in Permutations(3)] # optional - sage.combinat sage.graphs [[[1, 2, 3]], [[1, 3, 2], [3, 1, 2]], [[2, 1, 3]], @@ -4997,7 +4997,7 @@ def sylvester_class(self, left_to_right=False): The left sylvester classes in `S_3`:: - sage: [sorted(p.sylvester_class(left_to_right=True)) # optional - sage.combinat + sage: [sorted(p.sylvester_class(left_to_right=True)) # optional - sage.combinat sage.graphs ....: for p in Permutations(3)] [[[1, 2, 3]], [[1, 3, 2]], @@ -5009,7 +5009,7 @@ def sylvester_class(self, left_to_right=False): A left sylvester class in `S_5`:: sage: p = Permutation([4, 2, 1, 5, 3]) - sage: sorted(p.sylvester_class(left_to_right=True)) # optional - sage.combinat + sage: sorted(p.sylvester_class(left_to_right=True)) # optional - sage.combinat sage.graphs [[4, 2, 1, 3, 5], [4, 2, 1, 5, 3], [4, 2, 3, 1, 5], @@ -5342,21 +5342,21 @@ def shifted_shuffle(self, other): sage: Permutation([]).shifted_shuffle(Permutation([])) # optional - sage.graphs [[]] - sage: Permutation([1, 2, 3]).shifted_shuffle(Permutation([1])) # optional - sage.graphs + sage: Permutation([1, 2, 3]).shifted_shuffle(Permutation([1])) # optional - sage.graphs sage.modules sage.rings.finite_rings [[4, 1, 2, 3], [1, 2, 3, 4], [1, 2, 4, 3], [1, 4, 2, 3]] - sage: Permutation([1, 2]).shifted_shuffle(Permutation([2, 1])) # optional - sage.graphs + sage: Permutation([1, 2]).shifted_shuffle(Permutation([2, 1])) # optional - sage.graphs sage.modules sage.rings.finite_rings [[4, 1, 3, 2], [4, 3, 1, 2], [1, 4, 3, 2], [1, 4, 2, 3], [1, 2, 4, 3], [4, 1, 2, 3]] - sage: Permutation([1]).shifted_shuffle([1]) # optional - sage.graphs + sage: Permutation([1]).shifted_shuffle([1]) # optional - sage.graphs sage.modules sage.rings.finite_rings [[2, 1], [1, 2]] sage: p = Permutation([3, 1, 5, 4, 2]) - sage: len(p.shifted_shuffle(Permutation([2, 1, 4, 3]))) # optional - sage.graphs + sage: len(p.shifted_shuffle(Permutation([2, 1, 4, 3]))) # optional - sage.graphs sage.modules sage.rings.finite_rings 126 The shifted shuffle product is associative. We can test this on an admittedly toy example:: - sage: all( all( all( sorted(flatten([abs.shifted_shuffle(c) # optional - sage.graphs + sage: all( all( all( sorted(flatten([abs.shifted_shuffle(c) # optional - sage.graphs sage.modules sage.rings.finite_rings ....: for abs in a.shifted_shuffle(b)])) ....: == sorted(flatten([a.shifted_shuffle(bcs) ....: for bcs in b.shifted_shuffle(c)])) @@ -5369,7 +5369,7 @@ def shifted_shuffle(self, other): permutations as the ``shifted_shuffle`` method on words (but is faster):: - sage: all( all( sorted(p1.shifted_shuffle(p2)) # optional - sage.graphs + sage: all( all( sorted(p1.shifted_shuffle(p2)) # optional - sage.graphs sage.modules sage.rings.finite_rings ....: == sorted([Permutation(p) for p in ....: Word(p1).shifted_shuffle(Word(p2))]) ....: for p2 in Permutations(3) ) @@ -5499,7 +5499,7 @@ class Permutations(UniqueRepresentation, Parent): sage: p = Permutations(descents=([1], 4)); p Standard permutations of 4 with descents [1] - sage: p.list() # optional - sage.graphs + sage: p.list() # optional - sage.graphs sage.modules sage.rings.finite_rings [[2, 4, 1, 3], [3, 4, 1, 2], [1, 4, 2, 3], [1, 3, 2, 4], [2, 3, 1, 4]] :: @@ -5522,7 +5522,7 @@ class Permutations(UniqueRepresentation, Parent): sage: p = Permutations(recoils_finer=[2,1]); p Standard permutations whose recoils composition is finer than [2, 1] - sage: p.list() # optional - sage.graphs + sage: p.list() # optional - sage.graphs sage.modules sage.rings.finite_rings [[3, 1, 2], [1, 2, 3], [1, 3, 2]] :: @@ -7201,7 +7201,7 @@ def conjugacy_classes_iterator(self): EXAMPLES:: sage: G = Permutations(4) - sage: list(G.conjugacy_classes_iterator()) == G.conjugacy_classes() # optional - sage.combinat + sage: list(G.conjugacy_classes_iterator()) == G.conjugacy_classes() # optional - sage.combinat sage.graphs True """ from sage.combinat.partition import Partitions_n @@ -7216,7 +7216,7 @@ def conjugacy_classes(self): EXAMPLES:: sage: G = Permutations(4) - sage: G.conjugacy_classes() # optional - sage.combinat + sage: G.conjugacy_classes() # optional - sage.combinat sage.graphs [Conjugacy class of cycle type [1, 1, 1, 1] in Standard permutations of 4, Conjugacy class of cycle type [2, 1, 1] in Standard permutations of 4, Conjugacy class of cycle type [2, 2] in Standard permutations of 4, @@ -7237,9 +7237,9 @@ def conjugacy_class(self, g): sage: G = Permutations(5) sage: g = G([2,3,4,1,5]) - sage: G.conjugacy_class(g) # optional - sage.combinat + sage: G.conjugacy_class(g) # optional - sage.combinat sage.graphs Conjugacy class of cycle type [4, 1] in Standard permutations of 5 - sage: G.conjugacy_class(Partition([2, 1, 1, 1])) # optional - sage.combinat + sage: G.conjugacy_class(Partition([2, 1, 1, 1])) # optional - sage.combinat sage.graphs Conjugacy class of cycle type [2, 1, 1, 1] in Standard permutations of 5 """ from sage.groups.perm_gps.symgp_conjugacy_class import PermutationsConjugacyClass @@ -8061,7 +8061,7 @@ def cardinality(self): sage: def P(D, n): ....: return Permutations(descents=(D, n + 1)) - sage: all(P(D, n).cardinality() == len(P(D, n).list()) # optional - sage.graphs + sage: all(P(D, n).cardinality() == len(P(D, n).list()) # optional - sage.graphs sage.modules sage.rings.finite_rings ....: for n in range(5) for D in subsets(range(n))) True @@ -8126,7 +8126,7 @@ def __iter__(self): EXAMPLES:: - sage: Permutations(descents=([2,0],5)).list() # optional - sage.graphs + sage: Permutations(descents=([2,0],5)).list() # optional - sage.graphs sage.modules sage.rings.finite_rings [[5, 2, 4, 1, 3], [5, 3, 4, 1, 2], [4, 3, 5, 1, 2], @@ -8155,7 +8155,7 @@ def descents_composition_list(dc): EXAMPLES:: sage: import sage.combinat.permutation as permutation - sage: permutation.descents_composition_list([1,2,2]) # optional - sage.graphs + sage: permutation.descents_composition_list([1,2,2]) # optional - sage.graphs sage.modules sage.rings.finite_rings [[5, 2, 4, 1, 3], [5, 3, 4, 1, 2], [4, 3, 5, 1, 2], @@ -8269,7 +8269,7 @@ def __iter__(self): EXAMPLES:: - sage: Permutations(recoils_finer=[2,2]).list() # optional - sage.graphs + sage: Permutations(recoils_finer=[2,2]).list() # optional - sage.graphs sage.modules sage.rings.finite_rings [[3, 1, 4, 2], [3, 4, 1, 2], [1, 3, 4, 2], @@ -8337,7 +8337,7 @@ def __iter__(self): EXAMPLES:: - sage: Permutations(recoils_fatter=[2,2]).list() # optional - sage.graphs + sage: Permutations(recoils_fatter=[2,2]).list() # optional - sage.graphs sage.modules sage.rings.finite_rings [[4, 3, 2, 1], [3, 2, 1, 4], [3, 2, 4, 1], diff --git a/src/sage/combinat/posets/d_complete.py b/src/sage/combinat/posets/d_complete.py index 210317f2b44..2b603aeac2b 100644 --- a/src/sage/combinat/posets/d_complete.py +++ b/src/sage/combinat/posets/d_complete.py @@ -59,8 +59,8 @@ def _hooks(self): sage: P._hooks {0: 1, 1: 2, 2: 2, 3: 3} sage: from sage.combinat.posets.poset_examples import Posets - sage: P = DCompletePoset(Posets.YoungDiagramPoset(Partition([3,2,1]))._hasse_diagram.reverse()) - sage: P._hooks + sage: P = DCompletePoset(Posets.YoungDiagramPoset(Partition([3,2,1]))._hasse_diagram.reverse()) # optional - sage.combinat + sage: P._hooks # optional - sage.combinat {0: 5, 1: 3, 2: 1, 3: 3, 4: 1, 5: 1} """ hooks = {} @@ -150,8 +150,9 @@ def get_hooks(self): sage: P.get_hooks() {0: 1, 1: 2, 2: 2, 3: 3} sage: from sage.combinat.posets.poset_examples import Posets - sage: P = DCompletePoset(Posets.YoungDiagramPoset(Partition([3,2,1]))._hasse_diagram.reverse()) - sage: P.get_hooks() + sage: YDP321 = Posets.YoungDiagramPoset(Partition([3,2,1])) # optional - sage.combinat + sage: P = DCompletePoset(YDP321)._hasse_diagram.reverse()) # optional - sage.combinat + sage: P.get_hooks() # optional - sage.combinat {0: 5, 1: 3, 2: 1, 3: 3, 4: 1, 5: 1} """ return dict(self._hooks) @@ -166,8 +167,9 @@ def hook_product(self): sage: P = DCompletePoset(DiGraph({0: [1, 2], 1: [3], 2: [3], 3: []})) sage: P.hook_product() 12 - sage: P = DCompletePoset(posets.YoungDiagramPoset(Partition([3,2,1]), dual=True)) - sage: P.hook_product() + sage: P = DCompletePoset(posets.YoungDiagramPoset(Partition([3,2,1]), # optional - sage.combinat + ....: dual=True)) + sage: P.hook_product() # optional - sage.combinat 45 """ if not self._hasse_diagram: diff --git a/src/sage/combinat/posets/elements.py b/src/sage/combinat/posets/elements.py index 00b0707d8e1..4788246cd1d 100644 --- a/src/sage/combinat/posets/elements.py +++ b/src/sage/combinat/posets/elements.py @@ -78,13 +78,13 @@ def _latex_(self): EXAMPLES:: - sage: m = matrix(2,[1,2,3,4]) - sage: m.set_immutable() - sage: P = Poset(([m],[]), facade = False) - sage: [e] = P - sage: type(e) + sage: m = matrix(2, [1,2,3,4]) # optional - sage.modules + sage: m.set_immutable() # optional - sage.modules + sage: P = Poset(([m],[]), facade=False) # optional - sage.modules + sage: [e] = P # optional - sage.modules + sage: type(e) # optional - sage.modules <class 'sage.combinat.posets.posets.FinitePoset_with_category.element_class'> - sage: latex(e) #indirect doctest + sage: latex(e) #indirect doctest # optional - sage.modules \left(\begin{array}{rr} 1 & 2 \\ 3 & 4 @@ -243,14 +243,14 @@ def __mul__(self, other): EXAMPLES:: - sage: D = posets.DiamondPoset(5,facade=False) - sage: D(1) * D(2) + sage: D = posets.DiamondPoset(5, facade=False) + sage: D(1) * D(2) # optional - sage.modules 0 - sage: D(1) * D(1) + sage: D(1) * D(1) # optional - sage.modules 1 - sage: D(1) * D(0) + sage: D(1) * D(0) # optional - sage.modules 0 - sage: D(1) * D(4) + sage: D(1) * D(4) # optional - sage.modules 1 """ return self.parent().meet(self, other) @@ -264,13 +264,13 @@ def __add__(self, other): EXAMPLES:: sage: D = posets.DiamondPoset(5,facade=False) - sage: D(1) + D(2) + sage: D(1) + D(2) # optional - sage.modules 4 - sage: D(1) + D(1) + sage: D(1) + D(1) # optional - sage.modules 1 - sage: D(1) + D(4) + sage: D(1) + D(4) # optional - sage.modules 4 - sage: D(1) + D(0) + sage: D(1) + D(0) # optional - sage.modules 1 """ return self.parent().join(self, other) diff --git a/src/sage/combinat/posets/hasse_diagram.py b/src/sage/combinat/posets/hasse_diagram.py index 7e1f1c6e4c6..84364c149d7 100644 --- a/src/sage/combinat/posets/hasse_diagram.py +++ b/src/sage/combinat/posets/hasse_diagram.py @@ -123,7 +123,7 @@ def linear_extensions(self): sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0:[1,2],1:[3],2:[3],3:[]}) - sage: list(H.linear_extensions()) + sage: list(H.linear_extensions()) # optional - sage.modules [[0, 1, 2, 3], [0, 2, 1, 3]] """ from sage.combinat.combinat_cython import linear_extension_iterator @@ -559,18 +559,18 @@ def dual(self): EXAMPLES:: - sage: P = posets.IntegerPartitions(4) - sage: H = P._hasse_diagram; H + sage: P = posets.IntegerPartitions(4) # optional - sage.combinat + sage: H = P._hasse_diagram; H # optional - sage.combinat Hasse diagram of a poset containing 5 elements - sage: H.dual() + sage: H.dual() # optional - sage.combinat Hasse diagram of a poset containing 5 elements TESTS:: - sage: H = posets.IntegerPartitions(4)._hasse_diagram - sage: H.is_isomorphic( H.dual().dual() ) + sage: H = posets.IntegerPartitions(4)._hasse_diagram # optional - sage.combinat + sage: H.is_isomorphic( H.dual().dual() ) # optional - sage.combinat True - sage: H.is_isomorphic( H.dual() ) + sage: H.is_isomorphic( H.dual() ) # optional - sage.combinat False """ H = self.reverse() @@ -588,11 +588,11 @@ def _precompute_intervals(self): EXAMPLES:: sage: B4 = posets.BooleanLattice(4) - sage: B4.is_isoform() # Slow + sage: B4.is_isoform() # Slow # optional - sage.combinat True sage: B4._hasse_diagram._precompute_intervals() sage: B4 = posets.BooleanLattice(4) - sage: B4.is_isoform() # Faster now + sage: B4.is_isoform() # Faster now # optional - sage.combinat True """ n = self.order() @@ -1057,7 +1057,7 @@ def moebius_function_matrix(self, algorithm='cython'): sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0:[1,3,2],1:[4],2:[4,5,6],3:[6],4:[7],5:[7],6:[7],7:[]}) - sage: H.moebius_function_matrix() + sage: H.moebius_function_matrix() # optional - sage.libs.flint sage.modules [ 1 -1 -1 -1 1 0 1 0] [ 0 1 0 0 -1 0 0 0] [ 0 0 1 0 -1 -1 -1 2] @@ -1069,28 +1069,28 @@ def moebius_function_matrix(self, algorithm='cython'): TESTS:: - sage: H.moebius_function_matrix().is_immutable() + sage: H.moebius_function_matrix().is_immutable() # optional - sage.libs.flint sage.modules True - sage: hasattr(H,'_moebius_function_matrix') + sage: hasattr(H,'_moebius_function_matrix') # optional - sage.libs.flint sage.modules True - sage: H.moebius_function == H._moebius_function_from_matrix + sage: H.moebius_function == H._moebius_function_from_matrix # optional - sage.libs.flint sage.modules True sage: H = posets.TamariLattice(3)._hasse_diagram - sage: M = H.moebius_function_matrix('matrix'); M + sage: M = H.moebius_function_matrix('matrix'); M # optional - sage.modules [ 1 -1 -1 0 1] [ 0 1 0 0 -1] [ 0 0 1 -1 0] [ 0 0 0 1 -1] [ 0 0 0 0 1] - sage: _ = H.__dict__.pop('_moebius_function_matrix') - sage: H.moebius_function_matrix('cython') == M + sage: _ = H.__dict__.pop('_moebius_function_matrix') # optional - sage.modules + sage: H.moebius_function_matrix('cython') == M # optional - sage.libs.flint sage.modules True - sage: _ = H.__dict__.pop('_moebius_function_matrix') - sage: H.moebius_function_matrix('recursive') == M + sage: _ = H.__dict__.pop('_moebius_function_matrix') # optional - sage.libs.flint sage.modules + sage: H.moebius_function_matrix('recursive') == M # optional - sage.modules True - sage: _ = H.__dict__.pop('_moebius_function_matrix') + sage: _ = H.__dict__.pop('_moebius_function_matrix') # optional - sage.modules sage: H.moebius_function_matrix('banana') Traceback (most recent call last): ... @@ -1161,25 +1161,25 @@ def coxeter_transformation(self, algorithm='cython'): EXAMPLES:: - sage: P = posets.PentagonPoset()._hasse_diagram - sage: M = P.coxeter_transformation(); M + sage: P = posets.PentagonPoset()._hasse_diagram # optional - sage.modules + sage: M = P.coxeter_transformation(); M # optional - sage.libs.flint sage.modules [ 0 0 0 0 -1] [ 0 0 0 1 -1] [ 0 1 0 0 -1] [-1 1 1 0 -1] [-1 1 0 1 -1] - sage: P.__dict__['coxeter_transformation'].clear_cache() - sage: P.coxeter_transformation(algorithm="matrix") == M + sage: P.__dict__['coxeter_transformation'].clear_cache() # optional - sage.libs.flint sage.modules + sage: P.coxeter_transformation(algorithm="matrix") == M # optional - sage.modules True TESTS:: - sage: P = posets.PentagonPoset()._hasse_diagram - sage: M = P.coxeter_transformation() - sage: M**8 == 1 + sage: P = posets.PentagonPoset()._hasse_diagram # optional - sage.modules + sage: M = P.coxeter_transformation() # optional - sage.libs.flint sage.modules + sage: M**8 == 1 # optional - sage.libs.flint sage.modules True - sage: P.__dict__['coxeter_transformation'].clear_cache() - sage: P.coxeter_transformation(algorithm="banana") + sage: P.__dict__['coxeter_transformation'].clear_cache() # optional - sage.libs.flint sage.modules + sage: P.coxeter_transformation(algorithm="banana") # optional - sage.libs.flint sage.modules Traceback (most recent call last): ... ValueError: unknown algorithm @@ -1311,7 +1311,7 @@ def _leq_matrix_boolean(self): sage: P = Poset([[1,3,2],[4],[4,5,6],[6],[7],[7],[7],[]]) sage: H = P._hasse_diagram - sage: M = H._leq_matrix_boolean; M + sage: M = H._leq_matrix_boolean; M # optional - sage.modules sage.rings.finite_rings [1 1 1 1 1 1 1 1] [0 1 0 1 0 0 0 1] [0 0 1 1 1 0 1 1] @@ -1320,7 +1320,7 @@ def _leq_matrix_boolean(self): [0 0 0 0 0 1 1 1] [0 0 0 0 0 0 1 1] [0 0 0 0 0 0 0 1] - sage: M.base_ring() + sage: M.base_ring() # optional - sage.modules sage.rings.finite_rings Finite Field of size 2 """ n = self.order() @@ -1344,7 +1344,7 @@ def _leq_matrix(self): sage: P = Poset([[1,3,2],[4],[4,5,6],[6],[7],[7],[7],[]]) sage: H = P._hasse_diagram - sage: M = H._leq_matrix; M + sage: M = H._leq_matrix; M # optional - sage.modules [1 1 1 1 1 1 1 1] [0 1 0 1 0 0 0 1] [0 0 1 1 1 0 1 1] @@ -1353,7 +1353,7 @@ def _leq_matrix(self): [0 0 0 0 0 1 1 1] [0 0 0 0 0 0 1 1] [0 0 0 0 0 0 0 1] - sage: M.base_ring() + sage: M.base_ring() # optional - sage.modules Integer Ring """ n = self.order() @@ -1380,7 +1380,7 @@ def lequal_matrix(self, boolean=False): sage: P = Poset([[1,3,2],[4],[4,5,6],[6],[7],[7],[7],[]]) sage: H = P._hasse_diagram - sage: M = H.lequal_matrix(); M + sage: M = H.lequal_matrix(); M # optional - sage.modules [1 1 1 1 1 1 1 1] [0 1 0 1 0 0 0 1] [0 0 1 1 1 0 1 1] @@ -1389,18 +1389,18 @@ def lequal_matrix(self, boolean=False): [0 0 0 0 0 1 1 1] [0 0 0 0 0 0 1 1] [0 0 0 0 0 0 0 1] - sage: M.base_ring() + sage: M.base_ring() # optional - sage.modules Integer Ring sage: P = posets.DiamondPoset(6) sage: H = P._hasse_diagram - sage: M = H.lequal_matrix(boolean=True) - sage: M.base_ring() + sage: M = H.lequal_matrix(boolean=True) # optional - sage.modules sage.rings.finite_rings + sage: M.base_ring() # optional - sage.modules sage.rings.finite_rings Finite Field of size 2 TESTS:: - sage: H.lequal_matrix().is_immutable() + sage: H.lequal_matrix().is_immutable() # optional - sage.modules True """ if boolean: @@ -1422,7 +1422,7 @@ def _alternate_is_lequal(self, i, j): sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0:[2], 1:[2], 2:[3], 3:[4], 4:[]}) - sage: H.lequal_matrix() + sage: H.lequal_matrix() # optional - sage.modules [1 0 1 1 1] [0 1 1 1 1] [0 0 1 1 1] @@ -1508,7 +1508,7 @@ def _meet(self): sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0:[1,3,2],1:[4],2:[4,5,6],3:[6],4:[7],5:[7],6:[7],7:[]}) - sage: H._meet + sage: H._meet # optional - sage.modules [0 0 0 0 0 0 0 0] [0 1 0 0 1 0 0 1] [0 0 2 0 2 2 2 2] @@ -1519,14 +1519,14 @@ def _meet(self): [0 1 2 3 4 5 6 7] sage: H = HasseDiagram({0:[2,3],1:[2,3]}) - sage: H._meet + sage: H._meet # optional - sage.modules [ 0 -1 0 0] [-1 1 1 1] [ 0 1 2 -1] [ 0 1 -1 3] sage: H = HasseDiagram({0:[1,2],1:[3,4],2:[3,4]}) - sage: H._meet + sage: H._meet # optional - sage.modules [ 0 0 0 0 0] [ 0 1 0 1 1] [ 0 0 2 2 2] @@ -1536,9 +1536,9 @@ def _meet(self): TESTS:: sage: from sage.combinat.posets.hasse_diagram import HasseDiagram - sage: L = LatticePoset({0:[1,2,3],1:[4],2:[4],3:[4]}) - sage: P = L.dual() - sage: P.meet(2,3) + sage: L = LatticePoset({0:[1,2,3],1:[4],2:[4],3:[4]}) # optional - sage.modules + sage: P = L.dual() # optional - sage.modules + sage: P.meet(2,3) # optional - sage.modules 4 """ self._meet_semilattice_failure = () @@ -1588,7 +1588,7 @@ def meet_matrix(self): sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0:[1,3,2],1:[4],2:[4,5,6],3:[6],4:[7],5:[7],6:[7],7:[]}) - sage: H.meet_matrix() + sage: H.meet_matrix() # optional - sage.modules [0 0 0 0 0 0 0 0] [0 1 0 0 1 0 0 1] [0 0 2 0 2 2 2 2] @@ -1616,7 +1616,7 @@ def meet_matrix(self): ValueError: not a meet-semilattice: no bottom element sage: H = HasseDiagram({0:[1,2],1:[3,4],2:[3,4]}) - sage: H.meet_matrix() + sage: H.meet_matrix() # optional - sage.modules Traceback (most recent call last): ... LatticeError: no meet for ... @@ -1640,19 +1640,19 @@ def is_meet_semilattice(self) -> bool: sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0:[1,3,2],1:[4],2:[4,5,6],3:[6],4:[7],5:[7],6:[7],7:[]}) - sage: H.is_meet_semilattice() + sage: H.is_meet_semilattice() # optional - sage.modules True sage: H = HasseDiagram({0:[1,2],1:[3],2:[3],3:[]}) - sage: H.is_meet_semilattice() + sage: H.is_meet_semilattice() # optional - sage.modules True sage: H = HasseDiagram({0:[2,3],1:[2,3]}) - sage: H.is_meet_semilattice() + sage: H.is_meet_semilattice() # optional - sage.modules False sage: H = HasseDiagram({0:[1,2],1:[3,4],2:[3,4]}) - sage: H.is_meet_semilattice() + sage: H.is_meet_semilattice() # optional - sage.modules False """ try: @@ -1672,7 +1672,7 @@ def _join(self): sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0:[1,3,2],1:[4],2:[4,5,6],3:[6],4:[7],5:[7],6:[7],7:[]}) - sage: H._join + sage: H._join # optional - sage.modules [0 1 2 3 4 5 6 7] [1 1 4 7 4 7 7 7] [2 4 2 6 4 5 6 7] @@ -1683,14 +1683,14 @@ def _join(self): [7 7 7 7 7 7 7 7] sage: H = HasseDiagram({0:[2,3],1:[2,3]}) - sage: H._join + sage: H._join # optional - sage.modules [ 0 -1 2 3] [-1 1 2 3] [ 2 2 2 -1] [ 3 3 -1 3] sage: H = HasseDiagram({0:[2,3],1:[2,3],2:[4],3:[4]}) - sage: H._join + sage: H._join # optional - sage.modules [ 0 -1 2 3 4] [-1 1 2 3 4] [ 2 2 2 4 4] @@ -1700,9 +1700,9 @@ def _join(self): TESTS:: sage: from sage.combinat.posets.hasse_diagram import HasseDiagram - sage: L = LatticePoset({0:[1,2,3],1:[4],2:[4],3:[4]}) - sage: P = L.dual() - sage: P.join(2,3) + sage: L = LatticePoset({0:[1,2,3],1:[4],2:[4],3:[4]}) # optional - sage.modules + sage: P = L.dual() # optional - sage.modules + sage: P.join(2,3) # optional - sage.modules 0 """ self._join_semilattice_failure = () @@ -1753,7 +1753,7 @@ def join_matrix(self): sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0:[1,3,2],1:[4],2:[4,5,6],3:[6],4:[7],5:[7],6:[7],7:[]}) - sage: H.join_matrix() + sage: H.join_matrix() # optional - sage.modules [0 1 2 3 4 5 6 7] [1 1 4 7 4 7 7 7] [2 4 2 6 4 5 6 7] @@ -1773,7 +1773,7 @@ def join_matrix(self): ValueError: not a join-semilattice: no top element sage: H = HasseDiagram({0:[2,3],1:[2,3],2:[4],3:[4]}) - sage: H.join_matrix() + sage: H.join_matrix() # optional - sage.modules Traceback (most recent call last): ... LatticeError: no join for ... @@ -1797,13 +1797,13 @@ def is_join_semilattice(self) -> bool: sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0:[1,3,2],1:[4],2:[4,5,6],3:[6],4:[7],5:[7],6:[7],7:[]}) - sage: H.is_join_semilattice() + sage: H.is_join_semilattice() # optional - sage.modules True sage: H = HasseDiagram({0:[2,3],1:[2,3]}) - sage: H.is_join_semilattice() + sage: H.is_join_semilattice() # optional - sage.modules False sage: H = HasseDiagram({0:[2,3],1:[2,3],2:[4],3:[4]}) - sage: H.is_join_semilattice() + sage: H.is_join_semilattice() # optional - sage.modules False """ try: @@ -1837,9 +1837,9 @@ def find_nonsemidistributive_elements(self, meet_or_join): sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0:[1, 2], 1:[3, 4], 2:[4, 5], 3:[6], ....: 4:[6], 5:[6]}) - sage: H.find_nonsemidistributive_elements('join') is None + sage: H.find_nonsemidistributive_elements('join') is None # optional - sage.modules False - sage: H.find_nonsemidistributive_elements('meet') is None + sage: H.find_nonsemidistributive_elements('meet') is None # optional - sage.modules True """ if meet_or_join == 'join': @@ -1924,11 +1924,11 @@ def is_complemented(self) -> int | None: sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0:[1, 2], 1:[3], 2:[3], 3:[4]}) - sage: H.is_complemented() + sage: H.is_complemented() # optional - sage.modules 1 sage: H = HasseDiagram({0:[1, 2, 3], 1:[4], 2:[4], 3:[4]}) - sage: H.is_complemented() is None + sage: H.is_complemented() is None # optional - sage.modules True """ mt = self.meet_matrix() @@ -1969,11 +1969,11 @@ def pseudocomplement(self, element): sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0: [1, 2], 1: [3], 2: [4], 3: [4]}) - sage: H.pseudocomplement(2) + sage: H.pseudocomplement(2) # optional - sage.modules 3 sage: H = HasseDiagram({0: [1, 2, 3], 1: [4], 2: [4], 3: [4]}) - sage: H.pseudocomplement(2) is None + sage: H.pseudocomplement(2) is None # optional - sage.modules True """ e = self.order() - 1 @@ -2000,7 +2000,7 @@ def orthocomplementations_iterator(self): sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0:[1,2], 1:[3,4], 3:[5], 4:[5], 2:[6,7], ....: 6:[8], 7:[8], 5:[9], 8:[9]}) - sage: list(H.orthocomplementations_iterator()) + sage: list(H.orthocomplementations_iterator()) # optional - sage.groups [[9, 8, 5, 6, 7, 2, 3, 4, 1, 0], [9, 8, 5, 7, 6, 2, 4, 3, 1, 0]] ALGORITHM: @@ -2021,54 +2021,54 @@ def orthocomplementations_iterator(self): sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram() # Empty - sage: list(H.orthocomplementations_iterator()) + sage: list(H.orthocomplementations_iterator()) # optional - sage.groups [[]] sage: H = HasseDiagram({0:[]}) # One element - sage: list(H.orthocomplementations_iterator()) + sage: list(H.orthocomplementations_iterator()) # optional - sage.groups [[0]] sage: H = HasseDiagram({0:[1]}) # Two elements - sage: list(H.orthocomplementations_iterator()) + sage: list(H.orthocomplementations_iterator()) # optional - sage.groups [[1, 0]] Trivial cases: odd number of elements, not self-dual, not complemented:: sage: H = posets.DiamondPoset(5)._hasse_diagram - sage: list(H.orthocomplementations_iterator()) + sage: list(H.orthocomplementations_iterator()) # optional - sage.groups [] sage: H = posets.ChainPoset(4)._hasse_diagram - sage: list(H.orthocomplementations_iterator()) + sage: list(H.orthocomplementations_iterator()) # optional - sage.groups [] sage: H = HasseDiagram( ([[0, 1], [0, 2], [0, 3], [1, 4], [1, 8], [4, 6], [4, 7], [6, 9], [7, 9], [2, 5], [3, 5], [5, 8], [8, 9]]) ) - sage: list(H.orthocomplementations_iterator()) + sage: list(H.orthocomplementations_iterator()) # optional - sage.groups [] sage: H = HasseDiagram({0:[1, 2, 3], 1: [4], 2:[4], 3: [5], 4:[5]}) - sage: list(H.orthocomplementations_iterator()) + sage: list(H.orthocomplementations_iterator()) # optional - sage.groups [] Complemented, self-dual and even number of elements, but not orthocomplemented:: sage: H = HasseDiagram( ([[0, 1], [1, 2], [2, 3], [0, 4], [4, 5], [0, 6], [3, 7], [5, 7], [6, 7]]) ) - sage: list(H.orthocomplementations_iterator()) + sage: list(H.orthocomplementations_iterator()) # optional - sage.groups [] Unique orthocomplementations; second is not uniquely complemented, but has only one orthocomplementation:: sage: H = posets.BooleanLattice(4)._hasse_diagram # Uniquely complemented - sage: len(list(H.orthocomplementations_iterator())) + sage: len(list(H.orthocomplementations_iterator())) # optional - sage.groups 1 sage: H = HasseDiagram({0:[1, 2], 1:[3], 2:[4], 3:[5], 4:[5]}) - sage: len([_ for _ in H.orthocomplementations_iterator()]) + sage: len([_ for _ in H.orthocomplementations_iterator()]) # optional - sage.groups 1 "Lengthening diamond" must keep the number of orthocomplementations:: sage: H = HasseDiagram( ([[0, 1], [0, 2], [0, 3], [0, 4], [1, 5], [2, 5], [3, 5], [4, 5]]) ) - sage: n = len([_ for _ in H.orthocomplementations_iterator()]); n + sage: n = len([_ for _ in H.orthocomplementations_iterator()]); n # optional - sage.groups 3 sage: H = HasseDiagram('M]??O?@??C??OA???OA??@?A??C?A??O??') - sage: len([_ for _ in H.orthocomplementations_iterator()]) == n + sage: len([_ for _ in H.orthocomplementations_iterator()]) == n # optional - sage.groups True This lattice has an unique "possible orthocomplement" for every @@ -2077,7 +2077,7 @@ def orthocomplementations_iterator(self): for chain 0-1-6-11 would be 11-7-8-0, which is not a chain:: sage: H = HasseDiagram('KTGG_?AAC?O?o?@?@?E?@?@??') - sage: list(H.orthocomplementations_iterator()) + sage: list(H.orthocomplementations_iterator()) # optional - sage.groups [] """ n = self.order() @@ -2223,30 +2223,30 @@ def antichains_iterator(self): EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: H = P._hasse_diagram - sage: H.antichains_iterator() + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: H = P._hasse_diagram # optional - sage.modules + sage: H.antichains_iterator() # optional - sage.modules <generator object ...antichains_iterator at ...> - sage: list(H.antichains_iterator()) + sage: list(H.antichains_iterator()) # optional - sage.modules [[], [4], [3], [2], [1], [1, 3], [1, 2], [0]] sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0:[1,2],1:[4],2:[3],3:[4]}) - sage: list(H.antichains_iterator()) + sage: list(H.antichains_iterator()) # optional - sage.modules [[], [4], [3], [2], [1], [1, 3], [1, 2], [0]] sage: H = HasseDiagram({0:[],1:[],2:[]}) - sage: list(H.antichains_iterator()) + sage: list(H.antichains_iterator()) # optional - sage.modules [[], [2], [1], [1, 2], [0], [0, 2], [0, 1], [0, 1, 2]] sage: H = HasseDiagram({0:[1],1:[2],2:[3],3:[4]}) - sage: list(H.antichains_iterator()) + sage: list(H.antichains_iterator()) # optional - sage.modules [[], [4], [3], [2], [1], [0]] TESTS:: sage: H = Poset()._hasse_diagram - sage: list(H.antichains_iterator()) + sage: list(H.antichains_iterator()) # optional - sage.modules [[]] """ # NOTE: Ordering of antichains as a prefix tree is crucial for @@ -2280,12 +2280,12 @@ def are_incomparable(self, i, j): EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: H = P._hasse_diagram - sage: H.are_incomparable(1,2) + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: H = P._hasse_diagram # optional - sage.modules + sage: H.are_incomparable(1,2) # optional - sage.modules True - sage: V = H.vertices(sort=True) - sage: [ (i,j) for i in V for j in V if H.are_incomparable(i,j)] + sage: V = H.vertices(sort=True) # optional - sage.modules + sage: [ (i,j) for i in V for j in V if H.are_incomparable(i,j)] # optional - sage.modules [(1, 2), (1, 3), (2, 1), (3, 1)] """ if i == j: @@ -2305,13 +2305,15 @@ def are_comparable(self, i, j): EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: H = P._hasse_diagram - sage: H.are_comparable(1,2) + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: H = P._hasse_diagram # optional - sage.modules + sage: H.are_comparable(1,2) # optional - sage.modules False - sage: V = H.vertices(sort=True) - sage: [ (i,j) for i in V for j in V if H.are_comparable(i,j)] - [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 1), (1, 4), (2, 0), (2, 2), (2, 3), (2, 4), (3, 0), (3, 2), (3, 3), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4)] + sage: V = H.vertices(sort=True) # optional - sage.modules + sage: [ (i,j) for i in V for j in V if H.are_comparable(i,j)] # optional - sage.modules + [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 1), (1, 4), + (2, 0), (2, 2), (2, 3), (2, 4), (3, 0), (3, 2), (3, 3), (3, 4), + (4, 0), (4, 1), (4, 2), (4, 3), (4, 4)] """ if i == j: return True @@ -2330,26 +2332,26 @@ def antichains(self, element_class=list): EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: H = P._hasse_diagram - sage: A = H.antichains() - sage: list(A) + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: H = P._hasse_diagram # optional - sage.modules + sage: A = H.antichains() # optional - sage.modules + sage: list(A) # optional - sage.modules [[], [0], [1], [1, 2], [1, 3], [2], [3], [4]] - sage: A.cardinality() + sage: A.cardinality() # optional - sage.modules 8 - sage: [1,3] in A + sage: [1,3] in A # optional - sage.modules True - sage: [1,4] in A + sage: [1,4] in A # optional - sage.modules False TESTS:: - sage: TestSuite(A).run() + sage: TestSuite(A).run() # optional - sage.modules - sage: A = Poset()._hasse_diagram.antichains() - sage: list(A) + sage: A = Poset()._hasse_diagram.antichains() # optional - sage.modules + sage: list(A) # optional - sage.modules [[]] - sage: TestSuite(A).run() + sage: TestSuite(A).run() # optional - sage.modules """ from sage.combinat.subsets_pairwise import PairwiseCompatibleSubsets return PairwiseCompatibleSubsets(self.vertices(sort=True), @@ -2381,21 +2383,23 @@ def chains(self, element_class=list, exclude=None, conversion=None): EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: H = P._hasse_diagram - sage: A = H.chains() - sage: list(A) - [[], [0], [0, 1], [0, 1, 4], [0, 2], [0, 2, 3], [0, 2, 3, 4], [0, 2, 4], [0, 3], [0, 3, 4], [0, 4], [1], [1, 4], [2], [2, 3], [2, 3, 4], [2, 4], [3], [3, 4], [4]] - sage: A.cardinality() + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: H = P._hasse_diagram # optional - sage.modules + sage: A = H.chains() # optional - sage.modules + sage: list(A) # optional - sage.modules + [[], [0], [0, 1], [0, 1, 4], [0, 2], [0, 2, 3], [0, 2, 3, 4], [0, 2, 4], + [0, 3], [0, 3, 4], [0, 4], [1], [1, 4], [2], [2, 3], [2, 3, 4], [2, 4], + [3], [3, 4], [4]] + sage: A.cardinality() # optional - sage.modules 20 - sage: [1,3] in A + sage: [1,3] in A # optional - sage.modules False - sage: [1,4] in A + sage: [1,4] in A # optional - sage.modules True One can exclude some vertices:: - sage: list(H.chains(exclude=[4, 3])) + sage: list(H.chains(exclude=[4, 3])) # optional - sage.modules [[], [0], [0, 1], [0, 2], [1], [2]] The ``element_class`` keyword determines how the chains are @@ -2424,15 +2428,15 @@ def is_linear_interval(self, t_min, t_max) -> bool: EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: H = P._hasse_diagram - sage: H.is_linear_interval(0, 4) + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: H = P._hasse_diagram # optional - sage.modules + sage: H.is_linear_interval(0, 4) # optional - sage.modules False - sage: H.is_linear_interval(0, 3) + sage: H.is_linear_interval(0, 3) # optional - sage.modules True - sage: H.is_linear_interval(1, 3) + sage: H.is_linear_interval(1, 3) # optional - sage.modules False - sage: H.is_linear_interval(1, 1) + sage: H.is_linear_interval(1, 1) # optional - sage.modules True TESTS:: @@ -2504,9 +2508,9 @@ def diamonds(self): sage: H.diamonds() ([(0, 1, 2, 3)], True) - sage: P = posets.YoungDiagramPoset(Partition([3, 2, 2])) - sage: H = P._hasse_diagram - sage: H.diamonds() + sage: P = posets.YoungDiagramPoset(Partition([3, 2, 2])) # optional - sage.combinat + sage: H = P._hasse_diagram # optional - sage.combinat + sage: H.diamonds() # optional - sage.combinat ([(0, 1, 3, 4), (3, 4, 5, 6)], False) """ diamonds = [] @@ -2534,8 +2538,8 @@ def common_upper_covers(self, vertices): [3] sage: from sage.combinat.posets.poset_examples import Posets - sage: H = Posets.YoungDiagramPoset(Partition([3, 2, 2]))._hasse_diagram - sage: H.common_upper_covers([4, 5]) + sage: H = Posets.YoungDiagramPoset(Partition([3, 2, 2]))._hasse_diagram # optional - sage.combinat + sage: H.common_upper_covers([4, 5]) # optional - sage.combinat [6] """ covers = set(self.neighbors_out(vertices.pop())) @@ -2555,8 +2559,8 @@ def common_lower_covers(self, vertices): [0] sage: from sage.combinat.posets.poset_examples import Posets - sage: H = Posets.YoungDiagramPoset(Partition([3, 2, 2]))._hasse_diagram - sage: H.common_lower_covers([4, 5]) + sage: H = Posets.YoungDiagramPoset(Partition([3, 2, 2]))._hasse_diagram # optional - sage.combinat + sage: H.common_lower_covers([4, 5]) # optional - sage.combinat [3] """ covers = set(self.neighbors_in(vertices.pop())) @@ -2632,9 +2636,9 @@ def sublattices_iterator(self, elms, min_e): sage: H = HasseDiagram({0: [1, 2], 1:[3], 2:[3]}) sage: it = H.sublattices_iterator(set(), 0); it <generator object ...sublattices_iterator at ...> - sage: next(it) + sage: next(it) # optional - sage.modules set() - sage: next(it) + sage: next(it) # optional - sage.modules {0} """ yield elms @@ -2664,9 +2668,9 @@ def maximal_sublattices(self): EXAMPLES:: - sage: L = posets.PentagonPoset() - sage: ms = L._hasse_diagram.maximal_sublattices() - sage: sorted(ms, key=sorted) + sage: L = posets.PentagonPoset() # optional - sage.modules + sage: ms = L._hasse_diagram.maximal_sublattices() # optional - sage.modules + sage: sorted(ms, key=sorted) # optional - sage.modules [{0, 1, 2, 4}, {0, 1, 3, 4}, {0, 2, 3, 4}] """ jn = self.join_matrix() @@ -2768,8 +2772,8 @@ def frattini_sublattice(self): EXAMPLES:: - sage: H = posets.PentagonPoset()._hasse_diagram - sage: H.frattini_sublattice() + sage: H = posets.PentagonPoset()._hasse_diagram # optional - sage.modules + sage: H.frattini_sublattice() # optional - sage.modules [0, 4] """ # Just a direct computation, no optimization at all. @@ -2853,7 +2857,7 @@ def skeleton(self): sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0: [1, 2], 1: [3, 4], 2: [4], ....: 3: [5], 4: [5]}) - sage: H.skeleton() + sage: H.skeleton() # optional - sage.modules [5, 2, 0, 3] """ p_atoms = [] @@ -2945,8 +2949,8 @@ def neutral_elements(self): sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0: [1, 2], 1: [4], 2: [3], 3: [4, 5], - ....: 4: [6], 5:[6]}) - sage: sorted(H.neutral_elements()) + ....: 4: [6], 5: [6]}) + sage: sorted(H.neutral_elements()) # optional - sage.modules [0, 4, 6] ALGORITHM: @@ -3093,10 +3097,10 @@ def atoms_of_congruence_lattice(self): sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: N5 = HasseDiagram({0: [1, 2], 1: [4], 2: [3], 3:[4]}) - sage: N5.atoms_of_congruence_lattice() + sage: N5.atoms_of_congruence_lattice() # optional - sage.combinat [{{0}, {1}, {2, 3}, {4}}] sage: Hex = HasseDiagram({0: [1, 2], 1: [3], 2: [4], 3: [5], 4: [5]}) - sage: Hex.atoms_of_congruence_lattice() + sage: Hex.atoms_of_congruence_lattice() # optional - sage.combinat [{{0}, {1}, {2, 4}, {3}, {5}}, {{0}, {1, 3}, {2}, {4}, {5}}] ALGORITHM: @@ -3170,32 +3174,32 @@ def congruence(self, parts, start=None, stop_pairs=[]): sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0: [1, 2], 1: [3], 2: [4], 3: [4]}) - sage: cong = H.congruence([[0, 1]]); cong + sage: cong = H.congruence([[0, 1]]); cong # optional - sage.modules {{0, 1, 3}, {2, 4}} - sage: H.congruence([[0, 2]], start=cong) + sage: H.congruence([[0, 2]], start=cong) # optional - sage.modules {{0, 1, 2, 3, 4}} - sage: H.congruence([[0, 1]], stop_pairs=[(1, 3)]) is None + sage: H.congruence([[0, 1]], stop_pairs=[(1, 3)]) is None # optional - sage.modules True TESTS:: sage: H = HasseDiagram('HT@O?GO?OE?G@??') - sage: H.congruence([[0, 1]]).number_of_subsets() + sage: H.congruence([[0, 1]]).number_of_subsets() # optional - sage.modules 1 sage: H = HasseDiagram('HW_oC?@@O@?O@??') - sage: H.congruence([[0, 1]]).number_of_subsets() + sage: H.congruence([[0, 1]]).number_of_subsets() # optional - sage.modules 1 Check :trac:`21861`:: sage: H = HasseDiagram({0: [1, 2], 1: [3], 2: [4], 3: [4]}) - sage: tmp = H.congruence([[1, 3]]) - sage: tmp.number_of_subsets() + sage: tmp = H.congruence([[1, 3]]) # optional - sage.modules + sage: tmp.number_of_subsets() # optional - sage.modules 4 - sage: H.congruence([[0, 1]], start=tmp).number_of_subsets() + sage: H.congruence([[0, 1]], start=tmp).number_of_subsets() # optional - sage.modules 2 - sage: tmp.number_of_subsets() + sage: tmp.number_of_subsets() # optional - sage.modules 4 """ from sage.sets.disjoint_set import DisjointSet @@ -3313,11 +3317,11 @@ def find_nontrivial_congruence(self): sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram({0: [1, 2], 1: [5], 2: [3, 4], 3: [5], 4: [5]}) - sage: H.find_nontrivial_congruence() + sage: H.find_nontrivial_congruence() # optional - sage.modules {{0, 1}, {2, 3, 4, 5}} sage: H = HasseDiagram({0: [1, 2, 3], 1: [4], 2: [4], 3: [4]}) - sage: H.find_nontrivial_congruence() is None + sage: H.find_nontrivial_congruence() is None # optional - sage.modules True ALGORITHM: @@ -3372,12 +3376,12 @@ def principal_congruences_poset(self): sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: N5 = HasseDiagram({0: [1, 2], 1: [4], 2: [3], 3: [4]}) - sage: P, D = N5.principal_congruences_poset() - sage: P + sage: P, D = N5.principal_congruences_poset() # optional - sage.combinat + sage: P # optional - sage.combinat Finite poset containing 3 elements - sage: P.bottom() + sage: P.bottom() # optional - sage.combinat (2, 3) - sage: D[(2, 3)] + sage: D[(2, 3)] # optional - sage.combinat {{0}, {1}, {2, 3}, {4}} """ from sage.combinat.set_partition import SetPartition, SetPartitions @@ -3419,7 +3423,7 @@ def congruences_iterator(self): sage: H = HasseDiagram('GY@OQ?OW@?O?') sage: it = H.congruences_iterator(); it <generator object ...> - sage: sorted([cong.number_of_subsets() for cong in it]) + sage: sorted([cong.number_of_subsets() for cong in it]) # optional - sage.combinat [1, 2, 2, 2, 4, 4, 4, 8] """ from sage.sets.disjoint_set import DisjointSet @@ -3454,26 +3458,26 @@ def is_congruence_normal(self) -> bool: sage: from sage.combinat.posets.hasse_diagram import HasseDiagram sage: H = HasseDiagram('IX?Q@?AG?OG?W?O@??') - sage: H.is_congruence_normal() + sage: H.is_congruence_normal() # optional - sage.combinat True The 5-element diamond is the smallest non-example:: sage: H = HasseDiagram({0: [1, 2, 3], 1: [4], 2: [4], 3: [4]}) - sage: H.is_congruence_normal() + sage: H.is_congruence_normal() # optional - sage.combinat False This is done by doubling a non-convex subset:: sage: H = HasseDiagram('OQC?a?@CO?G_C@?GA?O??_??@?BO?A_?G??C??_?@???') - sage: H.is_congruence_normal() + sage: H.is_congruence_normal() # optional - sage.combinat False TESTS:: - sage: HasseDiagram().is_congruence_normal() + sage: HasseDiagram().is_congruence_normal() # optional - sage.combinat True - sage: HasseDiagram({0: []}).is_congruence_normal() + sage: HasseDiagram({0: []}).is_congruence_normal() # optional - sage.combinat True ALGORITHM: diff --git a/src/sage/combinat/posets/linear_extensions.py b/src/sage/combinat/posets/linear_extensions.py index e14be386228..8982e94eacc 100644 --- a/src/sage/combinat/posets/linear_extensions.py +++ b/src/sage/combinat/posets/linear_extensions.py @@ -232,8 +232,8 @@ def is_greedy(self): EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: for l in P.linear_extensions(): + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: for l in P.linear_extensions(): # optional - sage.modules ....: if not l.is_greedy(): ....: print(l) [0, 2, 1, 3, 4] @@ -274,16 +274,16 @@ def is_supergreedy(self): sage: X = [0,1,2,3,4,5,6] sage: Y = [[0,5],[1,4],[1,5],[3,6],[4,3],[5,6],[6,2]] - sage: P = Poset((X,Y), cover_relations = True, facade=False) - sage: for l in P.linear_extensions(): + sage: P = Poset((X,Y), cover_relations=True, facade=False) + sage: for l in P.linear_extensions(): # optional - sage.modules sage.rings.finite_rings ....: if l.is_supergreedy(): ....: print(l) [1, 4, 3, 0, 5, 6, 2] [0, 1, 4, 3, 5, 6, 2] [0, 1, 5, 4, 3, 6, 2] - sage: Q = posets.PentagonPoset() - sage: for l in Q.linear_extensions(): + sage: Q = posets.PentagonPoset() # optional - sage.modules + sage: for l in Q.linear_extensions(): # optional - sage.modules sage.rings.finite_rings ....: if not l.is_supergreedy(): ....: print(l) [0, 2, 1, 3, 4] @@ -332,7 +332,7 @@ def tau(self, i): [1, 2, 3, 4] sage: l.tau(1) [2, 1, 3, 4] - sage: for p in L: + sage: for p in L: # optional - sage.modules sage.rings.finite_rings ....: for i in range(1,4): ....: print("{} {} {}".format(i, p, p.tau(i))) 1 [1, 2, 3, 4] [2, 1, 3, 4] @@ -489,7 +489,7 @@ class LinearExtensionsOfPoset(UniqueRepresentation, Parent): The set of all linear extensions of Finite poset containing 4 elements with distinguished linear extension sage: L.cardinality() 5 - sage: L.list() + sage: L.list() # optional - sage.modules sage.rings.finite_rings [[1, 2, 3, 4], [2, 1, 3, 4], [2, 1, 4, 3], [1, 4, 2, 3], [1, 2, 4, 3]] sage: L.an_element() [1, 2, 3, 4] @@ -664,7 +664,7 @@ def __iter__(self): sage: rels = [[1,3],[1,4],[2,3]] sage: P = Poset((elms, rels), linear_extension=True) sage: L = P.linear_extensions() - sage: list(L) + sage: list(L) # optional - sage.modules sage.rings.finite_rings [[1, 2, 3, 4], [2, 1, 3, 4], [2, 1, 4, 3], [1, 4, 2, 3], [1, 2, 4, 3]] """ from sage.combinat.combinat_cython import linear_extension_iterator @@ -822,28 +822,28 @@ def markov_chain_transition_matrix(self, action='promotion', labeling='identity' sage: P = Poset(([1,2,3,4], [[1,3],[1,4],[2,3]]), linear_extension = True) sage: L = P.linear_extensions() - sage: L.markov_chain_transition_matrix() + sage: L.markov_chain_transition_matrix() # optional - sage.modules [-x0 - x1 - x2 x2 x0 + x1 0 0] [ x1 + x2 -x0 - x1 - x2 0 x0 0] [ 0 x1 -x0 - x1 0 x0] [ 0 x0 0 -x0 - x1 - x2 x1 + x2] [ x0 0 0 x1 + x2 -x0 - x1 - x2] - sage: L.markov_chain_transition_matrix(labeling = 'source') + sage: L.markov_chain_transition_matrix(labeling='source') # optional - sage.modules [-x0 - x1 - x2 x3 x0 + x3 0 0] [ x1 + x2 -x0 - x1 - x3 0 x1 0] [ 0 x1 -x0 - x3 0 x1] [ 0 x0 0 -x0 - x1 - x2 x0 + x3] [ x0 0 0 x0 + x2 -x0 - x1 - x3] - sage: L.markov_chain_transition_matrix(action = 'tau') + sage: L.markov_chain_transition_matrix(action='tau') # optional - sage.modules [ -x0 - x2 x2 0 x0 0] [ x2 -x0 - x1 - x2 x1 0 x0] [ 0 x1 -x1 0 0] [ x0 0 0 -x0 - x2 x2] [ 0 x0 0 x2 -x0 - x2] - sage: L.markov_chain_transition_matrix(action = 'tau', labeling = 'source') + sage: L.markov_chain_transition_matrix(action='tau', labeling='source') # optional - sage.modules [ -x0 - x2 x3 0 x1 0] [ x2 -x0 - x1 - x3 x3 0 x1] [ 0 x1 -x3 0 0] @@ -922,8 +922,8 @@ def cardinality(self): EXAMPLES:: sage: from sage.combinat.posets.poset_examples import Posets - sage: P = Posets.YoungDiagramPoset(Partition([3,2]), dual=True) - sage: P.linear_extensions().cardinality() + sage: P = Posets.YoungDiagramPoset(Partition([3,2]), dual=True) # optional - sage.combinat + sage: P.linear_extensions().cardinality() # optional - sage.combinat sage.modules 5 """ num_elmts = self._poset.cardinality() @@ -949,11 +949,11 @@ def cardinality(self): sage: from sage.combinat.posets.forest import ForestPoset sage: from sage.combinat.posets.poset_examples import Posets sage: P = Poset({0: [2], 1: [2], 2: [3, 4], 3: [], 4: []}) - sage: P.linear_extensions().cardinality() + sage: P.linear_extensions().cardinality() # optional - sage.modules 4 sage: Q = Poset({0: [1], 1: [2, 3], 2: [], 3: [], 4: [5, 6], 5: [], 6: []}) - sage: Q.linear_extensions().cardinality() + sage: Q.linear_extensions().cardinality() # optional - sage.modules 140 """ return sum(self.atkinson(self._elements[0])) @@ -974,17 +974,18 @@ def cardinality(self): sage: from sage.combinat.posets.mobile import MobilePoset sage: M = MobilePoset(DiGraph([[0,1,2,3,4,5,6,7,8], [(1,0),(3,0),(2,1),(2,3),(4, ....: 3), (5,4),(5,6),(7,4),(7,8)]])) - sage: M.linear_extensions().cardinality() + sage: M.linear_extensions().cardinality() # optional - sage.modules 1098 sage: M1 = posets.RibbonPoset(6, [1,3]) - sage: M1.linear_extensions().cardinality() + sage: M1.linear_extensions().cardinality() # optional - sage.modules 61 - sage: P = posets.MobilePoset(posets.RibbonPoset(7, [1,3]), {1: - ....: [posets.YoungDiagramPoset([3, 2], dual=True)], 3: [posets.DoubleTailedDiamond(6)]}, - ....: anchor=(4, 2, posets.ChainPoset(6))) - sage: P.linear_extensions().cardinality() + sage: P = posets.MobilePoset(posets.RibbonPoset(7, [1,3]), # optional - sage.combinat + ....: {1: [posets.YoungDiagramPoset([3, 2], dual=True)], + ....: 3: [posets.DoubleTailedDiamond(6)]}, + ....: anchor=(4, 2, posets.ChainPoset(6))) + sage: P.linear_extensions().cardinality() # optional - sage.combinat sage.modules 361628701868606400 """ import sage.combinat.posets.d_complete as dc diff --git a/src/sage/combinat/posets/mobile.py b/src/sage/combinat/posets/mobile.py index 26e793c96d2..d09eb370fa7 100644 --- a/src/sage/combinat/posets/mobile.py +++ b/src/sage/combinat/posets/mobile.py @@ -28,13 +28,13 @@ class MobilePoset(FinitePoset): EXAMPLES:: - sage: P = posets.MobilePoset(posets.RibbonPoset(7, [1,3]), + sage: P = posets.MobilePoset(posets.RibbonPoset(7, [1,3]), # optional - sage.combinat ....: {1: [posets.YoungDiagramPoset([3, 2], dual=True)], ....: 3: [posets.DoubleTailedDiamond(6)]}, ....: anchor=(4, 2, posets.ChainPoset(6))) - sage: len(P._ribbon) + sage: len(P._ribbon) # optional - sage.combinat 8 - sage: P._anchor + sage: P._anchor # optional - sage.combinat (4, 5) This example is Example 5.9 in [GGMM2020]_:: @@ -53,7 +53,7 @@ class MobilePoset(FinitePoset): [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] sage: P2._anchor (8, (8, 0)) - sage: P2.linear_extensions().cardinality() + sage: P2.linear_extensions().cardinality() # optional - sage.modules 21399440939 sage: EP = posets.MobilePoset(posets.ChainPoset(0), {}) diff --git a/src/sage/combinat/posets/poset_examples.py b/src/sage/combinat/posets/poset_examples.py index f5b32cc30bd..f9a5d793dfa 100644 --- a/src/sage/combinat/posets/poset_examples.py +++ b/src/sage/combinat/posets/poset_examples.py @@ -3,7 +3,7 @@ Some common posets can be accessed through the ``posets.<tab>`` object:: - sage: posets.PentagonPoset() + sage: posets.PentagonPoset() # optional - sage.modules Finite lattice containing 5 elements Moreover, the set of all posets of order `n` is represented by ``Posets(n)``:: @@ -238,9 +238,9 @@ def BooleanLattice(n, facade=None, use_subsets=False): Check the corner cases:: - sage: list(posets.BooleanLattice(0, use_subsets=True)) + sage: list(posets.BooleanLattice(0, use_subsets=True)) # optional - sage.modules [{}] - sage: list(posets.BooleanLattice(1, use_subsets=True)) + sage: list(posets.BooleanLattice(1, use_subsets=True)) # optional - sage.modules [{}, {1}] """ n = check_int(n) @@ -382,22 +382,22 @@ def PentagonPoset(facade=None): EXAMPLES:: - sage: P = posets.PentagonPoset(); P + sage: P = posets.PentagonPoset(); P # optional - sage.modules Finite lattice containing 5 elements - sage: P.cover_relations() + sage: P.cover_relations() # optional - sage.modules [[0, 1], [0, 2], [1, 4], [2, 3], [3, 4]] TESTS: This is smallest lattice that is not modular:: - sage: P.is_modular() + sage: P.is_modular() # optional - sage.modules False This poset and the :meth:`DiamondPoset` are the two smallest lattices which are not distributive:: - sage: P.is_distributive() + sage: P.is_distributive() # optional - sage.modules False sage: posets.DiamondPoset(5).is_distributive() False @@ -535,9 +535,9 @@ def IntegerPartitions(n): EXAMPLES:: - sage: P = posets.IntegerPartitions(7); P + sage: P = posets.IntegerPartitions(7); P # optional - sage.combinat Finite poset containing 15 elements - sage: len(P.cover_relations()) + sage: len(P.cover_relations()) # optional - sage.combinat 28 """ def lower_covers(partition): @@ -573,9 +573,9 @@ def RestrictedIntegerPartitions(n): EXAMPLES:: - sage: P = posets.RestrictedIntegerPartitions(7); P + sage: P = posets.RestrictedIntegerPartitions(7); P # optional - sage.combinat Finite poset containing 15 elements - sage: len(P.cover_relations()) + sage: len(P.cover_relations()) # optional - sage.combinat 17 """ @@ -617,9 +617,9 @@ def IntegerPartitionsDominanceOrder(n): EXAMPLES:: - sage: P = posets.IntegerPartitionsDominanceOrder(6); P + sage: P = posets.IntegerPartitionsDominanceOrder(6); P # optional - sage.combinat Finite lattice containing 11 elements - sage: P.cover_relations() + sage: P.cover_relations() # optional - sage.combinat [[[1, 1, 1, 1, 1, 1], [2, 1, 1, 1, 1]], [[2, 1, 1, 1, 1], [2, 2, 1, 1]], [[2, 2, 1, 1], [2, 2, 2]], @@ -652,22 +652,22 @@ def PowerPoset(n): EXAMPLES:: - sage: P3 = posets.PowerPoset(3); P3 + sage: P3 = posets.PowerPoset(3); P3 # optional - sage.modules Finite meet-semilattice containing 19 elements - sage: all(P.is_chain() for P in P3.maximal_elements()) + sage: all(P.is_chain() for P in P3.maximal_elements()) # optional - sage.modules True TESTS:: - sage: P0 = posets.PowerPoset(0); P0 + sage: P0 = posets.PowerPoset(0); P0 # optional - sage.modules Finite meet-semilattice containing 1 elements - sage: P0[0] + sage: P0[0] # optional - sage.modules Finite poset containing 0 elements - sage: P1 = posets.PowerPoset(1); P1 + sage: P1 = posets.PowerPoset(1); P1 # optional - sage.modules Finite meet-semilattice containing 1 elements - sage: P1[0] + sage: P1[0] # optional - sage.modules Finite poset containing 1 elements - sage: P1[0][0] + sage: P1[0][0] # optional - sage.modules 0 """ # Todo: Make this faster. @@ -697,22 +697,22 @@ def ProductOfChains(chain_lengths, facade=None): EXAMPLES:: - sage: P = posets.ProductOfChains([2, 2]); P + sage: P = posets.ProductOfChains([2, 2]); P # optional - sage.modules Finite lattice containing 4 elements - sage: P.linear_extension() + sage: P.linear_extension() # optional - sage.modules [(0, 0), (0, 1), (1, 0), (1, 1)] - sage: P.upper_covers((0,0)) + sage: P.upper_covers((0,0)) # optional - sage.modules [(0, 1), (1, 0)] - sage: P.lower_covers((1,1)) + sage: P.lower_covers((1,1)) # optional - sage.modules [(0, 1), (1, 0)] TESTS:: - sage: P = posets.ProductOfChains([]); P + sage: P = posets.ProductOfChains([]); P # optional - sage.modules Finite lattice containing 0 elements - sage: P = posets.ProductOfChains([3, 0, 1]); P + sage: P = posets.ProductOfChains([3, 0, 1]); P # optional - sage.modules Finite lattice containing 0 elements - sage: P = posets.ProductOfChains([1,1,1,1]); P + sage: P = posets.ProductOfChains([1,1,1,1]); P # optional - sage.modules Finite lattice containing 1 elements """ try: @@ -831,12 +831,12 @@ def RandomLattice(n, p, properties=None): EXAMPLES:: sage: set_random_seed(0) # Results are reproducible - sage: L = posets.RandomLattice(8, 0.995); L + sage: L = posets.RandomLattice(8, 0.995); L # optional - sage.modules Finite lattice containing 8 elements - sage: L.cover_relations() + sage: L.cover_relations() # optional - sage.modules [[7, 6], [7, 3], [7, 1], ..., [5, 4], [2, 4], [1, 4], [0, 4]] - sage: L = posets.RandomLattice(10, 0, properties=['dismantlable']) - sage: L.is_dismantlable() + sage: L = posets.RandomLattice(10, 0, properties=['dismantlable']) # optional - sage.modules + sage: L.is_dismantlable() # optional - sage.modules True .. SEEALSO:: :meth:`RandomPoset` @@ -858,7 +858,7 @@ def RandomLattice(n, p, properties=None): ... ValueError: unknown value junk for 'properties' - sage: posets.RandomLattice(0, 0.5) + sage: posets.RandomLattice(0, 0.5) # optional - sage.modules Finite lattice containing 0 elements """ from copy import copy @@ -941,7 +941,7 @@ def SetPartitions(n): EXAMPLES:: - sage: posets.SetPartitions(4) + sage: posets.SetPartitions(4) # optional - sage.combinat Finite lattice containing 15 elements """ from sage.combinat.set_partition import SetPartitions @@ -981,19 +981,19 @@ def SSTPoset(s, f=None): EXAMPLES:: - sage: posets.SSTPoset([2,1]) + sage: posets.SSTPoset([2,1]) # optional - sage.combinat Finite lattice containing 8 elements - sage: posets.SSTPoset([2,1],4) + sage: posets.SSTPoset([2,1],4) # optional - sage.combinat Finite lattice containing 20 elements - sage: posets.SSTPoset([2,1],2).cover_relations() + sage: posets.SSTPoset([2,1],2).cover_relations() # optional - sage.combinat [[[[1, 1], [2]], [[1, 2], [2]]]] - sage: posets.SSTPoset([3,2]).bottom() # long time (6s on sage.math, 2012) + sage: posets.SSTPoset([3,2]).bottom() # long time (6s on sage.math, 2012) # optional - sage.combinat [[1, 1, 1], [2, 2]] - sage: posets.SSTPoset([3,2],4).maximal_elements() + sage: posets.SSTPoset([3,2],4).maximal_elements() # optional - sage.combinat [[[3, 3, 4], [4, 4]]] """ from sage.combinat.tableau import SemistandardTableaux @@ -1202,11 +1202,11 @@ def TetrahedralPoset(n, *colors, **labels): sage: posets.TetrahedralPoset(4,'green','red','yellow','silver','blue','orange', labels='integers') Finite poset containing 10 elements - sage: A = AlternatingSignMatrices(3) - sage: p = A.lattice() - sage: ji = p.join_irreducibles_poset() - sage: tet = posets.TetrahedralPoset(3, 'green','yellow','blue','orange') - sage: ji.is_isomorphic(tet) + sage: A = AlternatingSignMatrices(3) # optional - sage.combinat sage.modules + sage: p = A.lattice() # optional - sage.combinat sage.modules + sage: ji = p.join_irreducibles_poset() # optional - sage.combinat sage.modules + sage: tet = posets.TetrahedralPoset(3, 'green','yellow','blue','orange') # optional - sage.combinat sage.modules + sage: ji.is_isomorphic(tet) # optional - sage.combinat sage.modules True TESTS:: @@ -1276,12 +1276,12 @@ def CoxeterGroupAbsoluteOrderPoset(W, use_reduced_words=True): EXAMPLES:: - sage: W = CoxeterGroup(['B', 3]) - sage: posets.CoxeterGroupAbsoluteOrderPoset(W) + sage: W = CoxeterGroup(['B', 3]) # optional - sage.combinat sage.groups + sage: posets.CoxeterGroupAbsoluteOrderPoset(W) # optional - sage.combinat sage.groups Finite poset containing 48 elements - sage: W = WeylGroup(['B', 2], prefix='s') - sage: posets.CoxeterGroupAbsoluteOrderPoset(W, False) + sage: W = WeylGroup(['B', 2], prefix='s') # optional - sage.combinat sage.groups + sage: posets.CoxeterGroupAbsoluteOrderPoset(W, False) # optional - sage.combinat sage.groups Finite poset containing 8 elements """ if use_reduced_words: @@ -1300,12 +1300,12 @@ def NoncrossingPartitions(W): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3]) - sage: posets.NoncrossingPartitions(W) + sage: W = CoxeterGroup(['A', 3]) # optional - sage.combinat sage.groups + sage: posets.NoncrossingPartitions(W) # optional - sage.combinat sage.groups Finite lattice containing 14 elements - sage: W = WeylGroup(['B', 2], prefix='s') - sage: posets.NoncrossingPartitions(W) + sage: W = WeylGroup(['B', 2], prefix='s') # optional - sage.combinat sage.groups + sage: posets.NoncrossingPartitions(W) # optional - sage.combinat sage.groups Finite lattice containing 6 elements """ return W.noncrossing_partition_lattice() @@ -1331,11 +1331,11 @@ def SymmetricGroupAbsoluteOrderPoset(n, labels="permutations"): EXAMPLES:: - sage: posets.SymmetricGroupAbsoluteOrderPoset(4) + sage: posets.SymmetricGroupAbsoluteOrderPoset(4) # optional - sage.groups Finite poset containing 24 elements - sage: posets.SymmetricGroupAbsoluteOrderPoset(3, labels="cycles") + sage: posets.SymmetricGroupAbsoluteOrderPoset(3, labels="cycles") # optional - sage.groups Finite poset containing 6 elements - sage: posets.SymmetricGroupAbsoluteOrderPoset(3, labels="reduced_words") + sage: posets.SymmetricGroupAbsoluteOrderPoset(3, labels="reduced_words") # optional - sage.groups Finite poset containing 6 elements """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -1380,7 +1380,7 @@ def UpDownPoset(n, m=1): Fibonacci numbers as the number of antichains of a poset:: - sage: [len(posets.UpDownPoset(n).antichains().list()) for n in range(6)] + sage: [len(posets.UpDownPoset(n).antichains().list()) for n in range(6)] # optional - sage.combinat [1, 2, 3, 5, 8, 13] TESTS:: @@ -1414,13 +1414,13 @@ def YoungDiagramPoset(lam, dual=False): EXAMPLES:: - sage: P = posets.YoungDiagramPoset(Partition([2, 2])); P + sage: P = posets.YoungDiagramPoset(Partition([2, 2])); P # optional - sage.combinat Finite meet-semilattice containing 4 elements - sage: sorted(P.cover_relations()) + sage: sorted(P.cover_relations()) # optional - sage.combinat [[(0, 0), (0, 1)], [(0, 0), (1, 0)], [(0, 1), (1, 1)], [(1, 0), (1, 1)]] - sage: posets.YoungDiagramPoset([3, 2], dual=True) + sage: posets.YoungDiagramPoset([3, 2], dual=True) # optional - sage.combinat Finite join-semilattice containing 5 elements """ from sage.combinat.partition import Partition @@ -1460,9 +1460,9 @@ def YoungsLattice(n): EXAMPLES:: - sage: P = posets.YoungsLattice(3); P + sage: P = posets.YoungsLattice(3); P # optional - sage.combinat Finite meet-semilattice containing 7 elements - sage: P.cover_relations() + sage: P.cover_relations() # optional - sage.combinat [[[], [1]], [[1], [1, 1]], [[1], [2]], @@ -1488,10 +1488,10 @@ def YoungsLatticePrincipalOrderIdeal(lam): EXAMPLES:: - sage: P = posets.YoungsLatticePrincipalOrderIdeal(Partition([2,2])) - sage: P + sage: P = posets.YoungsLatticePrincipalOrderIdeal(Partition([2,2])) # optional - sage.combinat + sage: P # optional - sage.combinat Finite lattice containing 6 elements - sage: P.cover_relations() + sage: P.cover_relations() # optional - sage.combinat [[[], [1]], [[1], [1, 1]], [[1], [2]], @@ -1527,16 +1527,16 @@ def YoungFibonacci(n): EXAMPLES:: - sage: Y5 = posets.YoungFibonacci(5); Y5 + sage: Y5 = posets.YoungFibonacci(5); Y5 # optional - sage.combinat Finite meet-semilattice containing 20 elements - sage: sorted(Y5.upper_covers(Word('211'))) + sage: sorted(Y5.upper_covers(Word('211'))) # optional - sage.combinat [word: 1211, word: 2111, word: 221] TESTS:: - sage: posets.YoungFibonacci(0) + sage: posets.YoungFibonacci(0) # optional - sage.combinat Finite meet-semilattice containing 1 elements - sage: posets.YoungFibonacci(1) + sage: posets.YoungFibonacci(1) # optional - sage.combinat Finite meet-semilattice containing 2 elements """ from sage.combinat.posets.lattices import FiniteMeetSemilattice @@ -1616,9 +1616,9 @@ def PermutationPattern(n): EXAMPLES:: - sage: P4 = posets.PermutationPattern(4); P4 + sage: P4 = posets.PermutationPattern(4); P4 # optional - sage.combinat Finite poset containing 33 elements - sage: sorted(P4.lower_covers(Permutation([2,4,1,3]))) + sage: sorted(P4.lower_covers(Permutation([2,4,1,3]))) # optional - sage.combinat [[1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2]] .. SEEALSO:: @@ -1627,9 +1627,9 @@ def PermutationPattern(n): TESTS:: - sage: posets.PermutationPattern(1) + sage: posets.PermutationPattern(1) # optional - sage.combinat Finite poset containing 1 elements - sage: posets.PermutationPattern(2) + sage: posets.PermutationPattern(2) # optional - sage.combinat Finite poset containing 3 elements """ n = check_int(n, 1) @@ -1660,9 +1660,9 @@ def PermutationPatternInterval(bottom, top): sage: t = Permutation([2,3,1]) sage: b = Permutation([4,6,2,3,5,1]) - sage: R = posets.PermutationPatternInterval(t, b); R + sage: R = posets.PermutationPatternInterval(t, b); R # optional - sage.combinat Finite poset containing 14 elements - sage: R.moebius_function(R.bottom(),R.top()) + sage: R.moebius_function(R.bottom(),R.top()) # optional - sage.combinat -4 .. SEEALSO:: @@ -1673,7 +1673,7 @@ def PermutationPatternInterval(bottom, top): TESTS:: sage: p = Permutation([1]) - sage: posets.PermutationPatternInterval(p, p) + sage: posets.PermutationPatternInterval(p, p) # optional - sage.combinat Finite poset containing 1 elements """ P = Permutations() @@ -1732,7 +1732,7 @@ def PermutationPatternOccurrenceInterval(bottom, top, pos): sage: t = Permutation([3,2,1]) sage: b = Permutation([6,3,4,5,2,1]) - sage: A = posets.PermutationPatternOccurrenceInterval(t, b, (0,2,4)); A + sage: A = posets.PermutationPatternOccurrenceInterval(t, b, (0,2,4)); A # optional - sage.combinat Finite poset containing 8 elements .. SEEALSO:: @@ -1818,11 +1818,11 @@ def MobilePoset(ribbon, hangers, anchor=None): sage: len(M.cover_relations()) 7 - sage: P = posets.MobilePoset(posets.RibbonPoset(7, [1,3]), + sage: P = posets.MobilePoset(posets.RibbonPoset(7, [1,3]), # optional - sage.combinat ....: {1: [posets.YoungDiagramPoset([3, 2], dual=True)], ....: 3: [posets.DoubleTailedDiamond(6)]}, ....: anchor=(4, 2, posets.ChainPoset(6))) - sage: len(P.cover_relations()) + sage: len(P.cover_relations()) # optional - sage.combinat 33 """ elements = [] @@ -2039,8 +2039,8 @@ def _random_distributive_lattice(n): EXAMPLES:: - sage: g = sage.combinat.posets.poset_examples._random_distributive_lattice(10) - sage: Poset(g).order_ideals_lattice(as_ideals=False).cardinality() + sage: g = sage.combinat.posets.poset_examples._random_distributive_lattice(10) # optional - sage.modules + sage: Poset(g).order_ideals_lattice(as_ideals=False).cardinality() # optional - sage.modules 10 ALGORITHM: @@ -2095,8 +2095,8 @@ def _random_stone_lattice(n): EXAMPLES:: - sage: g = sage.combinat.posets.poset_examples._random_stone_lattice(10) - sage: LatticePoset(g).is_stone() + sage: g = sage.combinat.posets.poset_examples._random_stone_lattice(10) # optional - sage.combinat + sage: LatticePoset(g).is_stone() # optional - sage.combinat True ALGORITHM: diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 0812da9a83c..65ad12be6bf 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -433,7 +433,7 @@ def Poset(data=None, element_labels=None, cover_relations=False, linear_extensio With a function that identifies the cover relations: the set partitions of `\{1, 2, 3\}` ordered by refinement:: - sage: elms = SetPartitions(3) + sage: elms = SetPartitions(3) # optional - sage.combinat sage: def fcn(A, B): ....: if len(A) != len(B)+1: ....: return False @@ -441,7 +441,7 @@ def Poset(data=None, element_labels=None, cover_relations=False, linear_extensio ....: if not any(set(a).issubset(b) for b in B): ....: return False ....: return True - sage: Poset((elms, fcn), cover_relations=True) + sage: Poset((elms, fcn), cover_relations=True) # optional - sage.combinat Finite poset containing 5 elements 3. A dictionary of upper covers:: @@ -1350,7 +1350,7 @@ def hasse_diagram(self): [1, 3, 5, 15] sage: H.edges(sort=True) [(1, 3, None), (1, 5, None), (3, 15, None), (5, 15, None)] - sage: H.set_latex_options(format="dot2tex") + sage: H.set_latex_options(format="dot2tex") # optional - sage.plot sage: view(H) # optional - dot2tex, not tested (opens external window) """ G = DiGraph(self._hasse_diagram).relabel(self._list, inplace=False) @@ -1396,8 +1396,8 @@ def _repr_(self): sage: P5._repr_() 'Finite poset containing 7 elements' - sage: M = MeetSemilattice([[1,2],[3],[3]]) - sage: M._repr_() + sage: M = MeetSemilattice([[1,2],[3],[3]]) # optional - sage.modules + sage: M._repr_() # optional - sage.modules 'Finite meet-semilattice containing 3 elements' """ s = "%s containing %s elements" % (self._desc, self._hasse_diagram.order()) @@ -1499,14 +1499,14 @@ def sorted(self, l, allow_incomparable=True, remove_duplicates=False): TESTS:: - sage: P = posets.PentagonPoset() - sage: P.sorted([], allow_incomparable=True, remove_duplicates=True) + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: P.sorted([], allow_incomparable=True, remove_duplicates=True) # optional - sage.modules [] - sage: P.sorted([], allow_incomparable=False, remove_duplicates=True) + sage: P.sorted([], allow_incomparable=False, remove_duplicates=True) # optional - sage.modules [] - sage: P.sorted([], allow_incomparable=True, remove_duplicates=False) + sage: P.sorted([], allow_incomparable=True, remove_duplicates=False) # optional - sage.modules [] - sage: P.sorted([], allow_incomparable=False, remove_duplicates=False) + sage: P.sorted([], allow_incomparable=False, remove_duplicates=False) # optional - sage.modules [] """ v = [self._element_to_vertex(x) for x in l] @@ -1616,7 +1616,7 @@ def linear_extensions(self, facade=False): [1, 2, 3, 4, 6, 12] sage: L.cardinality() 5 - sage: L.list() + sage: L.list() # optional - sage.modules sage.rings.finite_rings [[1, 2, 3, 4, 6, 12], [1, 2, 4, 3, 6, 12], [1, 3, 2, 4, 6, 12], @@ -1630,9 +1630,9 @@ def linear_extensions(self, facade=False): With ``facade=True``, the elements of ``L`` are plain lists instead:: - sage: L = P.linear_extensions(facade=True) - sage: l = L.an_element() - sage: type(l) + sage: L = P.linear_extensions(facade=True) # optional - sage.modules sage.rings.finite_rings + sage: l = L.an_element() # optional - sage.modules sage.rings.finite_rings + sage: type(l) # optional - sage.modules sage.rings.finite_rings <class 'list'> .. WARNING:: @@ -1640,13 +1640,13 @@ def linear_extensions(self, facade=False): In Sage <= 4.8, this function used to return a plain list of lists. To recover the previous functionality, please use:: - sage: L = list(P.linear_extensions(facade=True)); L + sage: L = list(P.linear_extensions(facade=True)); L # optional - sage.modules sage.rings.finite_rings [[1, 2, 3, 4, 6, 12], [1, 2, 4, 3, 6, 12], [1, 3, 2, 4, 6, 12], [1, 3, 2, 6, 4, 12], [1, 2, 3, 6, 4, 12]] - sage: type(L[0]) + sage: type(L[0]) # optional - sage.modules sage.rings.finite_rings <class 'list'> .. SEEALSO:: :meth:`linear_extension`, :meth:`is_linear_extension` @@ -1654,7 +1654,7 @@ def linear_extensions(self, facade=False): TESTS:: sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] }) - sage: list(D.linear_extensions()) + sage: list(D.linear_extensions()) # optional - sage.modules sage.rings.finite_rings [[0, 1, 2, 3, 4], [0, 2, 1, 3, 4], [0, 2, 1, 4, 3], [0, 2, 4, 1, 3], [0, 1, 2, 4, 3]] """ return self._lin_ext_type(self, facade=facade) @@ -1678,19 +1678,19 @@ def spectrum(self, a): EXAMPLES:: sage: P = posets.ChainPoset(5) - sage: P.spectrum(2) + sage: P.spectrum(2) # optional - sage.modules sage.rings.finite_rings [0, 0, 1, 0, 0] sage: P = posets.BooleanLattice(3) - sage: P.spectrum(5) + sage: P.spectrum(5) # optional - sage.modules sage.rings.finite_rings [0, 0, 0, 4, 12, 16, 16, 0] - sage: P = posets.YoungDiagramPoset(Partition([3,2,1])) - sage: P.spectrum((0,1)) + sage: P = posets.YoungDiagramPoset(Partition([3,2,1])) # optional - sage.combinat + sage: P.spectrum((0,1)) # optional - sage.combinat sage.modules sage.rings.finite_rings [0, 8, 6, 2, 0, 0] sage: P = posets.AntichainPoset(4) - sage: P.spectrum(3) + sage: P.spectrum(3) # optional - sage.modules sage.rings.finite_rings [6, 6, 6, 6] TESTS:: @@ -1826,7 +1826,7 @@ def is_linear_extension(self, l) -> bool: [1, 2, 4, 3, 6, 12], [1, 3, 2, 4, 6, 12], [1, 3, 2, 6, 4, 12]] - sage: list(P.linear_extensions()) + sage: list(P.linear_extensions()) # optional - sage.modules sage.rings.finite_rings [[1, 2, 3, 4, 6, 12], [1, 2, 4, 3, 6, 12], [1, 3, 2, 4, 6, 12], @@ -1954,13 +1954,14 @@ def plot(self, label_elements=True, element_labels=None, To emphasize some elements and show some options:: - sage: L = LatticePoset({0: [1, 2, 3, 4], 1: [12], 2: [6, 7], + sage: L = LatticePoset({0: [1, 2, 3, 4], 1: [12], 2: [6, 7], # optional - sage.modules ....: 3: [5, 9], 4: [5, 6, 10, 11], 5: [13], ....: 6: [12], 7: [12, 8, 9], 8: [13], 9: [13], ....: 10: [12], 11: [12], 12: [13]}) - sage: F = L.frattini_sublattice() - sage: F_internal = [c for c in F.cover_relations() if c in L.cover_relations()] - sage: L.plot(figsize=12, border=True, element_shape='s', # optional - sage.plot + sage: F = L.frattini_sublattice() # optional - sage.modules + sage: F_internal = [c for c in F.cover_relations() # optional - sage.modules + ....: if c in L.cover_relations()] + sage: L.plot(figsize=12, border=True, element_shape='s', # optional - sage.modules sage.plot ....: element_size=400, element_color='white', ....: element_colors={'blue': F, 'green': L.double_irreducibles()}, ....: cover_color='lightgray', cover_colors={'black': F_internal}, @@ -1976,21 +1977,21 @@ def plot(self, label_elements=True, element_labels=None, ....: if isinstance(t, sage.plot.text.Text)) sage: P1 = Poset({ 0:[1,2], 1:[3], 2:[3,4] }) sage: P2 = Poset({ 0:[1,2], 1:[3], 2:[3,4] }, facade=True) - sage: get_plot_labels(P1.plot(label_elements=False)) + sage: get_plot_labels(P1.plot(label_elements=False)) # optional - sage.plot [] - sage: get_plot_labels(P1.plot(label_elements=True)) + sage: get_plot_labels(P1.plot(label_elements=True)) # optional - sage.plot ['0', '1', '2', '3', '4'] sage: element_labels = {0:'a', 1:'b', 2:'c', 3:'d', 4:'e'} - sage: get_plot_labels(P1.plot(element_labels=element_labels)) + sage: get_plot_labels(P1.plot(element_labels=element_labels)) # optional - sage.plot ['a', 'b', 'c', 'd', 'e'] - sage: get_plot_labels(P2.plot(element_labels=element_labels)) + sage: get_plot_labels(P2.plot(element_labels=element_labels)) # optional - sage.plot ['a', 'b', 'c', 'd', 'e'] The following checks that :trac:`18936` has been fixed and labels still work:: sage: P = Poset({0: [1,2], 1:[3]}) sage: heights = {1 : [0], 2 : [1], 3 : [2,3]} - sage: P.plot(heights=heights) + sage: P.plot(heights=heights) # optional - sage.plot Graphics object consisting of 8 graphics primitives sage: elem_labels = {0 : 'a', 1 : 'b', 2 : 'c', 3 : 'd'} sage: P.plot(element_labels=elem_labels, heights=heights) # optional - sage.plot @@ -2015,7 +2016,7 @@ def plot(self, label_elements=True, element_labels=None, Plot of the empty poset:: sage: P = Poset({}) - sage: P.plot() + sage: P.plot() # optional - sage.plot Graphics object consisting of 0 graphics primitives """ graph = self.hasse_diagram() @@ -2110,8 +2111,8 @@ def show(self, label_elements=True, element_labels=None, One more example with cover labels:: - sage: P = posets.PentagonPoset() - sage: P.show(cover_labels=lambda a, b: a - b) # optional - sage.plot + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: P.show(cover_labels=lambda a, b: a - b) # optional - sage.modules sage.plot """ # We split the arguments into those meant for plot() and those meant for show() @@ -2286,8 +2287,8 @@ def diamonds(self): sage: P.diamonds() ([(0, 1, 2, 3)], True) - sage: P = posets.YoungDiagramPoset(Partition([3, 2, 2])) - sage: P.diamonds() + sage: P = posets.YoungDiagramPoset(Partition([3, 2, 2])) # optional - sage.combinat + sage: P.diamonds() # optional - sage.combinat ([((0, 0), (0, 1), (1, 0), (1, 1)), ((1, 0), (1, 1), (2, 0), (2, 1))], False) """ diamonds, all_diamonds_completed = self._hasse_diagram.diamonds() @@ -2327,23 +2328,23 @@ def meet(self, x, y): EXAMPLES:: sage: D = Poset({1:[2,3], 2:[4], 3:[4]}) - sage: D.meet(2, 3) + sage: D.meet(2, 3) # optional - sage.modules 1 sage: P = Poset({'a':['b', 'c'], 'b':['e', 'f'], 'c':['f', 'g'], ....: 'd':['f', 'g']}) - sage: P.meet('a', 'b') + sage: P.meet('a', 'b') # optional - sage.modules 'a' - sage: P.meet('e', 'a') + sage: P.meet('e', 'a') # optional - sage.modules 'a' - sage: P.meet('c', 'b') + sage: P.meet('c', 'b') # optional - sage.modules 'a' - sage: P.meet('e', 'f') + sage: P.meet('e', 'f') # optional - sage.modules 'b' - sage: P.meet('e', 'g') + sage: P.meet('e', 'g') # optional - sage.modules 'a' - sage: P.meet('c', 'd') is None + sage: P.meet('c', 'd') is None # optional - sage.modules True - sage: P.meet('g', 'f') is None + sage: P.meet('g', 'f') is None # optional - sage.modules True """ i, j = map(self._element_to_vertex, (x, y)) @@ -2361,23 +2362,23 @@ def join(self, x, y): EXAMPLES:: sage: D = Poset({1:[2,3], 2:[4], 3:[4]}) - sage: D.join(2, 3) + sage: D.join(2, 3) # optional - sage.modules 4 sage: P = Poset({'e':['b'], 'f':['b', 'c', 'd'], 'g':['c', 'd'], ....: 'b':['a'], 'c':['a']}) - sage: P.join('a', 'b') + sage: P.join('a', 'b') # optional - sage.modules 'a' - sage: P.join('e', 'a') + sage: P.join('e', 'a') # optional - sage.modules 'a' - sage: P.join('c', 'b') + sage: P.join('c', 'b') # optional - sage.modules 'a' - sage: P.join('e', 'f') + sage: P.join('e', 'f') # optional - sage.modules 'b' - sage: P.join('e', 'g') + sage: P.join('e', 'g') # optional - sage.modules 'a' - sage: P.join('c', 'd') is None + sage: P.join('c', 'd') is None # optional - sage.modules True - sage: P.join('g', 'f') is None + sage: P.join('g', 'f') is None # optional - sage.modules True """ i, j = map(self._element_to_vertex, (x, y)) @@ -2415,8 +2416,8 @@ def is_d_complete(self) -> bool: sage: D.is_d_complete() False - sage: P = Posets.YoungDiagramPoset(Partition([3, 2, 2]), dual=True) - sage: P.is_d_complete() + sage: P = Posets.YoungDiagramPoset(Partition([3, 2, 2]), dual=True) # optional - sage.combinat + sage: P.is_d_complete() # optional - sage.combinat True """ min_diamond = {} # Maps max of double-tailed diamond to min of double-tailed diamond @@ -2534,8 +2535,8 @@ def intervals_poset(self): sage: P.intervals_poset() Finite poset containing 3 elements - sage: P = posets.PentagonPoset() - sage: P.intervals_poset() + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: P.intervals_poset() # optional - sage.modules Finite lattice containing 13 elements TESTS:: @@ -2598,8 +2599,8 @@ def relations_iterator(self, strict=False): sage: next(it), next(it) ([1, 1], [1, 2]) - sage: P = posets.PentagonPoset() - sage: list(P.relations_iterator(strict=True)) + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: list(P.relations_iterator(strict=True)) # optional - sage.modules [[0, 1], [0, 2], [0, 4], [0, 3], [1, 4], [2, 3], [2, 4], [3, 4]] .. SEEALSO:: @@ -2634,8 +2635,8 @@ def relations_number(self): EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: P.relations_number() + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: P.relations_number() # optional - sage.modules 13 sage: posets.TamariLattice(4).relations_number() @@ -2667,8 +2668,8 @@ def linear_intervals_count(self) -> List[int]: EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: P.linear_intervals_count() + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: P.linear_intervals_count() # optional - sage.modules [5, 5, 2] sage: P = posets.TamariLattice(4) sage: P.linear_intervals_count() @@ -2713,12 +2714,12 @@ def is_linear_interval(self, x, y) -> bool: EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: P.is_linear_interval(0, 4) + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: P.is_linear_interval(0, 4) # optional - sage.modules False - sage: P.is_linear_interval(0, 3) + sage: P.is_linear_interval(0, 3) # optional - sage.modules True - sage: P.is_linear_interval(1, 3) + sage: P.is_linear_interval(1, 3) # optional - sage.modules False """ a = self._element_to_vertex(x) @@ -2748,40 +2749,42 @@ def is_incomparable_chain_free(self, m, n=None) -> bool: EXAMPLES:: sage: B3 = posets.BooleanLattice(3) - sage: B3.is_incomparable_chain_free(1, 3) + sage: B3.is_incomparable_chain_free(1, 3) # optional - sage.modules True - sage: B3.is_incomparable_chain_free(2, 2) + sage: B3.is_incomparable_chain_free(2, 2) # optional - sage.modules False - sage: IP6 = posets.IntegerPartitions(6) - sage: IP6.is_incomparable_chain_free(1, 3) + sage: IP6 = posets.IntegerPartitions(6) # optional - sage.combinat + sage: IP6.is_incomparable_chain_free(1, 3) # optional - sage.combinat sage.modules False - sage: IP6.is_incomparable_chain_free(2, 2) + sage: IP6.is_incomparable_chain_free(2, 2) # optional - sage.combinat sage.modules True A list of pairs as an argument:: - sage: B3.is_incomparable_chain_free([[1, 3], [2, 2]]) + sage: B3.is_incomparable_chain_free([[1, 3], [2, 2]]) # optional - sage.modules False We show how to get an incomparable chain pair:: - sage: P = posets.PentagonPoset() - sage: chains_1_2 = Poset({0:[], 1:[2]}) - sage: incomps = P.isomorphic_subposets(chains_1_2)[0] - sage: sorted(incomps.list()), incomps.cover_relations() + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: chains_1_2 = Poset({0:[], 1:[2]}) # optional - sage.modules + sage: incomps = P.isomorphic_subposets(chains_1_2)[0] # optional - sage.modules + sage: sorted(incomps.list()), incomps.cover_relations() # optional - sage.modules ([1, 2, 3], [[2, 3]]) TESTS:: - sage: Poset().is_incomparable_chain_free(1,1) # Test empty poset + sage: Poset().is_incomparable_chain_free(1,1) # Test empty poset # optional - sage.modules True - sage: [len([p for p in Posets(n) if p.is_incomparable_chain_free(((3, 1), (2, 2)))]) for n in range(6)] # long time + sage: [len([p for p in Posets(n) # long time # optional - sage.modules + ....: if p.is_incomparable_chain_free(((3, 1), (2, 2)))]) + ....: for n in range(6)] [1, 1, 2, 5, 14, 42] sage: Q = Poset({0:[2], 1:[2], 2:[3], 3:[4], 4:[]}) - sage: Q.is_incomparable_chain_free(2, 20/10) + sage: Q.is_incomparable_chain_free(2, 20/10) # optional - sage.modules True sage: Q.is_incomparable_chain_free(2, pi) # optional - sage.symbolic Traceback (most recent call last): @@ -2800,9 +2803,9 @@ def is_incomparable_chain_free(self, m, n=None) -> bool: Traceback (most recent call last): ... TypeError: [3, 1] and [2, 2] must be integers - sage: P.is_incomparable_chain_free([[3, 1], [2, 2]]) + sage: P.is_incomparable_chain_free([[3, 1], [2, 2]]) # optional - sage.modules True - sage: P.is_incomparable_chain_free(([3, 1], [2, 2])) + sage: P.is_incomparable_chain_free(([3, 1], [2, 2])) # optional - sage.modules True sage: P.is_incomparable_chain_free([3, 1], 2) Traceback (most recent call last): @@ -3137,7 +3140,7 @@ def height(self, certificate=False): sage: P = Poset({0: [1], 2: [3, 4], 4: [5, 6]}) sage: P.height() 3 - sage: posets.PentagonPoset().height(certificate=True) + sage: posets.PentagonPoset().height(certificate=True) # optional - sage.modules (4, [0, 2, 3, 4]) TESTS:: @@ -3183,14 +3186,14 @@ def has_isomorphic_subposet(self, other): sage: D = Poset({1:[2,3], 2:[4], 3:[4]}) sage: T = Poset({1:[2,3], 2:[4,5], 3:[6,7]}) - sage: N5 = posets.PentagonPoset() + sage: N5 = posets.PentagonPoset() # optional - sage.modules - sage: N5.has_isomorphic_subposet(T) + sage: N5.has_isomorphic_subposet(T) # optional - sage.modules False - sage: N5.has_isomorphic_subposet(D) + sage: N5.has_isomorphic_subposet(D) # optional - sage.modules True - sage: len([P for P in Posets(5) if P.has_isomorphic_subposet(D)]) + sage: len([P for P in Posets(5) if P.has_isomorphic_subposet(D)]) # optional - sage.modules 11 """ @@ -3338,17 +3341,17 @@ def is_antichain_of_poset(self, elms): TESTS:: - sage: P = posets.PentagonPoset() - sage: P.is_antichain_of_poset([]) + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: P.is_antichain_of_poset([]) # optional - sage.modules True - sage: P.is_antichain_of_poset([0]) + sage: P.is_antichain_of_poset([0]) # optional - sage.modules True - sage: P.is_antichain_of_poset([1, 2, 1]) + sage: P.is_antichain_of_poset([1, 2, 1]) # optional - sage.modules True Check :trac:`19078`:: - sage: P.is_antichain_of_poset([0, 1, 'junk']) + sage: P.is_antichain_of_poset([0, 1, 'junk']) # optional - sage.modules Traceback (most recent call last): ... ValueError: element (=junk) not in poset @@ -3701,17 +3704,17 @@ def magnitude(self) -> Integer: EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: P.magnitude() + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: P.magnitude() # optional - sage.libs.flint sage.modules 1 - sage: W = SymmetricGroup(4) - sage: P = W.noncrossing_partition_lattice().without_bounds() - sage: P.magnitude() + sage: W = SymmetricGroup(4) # optional - sage.groups + sage: P = W.noncrossing_partition_lattice().without_bounds() # optional - sage.groups + sage: P.magnitude() # optional - sage.groups sage.libs.flint sage.modules -4 sage: P = posets.TamariLattice(4).without_bounds() - sage: P.magnitude() + sage: P.magnitude() # optional - sage.libs.flint sage.modules 0 .. SEEALSO:: :meth:`order_complex` @@ -3720,18 +3723,18 @@ def magnitude(self) -> Integer: sage: P1 = posets.RandomPoset(20, 0.05) sage: P2 = posets.RandomPoset(20, 0.05) - sage: m1 = P1.magnitude() - sage: m2 = P2.magnitude() + sage: m1 = P1.magnitude() # optional - sage.libs.flint sage.modules + sage: m2 = P2.magnitude() # optional - sage.libs.flint sage.modules sage: U = P1.disjoint_union(P2) sage: P = P1.product(P2) - sage: U.magnitude() == m1 + m2 + sage: U.magnitude() == m1 + m2 # optional - sage.libs.flint sage.modules True - sage: P.magnitude() == m1*m2 + sage: P.magnitude() == m1*m2 # optional - sage.libs.flint sage.modules True - sage: Poset({}).magnitude() + sage: Poset({}).magnitude() # optional - sage.libs.flint sage.modules 0 - sage: Poset({1:[]}).magnitude() + sage: Poset({1:[]}).magnitude() # optional - sage.libs.flint sage.modules 1 """ H = self._hasse_diagram @@ -3862,10 +3865,10 @@ def is_jump_critical(self, certificate=False): sage: P.is_jump_critical() True - sage: P = posets.PentagonPoset() - sage: P.is_jump_critical() + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: P.is_jump_critical() # optional - sage.modules False - sage: P.is_jump_critical(certificate=True) + sage: P.is_jump_critical(certificate=True) # optional - sage.modules (False, 3) .. SEEALSO:: :meth:`jump_number` @@ -4024,8 +4027,8 @@ def is_graded(self) -> bool: EXAMPLES:: - sage: P = posets.PentagonPoset() # Not even ranked - sage: P.is_graded() + sage: P = posets.PentagonPoset() # Not even ranked # optional - sage.modules + sage: P.is_graded() # optional - sage.modules False sage: P = Poset({1:[2, 3], 3:[4]}) # Ranked, but not graded @@ -4214,20 +4217,20 @@ def moebius_function_matrix(self, ring=ZZ, sparse=False): sage: x,y = (P.linear_extension()[0],P.linear_extension()[1]) sage: P.moebius_function(x,y) -1 - sage: M = P.moebius_function_matrix(); M + sage: M = P.moebius_function_matrix(); M # optional - sage.libs.flint sage.modules [ 1 -1 -1 -1 2] [ 0 1 0 0 -1] [ 0 0 1 0 -1] [ 0 0 0 1 -1] [ 0 0 0 0 1] - sage: M[0,4] + sage: M[0,4] # optional - sage.libs.flint sage.modules 2 - sage: M[0,1] + sage: M[0,1] # optional - sage.libs.flint sage.modules -1 We now demonstrate the usage of the optional parameters:: - sage: P.moebius_function_matrix(ring=QQ, sparse=False).parent() + sage: P.moebius_function_matrix(ring=QQ, sparse=False).parent() # optional - sage.libs.flint sage.modules Full MatrixSpace of 5 by 5 dense matrices over Rational Field """ M = self._hasse_diagram.moebius_function_matrix() @@ -4251,8 +4254,8 @@ def lequal_matrix(self, ring=ZZ, sparse=False): EXAMPLES:: - sage: P = Poset([[1,3,2],[4],[4,5,6],[6],[7],[7],[7],[]], facade = False) - sage: LEQM = P.lequal_matrix(); LEQM + sage: P = Poset([[1,3,2],[4],[4,5,6],[6],[7],[7],[7],[]], facade=False) + sage: LEQM = P.lequal_matrix(); LEQM # optional - sage.modules [1 1 1 1 1 1 1 1] [0 1 0 1 0 0 0 1] [0 0 1 1 1 0 1 1] @@ -4261,18 +4264,18 @@ def lequal_matrix(self, ring=ZZ, sparse=False): [0 0 0 0 0 1 1 1] [0 0 0 0 0 0 1 1] [0 0 0 0 0 0 0 1] - sage: LEQM[1,3] + sage: LEQM[1,3] # optional - sage.modules 1 sage: P.linear_extension()[1] < P.linear_extension()[3] True - sage: LEQM[2,5] + sage: LEQM[2,5] # optional - sage.modules 0 sage: P.linear_extension()[2] < P.linear_extension()[5] False We now demonstrate the usage of the optional parameters:: - sage: P.lequal_matrix(ring=QQ, sparse=False).parent() + sage: P.lequal_matrix(ring=QQ, sparse=False).parent() # optional - sage.libs.flint sage.modules Full MatrixSpace of 8 by 8 dense matrices over Rational Field """ M = self._hasse_diagram.lequal_matrix(boolean=False) @@ -4298,7 +4301,7 @@ def coxeter_transformation(self): EXAMPLES:: - sage: posets.PentagonPoset().coxeter_transformation() + sage: posets.PentagonPoset().coxeter_transformation() # optional - sage.modules [ 0 0 0 0 -1] [ 0 0 0 1 -1] [ 0 1 0 0 -1] @@ -4311,8 +4314,8 @@ def coxeter_transformation(self): TESTS:: - sage: M = posets.PentagonPoset().coxeter_transformation() - sage: M ** 8 == 1 + sage: M = posets.PentagonPoset().coxeter_transformation() # optional - sage.modules + sage: M ** 8 == 1 # optional - sage.modules True """ return self._hasse_diagram.coxeter_transformation() @@ -4331,12 +4334,12 @@ def coxeter_polynomial(self): EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: P.coxeter_polynomial() + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: P.coxeter_polynomial() # optional - sage.modules x^5 + x^4 + x + 1 - sage: p = posets.SymmetricGroupWeakOrderPoset(3) - sage: p.coxeter_polynomial() + sage: p = posets.SymmetricGroupWeakOrderPoset(3) # optional - sage.groups + sage: p.coxeter_polynomial() # optional - sage.groups sage.modules x^6 + x^5 - x^3 + x + 1 .. SEEALSO:: @@ -4371,28 +4374,28 @@ def coxeter_smith_form(self, algorithm='singular'): EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: P.coxeter_smith_form() + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: P.coxeter_smith_form() # optional - sage.modules sage.libs.singular [1, 1, 1, 1, x^5 + x^4 + x + 1] sage: P = posets.DiamondPoset(7) - sage: prod(P.coxeter_smith_form()) == P.coxeter_polynomial() + sage: prod(P.coxeter_smith_form()) == P.coxeter_polynomial() # optional - sage.modules sage.libs.singular True TESTS:: - sage: P = posets.PentagonPoset() - sage: P.coxeter_smith_form(algorithm='sage') + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: P.coxeter_smith_form(algorithm='sage') # optional - sage.modules [1, 1, 1, 1, x^5 + x^4 + x + 1] - sage: P.coxeter_smith_form(algorithm='gap') + sage: P.coxeter_smith_form(algorithm='gap') # optional - sage.libs.gap sage.modules [1, 1, 1, 1, x^5 + x^4 + x + 1] - sage: P.coxeter_smith_form(algorithm='pari') + sage: P.coxeter_smith_form(algorithm='pari') # optional - sage.libs.pari sage.modules [1, 1, 1, 1, x^5 + x^4 + x + 1] - sage: P.coxeter_smith_form(algorithm='fricas') # optional - fricas + sage: P.coxeter_smith_form(algorithm='fricas') # optional - fricas # optional - sage.modules [1, 1, 1, 1, x^5 + x^4 + x + 1] - sage: P.coxeter_smith_form(algorithm='maple') # optional - maple + sage: P.coxeter_smith_form(algorithm='maple') # optional - maple # optional - sage.modules [1, 1, 1, 1, x^5 + x^4 + x + 1] - sage: P.coxeter_smith_form(algorithm='magma') # optional - magma + sage: P.coxeter_smith_form(algorithm='magma') # optional - magma # optional - sage.modules [1, 1, 1, 1, x^5 + x^4 + x + 1] .. SEEALSO:: @@ -4468,15 +4471,15 @@ def is_meet_semilattice(self, certificate=False): EXAMPLES:: sage: P = Poset({1:[2, 3, 4], 2:[5, 6], 3:[6], 4:[6, 7]}) - sage: P.is_meet_semilattice() + sage: P.is_meet_semilattice() # optional - sage.modules True sage: Q = P.dual() - sage: Q.is_meet_semilattice() + sage: Q.is_meet_semilattice() # optional - sage.modules False - sage: V = posets.IntegerPartitions(5) - sage: V.is_meet_semilattice(certificate=True) + sage: V = posets.IntegerPartitions(5) # optional - sage.combinat + sage: V.is_meet_semilattice(certificate=True) # optional - sage.combinat sage.modules (False, ((2, 2, 1), (3, 1, 1))) .. SEEALSO:: @@ -4486,13 +4489,13 @@ def is_meet_semilattice(self, certificate=False): TESTS:: - sage: Poset().is_meet_semilattice() # Test empty lattice + sage: Poset().is_meet_semilattice() # Test empty lattice # optional - sage.modules True - sage: len([P for P in Posets(4) if P.is_meet_semilattice()]) + sage: len([P for P in Posets(4) if P.is_meet_semilattice()]) # optional - sage.modules 5 sage: P = Poset({1: [2], 3: []}) - sage: P.is_meet_semilattice(certificate=True) + sage: P.is_meet_semilattice(certificate=True) # optional - sage.modules (False, (3, 1)) """ from sage.combinat.posets.hasse_diagram import LatticeError @@ -4541,13 +4544,13 @@ def is_join_semilattice(self, certificate=False): EXAMPLES:: sage: P = Poset([[1,3,2], [4], [4,5,6], [6], [7], [7], [7], []]) - sage: P.is_join_semilattice() + sage: P.is_join_semilattice() # optional - sage.modules True sage: P = Poset({1:[3, 4], 2:[3, 4], 3:[5], 4:[5]}) - sage: P.is_join_semilattice() + sage: P.is_join_semilattice() # optional - sage.modules False - sage: P.is_join_semilattice(certificate=True) + sage: P.is_join_semilattice(certificate=True) # optional - sage.modules (False, (2, 1)) .. SEEALSO:: @@ -4557,13 +4560,13 @@ def is_join_semilattice(self, certificate=False): TESTS:: - sage: Poset().is_join_semilattice() # Test empty lattice + sage: Poset().is_join_semilattice() # Test empty lattice # optional - sage.modules True - sage: len([P for P in Posets(4) if P.is_join_semilattice()]) + sage: len([P for P in Posets(4) if P.is_join_semilattice()]) # optional - sage.modules 5 sage: X = Poset({1: [3], 2: [3], 3: [4, 5]}) - sage: X.is_join_semilattice(certificate=True) + sage: X.is_join_semilattice(certificate=True) # optional - sage.modules (False, (5, 4)) """ from sage.combinat.posets.hasse_diagram import LatticeError @@ -4631,8 +4634,8 @@ def isomorphic_subposets_iterator(self, other): EXAMPLES:: sage: D = Poset({1:[2,3], 2:[4], 3:[4]}) - sage: N5 = posets.PentagonPoset() - sage: for P in N5.isomorphic_subposets_iterator(D): + sage: N5 = posets.PentagonPoset() # optional - sage.modules + sage: for P in N5.isomorphic_subposets_iterator(D): # optional - sage.modules ....: print(P.cover_relations()) [[0, 1], [0, 2], [1, 4], [2, 4]] [[0, 1], [0, 3], [1, 4], [3, 4]] @@ -4671,15 +4674,15 @@ def isomorphic_subposets(self, other): sage: C2 = Poset({0:[1]}) sage: C3 = Poset({'a':['b'], 'b':['c']}) - sage: L = sorted(x.cover_relations() for x in C3.isomorphic_subposets(C2)) - sage: for x in L: print(x) + sage: L = sorted(x.cover_relations() for x in C3.isomorphic_subposets(C2)) # optional - sage.modules + sage: for x in L: print(x) # optional - sage.modules [['a', 'b']] [['a', 'c']] [['b', 'c']] sage: D = Poset({1:[2,3], 2:[4], 3:[4]}) - sage: N5 = posets.PentagonPoset() - sage: len(N5.isomorphic_subposets(D)) + sage: N5 = posets.PentagonPoset() # optional - sage.modules + sage: len(N5.isomorphic_subposets(D)) # optional - sage.modules 2 .. NOTE:: @@ -4716,19 +4719,19 @@ def antichains(self, element_constructor=type([])): EXAMPLES:: - sage: A = posets.PentagonPoset().antichains(); A + sage: A = posets.PentagonPoset().antichains(); A # optional - sage.modules Set of antichains of Finite lattice containing 5 elements - sage: list(A) + sage: list(A) # optional - sage.modules [[], [0], [1], [1, 2], [1, 3], [2], [3], [4]] - sage: A.cardinality() + sage: A.cardinality() # optional - sage.modules 8 - sage: A[3] + sage: A[3] # optional - sage.modules [1, 2] To get the antichains as, say, sets, one may use the ``element_constructor`` option:: - sage: list(posets.ChainPoset(3).antichains(element_constructor=set)) + sage: list(posets.ChainPoset(3).antichains(element_constructor=set)) # optional - sage.modules [set(), {0}, {1}, {2}] To get the antichains of a given size one can currently use:: @@ -4771,9 +4774,9 @@ def antichains_iterator(self): EXAMPLES:: - sage: it = posets.PentagonPoset().antichains_iterator(); it + sage: it = posets.PentagonPoset().antichains_iterator(); it # optional - sage.modules <generator object ...antichains_iterator at ...> - sage: next(it), next(it) + sage: next(it), next(it) # optional - sage.modules ([], [4]) .. SEEALSO:: :meth:`antichains` @@ -4925,10 +4928,12 @@ def chains(self, element_constructor=type([]), exclude=None): EXAMPLES:: - sage: C = posets.PentagonPoset().chains(); C + sage: C = posets.PentagonPoset().chains(); C # optional - sage.modules Set of chains of Finite lattice containing 5 elements - sage: list(C) - [[], [0], [0, 1], [0, 1, 4], [0, 2], [0, 2, 3], [0, 2, 3, 4], [0, 2, 4], [0, 3], [0, 3, 4], [0, 4], [1], [1, 4], [2], [2, 3], [2, 3, 4], [2, 4], [3], [3, 4], [4]] + sage: list(C) # optional - sage.modules + [[], [0], [0, 1], [0, 1, 4], [0, 2], [0, 2, 3], [0, 2, 3, 4], [0, 2, 4], + [0, 3], [0, 3, 4], [0, 4], [1], [1, 4], [2], [2, 3], [2, 3, 4], [2, 4], + [3], [3, 4], [4]] Exclusion of elements, tuple (instead of list) as constructor:: @@ -4938,12 +4943,12 @@ def chains(self, element_constructor=type([]), exclude=None): To get the chains of a given size one can currently use:: - sage: list(C.elements_of_depth_iterator(2)) + sage: list(C.elements_of_depth_iterator(2)) # optional - sage.modules [[0, 1], [0, 2], [0, 3], [0, 4], [1, 4], [2, 3], [2, 4], [3, 4]] Eventually the following syntax will be accepted:: - sage: C.subset(size = 2) # todo: not implemented + sage: C.subset(size = 2) # todo: not implemented # optional - sage.modules .. SEEALSO:: :meth:`maximal_chains`, :meth:`antichains` """ @@ -5107,23 +5112,23 @@ def product(self, other): sage: P = posets.ChainPoset(3) sage: Q = posets.ChainPoset(4) - sage: PQ = P.product(Q) ; PQ + sage: PQ = P.product(Q) ; PQ # optional - sage.modules Finite lattice containing 12 elements - sage: len(PQ.cover_relations()) + sage: len(PQ.cover_relations()) # optional - sage.modules 17 - sage: Q.product(P).is_isomorphic(PQ) + sage: Q.product(P).is_isomorphic(PQ) # optional - sage.modules True sage: P = posets.BooleanLattice(2) - sage: Q = P.product(P) - sage: Q.is_isomorphic(posets.BooleanLattice(4)) + sage: Q = P.product(P) # optional - sage.modules + sage: Q.is_isomorphic(posets.BooleanLattice(4)) # optional - sage.modules True One can also simply use `*`:: sage: P = posets.ChainPoset(2) sage: Q = posets.ChainPoset(3) - sage: P*Q + sage: P*Q # optional - sage.modules Finite lattice containing 6 elements .. SEEALSO:: @@ -5132,15 +5137,15 @@ def product(self, other): TESTS:: - sage: Poset({0: [1]}).product(Poset()) # Product with empty poset + sage: Poset({0: [1]}).product(Poset()) # Product with empty poset # optional - sage.modules Finite poset containing 0 elements - sage: Poset().product(Poset()) # Product of two empty poset + sage: Poset().product(Poset()) # Product of two empty poset # optional - sage.modules Finite poset containing 0 elements We check that :trac:`19113` is fixed:: - sage: L = LatticePoset({1: []}) - sage: type(L) == type(L.product(L)) + sage: L = LatticePoset({1: []}) # optional - sage.modules + sage: type(L) == type(L.product(L)) # optional - sage.modules True """ from sage.combinat.posets.lattices import LatticePoset, \ @@ -5230,9 +5235,9 @@ def factor(self): EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: Q = P*P - sage: Q.factor() + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: Q = P*P # optional - sage.modules + sage: Q.factor() # optional - sage.modules [Finite poset containing 5 elements, Finite poset containing 5 elements] @@ -5240,12 +5245,12 @@ def factor(self): sage: P2 = posets.ChainPoset(7) sage: P1.factor() [Finite lattice containing 3 elements] - sage: (P1 * P2).factor() + sage: (P1 * P2).factor() # optional - sage.modules [Finite poset containing 7 elements, Finite poset containing 3 elements] sage: P = posets.TamariLattice(4) - sage: (P*P).factor() + sage: (P*P).factor() # optional - sage.modules [Finite poset containing 14 elements, Finite poset containing 14 elements] @@ -5367,9 +5372,9 @@ def disjoint_union(self, other, labels='pairs'): sage: P.cover_relations() [[2, 3], [0, 1]] - sage: N5 = posets.PentagonPoset(); N5 + sage: N5 = posets.PentagonPoset(); N5 # optional - sage.modules Finite lattice containing 5 elements - sage: N5.disjoint_union(N5) # Union of lattices is not a lattice + sage: N5.disjoint_union(N5) # Union of lattices is not a lattice # optional - sage.modules Finite poset containing 10 elements We show how to get literally direct sum with elements untouched:: @@ -5382,9 +5387,9 @@ def disjoint_union(self, other, labels='pairs'): TESTS:: - sage: N5 = posets.PentagonPoset() + sage: N5 = posets.PentagonPoset() # optional - sage.modules sage: P0 = Poset() - sage: N5.disjoint_union(P0).is_isomorphic(N5) + sage: N5.disjoint_union(P0).is_isomorphic(N5) # optional - sage.modules True sage: P0.disjoint_union(P0) Finite poset containing 0 elements @@ -5446,11 +5451,11 @@ def ordinal_product(self, other, labels='pairs'): ... ValueError: labels must be either 'pairs' or 'integers' - sage: N5 = posets.PentagonPoset() + sage: N5 = posets.PentagonPoset() # optional - sage.modules sage: P0 = Poset() - sage: N5.ordinal_product(P0) == P0 + sage: N5.ordinal_product(P0) == P0 # optional - sage.modules True - sage: P0.ordinal_product(N5) == P0 + sage: P0.ordinal_product(N5) == P0 # optional - sage.modules True sage: P0.ordinal_product(P0) == P0 True @@ -5464,7 +5469,7 @@ def ordinal_product(self, other, labels='pairs'): sage: C3 = posets.ChainPoset(3) sage: C4 = posets.ChainPoset(4) sage: C12 = posets.ChainPoset(12) - sage: C3.ordinal_product(C4).is_isomorphic(C12) + sage: C3.ordinal_product(C4).is_isomorphic(C12) # optional - sage.modules True """ from sage.combinat.posets.lattices import LatticePoset, \ @@ -5541,15 +5546,15 @@ def ordinal_sum(self, other, labels='pairs'): sage: P = Poset({1:[2]}); P Finite poset containing 2 elements - sage: JL = JoinSemilattice({1:[2]}); JL + sage: JL = JoinSemilattice({1:[2]}); JL # optional - sage.modules Finite join-semilattice containing 2 elements - sage: L = LatticePoset({1:[2]}); L + sage: L = LatticePoset({1:[2]}); L # optional - sage.modules Finite lattice containing 2 elements - sage: P.ordinal_sum(L) + sage: P.ordinal_sum(L) # optional - sage.modules Finite poset containing 4 elements - sage: L.ordinal_sum(JL) + sage: L.ordinal_sum(JL) # optional - sage.modules Finite join-semilattice containing 4 elements - sage: L.ordinal_sum(L) + sage: L.ordinal_sum(L) # optional - sage.modules Finite lattice containing 4 elements .. SEEALSO:: @@ -5559,11 +5564,11 @@ def ordinal_sum(self, other, labels='pairs'): TESTS:: - sage: N5 = posets.PentagonPoset() + sage: N5 = posets.PentagonPoset() # optional - sage.modules sage: P0 = LatticePoset({}) - sage: N5.ordinal_sum(P0).is_isomorphic(N5) + sage: N5.ordinal_sum(P0).is_isomorphic(N5) # optional - sage.modules True - sage: P0.ordinal_sum(P0) + sage: P0.ordinal_sum(P0) # optional - sage.modules Finite lattice containing 0 elements """ from sage.combinat.posets.lattices import LatticePoset, \ @@ -5630,7 +5635,7 @@ def star_product(self, other, labels='pairs'): sage: B3 = posets.BooleanLattice(3) sage: P = B2.star_product(B3); P Finite poset containing 10 elements - sage: P.is_eulerian() + sage: P.is_eulerian() # optional - sage.libs.flint sage.modules True We can get elements as pairs or as integers:: @@ -5721,10 +5726,11 @@ def lexicographic_sum(self, P): EXAMPLES:: sage: N = Poset({1: [3, 4], 2: [4]}) - sage: P = {1: posets.PentagonPoset(), 2: N, 3: posets.ChainPoset(3), 4: posets.AntichainPoset(4)} - sage: NP = N.lexicographic_sum(P); NP + sage: P = {1: posets.PentagonPoset(), 2: N, # optional - sage.modules + ....: 3: posets.ChainPoset(3), 4: posets.AntichainPoset(4)} + sage: NP = N.lexicographic_sum(P); NP # optional - sage.modules Finite poset containing 16 elements - sage: sorted(NP.minimal_elements()) + sage: sorted(NP.minimal_elements()) # optional - sage.modules [(1, 0), (2, 1), (2, 2)] TESTS:: @@ -5807,10 +5813,10 @@ def dual(self): join-semilattice and vice versa. Also the dual of a (non-)facade poset is again (non-)facade:: - sage: V = MeetSemilattice({1: [2, 3]}, facade=False) - sage: A = V.dual(); A + sage: V = MeetSemilattice({1: [2, 3]}, facade=False) # optional - sage.modules + sage: A = V.dual(); A # optional - sage.modules Finite join-semilattice containing 3 elements - sage: A(2) < A(1) + sage: A(2) < A(1) # optional - sage.modules True .. SEEALSO:: :meth:`~sage.categories.finite_posets.FinitePosets.ParentMethods.is_self_dual` @@ -5863,12 +5869,12 @@ def with_bounds(self, labels=('bottom', 'top')): sage: Y.cover_relations() [[-1, 0], [0, 1], [0, 2]] - sage: P = posets.PentagonPoset() # A lattice - sage: P.with_bounds() + sage: P = posets.PentagonPoset() # A lattice # optional - sage.modules + sage: P.with_bounds() # optional - sage.modules Finite lattice containing 7 elements - sage: P = posets.PentagonPoset(facade=False) - sage: P.with_bounds() + sage: P = posets.PentagonPoset(facade=False) # optional - sage.modules + sage: P.with_bounds() # optional - sage.modules Finite lattice containing 7 elements .. SEEALSO:: @@ -5881,58 +5887,58 @@ def with_bounds(self, labels=('bottom', 'top')): sage: P.cover_relations() [['bottom', 'top']] - sage: L = LatticePoset({}).with_bounds(); L + sage: L = LatticePoset({}).with_bounds(); L # optional - sage.modules Finite lattice containing 2 elements - sage: L.meet_irreducibles() # Issue 21543 + sage: L.meet_irreducibles() # Issue 21543 # optional - sage.modules ['bottom'] sage: Poset().with_bounds((None, 1)) Finite poset containing 1 elements - sage: LatticePoset().with_bounds((None, 1)) + sage: LatticePoset().with_bounds((None, 1)) # optional - sage.modules Finite lattice containing 1 elements - sage: MeetSemilattice().with_bounds((None, 1)) + sage: MeetSemilattice().with_bounds((None, 1)) # optional - sage.modules Finite lattice containing 1 elements - sage: JoinSemilattice().with_bounds((None, 1)) + sage: JoinSemilattice().with_bounds((None, 1)) # optional - sage.modules Finite join-semilattice containing 1 elements sage: Poset().with_bounds((1, None)) Finite poset containing 1 elements - sage: LatticePoset().with_bounds((1, None)) + sage: LatticePoset().with_bounds((1, None)) # optional - sage.modules Finite lattice containing 1 elements - sage: MeetSemilattice().with_bounds((1, None)) + sage: MeetSemilattice().with_bounds((1, None)) # optional - sage.modules Finite meet-semilattice containing 1 elements - sage: JoinSemilattice().with_bounds((1, None)) + sage: JoinSemilattice().with_bounds((1, None)) # optional - sage.modules Finite lattice containing 1 elements sage: P = Poset({0: []}) - sage: L = LatticePoset({0: []}) - sage: ML = MeetSemilattice({0: []}) - sage: JL = JoinSemilattice({0: []}) + sage: L = LatticePoset({0: []}) # optional - sage.modules + sage: ML = MeetSemilattice({0: []}) # optional - sage.modules + sage: JL = JoinSemilattice({0: []}) # optional - sage.modules sage: P.with_bounds((None, None)) Finite poset containing 1 elements - sage: L.with_bounds((None, None)) + sage: L.with_bounds((None, None)) # optional - sage.modules Finite lattice containing 1 elements - sage: ML.with_bounds((None, None)) + sage: ML.with_bounds((None, None)) # optional - sage.modules Finite meet-semilattice containing 1 elements - sage: JL.with_bounds((None, None)) + sage: JL.with_bounds((None, None)) # optional - sage.modules Finite join-semilattice containing 1 elements sage: P.with_bounds((1, None)) Finite poset containing 2 elements - sage: L.with_bounds((1, None)) + sage: L.with_bounds((1, None)) # optional - sage.modules Finite lattice containing 2 elements - sage: ML.with_bounds((1, None)) + sage: ML.with_bounds((1, None)) # optional - sage.modules Finite meet-semilattice containing 2 elements - sage: JL.with_bounds((1, None)) + sage: JL.with_bounds((1, None)) # optional - sage.modules Finite lattice containing 2 elements sage: P.with_bounds((None, 1)) Finite poset containing 2 elements - sage: L.with_bounds((None, 1)) + sage: L.with_bounds((None, 1)) # optional - sage.modules Finite lattice containing 2 elements - sage: ML.with_bounds((None, 1)) + sage: ML.with_bounds((None, 1)) # optional - sage.modules Finite lattice containing 2 elements - sage: JL.with_bounds((None, 1)) + sage: JL.with_bounds((None, 1)) # optional - sage.modules Finite join-semilattice containing 2 elements - sage: posets.PentagonPoset().with_bounds(labels=(4, 5)) + sage: posets.PentagonPoset().with_bounds(labels=(4, 5)) # optional - sage.modules Traceback (most recent call last): ... ValueError: the poset already has element 4 @@ -5991,10 +5997,10 @@ def without_bounds(self): EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: Q = P.without_bounds(); Q + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: Q = P.without_bounds(); Q # optional - sage.modules Finite poset containing 3 elements - sage: Q.cover_relations() + sage: Q.cover_relations() # optional - sage.modules [[2, 3]] sage: P = posets.DiamondPoset(5) @@ -6086,27 +6092,27 @@ def relabel(self, relabeling=None): Relabeling using a list:: - sage: P = posets.PentagonPoset() - sage: list(P) + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: list(P) # optional - sage.modules [0, 1, 2, 3, 4] - sage: P.cover_relations() + sage: P.cover_relations() # optional - sage.modules [[0, 1], [0, 2], [1, 4], [2, 3], [3, 4]] - sage: Q = P.relabel(list('abcde')) - sage: Q.cover_relations() + sage: Q = P.relabel(list('abcde')) # optional - sage.modules + sage: Q.cover_relations() # optional - sage.modules [['a', 'b'], ['a', 'c'], ['b', 'e'], ['c', 'd'], ['d', 'e']] Default behaviour is increasing relabeling:: sage: a2 = posets.ChainPoset(2) - sage: P = a2 * a2 - sage: Q = P.relabel() - sage: Q.cover_relations() + sage: P = a2 * a2 # optional - sage.modules + sage: Q = P.relabel() # optional - sage.modules + sage: Q.cover_relations() # optional - sage.modules [[0, 1], [0, 2], [1, 3], [2, 3]] Relabeling a (semi)lattice gives a (semi)lattice:: - sage: P = JoinSemilattice({0: [1]}) - sage: P.relabel(lambda n: n+1) + sage: P = JoinSemilattice({0: [1]}) # optional - sage.modules + sage: P.relabel(lambda n: n+1) # optional - sage.modules Finite join-semilattice containing 2 elements .. NOTE:: @@ -6207,10 +6213,10 @@ def canonical_label(self, algorithm=None): sage: D = DiGraph({'a':['b','c']}) sage: P = Poset(D) - sage: ML = MeetSemilattice(D) + sage: ML = MeetSemilattice(D) # optional - sage.modules sage: P.canonical_label() Finite poset containing 3 elements - sage: ML.canonical_label() + sage: ML.canonical_label() # optional - sage.modules Finite meet-semilattice containing 3 elements .. SEEALSO:: @@ -6287,8 +6293,8 @@ def with_linear_extension(self, linear_extension): (Semi)lattice remains (semi)lattice with new linear extension:: - sage: L = LatticePoset(P) - sage: Q = L.with_linear_extension([1,3,2,6,4,12]); Q + sage: L = LatticePoset(P) # optional - sage.modules + sage: Q = L.with_linear_extension([1,3,2,6,4,12]); Q # optional - sage.modules Finite lattice containing 6 elements with distinguished linear extension .. NOTE:: @@ -6348,9 +6354,9 @@ def subposet(self, elements): A subposet of a non-facade poset is again a non-facade poset:: - sage: P = posets.PentagonPoset(facade=False) - sage: Q = P.subposet([0, 1, 2, 4]) - sage: Q(1) < Q(2) + sage: P = posets.PentagonPoset(facade=False) # optional - sage.modules + sage: Q = P.subposet([0, 1, 2, 4]) # optional - sage.modules + sage: Q(1) < Q(2) # optional - sage.modules False TESTS:: @@ -6407,8 +6413,8 @@ def random_subposet(self, p): TESTS:: - sage: P = posets.IntegerPartitions(4) - sage: P.random_subposet(1) == P + sage: P = posets.IntegerPartitions(4) # optional - sage.combinat + sage: P.random_subposet(1) == P # optional - sage.combinat True """ from sage.misc.randstate import current_randstate @@ -6899,25 +6905,25 @@ def linear_extensions_graph(self): EXAMPLES:: sage: N = Poset({1: [3, 4], 2: [4]}) - sage: G = N.linear_extensions_graph(); G + sage: G = N.linear_extensions_graph(); G # optional - sage.modules Graph on 5 vertices - sage: G.neighbors(N.linear_extension([1,2,3,4])) + sage: G.neighbors(N.linear_extension([1,2,3,4])) # optional - sage.modules [[2, 1, 3, 4], [1, 3, 2, 4], [1, 2, 4, 3]] sage: chevron = Poset({1: [2, 6], 2: [3], 4: [3, 5], 6: [5]}) - sage: G = chevron.linear_extensions_graph(); G + sage: G = chevron.linear_extensions_graph(); G # optional - sage.modules Graph on 22 vertices - sage: G.size() + sage: G.size() # optional - sage.modules 36 TESTS:: - sage: Poset().linear_extensions_graph() + sage: Poset().linear_extensions_graph() # optional - sage.modules Graph on 1 vertex sage: A4 = posets.AntichainPoset(4) - sage: G = A4.linear_extensions_graph() - sage: G.is_regular() + sage: G = A4.linear_extensions_graph() # optional - sage.modules + sage: G.is_regular() # optional - sage.modules True """ from sage.graphs.graph import Graph @@ -6946,7 +6952,7 @@ def maximal_antichains(self): sage: [sorted(anti) for anti in P.maximal_antichains()] [['a'], ['b', 'c'], ['c', 'd', 'e']] - sage: posets.PentagonPoset().maximal_antichains() + sage: posets.PentagonPoset().maximal_antichains() # optional - sage.modules [[0], [1, 2], [1, 3], [4]] .. SEEALSO:: :meth:`antichains`, :meth:`maximal_chains` @@ -7081,10 +7087,10 @@ def order_complex(self, on_ints=False): Simplicial complex with vertex set (0, 1, 2, 3, 4, 5, 6, 7) and 6 facets sage: S.f_vector() [1, 8, 19, 18, 6] - sage: S.homology() # S is contractible + sage: S.homology() # S is contractible # optional - sage.modules {0: 0, 1: 0, 2: 0, 3: 0} sage: Q = P.subposet([1,2,3,4,5,6]) - sage: Q.order_complex().homology() # a circle + sage: Q.order_complex().homology() # a circle # optional - sage.modules {0: 0, 1: Z} sage: P = Poset((divisors(15), attrcall("divides")), facade = True) @@ -7138,17 +7144,17 @@ def order_polytope(self): EXAMPLES:: sage: P = posets.AntichainPoset(3) - sage: Q = P.order_polytope();Q + sage: Q = P.order_polytope(); Q # optional - sage.geometry.polyhedron A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices - sage: P = posets.PentagonPoset() - sage: Q = P.order_polytope();Q + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: Q = P.order_polytope(); Q # optional - sage.modules sage.geometry.polyhedron A 5-dimensional polyhedron in ZZ^5 defined as the convex hull of 8 vertices sage: P = Poset([[1,2,3],[[1,2],[1,3]]]) - sage: Q = P.order_polytope() - sage: Q.contains((1,0,0)) + sage: Q = P.order_polytope() # optional - sage.geometry.polyhedron + sage: Q.contains((1,0,0)) # optional - sage.geometry.polyhedron False - sage: Q.contains((0,1,1)) + sage: Q.contains((0,1,1)) # optional - sage.geometry.polyhedron True """ from sage.geometry.polyhedron.constructor import Polyhedron @@ -7184,10 +7190,10 @@ def chain_polytope(self): EXAMPLES:: sage: P = posets.AntichainPoset(3) - sage: Q = P.chain_polytope();Q + sage: Q = P.chain_polytope();Q # optional - sage.geometry.polyhedron A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices - sage: P = posets.PentagonPoset() - sage: Q = P.chain_polytope();Q + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: Q = P.chain_polytope();Q # optional - sage.modules sage.geometry.polyhedron A 5-dimensional polyhedron in ZZ^5 defined as the convex hull of 8 vertices """ from sage.geometry.polyhedron.constructor import Polyhedron @@ -7228,8 +7234,8 @@ def zeta_polynomial(self): sage: posets.ChainPoset(3).zeta_polynomial() 1/2*q^2 + 1/2*q - sage: P = posets.PentagonPoset() - sage: P.zeta_polynomial() + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: P.zeta_polynomial() # optional - sage.modules 1/6*q^3 + q^2 - 1/6*q sage: P = posets.DiamondPoset(5) @@ -7280,13 +7286,13 @@ def M_triangle(self): EXAMPLES:: sage: P = posets.DiamondPoset(5) - sage: P.M_triangle() + sage: P.M_triangle() # optional - sage.combinat M: x^2*y^2 - 3*x*y^2 + 3*x*y + 2*y^2 - 3*y + 1 TESTS:: - sage: P = posets.PentagonPoset() - sage: P.M_triangle() + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: P.M_triangle() # optional - sage.combinat sage.modules Traceback (most recent call last): ... ValueError: the poset is not graded @@ -7392,8 +7398,8 @@ def h_polynomial(self): EXAMPLES:: - sage: P = posets.AntichainPoset(3).order_ideals_lattice() - sage: P.h_polynomial() + sage: P = posets.AntichainPoset(3).order_ideals_lattice() # optional - sage.modules + sage: P.h_polynomial() # optional - sage.modules q^3 + 4*q^2 + q sage: P = posets.DiamondPoset(5) sage: P.h_polynomial() @@ -7693,13 +7699,13 @@ def order_polynomial(self): EXAMPLES:: sage: P = posets.AntichainPoset(3) - sage: P.order_polynomial() + sage: P.order_polynomial() # optional - sage.modules sage.rings.finite_rings q^3 sage: P = posets.ChainPoset(3) - sage: f = P.order_polynomial(); f + sage: f = P.order_polynomial(); f # optional - sage.modules sage.rings.finite_rings 1/6*q^3 + 1/2*q^2 + 1/3*q - sage: [f(i) for i in range(4)] + sage: [f(i) for i in range(4)] # optional - sage.modules sage.rings.finite_rings [0, 1, 4, 10] .. SEEALSO:: :meth:`order_polytope` @@ -7725,8 +7731,8 @@ def degree_polynomial(self): EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: P.degree_polynomial() + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: P.degree_polynomial() # optional - sage.modules x^2 + 3*x*y + y^2 sage: P = posets.BooleanLattice(4) @@ -7968,17 +7974,17 @@ def is_slender(self, certificate=False): sage: P.is_slender() False - sage: W = WeylGroup(['A', 2]) - sage: G = W.bruhat_poset() - sage: G.is_slender() + sage: W = WeylGroup(['A', 2]) # optional - sage.groups + sage: G = W.bruhat_poset() # optional - sage.groups + sage: G.is_slender() # optional - sage.groups True - sage: W = WeylGroup(['A', 3]) - sage: G = W.bruhat_poset() - sage: G.is_slender() + sage: W = WeylGroup(['A', 3]) # optional - sage.groups + sage: G = W.bruhat_poset() # optional - sage.groups + sage: G.is_slender() # optional - sage.groups True - sage: P = posets.IntegerPartitions(6) - sage: P.is_slender(certificate=True) + sage: P = posets.IntegerPartitions(6) # optional - sage.combinat + sage: P.is_slender(certificate=True) # optional - sage.combinat (False, ((6,), (3, 2, 1))) TESTS:: @@ -8022,7 +8028,7 @@ def is_sperner(self): EXAMPLES:: - sage: posets.SetPartitions(3).is_sperner() + sage: posets.SetPartitions(3).is_sperner() # optional - sage.combinat True sage: P = Poset({0:[3,4,5],1:[5],2:[5]}) @@ -8031,7 +8037,7 @@ def is_sperner(self): TESTS:: - sage: posets.PentagonPoset().is_sperner() + sage: posets.PentagonPoset().is_sperner() # optional - sage.modules Traceback (most recent call last): ... ValueError: the poset is not ranked @@ -8078,33 +8084,33 @@ def is_eulerian(self, k=None, certificate=False): sage: P = Poset({0: [1, 2, 3], 1: [4, 5], 2: [4, 6], 3: [5, 6], ....: 4: [7, 8], 5: [7, 8], 6: [7, 8], 7: [9], 8: [9]}) - sage: P.is_eulerian() + sage: P.is_eulerian() # optional - sage.modules sage.rings.finite_rings True sage: P = Poset({0: [1, 2, 3], 1: [4, 5, 6], 2: [4, 6], 3: [5,6], ....: 4: [7], 5:[7], 6:[7]}) - sage: P.is_eulerian() + sage: P.is_eulerian() # optional - sage.modules sage.rings.finite_rings False Canonical examples of Eulerian posets are the face lattices of convex polytopes:: - sage: P = polytopes.cube().face_lattice() - sage: P.is_eulerian() + sage: P = polytopes.cube().face_lattice() # optional - sage.geometry.polyhedron + sage: P.is_eulerian() # optional - sage.geometry.polyhedron sage.rings.finite_rings True A poset that is 3- but not 4-eulerian:: sage: P = Poset(DiGraph('MWW@_?W?@_?W??@??O@_?W?@_?W?@??O??')); P Finite poset containing 14 elements - sage: P.is_eulerian(k=3) + sage: P.is_eulerian(k=3) # optional - sage.modules True - sage: P.is_eulerian(k=4) + sage: P.is_eulerian(k=4) # optional - sage.modules False Getting an interval that is not Eulerian:: sage: P = posets.DivisorLattice(12) - sage: P.is_eulerian(certificate=True) + sage: P.is_eulerian(certificate=True) # optional - sage.modules (False, (1, 4)) TESTS:: @@ -8114,15 +8120,15 @@ def is_eulerian(self, k=None, certificate=False): ... ValueError: the poset is not bounded - sage: Poset({1: []}).is_eulerian() + sage: Poset({1: []}).is_eulerian() # optional - sage.modules True - sage: posets.PentagonPoset().is_eulerian() + sage: posets.PentagonPoset().is_eulerian() # optional - sage.modules Traceback (most recent call last): ... ValueError: the poset is not graded - sage: posets.BooleanLattice(3).is_eulerian(k=123, certificate=True) + sage: posets.BooleanLattice(3).is_eulerian(k=123, certificate=True) # optional - sage.modules (True, None) """ if k is not None: @@ -8368,17 +8374,18 @@ def greene_shape(self): EXAMPLES:: - sage: P = Poset([[3,2,1],[[3,1],[2,1]]]) - sage: P.greene_shape() + sage: P = Poset([[3,2,1], [[3,1],[2,1]]]) + sage: P.greene_shape() # optional - sage.combinat [2, 1] - sage: P = Poset([[1,2,3,4],[[1,4],[2,4],[4,3]]]) - sage: P.greene_shape() + sage: P = Poset([[1,2,3,4], [[1,4],[2,4],[4,3]]]) + sage: P.greene_shape() # optional - sage.combinat [3, 1] - sage: P = Poset([[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22],[[1,4],[2,4],[4,3]]]) - sage: P.greene_shape() + sage: P = Poset([[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22], + ....: [[1,4],[2,4],[4,3]]]) + sage: P.greene_shape() # optional - sage.combinat [3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] sage: P = Poset([[],[]]) - sage: P.greene_shape() + sage: P.greene_shape() # optional - sage.combinat [] AUTHOR: @@ -8461,34 +8468,42 @@ def p_partition_enumerator(self, tup, R, weights=None, check=False): EXAMPLES:: sage: P = Poset([[1,2,3,4],[[1,4],[2,4],[4,3]]]) - sage: FP = P.p_partition_enumerator((3,1,2,4), QQ, check=True); FP + sage: FP = P.p_partition_enumerator((3,1,2,4), QQ, check=True); FP # optional - sage.combinat 2*M[1, 1, 1, 1] + 2*M[1, 2, 1] + M[2, 1, 1] + M[3, 1] - sage: expansion = FP.expand(5) - sage: xs = expansion.parent().gens() - sage: expansion == sum([xs[a]*xs[b]*xs[c]*xs[d] for a in range(5) for b in range(5) for c in range(5) for d in range(5) if a <= b and c <= b and b < d]) + sage: expansion = FP.expand(5) # optional - sage.combinat + sage: xs = expansion.parent().gens() # optional - sage.combinat + sage: expansion == sum(xs[a]*xs[b]*xs[c]*xs[d] # optional - sage.combinat + ....: for a in range(5) for b in range(5) + ....: for c in range(5) for d in range(5) + ....: if a <= b and c <= b and b < d) True sage: P = Poset([[],[]]) - sage: FP = P.p_partition_enumerator((), QQ, check=True); FP + sage: FP = P.p_partition_enumerator((), QQ, check=True); FP # optional - sage.combinat M[] With the ``weights`` parameter:: sage: P = Poset([[1,2,3,4],[[1,4],[2,4],[4,3]]]) - sage: FP = P.p_partition_enumerator((3,1,2,4), QQ, weights={1: 1, 2: 2, 3: 1, 4: 1}, check=True); FP + sage: FP = P.p_partition_enumerator((3,1,2,4), QQ, # optional - sage.combinat + ....: weights={1: 1, 2: 2, 3: 1, 4: 1}, check=True); FP M[1, 2, 1, 1] + M[1, 3, 1] + M[2, 1, 1, 1] + M[2, 2, 1] + M[3, 1, 1] + M[4, 1] - sage: FP = P.p_partition_enumerator((3,1,2,4), QQ, weights={2: 2}, check=True); FP + sage: FP = P.p_partition_enumerator((3,1,2,4), QQ, # optional - sage.combinat + ....: weights={2: 2}, check=True); FP M[1, 2, 1, 1] + M[1, 3, 1] + M[2, 1, 1, 1] + M[2, 2, 1] + M[3, 1, 1] + M[4, 1] sage: P = Poset([['a','b','c'], [['a','b'], ['a','c']]]) - sage: FP = P.p_partition_enumerator(('b','c','a'), QQ, weights={'a': 3, 'b': 5, 'c': 7}, check=True); FP + sage: FP = P.p_partition_enumerator(('b','c','a'), QQ, # optional - sage.combinat + ....: weights={'a': 3, 'b': 5, 'c': 7}, check=True); FP M[3, 5, 7] + M[3, 7, 5] + M[3, 12] sage: P = Poset([['a','b','c'], [['a','c'], ['b','c']]]) - sage: FP = P.p_partition_enumerator(('b','c','a'), QQ, weights={'a': 3, 'b': 5, 'c': 7}, check=True); FP + sage: FP = P.p_partition_enumerator(('b','c','a'), QQ, # optional - sage.combinat + ....: weights={'a': 3, 'b': 5, 'c': 7}, check=True); FP M[3, 5, 7] + M[3, 12] + M[5, 3, 7] + M[8, 7] - sage: FP = P.p_partition_enumerator(('a','b','c'), QQ, weights={'a': 3, 'b': 5, 'c': 7}, check=True); FP + sage: FP = P.p_partition_enumerator(('a','b','c'), QQ, # optional - sage.combinat + ....: weights={'a': 3, 'b': 5, 'c': 7}, check=True); FP M[3, 5, 7] + M[3, 12] + M[5, 3, 7] + M[5, 10] + M[8, 7] + M[15] """ if check: @@ -8570,18 +8585,18 @@ def completion_by_cuts(self): EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: P.completion_by_cuts().is_isomorphic(P) + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: P.completion_by_cuts().is_isomorphic(P) # optional - sage.modules True sage: Y = Poset({1: [2], 2: [3, 4]}) - sage: trafficsign = LatticePoset({1: [2], 2: [3, 4], 3: [5], 4: [5]}) - sage: L = Y.completion_by_cuts() - sage: L.is_isomorphic(trafficsign) + sage: trafficsign = LatticePoset({1: [2], 2: [3, 4], 3: [5], 4: [5]}) # optional - sage.modules + sage: L = Y.completion_by_cuts() # optional - sage.modules + sage: L.is_isomorphic(trafficsign) # optional - sage.modules True sage: P = posets.SymmetricGroupBruhatOrderPoset(3) - sage: Q = P.completion_by_cuts(); Q + sage: Q = P.completion_by_cuts(); Q # optional - sage.modules Finite lattice containing 7 elements .. SEEALSO:: @@ -8610,7 +8625,7 @@ def incidence_algebra(self, R, prefix='I'): EXAMPLES:: sage: P = posets.BooleanLattice(4) - sage: P.incidence_algebra(QQ) + sage: P.incidence_algebra(QQ) # optional - sage.modules Incidence algebra of Finite lattice containing 16 elements over Rational Field """ @@ -8834,8 +8849,8 @@ def _macaulay2_init_(self, macaulay2=None): EXAMPLES:: - sage: P = posets.PentagonPoset() - sage: P._macaulay2_init_() + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: P._macaulay2_init_() # optional - sage.modules 'needsPackage "Posets";poset({0,1,2,3,4},{{0,1},{0,2},{1,4},{2,3},{3,4}})' sage: P = Poset({1:[2],2:[]}) @@ -8904,9 +8919,9 @@ def __contains__(self, P): """ EXAMPLES:: - sage: posets.PentagonPoset() in Posets(5) + sage: posets.PentagonPoset() in Posets(5) # optional - sage.modules True - sage: posets.PentagonPoset() in Posets(3) + sage: posets.PentagonPoset() in Posets(3) # optional - sage.modules False sage: 1 in Posets(3) False diff --git a/src/sage/combinat/quickref.py b/src/sage/combinat/quickref.py index ea2aba8915a..351563cec6c 100644 --- a/src/sage/combinat/quickref.py +++ b/src/sage/combinat/quickref.py @@ -46,7 +46,7 @@ sage: points = random_matrix(ZZ, 6, 3, x=7).rows() sage: L = LatticePolytope(points) - sage: L.npoints(); L.plot3d() # random + sage: L.npoints(); L.plot3d() # random # optional - sage.plot :ref:`Root systems, Coxeter and Weyl groups <sage.combinat.root_system.all>`:: diff --git a/src/sage/combinat/rooted_tree.py b/src/sage/combinat/rooted_tree.py index abb96594d2a..e8a44b1b163 100644 --- a/src/sage/combinat/rooted_tree.py +++ b/src/sage/combinat/rooted_tree.py @@ -625,14 +625,14 @@ class RootedTrees_size(RootedTrees): TESTS:: sage: from sage.combinat.rooted_tree import RootedTrees_size - sage: for i in range(1, 6): TestSuite(RootedTrees_size(i)).run() + sage: for i in range(1, 6): TestSuite(RootedTrees_size(i)).run() # optional - sage.combinat """ def __init__(self, n): """ TESTS:: - sage: for i in range(1, 6): + sage: for i in range(1, 6): # optional - sage.combinat ....: TestSuite(RootedTrees(i)).run() """ super().__init__(category=FiniteEnumeratedSets()) @@ -663,7 +663,7 @@ def _an_element_(self): """ TESTS:: - sage: RootedTrees(4).an_element() # indirect doctest + sage: RootedTrees(4).an_element() # indirect doctest # optional - sage.combinat [[[[]]]] """ return self.first() @@ -681,11 +681,11 @@ def __iter__(self): sage: from sage.combinat.rooted_tree import * sage: RootedTrees(1).list() [[]] - sage: RootedTrees(2).list() + sage: RootedTrees(2).list() # optional - sage.combinat [[[]]] - sage: RootedTrees(3).list() + sage: RootedTrees(3).list() # optional - sage.combinat [[[[]]], [[], []]] - sage: RootedTrees(4).list() + sage: RootedTrees(4).list() # optional - sage.combinat [[[[[]]]], [[[], []]], [[], [[]]], [[], [], []]] """ if self._n == 1: @@ -757,7 +757,7 @@ def element_class(self): sage: S = RootedTrees(3) sage: S.element_class <class 'sage.combinat.rooted_tree.RootedTrees_all_with_category.element_class'> - sage: S.first().__class__ == RootedTrees().first().__class__ + sage: S.first().__class__ == RootedTrees().first().__class__ # optional - sage.combinat True """ return self._parent_for.element_class diff --git a/src/sage/combinat/skew_partition.py b/src/sage/combinat/skew_partition.py index dd66961a807..a16e0ceaf75 100644 --- a/src/sage/combinat/skew_partition.py +++ b/src/sage/combinat/skew_partition.py @@ -1068,18 +1068,18 @@ def to_dag(self, format="string"): EXAMPLES:: - sage: dag = SkewPartition([[3, 3, 1], [1, 1]]).to_dag() - sage: dag.edges(sort=True) + sage: dag = SkewPartition([[3, 3, 1], [1, 1]]).to_dag() # optional - sage.graphs + sage: dag.edges(sort=True) # optional - sage.graphs [('0,1', '0,2', None), ('0,1', '1,1', None), ('0,2', '1,2', None), ('1,1', '1,2', None)] - sage: dag.vertices(sort=True) + sage: dag.vertices(sort=True) # optional - sage.graphs ['0,1', '0,2', '1,1', '1,2', '2,0'] - sage: dag = SkewPartition([[3, 2, 1], [1, 1]]).to_dag(format="tuple") - sage: dag.edges(sort=True) + sage: dag = SkewPartition([[3, 2, 1], [1, 1]]).to_dag(format="tuple") # optional - sage.graphs + sage: dag.edges(sort=True) # optional - sage.graphs [((0, 1), (0, 2), None), ((0, 1), (1, 1), None)] - sage: dag.vertices(sort=True) + sage: dag.vertices(sort=True) # optional - sage.graphs [(0, 1), (0, 2), (1, 1), (2, 0)] """ outer = list(self.outer()) diff --git a/src/sage/combinat/skew_tableau.py b/src/sage/combinat/skew_tableau.py index e7269bc7ce7..fdb5f030790 100644 --- a/src/sage/combinat/skew_tableau.py +++ b/src/sage/combinat/skew_tableau.py @@ -1950,7 +1950,7 @@ class StandardSkewTableaux(SkewTableaux): sage: S = StandardSkewTableaux(2); S Standard skew tableaux of size 2 - sage: S.cardinality() + sage: S.cardinality() # optional - sage.modules 4 :: @@ -2015,7 +2015,7 @@ def __init__(self): EXAMPLES:: sage: s = StandardSkewTableaux() - sage: TestSuite(s).run() + sage: TestSuite(s).run() # optional - sage.graphs """ StandardSkewTableaux.__init__(self, category=InfiniteEnumeratedSets()) @@ -2037,7 +2037,7 @@ def __iter__(self): EXAMPLES:: sage: it = StandardSkewTableaux().__iter__() - sage: [next(it) for x in range(10)] + sage: [next(it) for x in range(10)] # optional - sage.graphs [[], [[1]], [[1, 2]], [[1], [2]], [[None, 2], [1]], [[None, 1], [2]], @@ -2060,7 +2060,7 @@ def __init__(self, n): EXAMPLES:: sage: S = StandardSkewTableaux(3) - sage: TestSuite(S).run() + sage: TestSuite(S).run() # optional - sage.graphs """ self.n = n StandardSkewTableaux.__init__(self, category=FiniteEnumeratedSets()) @@ -2078,13 +2078,13 @@ def cardinality(self): """ EXAMPLES:: - sage: StandardSkewTableaux(1).cardinality() + sage: StandardSkewTableaux(1).cardinality() # optional - sage.modules 1 - sage: StandardSkewTableaux(2).cardinality() + sage: StandardSkewTableaux(2).cardinality() # optional - sage.modules 4 - sage: StandardSkewTableaux(3).cardinality() + sage: StandardSkewTableaux(3).cardinality() # optional - sage.modules 24 - sage: StandardSkewTableaux(4).cardinality() + sage: StandardSkewTableaux(4).cardinality() # optional - sage.modules 194 """ count = 0 @@ -2101,10 +2101,10 @@ def __iter__(self): EXAMPLES:: - sage: StandardSkewTableaux(2).list() + sage: StandardSkewTableaux(2).list() # optional - sage.graphs [[[1, 2]], [[1], [2]], [[None, 2], [1]], [[None, 1], [2]]] - sage: StandardSkewTableaux(3).list() + sage: StandardSkewTableaux(3).list() # optional - sage.graphs [[[1, 2, 3]], [[1, 2], [3]], [[1, 3], [2]], [[None, 2, 3], [1]], [[None, 1, 2], [3]], [[None, 1, 3], [2]], @@ -2149,7 +2149,7 @@ def __init__(self, skp): TESTS:: sage: S = StandardSkewTableaux([[3, 2, 1], [1, 1]]) - sage: TestSuite(S).run() + sage: TestSuite(S).run() # optional - sage.graphs sage.modules """ self.skp = skp StandardSkewTableaux.__init__(self, category=FiniteEnumeratedSets()) @@ -2173,7 +2173,7 @@ def cardinality(self): EXAMPLES:: - sage: StandardSkewTableaux([[3, 2, 1], [1, 1]]).cardinality() + sage: StandardSkewTableaux([[3, 2, 1], [1, 1]]).cardinality() # optional - sage.modules 8 """ outer, inner = self.skp @@ -2200,7 +2200,7 @@ def __iter__(self): EXAMPLES:: - sage: StandardSkewTableaux([[3, 2, 1], [1, 1]]).list() + sage: StandardSkewTableaux([[3, 2, 1], [1, 1]]).list() # optional - sage.graphs [[[None, 2, 3], [None, 4], [1]], [[None, 1, 2], [None, 3], [4]], [[None, 1, 2], [None, 4], [3]], diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 9d63ce27691..e7f7c8ee978 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -16,18 +16,18 @@ TESTS:: sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() + sage: p = SymmetricFunctions(QQ).power() # optional - sage.modules sage: CIS = CycleIndexSeriesRing(QQ) - sage: geo1 = CIS(lambda i: p([1])^i) - sage: geo2 = CIS(lambda i: p([2])^(i // 2) if is_even(i) else 0) - sage: s = geo1 * geo2 - sage: s[0] + sage: geo1 = CIS(lambda i: p([1])^i) # optional - sage.modules + sage: geo2 = CIS(lambda i: p([2])^(i // 2) if is_even(i) else 0) # optional - sage.modules + sage: s = geo1 * geo2 # optional - sage.modules + sage: s[0] # optional - sage.modules p[] - sage: s[1] + sage: s[1] # optional - sage.modules p[1] - sage: s[2] + sage: s[2] # optional - sage.modules p[1, 1] + p[2] - sage: s[3] + sage: s[3] # optional - sage.modules p[1, 1, 1] + p[2, 1] REFERENCES: @@ -292,14 +292,14 @@ def count(self, t): EXAMPLES:: sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() + sage: p = SymmetricFunctions(QQ).power() # optional - sage.modules sage: CIS = CycleIndexSeriesRing(QQ) - sage: f = CIS([0, p([1]), 2*p([1,1]), 3*p([2,1])]) - sage: f.count([1]) + sage: f = CIS([0, p([1]), 2*p([1,1]), 3*p([2,1])]) # optional - sage.modules + sage: f.count([1]) # optional - sage.modules 1 - sage: f.count([1,1]) + sage: f.count([1,1]) # optional - sage.modules 4 - sage: f.count([2,1]) + sage: f.count([2,1]) # optional - sage.modules 6 """ t = Partition(t) @@ -312,14 +312,14 @@ def coefficient_cycle_type(self, t): EXAMPLES:: sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: p = SymmetricFunctions(QQ).power() + sage: p = SymmetricFunctions(QQ).power() # optional - sage.modules sage: CIS = CycleIndexSeriesRing(QQ) - sage: f = CIS([0, p([1]), 2*p([1,1]),3*p([2,1])]) - sage: f.coefficient_cycle_type([1]) + sage: f = CIS([0, p([1]), 2*p([1,1]),3*p([2,1])]) # optional - sage.modules + sage: f.coefficient_cycle_type([1]) # optional - sage.modules 1 - sage: f.coefficient_cycle_type([1,1]) + sage: f.coefficient_cycle_type([1,1]) # optional - sage.modules 2 - sage: f.coefficient_cycle_type([2,1]) + sage: f.coefficient_cycle_type([2,1]) # optional - sage.modules 3 """ t = Partition(t) @@ -535,10 +535,10 @@ class CycleIndexSeriesRing(LazySymmetricFunctions): EXAMPLES:: sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: R = CycleIndexSeriesRing(QQ); R + sage: R = CycleIndexSeriesRing(QQ); R # optional - sage.modules Cycle Index Series Ring over Rational Field - sage: p = SymmetricFunctions(QQ).p() - sage: R(lambda n: p[n]) + sage: p = SymmetricFunctions(QQ).p() # optional - sage.modules + sage: R(lambda n: p[n]) # optional - sage.modules p[] + p[1] + p[2] + p[3] + p[4] + p[5] + p[6] + O^7 TESTS: @@ -558,8 +558,8 @@ def __init__(self, base_ring, sparse=True): sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing sage: CycleIndexSeriesRing.options.halting_precision(12) - sage: R = CycleIndexSeriesRing(QQ) - sage: TestSuite(R).run() + sage: R = CycleIndexSeriesRing(QQ) # optional - sage.modules + sage: TestSuite(R).run() # optional - sage.modules sage: CycleIndexSeriesRing.options._reset() # reset options """ @@ -573,7 +573,7 @@ def _repr_(self): EXAMPLES:: sage: from sage.combinat.species.generating_series import CycleIndexSeriesRing - sage: CycleIndexSeriesRing(QQ) + sage: CycleIndexSeriesRing(QQ) # optional - sage.modules Cycle Index Series Ring over Rational Field """ return "Cycle Index Series Ring over %s" % self.base_ring() @@ -588,7 +588,7 @@ def _exp_term(n, R=QQ): EXAMPLES:: sage: from sage.combinat.species.generating_series import _exp_term - sage: [_exp_term(i) for i in range(4)] + sage: [_exp_term(i) for i in range(4)] # optional - sage.modules [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3]] """ p = SymmetricFunctions(R).power() @@ -610,7 +610,7 @@ def ExponentialCycleIndexSeries(R=QQ): EXAMPLES:: sage: from sage.combinat.species.generating_series import ExponentialCycleIndexSeries - sage: ExponentialCycleIndexSeries()[:5] + sage: ExponentialCycleIndexSeries()[:5] # optional - sage.modules [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3], 1/24*p[1, 1, 1, 1] + 1/4*p[2, 1, 1] + 1/8*p[2, 2] + 1/3*p[3, 1] + 1/4*p[4]] @@ -629,7 +629,7 @@ def _cl_term(n, R=QQ): EXAMPLES:: sage: from sage.combinat.species.generating_series import _cl_term - sage: [_cl_term(i) for i in range(4)] + sage: [_cl_term(i) for i in range(4)] # optional - sage.modules [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] """ n = Integer(n) # check that n is an integer @@ -661,7 +661,7 @@ def LogarithmCycleIndexSeries(R=QQ): its cycle index has negative coefficients:: sage: from sage.combinat.species.generating_series import LogarithmCycleIndexSeries - sage: LogarithmCycleIndexSeries()[0:4] + sage: LogarithmCycleIndexSeries()[0:4] # optional - sage.modules [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] Its defining property is that `\Omega \circ E^{+} = E^{+} \circ \Omega = X` @@ -669,7 +669,7 @@ def LogarithmCycleIndexSeries(R=QQ): multiplicative identity `X`):: sage: Eplus = sage.combinat.species.set_species.SetSpecies(min=1).cycle_index_series() - sage: LogarithmCycleIndexSeries()(Eplus)[0:4] + sage: LogarithmCycleIndexSeries()(Eplus)[0:4] # optional - sage.modules [0, p[1], 0, 0] """ CIS = CycleIndexSeriesRing(R) diff --git a/src/sage/combinat/subsets_hereditary.py b/src/sage/combinat/subsets_hereditary.py index 68fe53e98ea..3ff251a2394 100644 --- a/src/sage/combinat/subsets_hereditary.py +++ b/src/sage/combinat/subsets_hereditary.py @@ -73,22 +73,22 @@ def subsets_with_hereditary_property(f,X,max_obstruction_size=None,ncpus=1): number of calls to `f` from 91 to 56:: sage: num_calls = 0 - sage: g = graphs.PetersenGraph() + sage: g = graphs.PetersenGraph() # optional - sage.graphs sage: def is_independent_set(S): ....: global num_calls ....: num_calls += 1 ....: return g.subgraph(S).size() == 0 - sage: l1 = list(subsets_with_hereditary_property(is_independent_set, + sage: l1 = list(subsets_with_hereditary_property(is_independent_set, # optional - sage.graphs ....: g.vertices(sort=False))) - sage: num_calls + sage: num_calls # optional - sage.graphs 91 sage: num_calls = 0 - sage: l2 = list(subsets_with_hereditary_property(is_independent_set, + sage: l2 = list(subsets_with_hereditary_property(is_independent_set, # optional - sage.graphs ....: g.vertices(sort=False), ....: max_obstruction_size=2)) - sage: num_calls + sage: num_calls # optional - sage.graphs 56 - sage: l1 == l2 + sage: l1 == l2 # optional - sage.graphs True TESTS:: diff --git a/src/sage/combinat/subword_complex.py b/src/sage/combinat/subword_complex.py index b5455260aaa..b7489bdf754 100644 --- a/src/sage/combinat/subword_complex.py +++ b/src/sage/combinat/subword_complex.py @@ -83,13 +83,13 @@ sage: W = CoxeterGroup(['A',3]); I = list(W.index_set()) sage: Q = I + W.w0.coxeter_sorting_word(I) sage: S = SubwordComplex(Q,W.w0) - sage: S.brick_polytope() + sage: S.brick_polytope() # optional - sage.geometry.polyhedron A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 14 vertices sage: W = CoxeterGroup(['H',3]); I = list(W.index_set()) sage: Q = I + W.w0.coxeter_sorting_word(I) sage: S = SubwordComplex(Q,W.w0) - sage: S.brick_polytope() + sage: S.brick_polytope() # optional - sage.geometry.polyhedron doctest:...: RuntimeWarning: the polytope is built with rational vertices A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 32 vertices @@ -754,20 +754,20 @@ def plot(self, list_colors=None, labels=[], thickness=3, fontsize=14, sage: W = ReflectionGroup(['A',2]) # optional - gap3 sage: w = W.from_reduced_word([1,2,1]) # optional - gap3 sage: SC = SubwordComplex([1,2,1,2,1],w) # optional - gap3 - sage: F = SC([1,2]); F.plot() # optional - gap3 + sage: F = SC([1,2]); F.plot() # optional - gap3 sage.plot Graphics object consisting of 26 graphics primitives sage: W = CoxeterGroup(['A',2]) sage: w = W.from_reduced_word([1,2,1]) sage: SC = SubwordComplex([1,2,1,2,1],w) - sage: F = SC([1,2]); F.plot() + sage: F = SC([1,2]); F.plot() # optional - sage.plot Graphics object consisting of 26 graphics primitives sage: W = ReflectionGroup(['B',3]) # optional - gap3 sage: c = W.from_reduced_word([1,2,3]) # optional - gap3 sage: Q = c.reduced_word()*2 + W.w0.coxeter_sorting_word(c) # optional - gap3 sage: SC = SubwordComplex(Q, W.w0) # optional - gap3 - sage: F = SC[15]; F.plot() # optional - gap3 + sage: F = SC[15]; F.plot() # optional - gap3 sage.plot Graphics object consisting of 53 graphics primitives TESTS:: @@ -776,7 +776,7 @@ def plot(self, list_colors=None, labels=[], thickness=3, fontsize=14, sage: c = W.from_reduced_word([1,2,3,4]) # optional - gap3 sage: Q = c.reduced_word() + W.w0.coxeter_sorting_word(c) # optional - gap3 sage: SC = SubwordComplex(Q, W.w0) # optional - gap3 - sage: F = SC[1]; F.plot() # optional - gap3 + sage: F = SC[1]; F.plot() # optional - gap3 sage.plot Traceback (most recent call last): ... ValueError: plotting is currently only implemented for irreducibles types A, B, and C. @@ -785,7 +785,7 @@ def plot(self, list_colors=None, labels=[], thickness=3, fontsize=14, sage: c = W.from_reduced_word([1,2,3,4]) sage: Q = c.reduced_word() + W.w0.coxeter_sorting_word(c) sage: SC = SubwordComplex(Q, W.w0) - sage: F = SC[1]; F.plot() + sage: F = SC[1]; F.plot() # optional - sage.plot Traceback (most recent call last): ... ValueError: plotting is currently only implemented for irreducibles types A, B, and C. diff --git a/src/sage/combinat/symmetric_group_algebra.py b/src/sage/combinat/symmetric_group_algebra.py index ef328aff704..3884747f825 100644 --- a/src/sage/combinat/symmetric_group_algebra.py +++ b/src/sage/combinat/symmetric_group_algebra.py @@ -1,3 +1,4 @@ +# optional - sage.combinat sage.modules sage.groups r""" Symmetric Group Algebra """ diff --git a/src/sage/combinat/symmetric_group_representations.py b/src/sage/combinat/symmetric_group_representations.py index 23f310b89ea..5799fa03bcc 100644 --- a/src/sage/combinat/symmetric_group_representations.py +++ b/src/sage/combinat/symmetric_group_representations.py @@ -815,7 +815,7 @@ def _repr_(self): EXAMPLES:: sage: from sage.combinat.symmetric_group_representations import YoungRepresentations_Orthogonal - sage: YoungRepresentations_Orthogonal(3) + sage: YoungRepresentations_Orthogonal(3) # optional - sage.symbolic Orthogonal representations of the symmetric group of order 3! over Symbolic Ring """ return "Orthogonal representations of the symmetric group of order %s! over %s" % (self._n, self._ring) diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 719f2260608..ed500a32c3c 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -1129,19 +1129,19 @@ def to_sign_matrix(self, max_entry=None): EXAMPLES:: sage: t = SemistandardTableau([[1,1,1,2,4],[3,3,4],[4,5],[6,6]]) - sage: t.to_sign_matrix(6) + sage: t.to_sign_matrix(6) # optional - sage.modules [ 0 0 0 1 0 0] [ 0 1 0 -1 0 0] [ 1 -1 0 1 0 0] [ 0 0 1 -1 1 1] [ 0 0 0 1 -1 0] sage: t = Tableau([[1,2,4],[3,5]]) - sage: t.to_sign_matrix(7) + sage: t.to_sign_matrix(7) # optional - sage.modules [ 0 0 0 1 0 0 0] [ 0 1 0 -1 1 0 0] [ 1 -1 1 0 -1 0 0] sage: t = Tableau([(4,5,4,3),(2,1,3)]) - sage: t.to_sign_matrix(5) + sage: t.to_sign_matrix(5) # optional - sage.modules [ 0 0 1 0 0] [ 0 0 0 1 0] [ 1 0 -1 -1 1] @@ -2795,26 +2795,26 @@ def row_stabilizer(self): EXAMPLES:: - sage: rs = Tableau([[1,2,3],[4,5]]).row_stabilizer() - sage: rs.order() == factorial(3)*factorial(2) + sage: rs = Tableau([[1,2,3],[4,5]]).row_stabilizer() # optional - sage.groups + sage: rs.order() == factorial(3)*factorial(2) # optional - sage.groups True - sage: PermutationGroupElement([(1,3,2),(4,5)]) in rs + sage: PermutationGroupElement([(1,3,2),(4,5)]) in rs # optional - sage.groups True - sage: PermutationGroupElement([(1,4)]) in rs + sage: PermutationGroupElement([(1,4)]) in rs # optional - sage.groups False - sage: rs = Tableau([[1, 2],[3]]).row_stabilizer() - sage: PermutationGroupElement([(1,2),(3,)]) in rs + sage: rs = Tableau([[1, 2],[3]]).row_stabilizer() # optional - sage.groups + sage: PermutationGroupElement([(1,2),(3,)]) in rs # optional - sage.groups True - sage: rs.one().domain() + sage: rs.one().domain() # optional - sage.groups [1, 2, 3] - sage: rs = Tableau([[1],[2],[3]]).row_stabilizer() - sage: rs.order() + sage: rs = Tableau([[1],[2],[3]]).row_stabilizer() # optional - sage.groups + sage: rs.order() # optional - sage.groups 1 - sage: rs = Tableau([[2,4,5],[1,3]]).row_stabilizer() - sage: rs.order() + sage: rs = Tableau([[2,4,5],[1,3]]).row_stabilizer() # optional - sage.groups + sage: rs.order() # optional - sage.groups 12 - sage: rs = Tableau([]).row_stabilizer() - sage: rs.order() + sage: rs = Tableau([]).row_stabilizer() # optional - sage.groups + sage: rs.order() # optional - sage.groups 1 """ # Ensure that the permutations involve all elements of the @@ -2836,12 +2836,12 @@ def column_stabilizer(self): EXAMPLES:: - sage: cs = Tableau([[1,2,3],[4,5]]).column_stabilizer() - sage: cs.order() == factorial(2)*factorial(2) + sage: cs = Tableau([[1,2,3],[4,5]]).column_stabilizer() # optional - sage.groups + sage: cs.order() == factorial(2)*factorial(2) # optional - sage.groups True - sage: PermutationGroupElement([(1,3,2),(4,5)]) in cs + sage: PermutationGroupElement([(1,3,2),(4,5)]) in cs # optional - sage.groups False - sage: PermutationGroupElement([(1,4)]) in cs + sage: PermutationGroupElement([(1,4)]) in cs # optional - sage.groups True """ return self.conjugate().row_stabilizer() @@ -2898,7 +2898,7 @@ def last_letter_lequal(self, tab2): sage: st = StandardTableaux([3,2]) sage: f = lambda b: 1 if b else 0 - sage: matrix( [ [ f(t1.last_letter_lequal(t2)) for t2 in st] for t1 in st] ) + sage: matrix([[f(t1.last_letter_lequal(t2)) for t2 in st] for t1 in st]) # optional - sage.modules [1 1 1 1 1] [0 1 1 1 1] [0 0 1 1 1] @@ -3659,9 +3659,9 @@ def _segments(self): sage: sorted(t._segments().items()) [((0, 2), 2), ((0, 3), 3), ((0, 5), 4), ((1, 3), 1), ((1, 5), 2), ((2, 4), 1)] - sage: B = crystals.Tableaux("A4", shape=[4,3,2,1]) - sage: t = B[31].to_tableau() - sage: sorted(t._segments().items()) + sage: B = crystals.Tableaux("A4", shape=[4,3,2,1]) # optional - sage.modules + sage: t = B[31].to_tableau() # optional - sage.modules + sage: sorted(t._segments().items()) # optional - sage.modules [((0, 5), 3), ((1, 4), 2), ((2, 4), 1)] """ segments = {} @@ -3691,9 +3691,9 @@ def seg(self): sage: t.seg() 6 - sage: B = crystals.Tableaux("A4",shape=[4,3,2,1]) - sage: t = B[31].to_tableau() - sage: t.seg() + sage: B = crystals.Tableaux("A4", shape=[4,3,2,1]) # optional - sage.modules + sage: t = B[31].to_tableau() # optional - sage.modules + sage: t.seg() # optional - sage.modules 3 """ return len(self._segments()) @@ -3719,9 +3719,9 @@ def flush(self): sage: t.flush() 3 - sage: B = crystals.Tableaux("A4",shape=[4,3,2,1]) - sage: t = B[32].to_tableau() - sage: t.flush() + sage: B = crystals.Tableaux("A4", shape=[4,3,2,1]) # optional - sage.modules + sage: t = B[32].to_tableau() # optional - sage.modules + sage: t.flush() # optional - sage.modules 4 """ for i in range(len(self)-1): @@ -3844,11 +3844,11 @@ def residue_sequence(self, e, multicharge=(0,)): EXAMPLES:: - sage: StandardTableauTuple([[1,2],[3,4]]).residue_sequence(2) + sage: StandardTableauTuple([[1,2],[3,4]]).residue_sequence(2) # optional - sage.groups 2-residue sequence (0,1,1,0) with multicharge (0) - sage: StandardTableauTuple([[1,2],[3,4]]).residue_sequence(3) + sage: StandardTableauTuple([[1,2],[3,4]]).residue_sequence(3) # optional - sage.groups 3-residue sequence (0,1,2,0) with multicharge (0) - sage: StandardTableauTuple([[1,2],[3,4]]).residue_sequence(4) + sage: StandardTableauTuple([[1,2],[3,4]]).residue_sequence(4) # optional - sage.groups 4-residue sequence (0,1,3,0) with multicharge (0) """ res = [0] * self.size() @@ -3882,9 +3882,9 @@ def degree(self, e, multicharge=(0,)): EXAMPLES:: - sage: StandardTableau([[1,2,5],[3,4]]).degree(3) + sage: StandardTableau([[1,2,5],[3,4]]).degree(3) # optional - sage.groups 0 - sage: StandardTableau([[1,2,5],[3,4]]).degree(4) + sage: StandardTableau([[1,2,5],[3,4]]).degree(4) # optional - sage.groups 1 """ n = self.size() @@ -3927,11 +3927,11 @@ def codegree(self, e, multicharge=(0,)): EXAMPLES:: - sage: StandardTableau([[1,3,5],[2,4]]).codegree(3) + sage: StandardTableau([[1,3,5],[2,4]]).codegree(3) # optional - sage.groups 0 - sage: StandardTableau([[1,2,5],[3,4]]).codegree(3) + sage: StandardTableau([[1,2,5],[3,4]]).codegree(3) # optional - sage.groups 1 - sage: StandardTableau([[1,2,5],[3,4]]).codegree(4) + sage: StandardTableau([[1,2,5],[3,4]]).codegree(4) # optional - sage.groups 0 """ if not self: # the trivial case @@ -6464,9 +6464,9 @@ def random_element(self): EXAMPLES:: - sage: SemistandardTableaux(6).random_element() # random + sage: SemistandardTableaux(6).random_element() # random # optional - sage.modules [[1, 1, 2], [3, 5, 5]] - sage: SemistandardTableaux(6, max_entry=7).random_element() # random + sage: SemistandardTableaux(6, max_entry=7).random_element() # random # optional - sage.modules [[2, 4, 4, 6, 6, 6]] """ from sage.rings.integer_ring import ZZ @@ -7015,13 +7015,13 @@ class RowStandardTableaux(Tableaux): sage: ST = RowStandardTableaux(3); ST Row standard tableaux of size 3 - sage: ST.first() + sage: ST.first() # optional - sage.graphs [[1, 2, 3]] - sage: ST.last() + sage: ST.last() # optional - sage.graphs [[3], [1], [2]] - sage: ST.cardinality() + sage: ST.cardinality() # optional - sage.graphs 10 - sage: ST.list() + sage: ST.list() # optional - sage.graphs [[[1, 2, 3]], [[2, 3], [1]], [[1, 2], [3]], @@ -7048,13 +7048,13 @@ class RowStandardTableaux(Tableaux): [] sage: ST = RowStandardTableaux([2,2]); ST Row standard tableaux of shape [2, 2] - sage: ST.first() + sage: ST.first() # optional - sage.graphs [[2, 4], [1, 3]] - sage: ST.last() + sage: ST.last() # optional - sage.graphs [[2, 3], [1, 4]] - sage: ST.cardinality() + sage: ST.cardinality() # optional - sage.graphs 6 - sage: ST.list() + sage: ST.list() # optional - sage.graphs [[[2, 4], [1, 3]], [[3, 4], [1, 2]], [[1, 4], [2, 3]], @@ -7189,11 +7189,11 @@ class RowStandardTableaux_size(RowStandardTableaux, DisjointUnionEnumeratedSets) EXAMPLES:: - sage: [ t for t in RowStandardTableaux(1) ] + sage: [t for t in RowStandardTableaux(1)] # optional - sage.graphs [[[1]]] - sage: [ t for t in RowStandardTableaux(2) ] + sage: [t for t in RowStandardTableaux(2)] # optional - sage.graphs [[[1, 2]], [[2], [1]], [[1], [2]]] - sage: list(RowStandardTableaux(3)) + sage: list(RowStandardTableaux(3)) # optional - sage.graphs [[[1, 2, 3]], [[2, 3], [1]], [[1, 2], [3]], @@ -7213,7 +7213,7 @@ class RowStandardTableaux_size(RowStandardTableaux, DisjointUnionEnumeratedSets) 10 sage: ns = [1,2,3,4,5,6] sage: sts = [RowStandardTableaux(n) for n in ns] - sage: all(st.cardinality() == len(st.list()) for st in sts) + sage: all(st.cardinality() == len(st.list()) for st in sts) # optional - sage.graphs True sage: RowStandardTableaux(40).cardinality() # not tested, too long 2063837185739279909309355007659204891024472174278 @@ -7230,8 +7230,8 @@ def __init__(self, n): TESTS:: - sage: TestSuite( RowStandardTableaux(0) ).run() - sage: TestSuite( RowStandardTableaux(3) ).run() + sage: TestSuite(RowStandardTableaux(0)).run() # optional - sage.graphs + sage: TestSuite(RowStandardTableaux(3)).run() # optional - sage.graphs """ RowStandardTableaux.__init__(self) from sage.combinat.partition import Partitions_n @@ -7254,10 +7254,10 @@ def __contains__(self, x): TESTS:: sage: ST3 = RowStandardTableaux(3) - sage: all(st in ST3 for st in ST3) + sage: all(st in ST3 for st in ST3) # optional - sage.graphs True sage: ST4 = RowStandardTableaux(4) - sage: [x for x in ST4 if x in ST3] + sage: [x for x in ST4 if x in ST3] # optional - sage.graphs [] Check that :trac:`14145` is fixed:: @@ -7300,7 +7300,7 @@ def __init__(self, p): TESTS:: - sage: TestSuite( RowStandardTableaux([2,1,1]) ).run() + sage: TestSuite( RowStandardTableaux([2,1,1]) ).run() # optional - sage.graphs """ super().__init__(category=FiniteEnumeratedSets()) self.shape = p @@ -7310,9 +7310,9 @@ def __contains__(self, x): EXAMPLES:: sage: ST = RowStandardTableaux([2,1,1]) - sage: all(st in ST for st in ST) + sage: all(st in ST for st in ST) # optional - sage.graphs True - sage: len([x for x in RowStandardTableaux(4) if x in ST]) + sage: len([x for x in RowStandardTableaux(4) if x in ST]) # optional - sage.graphs 12 sage: ST.cardinality() 12 @@ -7335,14 +7335,14 @@ def __iter__(self): EXAMPLES:: - sage: [t for t in RowStandardTableaux([2,2])] + sage: [t for t in RowStandardTableaux([2,2])] # optional - sage.graphs [[[2, 4], [1, 3]], [[3, 4], [1, 2]], [[1, 4], [2, 3]], [[1, 3], [2, 4]], [[1, 2], [3, 4]], [[2, 3], [1, 4]]] - sage: [t for t in RowStandardTableaux([3,2])] + sage: [t for t in RowStandardTableaux([3,2])] # optional - sage.graphs [[[2, 4, 5], [1, 3]], [[3, 4, 5], [1, 2]], [[1, 4, 5], [2, 3]], @@ -7354,7 +7354,7 @@ def __iter__(self): [[2, 3, 4], [1, 5]], [[2, 3, 5], [1, 4]]] sage: st = RowStandardTableaux([2,1]) - sage: st[0].parent() is st + sage: st[0].parent() is st # optional - sage.graphs True """ partial_sums = [sum(self.shape[:i]) for i in range(len(self.shape)+1)] @@ -7461,7 +7461,7 @@ class StandardTableaux(SemistandardTableaux): 2 sage: ST.list() [[[1, 3], [2, 4]], [[1, 2], [3, 4]]] - sage: StandardTableau([[1,2,3],[4,5]]).residue_sequence(3).standard_tableaux() + sage: StandardTableau([[1,2,3],[4,5]]).residue_sequence(3).standard_tableaux() # optional - sage.groups Standard tableaux with 3-residue sequence (0,1,2,2,0) and multicharge (0) """ @staticmethod diff --git a/src/sage/combinat/tiling.py b/src/sage/combinat/tiling.py index 640f1c6d096..6cb44cd99c8 100644 --- a/src/sage/combinat/tiling.py +++ b/src/sage/combinat/tiling.py @@ -109,8 +109,8 @@ Showing one solution:: sage: solution = next(T.solve()) # long time - sage: G = sum([piece.show2d() for piece in solution], Graphics()) # long time - sage: G.show(aspect_ratio=1, axes=False) # long time + sage: G = sum([piece.show2d() for piece in solution], Graphics()) # long time # optional - sage.plot + sage: G.show(aspect_ratio=1, axes=False) # long time # optional - sage.plot 1d Easy Example --------------- @@ -162,8 +162,8 @@ sage: T = TilingSolver(L, box=(8,8), reflection=True) sage: solution = next(T.solve()) # long time (7s) - sage: G = sum([piece.show2d() for piece in solution], Graphics()) # long time (<1s) - sage: G.show(aspect_ratio=1, axes=False) # long time (2s) + sage: G = sum([piece.show2d() for piece in solution], Graphics()) # long time (<1s) # optional - sage.plot + sage: G.show(aspect_ratio=1, axes=False) # long time (2s) # optional - sage.plot Compute the number of solutions:: @@ -218,8 +218,8 @@ sage: T.number_of_solutions() 10 sage: solution = next(T.solve()) - sage: G = sum([p.show2d() for p in solution], Graphics()) - sage: G.show(aspect_ratio=1) # long time (2s) + sage: G = sum([p.show2d() for p in solution], Graphics()) # optional - sage.plot + sage: G.show(aspect_ratio=1) # long time (2s) # optional - sage.plot :: @@ -240,16 +240,15 @@ sage: from sage.combinat.tiling import Polyomino, TilingSolver sage: Y = Polyomino([(0,0),(1,0),(2,0),(3,0),(2,1)], color='yellow') sage: T = TilingSolver([Y], box=(15,15), reusable=True, reflection=True) - sage: a = T.animate(stop=40) # long time # optional -- ImageMagick - sage: a # long time # optional -- ImageMagick + sage: a = T.animate(stop=40); a # long time # optional -- ImageMagick sage.plot Animation with 40 frames Incremental animation of the solutions (one piece is removed/added at a time):: - sage: a = T.animate('incremental', stop=40) # long time # optional -- ImageMagick - sage: a # long time # optional -- ImageMagick + sage: a = T.animate('incremental', stop=40) # long time # optional -- ImageMagick sage.plot + sage: a # long time # optional -- ImageMagick sage.plot Animation with 40 frames - sage: a.show(delay=50, iterations=1) # long time # optional -- ImageMagick + sage: a.show(delay=50, iterations=1) # long time # optional -- ImageMagick sage.plot 5d Easy Example --------------- @@ -1389,7 +1388,7 @@ def show3d(self, size=1): sage: from sage.combinat.tiling import Polyomino sage: p = Polyomino([(0,0,0), (0,1,0), (1,1,0), (1,1,1)], color='blue') - sage: p.show3d() # long time (2s) + sage: p.show3d() # long time (2s) # optional -- sage.plot Graphics3d Object """ assert self._dimension == 3, "Dimension of the polyomino must be 3." @@ -1422,7 +1421,7 @@ def show2d(self, size=0.7, color='black', thickness=1): sage: from sage.combinat.tiling import Polyomino sage: p = Polyomino([(0,0),(1,0),(1,1),(1,2)], color='deeppink') - sage: p.show2d() # long time (0.5s) + sage: p.show2d() # long time (0.5s) # optional -- sage.plot Graphics object consisting of 17 graphics primitives """ assert self._dimension == 2, "Dimension of the polyomino must be 2." @@ -1473,12 +1472,12 @@ def self_surrounding(self, radius, remove_incomplete_copies=True, ....: (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (2, 0), (2, 2), ....: (2, 3), (2, 5), (2, 6), (2, 8)]) sage: solution = H.self_surrounding(8) - sage: G = sum([p.show2d() for p in solution], Graphics()) + sage: G = sum([p.show2d() for p in solution], Graphics()) # optional - sage.plot :: sage: solution = H.self_surrounding(8, remove_incomplete_copies=False) - sage: G = sum([p.show2d() for p in solution], Graphics()) + sage: G = sum([p.show2d() for p in solution], Graphics()) # optional - sage.plot """ # Define the box to tile @@ -2425,38 +2424,38 @@ def animate(self, partial=None, stop=None, size=0.75, axes=False): sage: from sage.combinat.tiling import Polyomino, TilingSolver sage: y = Polyomino([(0,0),(1,0),(2,0),(3,0),(2,1)], color='cyan') sage: T = TilingSolver([y], box=(5,10), reusable=True, reflection=True) - sage: a = T.animate() - sage: a # optional -- ImageMagick # long time + sage: a = T.animate() # optional - sage.plot + sage: a # optional -- ImageMagick # long time # optional - sage.plot Animation with 10 frames Include partial solutions (common prefix between two consecutive solutions):: - sage: a = T.animate('common_prefix') - sage: a # optional -- ImageMagick # long time + sage: a = T.animate('common_prefix') # optional - sage.plot + sage: a # optional -- ImageMagick # long time # optional - sage.plot Animation with 19 frames Incremental solutions (one piece removed or added at a time):: - sage: a = T.animate('incremental') # long time (2s) - sage: a # long time (2s) # optional -- ImageMagick + sage: a = T.animate('incremental') # long time (2s) # optional - sage.plot + sage: a # long time (2s) # optional -- ImageMagick sage.plot Animation with 123 frames :: - sage: a.show() # optional -- ImageMagick # long time + sage: a.show() # optional -- ImageMagick # long time # optional - sage.plot The ``show`` function takes arguments to specify the delay between frames (measured in hundredths of a second, default value 20) and the number of iterations (default value 0, which means to iterate forever). To iterate 4 times with half a second between each frame:: - sage: a.show(delay=50, iterations=4) # optional -- ImageMagick # long time + sage: a.show(delay=50, iterations=4) # optional -- ImageMagick # long time # optional - sage.plot Limit the number of frames:: - sage: a = T.animate('incremental', stop=13) # not tested - sage: a # not tested + sage: a = T.animate('incremental', stop=13) # not tested # optional - sage.plot + sage: a # not tested # optional - sage.plot Animation with 13 frames """ dimension = self._box._dimension diff --git a/src/sage/combinat/triangles_FHM.py b/src/sage/combinat/triangles_FHM.py index 7fca1bd0252..43f2947a51b 100644 --- a/src/sage/combinat/triangles_FHM.py +++ b/src/sage/combinat/triangles_FHM.py @@ -12,11 +12,11 @@ The M-triangle class is motivated by the generating series of Möbius numbers for graded posets. A typical example is:: - sage: W = SymmetricGroup(4) - sage: posets.NoncrossingPartitions(W).M_triangle() + sage: W = SymmetricGroup(4) # optional - sage.groups + sage: posets.NoncrossingPartitions(W).M_triangle() # optional - sage.graphs sage.groups M: x^3*y^3 - 6*x^2*y^3 + 6*x^2*y^2 + 10*x*y^3 - 16*x*y^2 - 5*y^3 + 6*x*y + 10*y^2 - 6*y + 1 - sage: unicode_art(_) + sage: unicode_art(_) # optional - sage.graphs sage.modules sage.groups ⎛ -5 10 -6 1⎞ ⎜ 10 -16 6 0⎟ ⎜ -6 6 0 0⎟ @@ -31,7 +31,7 @@ sage: f = C.greedy_facet() sage: C.F_triangle(f) F: 5*x^3 + 5*x^2*y + 3*x*y^2 + y^3 + 10*x^2 + 8*x*y + 3*y^2 + 6*x + 3*y + 1 - sage: unicode_art(_) + sage: unicode_art(_) # optional - sage.modules ⎛ 1 0 0 0⎞ ⎜ 3 3 0 0⎟ ⎜ 3 8 5 0⎟ @@ -67,7 +67,7 @@ def _matrix_display(self, variables=None): sage: from sage.combinat.triangles_FHM import _matrix_display sage: x, y = PolynomialRing(QQ,['x', 'y']).gens() - sage: _matrix_display(x**2+x*y+y**3) + sage: _matrix_display(x**2+x*y+y**3) # optional - sage.modules [1 0 0] [0 0 0] [0 1 0] @@ -76,10 +76,10 @@ def _matrix_display(self, variables=None): With a specific choice of variables:: sage: x, y, z = PolynomialRing(QQ,['x','y','z']).gens() - sage: _matrix_display(x**2+z*x*y+z*y**3+z*x,[y,z]) + sage: _matrix_display(x**2+z*x*y+z*y**3+z*x,[y,z]) # optional - sage.modules [ x x 0 1] [x^2 0 0 0] - sage: _matrix_display(x**2+z*x*y+z*y**3+z*x,[x,z]) + sage: _matrix_display(x**2+z*x*y+z*y**3+z*x,[x,z]) # optional - sage.modules [ y^3 y + 1 0] [ 0 0 1] """ @@ -124,7 +124,7 @@ class Triangle(SageObject): sage: from sage.combinat.triangles_FHM import Triangle sage: x, y = polygens(ZZ, 'x,y') sage: ht = Triangle(1+4*x+2*x*y) - sage: unicode_art(ht) + sage: unicode_art(ht) # optional - sage.modules ⎛0 2⎞ ⎝1 4⎠ """ @@ -136,7 +136,7 @@ def __init__(self, poly, variables=None): sage: from sage.combinat.triangles_FHM import Triangle sage: x, y = polygens(ZZ, 'x,y') sage: ht = Triangle(1+2*x*y) - sage: unicode_art(ht) + sage: unicode_art(ht) # optional - sage.modules ⎛0 2⎞ ⎝1 0⎠ """ @@ -156,7 +156,7 @@ def _ascii_art_(self): sage: from sage.combinat.triangles_FHM import H_triangle sage: x, y = polygens(ZZ, 'x,y') sage: ht = H_triangle(1+2*x*y) - sage: ascii_art(ht) + sage: ascii_art(ht) # optional - sage.modules [0 2] [1 0] """ @@ -171,7 +171,7 @@ def _unicode_art_(self): sage: from sage.combinat.triangles_FHM import H_triangle sage: x, y = polygens(ZZ, 'x,y') sage: ht = H_triangle(1+2*x*y) - sage: unicode_art(ht) + sage: unicode_art(ht) # optional - sage.modules ⎛0 2⎞ ⎝1 0⎠ """ @@ -200,7 +200,7 @@ def _latex_(self): sage: from sage.combinat.triangles_FHM import H_triangle sage: x, y = polygens(ZZ, 'x,y') sage: ht = H_triangle(1+2*x*y) - sage: latex(ht) + sage: latex(ht) # optional - sage.modules \left(\begin{array}{rr} 0 & 2 \\ 1 & 0 @@ -296,7 +296,7 @@ def matrix(self): sage: from sage.combinat.triangles_FHM import H_triangle sage: x, y = polygens(ZZ, 'x,y') sage: h = H_triangle(1+2*x*y) - sage: h.matrix() + sage: h.matrix() # optional - sage.modules [0 2] [1 0] """ @@ -557,9 +557,9 @@ def gamma(self): sage: H_triangle(ht).gamma() Γ: y^2 + x - sage: W = SymmetricGroup(5) - sage: P = posets.NoncrossingPartitions(W) - sage: P.M_triangle().h().gamma() + sage: W = SymmetricGroup(5) # optional - sage.groups + sage: P = posets.NoncrossingPartitions(W) # optional - sage.graphs + sage: P.M_triangle().h().gamma() # optional - sage.graphs sage.groups Γ: y^4 + 3*x*y^2 + 2*x^2 + 2*x*y + x """ x, y = self._vars diff --git a/src/sage/combinat/tuple.py b/src/sage/combinat/tuple.py index 7e7f85c61ef..26c1b4ec074 100644 --- a/src/sage/combinat/tuple.py +++ b/src/sage/combinat/tuple.py @@ -47,9 +47,9 @@ class Tuples(Parent, UniqueRepresentation): :: - sage: K.<a> = GF(4, 'a') - sage: mset = [x for x in K if x != 0] - sage: Tuples(mset,2).list() + sage: K.<a> = GF(4, 'a') # optional - sage.rings.finite_rings + sage: mset = [x for x in K if x != 0] # optional - sage.rings.finite_rings + sage: Tuples(mset,2).list() # optional - sage.rings.finite_rings [[a, a], [a + 1, a], [1, a], [a, a + 1], [a + 1, a + 1], [1, a + 1], [a, 1], [a + 1, 1], [1, 1]] """ @@ -127,10 +127,10 @@ def cardinality(self): EXAMPLES:: sage: S = [1,2,3,4,5] - sage: Tuples(S,2).cardinality() + sage: Tuples(S,2).cardinality() # optional - sage.libs.gap 25 sage: S = [1,1,2,3,4,5] - sage: Tuples(S,2).cardinality() + sage: Tuples(S,2).cardinality() # optional - sage.libs.gap 25 """ return ZZ(libgap.NrTuples(self._index_list, ZZ(self.k))) @@ -210,7 +210,7 @@ def cardinality(self): EXAMPLES:: sage: S = [1,2,3,4,5] - sage: UnorderedTuples(S,2).cardinality() + sage: UnorderedTuples(S,2).cardinality() # optional - sage.libs.gap 15 """ return ZZ(libgap.NrUnorderedTuples(self._index_list, ZZ(self.k))) diff --git a/src/sage/combinat/tutorial.py b/src/sage/combinat/tutorial.py index dfab1793474..b8c4fde4386 100644 --- a/src/sage/combinat/tutorial.py +++ b/src/sage/combinat/tutorial.py @@ -447,7 +447,7 @@ sage: Qx = QQ['x'].fraction_field() sage: Qxy = Qx['y'] - sage: R = Qxy.quo(P); R + sage: R = Qxy.quo(P); R # optional - sage.symbolic Univariate Quotient Polynomial Ring in ybar over Fraction Field of Univariate Polynomial Ring in x over Rational Field with modulus y^2 - y + x @@ -458,7 +458,7 @@ We continue the calculation of this fraction in `R`:: - sage: fraction = - R(Px) / R(Py); fraction + sage: fraction = - R(Px) / R(Py); fraction # optional - sage.symbolic (1/2/(x - 1/4))*ybar - 1/4/(x - 1/4) .. note:: diff --git a/src/sage/combinat/words/abstract_word.py b/src/sage/combinat/words/abstract_word.py index ff3be9930ad..cfff867d67d 100644 --- a/src/sage/combinat/words/abstract_word.py +++ b/src/sage/combinat/words/abstract_word.py @@ -1478,24 +1478,24 @@ def sum_digits(self, base=2, mod=None): Sum of digits modulo 2 of the prime numbers written in base 2:: - sage: Word(primes(1000)).sum_digits() + sage: Word(primes(1000)).sum_digits() # optional - sage.libs.pari word: 1001110100111010111011001011101110011011... Sum of digits modulo 3 of the prime numbers written in base 3:: - sage: Word(primes(1000)).sum_digits(base=3) + sage: Word(primes(1000)).sum_digits(base=3) # optional - sage.libs.pari word: 2100002020002221222121022221022122111022... - sage: Word(primes(1000)).sum_digits(base=3, mod=3) + sage: Word(primes(1000)).sum_digits(base=3, mod=3) # optional - sage.libs.pari word: 2100002020002221222121022221022122111022... Sum of digits modulo 2 of the prime numbers written in base 3:: - sage: Word(primes(1000)).sum_digits(base=3, mod=2) + sage: Word(primes(1000)).sum_digits(base=3, mod=2) # optional - sage.libs.pari word: 0111111111111111111111111111111111111111... Sum of digits modulo 7 of the prime numbers written in base 10:: - sage: Word(primes(1000)).sum_digits(base=10, mod=7) + sage: Word(primes(1000)).sum_digits(base=10, mod=7) # optional - sage.libs.pari word: 2350241354435041006132432241353546006304... Negative entries:: diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index 53e04002cf6..05f6233e8bc 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -190,9 +190,9 @@ Rauzy graphs:: sage: f = words.FibonacciWord()[:30] - sage: f.rauzy_graph(4) + sage: f.rauzy_graph(4) # optional - sage.graphs Looped digraph on 5 vertices - sage: f.reduced_rauzy_graph(4) + sage: f.reduced_rauzy_graph(4) # optional - sage.graphs Looped multi-digraph on 2 vertices Left-special and bispecial factors:: @@ -1522,12 +1522,12 @@ def rauzy_graph(self, n): sage: w = Word(range(10)); w word: 0123456789 - sage: g = w.rauzy_graph(3); g + sage: g = w.rauzy_graph(3); g # optional - sage.graphs Looped digraph on 8 vertices sage: WordOptions(identifier='') - sage: g.vertices(sort=True) + sage: g.vertices(sort=True) # optional - sage.graphs [012, 123, 234, 345, 456, 567, 678, 789] - sage: g.edges(sort=True) + sage: g.edges(sort=True) # optional - sage.graphs [(012, 123, 3), (123, 234, 4), (234, 345, 5), @@ -1540,20 +1540,20 @@ def rauzy_graph(self, n): :: sage: f = words.FibonacciWord()[:100] - sage: f.rauzy_graph(8) + sage: f.rauzy_graph(8) # optional - sage.graphs Looped digraph on 9 vertices :: sage: w = Word('1111111') - sage: g = w.rauzy_graph(3) - sage: g.edges(sort=True) + sage: g = w.rauzy_graph(3) # optional - sage.graphs + sage: g.edges(sort=True) # optional - sage.graphs [(word: 111, word: 111, word: 1)] :: sage: w = Word('111') - sage: for i in range(5) : w.rauzy_graph(i) + sage: for i in range(5): w.rauzy_graph(i) # optional - sage.graphs Looped multi-digraph on 1 vertex Looped digraph on 1 vertex Looped digraph on 1 vertex @@ -1564,9 +1564,9 @@ def rauzy_graph(self, n): sage: W = Words('abcde') sage: w = W('abc') - sage: w.rauzy_graph(0) + sage: w.rauzy_graph(0) # optional - sage.graphs Looped multi-digraph on 1 vertex - sage: _.edges(sort=True) + sage: _.edges(sort=True) # optional - sage.graphs [(word: , word: , word: a), (word: , word: , word: b), (word: , word: , word: c)] @@ -1633,35 +1633,37 @@ def reduced_rauzy_graph(self, n): sage: w = Word(range(10)); w word: 0123456789 - sage: g = w.reduced_rauzy_graph(3); g + sage: g = w.reduced_rauzy_graph(3); g # optional - sage.graphs Looped multi-digraph on 2 vertices - sage: g.vertices(sort=True) + sage: g.vertices(sort=True) # optional - sage.graphs [word: 012, word: 789] - sage: g.edges(sort=True) + sage: g.edges(sort=True) # optional - sage.graphs [(word: 012, word: 789, word: 3456789)] For the Fibonacci word:: sage: f = words.FibonacciWord()[:100] - sage: g = f.reduced_rauzy_graph(8);g + sage: g = f.reduced_rauzy_graph(8);g # optional - sage.graphs Looped multi-digraph on 2 vertices - sage: g.vertices(sort=True) + sage: g.vertices(sort=True) # optional - sage.graphs [word: 01001010, word: 01010010] - sage: g.edges(sort=True) - [(word: 01001010, word: 01010010, word: 010), (word: 01010010, word: 01001010, word: 01010), (word: 01010010, word: 01001010, word: 10)] + sage: g.edges(sort=True) # optional - sage.graphs + [(word: 01001010, word: 01010010, word: 010), + (word: 01010010, word: 01001010, word: 01010), + (word: 01010010, word: 01001010, word: 10)] For periodic words:: sage: from itertools import cycle sage: w = Word(cycle('abcd'))[:100] - sage: g = w.reduced_rauzy_graph(3) - sage: g.edges(sort=True) + sage: g = w.reduced_rauzy_graph(3) # optional - sage.graphs + sage: g.edges(sort=True) # optional - sage.graphs [(word: abc, word: abc, word: dabc)] :: sage: w = Word('111') - sage: for i in range(5) : w.reduced_rauzy_graph(i) + sage: for i in range(5): w.reduced_rauzy_graph(i) # optional - sage.graphs Looped digraph on 1 vertex Looped digraph on 1 vertex Looped digraph on 1 vertex @@ -1673,10 +1675,10 @@ def reduced_rauzy_graph(self, n): sage: sigma = WordMorphism('a->abcd,b->cd,c->cd,d->cd') sage: w = sigma.fixed_point('a')[:100]; w word: abcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd... - sage: g = w.reduced_rauzy_graph(5) - sage: g.vertices(sort=True) + sage: g = w.reduced_rauzy_graph(5) # optional - sage.graphs + sage: g.vertices(sort=True) # optional - sage.graphs [word: abcdc, word: cdcdc] - sage: g.edges(sort=True) + sage: g.edges(sort=True) # optional - sage.graphs [(word: abcdc, word: cdcdc, word: dc), (word: cdcdc, word: cdcdc, word: dc)] AUTHOR: @@ -3097,9 +3099,9 @@ def defect(self, f=None): sage: sa = WordMorphism('a->ab,b->b') sage: sb = WordMorphism('a->a,b->ba') sage: w = (sa*sb*sb*sa*sa*sa*sb).fixed_point('a') - sage: w[:30].defect() + sage: w[:30].defect() # optional - sage.modules 0 - sage: w[110:140].defect() + sage: w[110:140].defect() # optional - sage.modules 0 It is even conjectured that the defect of an aperiodic word which is @@ -3107,11 +3109,11 @@ def defect(self, f=None): (see [BBGL2008]_):: sage: w = words.ThueMorseWord() - sage: w[:50].defect() + sage: w[:50].defect() # optional - sage.modules 12 - sage: w[:100].defect() + sage: w[:100].defect() # optional - sage.modules 16 - sage: w[:300].defect() + sage: w[:300].defect() # optional - sage.modules 52 For generalized defect with an involution different from the identity, diff --git a/src/sage/combinat/words/morphic.py b/src/sage/combinat/words/morphic.py index 6cca2834ee5..221ad94a310 100644 --- a/src/sage/combinat/words/morphic.py +++ b/src/sage/combinat/words/morphic.py @@ -24,7 +24,7 @@ abstract numeration system associated to the morphism and the starting letter, see chapter 3 of the book [BR2010b]_:: - sage: w[10000000] + sage: w[10000000] # optional - sage.modules 'b' """ @@ -57,7 +57,7 @@ def __init__(self, parent, morphism, letter, coding=None, length=Infinity): sage: w = m.fixed_point('a') sage: w word: abaababaabaababaababaabaababaabaababaaba... - sage: w[555:1000] + sage: w[555:1000] # optional - sage.modules word: abaababaabaababaababaabaababaabaababaaba... sage: w.length() +Infinity @@ -68,11 +68,11 @@ def __init__(self, parent, morphism, letter, coding=None, length=Infinity): sage: m.fixed_point('a') word: abcbabacababaabcbabaabccaabcbabaabcbabaa... sage: w = m.fixed_point('a') - sage: w[7] + sage: w[7] # optional - sage.modules 'c' - sage: w[2:7] + sage: w[2:7] # optional - sage.modules word: cbaba - sage: w[500:503] + sage: w[500:503] # optional - sage.modules word: caa When the morphic word is finite:: @@ -81,7 +81,7 @@ def __init__(self, parent, morphism, letter, coding=None, length=Infinity): sage: w = m.fixed_point("a") sage: w word: ab - sage: w[0] + sage: w[0] # optional - sage.modules 'a' sage: w.length() 2 @@ -93,7 +93,7 @@ def __init__(self, parent, morphism, letter, coding=None, length=Infinity): sage: from sage.combinat.words.morphic import WordDatatype_morphic sage: coding = {'a':'x', 'b':'y'} sage: w = WordDatatype_morphic(W, m, 'a', coding=coding) - sage: [w[i] for i in range(10)] + sage: [w[i] for i in range(10)] # optional - sage.modules ['x', 'y', 'x', 'x', 'y', 'x', 'y', 'x', 'x', 'y'] TESTS:: @@ -104,9 +104,9 @@ def __init__(self, parent, morphism, letter, coding=None, length=Infinity): sage: for _ in range(10000): _ = next(it) sage: L = [next(it) for _ in range(10)]; L ['d', 'd', 'd', 'c', 'd', 'd', 'd', 'c', 'b', 'a'] - sage: w[10000:10010] + sage: w[10000:10010] # optional - sage.modules word: dddcdddcba - sage: list(w[10000:10010]) == L + sage: list(w[10000:10010]) == L # optional - sage.modules True """ @@ -177,18 +177,18 @@ def representation(self, n): sage: m = WordMorphism('a->ab,b->a') sage: w = m.fixed_point('a') - sage: w.representation(5) + sage: w.representation(5) # optional - sage.modules [1, 0, 0, 0] When the morphic word is finite:: sage: m = WordMorphism("a->ab,b->,c->cdab,d->dcab") sage: w = m.fixed_point("a") - sage: w.representation(0) + sage: w.representation(0) # optional - sage.modules [] - sage: w.representation(1) + sage: w.representation(1) # optional - sage.modules [1] - sage: w.representation(2) + sage: w.representation(2) # optional - sage.modules Traceback (most recent call last): ... IndexError: index (=2) out of range, the fixed point is finite and has length 2 @@ -204,7 +204,7 @@ def representation(self, n): sage: w = WordDatatype_morphic(W, m, 'a') sage: type(w) <class 'sage.combinat.words.morphic.WordDatatype_morphic'> - sage: w.representation(5) + sage: w.representation(5) # optional - sage.modules [1, 0, 0, 0] """ letters_to_int = {a:i for (i,a) in enumerate(self._alphabet)} diff --git a/src/sage/combinat/words/morphism.py b/src/sage/combinat/words/morphism.py index 33a76127699..af43487a574 100644 --- a/src/sage/combinat/words/morphism.py +++ b/src/sage/combinat/words/morphism.py @@ -66,7 +66,7 @@ Incidence matrix:: - sage: matrix(m) + sage: matrix(m) # optional - sage.modules [2 3 1] [1 3 0] [1 1 1] @@ -612,7 +612,7 @@ def __str__(self) -> str: :: sage: s = WordMorphism({1:[1,2],2:[1]}) - sage: s.dual_map() + sage: s.dual_map() # optional - sage.modules E_1^*(1->12, 2->1) TESTS:: @@ -1099,21 +1099,21 @@ def _matrix_(self, R=None): sage: fibo = WordMorphism('a->ab,b->a') sage: tm = WordMorphism('a->ab,b->ba') - sage: Mfibo = matrix(fibo); Mfibo # indirect doctest + sage: Mfibo = matrix(fibo); Mfibo # indirect doctest # optional - sage.modules [1 1] [1 0] - sage: Mtm = matrix(tm); Mtm + sage: Mtm = matrix(tm); Mtm # optional - sage.modules [1 1] [1 1] - sage: Mtm * Mfibo == matrix(tm*fibo) # indirect doctest + sage: Mtm * Mfibo == matrix(tm*fibo) # indirect doctest # optional - sage.modules True - sage: Mfibo * Mtm == matrix(fibo*tm) # indirect doctest + sage: Mfibo * Mtm == matrix(fibo*tm) # indirect doctest # optional - sage.modules True - sage: Mfibo.parent() + sage: Mfibo.parent() # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: p = Mfibo.charpoly(); p + sage: p = Mfibo.charpoly(); p # optional - sage.modules x^2 - x - 1 - sage: p.roots(ring=RR, multiplicities=False) + sage: p.roots(ring=RR, multiplicities=False) # optional - sage.modules [-0.618033988749895, 1.61803398874989] """ if R is None: @@ -1134,12 +1134,12 @@ def incidence_matrix(self): EXAMPLES:: sage: m = WordMorphism('a->abc,b->a,c->c') - sage: m.incidence_matrix() + sage: m.incidence_matrix() # optional - sage.modules [1 1 0] [1 0 0] [1 0 1] sage: m = WordMorphism('a->abc,b->a,c->c,d->abbccccabca,e->abc') - sage: m.incidence_matrix() + sage: m.incidence_matrix() # optional - sage.modules [1 1 0 3 1] [1 0 0 3 1] [1 0 1 5 1] @@ -1202,9 +1202,10 @@ def is_endomorphism(self): We check that :trac:`8674` is fixed:: - sage: P = WordPaths('abcd') - sage: m = WordMorphism('a->adab,b->ab,c->cbcd,d->cd', domain=P, codomain=P) - sage: m.is_endomorphism() + sage: P = WordPaths('abcd') # optional - sage.modules + sage: m = WordMorphism('a->adab,b->ab,c->cbcd,d->cd', # optional - sage.modules + ....: domain=P, codomain=P) + sage: m.is_endomorphism() # optional - sage.modules True """ return self.codomain() == self.domain() @@ -1493,11 +1494,11 @@ def pisot_eigenvector_right(self): EXAMPLES:: sage: m = WordMorphism('a->aaaabbc,b->aaabbc,c->aabc') - sage: matrix(m) + sage: matrix(m) # optional - sage.modules [4 3 2] [2 2 1] [1 1 1] - sage: m.pisot_eigenvector_right() + sage: m.pisot_eigenvector_right() # optional - sage.modules sage.rings.number_field (1, 0.5436890126920763?, 0.2955977425220848?) """ eig = self.incidence_matrix().eigenvectors_right() @@ -1523,11 +1524,11 @@ def pisot_eigenvector_left(self): EXAMPLES:: sage: m = WordMorphism('a->aaaabbc,b->aaabbc,c->aabc') - sage: matrix(m) + sage: matrix(m) # optional - sage.modules [4 3 2] [2 2 1] [1 1 1] - sage: m.pisot_eigenvector_left() + sage: m.pisot_eigenvector_left() # optional - sage.modules sage.rings.number_field (1, 0.8392867552141611?, 0.5436890126920763?) """ eig = self.incidence_matrix().eigenvectors_left() @@ -2072,12 +2073,12 @@ def language(self, n, u=None): The fibonacci morphism:: - sage: s = WordMorphism({0: [0,1], 1:[0]}) - sage: sorted(s.language(3)) + sage: s = WordMorphism({0: [0,1], 1: [0]}) + sage: sorted(s.language(3)) # optional - sage.modules [word: 001, word: 010, word: 100, word: 101] - sage: len(s.language(1000)) + sage: len(s.language(1000)) # optional - sage.modules 1001 - sage: all(len(s.language(n)) == n+1 for n in range(100)) + sage: all(len(s.language(n)) == n+1 for n in range(100)) # optional - sage.modules True A growing but non-primitive example. The DOL-languages generated @@ -2087,14 +2088,14 @@ def language(self, n, u=None): sage: u = s.fixed_point(0) sage: A0 = u[:200].factor_set(5) - sage: B0 = s.language(5, [0]) - sage: set(A0) == B0 + sage: B0 = s.language(5, [0]) # optional - sage.modules + sage: set(A0) == B0 # optional - sage.modules True sage: v = s.fixed_point(2) sage: A2 = v[:200].factor_set(5) - sage: B2 = s.language(5, [2]) - sage: set(A2) == B2 + sage: B2 = s.language(5, [2]) # optional - sage.modules + sage: set(A2) == B2 # optional - sage.modules True sage: len(A0), len(A2) @@ -2103,7 +2104,7 @@ def language(self, n, u=None): The Chacon transformation (non-primitive):: sage: s = WordMorphism({0: [0,0,1,0], 1:[1]}) - sage: sorted(s.language(10)) + sage: sorted(s.language(10)) # optional - sage.modules [word: 0001000101, word: 0001010010, ... @@ -2457,8 +2458,8 @@ def dual_map(self, k=1): EXAMPLES:: - sage: sigma = WordMorphism({1:[2],2:[3],3:[1,2]}) - sage: sigma.dual_map() + sage: sigma = WordMorphism({1: [2], 2: [3], 3: [1,2]}) + sage: sigma.dual_map() # optional - sage.modules E_1^*(1->2, 2->3, 3->12) :: @@ -2512,7 +2513,7 @@ def rauzy_fractal_projection(self, eig=None, prec=53): is:: sage: s = WordMorphism('1->12,2->13,3->1') - sage: s.rauzy_fractal_projection() + sage: s.rauzy_fractal_projection() # optional - sage.modules {'1': (1.00000000000000, 0.000000000000000), '2': (-1.41964337760708, -0.606290729207199), '3': (-0.771844506346038, 1.11514250803994)} @@ -2520,9 +2521,9 @@ def rauzy_fractal_projection(self, eig=None, prec=53): TESTS:: sage: t = WordMorphism('1->12,2->3,3->45,4->5,5->6,6->7,7->8,8->1') - sage: E = t.incidence_matrix().eigenvalues() - sage: x = [x for x in E if -0.8 < x < -0.7][0] - sage: t.rauzy_fractal_projection(prec=10) + sage: E = t.incidence_matrix().eigenvalues() # optional - sage.modules + sage: x = [x for x in E if -0.8 < x < -0.7][0] # optional - sage.modules + sage: t.rauzy_fractal_projection(prec=10) # optional - sage.modules {'1': (1.0, 0.00), '2': (-1.7, -0.56), '3': (0.79, 1.3), @@ -2531,7 +2532,7 @@ def rauzy_fractal_projection(self, eig=None, prec=53): '6': (0.79, 1.3), '7': (0.21, -1.3), '8': (-0.88, 0.74)} - sage: t.rauzy_fractal_projection(eig=x, prec=10) + sage: t.rauzy_fractal_projection(eig=x, prec=10) # optional - sage.modules {'1': (1.0, 0.00), '2': (-0.12, -0.74), '3': (-0.66, -0.56), @@ -2616,19 +2617,20 @@ def rauzy_fractal_points(self, n=None, exchange=False, eig=None, translate=None, and ``'3'`` are respectively:: sage: s = WordMorphism('1->12,2->13,3->1') - sage: D = s.rauzy_fractal_points(n=100) - sage: len(D['1']) + sage: D = s.rauzy_fractal_points(n=100) # optional - sage.modules + sage: len(D['1']) # optional - sage.modules 54 - sage: len(D['2']) + sage: len(D['2']) # optional - sage.modules 30 - sage: len(D['3']) + sage: len(D['3']) # optional - sage.modules 16 TESTS:: sage: s = WordMorphism('1->12,2->13,3->1') - sage: D = s.rauzy_fractal_points(n=100, exchange=True, translate=[(3,1,-2), (5,-33,8)], prec=40) - sage: len(D['1']) + sage: D = s.rauzy_fractal_points(n=100, exchange=True, # optional - sage.modules + ....: translate=[(3,1,-2), (5,-33,8)], prec=40) + sage: len(D['1']) # optional - sage.modules 108 AUTHOR: @@ -2839,8 +2841,8 @@ def rauzy_fractal_plot(self, n=None, exchange=False, eig=None, #. Different fractals can be obtained by choosing another (non-Pisot) eigenvalue:: sage: s = WordMorphism('1->12,2->3,3->45,4->5,5->6,6->7,7->8,8->1') - sage: E = s.incidence_matrix().eigenvalues() - sage: x = [x for x in E if -0.8 < x < -0.7][0] + sage: E = s.incidence_matrix().eigenvalues() # optional - sage.modules + sage: x = [x for x in E if -0.8 < x < -0.7][0] # optional - sage.modules sage: s.rauzy_fractal_plot() # not tested (> 1 second) sage: s.rauzy_fractal_plot(eig=x) # not tested (> 1 second) @@ -2883,7 +2885,7 @@ def rauzy_fractal_plot(self, n=None, exchange=False, eig=None, :: sage: t = WordMorphism("a->aC,b->d,C->de,d->a,e->ab") # substitution found by Julien Bernat - sage: V = [vector((0,0,1,0,-1)), vector((0,0,1,-1,0))] + sage: V = [vector((0,0,1,0,-1)), vector((0,0,1,-1,0))] # optional - sage.modules sage: S = set(map(tuple, [i*V[0] + j*V[1] ....: for i in [-1,0,1] for j in [-1,0,1]])) sage: t.rauzy_fractal_plot(n=10000, # not tested (> 1 second) @@ -2907,7 +2909,7 @@ def rauzy_fractal_plot(self, n=None, exchange=False, eig=None, TESTS:: sage: s = WordMorphism('a->ab,b->c,c->d,d->e,e->a') - sage: s.rauzy_fractal_plot(n=1000, colormap='Set1', # optional - sage.plot + sage: s.rauzy_fractal_plot(n=1000, colormap='Set1', # optional - sage.modules sage.plot ....: opacity={'a':0.5,'b':1,'c':0.7,'d':0,'e':0.2}, ....: plot_origin=(100,"black"), plot_basis=True, ....: point_size=2.5) @@ -3327,24 +3329,24 @@ def abelian_rotation_subspace(self): EXAMPLES:: - sage: WordMorphism('0->1,1->0').abelian_rotation_subspace() + sage: WordMorphism('0->1,1->0').abelian_rotation_subspace() # optional - sage.modules Vector space of degree 2 and dimension 2 over Rational Field Basis matrix: [1 0] [0 1] - sage: WordMorphism('0->01,1->10').abelian_rotation_subspace() + sage: WordMorphism('0->01,1->10').abelian_rotation_subspace() # optional - sage.modules Vector space of degree 2 and dimension 0 over Rational Field Basis matrix: [] - sage: WordMorphism('0->01,1->1').abelian_rotation_subspace() + sage: WordMorphism('0->01,1->1').abelian_rotation_subspace() # optional - sage.modules Vector space of degree 2 and dimension 1 over Rational Field Basis matrix: [0 1] - sage: WordMorphism('1->122,2->211').abelian_rotation_subspace() + sage: WordMorphism('1->122,2->211').abelian_rotation_subspace() # optional - sage.modules Vector space of degree 2 and dimension 1 over Rational Field Basis matrix: [ 1 -1] - sage: WordMorphism('0->1,1->102,2->3,3->4,4->2').abelian_rotation_subspace() + sage: WordMorphism('0->1,1->102,2->3,3->4,4->2').abelian_rotation_subspace() # optional - sage.modules Vector space of degree 5 and dimension 3 over Rational Field Basis matrix: [0 0 1 0 0] @@ -3353,7 +3355,7 @@ def abelian_rotation_subspace(self): The domain needs to be equal to the codomain:: - sage: WordMorphism('0->1,1->',codomain=Words('01')).abelian_rotation_subspace() + sage: WordMorphism('0->1,1->',codomain=Words('01')).abelian_rotation_subspace() # optional - sage.modules Vector space of degree 2 and dimension 0 over Rational Field Basis matrix: [] diff --git a/src/sage/combinat/words/paths.py b/src/sage/combinat/words/paths.py index a924eb45c03..19bef31c3c5 100644 --- a/src/sage/combinat/words/paths.py +++ b/src/sage/combinat/words/paths.py @@ -104,14 +104,14 @@ Finite Dyck paths sage: d = D('()()()(())'); d Path: ()()()(()) - sage: d.plot() + sage: d.plot() # optional - sage.plot Graphics object consisting of 3 graphics primitives :: sage: P = WordPaths('abcdef', steps='triangle_grid') sage: p = P('babaddefadabcadefaadfafabacdefa') - sage: p.plot() + sage: p.plot() # optional - sage.plot Graphics object consisting of 3 graphics primitives Vector steps may be in more than 2 dimensions:: @@ -120,7 +120,7 @@ sage: P = WordPaths(alphabet='abc', steps=d); P Word Paths over 3 steps sage: p = P('abcabcabcabcaabacabcababcacbabacacabcaccbcac') - sage: p.plot() + sage: p.plot() # optional - sage.plot Graphics3d Object :: @@ -137,7 +137,7 @@ sage: CubePaths = WordPaths('abcABC', steps='cube_grid'); CubePaths Word Paths on the cube grid - sage: CubePaths('abcabaabcabAAAAA').plot() + sage: CubePaths('abcabaabcabAAAAA').plot() # optional - sage.plot Graphics3d Object The input data may be a str, a list, a tuple, diff --git a/src/sage/combinat/words/suffix_trees.py b/src/sage/combinat/words/suffix_trees.py index c7ae4af2aaf..c3646a36907 100644 --- a/src/sage/combinat/words/suffix_trees.py +++ b/src/sage/combinat/words/suffix_trees.py @@ -437,9 +437,9 @@ def to_digraph(self): sage: from sage.combinat.words.suffix_trees import SuffixTrie sage: w = Words("cao")("cac") sage: t = SuffixTrie(w) - sage: d = t.to_digraph(); d + sage: d = t.to_digraph(); d # optional - sage.graphs Digraph on 6 vertices - sage: d.adjacency_matrix() + sage: d.adjacency_matrix() # optional - sage.graphs sage.modules [0 1 0 1 0 0] [0 0 1 0 0 0] [0 0 0 0 1 0] @@ -829,7 +829,7 @@ def to_digraph(self, word_labels=False): sage: from sage.combinat.words.suffix_trees import ImplicitSuffixTree sage: W = Words([0,1,2]) sage: t = ImplicitSuffixTree(W([0,1,0,1,2])) - sage: t.to_digraph() + sage: t.to_digraph() # optional - sage.graphs Digraph on 8 vertices """ if not self._letters: @@ -865,17 +865,17 @@ def plot(self, word_labels=False, layout='tree', tree_root=0, EXAMPLES:: sage: from sage.combinat.words.suffix_trees import ImplicitSuffixTree - sage: ImplicitSuffixTree(Word('cacao')).plot(word_labels=True) # optional - sage.plot + sage: ImplicitSuffixTree(Word('cacao')).plot(word_labels=True) # optional - sage.graphs sage.plot Graphics object consisting of 23 graphics primitives - sage: ImplicitSuffixTree(Word('cacao')).plot(word_labels=False) # optional - sage.plot + sage: ImplicitSuffixTree(Word('cacao')).plot(word_labels=False) # optional - sage.graphs sage.plot Graphics object consisting of 23 graphics primitives TESTS:: sage: from sage.combinat.words.suffix_trees import ImplicitSuffixTree - sage: type(ImplicitSuffixTree(Word('cacao')).plot(word_labels=True)) # optional - sage.plot + sage: type(ImplicitSuffixTree(Word('cacao')).plot(word_labels=True)) # optional - sage.graphs sage.plot <class 'sage.plot.graphics.Graphics'> - sage: type(ImplicitSuffixTree(Word('cacao')).plot(word_labels=False)) # optional - sage.plot + sage: type(ImplicitSuffixTree(Word('cacao')).plot(word_labels=False)) # optional - sage.graphs sage.plot <class 'sage.plot.graphics.Graphics'> """ tree = self.to_digraph(word_labels=word_labels) @@ -1506,7 +1506,7 @@ def uncompactify(self): sage: abbab = Words("ab")("abbab") sage: s = SuffixTrie(abbab) sage: t = ImplicitSuffixTree(abbab) - sage: t.uncompactify().is_isomorphic(s.to_digraph()) + sage: t.uncompactify().is_isomorphic(s.to_digraph()) # optional - sage.graphs True """ tree = self.to_digraph(word_labels=True) diff --git a/src/sage/combinat/words/word.py b/src/sage/combinat/words/word.py index 051d0a1a702..4555c2df762 100644 --- a/src/sage/combinat/words/word.py +++ b/src/sage/combinat/words/word.py @@ -263,7 +263,7 @@ class FiniteWord_char(WordDatatype_char, FiniteWord_class): sage: len(w.factor_set()) 127 - sage: w.rauzy_graph(5) + sage: w.rauzy_graph(5) # optional - sage.graphs Looped digraph on 9 vertices sage: u = W([1,2,3]) diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index f046db3c46e..5790a56e440 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -241,10 +241,10 @@ def markoff_number(self): sage: w0 = words.LowerChristoffelWord(4,7) sage: w1, w2 = w0.standard_factorization() - sage: (m0,m1,m2) = (w.markoff_number() for w in (w0,w1,w2)) - sage: (m0,m1,m2) + sage: (m0,m1,m2) = (w.markoff_number() for w in (w0,w1,w2)) # optional - sage.modules + sage: (m0,m1,m2) # optional - sage.modules (294685, 13, 7561) - sage: m0**2 + m1**2 + m2**2 == 3*m0*m1*m2 + sage: m0**2 + m1**2 + m2**2 == 3*m0*m1*m2 # optional - sage.modules True """ from sage.matrix.constructor import matrix @@ -640,7 +640,7 @@ def FixedPointOfMorphism(self, morphism, first_letter): sage: tm = words.FixedPointOfMorphism(mu,0); tm word: 0110100110010110100101100110100110010110... sage: TM = words.ThueMorseWord() - sage: tm[:1000] == TM[:1000] + sage: tm[:1000] == TM[:1000] # optional - sage.modules True :: @@ -650,7 +650,7 @@ def FixedPointOfMorphism(self, morphism, first_letter): word: 0100101001001010010100100101001001010010... sage: F = words.FibonacciWord(); F word: 0100101001001010010100100101001001010010... - sage: f[:1000] == F[:1000] + sage: f[:1000] == F[:1000] # optional - sage.modules True :: @@ -1520,7 +1520,7 @@ def fibonacci_tile(self, n): EXAMPLES:: - sage: for i in range(3): words.fibonacci_tile(i) + sage: for i in range(3): words.fibonacci_tile(i) # optional - sage.modules Path: 3210 Path: 323030101212 Path: 3230301030323212323032321210121232121010... @@ -1538,7 +1538,7 @@ def dual_fibonacci_tile(self, n): EXAMPLES:: - sage: for i in range(4): words.dual_fibonacci_tile(i) + sage: for i in range(4): words.dual_fibonacci_tile(i) # optional - sage.modules Path: 3210 Path: 32123032301030121012 Path: 3212303230103230321232101232123032123210... diff --git a/src/sage/combinat/words/words.py b/src/sage/combinat/words/words.py index c0a4457df85..50cb3db11e8 100644 --- a/src/sage/combinat/words/words.py +++ b/src/sage/combinat/words/words.py @@ -705,9 +705,9 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr Construction of a word path from a finite word:: sage: W = FiniteWords('abcd') - sage: P = WordPaths('abcd') + sage: P = WordPaths('abcd') # optional - sage.modules sage: w = W('aaab') - sage: P(w) + sage: P(w) # optional - sage.modules Path: aaab Construction of a word path from a Christoffel word:: @@ -715,8 +715,8 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr sage: w = words.ChristoffelWord(5,8) sage: w word: 0010010100101 - sage: P = WordPaths([0,1,2,3]) - sage: P(w) + sage: P = WordPaths([0,1,2,3]) # optional - sage.modules + sage: P(w) # optional - sage.modules Path: 0010010100101 Construction of a word represented by a list from a word @@ -744,19 +744,19 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr sage: w = words.FibonacciWord() sage: f = w[:100] - sage: P = WordPaths([0,1,2,3]) - sage: p = P(f); p + sage: P = WordPaths([0,1,2,3]) # optional - sage.modules + sage: p = P(f); p # optional - sage.modules Path: 0100101001001010010100100101001001010010... - sage: p.length() + sage: p.length() # optional - sage.modules 100 Creation of a word path from a FiniteWord_callable:: sage: g = W(lambda n:n%2, length = 100) - sage: P = WordPaths([0,1,2,3]) - sage: p = P(g); p + sage: P = WordPaths([0,1,2,3]) # optional - sage.modules + sage: p = P(g); p # optional - sage.modules Path: 0101010101010101010101010101010101010101... - sage: p.length() + sage: p.length() # optional - sage.modules 100 Creation of a word from a pickled function:: @@ -1018,7 +1018,7 @@ def random_element(self, length=None, *args, **kwds): TESTS:: - sage: _ = FiniteWords(GF(5)).random_element() + sage: _ = FiniteWords(GF(5)).random_element() # optional - sage.rings.finite_rings """ if length is None: length = ZZ.random_element(0, 10) @@ -1928,9 +1928,9 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr Construction of a word path from a finite word:: sage: W = Words('abcd') - sage: P = WordPaths('abcd') + sage: P = WordPaths('abcd') # optional - sage.modules sage: w = W('aaab') - sage: P(w) + sage: P(w) # optional - sage.modules Path: aaab Construction of a word path from a Christoffel word:: @@ -1938,8 +1938,8 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr sage: w = words.ChristoffelWord(5,8) sage: w word: 0010010100101 - sage: P = WordPaths([0,1,2,3]) - sage: P(w) + sage: P = WordPaths([0,1,2,3]) # optional - sage.modules + sage: P(w) # optional - sage.modules Path: 0010010100101 Construction of a word represented by a list from a word @@ -1967,19 +1967,19 @@ def __call__(self, data=None, length=None, datatype=None, caching=True, check=Tr sage: w = words.FibonacciWord() sage: f = w[:100] - sage: P = WordPaths([0,1,2,3]) - sage: p = P(f); p + sage: P = WordPaths([0,1,2,3]) # optional - sage.modules + sage: p = P(f); p # optional - sage.modules Path: 0100101001001010010100100101001001010010... - sage: p.length() + sage: p.length() # optional - sage.modules 100 Creation of a word path from a FiniteWord_callable:: - sage: g = Word(lambda n:n%2, length = 100) - sage: P = WordPaths([0,1,2,3]) - sage: p = P(g); p + sage: g = Word(lambda n: n%2, length=100) + sage: P = WordPaths([0,1,2,3]) # optional - sage.modules + sage: p = P(g); p # optional - sage.modules Path: 0101010101010101010101010101010101010101... - sage: p.length() + sage: p.length() # optional - sage.modules 100 Creation of a word from a pickled function:: @@ -2215,7 +2215,7 @@ def random_element(self, *args, **kwds): TESTS:: - sage: _ = Words(GF(5),4).random_element() + sage: _ = Words(GF(5),4).random_element() # optional - sage.rings.finite_rings Check that :trac:`18283` is fixed:: diff --git a/src/sage/combinat/yang_baxter_graph.py b/src/sage/combinat/yang_baxter_graph.py index f5e5646c633..cfacceda6e1 100644 --- a/src/sage/combinat/yang_baxter_graph.py +++ b/src/sage/combinat/yang_baxter_graph.py @@ -68,7 +68,7 @@ def YangBaxterGraph(partition=None, root=None, operators=None): The ``partition`` keyword is a shorthand for the above construction:: - sage: Y = YangBaxterGraph(partition=[3,1]); Y + sage: Y = YangBaxterGraph(partition=[3,1]); Y # optional - sage.combinat Yang-Baxter graph of [3, 1], with top vertex (0, 2, 1, 0) sage: Y.vertices(sort=True) [(0, 2, 1, 0), (2, 0, 1, 0), (2, 1, 0, 0)] @@ -86,18 +86,18 @@ def YangBaxterGraph(partition=None, root=None, operators=None): sage: def left_multiplication_by(g): ....: return lambda h: h*g - sage: G = CyclicPermutationGroup(4) - sage: operators = [ left_multiplication_by(gen) for gen in G.gens() ] - sage: Y = YangBaxterGraph(root=G.identity(), operators=operators); Y + sage: G = CyclicPermutationGroup(4) # optional - sage.groups + sage: operators = [ left_multiplication_by(gen) for gen in G.gens() ] # optional - sage.groups + sage: Y = YangBaxterGraph(root=G.identity(), operators=operators); Y # optional - sage.groups Yang-Baxter graph with root vertex () - sage: Y.plot(edge_labels=False) # optional - sage.plot + sage: Y.plot(edge_labels=False) # optional - sage.groups sage.plot Graphics object consisting of 9 graphics primitives - sage: G = SymmetricGroup(4) - sage: operators = [left_multiplication_by(gen) for gen in G.gens()] - sage: Y = YangBaxterGraph(root=G.identity(), operators=operators); Y + sage: G = SymmetricGroup(4) # optional - sage.groups + sage: operators = [left_multiplication_by(gen) for gen in G.gens()] # optional - sage.groups + sage: Y = YangBaxterGraph(root=G.identity(), operators=operators); Y # optional - sage.groups Yang-Baxter graph with root vertex () - sage: Y.plot(edge_labels=False) # optional - sage.plot + sage: Y.plot(edge_labels=False) # optional - sage.groups sage.plot Graphics object consisting of 96 graphics primitives AUTHORS: @@ -361,7 +361,7 @@ def root(self): sage: Y = YangBaxterGraph(root=(1,0,3,2,1,0), operators=ops) sage: Y.root() (1, 0, 3, 2, 1, 0) - sage: Y = YangBaxterGraph(partition=[3,2]) + sage: Y = YangBaxterGraph(partition=[3,2]) # optional - sage.combinat sage: Y.root() (1, 0, 2, 1, 0) """ @@ -572,9 +572,9 @@ def __init__(self, partition): EXAMPLES:: - sage: Y = YangBaxterGraph(partition=[3,2,1]); Y + sage: Y = YangBaxterGraph(partition=[3,2,1]); Y # optional - sage.combinat Yang-Baxter graph of [3, 2, 1], with top vertex (0, 1, 0, 2, 1, 0) - sage: loads(dumps(Y)) == Y + sage: loads(dumps(Y)) == Y # optional - sage.combinat True AUTHORS: @@ -592,8 +592,8 @@ def __repr__(self): r""" EXAMPLES:: - sage: Y = YangBaxterGraph(partition=[3,2]) - sage: Y.__repr__() + sage: Y = YangBaxterGraph(partition=[3,2]) # optional - sage.combinat + sage: Y.__repr__() # optional - sage.combinat 'Yang-Baxter graph of [3, 2], with top vertex (1, 0, 2, 1, 0)' """ return "Yang-Baxter graph of %s, with top vertex %s" % (self._partition, self._root) @@ -604,13 +604,13 @@ def __copy__(self): EXAMPLES:: - sage: Y = YangBaxterGraph(partition=[3,2]); Y + sage: Y = YangBaxterGraph(partition=[3,2]); Y # optional - sage.combinat Yang-Baxter graph of [3, 2], with top vertex (1, 0, 2, 1, 0) - sage: B = copy(Y); B + sage: B = copy(Y); B # optional - sage.combinat Yang-Baxter graph of [3, 2], with top vertex (1, 0, 2, 1, 0) - sage: Y is B + sage: Y is B # optional - sage.combinat False - sage: Y == B + sage: Y == B # optional - sage.combinat True """ from copy import copy @@ -626,10 +626,10 @@ def _digraph(self): EXAMPLES:: - sage: Y = YangBaxterGraph(partition=[2,1]) - sage: Y._digraph + sage: Y = YangBaxterGraph(partition=[2,1]) # optional - sage.combinat + sage: Y._digraph # optional - sage.combinat Digraph on 2 vertices - sage: Y.edges() + sage: Y.edges() # optional - sage.combinat [((0, 1, 0), (1, 0, 0), Swap positions 0 and 1)] """ digraph = super()._digraph @@ -645,8 +645,8 @@ def _vertex_ordering(self): EXAMPLES:: - sage: Y = YangBaxterGraph(partition=[3,2]) - sage: Y._vertex_ordering + sage: Y = YangBaxterGraph(partition=[3,2]) # optional - sage.combinat + sage: Y._vertex_ordering # optional - sage.combinat [(1, 0, 2, 1, 0), (1, 2, 0, 1, 0), (1, 2, 1, 0, 0), (2, 1, 0, 1, 0), (2, 1, 1, 0, 0)] """ return self._digraph.vertices(sort=True) @@ -661,8 +661,8 @@ def __iter__(self): EXAMPLES:: - sage: Y = YangBaxterGraph(partition=[3,2]) - sage: list(Y.__iter__()) + sage: Y = YangBaxterGraph(partition=[3,2]) # optional - sage.combinat + sage: list(Y.__iter__()) # optional - sage.combinat [(1, 0, 2, 1, 0), (1, 2, 0, 1, 0), (1, 2, 1, 0, 0), (2, 1, 0, 1, 0), (2, 1, 1, 0, 0)] """ for v in self._vertex_ordering: @@ -680,14 +680,14 @@ def _swap_operator(self, operator, u): EXAMPLES:: - sage: Y = YangBaxterGraph(partition=[3,1]) - sage: from sage.combinat.yang_baxter_graph import SwapOperator - sage: ops = [SwapOperator(i) for i in range(3)] - sage: [Y._swap_operator(op, (1,2,3,4)) for op in ops] + sage: Y = YangBaxterGraph(partition=[3,1]) # optional - sage.combinat + sage: from sage.combinat.yang_baxter_graph import SwapOperator # optional - sage.combinat + sage: ops = [SwapOperator(i) for i in range(3)] # optional - sage.combinat + sage: [Y._swap_operator(op, (1,2,3,4)) for op in ops] # optional - sage.combinat [(2, 1, 3, 4), (1, 3, 2, 4), (1, 2, 4, 3)] - sage: [Y._swap_operator(op, [4,3,2,1]) for op in ops] + sage: [Y._swap_operator(op, [4,3,2,1]) for op in ops] # optional - sage.combinat [[3, 4, 2, 1], [4, 2, 3, 1], [4, 3, 1, 2]] - sage: [Y._swap_operator(op, Permutation([1,2,3,4])) for op in ops] + sage: [Y._swap_operator(op, Permutation([1,2,3,4])) for op in ops] # optional - sage.combinat [[2, 1, 3, 4], [1, 3, 2, 4], [1, 2, 4, 3]] """ return operator(u) @@ -710,12 +710,12 @@ def vertex_relabelling_dict(self, v): EXAMPLES:: - sage: Y = YangBaxterGraph(partition=[3,1]) - sage: Y.vertex_relabelling_dict((1,2,3,4)) + sage: Y = YangBaxterGraph(partition=[3,1]) # optional - sage.combinat + sage: Y.vertex_relabelling_dict((1,2,3,4)) # optional - sage.combinat {(0, 2, 1, 0): (1, 2, 3, 4), (2, 0, 1, 0): (2, 1, 3, 4), (2, 1, 0, 0): (2, 3, 1, 4)} - sage: Y.vertex_relabelling_dict((4,3,2,1)) + sage: Y.vertex_relabelling_dict((4,3,2,1)) # optional - sage.combinat {(0, 2, 1, 0): (4, 3, 2, 1), (2, 0, 1, 0): (3, 4, 2, 1), (2, 1, 0, 0): (3, 2, 4, 1)} @@ -737,14 +737,14 @@ def relabel_vertices(self, v, inplace=True): EXAMPLES:: - sage: Y = YangBaxterGraph(partition=[3,1]); Y + sage: Y = YangBaxterGraph(partition=[3,1]); Y # optional - sage.combinat Yang-Baxter graph of [3, 1], with top vertex (0, 2, 1, 0) - sage: d = Y.relabel_vertices((1,2,3,4), inplace=False); d + sage: d = Y.relabel_vertices((1,2,3,4), inplace=False); d # optional - sage.combinat Digraph on 3 vertices - sage: Y.vertices(sort=True) + sage: Y.vertices(sort=True) # optional - sage.combinat [(0, 2, 1, 0), (2, 0, 1, 0), (2, 1, 0, 0)] - sage: e = Y.relabel_vertices((1,2,3,4)); e - sage: Y.vertices(sort=True) + sage: e = Y.relabel_vertices((1,2,3,4)); e # optional - sage.combinat + sage: Y.vertices(sort=True) # optional - sage.combinat [(1, 2, 3, 4), (2, 1, 3, 4), (2, 3, 1, 4)] """ relabelling = self.vertex_relabelling_dict(v) @@ -911,7 +911,7 @@ def __call__(self, u): EXAMPLES:: - sage: Y = YangBaxterGraph(partition=[2,2]) + sage: Y = YangBaxterGraph(partition=[2,2]) # optional - sage.combinat sage: from sage.combinat.yang_baxter_graph import SwapIncreasingOperator sage: operators = [SwapIncreasingOperator(i) for i in range(3)] sage: [op((1,2,3,4)) for op in operators] From 1380e8ef236aacfd90d16b6b23729d0292440096 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sat, 3 Jun 2023 19:51:55 -0700 Subject: [PATCH 065/228] Remove stray file --- src/sage/rings/polynomial/all__sagemath_polyhedra.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/sage/rings/polynomial/all__sagemath_polyhedra.py diff --git a/src/sage/rings/polynomial/all__sagemath_polyhedra.py b/src/sage/rings/polynomial/all__sagemath_polyhedra.py deleted file mode 100644 index e69de29bb2d..00000000000 From a8dbc7062c0d88893f99997b34c03066b3fbd289 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Wed, 7 Jun 2023 11:36:07 -0700 Subject: [PATCH 066/228] sage.categories: More # optional --- src/sage/categories/homset.py | 12 ++++---- src/sage/categories/quotient_fields.py | 26 ++++++++--------- src/sage/categories/simplicial_sets.py | 40 +++++++++++++------------- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/sage/categories/homset.py b/src/sage/categories/homset.py index a5a438f8727..46c9de2ab04 100644 --- a/src/sage/categories/homset.py +++ b/src/sage/categories/homset.py @@ -592,15 +592,15 @@ class Homset(Set_generic): Conversely, homsets of non-unique parents are non-unique:: - sage: P11 = ProductProjectiveSpaces(QQ, [1, 1]) - sage: H = End(P11) - sage: loads(dumps(P11)) is ProductProjectiveSpaces(QQ, [1, 1]) + sage: P11 = ProductProjectiveSpaces(QQ, [1, 1]) # optional - sage.schemes + sage: H = End(P11) # optional - sage.schemes + sage: loads(dumps(P11)) is ProductProjectiveSpaces(QQ, [1, 1]) # optional - sage.schemes False - sage: loads(dumps(P11)) == ProductProjectiveSpaces(QQ, [1, 1]) + sage: loads(dumps(P11)) == ProductProjectiveSpaces(QQ, [1, 1]) # optional - sage.schemes True - sage: loads(dumps(H)) is H + sage: loads(dumps(H)) is H # optional - sage.schemes False - sage: loads(dumps(H)) == H + sage: loads(dumps(H)) == H # optional - sage.schemes True """ def __init__(self, X, Y, category=None, base=None, check=True): diff --git a/src/sage/categories/quotient_fields.py b/src/sage/categories/quotient_fields.py index 181cd0ff611..2a79049bd62 100644 --- a/src/sage/categories/quotient_fields.py +++ b/src/sage/categories/quotient_fields.py @@ -496,7 +496,7 @@ def partial_fraction_decomposition(self, decompose_powers=True): sage: S.<t> = QQ[] sage: r = t / (t^3+1)^5 - sage: r.partial_fraction_decomposition() + sage: r.partial_fraction_decomposition() # optional - sage.libs.pari (0, [-35/729/(t + 1), -35/729/(t^2 + 2*t + 1), @@ -508,37 +508,37 @@ def partial_fraction_decomposition(self, decompose_powers=True): (-1/81*t + 5/81)/(t^6 - 3*t^5 + 6*t^4 - 7*t^3 + 6*t^2 - 3*t + 1), (-2/27*t + 1/9)/(t^8 - 4*t^7 + 10*t^6 - 16*t^5 + 19*t^4 - 16*t^3 + 10*t^2 - 4*t + 1), (-2/27*t + 1/27)/(t^10 - 5*t^9 + 15*t^8 - 30*t^7 + 45*t^6 - 51*t^5 + 45*t^4 - 30*t^3 + 15*t^2 - 5*t + 1)]) - sage: sum(r.partial_fraction_decomposition()[1]) == r + sage: sum(r.partial_fraction_decomposition()[1]) == r # optional - sage.libs.pari True Some special cases:: sage: R = Frac(QQ['x']); x = R.gen() - sage: x.partial_fraction_decomposition() + sage: x.partial_fraction_decomposition() # optional - sage.libs.pari (x, []) - sage: R(0).partial_fraction_decomposition() + sage: R(0).partial_fraction_decomposition() # optional - sage.libs.pari (0, []) - sage: R(1).partial_fraction_decomposition() + sage: R(1).partial_fraction_decomposition() # optional - sage.libs.pari (1, []) - sage: (1/x).partial_fraction_decomposition() + sage: (1/x).partial_fraction_decomposition() # optional - sage.libs.pari (0, [1/x]) - sage: (1/x+1/x^3).partial_fraction_decomposition() + sage: (1/x+1/x^3).partial_fraction_decomposition() # optional - sage.libs.pari (0, [1/x, 1/x^3]) This was fixed in :trac:`16240`:: sage: R.<x> = QQ['x'] sage: p = 1/(-x + 1) - sage: whole,parts = p.partial_fraction_decomposition() - sage: p == sum(parts) + sage: whole,parts = p.partial_fraction_decomposition() # optional - sage.libs.pari + sage: p == sum(parts) # optional - sage.libs.pari True sage: p = 3/(-x^4 + 1) - sage: whole,parts = p.partial_fraction_decomposition() - sage: p == sum(parts) + sage: whole,parts = p.partial_fraction_decomposition() # optional - sage.libs.pari + sage: p == sum(parts) # optional - sage.libs.pari True sage: p = (6*x^2 - 9*x + 5)/(-x^3 + 3*x^2 - 3*x + 1) - sage: whole,parts = p.partial_fraction_decomposition() - sage: p == sum(parts) + sage: whole,parts = p.partial_fraction_decomposition() # optional - sage.libs.pari + sage: p == sum(parts) # optional - sage.libs.pari True """ denom = self.denominator() diff --git a/src/sage/categories/simplicial_sets.py b/src/sage/categories/simplicial_sets.py index 43a13dfe473..72c49da833c 100644 --- a/src/sage/categories/simplicial_sets.py +++ b/src/sage/categories/simplicial_sets.py @@ -236,11 +236,11 @@ def base_point_map(self, domain=None): sage: g = S3.base_point_map() # optional - sage.graphs sage: f.domain() == g.domain() # optional - sage.graphs True - sage: RP3 = simplicial_sets.RealProjectiveSpace(3) # optional - sage.graphs - sage: temp = simplicial_sets.Simplex(0) # optional - sage.graphs - sage: pt = temp.set_base_point(temp.n_cells(0)[0]) # optional - sage.graphs - sage: h = RP3.base_point_map(domain=pt) # optional - sage.graphs - sage: f.domain() == h.domain() # optional - sage.graphs + sage: RP3 = simplicial_sets.RealProjectiveSpace(3) # optional - sage.graphs sage.groups + sage: temp = simplicial_sets.Simplex(0) # optional - sage.graphs sage.groups + sage: pt = temp.set_base_point(temp.n_cells(0)[0]) # optional - sage.graphs sage.groups + sage: h = RP3.base_point_map(domain=pt) # optional - sage.graphs sage.groups + sage: f.domain() == h.domain() # optional - sage.graphs sage.groups False sage: C5 = groups.misc.MultiplicativeAbelian([5]) # optional - sage.graphs sage.groups @@ -304,7 +304,7 @@ def fundamental_group(self, simplify=True): sage: X_1.fundamental_group().is_abelian() # optional - sage.graphs sage.groups False - sage: RP3 = simplicial_sets.RealProjectiveSpace(3) # optional - sage.graphs + sage: RP3 = simplicial_sets.RealProjectiveSpace(3) # optional - sage.graphs sage.groups sage: RP3.fundamental_group() # optional - sage.graphs sage.groups Finitely presented group < e | e^2 > @@ -431,7 +431,7 @@ def covering_map(self, character): EXAMPLES:: - sage: S1 = simplicial_sets.Sphere(1) + sage: S1 = simplicial_sets.Sphere(1) # optional - sage.graphs sage: W = S1.wedge(S1) # optional - sage.graphs sage: G = CyclicPermutationGroup(3) # optional - sage.groups sage: a, b = W.n_cells(1) # optional - sage.graphs @@ -518,7 +518,7 @@ def cover(self, character): EXAMPLES:: - sage: S1 = simplicial_sets.Sphere(1) + sage: S1 = simplicial_sets.Sphere(1) # optional - sage.graphs sage: W = S1.wedge(S1) # optional - sage.graphs sage: G = CyclicPermutationGroup(3) # optional - sage.groups sage: (a, b) = W.n_cells(1) # optional - sage.graphs @@ -580,20 +580,20 @@ def is_simply_connected(self): EXAMPLES:: sage: T = simplicial_sets.Torus() # optional - sage.graphs - sage: T.is_simply_connected() # optional - sage.graphs + sage: T.is_simply_connected() # optional - sage.graphs sage.groups False - sage: T.suspension().is_simply_connected() # optional - sage.graphs + sage: T.suspension().is_simply_connected() # optional - sage.graphs sage.groups True - sage: simplicial_sets.KleinBottle().is_simply_connected() # optional - sage.graphs + sage: simplicial_sets.KleinBottle().is_simply_connected() # optional - sage.graphs sage.groups False sage: S2 = simplicial_sets.Sphere(2) # optional - sage.graphs sage: S3 = simplicial_sets.Sphere(3) # optional - sage.graphs - sage: (S2.wedge(S3)).is_simply_connected() # optional - sage.graphs + sage: (S2.wedge(S3)).is_simply_connected() # optional - sage.graphs sage.groups True sage: X = S2.disjoint_union(S3) # optional - sage.graphs sage: X = X.set_base_point(X.n_cells(0)[0]) # optional - sage.graphs - sage: X.is_simply_connected() # optional - sage.graphs + sage: X.is_simply_connected() # optional - sage.graphs sage.groups False sage: C3 = groups.misc.MultiplicativeAbelian([3]) # optional - sage.graphs sage.groups @@ -642,16 +642,16 @@ def connectivity(self, max_dim=None): EXAMPLES:: - sage: simplicial_sets.Sphere(3).connectivity() # optional - sage.graphs + sage: simplicial_sets.Sphere(3).connectivity() # optional - sage.graphs sage.groups 2 - sage: simplicial_sets.Sphere(0).connectivity() # optional - sage.graphs + sage: simplicial_sets.Sphere(0).connectivity() # optional - sage.graphs sage.groups -1 sage: K = simplicial_sets.Simplex(4) # optional - sage.graphs sage: K = K.set_base_point(K.n_cells(0)[0]) # optional - sage.graphs - sage: K.connectivity() # optional - sage.graphs + sage: K.connectivity() # optional - sage.graphs sage.groups +Infinity sage: X = simplicial_sets.Torus().suspension(2) # optional - sage.graphs - sage: X.connectivity() # optional - sage.graphs + sage: X.connectivity() # optional - sage.graphs sage.groups 2 sage: C2 = groups.misc.MultiplicativeAbelian([2]) # optional - sage.graphs sage.groups @@ -747,9 +747,9 @@ def smash_product(self, *others): EXAMPLES:: sage: S1 = simplicial_sets.Sphere(1) # optional - sage.graphs - sage: RP2 = simplicial_sets.RealProjectiveSpace(2) # optional - sage.graphs - sage: X = S1.smash_product(RP2) # optional - sage.graphs - sage: X.homology(base_ring=GF(2)) # optional - sage.graphs sage.modules + sage: RP2 = simplicial_sets.RealProjectiveSpace(2) # optional - sage.graphs sage.groups + sage: X = S1.smash_product(RP2) # optional - sage.graphs sage.groups + sage: X.homology(base_ring=GF(2)) # optional - sage.graphs sage.groups sage.modules sage.rings.finite_rings {0: Vector space of dimension 0 over Finite Field of size 2, 1: Vector space of dimension 0 over Finite Field of size 2, 2: Vector space of dimension 1 over Finite Field of size 2, From 314343129c3b02be1ece2d98a386dd26c4e6f9e1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Wed, 7 Jun 2023 12:14:35 -0700 Subject: [PATCH 067/228] src/sage/combinat/cluster_algebra_quiver/cluster_seed.py: Wrap some lines of excessive length --- .../cluster_algebra_quiver/cluster_seed.py | 429 +++++++++++------- 1 file changed, 272 insertions(+), 157 deletions(-) diff --git a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py index 8f8a2a9fb3c..cdfea6ab767 100644 --- a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py +++ b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py @@ -2,7 +2,7 @@ r""" ClusterSeed -A *cluster seed* is a pair `(B,\mathbf{x})` with `B` being a *skew-symmetrizable* `(n+m \times n)` *-matrix* +A *cluster seed* is a pair `(B,\mathbf{x})` with `B` being a *skew-symmetrizable* `(n+m) \times n` *-matrix* and with `\mathbf{x}` being an `n`-tuple of *independent elements* in the field of rational functions in `n` variables. For the compendium on the cluster algebra and quiver package see @@ -67,7 +67,8 @@ class ClusterSeed(SageObject): - ``data`` -- can be any of the following:: * :class:`QuiverMutationType` - * :class:`str` -- a string representing a :class:`QuiverMutationType` or a common quiver type (see Examples) + * :class:`str` -- a string representing a :class:`QuiverMutationType` + or a common quiver type (see Examples) * :class:`ClusterQuiver` * :class:`Matrix` -- a skew-symmetrizable matrix * :class:`DiGraph` -- must be the input data for a quiver @@ -130,46 +131,61 @@ class ClusterSeed(SageObject): def __init__(self, data, frozen=None, is_principal=False, user_labels=None, user_labels_prefix='x'): r""" - - Initializes the ClusterSeed ``self`` with the following range of possible attributes: - - * self._n - the number of mutable elements of the cluster seed. - * self._m - the number of immutable elements of the cluster seed. - * self._nlist - a list of mutable elements of the cluster seed. - * self._mlist - a list of immutable elements of the cluster seed. - * self._M - the 'n + m' x 'n' exchange matrix associated to the cluster seed. - * self._B - the mutable part of self._M. - * self._b_initial - the initial exchange matrix - * self._description - the description of the ClusterSeed - * self._use_fpolys - a boolean tracking whether F-polynomials and cluster variables will be tracked as part of every mutation. - * self._cluster - a list tracking the current names of cluster elements. - * self._user_labels_prefix - the prefix for every named cluster element. Defaults to 'x'. - * self._user_labels - an optional dictionary or list of user - defined names for all cluster elements. Defaults to ``'x_i'`` - for mutable elements and ``'y_i'`` for immutable elements. - All labels should be integers or alphanumeric strings. - * self._init_vars - an internal list for defining ambient the algebraic setting and naming quiver vertices. - * self._init_exch - the dictionary storing the initial mutable cluster variable names. - * self._U - the coefficient tuple of the initial cluster seed. - * self._F - the dictionary of F-polynomials. - * self._R - the ambient polynomial ring. - * self._y - the coefficient tuple for the current cluster seed. - * self._yhat - the mixed coefficient tuple appearing in Proposition 3.9 of [FZ2007] - * self._use_g_vec - a boolean stating if g-vectors for the cluster seed are being tracked. User input overridden as needed. - * self._G - the matrix containing all g-vectors. - * self._use_d_vec - a boolean stating if d-vectors for the cluster seed are being tracked. - * self._D - the matrix containing all d-vectors. - * self._bot_is_c - a boolean stating if the c-vectors are stored on the bottom of the exchange matrix M. - * self._use_c_vec - a boolean stating if c-vectors for the cluster seed are being tracked. User input overridden as needed. - * self._C - the matrix containing all c-vectors. - * self._BC - an extended matrix involving the B and C matrices used for simplifying mutation calculations. - * self._is_principal - a boolean tracking whether the ClusterSeed contains immutable elements coming from a principal extension of the mutable vertices. To be deprecated in future versions. - - * self._quiver - the ClusterQuiver corresponding to the exchange matrix self._M . - * self._mutation_type - the mutation type of self._quiver . - - * self._track_mut - a boolean tracking whether the ClusterSeed's mutation path is being recorded. - * self._mut_path - the list of integers recording the mutation path of a seed - with consecutive repeats deleted since mutations is an involution. + Initialize the ClusterSeed ``self`` with the following range of possible attributes: + + * self._n - the number of mutable elements of the cluster seed. + * self._m - the number of immutable elements of the cluster seed. + * self._nlist - a list of mutable elements of the cluster seed. + * self._mlist - a list of immutable elements of the cluster seed. + * self._M - the 'n + m' x 'n' exchange matrix associated to the cluster seed. + * self._B - the mutable part of self._M. + * self._b_initial - the initial exchange matrix + * self._description - the description of the ClusterSeed + * self._use_fpolys - a boolean tracking whether F-polynomials and cluster + variables will be tracked as part of every mutation. + * self._cluster - a list tracking the current names of cluster elements. + * self._user_labels_prefix - the prefix for every named cluster element. + Defaults to 'x'. + * self._user_labels - an optional dictionary or list of user + defined names for all cluster elements. Defaults to ``'x_i'`` + for mutable elements and ``'y_i'`` for immutable elements. + All labels should be integers or alphanumeric strings. + * self._init_vars - an internal list for defining ambient + the algebraic setting and naming quiver vertices. + * self._init_exch - the dictionary storing the initial + mutable cluster variable names. + * self._U - the coefficient tuple of the initial cluster seed. + * self._F - the dictionary of F-polynomials. + * self._R - the ambient polynomial ring. + * self._y - the coefficient tuple for the current cluster seed. + * self._yhat - the mixed coefficient tuple appearing in + Proposition 3.9 of [FZ2007] + * self._use_g_vec - a boolean stating if g-vectors for the cluster seed + are being tracked. User input overridden as needed. + * self._G - the matrix containing all g-vectors. + * self._use_d_vec - a boolean stating if d-vectors for the cluster seed + are being tracked. + * self._D - the matrix containing all d-vectors. + * self._bot_is_c - a boolean stating if the c-vectors are stored + on the bottom of the exchange matrix M. + * self._use_c_vec - a boolean stating if c-vectors for the cluster seed + are being tracked. User input overridden as needed. + * self._C - the matrix containing all c-vectors. + * self._BC - an extended matrix involving the B and C matrices used + for simplifying mutation calculations. + * self._is_principal - a boolean tracking whether the ClusterSeed + contains immutable elements coming from a principal extension + of the mutable vertices. To be deprecated in future versions. + + * self._quiver - the ClusterQuiver corresponding to the + exchange matrix ``self._M``. + * self._mutation_type - the mutation type of self._quiver . + + * self._track_mut - a boolean tracking whether the ClusterSeed's + mutation path is being recorded. + * self._mut_path - the list of integers recording the mutation path of + a seed - with consecutive repeats deleted since mutations + is an involution. TESTS:: @@ -371,16 +387,20 @@ def use_c_vectors(self, use=True, bot_is_c=False, force=False): INPUT: - ``use`` -- (default: ``True``) If ``True``, will use c-vectors - - ``bot_is_c`` -- (default: ``False``) If ``True`` and :class:`ClusterSeed` ``self`` has ``self._m == self._n``, - then will assume bottom half of the extended exchange matrix is the c-matrix. - If ``True``, lets the :class:`ClusterSeed` know c-vectors can be calculated. + - ``bot_is_c`` -- (default: ``False``) If ``True`` and + :class:`ClusterSeed` ``self`` has ``self._m == self._n``, then will + assume bottom half of the extended exchange matrix is the c-matrix. + If ``True``, lets the :class:`ClusterSeed` know c-vectors can be + calculated. EXAMPLES:: sage: S = ClusterSeed(['A',4]) - sage: S.use_c_vectors(False); S.use_g_vectors(False); S.use_fpolys(False); S.track_mutations(False) + sage: S.use_c_vectors(False); S.use_g_vectors(False) + sage: S.use_fpolys(False); S.track_mutations(False) sage: S.use_c_vectors(True) - Warning: Initializing c-vectors at this point could lead to inconsistent seed data. + Warning: Initializing c-vectors at this point + could lead to inconsistent seed data. sage: S.use_c_vectors(True, force=True) sage: S.c_matrix() @@ -390,7 +410,8 @@ def use_c_vectors(self, use=True, bot_is_c=False, force=False): [0 0 0 1] sage: S = ClusterSeed(['A',4]) - sage: S.use_c_vectors(False); S.use_g_vectors(False); S.use_fpolys(False); S.track_mutations(False) + sage: S.use_c_vectors(False); S.use_g_vectors(False) + sage: S.use_fpolys(False); S.track_mutations(False) sage: S.mutate(1) sage: S.use_c_vectors(True, force=True) sage: S.c_matrix() @@ -444,7 +465,9 @@ def use_g_vectors(self, use=True, force=False): r""" Reconstruct g-vectors from other data or initialize if no usable data exists. - Warning: Initialization may lead to inconsistent data. + .. warning:: + + Initialization may lead to inconsistent data. INPUT: @@ -485,7 +508,8 @@ def use_g_vectors(self, use=True, force=False): sage: S.mutate(1) sage: S.use_c_vectors(False) sage: S.use_g_vectors(True) - Warning: Initializing g-vectors at this point could lead to inconsistent seed data. + Warning: Initializing g-vectors at this point + could lead to inconsistent seed data. sage: S.use_g_vectors(True, force=True) sage: S.g_matrix() @@ -525,7 +549,9 @@ def use_d_vectors(self, use=True, force=False): r""" Reconstruct d-vectors from other data or initialize if no usable data exists. - Warning: Initialization may lead to inconsistent data. + .. warning:: + + Initialization may lead to inconsistent data. INPUT: @@ -576,7 +602,8 @@ def use_d_vectors(self, use=True, force=False): [ 0 1 0 0] [ 0 0 -1 0] [ 0 0 0 -1] - sage: S = ClusterSeed(['A',4]); S.use_d_vectors(True); S.mutate(1); S.d_matrix() + sage: S = ClusterSeed(['A',4]) + sage: S.use_d_vectors(True); S.mutate(1); S.d_matrix() [-1 0 0 0] [ 0 1 0 0] [ 0 0 -1 0] @@ -608,13 +635,16 @@ def use_fpolys(self, use=True, user_labels=None, user_labels_prefix=None): r""" Use F-polynomials in our Cluster Seed - Note: This will automatically try to recompute the cluster variables if possible + Note: This will automatically try to recompute the cluster variables + if possible INPUT: - ``use`` -- (default: ``True``) If ``True``, will use F-polynomials - - ``user_labels`` -- (default: ``None``) If set, will overwrite the default cluster variable labels - - ``user_labels_prefix`` -- (default: ``None``) If set, will overwrite the default + - ``user_labels`` -- (default: ``None``) If set, will overwrite the + default cluster variable labels + - ``user_labels_prefix`` -- (default: ``None``) If set, will overwrite + the default EXAMPLES:: @@ -700,9 +730,12 @@ def use_fpolys(self, use=True, user_labels=None, user_labels_prefix=None): def track_mutations(self, use=True): r""" - Begins tracking the mutation path. + Begin tracking the mutation path. + + .. warning:: - Warning: May initialize all other data to ensure that all c-, d-, and g-vectors agree on the start of mutations. + May initialize all other data to ensure that all + c-, d-, and g-vectors agree on the start of mutations. INPUT: @@ -762,7 +795,8 @@ def _sanitize_init_vars(self, user_labels, user_labels_prefix='x'): INPUT: - ``user_labels`` -- The labels that need sanitizing - - ``user_labels_prefix`` -- (default: ``'x'``) The prefix to use for labels if integers given for labels + - ``user_labels_prefix`` -- (default: ``'x'``) The prefix to use + for labels if integers given for labels EXAMPLES:: @@ -985,12 +1019,18 @@ def plot(self, circular=False, mark=None, save_pos=False, force_c=False, with_gr INPUT: - - ``circular`` -- (default: ``False``) if ``True``, the circular plot is chosen, otherwise >>spring<< is used. - - ``mark`` -- (default: ``None``) if set to i, the vertex i is highlighted. - - ``save_pos`` -- (default: ``False``) if ``True``, the positions of the vertices are saved. - - ``force_c`` -- (default: ``False``) if ``True``, will show the frozen vertices even if they were never initialized - - ``with_greens`` -- (default: ``False``) if ``True``, will display the green vertices in green - - ``add_labels`` -- (default: ``False``) if ``True``, will use the initial variables as labels + - ``circular`` -- (default: ``False``) if ``True``, the circular plot + is chosen, otherwise >>spring<< is used. + - ``mark`` -- (default: ``None``) if set to i, the vertex i is + highlighted. + - ``save_pos`` -- (default: ``False``) if ``True``, the positions + of the vertices are saved. + - ``force_c`` -- (default: ``False``) if ``True``, will show the frozen + vertices even if they were never initialized + - ``with_greens`` -- (default: ``False``) if ``True``, will display + the green vertices in green + - ``add_labels`` -- (default: ``False``) if ``True``, will use the + initial variables as labels EXAMPLES:: @@ -1023,13 +1063,20 @@ def show(self, fig_size=1, circular=False, mark=None, save_pos=False, force_c=Fa INPUT: - - ``fig_size`` -- (default: 1) factor by which the size of the plot is multiplied. - - ``circular`` -- (default: ``False``) if ``True``, the circular plot is chosen, otherwise >>spring<< is used. - - ``mark`` -- (default: ``None``) if set to i, the vertex i is highlighted. - - ``save_pos`` -- (default: ``False``) if ``True``, the positions of the vertices are saved. - - ``force_c`` -- (default: ``False``) if ``True``, will show the frozen vertices even if they were never initialized - - ``with_greens`` -- (default: ``False``) if ``True``, will display the green vertices in green - - ``add_labels`` -- (default: ``False``) if ``True``, will use the initial variables as labels + - ``fig_size`` -- (default: 1) factor by which the size of the plot + is multiplied. + - ``circular`` -- (default: ``False``) if ``True``, the circular plot + is chosen, otherwise >>spring<< is used. + - ``mark`` -- (default: ``None``) if set to i, the vertex i is + highlighted. + - ``save_pos`` -- (default: ``False``) if ``True``, the positions + of the vertices are saved. + - ``force_c`` -- (default: ``False``) if ``True``, will show the frozen + vertices even if they were never initialized + - ``with_greens`` -- (default: ``False``) if ``True``, will display the + green vertices in green + - ``add_labels`` -- (default: ``False``) if ``True``, will use the + initial variables as labels TESTS:: @@ -1080,9 +1127,11 @@ def save_image(self, filename, circular=False, mark=None, save_pos=False): INPUT: - ``filename`` -- the filename the image is saved to. - - ``circular`` -- (default: ``False``) if ``True``, the circular plot is chosen, otherwise >>spring<< is used. + - ``circular`` -- (default: ``False``) if ``True``, the circular plot + is chosen, otherwise >>spring<< is used. - ``mark`` -- (default: ``None``) if set to i, the vertex i is highlighted. - - ``save_pos`` -- (default: ``False``) if ``True``, the positions of the vertices are saved. + - ``save_pos`` -- (default: ``False``) if ``True``, the positions + of the vertices are saved. EXAMPLES:: @@ -1416,9 +1465,11 @@ def f_polynomial(self, k): Return the ``k``-th *F-polynomial* of ``self``. It is obtained from the ``k``-th cluster variable by setting all `x_i` to `1`. - Warning: this method assumes the sign-coherence conjecture and that the - input seed is sign-coherent (has an exchange matrix with columns of like signs). - Otherwise, computational errors might arise. + .. warning:: + + This method assumes the sign-coherence conjecture and that the + input seed is sign-coherent (has an exchange matrix with columns of like signs). + Otherwise, computational errors might arise. EXAMPLES:: @@ -1463,9 +1514,11 @@ def f_polynomials(self): Return all *F-polynomials* of ``self``. These are obtained from the cluster variables by setting all `x_i`'s to `1`. - Warning: this method assumes the sign-coherence conjecture and that the - input seed is sign-coherent (has an exchange matrix with columns of like signs). - Otherwise, computational errors might arise. + .. warning:: + + This method assumes the sign-coherence conjecture and that the + input seed is sign-coherent (has an exchange matrix with columns of like signs). + Otherwise, computational errors might arise. EXAMPLES:: @@ -1482,9 +1535,11 @@ def g_vector(self, k): Return the ``k``-th *g-vector* of ``self``. This is the degree vector of the ``k``-th cluster variable after setting all `y_i`'s to `0`. - Warning: this method assumes the sign-coherence conjecture and that the - input seed is sign-coherent (has an exchange matrix with columns of like signs). - Otherwise, computational errors might arise. + .. warning:: + + This method assumes the sign-coherence conjecture and that the + input seed is sign-coherent (has an exchange matrix with columns of like signs). + Otherwise, computational errors might arise. EXAMPLES:: @@ -1520,9 +1575,11 @@ def g_matrix(self, show_warnings=True): Return the matrix of all *g-vectors* of ``self``. These are the degree vectors of the cluster variables after setting all `y_i`'s to `0`. - Warning: this method assumes the sign-coherence conjecture and that the - input seed is sign-coherent (has an exchange matrix with columns of like signs). - Otherwise, computational errors might arise. + .. warning:: + + This method assumes the sign-coherence conjecture and that the + input seed is sign-coherent (has an exchange matrix with columns of like signs). + Otherwise, computational errors might arise. EXAMPLES:: @@ -1622,9 +1679,11 @@ def c_vector(self, k): ``k``-th column vector of the bottom part of the ``B``-matrix of ``self``. - Warning: this method assumes the sign-coherence conjecture and that the - input seed is sign-coherent (has an exchange matrix with columns of like signs). - Otherwise, computational errors might arise. + .. warning:: + + This method assumes the sign-coherence conjecture and that the + input seed is sign-coherent (has an exchange matrix with columns of like signs). + Otherwise, computational errors might arise. EXAMPLES:: @@ -1657,9 +1716,11 @@ def c_matrix(self, show_warnings=True): r""" Return all *c-vectors* of ``self``. - Warning: this method assumes the sign-coherence conjecture and that the - input seed is sign-coherent (has an exchange matrix with columns of like signs). - Otherwise, computational errors might arise. + .. warning:: + + This method assumes the sign-coherence conjecture and that the + input seed is sign-coherent (has an exchange matrix with columns of like signs). + Otherwise, computational errors might arise. EXAMPLES:: @@ -1892,7 +1953,8 @@ def is_bipartite(self, return_bipartition=False): INPUT: - - ``return_bipartition`` -- (default: ``False``) if ``True``, the bipartition is returned in the case of ``self`` being bipartite. + - ``return_bipartition`` -- (default: ``False``) if ``True``, the + bipartition is returned in the case of ``self`` being bipartite. EXAMPLES:: @@ -2221,7 +2283,8 @@ def mutate(self, sequence, inplace=True, input_type=None): - ``"green"``: mutates at the first green vertex, - ``"red"``: mutates at the first red vertex, - ``"urban_renewal"`` or ``"urban"``: mutates at first urban renewal vertex, - - ``"all_urban_renewals"`` or ``"all_urban"``: mutates at all urban renewal vertices. + - ``"all_urban_renewals"`` or ``"all_urban"``: mutates at all + urban renewal vertices. For ``input_type``, if no value is given, preference will be given to vertex names, then indices, then cluster variables. @@ -2643,13 +2706,18 @@ def mutation_sequence(self, sequence, show_sequence=False, INPUT: - ``sequence`` -- an iterable of vertices of self. - - ``show_sequence`` -- (default: ``False``) if ``True``, a png containing the associated quivers is shown. - - ``fig_size`` -- (default: 1.2) factor by which the size of the plot is multiplied. - - ``return_output`` -- (default: 'seed') determines what output is to be returned:: - - * if ``'seed'``, outputs all the cluster seeds obtained by the ``sequence`` of mutations. + - ``show_sequence`` -- (default: ``False``) if ``True``, a png + containing the associated quivers is shown. + - ``fig_size`` -- (default: 1.2) factor by which the size of + the plot is multiplied. + - ``return_output`` -- (default: 'seed') determines what output + is to be returned:: + + * if ``'seed'``, outputs all the cluster seeds obtained + by the ``sequence`` of mutations. * if ``'matrix'``, outputs a list of exchange matrices. - * if ``'var'``, outputs a list of new cluster variables obtained at each step. + * if ``'var'``, outputs a list of new cluster variables obtained + at each step. EXAMPLES:: @@ -2693,11 +2761,14 @@ def mutation_analysis(self, options=['all'], filter=None): r""" Runs an analysis of all potential mutation options. Note that this might take a long time on large seeds. - Notes: Edges are only returned if we have a non-valued quiver. Green and red vertices are only returned if the cluster is principal. + .. note:: + + Edges are only returned if we have a non-valued quiver. + Green and red vertices are only returned if the cluster is principal. INPUT: - - ``options`` -- (default: [``'all'``]) a list of mutation options. + - ``options`` -- (default: ``['all']``) a list of mutation options. - ``filter`` -- (default: ``None``) A vertex or interval of vertices to limit our search to Possible options are: @@ -3140,14 +3211,17 @@ def reorient(self, data): Reorients ``self`` with respect to the given total order, or with respect to an iterator of ordered pairs. - WARNING: + .. warning:: - - This operation might change the mutation type of ``self``. - - Ignores ordered pairs `(i,j)` for which neither `(i,j)` nor `(j,i)` is an edge of ``self``. + - This operation might change the mutation type of ``self``. + - Ignores ordered pairs `(i,j)` for which neither `(i,j)` nor `(j,i)` + is an edge of ``self``. INPUT: - - ``data`` -- an iterator defining a total order on ``self.vertices()``, or an iterator of ordered pairs in ``self`` defining the new orientation of these edges. + - ``data`` -- an iterator defining a total order on ``self.vertices()``, + or an iterator of ordered pairs in ``self`` defining the new + orientation of these edges. EXAMPLES:: @@ -3178,7 +3252,9 @@ def set_cluster(self, cluster, force=False): r""" Sets the cluster for ``self`` to ``cluster``. - Warning: Initialization may lead to inconsistent data. + .. warning:: + + Initialization may lead to inconsistent data. INPUT: @@ -3274,9 +3350,13 @@ def reset_coefficients(self): r""" Reset the coefficients of ``self`` to the frozen variables but keep the current cluster. - This raises an error if the number of frozen variables is different than the number of exchangeable variables. + This raises an error if the number of frozen variables is different + from the number of exchangeable variables. - WARNING: This command to be phased out since :meth:`use_c_vectors` does this more effectively. + .. warning:: + + This command to be phased out since :meth:`use_c_vectors` + does this more effectively. EXAMPLES:: @@ -3330,11 +3410,17 @@ def mutation_class_iter(self, depth=infinity, show_depth=False, INPUT: - - ``depth`` -- (default: infinity) integer or infinity, only seeds with distance at most ``depth`` from ``self`` are returned. - - ``show_depth`` -- (default: ``False``) if ``True``, the current depth of the mutation is shown while computing. - - ``return_paths`` -- (default: ``False``) if ``True``, a shortest path of mutations from ``self`` to the given quiver is returned as well. - - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only one seed up to simultaneous permutation of rows and columns of the exchange matrix is recorded. - - ``sink_source`` -- (default: ``False``) if ``True``, only mutations at sinks and sources are applied. + - ``depth`` -- (default: infinity) integer or infinity, only seeds with + distance at most ``depth`` from ``self`` are returned. + - ``show_depth`` -- (default: ``False``) if ``True``, the current depth + of the mutation is shown while computing. + - ``return_paths`` -- (default: ``False``) if ``True``, a shortest path + of mutations from ``self`` to the given quiver is returned as well. + - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only one + seed up to simultaneous permutation of rows and columns of the + exchange matrix is recorded. + - ``sink_source`` -- (default: ``False``) if ``True``, only mutations + at sinks and sources are applied. EXAMPLES: @@ -3559,9 +3645,13 @@ def cluster_class_iter(self, depth=infinity, show_depth=False, up_to_equivalence INPUT: - - ``depth`` -- (default: infinity) integer or infinity, only seeds with distance at most ``depth`` from ``self`` are returned - - ``show_depth`` -- (default: ``False``) if ``True``, ignored if ``depth`` is set; returns the depth of the mutation class, i.e., the maximal distance from ``self`` of an element in the mutation class - - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only clusters up to equivalence are considered. + - ``depth`` -- (default: infinity) integer or infinity, only seeds with + distance at most ``depth`` from ``self`` are returned + - ``show_depth`` -- (default: ``False``) if ``True``, ignored if + ``depth`` is set; returns the depth of the mutation class, i.e., the + maximal distance from ``self`` of an element in the mutation class + - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only + clusters up to equivalence are considered. EXAMPLES: @@ -3655,9 +3745,13 @@ def cluster_class(self, depth=infinity, show_depth=False, up_to_equivalence=True INPUT: - - ``depth`` -- (default: infinity) integer, only seeds with distance at most ``depth`` from ``self`` are returned - - ``return_depth`` -- (default: ``False``) - if ``True``, ignored if ``depth`` is set; returns the depth of the mutation class, i.e., the maximal distance from ``self`` of an element in the mutation class - - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only clusters up to equivalence are considered. + - ``depth`` -- (default: infinity) integer, only seeds with distance + at most ``depth`` from ``self`` are returned + - ``return_depth`` -- (default: ``False``) - if ``True``, ignored if + ``depth`` is set; returns the depth of the mutation class, i.e., + the maximal distance from ``self`` of an element in the mutation class + - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only + clusters up to equivalence are considered. EXAMPLES: @@ -3678,8 +3772,10 @@ def b_matrix_class_iter(self, depth=infinity, up_to_equivalence=True): INPUT: - - ``depth`` -- (default:infinity) integer or infinity, only seeds with distance at most ``depth`` from ``self`` are returned - - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only `B`-matrices up to equivalence are considered. + - ``depth`` -- (default:infinity) integer or infinity, only seeds + with distance at most ``depth`` from ``self`` are returned + - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only + `B`-matrices up to equivalence are considered. EXAMPLES: @@ -3782,8 +3878,10 @@ def b_matrix_class(self, depth=infinity, up_to_equivalence=True): INPUT: - - ``depth`` -- (default: infinity) integer or infinity, only seeds with distance at most ``depth`` from ``self`` are returned - - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only `B`-matrices up to equivalence are considered. + - ``depth`` -- (default: infinity) integer or infinity, only seeds + with distance at most ``depth`` from ``self`` are returned + - ``up_to_equivalence`` -- (default: ``True``) if ``True``, only + `B`-matrices up to equivalence are considered. EXAMPLES: @@ -3805,8 +3903,10 @@ def variable_class_iter(self, depth=infinity, ignore_bipartite_belt=False): INPUT: - - ``depth`` -- (default: infinity) integer, only seeds with distance at most ``depth`` from ``self`` are returned - - ``ignore_bipartite_belt`` -- (default: ``False``) if ``True``, the algorithm does not use the bipartite belt + - ``depth`` -- (default: infinity) integer, only seeds with distance + at most ``depth`` from ``self`` are returned + - ``ignore_bipartite_belt`` -- (default: ``False``) if ``True``, + the algorithm does not use the bipartite belt EXAMPLES: @@ -3829,7 +3929,8 @@ def variable_class_iter(self, depth=infinity, ignore_bipartite_belt=False): sage: it = S.variable_class_iter(depth=1) sage: for T in it: print(T) - Found a bipartite seed - restarting the depth counter at zero and constructing the variable class using its bipartite belt. + Found a bipartite seed - restarting the depth counter at zero + and constructing the variable class using its bipartite belt. x0 x1 x2 @@ -3840,9 +3941,10 @@ def variable_class_iter(self, depth=infinity, ignore_bipartite_belt=False): (x0*x2 + 1)/x1 (x0*x2 + x1 + 1)/(x1*x2) - Note that the notion of *depth* depends on whether a bipartite seed is found or not, or if it is manually ignored:: + Note that the notion of *depth* depends on whether a bipartite seed + is found or not, or if it is manually ignored:: - sage: it = S.variable_class_iter(depth=1,ignore_bipartite_belt=True) + sage: it = S.variable_class_iter(depth=1, ignore_bipartite_belt=True) sage: for T in it: print(T) x0 x1 @@ -3866,7 +3968,8 @@ def variable_class_iter(self, depth=infinity, ignore_bipartite_belt=False): sage: S = ClusterSeed(['A',[1,1],1]) sage: it = S.variable_class_iter(depth=2) sage: for T in it: print(T) - Found a bipartite seed - restarting the depth counter at zero and constructing the variable class using its bipartite belt. + Found a bipartite seed - restarting the depth counter at zero + and constructing the variable class using its bipartite belt. x0 x1 (x1^2 + 1)/x0 @@ -3931,8 +4034,10 @@ def variable_class(self, depth=infinity, ignore_bipartite_belt=False): INPUT: - - ``depth`` -- (default: infinity) integer, only seeds with distance at most ``depth`` from ``self`` are returned - - ``ignore_bipartite_belt`` -- (default: ``False``) if ``True``, the algorithms does not use the bipartite belt + - ``depth`` -- (default: infinity) integer, only seeds with distance + at most ``depth`` from ``self`` are returned + - ``ignore_bipartite_belt`` -- (default: ``False``) if ``True``, the + algorithm does not use the bipartite belt EXAMPLES: @@ -3980,18 +4085,21 @@ def is_mutation_finite(self, nr_of_checks=None, return_path=False): INPUT: - - ``nr_of_checks`` -- (default: ``None``) number of mutations applied. Standard is 500*(number of vertices of ``self``). - - ``return_path`` -- (default: ``False``) if ``True``, in case of ``self`` not being mutation finite, - a path from ``self`` to a quiver with an edge label `(a,-b)` and `a*b > 4` is returned. + - ``nr_of_checks`` -- (default: ``None``) number of mutations applied. + Standard is 500 times the number of vertices of ``self``. + - ``return_path`` -- (default: ``False``) if ``True``, in case of + ``self`` not being mutation finite, a path from ``self`` to a quiver + with an edge label `(a,-b)` and `a*b > 4` is returned. ALGORITHM: - - A cluster seed is mutation infinite if and only if every `b_{ij}*b_{ji} > -4`. Thus, we apply random mutations in random directions + - A cluster seed is mutation infinite if and only if every + `b_{ij}*b_{ji} > -4`. Thus, we apply random mutations in random directions - WARNING: + .. warning:: - - Uses a non-deterministic method by random mutations in various directions. - - In theory, it can return a wrong True. + - Uses a non-deterministic method by random mutations in various directions. + - In theory, it can return a wrong ``True``. EXAMPLES:: @@ -4012,18 +4120,21 @@ def is_mutation_finite(self, nr_of_checks=None, return_path=False): def mutation_type(self): r""" - Return the mutation_type of each connected component of ``self``, if it can be determined. + Return the mutation type of each connected component of ``self``, if it can be determined. + Otherwise, the mutation type of this component is set to be unknown. The mutation types of the components are ordered by vertex labels. - WARNING: + .. warning:: - - All finite types can be detected, - - All affine types can be detected, EXCEPT affine type D (the algorithm is not yet implemented) - - All exceptional types can be detected. + - All finite types can be detected, + - All affine types can be detected, **except** affine type D + (the algorithm is not yet implemented) + - All exceptional types can be detected. - - Might fail to work if it is used within different Sage processes simultaneously (that happened in the doctesting). + - Might fail to work if it is used within different Sage processes + simultaneously (that happened in the doctesting). EXAMPLES: @@ -4168,8 +4279,7 @@ def greedy(self, a1, a2, algorithm='by_recursion'): def oriented_exchange_graph(self): """ - Return the oriented exchange graph of ``self`` as a directed - graph. + Return the oriented exchange graph of ``self`` as a directed graph. The seed must be a cluster seed for a cluster algebra of finite type with principal coefficients (the corresponding @@ -4352,7 +4462,8 @@ def get_upper_cluster_algebra_element(self,a): INPUT: - - `B` -- a skew-symmetric matrix. Must have the same number of columns as the length of the vectors in `vd`. + - ``B`` -- a skew-symmetric matrix. Must have the same number of columns + as the length of the vectors in `vd`. - ``a`` -- a vector in `\ZZ^n` where `n` is the number of columns in `B`. OUTPUT: @@ -4401,7 +4512,7 @@ def LLM_gen_set(self, size_limit=-1): INPUT: - - `B` -- a skew-symmetric matrix. + - ``B`` -- a skew-symmetric matrix. - ``size_limit`` -- a limit on how many vectors you want the function to return. @@ -4444,9 +4555,11 @@ def _compute_compatible_vectors(self, vd): INPUT: - - `B` -- a skew-symmetric matrix. Must have the same number of columns as the length of the vectors in ``vd``. + - ``B`` -- a skew-symmetric matrix. Must have the same number of columns + as the length of the vectors in ``vd``. - ``vd`` -- a collection of tuples `(v,z)` with `v \in \{0,1\}^n` and `z \in \ZZ`. - `n` must be the number of columns in `B`. Taken from the output of vector_decomposition. + `n` must be the number of columns in `B`. Taken from the output of + :func:`_vector_decomposition`. OUTPUT: @@ -4651,11 +4764,12 @@ def coeff_recurs(p, q, a1, a2, b, c): def PathSubset(n, m): r""" - Encodes a *maximal* Dyck path from (0,0) to (n,m) (for n >= m >= 0) as a subset of {0,1,2,..., 2n-1}. + Encode a *maximal* Dyck path from `(0,0)` to `(n,m)` (for `n \geq m \geq 0`) as a subset of `\{0,1,2,..., 2n-1\}`. + The encoding is given by indexing horizontal edges by odd numbers and vertical edges by evens. - The horizontal between (i,j) and (i+1,j) is indexed by the odd number 2*i+1. - The vertical between (i,j) and (i,j+1) is indexed by the even number 2*j. + The horizontal between `(i,j)` and `(i+1,j)` is indexed by the odd number `2*i+1`. + The vertical between `(i,j)` and `(i,j+1)` is indexed by the even number `2*j`. EXAMPLES:: @@ -4681,7 +4795,7 @@ def PathSubset(n, m): def SetToPath(T): r""" - Rearranges the encoding for a *maximal* Dyck path (as a set) so that it is a list in the proper order of the edges. + Rearrange the encoding for a *maximal* Dyck path (as a set) so that it is a list in the proper order of the edges. EXAMPLES:: @@ -4711,8 +4825,7 @@ def SetToPath(T): def is_LeeLiZel_allowable(T,n,m,b,c): """ - Check if the subset T contributes to the computation of the greedy - element x[m,n] in the rank two (b,c)-cluster algebra. + Check if the subset `T` contributes to the computation of the greedy element `x[m,n]` in the rank two `(b,c)`-cluster algebra. This uses the conditions of Lee-Li-Zelevinsky's paper [LLZ2014]_. @@ -4772,7 +4885,9 @@ def is_LeeLiZel_allowable(T,n,m,b,c): def get_green_vertices(C): r""" - Get the green vertices from a matrix. Will go through each column and return + Get the green vertices from a matrix. + + Will go through each column and return the ones where no entry is greater than 0. INPUT: From c5568c2ee9ca26f7709dd0aa6baf36695f052f26 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Wed, 7 Jun 2023 13:22:20 -0700 Subject: [PATCH 068/228] src/sage/combinat/cluster_algebra_quiver/cluster_seed.py: Fix markup --- src/sage/combinat/cluster_algebra_quiver/cluster_seed.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py index cdfea6ab767..b3719392b7c 100644 --- a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py +++ b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py @@ -67,11 +67,16 @@ class ClusterSeed(SageObject): - ``data`` -- can be any of the following:: * :class:`QuiverMutationType` + * :class:`str` -- a string representing a :class:`QuiverMutationType` or a common quiver type (see Examples) + * :class:`ClusterQuiver` + * :class:`Matrix` -- a skew-symmetrizable matrix + * :class:`DiGraph` -- must be the input data for a quiver + * List of edges -- must be the edge list of a digraph for a quiver EXAMPLES:: From 0f18153d2c105d6fc7e9a77eccbdfc424b9f2948 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Wed, 7 Jun 2023 17:44:20 -0700 Subject: [PATCH 069/228] src/sage/combinat/posets: Fix # optional --- src/sage/combinat/posets/d_complete.py | 2 +- src/sage/combinat/posets/hasse_diagram.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/posets/d_complete.py b/src/sage/combinat/posets/d_complete.py index 2b603aeac2b..efd9b36b335 100644 --- a/src/sage/combinat/posets/d_complete.py +++ b/src/sage/combinat/posets/d_complete.py @@ -151,7 +151,7 @@ def get_hooks(self): {0: 1, 1: 2, 2: 2, 3: 3} sage: from sage.combinat.posets.poset_examples import Posets sage: YDP321 = Posets.YoungDiagramPoset(Partition([3,2,1])) # optional - sage.combinat - sage: P = DCompletePoset(YDP321)._hasse_diagram.reverse()) # optional - sage.combinat + sage: P = DCompletePoset(YDP321)._hasse_diagram.reverse() # optional - sage.combinat sage: P.get_hooks() # optional - sage.combinat {0: 5, 1: 3, 2: 1, 3: 3, 4: 1, 5: 1} """ diff --git a/src/sage/combinat/posets/hasse_diagram.py b/src/sage/combinat/posets/hasse_diagram.py index 84364c149d7..eb223bb1036 100644 --- a/src/sage/combinat/posets/hasse_diagram.py +++ b/src/sage/combinat/posets/hasse_diagram.py @@ -1169,7 +1169,7 @@ def coxeter_transformation(self, algorithm='cython'): [-1 1 1 0 -1] [-1 1 0 1 -1] sage: P.__dict__['coxeter_transformation'].clear_cache() # optional - sage.libs.flint sage.modules - sage: P.coxeter_transformation(algorithm="matrix") == M # optional - sage.modules + sage: P.coxeter_transformation(algorithm="matrix") == M # optional - sage.libs.flint sage.modules True TESTS:: @@ -2167,7 +2167,7 @@ def find_nonsemimodular_pair(self, upper): INPUT: - - upper, a Boolean -- if ``True``, test whether the lattice is + - ``upper``, a Boolean -- if ``True``, test whether the lattice is upper semimodular; otherwise test whether the lattice is lower semimodular. From 0b50e1a654f0f2e588b80a7e5cc0894a9bce0777 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Wed, 7 Jun 2023 17:51:32 -0700 Subject: [PATCH 070/228] src/sage/combinat/root_system/plot.py: Fix doctest --- src/sage/combinat/root_system/plot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/root_system/plot.py b/src/sage/combinat/root_system/plot.py index 90bab1e8ac0..be6626e40fc 100644 --- a/src/sage/combinat/root_system/plot.py +++ b/src/sage/combinat/root_system/plot.py @@ -592,7 +592,7 @@ sage: L = RootSystem(["B",3,1]).ambient_space() sage: w3 = [0,2,1,3,2,0,2,1,0,2,3,1,2,1,3,2,0,2,0,1,2,0] sage: (L.plot_fundamental_weights() # optional - sage.plot sage.symbolic - ....: + L.plot_reflection_hyperplanes(bounding_box=2) + L.plot_alcove_walk(w3) + ....: + L.plot_reflection_hyperplanes(bounding_box=2) + L.plot_alcove_walk(w3)) Graphics3d Object .. PLOT:: From 2710137a94f627cba76846f690da442a63320b33 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Wed, 7 Jun 2023 19:04:12 -0700 Subject: [PATCH 071/228] src/sage/combinat/cluster_algebra_quiver/cluster_seed.py: Fix markup --- src/sage/combinat/cluster_algebra_quiver/cluster_seed.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py index b3719392b7c..ae93b3e67af 100644 --- a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py +++ b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py @@ -2711,16 +2711,21 @@ def mutation_sequence(self, sequence, show_sequence=False, INPUT: - ``sequence`` -- an iterable of vertices of self. + - ``show_sequence`` -- (default: ``False``) if ``True``, a png containing the associated quivers is shown. + - ``fig_size`` -- (default: 1.2) factor by which the size of the plot is multiplied. - - ``return_output`` -- (default: 'seed') determines what output - is to be returned:: + + - ``return_output`` -- (default: ``'seed'``) determines what output + is to be returned: * if ``'seed'``, outputs all the cluster seeds obtained by the ``sequence`` of mutations. + * if ``'matrix'``, outputs a list of exchange matrices. + * if ``'var'``, outputs a list of new cluster variables obtained at each step. From 2b0992da4ecf5db0f7630d0c642a4c2b382ce961 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Thu, 8 Jun 2023 09:20:09 -0700 Subject: [PATCH 072/228] src/sage/combinat/posets/d_complete.py: Fix up doctest --- src/sage/combinat/posets/d_complete.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/posets/d_complete.py b/src/sage/combinat/posets/d_complete.py index efd9b36b335..80cff74eb5c 100644 --- a/src/sage/combinat/posets/d_complete.py +++ b/src/sage/combinat/posets/d_complete.py @@ -151,7 +151,7 @@ def get_hooks(self): {0: 1, 1: 2, 2: 2, 3: 3} sage: from sage.combinat.posets.poset_examples import Posets sage: YDP321 = Posets.YoungDiagramPoset(Partition([3,2,1])) # optional - sage.combinat - sage: P = DCompletePoset(YDP321)._hasse_diagram.reverse() # optional - sage.combinat + sage: P = DCompletePoset(YDP321._hasse_diagram.reverse()) # optional - sage.combinat sage: P.get_hooks() # optional - sage.combinat {0: 5, 1: 3, 2: 1, 3: 3, 4: 1, 5: 1} """ From 6b97c825c90a5d658ccfb085fed999195073ac5d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sat, 10 Jun 2023 09:18:06 -0700 Subject: [PATCH 073/228] src/sage/combinat/k_regular_sequence.py: Use file-level annotation for # optional - sage.symbolic --- src/sage/combinat/k_regular_sequence.py | 252 ++++++++++++------------ 1 file changed, 126 insertions(+), 126 deletions(-) diff --git a/src/sage/combinat/k_regular_sequence.py b/src/sage/combinat/k_regular_sequence.py index a170582116f..454e064868b 100644 --- a/src/sage/combinat/k_regular_sequence.py +++ b/src/sage/combinat/k_regular_sequence.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat sage.modules +# sage.doctest: optional - sage.combinat sage.modules sage.symbolic r""" `k`-regular Sequences @@ -331,17 +331,17 @@ def subsequence(self, a, b): We check if the linear representation of the subsequences above indeed represent the correct vector valued sequences:: - sage: var('n') # optional - sage.symbolic + sage: var('n') n sage: def v(n): ....: return vector([3*n + 1, 6*n + 1]) - sage: S31.mu[0] * v(n) == v(2*n) # optional - sage.symbolic + sage: S31.mu[0] * v(n) == v(2*n) True - sage: S31.mu[1] * v(n) == v(2*n + 1) # optional - sage.symbolic + sage: S31.mu[1] * v(n) == v(2*n + 1) True - sage: function('delta_0') # optional - sage.symbolic + sage: function('delta_0') delta_0 sage: def simplify_delta(expr): @@ -349,17 +349,17 @@ def subsequence(self, a, b): sage: def v(n): ....: return vector([n -1 + delta_0(n), 2*n - 1 + delta_0(n), 4*n + 1]) - sage: simplify_delta(v(2*n) - Srs.mu[0]*v(n)).is_zero() # optional - sage.symbolic + sage: simplify_delta(v(2*n) - Srs.mu[0]*v(n)).is_zero() True - sage: simplify_delta(v(2*n + 1) - Srs.mu[1]*v(n)).is_zero() # optional - sage.symbolic + sage: simplify_delta(v(2*n + 1) - Srs.mu[1]*v(n)).is_zero() True sage: def v(n): ....: return vector([1 - delta_0(n), 1]) - sage: simplify_delta(v(2*n) - Sbd.mu[0]*v(n)).is_zero() # optional - sage.symbolic + sage: simplify_delta(v(2*n) - Sbd.mu[0]*v(n)).is_zero() True - sage: simplify_delta(v(2*n + 1) - Sbd.mu[1]*v(n)).is_zero() # optional - sage.symbolic + sage: simplify_delta(v(2*n + 1) - Sbd.mu[1]*v(n)).is_zero() True We check some corner-cases:: @@ -934,11 +934,11 @@ def from_recurrence(self, *args, **kwds): :: sage: Seq2 = kRegularSequenceSpace(2, ZZ) - sage: var('n') # optional - sage.symbolic + sage: var('n') n - sage: function('f') # optional - sage.symbolic + sage: function('f') f - sage: Seq2.from_recurrence([ # optional - sage.symbolic + sage: Seq2.from_recurrence([ ....: f(2*n) == 2*f(n), f(2*n + 1) == 3*f(n) + 4*f(n - 1), ....: f(0) == 0, f(1) == 1], f, n) 2-regular sequence 0, 0, 0, 1, 2, 3, 4, 10, 6, 17, ... @@ -1022,26 +1022,26 @@ def from_recurrence(self, *args, **kwds): Stern--Brocot Sequence:: sage: Seq2 = kRegularSequenceSpace(2, ZZ) - sage: var('n') # optional - sage.symbolic + sage: var('n') n - sage: function('f') # optional - sage.symbolic + sage: function('f') f - sage: SB = Seq2.from_recurrence([ # optional - sage.symbolic + sage: SB = Seq2.from_recurrence([ ....: f(2*n) == f(n), f(2*n + 1) == f(n) + f(n + 1), ....: f(0) == 0, f(1) == 1], f, n) - sage: SB # optional - sage.symbolic + sage: SB 2-regular sequence 0, 1, 1, 2, 1, 3, 2, 3, 1, 4, ... Number of Odd Entries in Pascal's Triangle:: - sage: Seq2.from_recurrence([ # optional - sage.symbolic + sage: Seq2.from_recurrence([ ....: f(2*n) == 3*f(n), f(2*n + 1) == 2*f(n) + f(n + 1), ....: f(0) == 0, f(1) == 1], f, n) 2-regular sequence 0, 1, 3, 5, 9, 11, 15, 19, 27, 29, ... Number of Unbordered Factors in the Thue--Morse Sequence:: - sage: UB = Seq2.from_recurrence([ # optional - sage.symbolic + sage: UB = Seq2.from_recurrence([ ....: f(8*n) == 2*f(4*n), ....: f(8*n + 1) == f(4*n + 1), ....: f(8*n + 2) == f(4*n + 1) + f(4*n + 3), @@ -1055,20 +1055,20 @@ def from_recurrence(self, *args, **kwds): ....: f(10) == 4, f(11) == 4, f(12) == 12, f(13) == 0, f(14) == 4, ....: f(15) == 4, f(16) == 8, f(17) == 4, f(18) == 8, f(19) == 0, ....: f(20) == 8, f(21) == 4, f(22) == 4, f(23) == 8], f, n, offset=3) - sage: UB # optional - sage.symbolic + sage: UB 2-regular sequence 1, 2, 2, 4, 2, 4, 6, 0, 4, 4, ... Binary sum of digits `S(n)`, characterized by the recurrence relations `S(4n) = S(2n)`, `S(4n + 1) = S(2n + 1)`, `S(4n + 2) = S(2n + 1)` and `S(4n + 3) = -S(2n) + 2S(2n + 1)`:: - sage: S = Seq2.from_recurrence([ # optional - sage.symbolic + sage: S = Seq2.from_recurrence([ ....: f(4*n) == f(2*n), ....: f(4*n + 1) == f(2*n + 1), ....: f(4*n + 2) == f(2*n + 1), ....: f(4*n + 3) == -f(2*n) + 2*f(2*n + 1), ....: f(0) == 0, f(1) == 1], f, n) - sage: S # optional - sage.symbolic + sage: S 2-regular sequence 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, ... In order to check if this sequence is indeed the binary sum of digits, @@ -1078,7 +1078,7 @@ def from_recurrence(self, *args, **kwds): sage: S2 = Seq2( ....: (Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [1, 1]])), ....: left=vector([0, 1]), right=vector([1, 0])) - sage: (S - S2).is_trivial_zero() # optional - sage.symbolic + sage: (S - S2).is_trivial_zero() True Alternatively, we can also use the simpler but inhomogeneous recurrence relations @@ -1096,13 +1096,13 @@ def from_recurrence(self, *args, **kwds): Number of Non-Zero Elements in the Generalized Pascal's Triangle (see [LRS2017]_):: sage: Seq2 = kRegularSequenceSpace(2, QQ) - sage: P = Seq2.from_recurrence([ # optional - sage.symbolic + sage: P = Seq2.from_recurrence([ ....: f(4*n) == 5/3*f(2*n) - 1/3*f(2*n + 1), ....: f(4*n + 1) == 4/3*f(2*n) + 1/3*f(2*n + 1), ....: f(4*n + 2) == 1/3*f(2*n) + 4/3*f(2*n + 1), ....: f(4*n + 3) == -1/3*f(2*n) + 5/3*f(2*n + 1), ....: f(0) == 1, f(1) == 2], f, n) - sage: P # optional - sage.symbolic + sage: P 2-regular sequence 1, 2, 3, 3, 4, 5, 5, 4, 5, 7, ... Finally, the same sequence can also be obtained via direct parameters @@ -1118,7 +1118,7 @@ def from_recurrence(self, *args, **kwds): TESTS:: - sage: Seq2.from_recurrence([ # long time # optional - sage.symbolic + sage: Seq2.from_recurrence([ # long time ....: f(4*n) == f(2*n), ....: f(4*n + 1) == f(2*n), ....: f(4*n + 2) == f(2*n), @@ -1130,7 +1130,7 @@ def from_recurrence(self, *args, **kwds): :: - sage: S = Seq2.from_recurrence([ # optional - sage.symbolic + sage: S = Seq2.from_recurrence([ ....: f(4*n) == f(2*n), ....: f(4*n + 1) == f(2*n), ....: f(4*n + 2) == f(2*n), @@ -1139,7 +1139,7 @@ def from_recurrence(self, *args, **kwds): ....: f(5) == 5, f(6) == 6, f(7) == 7, f(16) == 4, f(18) == 4, ....: f(20) == 4, f(22) == 4, f(24) == 6, f(26) == 6, f(28) == 6], ....: f, n, offset=2) - sage: all([S[4*i] == S[2*i] and # optional - sage.symbolic + sage: all([S[4*i] == S[2*i] and ....: S[4*i + 1] == S[2*i] and ....: S[4*i + 2] == S[2*i] and ....: S[4*i + 3] == S[2*i + 16] for i in srange(2, 100)]) @@ -1147,7 +1147,7 @@ def from_recurrence(self, *args, **kwds): :: - sage: S = Seq2.from_recurrence([ # optional - sage.symbolic + sage: S = Seq2.from_recurrence([ ....: f(4*n) == f(2*n), ....: f(4*n + 1) == f(2*n), ....: f(4*n + 2) == f(2*n), @@ -1160,7 +1160,7 @@ def from_recurrence(self, *args, **kwds): ....: f(22) == 22, f(23) == 23, f(24) == 24, f(25) == 25, ....: f(26) == 26, f(27) == 27, f(28) == 28, f(29) == 29, ....: f(30) == 30, f(31) == 31], f, n, offset=8) - sage: all([S[4*i] == S[2*i] and # optional - sage.symbolic + sage: all([S[4*i] == S[2*i] and ....: S[4*i + 1] == S[2*i] and ....: S[4*i + 2] == S[2*i] and ....: S[4*i + 3] == S[2*i - 16] for i in srange(8, 100)]) @@ -1168,11 +1168,11 @@ def from_recurrence(self, *args, **kwds): Same test with different variable and function names:: - sage: var('m') # optional - sage.symbolic + sage: var('m') m - sage: function('g') # optional - sage.symbolic + sage: function('g') g - sage: T = Seq2.from_recurrence([ # optional - sage.symbolic + sage: T = Seq2.from_recurrence([ ....: g(4*m) == g(2*m), ....: g(4*m + 1) == g(2*m), ....: g(4*m + 2) == g(2*m), @@ -1185,12 +1185,12 @@ def from_recurrence(self, *args, **kwds): ....: g(22) == 22, g(23) == 23, g(24) == 24, g(25) == 25, ....: g(26) == 26, g(27) == 27, g(28) == 28, g(29) == 29, ....: g(30) == 30, g(31) == 31], g, m, offset=8) - sage: (S - T).is_trivial_zero() # long time # optional - sage.symbolic + sage: (S - T).is_trivial_zero() # long time True Zero-sequence with non-zero initial values:: - sage: Seq2.from_recurrence([ # optional - sage.symbolic + sage: Seq2.from_recurrence([ ....: f(2*n) == 0, f(2*n + 1) == 0, ....: f(0) == 1, f(1) == 1, f(2) == 2, f(3) == 3], f, n) Traceback (most recent call last): @@ -1199,14 +1199,14 @@ def from_recurrence(self, *args, **kwds): :: - sage: Seq2.from_recurrence([ # optional - sage.symbolic + sage: Seq2.from_recurrence([ ....: f(2*n) == 0, f(2*n + 1) == 0, ....: f(0) == 1, f(1) == 1, f(2) == 2, f(3) == 3], f, n, offset=2) 2-regular sequence 1, 1, 2, 3, 0, 0, 0, 0, 0, 0, ... Check if inhomogeneities `0` do not change the sequence:: - sage: Seq2.from_recurrence([ # optional - sage.symbolic + sage: Seq2.from_recurrence([ ....: f(2*n) == 0, f(2*n + 1) == 0, ....: f(0) == 1, f(1) == 1, f(2) == 2, f(3) == 3], f, n, offset=2, ....: inhomogeneities={0: 0, 1: Seq2.zero()}) @@ -1229,26 +1229,26 @@ def from_recurrence(self, *args, **kwds): of non-zero elements in the generalized Pascal's triangle (see [LRS2017]_):: - sage: U = Seq2.from_recurrence(M=1, m=0, # optional - sage.symbolic + sage: U = Seq2.from_recurrence(M=1, m=0, ....: coeffs={(0, 0): 1}, ....: initial_values={0: 0, 1: 1}, ....: inhomogeneities={1: P}) - sage: (U - Seq2(SB)).is_trivial_zero() # optional - sage.symbolic + sage: (U - Seq2(SB)).is_trivial_zero() True :: - sage: U = Seq2.from_recurrence(M=1, m=0, # optional - sage.symbolic + sage: U = Seq2.from_recurrence(M=1, m=0, ....: coeffs={}, ....: initial_values={0: 0, 1: 1}, ....: inhomogeneities={0: SB, 1: P}) - sage: (U - Seq2(SB)).is_trivial_zero() # optional - sage.symbolic + sage: (U - Seq2(SB)).is_trivial_zero() True Number of Unbordered Factors in the Thue--Morse Sequence, but partly encoded with inhomogeneities:: - sage: UB2 = Seq2.from_recurrence([ # optional - sage.symbolic + sage: UB2 = Seq2.from_recurrence([ ....: f(8*n) == 2*f(4*n), ....: f(8*n + 1) == f(4*n + 1), ....: f(8*n + 2) == f(4*n + 1), @@ -1264,7 +1264,7 @@ def from_recurrence(self, *args, **kwds): ....: f(20) == 8, f(21) == 4, f(22) == 4, f(23) == 8], f, n, offset=3, ....: inhomogeneities={2: UB.subsequence(4, 3), 3: -UB.subsequence(4, 1), ....: 6: UB.subsequence(4, 2) + UB.subsequence(4, 3)}) - sage: (UB2 - Seq2(UB)).is_trivial_zero() # optional - sage.symbolic + sage: (UB2 - Seq2(UB)).is_trivial_zero() True """ RP = RecurrenceParser(self.k, self.coefficient_ring()) @@ -1325,11 +1325,11 @@ def parse_recurrence(self, equations, function, var): sage: from sage.combinat.k_regular_sequence import RecurrenceParser sage: RP = RecurrenceParser(2, ZZ) - sage: var('n') # optional - sage.symbolic + sage: var('n') n - sage: function('f') # optional - sage.symbolic + sage: function('f') f - sage: RP.parse_recurrence([ # optional - sage.symbolic + sage: RP.parse_recurrence([ ....: f(4*n) == f(2*n) + 2*f(2*n + 1) + 3*f(2*n - 2), ....: f(4*n + 1) == 4*f(2*n) + 5*f(2*n + 1) + 6*f(2*n - 2), ....: f(4*n + 2) == 7*f(2*n) + 8*f(2*n + 1) + 9*f(2*n - 2), @@ -1341,7 +1341,7 @@ def parse_recurrence(self, equations, function, var): Stern--Brocot Sequence:: - sage: RP.parse_recurrence([ # optional - sage.symbolic + sage: RP.parse_recurrence([ ....: f(2*n) == f(n), f(2*n + 1) == f(n) + f(n + 1), ....: f(0) == 0, f(1) == 1], f, n) (1, 0, {(0, 0): 1, (1, 0): 1, (1, 1): 1}, {0: 0, 1: 1}) @@ -1354,28 +1354,28 @@ def parse_recurrence(self, equations, function, var): The following tests check that the equations are well-formed:: - sage: RP.parse_recurrence([], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([], f, n) Traceback (most recent call last): ... ValueError: List of recurrence equations is empty. :: - sage: RP.parse_recurrence([f(4*n + 1)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(4*n + 1)], f, n) Traceback (most recent call last): ... ValueError: f(4*n + 1) is not an equation with ==. :: - sage: RP.parse_recurrence([42], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([42], f, n) Traceback (most recent call last): ... ValueError: 42 is not a symbolic expression. :: - sage: RP.parse_recurrence([f(2*n) + 1 == f(n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) + 1 == f(n)], f, n) Traceback (most recent call last): ... ValueError: Term f(2*n) + 1 in the equation f(2*n) + 1 == f(n) is @@ -1383,7 +1383,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n, 5) == 3], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n, 5) == 3], f, n) Traceback (most recent call last): ... ValueError: Term f(2*n, 5) in the equation f(2*n, 5) == 3 does not @@ -1391,7 +1391,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f() == 3], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f() == 3], f, n) Traceback (most recent call last): ... ValueError: Term f() in the equation f() == 3 does not have one @@ -1399,7 +1399,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(1/n + 1) == f(n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(1/n + 1) == f(n)], f, n) Traceback (most recent call last): ... ValueError: Term f(1/n + 1) in the equation f(1/n + 1) == f(n): @@ -1407,7 +1407,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n + 1/2) == f(n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n + 1/2) == f(n)], f, n) Traceback (most recent call last): ... ValueError: Term f(2*n + 1/2) in the equation f(2*n + 1/2) == f(n): @@ -1415,7 +1415,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(4*n^2) == f(2*n^2)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(4*n^2) == f(2*n^2)], f, n) Traceback (most recent call last): ... ValueError: Term f(4*n^2) in the equation f(4*n^2) == f(2*n^2): @@ -1423,7 +1423,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(42) == 1/2], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(42) == 1/2], f, n) Traceback (most recent call last): ... ValueError: Initial value 1/2 given by the equation f(42) == (1/2) @@ -1431,14 +1431,14 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(42) == 0, f(42) == 1], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(42) == 0, f(42) == 1], f, n) Traceback (most recent call last): ... ValueError: Initial value f(42) is given twice. :: - sage: RP.parse_recurrence([f(42) == f(n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(42) == f(n)], f, n) Traceback (most recent call last): ... ValueError: Initial value f(n) given by the equation f(42) == f(n) @@ -1446,7 +1446,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(4*n) == f(n), f(2*n) == f(n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(4*n) == f(n), f(2*n) == f(n)], f, n) Traceback (most recent call last): ... ValueError: Term f(2*n) in the equation f(2*n) == f(n): 2 does not @@ -1455,7 +1455,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(3*n + 1) == f(n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(3*n + 1) == f(n)], f, n) Traceback (most recent call last): ... ValueError: Term f(3*n + 1) in the equation f(3*n + 1) == f(n): @@ -1463,7 +1463,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(n + 1) == f(n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(n + 1) == f(n)], f, n) Traceback (most recent call last): ... ValueError: Term f(n + 1) in the equation f(n + 1) == f(n): @@ -1471,14 +1471,14 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == f(n), f(2*n) == 0], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) == f(n), f(2*n) == 0], f, n) Traceback (most recent call last): ... ValueError: There are more than one recurrence relation for f(2*n). :: - sage: RP.parse_recurrence([f(2*n + 2) == f(n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n + 2) == f(n)], f, n) Traceback (most recent call last): ... ValueError: Term f(2*n + 2) in the equation f(2*n + 2) == f(n): @@ -1486,7 +1486,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n - 1) == f(n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n - 1) == f(n)], f, n) Traceback (most recent call last): ... ValueError: Term f(2*n - 1) in the equation f(2*n - 1) == f(n): @@ -1494,7 +1494,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == 2*n], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) == 2*n], f, n) Traceback (most recent call last): ... ValueError: Term 2*n in the equation f(2*n) == 2*n does not @@ -1502,7 +1502,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == 1/2*f(n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) == 1/2*f(n)], f, n) Traceback (most recent call last): ... ValueError: Term 1/2*f(n) in the equation f(2*n) == 1/2*f(n): @@ -1510,21 +1510,21 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == 1/f(n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) == 1/f(n)], f, n) Traceback (most recent call last): ... ValueError: 1/f(n) is not a valid right hand side. :: - sage: RP.parse_recurrence([f(2*n) == 2*n*f(n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) == 2*n*f(n)], f, n) Traceback (most recent call last): ... ValueError: 2*n*f(n) is not a valid right hand side. :: - sage: RP.parse_recurrence([f(2*n) == 2*f(n, 5)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) == 2*f(n, 5)], f, n) Traceback (most recent call last): ... ValueError: Term f(n, 5) in the equation f(2*n) == 2*f(n, 5) @@ -1532,14 +1532,14 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == 2*f()], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) == 2*f()], f, n) Traceback (most recent call last): ... ValueError: Term f() in the equation f(2*n) == 2*f() has no argument. :: - sage: RP.parse_recurrence([f(2*n) == 1/f(n) + 2*f(n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) == 1/f(n) + 2*f(n)], f, n) Traceback (most recent call last): ... ValueError: Term 1/f(n) in the equation f(2*n) == 1/f(n) + 2*f(n) @@ -1547,7 +1547,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == 2*f(1/n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) == 2*f(1/n)], f, n) Traceback (most recent call last): ... ValueError: Term f(1/n) in the equation f(2*n) == 2*f(1/n): @@ -1555,7 +1555,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == f(n + 1/2)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) == f(n + 1/2)], f, n) Traceback (most recent call last): ... ValueError: Term f(n + 1/2) in the equation f(2*n) == f(n + 1/2): @@ -1563,7 +1563,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == f(1/2*n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) == f(1/2*n)], f, n) Traceback (most recent call last): ... ValueError: Term f(1/2*n) in the equation f(2*n) == f(1/2*n): @@ -1571,7 +1571,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == f(n^2 + 1)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) == f(n^2 + 1)], f, n) Traceback (most recent call last): ... ValueError: Term f(n^2 + 1) in the equation f(2*n) == f(n^2 + 1): @@ -1579,7 +1579,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == f(1)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) == f(1)], f, n) Traceback (most recent call last): ... ValueError: Term f(1) in the equation f(2*n) == f(1): @@ -1587,7 +1587,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(4*n) == f(2*n) + f(n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(4*n) == f(2*n) + f(n)], f, n) Traceback (most recent call last): ... ValueError: Term f(n) in the equation f(4*n) == f(2*n) + f(n): @@ -1596,7 +1596,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(4*n) == f(2*n), f(4*n + 1) == f(n)], # optional - sage.symbolic + sage: RP.parse_recurrence([f(4*n) == f(2*n), f(4*n + 1) == f(n)], ....: f, n) Traceback (most recent call last): ... @@ -1606,7 +1606,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(4*n) == f(3*n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(4*n) == f(3*n)], f, n) Traceback (most recent call last): ... ValueError: Term f(3*n) in the equation f(4*n) == f(3*n): 3 is not @@ -1614,7 +1614,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == f(4*n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) == f(4*n)], f, n) Traceback (most recent call last): ... ValueError: Term f(4*n) in the equation f(2*n) == f(4*n): @@ -1622,7 +1622,7 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == f(2*n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) == f(2*n)], f, n) Traceback (most recent call last): ... ValueError: Term f(2*n) in the equation f(2*n) == f(2*n): @@ -1630,14 +1630,14 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(2*n) == f(n)], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) == f(n)], f, n) Traceback (most recent call last): ... ValueError: Recurrence relations for [f(2*n + 1)] are missing. :: - sage: RP.parse_recurrence([f(4*n) == f(n), f(4*n + 3) == 0], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(4*n) == f(n), f(4*n + 3) == 0], f, n) Traceback (most recent call last): ... ValueError: Recurrence relations for [f(4*n + 1), f(4*n + 2)] @@ -1645,20 +1645,20 @@ def parse_recurrence(self, equations, function, var): :: - sage: RP.parse_recurrence([f(42) == 0], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(42) == 0], f, n) Traceback (most recent call last): ... ValueError: No recurrence relations are given. :: - sage: RP.parse_recurrence( # optional - sage.symbolic + sage: RP.parse_recurrence( ....: [f(4*n + r) == f(n) for r in srange(4)], f, n) (2, 0, {(0, 0): 1, (1, 0): 1, (2, 0): 1, (3, 0): 1}, {}) :: - sage: RP.parse_recurrence( # optional - sage.symbolic + sage: RP.parse_recurrence( ....: [f(8*n) == f(n)] + ....: [f(8*n + r) == f(2*n) for r in srange(1,8)], f, n) Traceback (most recent call last): @@ -1669,35 +1669,35 @@ def parse_recurrence(self, equations, function, var): Finally, also for the zero-sequence the output is as expected:: - sage: RP.parse_recurrence([f(2*n) == 0, f(2*n + 1) == 0], f, n) # optional - sage.symbolic + sage: RP.parse_recurrence([f(2*n) == 0, f(2*n + 1) == 0], f, n) (1, 0, {}, {}) We check that the output is of the correct type (:trac:`33158`):: sage: RP = RecurrenceParser(2, QQ) - sage: equations = [ # optional - sage.symbolic + sage: equations = [ ....: f(4*n) == 5/3*f(2*n) - 1/3*f(2*n + 1), ....: f(4*n + 1) == 4/3*f(2*n) + 1/3*f(2*n + 1), ....: f(4*n + 2) == 1/3*f(2*n) + 4/3*f(2*n + 1), ....: f(4*n + 3) == -1/3*f(2*n) + 5/3*f(2*n + 1), ....: f(0) == 1, f(1) == 2] - sage: M, m, coeffs, initial_values = RP.parse_recurrence(equations, f, n) # optional - sage.symbolic - sage: M.parent() # optional - sage.symbolic + sage: M, m, coeffs, initial_values = RP.parse_recurrence(equations, f, n) + sage: M.parent() Integer Ring - sage: m.parent() # optional - sage.symbolic + sage: m.parent() Integer Ring - sage: all(v.parent() == QQ for v in coeffs.values()) # optional - sage.symbolic + sage: all(v.parent() == QQ for v in coeffs.values()) True - sage: all(v.parent() == QQ for v in initial_values.values()) # optional - sage.symbolic + sage: all(v.parent() == QQ for v in initial_values.values()) True This results in giving the correct (see :trac:`33158`) minimization in:: sage: Seq2 = kRegularSequenceSpace(2, QQ) - sage: P = Seq2.from_recurrence(equations, f, n) # optional - sage.symbolic - sage: P # optional - sage.symbolic + sage: P = Seq2.from_recurrence(equations, f, n) + sage: P 2-regular sequence 1, 2, 3, 3, 4, 5, 5, 4, 5, 7, ... - sage: P.minimized() # optional - sage.symbolic + sage: P.minimized() 2-regular sequence 1, 2, 3, 3, 4, 5, 5, 4, 5, 7, ... """ from sage.arith.srange import srange @@ -2119,9 +2119,9 @@ def parameters(self, M, m, coeffs, initial_values, offset=0, inhomogeneities={}) TESTS:: - sage: var('n') # optional - sage.symbolic + sage: var('n') n - sage: RP.parameters(1, 0, {(0, 0): 1}, {}, 0, # optional - sage.symbolic + sage: RP.parameters(1, 0, {(0, 0): 1}, {}, 0, ....: {-1: 0, 1: 0, 10: 0, I: 0, n: 0}) Traceback (most recent call last): ... @@ -2130,7 +2130,7 @@ def parameters(self, M, m, coeffs, initial_values, offset=0, inhomogeneities={}) :: - sage: RP.parameters(1, 0, {(0, 0): 1}, {}, 0, # optional - sage.symbolic + sage: RP.parameters(1, 0, {(0, 0): 1}, {}, 0, ....: {0: n}) Traceback (most recent call last): ... @@ -2585,11 +2585,11 @@ def shifted_inhomogeneities(self, recurrence_rules): TESTS:: sage: Seq2 = kRegularSequenceSpace(2, ZZ) - sage: var('n') # optional - sage.symbolic + sage: var('n') n - sage: function('f') # optional - sage.symbolic + sage: function('f') f - sage: UB = Seq2.from_recurrence([ # optional - sage.symbolic + sage: UB = Seq2.from_recurrence([ ....: f(8*n) == 2*f(4*n), ....: f(8*n + 1) == f(4*n + 1), ....: f(8*n + 2) == f(4*n + 1) + f(4*n + 3), @@ -2603,16 +2603,16 @@ def shifted_inhomogeneities(self, recurrence_rules): ....: f(10) == 4, f(11) == 4, f(12) == 12, f(13) == 0, f(14) == 4, ....: f(15) == 4, f(16) == 8, f(17) == 4, f(18) == 8, f(19) == 0, ....: f(20) == 8, f(21) == 4, f(22) == 4, f(23) == 8], f, n, offset=3) - sage: inhomogeneities={2: UB.subsequence(4, 3), 3: -UB.subsequence(4, 1), # optional - sage.symbolic + sage: inhomogeneities={2: UB.subsequence(4, 3), 3: -UB.subsequence(4, 1), ....: 6: UB.subsequence(4, 2) + UB.subsequence(4, 3)} - sage: recurrence_rules_UB = RR(M=3, m=2, ll=0, uu=9, # optional - sage.symbolic + sage: recurrence_rules_UB = RR(M=3, m=2, ll=0, uu=9, ....: inhomogeneities=inhomogeneities) - sage: shifted_inhomog = RP.shifted_inhomogeneities(recurrence_rules_UB) # optional - sage.symbolic - sage: shifted_inhomog # optional - sage.symbolic + sage: shifted_inhomog = RP.shifted_inhomogeneities(recurrence_rules_UB) + sage: shifted_inhomog {2: 2-regular sequence 8, 8, 8, 12, 12, 16, 12, 16, 12, 24, ..., 3: 2-regular sequence -10, -8, -8, -8, -8, -8, -8, -8, -8, -12, ..., 6: 2-regular sequence 20, 22, 24, 28, 28, 32, 28, 32, 32, 48, ...} - sage: shifted_inhomog[2].mu[0].ncols() == 3*inhomogeneities[2].mu[0].ncols() # optional - sage.symbolic + sage: shifted_inhomog[2].mu[0].ncols() == 3*inhomogeneities[2].mu[0].ncols() True .. SEEALSO:: @@ -2719,11 +2719,11 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): sage: from sage.combinat.k_regular_sequence import RecurrenceParser sage: RP = RecurrenceParser(2, ZZ) - sage: var('n') # optional - sage.symbolic + sage: var('n') n - sage: function('f') # optional - sage.symbolic + sage: function('f') f - sage: M, m, coeffs, initial_values = RP.parse_recurrence([ # optional - sage.symbolic + sage: M, m, coeffs, initial_values = RP.parse_recurrence([ ....: f(8*n) == -1*f(2*n - 1) + 1*f(2*n + 1), ....: f(8*n + 1) == -11*f(2*n - 1) + 10*f(2*n) + 11*f(2*n + 1), ....: f(8*n + 2) == -21*f(2*n - 1) + 20*f(2*n) + 21*f(2*n + 1), @@ -2734,9 +2734,9 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): ....: f(8*n + 7) == -71*f(2*n - 1) + 70*f(2*n) + 71*f(2*n + 1), ....: f(0) == 0, f(1) == 1, f(2) == 2, f(3) == 3, f(4) == 4, ....: f(5) == 5, f(6) == 6, f(7) == 7], f, n) - sage: rules = RP.parameters( # optional - sage.symbolic + sage: rules = RP.parameters( ....: M, m, coeffs, initial_values, 0) - sage: RP.matrix(rules, 0, False) # optional - sage.symbolic + sage: RP.matrix(rules, 0, False) [ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0] @@ -2754,7 +2754,7 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): [ 0 0 0 -31 30 31 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 -41 40 41 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 -51 50 51 0 0 0 0 0 0 0 0 0 0 0] - sage: RP.matrix(rules, 1, False) # optional - sage.symbolic + sage: RP.matrix(rules, 1, False) [ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0] @@ -2789,7 +2789,7 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): Number of Unbordered Factors in the Thue--Morse Sequence:: - sage: M, m, coeffs, initial_values = RP.parse_recurrence([ # optional - sage.symbolic + sage: M, m, coeffs, initial_values = RP.parse_recurrence([ ....: f(8*n) == 2*f(4*n), ....: f(8*n + 1) == f(4*n + 1), ....: f(8*n + 2) == f(4*n + 1) + f(4*n + 3), @@ -2803,9 +2803,9 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): ....: f(10) == 4, f(11) == 4, f(12) == 12, f(13) == 0, f(14) == 4, ....: f(15) == 4, f(16) == 8, f(17) == 4, f(18) == 8, f(19) == 0, ....: f(20) == 8, f(21) == 4, f(22) == 4, f(23) == 8], f, n) - sage: UB_rules = RP.parameters( # optional - sage.symbolic + sage: UB_rules = RP.parameters( ....: M, m, coeffs, initial_values, 3) - sage: RP.matrix(UB_rules, 0) # optional - sage.symbolic + sage: RP.matrix(UB_rules, 0) [ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0] @@ -2822,7 +2822,7 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): [ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0] - sage: RP.matrix(UB_rules, 1) # optional - sage.symbolic + sage: RP.matrix(UB_rules, 1) [ 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0] @@ -3016,9 +3016,9 @@ def right(self, recurrence_rules): sage: from sage.combinat.k_regular_sequence import RecurrenceParser sage: RP = RecurrenceParser(2, ZZ) - sage: var('n') # optional - sage.symbolic + sage: var('n') n - sage: function('f') # optional - sage.symbolic + sage: function('f') f sage: SB_rules = RP.parameters( ....: 1, 0, {(0, 0): 1, (1, 0): 1, (1, 1): 1}, @@ -3028,7 +3028,7 @@ def right(self, recurrence_rules): Number of Unbordered Factors in the Thue--Morse Sequence:: - sage: M, m, coeffs, initial_values = RP.parse_recurrence([ # optional - sage.symbolic + sage: M, m, coeffs, initial_values = RP.parse_recurrence([ ....: f(8*n) == 2*f(4*n), ....: f(8*n + 1) == f(4*n + 1), ....: f(8*n + 2) == f(4*n + 1) + f(4*n + 3), @@ -3042,9 +3042,9 @@ def right(self, recurrence_rules): ....: f(10) == 4, f(11) == 4, f(12) == 12, f(13) == 0, f(14) == 4, ....: f(15) == 4, f(16) == 8, f(17) == 4, f(18) == 8, f(19) == 0, ....: f(20) == 8, f(21) == 4, f(22) == 4, f(23) == 8], f, n) - sage: UB_rules = RP.parameters( # optional - sage.symbolic + sage: UB_rules = RP.parameters( ....: M, m, coeffs, initial_values, 3) - sage: RP.right(UB_rules) # optional - sage.symbolic + sage: RP.right(UB_rules) (1, 1, 2, 1, 2, 2, 4, 2, 4, 6, 0, 4, 4, 1, 0, 0) """ from sage.modules.free_module_element import vector @@ -3080,12 +3080,12 @@ def __call__(self, *args, **kwds): sage: from sage.combinat.k_regular_sequence import RecurrenceParser sage: RP = RecurrenceParser(2, ZZ) - sage: var('n') # optional - sage.symbolic + sage: var('n') n - sage: function('f') # optional - sage.symbolic + sage: function('f') f - sage: RP([f(2*n) == f(n), f(2*n + 1) == f(n) + f(n + 1), # optional - sage.symbolic + sage: RP([f(2*n) == f(n), f(2*n + 1) == f(n) + f(n + 1), ....: f(0) == 0, f(1) == 1], f, n) ([ [1 0 0] [1 1 0] @@ -3095,7 +3095,7 @@ def __call__(self, *args, **kwds): (1, 0, 0), (0, 1, 1)) - sage: RP(equations=[f(2*n) == f(n), f(2*n + 1) == f(n) + f(n + 1), # optional - sage.symbolic + sage: RP(equations=[f(2*n) == f(n), f(2*n + 1) == f(n) + f(n + 1), ....: f(0) == 0, f(1) == 1], function=f, var=n) ([ [1 0 0] [1 1 0] From d15a157ea97a53f5331a17f732d6aa265c2ad5c4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sat, 10 Jun 2023 09:55:38 -0700 Subject: [PATCH 074/228] src/sage/combinat/root_system/root_lattice_realizations.py: Docstring cosmetics --- .../root_system/root_lattice_realizations.py | 353 ++++++++++-------- 1 file changed, 195 insertions(+), 158 deletions(-) diff --git a/src/sage/combinat/root_system/root_lattice_realizations.py b/src/sage/combinat/root_system/root_lattice_realizations.py index e7f0e87807f..e8d63867f09 100644 --- a/src/sage/combinat/root_system/root_lattice_realizations.py +++ b/src/sage/combinat/root_system/root_lattice_realizations.py @@ -107,7 +107,8 @@ class RootLatticeRealizations(Category_over_base_ring): sage: L(x) Traceback (most recent call last): ... - TypeError: do not know how to make x (= alpha[2] + 1/2*alpha[5]) an element of self (=Weight lattice of the Root system of type ['A', 7]) + TypeError: do not know how to make x (= alpha[2] + 1/2*alpha[5]) + an element of self (=Weight lattice of the Root system of type ['A', 7]) If `K_1` is a subring of `K_2`, then one could in theory have an embedding from the root space over `K_1` to any root @@ -125,7 +126,9 @@ class RootLatticeRealizations(Category_over_base_ring): sage: L(alpha[1]) Traceback (most recent call last): ... - TypeError: do not know how to make x (= alpha[1]) an element of self (=Weight space over the Univariate Polynomial Ring in q over Rational Field of the Root system of type ['A', 7]) + TypeError: do not know how to make x (= alpha[1]) an element of self + (=Weight space over the Univariate Polynomial Ring in q + over Rational Field of the Root system of type ['A', 7]) By a slight abuse, the embedding of the root lattice is not actually required to be faithful. Typically for an affine root system, the @@ -277,7 +280,7 @@ def _name_string_helper(self, name, capitalize=True, base_ring=True, type=True, def some_elements(self): """ - Return some elements of this root lattice realization + Return some elements of this root lattice realization. EXAMPLES:: @@ -299,7 +302,7 @@ def some_elements(self): def _test_root_lattice_realization(self, **options): """ - Runs sanity checks on this root lattice realization + Run sanity checks on this root lattice realization - embedding of the root lattice - embedding of the root space over the same base ring @@ -369,7 +372,7 @@ def _test_root_lattice_realization(self, **options): @cached_method def highest_root(self): """ - Returns the highest root (for an irreducible finite root system) + Return the highest root (for an irreducible finite root system). EXAMPLES:: @@ -389,23 +392,27 @@ def highest_root(self): @cached_method def a_long_simple_root(self): """ - Returns a long simple root, corresponding to the highest outgoing edge + Return a long simple root, corresponding to the highest outgoing edge in the Dynkin diagram. - Caveat: this may be break in affine type `A_{2n}^{(2)}` + .. warning:: + + This may be broken in affine type `A_{2n}^{(2)}` - Caveat: meaningful/broken for non irreducible? + Is it meaningful/broken for non irreducible? - TODO: implement CartanType.nodes_by_length as in - MuPAD-Combinat (using CartanType.symmetrizer), and use it - here. + .. TODO:: + + implement CartanType.nodes_by_length as in + MuPAD-Combinat (using CartanType.symmetrizer), and use it + here. TESTS:: - sage: X=RootSystem(['A',1]).weight_space() + sage: X = RootSystem(['A',1]).weight_space() sage: X.a_long_simple_root() 2*Lambda[1] - sage: X=RootSystem(['A',5]).weight_space() + sage: X = RootSystem(['A',5]).weight_space() sage: X.a_long_simple_root() 2*Lambda[1] - Lambda[2] """ @@ -424,7 +431,7 @@ def a_long_simple_root(self): @abstract_method def simple_root(self, i): """ - Returns the `i^{th}` simple root. + Return the `i`-th simple root. This should be overridden by any subclass, and typically implemented as a cached method for efficiency. @@ -446,7 +453,7 @@ def simple_root(self, i): @cached_method def simple_roots(self): r""" - Returns the family `(\alpha_i)_{i\in I}` of the simple roots. + Return the family `(\alpha_i)_{i\in I}` of the simple roots. EXAMPLES:: @@ -570,7 +577,8 @@ def roots(self): This matches with :wikipedia:`Root_systems`:: sage: for T in CartanType.samples(finite = True, crystallographic = True): - ....: print("%s %3s %3s"%(T, len(RootSystem(T).root_lattice().roots()), len(RootSystem(T).weight_lattice().roots()))) + ....: print("%s %3s %3s"%(T, len(RootSystem(T).root_lattice().roots()), + ....: len(RootSystem(T).weight_lattice().roots()))) ['A', 1] 2 2 ['A', 5] 30 30 ['B', 1] 2 2 @@ -698,7 +706,7 @@ def nonparabolic_positive_roots(self, index_set = None): Return the positive roots of ``self`` that are not in the parabolic subsystem indicated by ``index_set``. - If ``index_set`` is None, as in :meth:`positive_roots` + If ``index_set`` is ``None``, as in :meth:`positive_roots` it is assumed to be the entire Dynkin node set. Then the parabolic subsystem consists of all positive roots and the empty list is returned. @@ -711,7 +719,8 @@ def nonparabolic_positive_roots(self, index_set = None): sage: sorted(L.nonparabolic_positive_roots((1,2))) [alpha[1] + alpha[2] + alpha[3], alpha[2] + alpha[3], alpha[3]] sage: sorted(L.nonparabolic_positive_roots(())) - [alpha[1], alpha[1] + alpha[2], alpha[1] + alpha[2] + alpha[3], alpha[2], alpha[2] + alpha[3], alpha[3]] + [alpha[1], alpha[1] + alpha[2], alpha[1] + alpha[2] + alpha[3], + alpha[2], alpha[2] + alpha[3], alpha[3]] """ if not self.cartan_type().is_finite(): @@ -871,7 +880,7 @@ def positive_imaginary_roots(self): @cached_method def positive_roots_by_height(self, increasing = True): r""" - Returns a list of positive roots in increasing order by height. + Return a list of positive roots in increasing order by height. If ``increasing`` is False, returns them in decreasing order. @@ -912,17 +921,20 @@ def positive_roots_parabolic(self, index_set = None): INPUT: - - ``index_set`` -- (default:None) the Dynkin node set of the parabolic subsystem. It should be a tuple. The default value implies the entire Dynkin node set + - ``index_set`` -- (default: ``None``) the Dynkin node set of the + parabolic subsystem. It should be a tuple. The default value + implies the entire Dynkin node set EXAMPLES:: - sage: lattice = RootSystem(['A',3]).root_lattice() + sage: lattice = RootSystem(['A',3]).root_lattice() sage: sorted(lattice.positive_roots_parabolic((1,3)), key=str) [alpha[1], alpha[3]] sage: sorted(lattice.positive_roots_parabolic((2,3)), key=str) [alpha[2], alpha[2] + alpha[3], alpha[3]] sage: sorted(lattice.positive_roots_parabolic(), key=str) - [alpha[1], alpha[1] + alpha[2], alpha[1] + alpha[2] + alpha[3], alpha[2], alpha[2] + alpha[3], alpha[3]] + [alpha[1], alpha[1] + alpha[2], alpha[1] + alpha[2] + alpha[3], + alpha[2], alpha[2] + alpha[3], alpha[3]] .. WARNING:: @@ -943,15 +955,17 @@ def parabolic_covers(alpha): @cached_method def positive_roots_nonparabolic(self, index_set = None): r""" - Returns the set of positive roots outside the parabolic subsystem with Dynkin node set ``index_set``. + Return the set of positive roots outside the parabolic subsystem with Dynkin node set ``index_set``. INPUT: - - ``index_set`` -- (default:None) the Dynkin node set of the parabolic subsystem. It should be a tuple. The default value implies the entire Dynkin node set + - ``index_set`` -- (default: ``None``) the Dynkin node set of the + parabolic subsystem. It should be a tuple. The default value + implies the entire Dynkin node set EXAMPLES:: - sage: lattice = RootSystem(['A',3]).root_lattice() + sage: lattice = RootSystem(['A',3]).root_lattice() sage: sorted(lattice.positive_roots_nonparabolic((1,3)), key=str) [alpha[1] + alpha[2], alpha[1] + alpha[2] + alpha[3], alpha[2], alpha[2] + alpha[3]] sage: sorted(lattice.positive_roots_nonparabolic((2,3)), key=str) @@ -975,11 +989,13 @@ def positive_roots_nonparabolic(self, index_set = None): @cached_method def positive_roots_nonparabolic_sum(self, index_set = None): r""" - Returns the sum of positive roots outside the parabolic subsystem with Dynkin node set ``index_set``. + Return the sum of positive roots outside the parabolic subsystem with Dynkin node set ``index_set``. INPUT: - - ``index_set`` -- (default:None) the Dynkin node set of the parabolic subsystem. It should be a tuple. The default value implies the entire Dynkin node set + - ``index_set`` -- (default: ``None``) the Dynkin node set of the + parabolic subsystem. It should be a tuple. The default value + implies the entire Dynkin node set EXAMPLES:: @@ -1009,37 +1025,38 @@ def positive_roots_nonparabolic_sum(self, index_set = None): def root_poset(self, restricted=False, facade=False): r""" - Returns the (restricted) root poset associated to ``self``. + Return the (restricted) root poset associated to ``self``. The elements are given by the positive roots (resp. non-simple, positive roots), and `\alpha \leq \beta` iff `\beta - \alpha` is a non-negative linear combination of simple roots. INPUT: - - ``restricted`` -- (default:False) if True, only non-simple roots are considered. - - ``facade`` -- (default:False) passes facade option to the poset generator. + - ``restricted`` -- (default: ``False``) if ``True``, only non-simple roots are considered. + - ``facade`` -- (default: ``False``) passes facade option to the poset generator. EXAMPLES:: - sage: Phi = RootSystem(['A',1]).root_poset(); Phi + sage: Phi = RootSystem(['A',1]).root_poset(); Phi # optional - sage.graphs Finite poset containing 1 elements - sage: Phi.cover_relations() + sage: Phi.cover_relations() # optional - sage.graphs [] - sage: Phi = RootSystem(['A',2]).root_poset(); Phi + sage: Phi = RootSystem(['A',2]).root_poset(); Phi # optional - sage.graphs Finite poset containing 3 elements - sage: sorted(Phi.cover_relations(), key=str) + sage: sorted(Phi.cover_relations(), key=str) # optional - sage.graphs [[alpha[1], alpha[1] + alpha[2]], [alpha[2], alpha[1] + alpha[2]]] - sage: Phi = RootSystem(['A',3]).root_poset(restricted=True); Phi + sage: Phi = RootSystem(['A',3]).root_poset(restricted=True); Phi # optional - sage.graphs Finite poset containing 3 elements - sage: sorted(Phi.cover_relations(), key=str) - [[alpha[1] + alpha[2], alpha[1] + alpha[2] + alpha[3]], [alpha[2] + alpha[3], alpha[1] + alpha[2] + alpha[3]]] + sage: sorted(Phi.cover_relations(), key=str) # optional - sage.graphs + [[alpha[1] + alpha[2], alpha[1] + alpha[2] + alpha[3]], + [alpha[2] + alpha[3], alpha[1] + alpha[2] + alpha[3]]] - sage: Phi = RootSystem(['B',2]).root_poset(); Phi + sage: Phi = RootSystem(['B',2]).root_poset(); Phi # optional - sage.graphs Finite poset containing 4 elements - sage: sorted(Phi.cover_relations(), key=str) + sage: sorted(Phi.cover_relations(), key=str) # optional - sage.graphs [[alpha[1] + alpha[2], alpha[1] + 2*alpha[2]], [alpha[1], alpha[1] + alpha[2]], [alpha[2], alpha[1] + alpha[2]]] @@ -1048,7 +1065,7 @@ def root_poset(self, restricted=False, facade=False): Check that :trac:`17982` is fixed:: - sage: RootSystem(['A', 2]).ambient_space().root_poset() + sage: RootSystem(['A', 2]).ambient_space().root_poset() # optional - sage.graphs Finite poset containing 3 elements """ from sage.combinat.posets.posets import Poset @@ -1066,7 +1083,7 @@ def root_poset(self, restricted=False, facade=False): def nonnesting_partition_lattice(self, facade=False): r""" - Return the lattice of nonnesting partitions + Return the lattice of nonnesting partitions. This is the lattice of order ideals of the root poset. @@ -1080,16 +1097,16 @@ def nonnesting_partition_lattice(self, facade=False): sage: R = RootSystem(['A', 3]) sage: RS = R.root_lattice() - sage: P = RS.nonnesting_partition_lattice(); P + sage: P = RS.nonnesting_partition_lattice(); P # optional - sage.graphs Finite lattice containing 14 elements - sage: P.coxeter_transformation()**10 == 1 + sage: P.coxeter_transformation()**10 == 1 # optional - sage.graphs True - sage: R = RootSystem(['B', 3]) - sage: RS = R.root_lattice() - sage: P = RS.nonnesting_partition_lattice(); P + sage: R = RootSystem(['B', 3]) # optional - sage.graphs + sage: RS = R.root_lattice() # optional - sage.graphs + sage: P = RS.nonnesting_partition_lattice(); P # optional - sage.graphs Finite lattice containing 20 elements - sage: P.coxeter_transformation()**7 == 1 + sage: P.coxeter_transformation()**7 == 1 # optional - sage.graphs True REFERENCES: @@ -1103,7 +1120,7 @@ def nonnesting_partition_lattice(self, facade=False): def generalized_nonnesting_partition_lattice(self, m, facade=False): r""" - Return the lattice of `m`-nonnesting partitions + Return the lattice of `m`-nonnesting partitions. This has been defined by Athanasiadis, see chapter 5 of [Arm06]_. @@ -1119,9 +1136,9 @@ def generalized_nonnesting_partition_lattice(self, m, facade=False): sage: R = RootSystem(['A', 2]) sage: RS = R.root_lattice() - sage: P = RS.generalized_nonnesting_partition_lattice(2); P + sage: P = RS.generalized_nonnesting_partition_lattice(2); P # optional - sage.graphs Finite lattice containing 12 elements - sage: P.coxeter_transformation()**20 == 1 + sage: P.coxeter_transformation()**20 == 1 # optional - sage.graphs True """ Phi_plus = self.positive_roots() @@ -1163,7 +1180,7 @@ def is_componentwise_subset(chain1, chain2): def almost_positive_roots(self): r""" - Returns the almost positive roots of ``self`` + Return the almost positive roots of ``self``. These are the positive roots together with the simple negative roots. @@ -1181,7 +1198,7 @@ def almost_positive_roots(self): def negative_roots(self): r""" - Returns the negative roots of self. + Return the negative roots of ``self``. EXAMPLES:: @@ -1202,7 +1219,7 @@ def negative_roots(self): def coroot_lattice(self): """ - Returns the coroot lattice. + Return the coroot lattice. EXAMPLES:: @@ -1226,7 +1243,8 @@ def coroot_space(self, base_ring = QQ): Coroot space over the Rational Field of the Root system of type ['A', 2] sage: RootSystem(['A',2]).root_lattice().coroot_space(QQ['q']) - Coroot space over the Univariate Polynomial Ring in q over Rational Field of the Root system of type ['A', 2] + Coroot space over the Univariate Polynomial Ring in q over Rational Field + of the Root system of type ['A', 2] """ return self.root_system.coroot_space(base_ring = base_ring) @@ -1300,7 +1318,7 @@ def alphacheck(self): @cached_method def cohighest_root(self): """ - Returns the associated coroot of the highest root. + Return the associated coroot of the highest root. .. note:: this is usually not the highest coroot. @@ -1318,9 +1336,11 @@ def cohighest_root(self): @cached_method def null_root(self): """ - Returns the null root of self. The null root is the smallest - non trivial positive root which is orthogonal to all simple - coroots. It exists for any affine root system. + Return the null root of ``self``. + + The null root is the smallest non trivial positive root which is + orthogonal to all simple coroots. It exists for any affine root + system. EXAMPLES:: @@ -1342,20 +1362,22 @@ def null_root(self): @cached_method def null_coroot(self): """ - Returns the null coroot of self. + Return the null coroot of ``self``. - The null coroot is the smallest non trivial positive - coroot which is orthogonal to all simple roots. It exists - for any affine root system. + The null coroot is the smallest non trivial positive coroot which is + orthogonal to all simple roots. It exists for any affine root + system. EXAMPLES:: sage: RootSystem(['C',2,1]).root_lattice().null_coroot() alphacheck[0] + alphacheck[1] + alphacheck[2] sage: RootSystem(['D',4,1]).root_lattice().null_coroot() - alphacheck[0] + alphacheck[1] + 2*alphacheck[2] + alphacheck[3] + alphacheck[4] + alphacheck[0] + alphacheck[1] + 2*alphacheck[2] + + alphacheck[3] + alphacheck[4] sage: RootSystem(['F',4,1]).root_lattice().null_coroot() - alphacheck[0] + 2*alphacheck[1] + 3*alphacheck[2] + 2*alphacheck[3] + alphacheck[4] + alphacheck[0] + 2*alphacheck[1] + 3*alphacheck[2] + + 2*alphacheck[3] + alphacheck[4] """ if not self.cartan_type().is_affine(): raise ValueError("%s is not an affine Cartan type" % (self.cartan_type())) @@ -1409,7 +1431,8 @@ def fundamental_weights_from_simple_roots(self): sage: L.fundamental_weights_from_simple_roots() Traceback (most recent call last): ... - ValueError: The fundamental weights do not live in this realization of the root lattice + ValueError: The fundamental weights do not live in this realization + of the root lattice Beware of the usual `GL_n` vs `SL_n` catch in type `A`:: @@ -1417,13 +1440,16 @@ def fundamental_weights_from_simple_roots(self): sage: L.fundamental_weights() Finite family {1: (1, 0, 0, 0), 2: (1, 1, 0, 0), 3: (1, 1, 1, 0)} sage: L.fundamental_weights_from_simple_roots() - Finite family {1: (3/4, -1/4, -1/4, -1/4), 2: (1/2, 1/2, -1/2, -1/2), 3: (1/4, 1/4, 1/4, -3/4)} + Finite family {1: (3/4, -1/4, -1/4, -1/4), + 2: (1/2, 1/2, -1/2, -1/2), + 3: (1/4, 1/4, 1/4, -3/4)} sage: L = RootSystem(["A",3]).ambient_lattice() sage: L.fundamental_weights_from_simple_roots() Traceback (most recent call last): ... - ValueError: The fundamental weights do not live in this realization of the root lattice + ValueError: The fundamental weights do not live in this realization + of the root lattice """ # We first scale the inverse of the Cartan matrix to be # with integer coefficients; then the linear combination @@ -1448,15 +1474,14 @@ def fundamental_weights_from_simple_roots(self): def reflection(self, root, coroot=None): """ - Returns the reflection along the root, and across the - hyperplane define by coroot, as a function from - self to self. + Return the reflection along the ``root``, and across the hyperplane + defined by ``coroot``, as a function from ``self`` to ``self``. EXAMPLES:: sage: space = RootSystem(['A',2]).weight_lattice() - sage: x=space.simple_roots()[1] - sage: y=space.simple_coroots()[1] + sage: x = space.simple_roots()[1] + sage: y = space.simple_coroots()[1] sage: s = space.reflection(x,y) sage: x 2*Lambda[1] - Lambda[2] @@ -1472,12 +1497,12 @@ def reflection(self, root, coroot=None): @cached_method def simple_reflection(self, i): """ - Returns the `i^{th}` simple reflection, as a function from - self to self. + Return the `i`-th simple reflection, as a function from + ``self`` to ``self``. INPUT: - - ``i`` - i is in self's index set + - ``i`` -- an element of the index set of ``self`` EXAMPLES:: @@ -1522,19 +1547,21 @@ def simple_reflections(self): def projection(self, root, coroot=None, to_negative=True): r""" - Returns the projection along the root, and across the - hyperplane define by coroot, as a function `\pi` from self to - self. `\pi` is a half-linear map which stabilizes the negative - half space, and acts by reflection on the positive half space. + Return the projection along the ``root``, and across the + hyperplane defined by ``coroot``, as a function `\pi` from ``self`` to + ``self``. - If to_negative is False, then this project onto the positive + `\pi` is a half-linear map which stabilizes the negative + half space and acts by reflection on the positive half space. + + If ``to_negative`` is ``False``, then project onto the positive half space instead. EXAMPLES:: sage: space = RootSystem(['A',2]).weight_lattice() - sage: x=space.simple_roots()[1] - sage: y=space.simple_coroots()[1] + sage: x = space.simple_roots()[1] + sage: y = space.simple_coroots()[1] sage: pi = space.projection(x,y) sage: x 2*Lambda[1] - Lambda[2] @@ -1554,13 +1581,13 @@ def projection(self, root, coroot=None, to_negative=True): @cached_method def simple_projection(self, i, to_negative=True): """ - Returns the projection along the `i^{th}` simple root, and across the - hyperplane define by the `i^{th}` simple coroot, as a function from - self to self. + Return the projection along the `i`-th simple root, and across the + hyperplane define by the `i`-th simple coroot, as a function from + ``self`` to ``self``. INPUT: - - ``i`` - i is in self's index set + - ``i`` -- an element of the index set of ``self`` EXAMPLES:: @@ -1582,8 +1609,8 @@ def simple_projection(self, i, to_negative=True): @cached_method def simple_projections(self, to_negative=True): r""" - Returns the family `(s_i)_{i\in I}` of the simple projections - of this root system + Return the family `(s_i)_{i\in I}` of the simple projections + of this root system. EXAMPLES:: @@ -1611,7 +1638,7 @@ def simple_projections(self, to_negative=True): def weyl_group(self, prefix=None): """ - Returns the Weyl group associated to self. + Return the Weyl group associated to ``self``. EXAMPLES:: @@ -1634,7 +1661,7 @@ def weyl_group(self, prefix=None): # create conflicts def tau_epsilon_operator_on_almost_positive_roots(self, J): r""" - The `\tau_\epsilon` operator on almost positive roots + The `\tau_\epsilon` operator on almost positive roots. Given a subset `J` of non adjacent vertices of the Dynkin diagram, this constructs the operator on the almost positive @@ -1717,7 +1744,7 @@ def tau_epsilon(alpha): def tau_plus_minus(self): r""" - Returns the `\tau^+` and `\tau^-` piecewise linear operators on ``self`` + Return the `\tau^+` and `\tau^-` piecewise linear operators on ``self``. Those operators are induced by the bipartition `\{L,R\}` of the simple roots of ``self``, and stabilize the almost @@ -1742,7 +1769,8 @@ def tau_plus_minus(self): sage: S = RootSystem(['A',2]).root_lattice() sage: taup, taum = S.tau_plus_minus() - sage: for beta in S.almost_positive_roots(): print("{} , {} , {}".format(beta, taup(beta), taum(beta))) + sage: for beta in S.almost_positive_roots(): + ....: print("{} , {} , {}".format(beta, taup(beta), taum(beta))) -alpha[1] , alpha[1] , -alpha[1] alpha[1] , -alpha[1] , alpha[1] + alpha[2] alpha[1] + alpha[2] , alpha[2] , alpha[1] @@ -1755,7 +1783,7 @@ def tau_plus_minus(self): def almost_positive_roots_decomposition(self): r""" - Returns the decomposition of the almost positive roots of ``self`` + Return the decomposition of the almost positive roots of ``self``. This is the list of the orbits of the almost positive roots under the action of the dihedral group generated by the @@ -1772,11 +1800,13 @@ def almost_positive_roots_decomposition(self): [[-alpha[1], alpha[1], alpha[1] + alpha[2], alpha[2], -alpha[2]]] sage: RootSystem(['B',2]).root_lattice().almost_positive_roots_decomposition() - [[-alpha[1], alpha[1], alpha[1] + 2*alpha[2]], [-alpha[2], alpha[2], alpha[1] + alpha[2]]] + [[-alpha[1], alpha[1], alpha[1] + 2*alpha[2]], + [-alpha[2], alpha[2], alpha[1] + alpha[2]]] sage: RootSystem(['D',4]).root_lattice().almost_positive_roots_decomposition() [[-alpha[1], alpha[1], alpha[1] + alpha[2], alpha[2] + alpha[3] + alpha[4]], - [-alpha[2], alpha[2], alpha[1] + alpha[2] + alpha[3] + alpha[4], alpha[1] + 2*alpha[2] + alpha[3] + alpha[4]], + [-alpha[2], alpha[2], alpha[1] + alpha[2] + alpha[3] + alpha[4], + alpha[1] + 2*alpha[2] + alpha[3] + alpha[4]], [-alpha[3], alpha[3], alpha[2] + alpha[3], alpha[1] + alpha[2] + alpha[4]], [-alpha[4], alpha[4], alpha[2] + alpha[4], alpha[1] + alpha[2] + alpha[3]]] """ @@ -2029,7 +2059,7 @@ def plot(self, EXAMPLES:: - sage: L = RootSystem(["A",2,1]).ambient_space().plot() # long time + sage: L = RootSystem(["A",2,1]).ambient_space().plot() # long time # optional - sage.plot sage.symbolic .. SEEALSO:: @@ -3220,7 +3250,7 @@ def plot_crystal(self, crystal, @cached_method def dual_type_cospace(self): r""" - Returns the cospace of dual type. + Return the cospace of dual type. For example, if invoked on the root lattice of type `['B',2]`, returns the coroot lattice of type `['C',2]`. @@ -3399,7 +3429,7 @@ def norm_squared(self): def simple_reflection(self, i): r""" - Returns the image of ``self`` by the `i`-th simple reflection. + Return the image of ``self`` by the `i`-th simple reflection. EXAMPLES:: @@ -3407,7 +3437,7 @@ def simple_reflection(self, i): sage: alpha[1].simple_reflection(2) alpha[1] + alpha[2] - sage: Q = RootSystem(['A', 3, 1]).weight_lattice(extended = True) + sage: Q = RootSystem(['A', 3, 1]).weight_lattice(extended=True) sage: Lambda = Q.fundamental_weights() sage: L = Lambda[0] + Q.null_root() sage: L.simple_reflection(0) @@ -3418,7 +3448,7 @@ def simple_reflection(self, i): def simple_reflections(self): """ - The images of self by all the simple reflections + The images of ``self`` by all the simple reflections EXAMPLES:: @@ -3557,7 +3587,7 @@ def dot_orbit(self): @abstract_method(optional=True) def associated_coroot(self): """ - Returns the coroot associated to this root + Return the coroot associated to this root. EXAMPLES:: @@ -3568,9 +3598,9 @@ def associated_coroot(self): def reflection(self, root, use_coroot = False): r""" - Reflects ``self`` across the hyperplane orthogonal to ``root``. + Reflect ``self`` across the hyperplane orthogonal to ``root``. - If ``use_coroot`` is True, ``root`` is interpreted as a coroot. + If ``use_coroot`` is ``True``, ``root`` is interpreted as a coroot. EXAMPLES:: @@ -3597,17 +3627,17 @@ def reflection(self, root, use_coroot = False): def has_descent(self, i, positive=False): """ - Test if self has a descent at position `i`, that is if self is - on the strict negative side of the `i^{th}` simple reflection + Test if ``self`` has a descent at position `i`, that is, if ``self`` is + on the strict negative side of the `i`-th simple reflection hyperplane. - If positive if True, tests if it is on the strict positive + If positive is ``True``, tests if it is on the strict positive side instead. EXAMPLES:: - sage: space=RootSystem(['A',5]).weight_space() - sage: alpha=RootSystem(['A',5]).weight_space().simple_roots() + sage: space = RootSystem(['A',5]).weight_space() + sage: alpha = RootSystem(['A',5]).weight_space().simple_roots() sage: [alpha[i].has_descent(1) for i in space.index_set()] [False, True, False, False, False] sage: [(-alpha[i]).has_descent(1) for i in space.index_set()] @@ -3631,15 +3661,15 @@ def has_descent(self, i, positive=False): def first_descent(self, index_set=None, positive=False): """ - Returns the first descent of pt + Return the first descent of pt - One can use the index_set option to restrict to the parabolic - subgroup indexed by index_set. + One can use the ``index_set`` option to restrict to the parabolic + subgroup indexed by ``index_set``. EXAMPLES:: - sage: space=RootSystem(['A',5]).weight_space() - sage: alpha=space.simple_roots() + sage: space = RootSystem(['A',5]).weight_space() + sage: alpha = space.simple_roots() sage: (alpha[1]+alpha[2]+alpha[4]).first_descent() 3 sage: (alpha[1]+alpha[2]+alpha[4]).first_descent([1,2,5]) @@ -3656,12 +3686,12 @@ def first_descent(self, index_set=None, positive=False): def descents(self, index_set=None, positive=False): """ - Returns the descents of pt + Return the descents of pt EXAMPLES:: - sage: space=RootSystem(['A',5]).weight_space() - sage: alpha=space.simple_roots() + sage: space = RootSystem(['A',5]).weight_space() + sage: alpha = space.simple_roots() sage: (alpha[1]+alpha[2]+alpha[4]).descents() [3, 5] """ @@ -3671,14 +3701,14 @@ def descents(self, index_set=None, positive=False): def to_dominant_chamber(self, index_set = None, positive = True, reduced_word = False): r""" - Returns the unique dominant element in the Weyl group orbit of the vector ``self``. + Return the unique dominant element in the Weyl group orbit of the vector ``self``. - If ``positive`` is False, returns the antidominant orbit element. + If ``positive`` is ``False``, returns the antidominant orbit element. With the ``index_set`` optional parameter, this is done with respect to the corresponding parabolic subgroup. - If ``reduced_word`` is True, returns the 2-tuple (``weight``, ``direction``) + If ``reduced_word`` is ``True``, returns the 2-tuple (``weight``, ``direction``) where ``weight`` is the (anti)dominant orbit element and ``direction`` is a reduced word for the Weyl group element sending ``weight`` to ``self``. @@ -3698,15 +3728,15 @@ def to_dominant_chamber(self, index_set = None, positive = True, reduced_word = EXAMPLES:: - sage: space=RootSystem(['A',5]).weight_space() - sage: alpha=RootSystem(['A',5]).weight_space().simple_roots() + sage: space = RootSystem(['A',5]).weight_space() + sage: alpha = RootSystem(['A',5]).weight_space().simple_roots() sage: alpha[1].to_dominant_chamber() Lambda[1] + Lambda[5] sage: alpha[1].to_dominant_chamber([1,2]) Lambda[1] + Lambda[2] - Lambda[3] - sage: wl=RootSystem(['A',2,1]).weight_lattice(extended=True) - sage: mu=wl.from_vector(vector([1,-3,0])) - sage: mu.to_dominant_chamber(positive=False, reduced_word = True) + sage: wl = RootSystem(['A',2,1]).weight_lattice(extended=True) + sage: mu = wl.from_vector(vector([1,-3,0])) + sage: mu.to_dominant_chamber(positive=False, reduced_word=True) (-Lambda[1] - Lambda[2] - delta, [0, 2]) sage: R = RootSystem(['A',1,1]) @@ -3765,7 +3795,7 @@ def to_dominant_chamber(self, index_set = None, positive = True, reduced_word = def reduced_word(self, index_set = None, positive = True): r""" - Returns a reduced word for the inverse of the shortest Weyl group element that sends the vector ``self`` into the dominant chamber. + Return a reduced word for the inverse of the shortest Weyl group element that sends the vector ``self`` into the dominant chamber. With the ``index_set`` optional parameter, this is done with respect to the corresponding parabolic subgroup. @@ -3774,8 +3804,8 @@ def reduced_word(self, index_set = None, positive = True): EXAMPLES:: - sage: space=RootSystem(['A',5]).weight_space() - sage: alpha=RootSystem(['A',5]).weight_space().simple_roots() + sage: space = RootSystem(['A',5]).weight_space() + sage: alpha = RootSystem(['A',5]).weight_space().simple_roots() sage: alpha[1].reduced_word() [2, 3, 4, 5] sage: alpha[1].reduced_word([1,2]) @@ -3786,11 +3816,11 @@ def reduced_word(self, index_set = None, positive = True): def is_dominant(self, index_set = None, positive = True): r""" - Returns whether self is dominant. + Return whether ``self`` is dominant. - This is done with respect to the subrootsystem indicated by the subset of Dynkin nodes - index_set. If index_set is None then the entire Dynkin node set is used. - If positive is False then the dominance condition is replaced by antidominance. + This is done with respect to the sub--root system indicated by the subset of Dynkin nodes + ``index_set``. If ``index_set`` is ``None``, then the entire Dynkin node set is used. + If positive is ``False``, then the dominance condition is replaced by antidominance. EXAMPLES:: @@ -3857,7 +3887,7 @@ def succ(self, index_set=None): INPUT: - - ``index_set`` - a subset (as a list or iterable) of the + - ``index_set`` -- a subset (as a list or iterable) of the nodes of the Dynkin diagram; (default: ``None`` for all of them) If ``index_set`` is specified, the successors for the @@ -3870,7 +3900,9 @@ def succ(self, index_set=None): sage: Lambda[1].succ() [-Lambda[1] + Lambda[2]] sage: L.rho().succ() - [-Lambda[1] + 2*Lambda[2] + Lambda[3], 2*Lambda[1] - Lambda[2] + 2*Lambda[3], Lambda[1] + 2*Lambda[2] - Lambda[3]] + [-Lambda[1] + 2*Lambda[2] + Lambda[3], + 2*Lambda[1] - Lambda[2] + 2*Lambda[3], + Lambda[1] + 2*Lambda[2] - Lambda[3]] sage: (-L.rho()).succ() [] sage: L.rho().succ(index_set=[1]) @@ -3886,7 +3918,7 @@ def pred(self, index_set=None): INPUT: - - ``index_set`` - a subset (as a list or iterable) of the + - ``index_set`` -- a subset (as a list or iterable) of the nodes of the Dynkin diagram; (default: ``None`` for all of them) If ``index_set`` is specified, the successors for the @@ -3901,7 +3933,9 @@ def pred(self, index_set=None): sage: L.rho().pred() [] sage: (-L.rho()).pred() - [Lambda[1] - 2*Lambda[2] - Lambda[3], -2*Lambda[1] + Lambda[2] - 2*Lambda[3], -Lambda[1] - 2*Lambda[2] + Lambda[3]] + [Lambda[1] - 2*Lambda[2] - Lambda[3], + -2*Lambda[1] + Lambda[2] - 2*Lambda[3], + -Lambda[1] - 2*Lambda[2] + Lambda[3]] sage: (-L.rho()).pred(index_set=[1]) [Lambda[1] - 2*Lambda[2] - Lambda[3]] """ @@ -3909,8 +3943,8 @@ def pred(self, index_set=None): def greater(self): r""" - Returns the elements in the orbit of self which are - greater than self in the weak order. + Return the elements in the orbit of ``self`` which are + greater than ``self`` in the weak order. EXAMPLES:: @@ -3930,8 +3964,8 @@ def greater(self): def smaller(self): r""" - Returns the elements in the orbit of self which are - smaller than self in the weak order. + Return the elements in the orbit of ``self`` which are + smaller than ``self`` in the weak order. EXAMPLES:: @@ -4023,7 +4057,7 @@ def to_simple_root(self, reduced_word=False): OUTPUT: - The index `i` of a simple root `\alpha_i`. - If ``reduced_word`` is True, this returns instead a pair + If ``reduced_word`` is ``True``, this returns instead a pair ``(i, word)``, where word is a sequence of reflections mapping `\alpha_i` up the root poset to ``self``. @@ -4098,15 +4132,16 @@ def to_simple_root(self, reduced_word=False): @cached_in_parent_method def associated_reflection(self): r""" - Given a positive root ``self``, returns a reduced word for the reflection orthogonal to ``self``. + Given a positive root ``self``, return a reduced word for the reflection orthogonal to ``self``. Since the answer is cached, it is a tuple instead of a list. EXAMPLES:: - sage: RootSystem(['C',3]).root_lattice().simple_root(3).weyl_action([1,2]).associated_reflection() + sage: C3_rl = RootSystem(['C',3]).root_lattice() + sage: C3_rl.simple_root(3).weyl_action([1,2]).associated_reflection() (1, 2, 3, 2, 1) - sage: RootSystem(['C',3]).root_lattice().simple_root(2).associated_reflection() + sage: C3_rl.simple_root(2).associated_reflection() (2,) """ @@ -4115,13 +4150,13 @@ def associated_reflection(self): def translation(self, x): """ + Return `x` translated by `t`, that is, `x+level(x) t`. + INPUT: - ``self`` -- an element `t` at level `0` - ``x`` -- an element of the same space - Returns `x` translated by `t`, that is `x+level(x) t` - EXAMPLES:: sage: L = RootSystem(['A',2,1]).weight_lattice() @@ -4177,7 +4212,7 @@ def weyl_action(self, element, inverse=False): sage: mu = wl.from_vector(vector([1,0,-2])) sage: mu Lambda[1] - 2*Lambda[3] - sage: mudom, rw = mu.to_dominant_chamber(positive=False, reduced_word = True) + sage: mudom, rw = mu.to_dominant_chamber(positive=False, reduced_word=True) sage: mudom, rw (-Lambda[2] - Lambda[3], [1, 2]) @@ -4234,15 +4269,15 @@ def weyl_action(self, element, inverse=False): def weyl_stabilizer(self, index_set=None): r""" - Returns the subset of Dynkin nodes whose reflections fix ``self``. + Return the subset of Dynkin nodes whose reflections fix ``self``. - If ``index_set`` is not None, only consider nodes in this set. + If ``index_set`` is not ``None``, only consider nodes in this set. Note that if ``self`` is dominant or antidominant, then its stabilizer is the parabolic subgroup defined by the returned node set. EXAMPLES:: - sage: wl = RootSystem(['A',2,1]).weight_lattice(extended = True) + sage: wl = RootSystem(['A',2,1]).weight_lattice(extended=True) sage: al = wl.null_root() sage: al.weyl_stabilizer() [0, 1, 2] @@ -4254,7 +4289,6 @@ def weyl_stabilizer(self, index_set=None): [3] """ - if index_set is None: index_set = self.parent().cartan_type().index_set() alphavee = self.parent().coroot_lattice().basis() @@ -4309,7 +4343,9 @@ def dot_action(self, w, inverse=False): def is_parabolic_root(self, index_set): r""" - Supposing that ``self`` is a root, is it in the parabolic subsystem with Dynkin nodes ``index_set``? + Return whether ``root`` is in the parabolic subsystem with Dynkin nodes ``index_set``. + + This assumes that ``self`` is a root. INPUT: @@ -4337,7 +4373,7 @@ def is_short_root(self): r""" Return ``True`` if ``self`` is a short (real) root. - Returns False unless the parent is an irreducible root system of finite type + Returns ``False`` unless the parent is an irreducible root system of finite type having two root lengths and ``self`` is of the shorter length. There is no check of whether ``self`` is actually a root. @@ -4439,19 +4475,20 @@ def to_ambient(self): EXAMPLES:: - sage: alpha = CartanType(['B',4]).root_system().root_lattice().an_element(); alpha + sage: B4_rs = CartanType(['B',4]).root_system() + sage: alpha = B4_rs.root_lattice().an_element(); alpha 2*alpha[1] + 2*alpha[2] + 3*alpha[3] sage: alpha.to_ambient() (2, 0, 1, -3) - sage: mu = CartanType(['B',4]).root_system().weight_lattice().an_element(); mu + sage: mu = B4_rs.weight_lattice().an_element(); mu 2*Lambda[1] + 2*Lambda[2] + 3*Lambda[3] sage: mu.to_ambient() (7, 5, 3, 0) - sage: v = CartanType(['B',4]).root_system().ambient_space().an_element(); v + sage: v = B4_rs.ambient_space().an_element(); v (2, 2, 3, 0) sage: v.to_ambient() (2, 2, 3, 0) - sage: alphavee = CartanType(['B',4]).root_system().coroot_lattice().an_element(); alphavee + sage: alphavee = B4_rs.coroot_lattice().an_element(); alphavee 2*alphacheck[1] + 2*alphacheck[2] + 3*alphacheck[3] sage: alphavee.to_ambient() (2, 0, 1, -3) @@ -4482,7 +4519,7 @@ def is_imaginary_root(self): r""" Return ``True`` if ``self`` is an imaginary root. - A root `\alpha` is imaginary if it is not `W` conjugate + A root `\alpha` is imaginary if it is not `W`-conjugate to a simple root where `W` is the corresponding Weyl group. EXAMPLES:: @@ -4501,7 +4538,7 @@ def is_real_root(self): r""" Return ``True`` if ``self`` is a real root. - A root `\alpha` is real if it is `W` conjugate to a simple + A root `\alpha` is real if it is `W`-conjugate to a simple root where `W` is the corresponding Weyl group. EXAMPLES:: From 3178ccbd96966127b0488967f9d5ff46dc1bf3d1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sat, 10 Jun 2023 10:08:56 -0700 Subject: [PATCH 075/228] src/sage/combinat/ordered_tree.py: Docstring cosmetics --- src/sage/combinat/ordered_tree.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/ordered_tree.py b/src/sage/combinat/ordered_tree.py index 8faea2f248b..0b2fa87e3c7 100644 --- a/src/sage/combinat/ordered_tree.py +++ b/src/sage/combinat/ordered_tree.py @@ -353,7 +353,7 @@ def to_parallelogram_polyomino(self, bijection=None): INPUT: - - ``bijection`` -- (default:``'Boussicault-Socci'``) is the name of the + - ``bijection`` -- (default: ``'Boussicault-Socci'``) is the name of the bijection to use. Possible values are ``'Boussicault-Socci'``, ``'via dyck and Delest-Viennot'``. From 62d3d48d42499a387a716efea1be40f7580dfe5a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sat, 10 Jun 2023 10:31:51 -0700 Subject: [PATCH 076/228] src/sage/combinat/designs/block_design.py: Doctest/docstring cosmetics, use file-level # optional - sage.rings.finite_rings, add some # optional - sage.modules --- src/sage/combinat/designs/block_design.py | 196 +++++++++++----------- 1 file changed, 99 insertions(+), 97 deletions(-) diff --git a/src/sage/combinat/designs/block_design.py b/src/sage/combinat/designs/block_design.py index 6e618e36d89..28f3746ad88 100644 --- a/src/sage/combinat/designs/block_design.py +++ b/src/sage/combinat/designs/block_design.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.rings.finite_rings r""" Block designs @@ -75,7 +75,7 @@ def tdesign_params(t, v, k, L): EXAMPLES:: - sage: BD = BlockDesign(7,[[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]]) + sage: BD = BlockDesign(7, [[0,1,2],[0,3,4],[0,5,6],[1,3,5],[1,4,6],[2,3,6],[2,4,5]]) sage: from sage.combinat.designs.block_design import tdesign_params sage: tdesign_params(2,7,3,1) (2, 7, 7, 3, 3, 1) @@ -114,17 +114,19 @@ def are_hyperplanes_in_projective_geometry_parameters(v, k, lmbda, return_parame EXAMPLES:: sage: from sage.combinat.designs.block_design import are_hyperplanes_in_projective_geometry_parameters - sage: are_hyperplanes_in_projective_geometry_parameters(40,13,4) + sage: are_hyperplanes_in_projective_geometry_parameters(40, 13, 4) True - sage: are_hyperplanes_in_projective_geometry_parameters(40,13,4,return_parameters=True) + sage: are_hyperplanes_in_projective_geometry_parameters(40, 13, 4, + ....: return_parameters=True) (True, (3, 3)) - sage: PG = designs.ProjectiveGeometryDesign(3,2,GF(3)) + sage: PG = designs.ProjectiveGeometryDesign(3, 2, GF(3)) sage: PG.is_t_design(return_parameters=True) (True, (2, 40, 13, 4)) - sage: are_hyperplanes_in_projective_geometry_parameters(15,3,1) + sage: are_hyperplanes_in_projective_geometry_parameters(15, 3, 1) False - sage: are_hyperplanes_in_projective_geometry_parameters(15,3,1,return_parameters=True) + sage: are_hyperplanes_in_projective_geometry_parameters(15, 3, 1, + ....: return_parameters=True) (False, (None, None)) TESTS:: @@ -167,7 +169,7 @@ def ProjectiveGeometryDesign(n, d, F, algorithm=None, point_coordinates=True, ch Return a projective geometry design. The projective geometry design `PG_d(n,q)` has for points the lines of - `\GF{q}^{n+1}`, and for blocks the `d+1`-dimensional subspaces of + `\GF{q}^{n+1}`, and for blocks the `(d+1)`-dimensional subspaces of `\GF{q}^{n+1}`, each of which contains `\frac {|\GF{q}|^{d+1}-1} {|\GF{q}|-1}` lines. It is a `2`-design with parameters @@ -189,9 +191,9 @@ def ProjectiveGeometryDesign(n, d, F, algorithm=None, point_coordinates=True, ch INPUT: - - ``n`` is the projective dimension + - ``n`` -- the projective dimension - - ``d`` is the dimension of the subspaces which make up the blocks. + - ``d`` -- the dimension of the subspaces which make up the blocks. - ``F`` -- a finite field or a prime power. @@ -236,14 +238,14 @@ def ProjectiveGeometryDesign(n, d, F, algorithm=None, point_coordinates=True, ch Use indexing by integers:: - sage: PG = designs.ProjectiveGeometryDesign(2,1,GF(3),point_coordinates=0) + sage: PG = designs.ProjectiveGeometryDesign(2, 1, GF(3), point_coordinates=0) sage: PG.blocks()[0] [0, 1, 2, 12] Check that the constructor using gap also works:: - sage: BD = designs.ProjectiveGeometryDesign(2, 1, GF(2), algorithm="gap") # optional - gap_packages (design package) - sage: BD.is_t_design(return_parameters=True) # optional - gap_packages (design package) + sage: BD = designs.ProjectiveGeometryDesign(2, 1, GF(2), algorithm="gap") # optional - gap_packages (design package) + sage: BD.is_t_design(return_parameters=True) # optional - gap_packages (design package) (True, (2, 7, 3, 1)) """ try: @@ -304,7 +306,7 @@ def DesarguesianProjectivePlaneDesign(n, point_coordinates=True, check=True): - ``n`` -- an integer which must be a power of a prime number - - ``point_coordinates`` (boolean) -- whether to label the points with their + - ``point_coordinates`` -- (boolean) whether to label the points with their homogeneous coordinates (default) or with integers. - ``check`` -- (boolean) Whether to check that output is correct before @@ -318,15 +320,15 @@ def DesarguesianProjectivePlaneDesign(n, point_coordinates=True, check=True): EXAMPLES:: - sage: designs.DesarguesianProjectivePlaneDesign(2) # optional - sage.rings.finite_rings + sage: designs.DesarguesianProjectivePlaneDesign(2) (7,3,1)-Balanced Incomplete Block Design - sage: designs.DesarguesianProjectivePlaneDesign(3) # optional - sage.rings.finite_rings + sage: designs.DesarguesianProjectivePlaneDesign(3) (13,4,1)-Balanced Incomplete Block Design - sage: designs.DesarguesianProjectivePlaneDesign(4) # optional - sage.rings.finite_rings + sage: designs.DesarguesianProjectivePlaneDesign(4) (21,5,1)-Balanced Incomplete Block Design - sage: designs.DesarguesianProjectivePlaneDesign(5) # optional - sage.rings.finite_rings + sage: designs.DesarguesianProjectivePlaneDesign(5) (31,6,1)-Balanced Incomplete Block Design - sage: designs.DesarguesianProjectivePlaneDesign(6) # optional - sage.rings.finite_rings + sage: designs.DesarguesianProjectivePlaneDesign(6) Traceback (most recent call last): ... ValueError: the order of a finite field must be a prime power @@ -395,25 +397,25 @@ def q3_minus_one_matrix(K): r""" Return a companion matrix in `GL(3, K)` whose multiplicative order is `q^3 - 1`. - This function is used in :func:`HughesPlane` + This function is used in :func:`HughesPlane`. EXAMPLES:: sage: from sage.combinat.designs.block_design import q3_minus_one_matrix - sage: m = q3_minus_one_matrix(GF(3)) # optional - sage.rings.finite_rings - sage: m.multiplicative_order() == 3**3 - 1 # optional - sage.rings.finite_rings + sage: m = q3_minus_one_matrix(GF(3)) + sage: m.multiplicative_order() == 3**3 - 1 True - sage: m = q3_minus_one_matrix(GF(4, 'a')) # optional - sage.rings.finite_rings - sage: m.multiplicative_order() == 4**3 - 1 # optional - sage.rings.finite_rings + sage: m = q3_minus_one_matrix(GF(4, 'a')) + sage: m.multiplicative_order() == 4**3 - 1 True - sage: m = q3_minus_one_matrix(GF(5)) # optional - sage.rings.finite_rings - sage: m.multiplicative_order() == 5**3 - 1 # optional - sage.rings.finite_rings + sage: m = q3_minus_one_matrix(GF(5)) + sage: m.multiplicative_order() == 5**3 - 1 True - sage: m = q3_minus_one_matrix(GF(9, 'a')) # optional - sage.rings.finite_rings - sage: m.multiplicative_order() == 9**3 - 1 # optional - sage.rings.finite_rings + sage: m = q3_minus_one_matrix(GF(9, 'a')) + sage: m.multiplicative_order() == 9**3 - 1 True """ q = K.cardinality() @@ -450,24 +452,24 @@ def normalize_hughes_plane_point(p, q): INPUT: - - ``p`` - point with the coordinates (x,y,z) (a list, a vector, a tuple...) + - ``p`` -- point with the coordinates `(x,y,z)` (a list, a vector, a tuple...) - - ``q`` - cardinality of the underlying finite field + - ``q`` -- cardinality of the underlying finite field EXAMPLES:: sage: from sage.combinat.designs.block_design import normalize_hughes_plane_point - sage: K = FiniteField(9,'x') # optional - sage.rings.finite_rings - sage: x = K.gen() # optional - sage.rings.finite_rings - sage: normalize_hughes_plane_point((x, x+1, x), 9) # optional - sage.rings.finite_rings + sage: K = FiniteField(9,'x') + sage: x = K.gen() + sage: normalize_hughes_plane_point((x, x + 1, x), 9) (1, x, 1) - sage: normalize_hughes_plane_point(vector((x,x,x)), 9) # optional - sage.rings.finite_rings + sage: normalize_hughes_plane_point(vector((x,x,x)), 9) (1, 1, 1) - sage: zero = K.zero() # optional - sage.rings.finite_rings - sage: normalize_hughes_plane_point((2*x+2, zero, zero), 9) # optional - sage.rings.finite_rings + sage: zero = K.zero() + sage: normalize_hughes_plane_point((2*x + 2, zero, zero), 9) (1, 0, 0) - sage: one = K.one() # optional - sage.rings.finite_rings - sage: normalize_hughes_plane_point((2*x, one, zero), 9) # optional - sage.rings.finite_rings + sage: one = K.one() + sage: normalize_hughes_plane_point((2*x, one, zero), 9) (2*x, 1, 0) """ for i in [2,1,0]: @@ -526,7 +528,7 @@ def HughesPlane(q2, check=True): EXAMPLES:: - sage: H = designs.HughesPlane(9); H # optional - sage.rings.finite_rings + sage: H = designs.HughesPlane(9); H (91,10,1)-Balanced Incomplete Block Design We prove in the following computations that the Desarguesian plane ``H`` is @@ -535,45 +537,45 @@ def HughesPlane(q2, check=True): `D_{1,10} \cap D_{70,59}` and `D_{10,0} \cap D_{59,57}` are on the same line while `D_{0,70}`, `D_{1,59}` and `D_{10,57}` are not concurrent:: - sage: blocks = H.blocks() # optional - sage.rings.finite_rings - sage: line = lambda p,q: next(b for b in blocks if p in b and q in b) # optional - sage.rings.finite_rings + sage: blocks = H.blocks() + sage: line = lambda p,q: next(b for b in blocks if p in b and q in b) - sage: b_0_1 = line(0, 1) # optional - sage.rings.finite_rings - sage: b_1_10 = line(1, 10) # optional - sage.rings.finite_rings - sage: b_10_0 = line(10, 0) # optional - sage.rings.finite_rings - sage: b_57_70 = line(57, 70) # optional - sage.rings.finite_rings - sage: b_70_59 = line(70, 59) # optional - sage.rings.finite_rings - sage: b_59_57 = line(59, 57) # optional - sage.rings.finite_rings + sage: b_0_1 = line(0, 1) + sage: b_1_10 = line(1, 10) + sage: b_10_0 = line(10, 0) + sage: b_57_70 = line(57, 70) + sage: b_70_59 = line(70, 59) + sage: b_59_57 = line(59, 57) - sage: set(b_0_1).intersection(b_57_70) # optional - sage.rings.finite_rings + sage: set(b_0_1).intersection(b_57_70) {2} - sage: set(b_1_10).intersection(b_70_59) # optional - sage.rings.finite_rings + sage: set(b_1_10).intersection(b_70_59) {73} - sage: set(b_10_0).intersection(b_59_57) # optional - sage.rings.finite_rings + sage: set(b_10_0).intersection(b_59_57) {60} - sage: line(2, 73) == line(73, 60) # optional - sage.rings.finite_rings + sage: line(2, 73) == line(73, 60) True - sage: b_0_57 = line(0, 57) # optional - sage.rings.finite_rings - sage: b_1_70 = line(1, 70) # optional - sage.rings.finite_rings - sage: b_10_59 = line(10, 59) # optional - sage.rings.finite_rings + sage: b_0_57 = line(0, 57) + sage: b_1_70 = line(1, 70) + sage: b_10_59 = line(10, 59) - sage: p = set(b_0_57).intersection(b_1_70) # optional - sage.rings.finite_rings - sage: q = set(b_1_70).intersection(b_10_59) # optional - sage.rings.finite_rings - sage: p == q # optional - sage.rings.finite_rings + sage: p = set(b_0_57).intersection(b_1_70) + sage: q = set(b_1_70).intersection(b_10_59) + sage: p == q False TESTS: Some wrong input:: - sage: designs.HughesPlane(5) # optional - sage.rings.finite_rings + sage: designs.HughesPlane(5) Traceback (most recent call last): ... EmptySetError: No Hughes plane of non-square order exists. - sage: designs.HughesPlane(16) # optional - sage.rings.finite_rings + sage: designs.HughesPlane(16) Traceback (most recent call last): ... EmptySetError: No Hughes plane of even order exists. @@ -631,9 +633,9 @@ def projective_plane_to_OA(pplane, pt=None, check=True): INPUT: - - ``pplane`` - a projective plane as a 2-design + - ``pplane`` -- a projective plane as a 2-design - - ``pt`` - a point in the projective plane ``pplane``. If it is not provided + - ``pt`` -- a point in the projective plane ``pplane``. If it is not provided, then it is set to `n^2 + n`. - ``check`` -- (boolean) Whether to check that output is correct before @@ -644,13 +646,11 @@ def projective_plane_to_OA(pplane, pt=None, check=True): EXAMPLES:: sage: from sage.combinat.designs.block_design import projective_plane_to_OA - sage: p2 = designs.DesarguesianProjectivePlaneDesign(2, # optional - sage.rings.finite_rings - ....: point_coordinates=False) - sage: projective_plane_to_OA(p2) # optional - sage.rings.finite_rings + sage: p2 = designs.DesarguesianProjectivePlaneDesign(2, point_coordinates=False) + sage: projective_plane_to_OA(p2) [[0, 0, 0], [0, 1, 1], [1, 0, 1], [1, 1, 0]] - sage: p3 = designs.DesarguesianProjectivePlaneDesign(3, # optional - sage.rings.finite_rings - ....: point_coordinates=False) - sage: projective_plane_to_OA(p3) # optional - sage.rings.finite_rings + sage: p3 = designs.DesarguesianProjectivePlaneDesign(3, point_coordinates=False) + sage: projective_plane_to_OA(p3) [[0, 0, 0, 0], [0, 1, 2, 1], [0, 2, 1, 2], @@ -661,11 +661,10 @@ def projective_plane_to_OA(pplane, pt=None, check=True): [2, 1, 0, 2], [2, 2, 2, 0]] - sage: pp = designs.DesarguesianProjectivePlaneDesign(16, # optional - sage.rings.finite_rings - ....: point_coordinates=False) - sage: _ = projective_plane_to_OA(pp, pt=0) # optional - sage.rings.finite_rings - sage: _ = projective_plane_to_OA(pp, pt=3) # optional - sage.rings.finite_rings - sage: _ = projective_plane_to_OA(pp, pt=7) # optional - sage.rings.finite_rings + sage: pp = designs.DesarguesianProjectivePlaneDesign(16, point_coordinates=False) + sage: _ = projective_plane_to_OA(pp, pt=0) + sage: _ = projective_plane_to_OA(pp, pt=3) + sage: _ = projective_plane_to_OA(pp, pt=7) """ from .bibd import _relabel_bibd pplane = pplane.blocks() @@ -697,9 +696,9 @@ def projective_plane(n, check=True, existence=False): `n^2+n+1` points. For more information on finite projective planes, see the :wikipedia:`Projective_plane#Finite_projective_planes`. - If no construction is possible, then the function raises a ``EmptySetError`` - whereas if no construction is available the function raises a - ``NotImplementedError``. + If no construction is possible, then the function raises a :class:`EmptySetError`, + whereas if no construction is available, the function raises a + :class:`NotImplementedError`. INPUT: @@ -722,11 +721,14 @@ def projective_plane(n, check=True, existence=False): sage: designs.projective_plane(10) Traceback (most recent call last): ... - EmptySetError: No projective plane of order 10 exists by C. Lam, L. Thiel and S. Swiercz "The nonexistence of finite projective planes of order 10" (1989), Canad. J. Math. + EmptySetError: No projective plane of order 10 exists by + C. Lam, L. Thiel and S. Swiercz "The nonexistence of finite + projective planes of order 10" (1989), Canad. J. Math. sage: designs.projective_plane(12) Traceback (most recent call last): ... - NotImplementedError: If such a projective plane exists, we do not know how to build it. + NotImplementedError: If such a projective plane exists, + we do not know how to build it. sage: designs.projective_plane(14) Traceback (most recent call last): ... @@ -813,28 +815,28 @@ def AffineGeometryDesign(n, d, F, point_coordinates=True, check=True): EXAMPLES:: - sage: BD = designs.AffineGeometryDesign(3, 1, GF(2)) # optional - sage.rings.finite_rings - sage: BD.is_t_design(return_parameters=True) # optional - sage.rings.finite_rings + sage: BD = designs.AffineGeometryDesign(3, 1, GF(2)) + sage: BD.is_t_design(return_parameters=True) (True, (2, 8, 2, 1)) - sage: BD = designs.AffineGeometryDesign(3, 2, GF(4)) # optional - sage.rings.finite_rings - sage: BD.is_t_design(return_parameters=True) # optional - sage.rings.finite_rings + sage: BD = designs.AffineGeometryDesign(3, 2, GF(4)) + sage: BD.is_t_design(return_parameters=True) (True, (2, 64, 16, 5)) - sage: BD = designs.AffineGeometryDesign(4, 2, GF(3)) # optional - sage.rings.finite_rings - sage: BD.is_t_design(return_parameters=True) # optional - sage.rings.finite_rings + sage: BD = designs.AffineGeometryDesign(4, 2, GF(3)) + sage: BD.is_t_design(return_parameters=True) (True, (2, 81, 9, 13)) With ``F`` an integer instead of a finite field:: - sage: BD = designs.AffineGeometryDesign(3, 2, 4) # optional - sage.rings.finite_rings - sage: BD.is_t_design(return_parameters=True) # optional - sage.rings.finite_rings + sage: BD = designs.AffineGeometryDesign(3, 2, 4) + sage: BD.is_t_design(return_parameters=True) (True, (2, 64, 16, 5)) Testing the option ``point_coordinates``:: - sage: designs.AffineGeometryDesign(3, 1, GF(2), # optional - sage.rings.finite_rings + sage: designs.AffineGeometryDesign(3, 1, GF(2), ....: point_coordinates=True).blocks()[0] [(0, 0, 0), (0, 0, 1)] - sage: designs.AffineGeometryDesign(3, 1, GF(2), # optional - sage.rings.finite_rings + sage: designs.AffineGeometryDesign(3, 1, GF(2), ....: point_coordinates=False).blocks()[0] [0, 1] """ @@ -886,7 +888,7 @@ def AffineGeometryDesign(n, d, F, point_coordinates=True, check=True): def CremonaRichmondConfiguration(): r""" - Return the Cremona-Richmond configuration + Return the Cremona-Richmond configuration. The Cremona-Richmond configuration is a set system whose incidence graph is equal to the @@ -954,16 +956,16 @@ def HadamardDesign(n): EXAMPLES:: - sage: designs.HadamardDesign(7) + sage: designs.HadamardDesign(7) # optional - sage.modules Incidence structure with 7 points and 7 blocks - sage: print(designs.HadamardDesign(7)) + sage: print(designs.HadamardDesign(7)) # optional - sage.modules Incidence structure with 7 points and 7 blocks - For example, the Hadamard 2-design with `n = 11` is a design whose parameters are 2-(11, 5, 2). + For example, the Hadamard 2-design with `n = 11` is a design whose parameters are `2-(11, 5, 2)`. We verify that `NJ = 5J` for this design. :: - sage: D = designs.HadamardDesign(11); N = D.incidence_matrix() - sage: J = matrix(ZZ, 11, 11, [1]*11*11); N*J + sage: D = designs.HadamardDesign(11); N = D.incidence_matrix() # optional - sage.modules + sage: J = matrix(ZZ, 11, 11, [1]*11*11); N*J # optional - sage.modules [5 5 5 5 5 5 5 5 5 5 5] [5 5 5 5 5 5 5 5 5 5 5] [5 5 5 5 5 5 5 5 5 5 5] @@ -1007,7 +1009,7 @@ def Hadamard3Design(n): EXAMPLES:: - sage: designs.Hadamard3Design(12) + sage: designs.Hadamard3Design(12) # optional - sage.modules Incidence structure with 12 points and 22 blocks We verify that any two blocks of the Hadamard `3`-design `3-(8, 4, 1)` @@ -1017,9 +1019,9 @@ def Hadamard3Design(n): :: - sage: D = designs.Hadamard3Design(8) - sage: N = D.incidence_matrix() - sage: N.transpose()*N + sage: D = designs.Hadamard3Design(8) # optional - sage.modules + sage: N = D.incidence_matrix() # optional - sage.modules + sage: N.transpose()*N # optional - sage.modules [4 2 2 2 2 2 2 2 2 2 2 2 2 0] [2 4 2 2 2 2 2 2 2 2 2 2 0 2] [2 2 4 2 2 2 2 2 2 2 2 0 2 2] From e5fd4e13a18ad36d367170acf861d38fbb2c066c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sat, 10 Jun 2023 10:37:01 -0700 Subject: [PATCH 077/228] Fix typo of # optional - sage.modules --- src/sage/categories/magmas.py | 22 +++++++++++----------- src/sage/combinat/designs/designs_pyx.pyx | 22 +++++++++++----------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/sage/categories/magmas.py b/src/sage/categories/magmas.py index e80088548a9..178361b2961 100644 --- a/src/sage/categories/magmas.py +++ b/src/sage/categories/magmas.py @@ -902,10 +902,10 @@ def multiplication_table(self, names='letters', elements=None): sage: from sage.categories.examples.finite_semigroups import LeftRegularBand sage: L = LeftRegularBand(('a', 'b')) - sage: T = L.multiplication_table(names='digits') # optional - sage.matrix - sage: T.column_keys() # optional - sage.matrix + sage: T = L.multiplication_table(names='digits') # optional - sage.modules + sage: T.column_keys() # optional - sage.modules ('a', 'ab', 'b', 'ba') - sage: T # optional - sage.matrix + sage: T # optional - sage.modules * 0 1 2 3 +-------- 0| 0 1 1 1 @@ -918,7 +918,7 @@ def multiplication_table(self, names='letters', elements=None): sage: L = LeftRegularBand(('a', 'b', 'c')) sage: elts = sorted(L.list()) - sage: L.multiplication_table(elements=elts) # optional - sage.matrix + sage: L.multiplication_table(elements=elts) # optional - sage.modules * a b c d e f g h i j k l m n o +------------------------------ a| a b c d e b b c c c d d e e e @@ -947,7 +947,7 @@ def multiplication_table(self, names='letters', elements=None): sage: L = LeftRegularBand(('a','b','c')) sage: elts=['a', 'c', 'ac', 'ca'] - sage: L.multiplication_table(names='elements', elements=elts) # optional - sage.matrix + sage: L.multiplication_table(names='elements', elements=elts) # optional - sage.modules * 'a' 'c' 'ac' 'ca' +-------------------- 'a'| 'a' 'ac' 'ac' 'ac' @@ -961,15 +961,15 @@ def multiplication_table(self, names='letters', elements=None): comprehensive documentation. :: sage: G = AlternatingGroup(3) # optional - sage.groups - sage: T = G.multiplication_table() # optional - sage.groups sage.matrix - sage: T.column_keys() # optional - sage.groups sage.matrix + sage: T = G.multiplication_table() # optional - sage.groups sage.modules + sage: T.column_keys() # optional - sage.groups sage.modules ((), (1,2,3), (1,3,2)) - sage: T.translation() # optional - sage.groups sage.matrix + sage: T.translation() # optional - sage.groups sage.modules {'a': (), 'b': (1,2,3), 'c': (1,3,2)} - sage: T.change_names(['x', 'y', 'z']) # optional - sage.groups sage.matrix - sage: T.translation() # optional - sage.groups sage.matrix + sage: T.change_names(['x', 'y', 'z']) # optional - sage.groups sage.modules + sage: T.translation() # optional - sage.groups sage.modules {'x': (), 'y': (1,2,3), 'z': (1,3,2)} - sage: T # optional - sage.groups sage.matrix + sage: T # optional - sage.groups sage.modules * x y z +------ x| x y z diff --git a/src/sage/combinat/designs/designs_pyx.pyx b/src/sage/combinat/designs/designs_pyx.pyx index 55cfbca19b1..be8745f2acb 100644 --- a/src/sage/combinat/designs/designs_pyx.pyx +++ b/src/sage/combinat/designs/designs_pyx.pyx @@ -183,16 +183,16 @@ def is_group_divisible_design(groups,blocks,v,G=None,K=None,lambd=1,verbose=Fals EXAMPLES:: sage: from sage.combinat.designs.designs_pyx import is_group_divisible_design - sage: TD = designs.transversal_design(4,10) # optional - sage.matrix - sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] # optional - sage.matrix - sage: is_group_divisible_design(groups,TD,40,lambd=1) # optional - sage.matrix + sage: TD = designs.transversal_design(4,10) # optional - sage.modules + sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] # optional - sage.modules + sage: is_group_divisible_design(groups,TD,40,lambd=1) # optional - sage.modules True TESTS:: - sage: TD = designs.transversal_design(4,10) # optional - sage.matrix - sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] # optional - sage.matrix - sage: is_group_divisible_design(groups, TD, 40, lambd=2, verbose=True) # optional - sage.matrix + sage: TD = designs.transversal_design(4,10) # optional - sage.modules + sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] # optional - sage.modules + sage: is_group_divisible_design(groups, TD, 40, lambd=2, verbose=True) # optional - sage.modules the pair (0,10) has been seen 1 times but lambda=2 False sage: is_group_divisible_design([[1,2],[3,4]],[[1,2]],40,lambd=1,verbose=True) @@ -362,18 +362,18 @@ def is_pairwise_balanced_design(blocks,v,K=None,lambd=1,verbose=False): sage: sts = designs.steiner_triple_system(9) sage: is_pairwise_balanced_design(sts,9,[3],1) True - sage: TD = designs.transversal_design(4,10).blocks() # optional - sage.matrix - sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] # optional - sage.matrix - sage: is_pairwise_balanced_design(TD + groups, 40, [4,10], 1, verbose=True) # optional - sage.matrix + sage: TD = designs.transversal_design(4,10).blocks() # optional - sage.modules + sage: groups = [list(range(i*10,(i+1)*10)) for i in range(4)] # optional - sage.modules + sage: is_pairwise_balanced_design(TD + groups, 40, [4,10], 1, verbose=True) # optional - sage.modules True TESTS:: sage: from sage.combinat.designs.designs_pyx import is_pairwise_balanced_design - sage: is_pairwise_balanced_design(TD + groups, 40, [4,10], 2, verbose=True) # optional - sage.matrix + sage: is_pairwise_balanced_design(TD + groups, 40, [4,10], 2, verbose=True) # optional - sage.modules the pair (0,1) has been seen 1 times but lambda=2 False - sage: is_pairwise_balanced_design(TD + groups, 40, [10], 1, verbose=True) # optional - sage.matrix + sage: is_pairwise_balanced_design(TD + groups, 40, [10], 1, verbose=True) # optional - sage.modules a block has size 4 while K=[10] False sage: is_pairwise_balanced_design([[2,2]],40,[2],1,verbose=True) From 911653654264f314b810297a7eeefa30f2927706 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian <aram.dermenjian.o+github@gmail.com> Date: Sun, 11 Jun 2023 09:01:16 +0100 Subject: [PATCH 078/228] Update src/sage/combinat/output.py Co-authored-by: Travis Scrimshaw <clfrngrown@aol.com> --- src/sage/combinat/output.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/output.py b/src/sage/combinat/output.py index 7ad0cd018ae..6e9d2943cfd 100644 --- a/src/sage/combinat/output.py +++ b/src/sage/combinat/output.py @@ -767,7 +767,7 @@ def get_len(e): def box_exists(tab, i, j): - r """ + r""" Return ``True`` if ``tab[i][j]`` exists and is not ``None``; in particular this allows for `tab[i][j]` to be ``''`` or ``0``. From 7752c5877cc9b8d3b2e058b07ca978947eaa3230 Mon Sep 17 00:00:00 2001 From: Antonio Rojas <arojas@archlinux.org> Date: Mon, 12 Jun 2023 17:03:07 +0200 Subject: [PATCH 079/228] Drop redundant test --- src/sage/functions/bessel.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/sage/functions/bessel.py b/src/sage/functions/bessel.py index 2dacd014e6f..48607c49f56 100644 --- a/src/sage/functions/bessel.py +++ b/src/sage/functions/bessel.py @@ -293,9 +293,6 @@ class Function_Bessel_J(BuiltinFunction): sage: f = bessel_J(2, x) sage: f.integrate(x) 1/24*x^3*hypergeometric((3/2,), (5/2, 3), -1/4*x^2) - sage: m = maxima(bessel_J(2, x)) - sage: m.integrate(x).sage() - 1/24*x^3*hypergeometric((3/2,), (5/2, 3), -1/4*x^2) Visualization (set plot_points to a higher value to get more detail):: From 4642fea94cf3cdf6feeaf6b031454e9e5148fea0 Mon Sep 17 00:00:00 2001 From: Antonio Rojas <arojas@archlinux.org> Date: Mon, 12 Jun 2023 17:15:11 +0200 Subject: [PATCH 080/228] Don't use maxima to compute the Laplace transform in the tutorial --- src/doc/de/tutorial/tour_algebra.rst | 7 +++++-- src/doc/en/tutorial/tour_algebra.rst | 7 +++++-- src/doc/es/tutorial/tour_algebra.rst | 9 ++++++--- src/doc/fr/tutorial/tour_algebra.rst | 9 ++++++--- src/doc/it/tutorial/tour_algebra.rst | 9 ++++++--- src/doc/ja/tutorial/tour_algebra.rst | 9 ++++++--- src/doc/pt/tutorial/tour_algebra.rst | 9 ++++++--- src/doc/ru/tutorial/tour_algebra.rst | 9 ++++++--- 8 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/doc/de/tutorial/tour_algebra.rst b/src/doc/de/tutorial/tour_algebra.rst index 60e05332eaa..59eed8f1888 100644 --- a/src/doc/de/tutorial/tour_algebra.rst +++ b/src/doc/de/tutorial/tour_algebra.rst @@ -209,8 +209,11 @@ Lösung: Berechnen Sie die Laplace-Transformierte der ersten Gleichung :: - sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") - sage: lde1 = de1.laplace("t","s"); lde1.sage() + sage: t,s = SR.var('t,s') + sage: x = function('x') + sage: y = function('y') + sage: f = 2*x(t).diff(t,2) + 6*x(t) - 2*y(t) + sage: f.laplace(t,s) 2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0) Das ist schwierig zu lesen, es besagt jedoch, dass diff --git a/src/doc/en/tutorial/tour_algebra.rst b/src/doc/en/tutorial/tour_algebra.rst index 3a9830f16d5..225606a729f 100644 --- a/src/doc/en/tutorial/tour_algebra.rst +++ b/src/doc/en/tutorial/tour_algebra.rst @@ -216,8 +216,11 @@ the notation :math:`x=x_{1}`, :math:`y=x_{2}`): :: - sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)") - sage: lde1 = de1.laplace("t","s"); lde1.sage() + sage: t,s = SR.var('t,s') + sage: x = function('x') + sage: y = function('y') + sage: f = 2*x(t).diff(t,2) + 6*x(t) - 2*y(t) + sage: f.laplace(t,s) 2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0) This is hard to read, but it says that diff --git a/src/doc/es/tutorial/tour_algebra.rst b/src/doc/es/tutorial/tour_algebra.rst index c57e6775a49..42c818fe8d7 100644 --- a/src/doc/es/tutorial/tour_algebra.rst +++ b/src/doc/es/tutorial/tour_algebra.rst @@ -211,9 +211,12 @@ Toma la transformada de Laplace de la segunda ecuación: :: - sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") - sage: lde2 = de2.laplace("t","s"); lde2.sage() - s^2*laplace(y(t), t, s) - s*y(0) - 2*laplace(x(t), t, s) + 2*laplace(y(t), t, s) - D[0](y)(0) + sage: t,s = SR.var('t,s') + sage: x = function('x') + sage: y = function('y') + sage: f = 2*x(t).diff(t,2) + 6*x(t) - 2*y(t) + sage: f.laplace(t,s) + 2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0) Esto dice diff --git a/src/doc/fr/tutorial/tour_algebra.rst b/src/doc/fr/tutorial/tour_algebra.rst index be534cd556b..267bd1dd4f9 100644 --- a/src/doc/fr/tutorial/tour_algebra.rst +++ b/src/doc/fr/tutorial/tour_algebra.rst @@ -196,9 +196,12 @@ la seconde équation : :: - sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") - sage: lde2 = de2.laplace("t","s"); lde2.sage() - s^2*laplace(y(t), t, s) - s*y(0) - 2*laplace(x(t), t, s) + 2*laplace(y(t), t, s) - D[0](y)(0) + sage: t,s = SR.var('t,s') + sage: x = function('x') + sage: y = function('y') + sage: f = 2*x(t).diff(t,2) + 6*x(t) - 2*y(t) + sage: f.laplace(t,s) + 2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0) Ceci signifie diff --git a/src/doc/it/tutorial/tour_algebra.rst b/src/doc/it/tutorial/tour_algebra.rst index 5a153e6fb75..cde427d3090 100644 --- a/src/doc/it/tutorial/tour_algebra.rst +++ b/src/doc/it/tutorial/tour_algebra.rst @@ -197,9 +197,12 @@ trasformata di Laplace della seconda equazione: :: - sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") - sage: lde2 = de2.laplace("t","s"); lde2.sage() - s^2*laplace(y(t), t, s) - s*y(0) - 2*laplace(x(t), t, s) + 2*laplace(y(t), t, s) - D[0](y)(0) + sage: t,s = SR.var('t,s') + sage: x = function('x') + sage: y = function('y') + sage: f = 2*x(t).diff(t,2) + 6*x(t) - 2*y(t) + sage: f.laplace(t,s) + 2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0) che significa diff --git a/src/doc/ja/tutorial/tour_algebra.rst b/src/doc/ja/tutorial/tour_algebra.rst index 64edd47b930..746cbb4475c 100644 --- a/src/doc/ja/tutorial/tour_algebra.rst +++ b/src/doc/ja/tutorial/tour_algebra.rst @@ -226,9 +226,12 @@ Sageを使って常微分方程式を研究することもできる. :math:`x' :: - sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") - sage: lde2 = de2.laplace("t","s"); lde2.sage() - s^2*laplace(y(t), t, s) - s*y(0) - 2*laplace(x(t), t, s) + 2*laplace(y(t), t, s) - D[0](y)(0) + sage: t,s = SR.var('t,s') + sage: x = function('x') + sage: y = function('y') + sage: f = 2*x(t).diff(t,2) + 6*x(t) - 2*y(t) + sage: f.laplace(t,s) + 2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0) 意味するところは diff --git a/src/doc/pt/tutorial/tour_algebra.rst b/src/doc/pt/tutorial/tour_algebra.rst index b3cbd06d8d9..170e0d8a367 100644 --- a/src/doc/pt/tutorial/tour_algebra.rst +++ b/src/doc/pt/tutorial/tour_algebra.rst @@ -219,9 +219,12 @@ calcule a transformada de Laplace da segunda equação: :: - sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") - sage: lde2 = de2.laplace("t","s"); lde2.sage() - s^2*laplace(y(t), t, s) - s*y(0) - 2*laplace(x(t), t, s) + 2*laplace(y(t), t, s) - D[0](y)(0) + sage: t,s = SR.var('t,s') + sage: x = function('x') + sage: y = function('y') + sage: f = 2*x(t).diff(t,2) + 6*x(t) - 2*y(t) + sage: f.laplace(t,s) + 2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0) O resultado significa que diff --git a/src/doc/ru/tutorial/tour_algebra.rst b/src/doc/ru/tutorial/tour_algebra.rst index 107571f6018..bc0d4926f83 100644 --- a/src/doc/ru/tutorial/tour_algebra.rst +++ b/src/doc/ru/tutorial/tour_algebra.rst @@ -210,9 +210,12 @@ Sage может использоваться для решения диффер :: - sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)") - sage: lde2 = de2.laplace("t","s"); lde2.sage() - s^2*laplace(y(t), t, s) - s*y(0) - 2*laplace(x(t), t, s) + 2*laplace(y(t), t, s) - D[0](y)(0) + sage: t,s = SR.var('t,s') + sage: x = function('x') + sage: y = function('y') + sage: f = 2*x(t).diff(t,2) + 6*x(t) - 2*y(t) + sage: f.laplace(t,s) + 2*s^2*laplace(x(t), t, s) - 2*s*x(0) + 6*laplace(x(t), t, s) - 2*laplace(y(t), t, s) - 2*D[0](x)(0) Результат: From 55c7762ead608af9fca6ceb03b7003a046c85e26 Mon Sep 17 00:00:00 2001 From: Sebastian <seb.oehms@gmail.com> Date: Mon, 12 Jun 2023 18:40:19 +0200 Subject: [PATCH 081/228] fix_snappy_doctests_after_35665 initial --- src/sage/knots/knotinfo.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index 19e2589af9d..a6a84a11f00 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -107,7 +107,7 @@ sage: type(l6s) # optional - snappy <class 'spherogram.links.invariants.Link'> - sage: l6 = L6.link().mirror_image() + sage: l6 = L6.link() sage: l6 == l6s.sage_link() # optional - snappy True sage: L6.link(L6.items.name, snappy=True) # optional - snappy @@ -115,7 +115,8 @@ sage: l6sn = _ # optional - snappy sage: l6s == l6sn # optional - snappy False - sage: l6sn.sage_link().is_isotopic(l6) # optional - snappy + sage: l6m = l6.mirror_image() # optional - snappy + sage: l6sn.sage_link().is_isotopic(l6m) # optional - snappy True But observe that the name conversion to SnapPy does not distinguish orientation @@ -1853,25 +1854,24 @@ def link(self, use_item=db.columns().pd_notation, snappy=False): using ``snappy``:: - sage: K7 = KnotInfo.K7_2 - sage: k7s = K7.link(snappy=True); k7s # optional - snappy - <Link: 1 comp; 7 cross> - sage: K7.link(K7.items.name, snappy=True) # optional - snappy - <Link 7_2: 1 comp; 7 cross> - sage: k7sn = _ # optional - snappy - sage: k7s == k7sn # optional - snappy - False - sage: k7s.sage_link().is_isotopic(k7sn.sage_link()) # optional - snappy - True - - but observe:: - sage: L2 = KnotInfo.L2a1_1 sage: l2 = L2.link() sage: l2s = L2.link(snappy=True).sage_link() # optional - snappy sage: l2 == l2s # optional - snappy + True + + but observe:: + + sage: K7 = KnotInfo.K7_2 + sage: k7s = K7.link(snappy=True); k7s # optional - snappy + <Link: 1 comp; 7 cross> + sage: K7.link(K7.items.name, snappy=True) # optional - snappy + <Link 7_2: 1 comp; 7 cross> + sage: k7sn = _ # optional - snappy + sage: k7s.sage_link().is_isotopic(k7sn) # optional - snappy False - sage: l2 == l2s.mirror_image() # optional - snappy + sage: k7snm = k7sn.sage_link().mirror_image() # optional - snappy + sage: k7s.sage_link().is_isotopic(k7snm) # optional - snappy True using ``braid_notation``:: From b54a5c58932b1491a49f8121e678e2d86079a441 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Wed, 14 Jun 2023 18:15:05 -0700 Subject: [PATCH 082/228] src/sage/ext/fast_callable.pyx: Fall back to more general interpreter on ImportError --- src/sage/ext/fast_callable.pyx | 93 ++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 31 deletions(-) diff --git a/src/sage/ext/fast_callable.pyx b/src/sage/ext/fast_callable.pyx index d21bddd5deb..f45e8b31930 100644 --- a/src/sage/ext/fast_callable.pyx +++ b/src/sage/ext/fast_callable.pyx @@ -465,41 +465,72 @@ def fast_callable(x, domain=None, vars=None, etb = ExpressionTreeBuilder(vars=vars, domain=domain) et = x._fast_callable_(etb) - if isinstance(domain, sage.rings.abc.RealField): - from sage.ext.interpreters.wrapper_rr import Wrapper_rr as builder - str = InstructionStream(sage.ext.interpreters.wrapper_rr.metadata, - len(vars), - domain) - - elif isinstance(domain, sage.rings.abc.ComplexField): - from sage.ext.interpreters.wrapper_cc import Wrapper_cc as builder - str = InstructionStream(sage.ext.interpreters.wrapper_cc.metadata, - len(vars), - domain) - - elif isinstance(domain, sage.rings.abc.RealDoubleField) or domain is float: - from sage.ext.interpreters.wrapper_rdf import Wrapper_rdf as builder - str = InstructionStream(sage.ext.interpreters.wrapper_rdf.metadata, - len(vars), - domain) - elif isinstance(domain, sage.rings.abc.ComplexDoubleField): - from sage.ext.interpreters.wrapper_cdf import Wrapper_cdf as builder - str = InstructionStream(sage.ext.interpreters.wrapper_cdf.metadata, - len(vars), - domain) - elif domain is None: - from sage.ext.interpreters.wrapper_py import Wrapper_py as builder - str = InstructionStream(sage.ext.interpreters.wrapper_py.metadata, - len(vars)) - else: - from sage.ext.interpreters.wrapper_el import Wrapper_el as builder - str = InstructionStream(sage.ext.interpreters.wrapper_el.metadata, - len(vars), - domain) + builder, str = _builder_and_stream(vars=vars, domain=domain) + generate_code(et, str) str.instr('return') return builder(str.get_current()) + +def _builder_and_stream(vars, domain): + r""" + Return a builder and a stream. + + INPUT: + + - ``vars`` -- a sequence of variable names + + - ``domain`` -- a Sage parent or Python type or ``None``; if non-``None``, + all arithmetic is done in that domain + + OUTPUT: A :class:`Wrapper`, an class:`InstructionStream` + + EXAMPLES: + + sage: from sage.ext.fast_callable import _builder_and_stream + sage: _builder_and_stream(ZZ, ["x", "y"]) + + """ + if isinstance(domain, sage.rings.abc.RealField): + try: + from sage.ext.interpreters.wrapper_rr import metadata, Wrapper_rr as builder + except ImportError: + pass + else: + return builder, InstructionStream(metadata, len(vars), domain) + + if isinstance(domain, sage.rings.abc.ComplexField): + try: + from sage.ext.interpreters.wrapper_cc import metadata, Wrapper_cc as builder + except ImportError: + pass + else: + return builder, InstructionStream(metadata, len(vars), domain) + + if isinstance(domain, sage.rings.abc.RealDoubleField) or domain is float: + try: + from sage.ext.interpreters.wrapper_rdf import metadata, Wrapper_rdf as builder + except ImportError: + pass + else: + return builder, InstructionStream(metadata, len(vars), domain) + + if isinstance(domain, sage.rings.abc.ComplexDoubleField): + try: + from sage.ext.interpreters.wrapper_cdf import metadata, Wrapper_cdf as builder + except ImportError: + pass + else: + return builder, InstructionStream(metadata, len(vars), domain) + + if domain is None: + from sage.ext.interpreters.wrapper_py import metadata, Wrapper_py as builder + return builder, InstructionStream(metadata, len(vars)) + + from sage.ext.interpreters.wrapper_el import metadata, Wrapper_el as builder + return builder, InstructionStream(metadata, len(vars), domain) + + def function_name(fn): r""" Given a function, return a string giving a name for the function. From c5033e728d77767ce18f2f30731ee493e99b93b5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Wed, 14 Jun 2023 18:15:49 -0700 Subject: [PATCH 083/228] src/sage_setup/autogen/interpreters/__init__.py: Support building a subset of interpreters --- .../autogen/interpreters/__init__.py | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/sage_setup/autogen/interpreters/__init__.py b/src/sage_setup/autogen/interpreters/__init__.py index c3534aeccf9..39f44169ed3 100644 --- a/src/sage_setup/autogen/interpreters/__init__.py +++ b/src/sage_setup/autogen/interpreters/__init__.py @@ -119,25 +119,10 @@ from .instructions import * from .memory import * from .specs.base import * -from .specs.cdf import * -from .specs.element import * -from .specs.python import * -from .specs.rdf import * -from .specs.rr import * -from .specs.cc import * from .storage import * from .utils import * -# Gather up a list of all interpreter classes imported into this module -# A better way might be to recursively iterate InterpreterSpec.__subclasses__ -# or to use a registry, but this is fine for now. -_INTERPRETERS = sorted(filter(lambda c: (isinstance(c, type) and - issubclass(c, InterpreterSpec) and - c.name), - globals().values()), - key=lambda c: c.name) - # Tuple of (filename_root, extension, method) where filename_root is the # root of the filename to be joined with "_<interpreter_name>".ext and # method is the name of a get_ method on InterpreterGenerator that returns @@ -174,7 +159,7 @@ def build_interp(interp_spec, dir): write_if_changed(path, method()) -def rebuild(dirname, force=False): +def rebuild(dirname, force=False, interpreters=None, distribution=None): r""" Check whether the interpreter and wrapper sources have been written since the last time this module was changed. If not, write them. @@ -194,6 +179,20 @@ def rebuild(dirname, force=False): # you run it). print("Building interpreters for fast_callable") + if interpreters is None: + interpreters = ['CDF', 'Element', 'Python', 'RDF', 'RR', 'CC'] + + from importlib import import_module + + _INTERPRETERS = [getattr(import_module('sage_setup.autogen.interpreters.specs.' + interpreter.lower()), + interpreter + 'Interpreter') + for interpreter in interpreters] + + if distribution is None: + all_py = 'all.py' + else: + all_py = f'all__{distribution.replace("-", "_")}.py' + try: os.makedirs(dirname) except OSError: @@ -213,7 +212,7 @@ class NeedToRebuild(Exception): try: if force: raise NeedToRebuild("-> Force rebuilding interpreters") - gen_file = os.path.join(dirname, 'all.py') + gen_file = os.path.join(dirname, all_py) if not os.path.isfile(gen_file): raise NeedToRebuild("-> First build of interpreters") @@ -235,5 +234,5 @@ class NeedToRebuild(Exception): for interp in _INTERPRETERS: build_interp(interp(), dirname) - with open(os.path.join(dirname, 'all.py'), 'w') as f: + with open(os.path.join(dirname, all_py), 'w') as f: f.write("# " + AUTOGEN_WARN) From 814e264b54f2898711782df6b222e7177d5c54c4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Wed, 14 Jun 2023 22:28:09 -0700 Subject: [PATCH 084/228] sage_setup.autogen.interpreters: Update imports in doctests --- src/sage_setup/autogen/interpreters/__init__.py | 1 + src/sage_setup/autogen/interpreters/generator.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/sage_setup/autogen/interpreters/__init__.py b/src/sage_setup/autogen/interpreters/__init__.py index 39f44169ed3..20153a3dd19 100644 --- a/src/sage_setup/autogen/interpreters/__init__.py +++ b/src/sage_setup/autogen/interpreters/__init__.py @@ -142,6 +142,7 @@ def build_interp(interp_spec, dir): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter sage: testdir = tmp_dir() sage: rdf_interp = RDFInterpreter() sage: build_interp(rdf_interp, testdir) diff --git a/src/sage_setup/autogen/interpreters/generator.py b/src/sage_setup/autogen/interpreters/generator.py index f090f201afd..bec7cae2b47 100644 --- a/src/sage_setup/autogen/interpreters/generator.py +++ b/src/sage_setup/autogen/interpreters/generator.py @@ -43,6 +43,7 @@ def __init__(self, spec): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter sage: interp = RDFInterpreter() sage: gen = InterpreterGenerator(interp) sage: gen._spec is interp @@ -72,6 +73,7 @@ def gen_code(self, instr_desc, write): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter sage: interp = RDFInterpreter() sage: gen = InterpreterGenerator(interp) sage: from io import StringIO @@ -218,6 +220,7 @@ def func_header(self, cython=False): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.element import ElementInterpreter sage: interp = ElementInterpreter() sage: gen = InterpreterGenerator(interp) sage: print(gen.func_header()) @@ -260,6 +263,7 @@ def write_interpreter(self, write): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter sage: interp = RDFInterpreter() sage: gen = InterpreterGenerator(interp) sage: from io import StringIO @@ -307,6 +311,7 @@ def write_wrapper(self, write): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter sage: interp = RDFInterpreter() sage: gen = InterpreterGenerator(interp) sage: from io import StringIO @@ -476,6 +481,7 @@ def write_pxd(self, write): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter sage: interp = RDFInterpreter() sage: gen = InterpreterGenerator(interp) sage: from io import StringIO @@ -527,6 +533,9 @@ def get_interpreter(self): First we get the InterpreterSpec for several interpreters:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.specs.rr import RRInterpreter + sage: from sage_setup.autogen.interpreters.specs.element import ElementInterpreter sage: rdf_spec = RDFInterpreter() sage: rr_spec = RRInterpreter() sage: el_spec = ElementInterpreter() @@ -649,6 +658,9 @@ def get_wrapper(self): First we get the InterpreterSpec for several interpreters:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.specs.rr import RRInterpreter + sage: from sage_setup.autogen.interpreters.specs.element import ElementInterpreter sage: rdf_spec = RDFInterpreter() sage: rr_spec = RRInterpreter() sage: el_spec = ElementInterpreter() @@ -972,6 +984,9 @@ def get_pxd(self): First we get the InterpreterSpec for several interpreters:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.specs.rr import RRInterpreter + sage: from sage_setup.autogen.interpreters.specs.element import ElementInterpreter sage: rdf_spec = RDFInterpreter() sage: rr_spec = RRInterpreter() sage: el_spec = ElementInterpreter() From eb373b0eb8113b36e2f3ed15c791c2b530727a01 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Wed, 14 Jun 2023 22:28:25 -0700 Subject: [PATCH 085/228] src/sage/ext/fast_callable.pyx: Fix doctest --- src/sage/ext/fast_callable.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/ext/fast_callable.pyx b/src/sage/ext/fast_callable.pyx index f45e8b31930..7bcd783eaff 100644 --- a/src/sage/ext/fast_callable.pyx +++ b/src/sage/ext/fast_callable.pyx @@ -488,7 +488,7 @@ def _builder_and_stream(vars, domain): EXAMPLES: sage: from sage.ext.fast_callable import _builder_and_stream - sage: _builder_and_stream(ZZ, ["x", "y"]) + sage: _builder_and_stream(["x", "y"], ZZ) """ if isinstance(domain, sage.rings.abc.RealField): From 11c537225b06193934f730808e538ffd8095e0a4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Thu, 15 Jun 2023 08:25:41 -0700 Subject: [PATCH 086/228] src/sage/ext/fast_callable.pyx: Fill in doctest output --- src/sage/ext/fast_callable.pyx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/ext/fast_callable.pyx b/src/sage/ext/fast_callable.pyx index 7bcd783eaff..497a2262a2f 100644 --- a/src/sage/ext/fast_callable.pyx +++ b/src/sage/ext/fast_callable.pyx @@ -489,7 +489,8 @@ def _builder_and_stream(vars, domain): sage: from sage.ext.fast_callable import _builder_and_stream sage: _builder_and_stream(["x", "y"], ZZ) - + (<class 'sage.ext.interpreters.wrapper_el.Wrapper_el'>, + <sage.ext.fast_callable.InstructionStream object at 0x...>) """ if isinstance(domain, sage.rings.abc.RealField): try: From 15e869852d708bf25e6193c2d21b3afee97f3330 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Thu, 15 Jun 2023 08:40:16 -0700 Subject: [PATCH 087/228] src/sage_setup/autogen/interpreters: Add missing imports to doctests --- src/sage_setup/autogen/interpreters/instructions.py | 11 ++++++++++- src/sage_setup/autogen/interpreters/memory.py | 1 + src/sage_setup/autogen/interpreters/specs/base.py | 5 +++++ src/sage_setup/autogen/interpreters/specs/cc.py | 6 ++++++ src/sage_setup/autogen/interpreters/specs/cdf.py | 1 + src/sage_setup/autogen/interpreters/specs/element.py | 3 +++ src/sage_setup/autogen/interpreters/specs/python.py | 10 ++++++++++ src/sage_setup/autogen/interpreters/specs/rdf.py | 11 ++++++----- src/sage_setup/autogen/interpreters/specs/rr.py | 6 ++++++ 9 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/sage_setup/autogen/interpreters/instructions.py b/src/sage_setup/autogen/interpreters/instructions.py index d45a34e629a..116f598197c 100644 --- a/src/sage_setup/autogen/interpreters/instructions.py +++ b/src/sage_setup/autogen/interpreters/instructions.py @@ -187,6 +187,7 @@ class InstrSpec(object): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter sage: pg = RDFInterpreter().pg sage: InstrSpec('add', pg('SS','S'), code='o0 = i0+i1;') add: SS->S = 'o0 = i0+i1;' @@ -213,7 +214,7 @@ def __init__(self, name, io, code=None, uses_error_handler=False, EXAMPLES:: sage: from sage_setup.autogen.interpreters import * - + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter sage: pg = RDFInterpreter().pg sage: InstrSpec('add', pg('SS','S'), code='o0 = i0+i1;') add: SS->S = 'o0 = i0+i1;' @@ -288,6 +289,7 @@ def __repr__(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter sage: pg = RDFInterpreter().pg sage: InstrSpec('add', pg('SS','S'), code='o0 = i0+i1;') add: SS->S = 'o0 = i0+i1;' @@ -310,6 +312,7 @@ def instr_infix(name, io, op): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter sage: pg = RDFInterpreter().pg sage: instr_infix('mul', pg('SS', 'S'), '*') mul: SS->S = 'o0 = i0 * i1;' @@ -325,6 +328,7 @@ def instr_funcall_2args(name, io, op): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter sage: pg = RDFInterpreter().pg sage: instr_funcall_2args('atan2', pg('SS', 'S'), 'atan2') atan2: SS->S = 'o0 = atan2(i0, i1);' @@ -340,6 +344,7 @@ def instr_unary(name, io, op): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter sage: pg = RDFInterpreter().pg sage: instr_unary('sin', pg('S','S'), 'sin(i0)') sin: S->S = 'o0 = sin(i0);' @@ -357,6 +362,7 @@ def instr_funcall_2args_mpfr(name, io, op): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rr import RRInterpreter sage: pg = RRInterpreter().pg sage: instr_funcall_2args_mpfr('add', pg('SS','S'), 'mpfr_add') add: SS->S = 'mpfr_add(o0, i0, i1, MPFR_RNDN);' @@ -372,6 +378,7 @@ def instr_funcall_1arg_mpfr(name, io, op): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rr import RRInterpreter sage: pg = RRInterpreter().pg sage: instr_funcall_1arg_mpfr('exp', pg('S','S'), 'mpfr_exp') exp: S->S = 'mpfr_exp(o0, i0, MPFR_RNDN);' @@ -386,6 +393,7 @@ def instr_funcall_2args_mpc(name, io, op): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.cc import CCInterpreter sage: pg = CCInterpreter().pg sage: instr_funcall_2args_mpc('add', pg('SS','S'), 'mpc_add') add: SS->S = 'mpc_add(o0, i0, i1, MPC_RNDNN);' @@ -400,6 +408,7 @@ def instr_funcall_1arg_mpc(name, io, op): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.cc import CCInterpreter sage: pg = CCInterpreter().pg sage: instr_funcall_1arg_mpc('exp', pg('S','S'), 'mpc_exp') exp: S->S = 'mpc_exp(o0, i0, MPC_RNDNN);' diff --git a/src/sage_setup/autogen/interpreters/memory.py b/src/sage_setup/autogen/interpreters/memory.py index be6ec531722..e719f47d77a 100644 --- a/src/sage_setup/autogen/interpreters/memory.py +++ b/src/sage_setup/autogen/interpreters/memory.py @@ -172,6 +172,7 @@ class using this memory chunk, to allocate local variables. EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rr import * sage: mc = MemoryChunkRRRetval('retval', ty_mpfr) sage: mc.declare_call_locals() ' cdef RealNumber retval = (self.domain)()\n' diff --git a/src/sage_setup/autogen/interpreters/specs/base.py b/src/sage_setup/autogen/interpreters/specs/base.py index 67d75b9bf45..b8c22ae65dd 100644 --- a/src/sage_setup/autogen/interpreters/specs/base.py +++ b/src/sage_setup/autogen/interpreters/specs/base.py @@ -49,6 +49,7 @@ def __init__(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter sage: interp = RDFInterpreter() sage: interp.c_header '#include <gsl/gsl_math.h>' @@ -84,6 +85,7 @@ def _set_opcodes(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter sage: interp = RDFInterpreter() sage: interp.instr_descs[5].opcode 5 @@ -128,6 +130,9 @@ def __init__(self, type, mc_retval=None): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.specs.rr import RRInterpreter + sage: from sage_setup.autogen.interpreters.specs.element import ElementInterpreter sage: rdf = RDFInterpreter() sage: rr = RRInterpreter() sage: el = ElementInterpreter() diff --git a/src/sage_setup/autogen/interpreters/specs/cc.py b/src/sage_setup/autogen/interpreters/specs/cc.py index aa0db45bad1..ea5e8708647 100644 --- a/src/sage_setup/autogen/interpreters/specs/cc.py +++ b/src/sage_setup/autogen/interpreters/specs/cc.py @@ -31,6 +31,7 @@ def declare_class_members(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.cc import * sage: mc = MemoryChunkCCRetval('retval', ty_mpc) sage: mc.declare_class_members() '' @@ -45,6 +46,7 @@ class using this memory chunk, to allocate local variables. EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.cc import * sage: mc = MemoryChunkCCRetval('retval', ty_mpc) sage: mc.declare_call_locals() ' cdef ComplexNumber retval = (self.domain_element._new())\n' @@ -62,6 +64,7 @@ def declare_parameter(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.cc import * sage: mc = MemoryChunkCCRetval('retval', ty_mpc) sage: mc.declare_parameter() 'mpc_t retval' @@ -76,6 +79,7 @@ def pass_argument(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.cc import * sage: mc = MemoryChunkCCRetval('retval', ty_mpc) sage: mc.pass_argument() '(<mpc_t>(retval.__re))' @@ -90,6 +94,7 @@ def pass_call_c_argument(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.cc import * sage: mc = MemoryChunkCCRetval('retval', ty_mpc) sage: mc.pass_call_c_argument() 'result' @@ -111,6 +116,7 @@ def __init__(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.cc import * sage: interp = CCInterpreter() sage: interp.name 'cc' diff --git a/src/sage_setup/autogen/interpreters/specs/cdf.py b/src/sage_setup/autogen/interpreters/specs/cdf.py index 7f09c3b6a5c..137487e1de2 100644 --- a/src/sage_setup/autogen/interpreters/specs/cdf.py +++ b/src/sage_setup/autogen/interpreters/specs/cdf.py @@ -34,6 +34,7 @@ def __init__(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.cdf import * sage: interp = CDFInterpreter() sage: interp.name 'cdf' diff --git a/src/sage_setup/autogen/interpreters/specs/element.py b/src/sage_setup/autogen/interpreters/specs/element.py index 3e4e4eca04f..bbb9c21ae57 100644 --- a/src/sage_setup/autogen/interpreters/specs/element.py +++ b/src/sage_setup/autogen/interpreters/specs/element.py @@ -38,6 +38,7 @@ def setup_args(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.element import * sage: mc = MemoryChunkElementArguments('args', ty_python) sage: mc.setup_args() 'mapped_args = [self._domain(a) for a in args]\n' @@ -51,6 +52,7 @@ def pass_argument(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.element import * sage: mc = MemoryChunkElementArguments('args', ty_python) sage: mc.pass_argument() '(<PyListObject*>mapped_args).ob_item' @@ -80,6 +82,7 @@ def __init__(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.element import * sage: interp = ElementInterpreter() sage: interp.name 'el' diff --git a/src/sage_setup/autogen/interpreters/specs/python.py b/src/sage_setup/autogen/interpreters/specs/python.py index eb4eee56b68..86d0d95f827 100644 --- a/src/sage_setup/autogen/interpreters/specs/python.py +++ b/src/sage_setup/autogen/interpreters/specs/python.py @@ -32,6 +32,7 @@ def declare_class_members(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.python import * sage: mc = MemoryChunkPythonArguments('args', ty_python) """ return " cdef int _n_%s\n" % self.name @@ -45,6 +46,7 @@ class members. EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.python import * sage: mc = MemoryChunkPythonArguments('args', ty_python) sage: mc.init_class_members() " count = args['args']\n self._n_args = count\n" @@ -62,6 +64,7 @@ def setup_args(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.python import * sage: mc = MemoryChunkPythonArguments('args', ty_python) sage: mc.setup_args() '' @@ -75,6 +78,7 @@ def pass_argument(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.python import * sage: mc = MemoryChunkPythonArguments('args', ty_python) sage: mc.pass_argument() '(<PyTupleObject*>args).ob_item' @@ -97,6 +101,7 @@ def __init__(self, name): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.python import * sage: mc = MemoryChunkPyConstant('domain') sage: mc.name 'domain' @@ -113,6 +118,7 @@ def declare_class_members(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.python import * sage: mc = MemoryChunkPyConstant('domain') sage: mc.declare_class_members() ' cdef object _domain\n' @@ -131,6 +137,7 @@ class members. EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.python import * sage: mc = MemoryChunkPyConstant('domain') sage: mc.init_class_members() " self._domain = args['domain']\n" @@ -148,6 +155,7 @@ def declare_parameter(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.python import * sage: mc = MemoryChunkPyConstant('domain') sage: mc.declare_parameter() 'PyObject* domain' @@ -162,6 +170,7 @@ def pass_argument(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.python import * sage: mc = MemoryChunkPyConstant('domain') sage: mc.pass_argument() '<PyObject*>self._domain' @@ -204,6 +213,7 @@ def __init__(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.python import * sage: interp = PythonInterpreter() sage: interp.name 'py' diff --git a/src/sage_setup/autogen/interpreters/specs/rdf.py b/src/sage_setup/autogen/interpreters/specs/rdf.py index 6f576844d13..367c4cf2c2e 100644 --- a/src/sage_setup/autogen/interpreters/specs/rdf.py +++ b/src/sage_setup/autogen/interpreters/specs/rdf.py @@ -37,6 +37,7 @@ def __init__(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rdf import * sage: interp = RDFInterpreter() sage: interp.name 'rdf' @@ -60,14 +61,14 @@ def __init__(self): Make sure that pow behaves reasonably:: - sage: var('x,y') + sage: var('x,y') # optional - sage.symbolic (x, y) - sage: ff = fast_callable(x^y, vars=[x,y], domain=RDF) - sage: ff(1.5, 3) + sage: ff = fast_callable(x^y, vars=[x,y], domain=RDF) # optional - sage.symbolic + sage: ff(1.5, 3) # optional - sage.symbolic 3.375 - sage: ff(-2, 3) + sage: ff(-2, 3) # optional - sage.symbolic -8.0 - sage: ff(-2, 1/3) + sage: ff(-2, 1/3) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: negative number to a fractional power not real diff --git a/src/sage_setup/autogen/interpreters/specs/rr.py b/src/sage_setup/autogen/interpreters/specs/rr.py index d59e1c2bf8e..264b694dfab 100644 --- a/src/sage_setup/autogen/interpreters/specs/rr.py +++ b/src/sage_setup/autogen/interpreters/specs/rr.py @@ -31,6 +31,7 @@ def declare_class_members(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rr import * sage: mc = MemoryChunkRRRetval('retval', ty_mpfr) sage: mc.declare_class_members() '' @@ -45,6 +46,7 @@ class using this memory chunk, to allocate local variables. EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rr import * sage: mc = MemoryChunkRRRetval('retval', ty_mpfr) sage: mc.declare_call_locals() ' cdef RealNumber retval = (self.domain)()\n' @@ -62,6 +64,7 @@ def declare_parameter(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rr import * sage: mc = MemoryChunkRRRetval('retval', ty_mpfr) sage: mc.declare_parameter() 'mpfr_t retval' @@ -76,6 +79,7 @@ def pass_argument(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rr import * sage: mc = MemoryChunkRRRetval('retval', ty_mpfr) sage: mc.pass_argument() 'retval.value' @@ -90,6 +94,7 @@ def pass_call_c_argument(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rr import * sage: mc = MemoryChunkRRRetval('retval', ty_mpfr) sage: mc.pass_call_c_argument() 'result' @@ -112,6 +117,7 @@ def __init__(self): EXAMPLES:: sage: from sage_setup.autogen.interpreters import * + sage: from sage_setup.autogen.interpreters.specs.rr import * sage: interp = RRInterpreter() sage: interp.name 'rr' From 210f27b796891b30e7341490f1f18eb4bb19978c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Thu, 15 Jun 2023 12:20:06 -0700 Subject: [PATCH 088/228] src/sage_setup/autogen/interpreters: Add another missing imports to doctests --- src/sage_setup/autogen/interpreters/specs/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage_setup/autogen/interpreters/specs/base.py b/src/sage_setup/autogen/interpreters/specs/base.py index b8c22ae65dd..c020c37cdb3 100644 --- a/src/sage_setup/autogen/interpreters/specs/base.py +++ b/src/sage_setup/autogen/interpreters/specs/base.py @@ -50,6 +50,7 @@ def __init__(self): sage: from sage_setup.autogen.interpreters import * sage: from sage_setup.autogen.interpreters.specs.rdf import RDFInterpreter + sage: from sage_setup.autogen.interpreters.specs.rr import RRInterpreter sage: interp = RDFInterpreter() sage: interp.c_header '#include <gsl/gsl_math.h>' From 8cbcb9ea6306e2ed97acdc923f2ec2485d6569a5 Mon Sep 17 00:00:00 2001 From: Miguel Marco <mmarco@unizar.es> Date: Fri, 16 Jun 2023 18:33:16 +0200 Subject: [PATCH 089/228] Allow partial result in minimal_model, and translate OS-algebra to cdga --- src/sage/algebras/commutative_dga.py | 53 ++++++++++++++++++++++++---- src/sage/algebras/orlik_solomon.py | 27 ++++++++++++++ 2 files changed, 74 insertions(+), 6 deletions(-) diff --git a/src/sage/algebras/commutative_dga.py b/src/sage/algebras/commutative_dga.py index 3159fc608d8..1982fe85345 100644 --- a/src/sage/algebras/commutative_dga.py +++ b/src/sage/algebras/commutative_dga.py @@ -2424,7 +2424,7 @@ def vector_to_element(v, deg): for g in Q.basis()] return res - def minimal_model(self, i=3, max_iterations=3): + def minimal_model(self, i=3, max_iterations=3, partial_result=False): r""" Try to compute a map from a ``i``-minimal gcda that is a ``i``-quasi-isomorphism to self. @@ -2437,7 +2437,12 @@ def minimal_model(self, i=3, max_iterations=3): - ``max_iterations`` -- integer (default: `3`); the number of iterations of the method at each degree. If the algorithm does not - finish in this many iterations at each degree, an error is raised. + finish in this many iterations at each degree, an error is raised, + or the partial result computed up to that point is returned, deppending + on the `partial_result` flag. + + - ``partial_result`` -- boolean (default: `False`); wether to return + the partial result if the `max_iterations` limit is reached. OUTPUT: @@ -2576,6 +2581,31 @@ def minimal_model(self, i=3, max_iterations=3): t --> 0 Defn: (x3_0, x3_1) --> (z, t) + :: + + sage: A.<a,b,c> = GradedCommutativeAlgebra(QQ) + sage: I = A.ideal([a*b-a*c+b*c]) + sage: B = A.quotient(I) + sage: S = B.cdg_algebra({}) + sage: S.minimal_model() + ... + ValueError: could not cover all relations in max iterations in degree 2 + sage: S.minimal_model(partial_result=True) + Commutative Differential Graded Algebra morphism: + From: Commutative Differential Graded Algebra with generators ('x1_0', 'x1_1', 'x1_2', 'y1_0', 'y1_1', 'y1_2') in degrees (1, 1, 1, 1, 1, 1) over Rational Field with differential: + x1_0 --> 0 + x1_1 --> 0 + x1_2 --> 0 + y1_0 --> x1_0*x1_1 - x1_0*x1_2 + x1_1*x1_2 + y1_1 --> x1_0*y1_0 - x1_2*y1_0 + y1_2 --> x1_1*y1_0 - x1_2*y1_0 + To: Commutative Differential Graded Algebra with generators ('a', 'b', 'c') in degrees (1, 1, 1) with relations [a*b - a*c + b*c] over Rational Field with differential: + a --> 0 + b --> 0 + c --> 0 + Defn: (x1_0, x1_1, x1_2, y1_0, y1_1, y1_2) --> (a, b, c, 0, 0, 0) + + REFERENCES: - [Fel2001]_ @@ -2661,7 +2691,7 @@ def extendy(phi, degree): if K.dimension() == 0: return phi if iteration == max_iterations - 1: - raise ValueError("could not cover all relations in max iterations in degree {}".format(degree)) + return (phi,) ndifs = [CB.lift(g) for g in K.basis()] basisdegree = B.basis(degree) ndifs = [sum(basisdegree[j] * g[j] for j in @@ -2699,7 +2729,13 @@ def extendy(phi, degree): B = A.cdg_algebra(A.differential({})) # Solve case that fails with one generator return B,gens phi = B.hom(gens) - phi = extendy(phi, degnzero + 1) + phiext = extendy(phi, degnzero + 1) + if isinstance(phiext, tuple): + if partial_result: + return phiext[0] + else: + raise ValueError("could not cover all relations in max iterations in degree {}".format(degnzero + 1)) + phi = phiext self._minimalmodels[degnzero] = phi else: degnzero = max(self._minimalmodels) @@ -2707,9 +2743,14 @@ def extendy(phi, degree): for degree in range(degnzero + 1, max_degree + 1): phi = extendx(phi, degree) - phi = extendy(phi, degree + 1) + phiext = extendy(phi, degree + 1) + if isinstance(phiext, tuple): + if partial_result: + return phiext[0] + else: + raise ValueError("could not cover all relations in max iterations in degree {}".format(degree + 1)) + phi = phiext self._minimalmodels[degree] = phi - return phi def cohomology_algebra(self, max_degree=3): diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index 4f256fe7777..59df4aa5277 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -446,6 +446,33 @@ def degree_on_basis(self, m): """ return len(m) + def as_cdga(self): + """ + Return the commutative differential graded algebra corresponding to self, with + trivial differential. + + EXAMPLES:: + + sage: H = hyperplane_arrangements.braid(3) + sage: O = H.orlik_solomon_algebra(QQ) + sage: O.as_cdga() + Commutative Differential Graded Algebra with generators ('e0', 'e1', 'e2') in degrees (1, 1, 1) with relations [e0*e1 - e0*e2 + e1*e2] over Rational Field with differential: + e0 --> 0 + e1 --> 0 + e2 --> 0 + """ + from sage.algebras.commutative_dga import GradedCommutativeAlgebra + gens = list(self.algebra_generators()) + names = ['e{}'.format(i) for i in range(len(gens))] + A = GradedCommutativeAlgebra(self.base_ring(), names) + bas2 = [(i,j) for j in range(len(gens)) for i in range(j) if gens[i]*gens[j] in self.basis()] + non_basis = [(i,j) for j in range(len(gens)) for i in range(j) if not gens[i]*gens[j] in self.basis()] + rels = {(i,j) : {p : (gens[i]*gens[j]).coefficient(frozenset(p)) for p in bas2} for (i,j) in non_basis} + I = A.ideal([A.gen(l)*A.gen(m) - sum(k*A.gen(i)*A.gen(j) for ((i,j),k) in rels[(l,m)].items()) for (l,m) in non_basis]) + B = A.quotient(I) + return B.cdg_algebra({}) + + class OrlikSolomonInvariantAlgebra(FiniteDimensionalInvariantModule): r""" The invariant algebra of the Orlik-Solomon algebra from the From af073614a82324cae90c1dbef52e866db0da2dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Fri, 16 Jun 2023 21:08:30 +0200 Subject: [PATCH 090/228] full pep8 for preparser + little refreshing --- src/sage/repl/preparse.py | 217 ++++++++++++++++++-------------------- 1 file changed, 104 insertions(+), 113 deletions(-) diff --git a/src/sage/repl/preparse.py b/src/sage/repl/preparse.py index 24a20be32e2..a051ec6e198 100644 --- a/src/sage/repl/preparse.py +++ b/src/sage/repl/preparse.py @@ -297,12 +297,13 @@ def implicit_multiplication(level=None): global implicit_mul_level if level is None: return implicit_mul_level - elif level is True: + if level is True: implicit_mul_level = 5 else: implicit_mul_level = level -def isalphadigit_(s): + +def isalphadigit_(s) -> bool: """ Return ``True`` if ``s`` is a non-empty string of alphabetic characters or a non-empty string of digits or just a single ``_`` @@ -321,13 +322,16 @@ def isalphadigit_(s): """ return s.isalpha() or s.isdigit() or s == "_" + in_single_quote = False in_double_quote = False in_triple_quote = False -def in_quote(): + +def in_quote() -> bool: return in_single_quote or in_double_quote or in_triple_quote + class QuoteStack: """The preserved state of parsing in :func:`strip_string_literals`.""" @@ -340,9 +344,8 @@ def __init__(self): sage: qs = sage.repl.preparse.QuoteStack() sage: len(qs) 0 - """ - self._stack = [] # list of QuoteStackFrame + self._stack = [] # list of QuoteStackFrame self._single_quote_safe = True self._double_quote_safe = True @@ -360,7 +363,6 @@ def __len__(self): QuoteStackFrame(...) sage: len(qs) 0 - """ return len(self._stack) @@ -376,7 +378,6 @@ def __repr__(self): [QuoteStackFrame(...delim='"'...)] sage: qs.push(sage.repl.preparse.QuoteStackFrame("'")); qs [QuoteStackFrame(...delim='"'...), QuoteStackFrame(...delim="'"...)] - """ return repr(self._stack) @@ -391,7 +392,6 @@ def peek(self): sage: qs.push(sage.repl.preparse.QuoteStackFrame('"')) sage: qs.peek() QuoteStackFrame(...delim='"'...) - """ return self._stack[-1] if self._stack else None @@ -411,7 +411,6 @@ def pop(self): sage: qs.push(sage.repl.preparse.QuoteStackFrame('"')) sage: qs.pop() QuoteStackFrame(...delim='"'...) - """ return self._stack.pop() @@ -428,7 +427,6 @@ def push(self, frame): sage: qs.push(sage.repl.preparse.QuoteStackFrame("'")) sage: len(qs) 1 - """ self._stack.append(frame) if frame.f_string: @@ -469,14 +467,12 @@ def safe_delimiter(self): sage: s.push(QuoteStackFrame('"', f_string=True)) sage: s.safe_delimiter() is None True - """ if self._single_quote_safe: return "'" - elif self._double_quote_safe: + if self._double_quote_safe: return '"' - else: - return None + return None class QuoteStackFrame(SimpleNamespace): @@ -484,7 +480,6 @@ class QuoteStackFrame(SimpleNamespace): The state of a single level of a string literal being parsed. Only F-strings have more than one level. - """ def __init__(self, delim, raw=False, f_string=False, braces=0, parens=0, brackets=0, @@ -538,7 +533,7 @@ def strip_string_literals(code, state=None): - ``code`` - a string; the input - - ``state`` - a :class:`QuoteStack` (default: None); state with which to + - ``state`` - a :class:`QuoteStack` (default: ``None``); state with which to continue processing, e.g., across multiple calls to this function OUTPUT: @@ -722,13 +717,12 @@ def strip_string_literals(code, state=None): ' f\'{r"abc".upper()[1:]:{width:10}}\' ' sage: s_broken_up == s_one_time True - """ new_code = [] literals = {} - counter = 0 # to assign unique label numbers - start = 0 # characters before this point have been added to new_code or literals - q = 0 # current search position in code string + counter = 0 # to assign unique label numbers + start = 0 # characters before this point have been added to new_code or literals + q = 0 # current search position in code string state = state or QuoteStack() quote = state.peek() @@ -736,10 +730,9 @@ def in_literal(): """In the literal portion of a string?""" if not quote: return False - elif not quote.f_string or not quote.braces or quote.nested_fmt_spec: + if not quote.f_string or not quote.braces or quote.nested_fmt_spec: return True - else: - return quote.fmt_spec and quote.braces == 1 + return quote.fmt_spec and quote.braces == 1 match = ssl_search_chars.search(code) while match: @@ -765,17 +758,17 @@ def in_literal(): if in_literal(): # Deal with escaped quotes (odd number of backslashes preceding). escaped = False - if q>0 and code[q-1] == '\\': + if q > 0 and code[q - 1] == '\\': k = 2 - while q >= k and code[q-k] == '\\': + while q >= k and code[q - k] == '\\': k += 1 - if k % 2 == 0: + if not k % 2: escaped = True # Check for end of quote. - if not escaped and code[q:q+len(quote.delim)] == quote.delim: + if not escaped and code[q:q + len(quote.delim)] == quote.delim: counter += 1 label = "L%s" % counter - literals[label] = code[start:q+len(quote.delim)] + literals[label] = code[start:q + len(quote.delim)] new_code.append("%%(%s)s" % label) q += len(quote.delim) start = q @@ -783,17 +776,17 @@ def in_literal(): quote = state.peek() else: # Check prefixes for raw or F-string. - if q>0 and code[q-1] in 'rR': + if q > 0 and code[q - 1] in 'rR': raw = True - f_string = q>1 and code[q-2] in 'fF' - elif q>0 and code[q-1] in 'fF': + f_string = q > 1 and code[q - 2] in 'fF' + elif q > 0 and code[q - 1] in 'fF': f_string = True - raw = q>1 and code[q-2] in 'rR' + raw = q > 1 and code[q - 2] in 'rR' else: raw = f_string = False # Short or long string? - if len(code) >= q+3 and (code[q+1] == ch == code[q+2]): - delim = ch*3 + if len(code) >= q + 3 and (code[q + 1] == ch == code[q + 2]): + delim = ch * 3 else: delim = ch # Now inside quotes. @@ -812,7 +805,7 @@ def in_literal(): newline = len(code) counter += 1 label = "L%s" % counter - literals[label] = code[q+1:newline] + literals[label] = code[q + 1:newline] new_code.append(code[start:q].replace('%', '%%')) new_code.append("#%%(%s)s" % label) start = q = newline @@ -831,13 +824,13 @@ def in_literal(): handle_colon = True if handle_colon: # Treat the preceding substring and the colon itself as code. - new_code.append(code[start:q+1].replace('%', '%%')) - start = q+1 + new_code.append(code[start:q + 1].replace('%', '%%')) + start = q + 1 elif ch == '{' or ch == '}': if quote and quote.f_string: # Skip over {{ and }} escape sequences outside of replacement sections. - if not quote.braces and q+1 < len(code) and code[q+1] == ch: + if not quote.braces and q + 1 < len(code) and code[q + 1] == ch: q += 2 else: # Handle the substring preceding the brace. @@ -857,7 +850,7 @@ def in_literal(): quote.braces -= 1 # We can no longer be in a nested format specifier following a }. quote.nested_fmt_spec = False - start = q+1 + start = q + 1 # Move to the next character if we have not already moved elsewhere. if q == orig_q: @@ -878,7 +871,7 @@ def in_literal(): return "".join(new_code), literals, state -def containing_block(code, idx, delimiters=['()','[]','{}'], require_delim=True): +def containing_block(code, idx, delimiters=['()', '[]', '{}'], require_delim=True): """ Find the code block given by balanced delimiters that contains the position ``idx``. @@ -893,8 +886,8 @@ def containing_block(code, idx, delimiters=['()','[]','{}'], require_delim=True) character and no character can at the same time be opening and closing delimiter. - - ``require_delim`` - a boolean (default: True); whether to raise - a SyntaxError if delimiters are present. If the delimiters are + - ``require_delim`` - a boolean (default: ``True``); whether to raise + a ``SyntaxError`` if delimiters are present. If the delimiters are unbalanced, an error will be raised in any case. OUTPUT: @@ -969,7 +962,6 @@ def containing_block(code, idx, delimiters=['()','[]','{}'], require_delim=True) (0, 6) sage: containing_block('abc',1, require_delim=False) (0, 3) - """ openings = "".join(d[0] for d in delimiters) closings = "".join(d[-1] for d in delimiters) @@ -1005,7 +997,7 @@ def containing_block(code, idx, delimiters=['()','[]','{}'], require_delim=True) if code[end] in closings: p = closings.index(code[end]) levels[p] += 1 - if p==p0 and levels[p] == 0: + if p == p0 and levels[p] == 0: break elif code[end] in openings and end > idx: p = openings.index(code[end]) @@ -1028,7 +1020,7 @@ def parse_ellipsis(code, preparse_step=True): - ``code`` - a string - - ``preparse_step`` - a boolean (default: True) + - ``preparse_step`` - a boolean (default: ``True``) OUTPUT: @@ -1056,33 +1048,33 @@ def parse_ellipsis(code, preparse_step=True): while ix != -1: if ix == 0: raise SyntaxError("cannot start line with ellipsis") - elif code[ix-1]=='.': + elif code[ix - 1] == '.': # '...' be valid Python in index slices - code = code[:ix-1] + "Ellipsis" + code[ix+2:] - elif len(code) >= ix+3 and code[ix+2]=='.': + code = code[:ix - 1] + "Ellipsis" + code[ix + 2:] + elif len(code) >= ix + 3 and code[ix + 2] == '.': # '...' be valid Python in index slices - code = code[:ix] + "Ellipsis" + code[ix+3:] + code = code[:ix] + "Ellipsis" + code[ix + 3:] else: - start_list, end_list = containing_block(code, ix, ['()','[]']) + start_list, end_list = containing_block(code, ix, ['()', '[]']) - #search the current containing block for other '..' occurrences that may - #be contained in proper subblocks. Those need to be processed before - #we can deal with the present level of ellipses. - ix = code.find('..',ix+2,end_list) + # search the current containing block for other '..' occurrences that may + # be contained in proper subblocks. Those need to be processed before + # we can deal with the present level of ellipses. + ix = code.find('..', ix + 2, end_list) while ix != -1: - if code[ix-1]!='.' and code[ix+2]!='.': - start_list,end_list = containing_block(code,ix,['()','[]']) - ix = code.find('..',ix+2,end_list) + if code[ix - 1] != '.' and code[ix + 2] != '.': + start_list, end_list = containing_block(code, ix, ['()', '[]']) + ix = code.find('..', ix + 2, end_list) - arguments = code[start_list+1:end_list-1].replace('...', ',Ellipsis,').replace('..', ',Ellipsis,') + arguments = code[start_list + 1:end_list - 1].replace('...', ',Ellipsis,').replace('..', ',Ellipsis,') arguments = re.sub(r',\s*,', ',', arguments) if preparse_step: arguments = arguments.replace(';', ', step=') - range_or_iter = 'range' if code[start_list]=='[' else 'iter' - code = "%s(ellipsis_%s(%s))%s" % (code[:start_list], - range_or_iter, - arguments, - code[end_list:]) + range_or_iter = 'range' if code[start_list] == '[' else 'iter' + code = "%s(ellipsis_%s(%s))%s" % (code[:start_list], + range_or_iter, + arguments, + code[end_list:]) ix = code.find('..') return code @@ -1120,8 +1112,10 @@ def extract_numeric_literals(code): """ return preparse_numeric_literals(code, True) + all_num_regex = None + def preparse_numeric_literals(code, extract=False, quotes="'"): """ Preparse numerical literals into their Sage counterparts, @@ -1297,11 +1291,11 @@ def preparse_numeric_literals(code, extract=False, quotes="'"): # The Sage preparser does extra things with numbers, which we need to handle here. if '.' in num: if start > 0 and num[0] == '.': - if code[start-1] == '.': + if code[start - 1] == '.': # handle Ellipsis start += 1 num = num[1:] - elif re.match(r'[\w\])]', code[start-1]): + elif re.match(r'[\w\])]', code[start - 1]): # handle R.0 continue elif end < len(code) and num[-1] == '.': @@ -1312,7 +1306,7 @@ def preparse_numeric_literals(code, extract=False, quotes="'"): elif end < len(code) and code[end] == '.' and not postfix and re.match(r'\d+(_\d+)*$', num): # \b does not match after the . for floating point # two dots in a row would be an ellipsis - if end+1 == len(code) or code[end+1] != '.': + if end + 1 == len(code) or code[end + 1] != '.': end += 1 num += '.' @@ -1343,7 +1337,7 @@ def preparse_numeric_literals(code, extract=False, quotes="'"): new_code.append(code[last:start]) if extract: - new_code.append(num_name+' ') + new_code.append(num_name + ' ') else: new_code.append(num_make) last = end @@ -1358,7 +1352,7 @@ def preparse_numeric_literals(code, extract=False, quotes="'"): def strip_prompts(line): r""" - Removes leading sage: and >>> prompts so that pasting of examples + Remove leading sage: and >>> prompts so that pasting of examples from the documentation works. INPUT: @@ -1379,10 +1373,9 @@ def strip_prompts(line): sage: strip_prompts(" 2 + 4") ' 2 + 4' """ - for prompt in ['sage:', '>>>']: + for prompt, length in [('sage:', 5), ('>>>', 3)]: if line.startswith(prompt): - line = line[len(prompt):].lstrip() - break + return line[length:].lstrip() return line @@ -1504,14 +1497,14 @@ def preparse_calculus(code): if last_end == 0: return code - else: - new_code.append(code[m.end():]) - return ''.join(new_code) + + new_code.append(code[m.end():]) + return ''.join(new_code) def preparse_generators(code): r""" - Parses generator syntax, converting:: + Parse generator syntax, converting:: obj.<gen0,gen1,...,genN> = objConstructor(...) @@ -1663,7 +1656,7 @@ def preparse_generators(code): raise SyntaxError("mismatched ')'") opening = constructor.rindex('(') # Only use comma if there are already arguments to the constructor - comma = ', ' if constructor[opening+1:-1].strip() != '' else '' + comma = ', ' if constructor[opening + 1:-1].strip() else '' names = "('%s',)" % "', '".join(gens) constructor = constructor[:-1] + comma + "names=%s)" % names elif constructor[-1] == ']': @@ -1672,9 +1665,9 @@ def preparse_generators(code): raise SyntaxError("mismatched ']'") opening = constructor.rindex('[') closing = constructor.index(']', opening) - if constructor[opening+1:closing].strip() == '': + if not constructor[opening + 1:closing].strip(): names = "'" + ', '.join(gens) + "'" - constructor = constructor[:opening+1] + names + constructor[closing:] + constructor = constructor[:opening + 1] + names + constructor[closing:] else: pass gens_tuple = "(%s,)" % ', '.join(gens) @@ -1685,9 +1678,9 @@ def preparse_generators(code): if last_end == 0: return code - else: - new_code.append(code[m.end():]) - return ''.join(new_code) + + new_code.append(code[m.end():]) + return ''.join(new_code) quote_state = None @@ -1696,19 +1689,19 @@ def preparse_generators(code): def preparse(line, reset=True, do_time=False, ignore_prompts=False, numeric_literals=True): r""" - Preparses a line of input. + Preparse a line of input. INPUT: - ``line`` - a string - - ``reset`` - a boolean (default: True) + - ``reset`` - a boolean (default: ``True``) - - ``do_time`` - a boolean (default: False) + - ``do_time`` - a boolean (default: ``False``) - - ``ignore_prompts`` - a boolean (default: False) + - ``ignore_prompts`` - a boolean (default: ``False``) - - ``numeric_literals`` - a boolean (default: True) + - ``numeric_literals`` - a boolean (default: ``True``) OUTPUT: @@ -1786,7 +1779,8 @@ def preparse(line, reset=True, do_time=False, ignore_prompts=False, if L.startswith('...'): i = line.find('...') - return line[:i+3] + preparse(line[i+3:], reset=reset, do_time=do_time, ignore_prompts=ignore_prompts) + return line[:i + 3] + preparse(line[i + 3:], reset=reset, + do_time=do_time, ignore_prompts=ignore_prompts) if ignore_prompts: # Get rid of leading sage: and >>> so that pasting of examples from @@ -1840,7 +1834,7 @@ def preparse(line, reset=True, do_time=False, ignore_prompts=False, ends.append(i) while ends: i = ends.pop() - L = L[:i] + ';%s;' % L[i] + L[i+1:] + L = L[:i] + ';%s;' % L[i] + L[i + 1:] L = ';' + L + ';' if do_time: @@ -1870,13 +1864,11 @@ def preparse(line, reset=True, do_time=False, ignore_prompts=False, L = L.replace(';#;', '#') L = L.replace(';\n;', '\n')[1:-1] - line = L % literals - - return line + return L % literals ###################################################### -## Apply the preparser to an entire file +# Apply the preparser to an entire file ###################################################### def preparse_file(contents, globals=None, numeric_literals=True): @@ -1893,11 +1885,11 @@ def preparse_file(contents, globals=None, numeric_literals=True): - ``contents`` - a string - - ``globals`` - dict or None (default: None); if given, then + - ``globals`` - dict or None (default: ``None``); if given, then arguments to load/attach are evaluated in the namespace of this dict. - - ``numeric_literals`` - bool (default: True), whether to factor + - ``numeric_literals`` - bool (default: ``True``), whether to factor out wrapping of integers and floats, so they do not get created repeatedly inside loops @@ -1918,19 +1910,17 @@ def preparse_file(contents, globals=None, numeric_literals=True): sage: file_contents = ''' ....: @parallel(8) - ....: def f(p): + ....: def func(p): ....: t = cputime() ....: M = ModularSymbols(p^2,sign=1) ....: w = M.atkin_lehner_operator(p) - ....: K = (w-1).kernel() - ....: N = K.new_subspace() - ....: D = N.decomposition()''' + ....: K = (w-1).kernel()''' sage: t = tmp_filename(ext=".sage") - sage: with open(t, 'w') as f: - ....: f.write(file_contents) - 185 + sage: with open(t, 'w') as file: + ....: file.write(file_contents) + 137 sage: load(t) - sage: sorted(list(f([11,17]))) + sage: sorted(list(func([11,17]))) [(((11,), {}), None), (((17,), {}), None)] """ if not isinstance(contents, str): @@ -1950,7 +1940,7 @@ def preparse_file(contents, globals=None, numeric_literals=True): if ix == -1: ix = len(contents) if not re.match(r"^ *(#.*)?$", contents[:ix]): - contents = "\n"+contents + contents = "\n" + contents assignments = ["%s = %s" % x for x in nums.items()] # the preparser recurses on semicolons, so we only attempt # to preserve line numbers if there are a few @@ -1966,7 +1956,7 @@ def preparse_file(contents, globals=None, numeric_literals=True): # Preparse contents prior to the load/attach. lines_out += preparse(contents[start:m.start()], **preparse_opts).splitlines() # Wrap the load/attach itself. - lines_out.append(m.group(1) + load_wrap(m.group(3), m.group(2)=='attach')) + lines_out.append(m.group(1) + load_wrap(m.group(3), m.group(2) == 'attach')) # Further preparsing should start after this load/attach line. start = m.end() # Preparse the remaining contents. @@ -2034,7 +2024,7 @@ def implicit_mul(code, level=5): keywords_py2 = ['print', 'exec'] def re_no_keyword(pattern, code): - for _ in range(2): # do it twice in because matches do not overlap + for _ in range(2): # do it twice in because matches do not overlap for m in reversed(list(re.finditer(pattern, code))): left, right = m.groups() if not iskeyword(left) and not iskeyword(right) \ @@ -2054,7 +2044,7 @@ def re_no_keyword(pattern, code): code = re.sub(r'\b(\d+(?:\.\d+)?)e([-\d])', r'\1%se%s\2' % (no_mul_token, no_mul_token), code, flags=re.I) # exclude such things as 1e5 code = re_no_keyword(r'\b((?:\d+(?:\.\d+)?)|(?:%s[0-9eEpn]*\b)) *([^\W\d(]\w*)\b' % numeric_literal_prefix, code) if level >= 2: - code = re.sub(r'(\%\(L\d+\))s', r'\1%ss%s' % (no_mul_token, no_mul_token), code) # literal strings + code = re.sub(r'(\%\(L\d+\))s', r'\1%ss%s' % (no_mul_token, no_mul_token), code) # literal strings code = re_no_keyword(r'(\)) *(\w+)', code) if level >= 3: code = re_no_keyword(r'(\w+) +(\w+)', code) @@ -2066,7 +2056,7 @@ def re_no_keyword(pattern, code): def _strip_quotes(s): """ - Strips one set of outer quotes. + Strip one set of outer quotes. INPUT: @@ -2092,7 +2082,7 @@ def _strip_quotes(s): sage: sage.repl.preparse._strip_quotes('""foo".sage""') '"foo".sage"' """ - if len(s) == 0: + if not s: return s if s[0] in ["'", '"']: s = s[1:] @@ -2179,7 +2169,6 @@ def handle_encoding_declaration(contents, out): # -*- coding: utf-42 -*- '#!/usr/local/bin/python\nimport os, sys' - .. NOTE:: - :pep:`263` says that Python will interpret a UTF-8 @@ -2201,7 +2190,7 @@ def handle_encoding_declaration(contents, out): for num, line in enumerate(lines[:2]): if re.search(r"coding[:=]\s*([-\w.]+)", line): out.write(line + '\n') - return '\n'.join(lines[:num] + lines[(num+1):]) + return '\n'.join(lines[:num] + lines[(num + 1):]) # If we did not find any encoding hints, use utf-8. This is not in # conformance with PEP 263, which says that Python files default to @@ -2209,6 +2198,7 @@ def handle_encoding_declaration(contents, out): out.write("# -*- coding: utf-8 -*-\n") return contents + def preparse_file_named_to_stream(name, out): r""" Preparse file named \code{name} (presumably a .sage file), outputting to @@ -2219,11 +2209,12 @@ def preparse_file_named_to_stream(name, out): contents = f.read() contents = handle_encoding_declaration(contents, out) parsed = preparse_file(contents) - out.write('#'*70+'\n') - out.write('# This file was *autogenerated* from the file %s.\n' % name) - out.write('#'*70+'\n') + out.write('#' * 70 + '\n') + out.write(f'# This file was *autogenerated* from the file {name}.\n') + out.write('#' * 70 + '\n') out.write(parsed) + def preparse_file_named(name): r""" Preparse file named \code{name} (presumably a .sage file), outputting to a From 81f17dce8abca5687290a0aec749e1b12a77bee1 Mon Sep 17 00:00:00 2001 From: Miguel Marco <mmarco@unizar.es> Date: Fri, 16 Jun 2023 21:56:23 +0200 Subject: [PATCH 091/228] Fixed doctest --- src/sage/algebras/commutative_dga.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/algebras/commutative_dga.py b/src/sage/algebras/commutative_dga.py index 1982fe85345..8cebbb79963 100644 --- a/src/sage/algebras/commutative_dga.py +++ b/src/sage/algebras/commutative_dga.py @@ -2588,6 +2588,7 @@ def minimal_model(self, i=3, max_iterations=3, partial_result=False): sage: B = A.quotient(I) sage: S = B.cdg_algebra({}) sage: S.minimal_model() + Traceback (most recent call last): ... ValueError: could not cover all relations in max iterations in degree 2 sage: S.minimal_model(partial_result=True) From 9c38f5826c46f612133a486033bc7af4058e4889 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sat, 17 Jun 2023 06:14:16 -0700 Subject: [PATCH 092/228] build/pkgs/onetbb: Add distros/opensuse.txt --- build/pkgs/onetbb/distros/opensuse.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 build/pkgs/onetbb/distros/opensuse.txt diff --git a/build/pkgs/onetbb/distros/opensuse.txt b/build/pkgs/onetbb/distros/opensuse.txt new file mode 100644 index 00000000000..2e18bff2796 --- /dev/null +++ b/build/pkgs/onetbb/distros/opensuse.txt @@ -0,0 +1 @@ +tbb From 0b52ef28364cb99e7f1cd4d7893d31f5ef733059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Sat, 17 Jun 2023 19:03:09 +0200 Subject: [PATCH 093/228] fix fricas doctest --- src/sage/symbolic/expression.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index aa876c9b324..255a6cdb5e0 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -10667,7 +10667,7 @@ cdef class Expression(Expression_abc): sage: ex.simplify(algorithm="giac") I*sqrt(x^2 - 1) sage: ex.simplify(algorithm="fricas") # optional - fricas - I*sqrt(x^2 - 1)? + (I*x^2 + I*sqrt(x^2 - 1)*x - I)/(x + sqrt(x^2 - 1)) TESTS: From f8a7e9b64c9c5db4e2295de3d6599ec3cb0d4bfb Mon Sep 17 00:00:00 2001 From: OP5642 <ognjenpetrov@yahoo.com> Date: Sat, 17 Jun 2023 23:49:19 +0200 Subject: [PATCH 094/228] Expanded the docstring and fixed is_golod method --- src/sage/topology/simplicial_complex.py | 33 ++++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/sage/topology/simplicial_complex.py b/src/sage/topology/simplicial_complex.py index 6dd5dc45479..a714877a274 100644 --- a/src/sage/topology/simplicial_complex.py +++ b/src/sage/topology/simplicial_complex.py @@ -4957,16 +4957,25 @@ def is_golod(self): A simplicial complex is Golod if multiplication and all higher Massey operations in the associated Tor-algebra are trivial. This is done by checking the bigraded Betti numbers. + + EXAMPLES:: + + sage: X = SimplicialComplex([[0,1],[1,2],[2,3],[3,0]]) + sage: Y = SimplicialComplex([[0,1,2],[0,2],[0,4]]) + sage: X.is_golod() + False + sage: Y.is_golod() + True """ H = set(a+b for (a, b) in self.bigraded_betti_numbers()) for i in H: for j in H: - if i + j in H: + if i+j in H and i != 0 and j != 0: return False return True - def is_minimally_non_golod(self, decomposition=True): + def is_minimally_non_golod(self): r""" Return whether `self` is minimally non-Golod. @@ -4974,11 +4983,23 @@ def is_minimally_non_golod(self, decomposition=True): gives us a full subcomplex that is Golod, then we say that a simplicial complex is minimally non-Golod. - :param decomposition: If ``False``, do not print the decomposition - of the corresponding moment-angle complex - :type decomposition: boolean; optional, default ``True`` + .. SEEALSO:: + + See :meth:`is_golod` for more information. + + EXAMPLES:: + + sage: X = SimplicialComplex([[0,1],[1,2],[2,3],[3,0]]) + sage: Y = SimplicialComplex([[1,2,3],[1,2,4],[3,5],[4,5]]) + sage: X.is_golod() + False + sage: X.is_minimally_non_golod() + True + sage: Y.is_golod() + False + sage: Y.is_minimally_non_golod() + True """ - #TODO L = self.vertices() n = len(L) From 9f4a2941237202085d69fbcab2932c0dc62218d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Sun, 18 Jun 2023 08:38:21 +0200 Subject: [PATCH 095/228] cleaning some things remaining from python 2 --- src/doc/fr/tutorial/afterword.rst | 12 +++---- src/sage/combinat/tutorial.py | 10 ++---- src/sage/databases/findstat.py | 4 +-- src/sage/rings/rational.pyx | 57 ++---------------------------- src/sage/rings/rational_field.py | 2 +- src/sage/structure/sage_object.pyx | 7 +--- 6 files changed, 15 insertions(+), 77 deletions(-) diff --git a/src/doc/fr/tutorial/afterword.rst b/src/doc/fr/tutorial/afterword.rst index 857d2de5ec1..05e26ae4a50 100644 --- a/src/doc/fr/tutorial/afterword.rst +++ b/src/doc/fr/tutorial/afterword.rst @@ -112,12 +112,12 @@ Aussi, Sage se comporte différemment de Python à plusieurs égards. sage: a 10 -- **Division entière :** L'expression Python ``2/3`` ne se comporte pas - de la manière à laquelle s'attendraient des mathématiciens. En Python 2, si - ``m`` et ``n`` sont de type int, alors ``m/n`` est aussi de type int, c'est - le quotient entier de ``m`` par ``n``. Par conséquent, ``2/3=0``. Ce - comportement est différent en Python 3, où ``2/3`` renvoie un flottant - ``0.6666...`` et c'est ``2//3`` qui renvoie ``0``. +- **Division entière :** L'expression Python ``2/3`` ne se comporte + pas de la manière à laquelle s'attendraient des mathématiciens. En + Python 3, si ``m`` et ``n`` sont de type ``int``, alors ``m/n`` est + de type ``float``, c'est le quotient réel de ``m`` par ``n``. Par + exemple, ``2/3`` renvoie ``0.6666...``. Pour obtenir le quotient + entier, il faut utiliser ``2//3`` qui renvoie ``0``. Dans l'interpréteur Sage, nous réglons cela en encapsulant automatiquement les entiers litéraux par ``Integer( )`` et en faisant diff --git a/src/sage/combinat/tutorial.py b/src/sage/combinat/tutorial.py index 6422d920378..4ab35045742 100644 --- a/src/sage/combinat/tutorial.py +++ b/src/sage/combinat/tutorial.py @@ -1048,7 +1048,7 @@ the function ``sum`` receives the iterator directly, and can short-circuit the construction of the intermediate list. If there are a large number of elements, this avoids allocating a large quantity of -memory to fill a list which will be immediately destroyed [2]_. +memory to fill a list which will be immediately destroyed. Most functions that take a list of elements as input will also accept an iterator (or an iterable) instead. To begin with, one can obtain the @@ -1805,7 +1805,7 @@ then the graphs with two edges, and so on. The set of children of a graph `G` can be constructed by *augmentation*, adding an edge in all the possible ways to `G`, and then selecting, from among those graphs, -the ones that are still canonical [3]_. Recursively, one obtains all +the ones that are still canonical [2]_. Recursively, one obtains all the canonical graphs. .. figure:: ../../media/prefix-tree-graphs-4.png @@ -1848,12 +1848,6 @@ clean up. .. [2] - Technical detail: ``range`` returns an iterator on - `\{0,\dots,8\}` while ``range`` returns the corresponding - list. Starting in ``Python`` 3.0, ``range`` will behave like ``range``, and - ``range`` will no longer be needed. - -.. [3] In practice, an efficient implementation would exploit the symmetries of `G`, i.e., its automorphism group, to reduce the number of children to explore, and to reduce the cost of each test of diff --git a/src/sage/databases/findstat.py b/src/sage/databases/findstat.py index ecb85b8364e..a3fc0671644 100644 --- a/src/sage/databases/findstat.py +++ b/src/sage/databases/findstat.py @@ -2095,7 +2095,7 @@ def oeis_search(self, search_size=32, verbose=True): if counter >= 4: if verbose: print('Searching the OEIS for "%s"' % OEIS_string) - return oeis(str(OEIS_string)) # in python 2.7, oeis does not like unicode + return oeis(OEIS_string) if verbose: print("Too little information to search the OEIS for this statistic (only %s values given)." % counter) @@ -2371,7 +2371,7 @@ def submit(self, max_values=FINDSTAT_MAX_SUBMISSION_VALUES): sage: s.set_description(u"Möbius") # optional -- internet sage: s.submit() # optional -- webbrowser """ - args = dict() + args = {} args["OriginalStatistic"] = self.id_str() args["Domain"] = self.domain().id_str() args["Values"] = self.first_terms_str(max_values=max_values) diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index 5c2a9e6ae0c..37710236c85 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -4187,7 +4187,7 @@ cdef class Q_to_Z(Map): cdef class int_to_Q(Morphism): r""" - A morphism from Python 2 ``int`` to `\QQ`. + A morphism from Python 3 ``int`` to `\QQ`. """ def __init__(self): """ @@ -4203,57 +4203,6 @@ cdef class int_to_Q(Morphism): from . import rational_field import sage.categories.homset from sage.sets.pythonclass import Set_PythonType - Morphism.__init__(self, sage.categories.homset.Hom(Set_PythonType(int), rational_field.QQ)) - - cpdef Element _call_(self, a): - """ - Return the image of the morphism on ``a``. - - EXAMPLES:: - - sage: f = sage.rings.rational.int_to_Q() - sage: f(int(4)) # indirect doctest - 4 - """ - cdef Rational rat - - if type(a) is not int: - raise TypeError("must be a Python int object") - - rat = <Rational> Rational.__new__(Rational) - mpq_set_si(rat.value, PyInt_AS_LONG(a), 1) - return rat - - def _repr_type(self): - """ - Return string that describes the type of morphism. - - EXAMPLES:: - - sage: sage.rings.rational.int_to_Q()._repr_type() - 'Native' - """ - return "Native" - - -cdef class long_to_Q(Morphism): - r""" - A morphism from Python 2 ``long``/Python 3 ``int`` to `\QQ`. - """ - def __init__(self): - """ - Initialize ``self``. - - EXAMPLES:: - - sage: sage.rings.rational.long_to_Q() - Native morphism: - From: Set of Python objects of class 'int' - To: Rational Field - """ - from . import rational_field - import sage.categories.homset - from sage.sets.pythonclass import Set_PythonType Morphism.__init__(self, sage.categories.homset.Hom( Set_PythonType(long), rational_field.QQ)) @@ -4263,7 +4212,7 @@ cdef class long_to_Q(Morphism): EXAMPLES:: - sage: f = sage.rings.rational.long_to_Q() + sage: f = sage.rings.rational.int_to_Q() sage: f(4^100) 1606938044258990275541962092341162602522202993782792835301376 """ @@ -4289,7 +4238,7 @@ cdef class long_to_Q(Morphism): EXAMPLES:: - sage: sage.rings.rational.long_to_Q()._repr_type() + sage: sage.rings.rational.int_to_Q()._repr_type() 'Native' """ return "Native" diff --git a/src/sage/rings/rational_field.py b/src/sage/rings/rational_field.py index 3fb31328e76..cbd5a4ba483 100644 --- a/src/sage/rings/rational_field.py +++ b/src/sage/rings/rational_field.py @@ -374,7 +374,7 @@ def _coerce_map_from_(self, S): if S is ZZ: return rational.Z_to_Q() elif S is int: - return rational.long_to_Q() + return rational.int_to_Q() elif ZZ.has_coerce_map_from(S): return rational.Z_to_Q() * ZZ._internal_coerce_map_from(S) from sage.rings.localization import Localization diff --git a/src/sage/structure/sage_object.pyx b/src/sage/structure/sage_object.pyx index 2140a285f2c..14a5c3138aa 100644 --- a/src/sage/structure/sage_object.pyx +++ b/src/sage/structure/sage_object.pyx @@ -141,7 +141,6 @@ cdef class SageObject: if hasattr(self, '__custom_name'): del self.__custom_name - def __repr__(self): """ Default method for string representation. @@ -191,11 +190,7 @@ cdef class SageObject: reprfunc = self._repr_ except AttributeError: return super().__repr__() - result = reprfunc() - if isinstance(result, str): - return result - # Allow _repr_ to return unicode on Python 2 - return result.encode('utf-8') + return reprfunc() def _ascii_art_(self): r""" From a4402747a2fbf86beece3f8ee226ad7a6e9f96e5 Mon Sep 17 00:00:00 2001 From: miguelmarco <mmarco@unizar.es> Date: Sun, 18 Jun 2023 16:23:38 +0200 Subject: [PATCH 096/228] Update src/sage/algebras/commutative_dga.py Co-authored-by: Travis Scrimshaw <clfrngrown@aol.com> --- src/sage/algebras/commutative_dga.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sage/algebras/commutative_dga.py b/src/sage/algebras/commutative_dga.py index 8cebbb79963..4369241f07f 100644 --- a/src/sage/algebras/commutative_dga.py +++ b/src/sage/algebras/commutative_dga.py @@ -2732,10 +2732,9 @@ def extendy(phi, degree): phi = B.hom(gens) phiext = extendy(phi, degnzero + 1) if isinstance(phiext, tuple): - if partial_result: - return phiext[0] - else: + if not partial_result: raise ValueError("could not cover all relations in max iterations in degree {}".format(degnzero + 1)) + return phiext[0] phi = phiext self._minimalmodels[degnzero] = phi else: From ba51c2e0cdd996bd6890d4db95d4269ba74cc02f Mon Sep 17 00:00:00 2001 From: miguelmarco <mmarco@unizar.es> Date: Sun, 18 Jun 2023 16:25:33 +0200 Subject: [PATCH 097/228] Update src/sage/algebras/orlik_solomon.py Co-authored-by: Travis Scrimshaw <clfrngrown@aol.com> --- src/sage/algebras/orlik_solomon.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index 59df4aa5277..5fcdc7ff1d0 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -465,10 +465,24 @@ def as_cdga(self): gens = list(self.algebra_generators()) names = ['e{}'.format(i) for i in range(len(gens))] A = GradedCommutativeAlgebra(self.base_ring(), names) - bas2 = [(i,j) for j in range(len(gens)) for i in range(j) if gens[i]*gens[j] in self.basis()] - non_basis = [(i,j) for j in range(len(gens)) for i in range(j) if not gens[i]*gens[j] in self.basis()] - rels = {(i,j) : {p : (gens[i]*gens[j]).coefficient(frozenset(p)) for p in bas2} for (i,j) in non_basis} - I = A.ideal([A.gen(l)*A.gen(m) - sum(k*A.gen(i)*A.gen(j) for ((i,j),k) in rels[(l,m)].items()) for (l,m) in non_basis]) + B = self.basis() + bas2 = [] + non_basis = [] + for j, gj in enumerate(gens): + for i in range(j): + if gens[i] * gj in B: + bas2.append((i, j)) + else: + non_basis.append((i, j)) + AG = A.gens() + AGbas = {(i, j): AG[i] * AG[j] for (i, j) in bas2} + gij = {(i, j): gens[i] * gens[j] for (i, j) in bas2} + + def rhs(l, m): + P = gens[l] * gens[m] + return A.sum(P.coefficient(gij[p]) * AGbas[p] for p in bas2) + + I = A.ideal([AG[l]*AG[m] - rhs(l, m) for (l,m) in non_basis]) B = A.quotient(I) return B.cdg_algebra({}) From d58aac93a172cd9daeb94570f87073683549bb24 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sun, 18 Jun 2023 09:14:24 -0700 Subject: [PATCH 098/228] tox.ini, .github/workflow/docker.yml: Add almalinux --- .github/workflows/docker.yml | 2 ++ tox.ini | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index bf21a83cc60..05d8603540f 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -50,6 +50,8 @@ on: "centos-7-devtoolset-gcc_11", "centos-stream-8-python3.9", "centos-stream-9-python3.9", + "almalinux-8-python3.9", + "almalinux-9-python3.11", "gentoo-python3.10", "gentoo-python3.11", "archlinux-latest", diff --git a/tox.ini b/tox.ini index c5591c5a546..9c74d31bbe5 100644 --- a/tox.ini +++ b/tox.ini @@ -308,6 +308,13 @@ setenv = centos-stream-8: BASE_TAG=stream8 centos-stream-9: BASE_TAG=stream9 # + # https://hub.docker.com/_/almalinux + # + almalinux: SYSTEM=fedora + almalinux: BASE_IMAGE=almalinux + almalinux: IGNORE_MISSING_SYSTEM_PACKAGES=yes + almalinux-8: BASE_TAG=8 + almalinux-9: BASE_TAG=9 # https://hub.docker.com/r/sheerluck/sage-on-gentoo-stage4/tags # gentoo: SYSTEM=gentoo From 2e360012a90d7b6fdad3ca62f29a8dba454b91fa Mon Sep 17 00:00:00 2001 From: Miguel Marco <mmarco@unizar.es> Date: Sun, 18 Jun 2023 19:02:48 +0200 Subject: [PATCH 099/228] use frozenset to look for coefficients --- src/sage/algebras/orlik_solomon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index 5fcdc7ff1d0..fa39b6243a1 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -480,7 +480,7 @@ def as_cdga(self): def rhs(l, m): P = gens[l] * gens[m] - return A.sum(P.coefficient(gij[p]) * AGbas[p] for p in bas2) + return A.sum(P.coefficient(frozenset(p)) * AGbas[p] for p in bas2) I = A.ideal([AG[l]*AG[m] - rhs(l, m) for (l,m) in non_basis]) B = A.quotient(I) From 0b7213f8f981e504348c321e47f43d097d116097 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee <ekwankyu@gmail.com> Date: Mon, 19 Jun 2023 07:26:18 +0900 Subject: [PATCH 100/228] Fix copyright headers in function fields --- src/sage/rings/function_field/constructor.py | 5 +++-- src/sage/rings/function_field/derivations.py | 1 + src/sage/rings/function_field/differential.py | 5 +++-- src/sage/rings/function_field/divisor.py | 5 +++-- src/sage/rings/function_field/element.pyx | 4 ++-- .../rings/function_field/element_polymod.pyx | 15 +++++++++++--- .../rings/function_field/element_rational.pyx | 15 +++++++++++--- .../rings/function_field/function_field.py | 4 ++-- .../function_field/function_field_polymod.py | 20 ++++++++++++++++--- .../function_field/function_field_rational.py | 20 ++++++++++++++++--- .../hermite_form_polynomial.pyx | 5 +++-- .../rings/function_field/ideal_polymod.py | 11 +++++++--- .../rings/function_field/ideal_rational.py | 11 +++++++--- src/sage/rings/function_field/maps.py | 1 + src/sage/rings/function_field/order.py | 4 ++-- src/sage/rings/function_field/order_basis.py | 10 +++++++--- .../rings/function_field/order_polymod.py | 10 +++++++--- .../rings/function_field/order_rational.py | 10 +++++++--- src/sage/rings/function_field/place.py | 4 ++-- .../rings/function_field/place_polymod.py | 8 +++++--- .../rings/function_field/place_rational.py | 8 +++++--- src/sage/rings/function_field/valuation.py | 2 ++ .../rings/function_field/valuation_ring.py | 1 + 23 files changed, 130 insertions(+), 49 deletions(-) diff --git a/src/sage/rings/function_field/constructor.py b/src/sage/rings/function_field/constructor.py index f34024aa03b..37aa8494a9e 100644 --- a/src/sage/rings/function_field/constructor.py +++ b/src/sage/rings/function_field/constructor.py @@ -24,7 +24,8 @@ ``UniqueFactory`` """ -#***************************************************************************** + +# **************************************************************************** # Copyright (C) 2010 William Stein <wstein@gmail.com> # 2011 Maarten Derickx <m.derickx.student@gmail.com> # 2011-2014 Julian Rueth <julian.rueth@gmail.com> @@ -35,7 +36,7 @@ # 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.structure.factory import UniqueFactory diff --git a/src/sage/rings/function_field/derivations.py b/src/sage/rings/function_field/derivations.py index e849a4e0016..d0c34397a46 100644 --- a/src/sage/rings/function_field/derivations.py +++ b/src/sage/rings/function_field/derivations.py @@ -20,6 +20,7 @@ - Kwankyu Lee (2017-04-30): added higher derivations and completions """ + # **************************************************************************** # Copyright (C) 2010 William Stein <wstein@gmail.com> # 2011-2017 Julian Rüth <julian.rueth@gmail.com> diff --git a/src/sage/rings/function_field/differential.py b/src/sage/rings/function_field/differential.py index 24ea2371040..756d8b3993d 100644 --- a/src/sage/rings/function_field/differential.py +++ b/src/sage/rings/function_field/differential.py @@ -45,7 +45,8 @@ - Kwankyu Lee (2017-04-30): initial version """ -#***************************************************************************** + +# **************************************************************************** # Copyright (C) 2016-2019 Kwankyu Lee <ekwankyu@gmail.com> # 2019 Brent Baccala # 2019 Travis Scrimshaw @@ -54,7 +55,7 @@ # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # http://www.gnu.org/licenses/ -#***************************************************************************** +# **************************************************************************** from sage.misc.latex import latex diff --git a/src/sage/rings/function_field/divisor.py b/src/sage/rings/function_field/divisor.py index 4646491c7e0..59f0f7a0cbb 100644 --- a/src/sage/rings/function_field/divisor.py +++ b/src/sage/rings/function_field/divisor.py @@ -39,7 +39,8 @@ - Kwankyu Lee (2017-04-30): initial version """ -#***************************************************************************** + +# **************************************************************************** # Copyright (C) 2016-2022 Kwankyu Lee <ekwankyu@gmail.com> # 2019 Brent Baccala # @@ -47,7 +48,7 @@ # 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 random diff --git a/src/sage/rings/function_field/element.pyx b/src/sage/rings/function_field/element.pyx index 3aebcbc3f1a..c17b904f6d6 100644 --- a/src/sage/rings/function_field/element.pyx +++ b/src/sage/rings/function_field/element.pyx @@ -47,7 +47,7 @@ AUTHORS: - Kwankyu Lee (2017-04-30): added elements for global function fields """ -# **************************************************************************** +# ***************************************************************************** # Copyright (C) 2010 William Stein <wstein@gmail.com> # 2010 Robert Bradshaw <robertwb@math.washington.edu> # 2011-2020 Julian Rueth <julian.rueth@gmail.com> @@ -63,7 +63,7 @@ AUTHORS: # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ -# **************************************************************************** +# ***************************************************************************** from sage.structure.element cimport FieldElement from sage.misc.cachefunc import cached_method diff --git a/src/sage/rings/function_field/element_polymod.pyx b/src/sage/rings/function_field/element_polymod.pyx index 21aa9e36ab3..fa1fc11bf62 100644 --- a/src/sage/rings/function_field/element_polymod.pyx +++ b/src/sage/rings/function_field/element_polymod.pyx @@ -3,14 +3,23 @@ r""" Elements of function fields: extension """ -# **************************************************************************** -# Copyright (C) 2023 Kwankyu Lee <ekwankyu@gmail.com> +# ***************************************************************************** +# Copyright (C) 2010 William Stein <wstein@gmail.com> +# 2010 Robert Bradshaw <robertwb@math.washington.edu> +# 2011-2020 Julian Rueth <julian.rueth@gmail.com> +# 2011 Maarten Derickx <m.derickx.student@gmail.com> +# 2015 Nils Bruin +# 2016 Frédéric Chapoton +# 2017-2019 Kwankyu Lee +# 2018-2020 Travis Scrimshaw +# 2019 Brent Baccala +# 2021 Saher Amasha # # 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. # https://www.gnu.org/licenses/ -# **************************************************************************** +# ***************************************************************************** from sage.structure.richcmp cimport richcmp from sage.structure.element cimport FieldElement diff --git a/src/sage/rings/function_field/element_rational.pyx b/src/sage/rings/function_field/element_rational.pyx index 9af91c2b496..a21fbe397e2 100644 --- a/src/sage/rings/function_field/element_rational.pyx +++ b/src/sage/rings/function_field/element_rational.pyx @@ -2,14 +2,23 @@ r""" Elements of function fields: rational """ -# **************************************************************************** -# Copyright (C) 2023 Kwankyu Lee <ekwankyu@gmail.com> +# ***************************************************************************** +# Copyright (C) 2010 William Stein <wstein@gmail.com> +# 2010 Robert Bradshaw <robertwb@math.washington.edu> +# 2011-2020 Julian Rueth <julian.rueth@gmail.com> +# 2011 Maarten Derickx <m.derickx.student@gmail.com> +# 2015 Nils Bruin +# 2016 Frédéric Chapoton +# 2017-2019 Kwankyu Lee +# 2018-2020 Travis Scrimshaw +# 2019 Brent Baccala +# 2021 Saher Amasha # # 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. # https://www.gnu.org/licenses/ -# **************************************************************************** +# ***************************************************************************** from sage.structure.richcmp cimport richcmp, richcmp_not_equal from sage.structure.element cimport FieldElement diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index e89ea118106..75c8fc1e0b0 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -210,7 +210,7 @@ """ -# **************************************************************************** +# ***************************************************************************** # Copyright (C) 2010 William Stein <wstein@gmail.com> # 2010 Robert Bradshaw <robertwb@math.washington.edu> # 2011-2018 Julian Rüth <julian.rueth@gmail.com> @@ -231,7 +231,7 @@ # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ -# **************************************************************************** +# ***************************************************************************** from sage.misc.cachefunc import cached_method from sage.misc.lazy_import import LazyImport diff --git a/src/sage/rings/function_field/function_field_polymod.py b/src/sage/rings/function_field/function_field_polymod.py index 76d12423004..fa8731848ee 100644 --- a/src/sage/rings/function_field/function_field_polymod.py +++ b/src/sage/rings/function_field/function_field_polymod.py @@ -3,14 +3,28 @@ Function Fields: extension """ -#***************************************************************************** -# Copyright (C) 2023 Kwankyu Lee <ekwankyu@gmail.com> +# ***************************************************************************** +# Copyright (C) 2010 William Stein <wstein@gmail.com> +# 2010 Robert Bradshaw <robertwb@math.washington.edu> +# 2011-2018 Julian Rüth <julian.rueth@gmail.com> +# 2011 Maarten Derickx <m.derickx.student@gmail.com> +# 2011 Syed Ahmad Lavasani +# 2013-2014 Simon King +# 2017 Dean Bisogno +# 2017 Alyson Deines +# 2017-2019 David Roe +# 2017-2022 Kwankyu Lee +# 2018 Marc Mezzarobba +# 2018 Wilfried Luebbe +# 2019 Brent Baccala +# 2022 Frédéric Chapoton +# 2022 Gonzalo Tornaría # # 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.arith.functions import lcm from sage.misc.cachefunc import cached_method diff --git a/src/sage/rings/function_field/function_field_rational.py b/src/sage/rings/function_field/function_field_rational.py index 8ada23fec93..88d1c2cc0a3 100644 --- a/src/sage/rings/function_field/function_field_rational.py +++ b/src/sage/rings/function_field/function_field_rational.py @@ -2,14 +2,28 @@ Function Fields: rational """ -#***************************************************************************** -# Copyright (C) 2023 Kwankyu Lee <ekwankyu@gmail.com> +# ***************************************************************************** +# Copyright (C) 2010 William Stein <wstein@gmail.com> +# 2010 Robert Bradshaw <robertwb@math.washington.edu> +# 2011-2018 Julian Rüth <julian.rueth@gmail.com> +# 2011 Maarten Derickx <m.derickx.student@gmail.com> +# 2011 Syed Ahmad Lavasani +# 2013-2014 Simon King +# 2017 Dean Bisogno +# 2017 Alyson Deines +# 2017-2019 David Roe +# 2017-2022 Kwankyu Lee +# 2018 Marc Mezzarobba +# 2018 Wilfried Luebbe +# 2019 Brent Baccala +# 2022 Frédéric Chapoton +# 2022 Gonzalo Tornaría # # 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.arith.functions import lcm from sage.misc.cachefunc import cached_method diff --git a/src/sage/rings/function_field/hermite_form_polynomial.pyx b/src/sage/rings/function_field/hermite_form_polynomial.pyx index dff24054110..12881615315 100644 --- a/src/sage/rings/function_field/hermite_form_polynomial.pyx +++ b/src/sage/rings/function_field/hermite_form_polynomial.pyx @@ -42,14 +42,15 @@ AUTHORS: - Kwankyu Lee (2021-05-21): initial version """ -#***************************************************************************** + +# **************************************************************************** # Copyright (C) 2021 Kwankyu Lee <ekwankyu@gmail.com> # # 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.matrix.matrix cimport Matrix from sage.rings.polynomial.polynomial_element cimport Polynomial diff --git a/src/sage/rings/function_field/ideal_polymod.py b/src/sage/rings/function_field/ideal_polymod.py index 0a5309b4584..936b63b48fe 100644 --- a/src/sage/rings/function_field/ideal_polymod.py +++ b/src/sage/rings/function_field/ideal_polymod.py @@ -3,14 +3,19 @@ Ideals of function fields: extension """ -#***************************************************************************** -# Copyright (C) 2023 Kwankyu Lee <ekwankyu@gmail.com> +# **************************************************************************** +# Copyright (C) 2010 William Stein <wstein@gmail.com> +# 2011 Maarten Derickx <m.derickx.student@gmail.com> +# 2017-2021 Kwankyu Lee +# 2018 Frédéric Chapoton +# 2019 Brent Baccala +# 2021 Jonathan Kliem # # 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/ -#***************************************************************************** +# **************************************************************************** import itertools from sage.rings.infinity import infinity diff --git a/src/sage/rings/function_field/ideal_rational.py b/src/sage/rings/function_field/ideal_rational.py index 9f110034c55..06400bf31f1 100644 --- a/src/sage/rings/function_field/ideal_rational.py +++ b/src/sage/rings/function_field/ideal_rational.py @@ -2,14 +2,19 @@ Ideals of function fields: rational """ -#***************************************************************************** -# Copyright (C) 2023 Kwankyu Lee <ekwankyu@gmail.com> +# **************************************************************************** +# Copyright (C) 2010 William Stein <wstein@gmail.com> +# 2011 Maarten Derickx <m.derickx.student@gmail.com> +# 2017-2021 Kwankyu Lee +# 2018 Frédéric Chapoton +# 2019 Brent Baccala +# 2021 Jonathan Kliem # # 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.misc.cachefunc import cached_method from sage.structure.richcmp import richcmp diff --git a/src/sage/rings/function_field/maps.py b/src/sage/rings/function_field/maps.py index ce0a775c31e..fc1768df310 100644 --- a/src/sage/rings/function_field/maps.py +++ b/src/sage/rings/function_field/maps.py @@ -34,6 +34,7 @@ - Kwankyu Lee (2017-04-30): added higher derivations and completions """ + # **************************************************************************** # Copyright (C) 2010 William Stein <wstein@gmail.com> # 2011-2017 Julian Rüth <julian.rueth@gmail.com> diff --git a/src/sage/rings/function_field/order.py b/src/sage/rings/function_field/order.py index a2e85f21fc8..47d85622146 100644 --- a/src/sage/rings/function_field/order.py +++ b/src/sage/rings/function_field/order.py @@ -95,7 +95,7 @@ """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2010 William Stein <wstein@gmail.com> # 2011 Maarten Derickx <m.derickx.student@gmail.com> # 2011 Julian Rueth <julian.rueth@gmail.com> @@ -106,7 +106,7 @@ # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ -#***************************************************************************** +# **************************************************************************** from sage.categories.integral_domains import IntegralDomains from sage.structure.parent import Parent diff --git a/src/sage/rings/function_field/order_basis.py b/src/sage/rings/function_field/order_basis.py index bb9ffd72979..1b0a4434d2c 100644 --- a/src/sage/rings/function_field/order_basis.py +++ b/src/sage/rings/function_field/order_basis.py @@ -4,14 +4,18 @@ Orders of function fields: basis """ -#***************************************************************************** -# Copyright (C) 2023 Kwankyu Lee <ekwankyu@gmail.com> +# **************************************************************************** +# Copyright (C) 2010 William Stein <wstein@gmail.com> +# 2011 Maarten Derickx <m.derickx.student@gmail.com> +# 2011 Julian Rueth <julian.rueth@gmail.com> +# 2017-2020 Kwankyu Lee +# 2019 Brent Baccala # # 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 .ideal import FunctionFieldIdeal, FunctionFieldIdeal_module, FunctionFieldIdealInfinite_module from .order import FunctionFieldOrder, FunctionFieldOrderInfinite diff --git a/src/sage/rings/function_field/order_polymod.py b/src/sage/rings/function_field/order_polymod.py index 66f6fb4b3db..a95c003188f 100644 --- a/src/sage/rings/function_field/order_polymod.py +++ b/src/sage/rings/function_field/order_polymod.py @@ -3,14 +3,18 @@ Orders of function fields: extension """ -#***************************************************************************** -# Copyright (C) 2023 Kwankyu Lee <ekwankyu@gmail.com> +# **************************************************************************** +# Copyright (C) 2010 William Stein <wstein@gmail.com> +# 2011 Maarten Derickx <m.derickx.student@gmail.com> +# 2011 Julian Rueth <julian.rueth@gmail.com> +# 2017-2020 Kwankyu Lee +# 2019 Brent Baccala # # 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.arith.functions import lcm from sage.misc.cachefunc import cached_method diff --git a/src/sage/rings/function_field/order_rational.py b/src/sage/rings/function_field/order_rational.py index d421b64e67e..9a57abfafe5 100644 --- a/src/sage/rings/function_field/order_rational.py +++ b/src/sage/rings/function_field/order_rational.py @@ -2,14 +2,18 @@ Orders of function fields: rational """ -#***************************************************************************** -# Copyright (C) 2023 Kwankyu Lee <ekwankyu@gmail.com> +# **************************************************************************** +# Copyright (C) 2010 William Stein <wstein@gmail.com> +# 2011 Maarten Derickx <m.derickx.student@gmail.com> +# 2011 Julian Rueth <julian.rueth@gmail.com> +# 2017-2020 Kwankyu Lee +# 2019 Brent Baccala # # 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/ -#***************************************************************************** +# **************************************************************************** import sage.rings.abc diff --git a/src/sage/rings/function_field/place.py b/src/sage/rings/function_field/place.py index 0c61671bffa..a1f5f101475 100644 --- a/src/sage/rings/function_field/place.py +++ b/src/sage/rings/function_field/place.py @@ -47,7 +47,7 @@ """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2016-2022 Kwankyu Lee <ekwankyu@gmail.com> # 2019 Brent Baccala # 2021 Jonathan Kliem @@ -56,7 +56,7 @@ # 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.structure.unique_representation import UniqueRepresentation from sage.structure.parent import Parent diff --git a/src/sage/rings/function_field/place_polymod.py b/src/sage/rings/function_field/place_polymod.py index dcba75d7fd3..f3f7778b6aa 100644 --- a/src/sage/rings/function_field/place_polymod.py +++ b/src/sage/rings/function_field/place_polymod.py @@ -3,14 +3,16 @@ Places of function fields: extension """ -#***************************************************************************** -# Copyright (C) 2023 Kwankyu Lee <ekwankyu@gmail.com> +# **************************************************************************** +# Copyright (C) 2016-2022 Kwankyu Lee <ekwankyu@gmail.com> +# 2019 Brent Baccala +# 2021 Jonathan Kliem # # 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/ -#***************************************************************************** +# **************************************************************************** import sage from sage.arith.functions import lcm diff --git a/src/sage/rings/function_field/place_rational.py b/src/sage/rings/function_field/place_rational.py index 7a8acd440b6..c73d704f387 100644 --- a/src/sage/rings/function_field/place_rational.py +++ b/src/sage/rings/function_field/place_rational.py @@ -3,14 +3,16 @@ Places of function fields: rational """ -#***************************************************************************** -# Copyright (C) 2023 Kwankyu Lee <ekwankyu@gmail.com> +# **************************************************************************** +# Copyright (C) 2016-2022 Kwankyu Lee <ekwankyu@gmail.com> +# 2019 Brent Baccala +# 2021 Jonathan Kliem # # 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 .place import FunctionFieldPlace diff --git a/src/sage/rings/function_field/valuation.py b/src/sage/rings/function_field/valuation.py index 0db45fb4d54..90d5a2dae3e 100644 --- a/src/sage/rings/function_field/valuation.py +++ b/src/sage/rings/function_field/valuation.py @@ -140,6 +140,7 @@ developed for number fields in [Mac1936I]_ and [Mac1936II]_. """ + # **************************************************************************** # Copyright (C) 2016-2018 Julian Rüth <julian.rueth@fsfe.org> # @@ -148,6 +149,7 @@ # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** + from sage.structure.factory import UniqueFactory from sage.rings.rational_field import QQ from sage.misc.cachefunc import cached_method diff --git a/src/sage/rings/function_field/valuation_ring.py b/src/sage/rings/function_field/valuation_ring.py index 37d111df2c8..b9ab7d50fb9 100644 --- a/src/sage/rings/function_field/valuation_ring.py +++ b/src/sage/rings/function_field/valuation_ring.py @@ -55,6 +55,7 @@ - Kwankyu Lee (2017-04-30): initial version """ + # **************************************************************************** # Copyright (C) 2016-2019 Kwankyu Lee <ekwankyu@gmail.com> # From 12c04b899ff90a0739b7b59456c7815026426aaf Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sun, 18 Jun 2023 15:50:17 -0700 Subject: [PATCH 101/228] src/sage_setup/autogen/interpreters/__init__.py: Add doc and test --- .../autogen/interpreters/__init__.py | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/sage_setup/autogen/interpreters/__init__.py b/src/sage_setup/autogen/interpreters/__init__.py index 20153a3dd19..13b50e41d8c 100644 --- a/src/sage_setup/autogen/interpreters/__init__.py +++ b/src/sage_setup/autogen/interpreters/__init__.py @@ -165,7 +165,23 @@ def rebuild(dirname, force=False, interpreters=None, distribution=None): Check whether the interpreter and wrapper sources have been written since the last time this module was changed. If not, write them. - EXAMPLES:: + INPUT: + + - ``dirname`` -- name of the target directory for the generated sources + + - ``force`` -- boolean (default ``False``); if ``True``, ignore timestamps + and regenerate the sources unconditionally + + - ``interpreters`` -- an iterable of strings, or ``None`` (the default, + which means all interpreters); which interpreters to generate + + - ``distribution`` -- a string (the distribution name such as + ``"sagemath-categories"``) or ``None`` (the default, which means + the monolithic Sage library) + + EXAMPLES: + + Monolithic build:: sage: from sage_setup.autogen.interpreters import * sage: testdir = tmp_dir() @@ -175,6 +191,17 @@ def rebuild(dirname, force=False, interpreters=None, distribution=None): sage: with open(testdir + '/wrapper_el.pyx') as f: ....: f.readline() '# Automatically generated by ...\n' + + Modularized build:: + + sage: testdir = tmp_dir() + sage: rebuild(testdir, interpreters=['Element', 'Python'], + ....: distribution='sagemath-categories') + Building interpreters for fast_callable + -> First build of interpreters + sage: with open(testdir + '/all__sagemath_categories.py') as f: + ....: f.readline() + '# Automatically generated by ...\n' """ # This line will show up in "sage -b" (once per upgrade, not every time # you run it). From afd3be66e4da91bf1fcac046e48cac29386721ea Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sun, 18 Jun 2023 16:04:48 -0700 Subject: [PATCH 102/228] src/sage/ext/fast_callable.pyx: Add tests --- src/sage/ext/fast_callable.pyx | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/sage/ext/fast_callable.pyx b/src/sage/ext/fast_callable.pyx index 497a2262a2f..8719f0bdeb9 100644 --- a/src/sage/ext/fast_callable.pyx +++ b/src/sage/ext/fast_callable.pyx @@ -476,6 +476,8 @@ def _builder_and_stream(vars, domain): r""" Return a builder and a stream. + This is an internal function used only once, by :func:`fast_callable`. + INPUT: - ``vars`` -- a sequence of variable names @@ -485,12 +487,26 @@ def _builder_and_stream(vars, domain): OUTPUT: A :class:`Wrapper`, an class:`InstructionStream` - EXAMPLES: + EXAMPLES:: sage: from sage.ext.fast_callable import _builder_and_stream sage: _builder_and_stream(["x", "y"], ZZ) (<class 'sage.ext.interpreters.wrapper_el.Wrapper_el'>, <sage.ext.fast_callable.InstructionStream object at 0x...>) + sage: _builder_and_stream(["x", "y"], RR) # optional - sage.rings.real_mpfr + (<class 'sage.ext.interpreters.wrapper_rr.Wrapper_rr'>, + <sage.ext.fast_callable.InstructionStream object at 0x...>) + + Modularized test with sagemath-categories after :issue:`35095`, which has + (a basic version of) ``RDF`` but not the specialized interpreter for it. + In this case, the function falls back to using the :class:`Element` + interpreter:: + + sage: domain = RDF + sage: from sage.structure.element import Element as domain # optional - sage.modules + sage: _builder_and_stream(["x", "y"], domain) + (<class 'sage.ext.interpreters.wrapper_el.Wrapper_el'>, + <sage.ext.fast_callable.InstructionStream object at 0x...>) """ if isinstance(domain, sage.rings.abc.RealField): try: From d5812e485ae7a8fc6f37d07dec25c67f1e8f1e01 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sun, 18 Jun 2023 20:14:05 -0700 Subject: [PATCH 103/228] src/sage_setup/autogen/interpreters/__init__.py: Fix doctest --- src/sage_setup/autogen/interpreters/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage_setup/autogen/interpreters/__init__.py b/src/sage_setup/autogen/interpreters/__init__.py index 13b50e41d8c..75096d06b80 100644 --- a/src/sage_setup/autogen/interpreters/__init__.py +++ b/src/sage_setup/autogen/interpreters/__init__.py @@ -201,7 +201,7 @@ def rebuild(dirname, force=False, interpreters=None, distribution=None): -> First build of interpreters sage: with open(testdir + '/all__sagemath_categories.py') as f: ....: f.readline() - '# Automatically generated by ...\n' + '# Automatically generated by ...' """ # This line will show up in "sage -b" (once per upgrade, not every time # you run it). From 97135ad4b196272997896f86e8b5d4dd631c278b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Mon, 19 Jun 2023 08:20:54 -0700 Subject: [PATCH 104/228] src/sage_setup/autogen/interpreters/specs/rdf.py: Avoid gratuitous use of symbolics in doctest --- src/sage_setup/autogen/interpreters/specs/rdf.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/sage_setup/autogen/interpreters/specs/rdf.py b/src/sage_setup/autogen/interpreters/specs/rdf.py index 367c4cf2c2e..95894f8d6d2 100644 --- a/src/sage_setup/autogen/interpreters/specs/rdf.py +++ b/src/sage_setup/autogen/interpreters/specs/rdf.py @@ -61,14 +61,16 @@ def __init__(self): Make sure that pow behaves reasonably:: - sage: var('x,y') # optional - sage.symbolic - (x, y) - sage: ff = fast_callable(x^y, vars=[x,y], domain=RDF) # optional - sage.symbolic - sage: ff(1.5, 3) # optional - sage.symbolic + sage: from sage.ext.fast_callable import ExpressionTreeBuilder + sage: etb = ExpressionTreeBuilder(vars=('x','y')) + sage: x = etb.var('x') + sage: y = etb.var('y') + sage: ff = fast_callable(x^y, domain=RDF) + sage: ff(1.5, 3) 3.375 - sage: ff(-2, 3) # optional - sage.symbolic + sage: ff(-2, 3) -8.0 - sage: ff(-2, 1/3) # optional - sage.symbolic + sage: ff(-2, 1/3) Traceback (most recent call last): ... ValueError: negative number to a fractional power not real From 97eaac987528ed0a0532c3c8042ac874c7ffea91 Mon Sep 17 00:00:00 2001 From: Sebastian <seb.oehms@gmail.com> Date: Mon, 19 Jun 2023 18:39:06 +0200 Subject: [PATCH 105/228] 35668: pycodestyle fix --- src/sage/doctest/control.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index 7a7428bb78c..802f185d363 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -422,7 +422,6 @@ def __init__(self, options, args): feature_names = set([f.name for f in all_features() if f.is_optional()]) options.hide = options.hide.union(feature_names) - options.disabled_optional = set() if isinstance(options.optional, str): s = options.optional.lower() From f69c0024b362508262f3c0c738d62a61cca8e048 Mon Sep 17 00:00:00 2001 From: Miguel Marco <mmarco@unizar.es> Date: Mon, 19 Jun 2023 19:41:35 +0200 Subject: [PATCH 106/228] Add as_gca method --- src/sage/algebras/orlik_solomon.py | 32 ++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index fa39b6243a1..4a1ecea9a84 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -446,20 +446,16 @@ def degree_on_basis(self, m): """ return len(m) - def as_cdga(self): + def as_gca(self): """ - Return the commutative differential graded algebra corresponding to self, with - trivial differential. + Return the graded commutative algebra corresponding to self. EXAMPLES:: sage: H = hyperplane_arrangements.braid(3) sage: O = H.orlik_solomon_algebra(QQ) - sage: O.as_cdga() - Commutative Differential Graded Algebra with generators ('e0', 'e1', 'e2') in degrees (1, 1, 1) with relations [e0*e1 - e0*e2 + e1*e2] over Rational Field with differential: - e0 --> 0 - e1 --> 0 - e2 --> 0 + sage: O.as_gca() + Graded Commutative Algebra with generators ('e0', 'e1', 'e2') in degrees (1, 1, 1) with relations [e0*e1 - e0*e2 + e1*e2] over Rational Field """ from sage.algebras.commutative_dga import GradedCommutativeAlgebra gens = list(self.algebra_generators()) @@ -483,8 +479,24 @@ def rhs(l, m): return A.sum(P.coefficient(frozenset(p)) * AGbas[p] for p in bas2) I = A.ideal([AG[l]*AG[m] - rhs(l, m) for (l,m) in non_basis]) - B = A.quotient(I) - return B.cdg_algebra({}) + return A.quotient(I) + + def as_cdga(self): + """ + Return the commutative differential graded algebra corresponding to self, with + trivial differential. + + EXAMPLES:: + + sage: H = hyperplane_arrangements.braid(3) + sage: O = H.orlik_solomon_algebra(QQ) + sage: O.as_cdga() + Commutative Differential Graded Algebra with generators ('e0', 'e1', 'e2') in degrees (1, 1, 1) with relations [e0*e1 - e0*e2 + e1*e2] over Rational Field with differential: + e0 --> 0 + e1 --> 0 + e2 --> 0 + """ + return self.as_gca().cdg_algebra({}) class OrlikSolomonInvariantAlgebra(FiniteDimensionalInvariantModule): From d7f8a5dcda3e197cbb8ade14fa39091c8be47c96 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Mon, 19 Jun 2023 14:00:09 -0700 Subject: [PATCH 107/228] Replace imports from sage.geometry*all, update relint pattern --- src/.relint.yml | 2 +- src/sage/combinat/root_system/plot.py | 4 ++-- src/sage/combinat/root_system/root_lattice_realizations.py | 4 ++-- src/sage/misc/replace_dot_all.py | 2 +- src/sage/schemes/toric/fano_variety.py | 5 ++++- src/sage/schemes/toric/library.py | 4 +++- src/sage/schemes/toric/morphism.py | 3 ++- 7 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/.relint.yml b/src/.relint.yml index 7996583cb4f..d0eafb0d8fc 100644 --- a/src/.relint.yml +++ b/src/.relint.yml @@ -49,7 +49,7 @@ namespace package. Type import_statements("SOME_IDENTIFIER") to find a more specific import, or use 'sage --fiximports' to fix automatically in the source file. # Keep in sync with SAGE_ROOT/src/sage/misc/replace_dot_all.py - pattern: 'from\s+sage(|[.](arith|categories|combinat|crypto|databases|data_structures|dynamics|ext|game_theory|games|graphs|groups|interfaces|manifolds|matrix|matroids|misc|modules|monoids|numerical|probability|quadratic_forms|quivers|rings|sat|schemes|sets|stats|symbolic|tensor)[a-z0-9_.]*|[.]libs)[.]all\s+import' + pattern: 'from\s+sage(|[.](arith|categories|combinat|crypto|databases|data_structures|dynamics|ext|game_theory|games|geometry|graphs|groups|interfaces|manifolds|matrix|matroids|misc|modules|monoids|numerical|probability|quadratic_forms|quivers|rings|sat|schemes|sets|stats|symbolic|tensor)[a-z0-9_.]*|[.]libs)[.]all\s+import' # imports from .all are allowed in all.py; also allow in some modules that need sage.all filePattern: '(.*/|)(?!(all|benchmark|dev_tools|parsing|sage_eval))[^/.]*[.](py|pyx|pxi)$' diff --git a/src/sage/combinat/root_system/plot.py b/src/sage/combinat/root_system/plot.py index 354ae0ca741..56b127e2dac 100644 --- a/src/sage/combinat/root_system/plot.py +++ b/src/sage/combinat/root_system/plot.py @@ -916,7 +916,7 @@ def __init__(self, space, # Bounding box from sage.rings.real_mpfr import RR - from sage.geometry.polyhedron.all import Polyhedron + from sage.geometry.polyhedron.constructor import Polyhedron from itertools import product if bounding_box in RR: bounding_box = [[-bounding_box,bounding_box]] * self.dimension @@ -1383,7 +1383,7 @@ def cone(self, rays=[], lines=[], color="black", thickness=1, alpha=1, wireframe """ if color is None: return self.empty() - from sage.geometry.polyhedron.all import Polyhedron + from sage.geometry.polyhedron.constructor import Polyhedron # TODO: we currently convert lines into rays, which simplify a # bit the calculation of the intersection. But it would be # nice to benefit from the new ``lines`` option of Polyhedra diff --git a/src/sage/combinat/root_system/root_lattice_realizations.py b/src/sage/combinat/root_system/root_lattice_realizations.py index 84a7b847f43..c380c53b1db 100644 --- a/src/sage/combinat/root_system/root_lattice_realizations.py +++ b/src/sage/combinat/root_system/root_lattice_realizations.py @@ -2539,7 +2539,7 @@ def plot_hedron(self, **options): Line defined by 2 points: [(1.5, -0.5), (1.5, 0.5)] Point set defined by 8 point(s): [(-1.5, -0.5), (-1.5, 0.5), (-0.5, -1.5), (-0.5, 1.5), (0.5, -1.5), (0.5, 1.5), (1.5, -0.5), (1.5, 0.5)] """ - from sage.geometry.polyhedron.all import Polyhedron + from sage.geometry.polyhedron.constructor import Polyhedron plot_options = self.plot_parse_options(**options) if not self.cartan_type().is_finite(): raise ValueError("the Cartan type must be finite") @@ -3061,7 +3061,7 @@ def plot_mv_polytope(self, mv_polytope, mark_endpoints=True, sage: L.plot_mv_polytope(p) Graphics3d Object """ - from sage.geometry.polyhedron.all import Polyhedron + from sage.geometry.polyhedron.constructor import Polyhedron plot_options = self.plot_parse_options(**options) # Setup the shift for plotting diff --git a/src/sage/misc/replace_dot_all.py b/src/sage/misc/replace_dot_all.py index 8b48118aef6..ebb9a83dfff 100644 --- a/src/sage/misc/replace_dot_all.py +++ b/src/sage/misc/replace_dot_all.py @@ -72,7 +72,7 @@ # Keep in sync with SAGE_ROOT/src/.relint.yml (namespace_pkg_all_import) default_package_regex = (r"sage(" - r"|[.](arith|categories|combinat|crypto|databases|data_structures|dynamics|ext|game_theory|games|graphs|groups|interfaces|manifolds|matrix|matroids|misc|modules|monoids|numerical|probability|quadratic_forms|quivers|rings|sat|schemes|sets|stats|tensor)[a-z0-9_.]*|[.]libs" + r"|[.](arith|categories|combinat|crypto|databases|data_structures|dynamics|ext|game_theory|games|geometry|graphs|groups|interfaces|manifolds|matrix|matroids|misc|modules|monoids|numerical|probability|quadratic_forms|quivers|rings|sat|schemes|sets|stats|tensor)[a-z0-9_.]*|[.]libs" r")[.]all") diff --git a/src/sage/schemes/toric/fano_variety.py b/src/sage/schemes/toric/fano_variety.py index c7d05455d97..e3433787106 100644 --- a/src/sage/schemes/toric/fano_variety.py +++ b/src/sage/schemes/toric/fano_variety.py @@ -119,7 +119,10 @@ import re -from sage.geometry.all import Cone, FaceFan, Fan, LatticePolytope +from sage.geometry.cone import Cone +from sage.geometry.fan import FaceFan +from sage.geometry.fan import Fan +from sage.geometry.lattice_polytope import LatticePolytope from sage.misc.latex import latex from sage.misc.misc_c import prod from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing diff --git a/src/sage/schemes/toric/library.py b/src/sage/schemes/toric/library.py index c12c8e2c75e..8e1a9dfb732 100644 --- a/src/sage/schemes/toric/library.py +++ b/src/sage/schemes/toric/library.py @@ -42,7 +42,9 @@ from sage.matrix.constructor import Matrix as matrix from sage.matrix.special import identity_matrix -from sage.geometry.all import Fan, LatticePolytope, ToricLattice +from sage.geometry.fan import Fan +from sage.geometry.lattice_polytope import LatticePolytope +from sage.geometry.toric_lattice import ToricLattice from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.arith.misc import GCD as gcd diff --git a/src/sage/schemes/toric/morphism.py b/src/sage/schemes/toric/morphism.py index 7a304865825..5b494b07be6 100644 --- a/src/sage/schemes/toric/morphism.py +++ b/src/sage/schemes/toric/morphism.py @@ -370,7 +370,8 @@ from sage.misc.cachefunc import cached_method from sage.matrix.constructor import matrix, identity_matrix from sage.modules.free_module_element import vector -from sage.geometry.all import Cone, Fan +from sage.geometry.cone import Cone +from sage.geometry.fan import Fan from sage.schemes.generic.scheme import is_Scheme from sage.schemes.generic.morphism import ( From 25c193af54e58e106d30cb0be6d2a370d9d295bf Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Mon, 19 Jun 2023 14:48:11 -0700 Subject: [PATCH 108/228] src/sage/numerical/interactive_simplex_method.py: Replace .all import, add # optional - sage.plot --- .../numerical/interactive_simplex_method.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/sage/numerical/interactive_simplex_method.py b/src/sage/numerical/interactive_simplex_method.py index 26e332cd8d9..8ff00fb95a5 100644 --- a/src/sage/numerical/interactive_simplex_method.py +++ b/src/sage/numerical/interactive_simplex_method.py @@ -64,7 +64,7 @@ Since it has only two variables, we can solve it graphically:: - sage: P.plot() + sage: P.plot() # optional - sage.plot Graphics object consisting of 19 graphics primitives @@ -182,7 +182,7 @@ from copy import copy from sage.misc.abstract_method import abstract_method -from sage.geometry.all import Polyhedron +from sage.geometry.polyhedron.constructor import Polyhedron from sage.matrix.special import column_matrix from sage.matrix.special import identity_matrix from sage.matrix.constructor import Matrix as matrix @@ -1534,19 +1534,19 @@ def plot(self, *args, **kwds): sage: b = (1000, 1500) sage: c = (10, 5) sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") - sage: p = P.plot() - sage: p.show() + sage: p = P.plot() # optional - sage.plot + sage: p.show() # optional - sage.plot In this case the plot works better with the following axes ranges:: - sage: p = P.plot(0, 1000, 0, 1500) - sage: p.show() + sage: p = P.plot(0, 1000, 0, 1500) # optional - sage.plot + sage: p.show() # optional - sage.plot TESTS: We check that zero objective can be dealt with:: - sage: InteractiveLPProblem(A, b, (0, 0), ["C", "B"], variable_type=">=").plot() + sage: InteractiveLPProblem(A, b, (0, 0), ["C", "B"], variable_type=">=").plot() # optional - sage.plot Graphics object consisting of 8 graphics primitives """ FP = self.plot_feasible_set(*args, **kwds) @@ -1611,13 +1611,13 @@ def plot_feasible_set(self, xmin=None, xmax=None, ymin=None, ymax=None, sage: b = (1000, 1500) sage: c = (10, 5) sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") - sage: p = P.plot_feasible_set() - sage: p.show() + sage: p = P.plot_feasible_set() # optional - sage.plot + sage: p.show() # optional - sage.plot In this case the plot works better with the following axes ranges:: - sage: p = P.plot_feasible_set(0, 1000, 0, 1500) - sage: p.show() + sage: p = P.plot_feasible_set(0, 1000, 0, 1500) # optional - sage.plot + sage: p.show() # optional - sage.plot """ if self.n() != 2: raise ValueError("only problems with 2 variables can be plotted") From 5fd9c29cc841c296fcd9e80b8c2fdbd0b2465dca Mon Sep 17 00:00:00 2001 From: miguelmarco <mmarco@unizar.es> Date: Mon, 19 Jun 2023 23:49:57 +0200 Subject: [PATCH 109/228] Update src/sage/algebras/commutative_dga.py Co-authored-by: Travis Scrimshaw <clfrngrown@aol.com> --- src/sage/algebras/commutative_dga.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sage/algebras/commutative_dga.py b/src/sage/algebras/commutative_dga.py index 4369241f07f..17aa8429ede 100644 --- a/src/sage/algebras/commutative_dga.py +++ b/src/sage/algebras/commutative_dga.py @@ -2605,8 +2605,6 @@ def minimal_model(self, i=3, max_iterations=3, partial_result=False): b --> 0 c --> 0 Defn: (x1_0, x1_1, x1_2, y1_0, y1_1, y1_2) --> (a, b, c, 0, 0, 0) - - REFERENCES: - [Fel2001]_ From 31d1ba334838f39caca500cfc7bf68a7957f2959 Mon Sep 17 00:00:00 2001 From: miguelmarco <mmarco@unizar.es> Date: Mon, 19 Jun 2023 23:50:10 +0200 Subject: [PATCH 110/228] Update src/sage/algebras/orlik_solomon.py Co-authored-by: Travis Scrimshaw <clfrngrown@aol.com> --- src/sage/algebras/orlik_solomon.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index 4a1ecea9a84..9516814de15 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -447,8 +447,8 @@ def degree_on_basis(self, m): return len(m) def as_gca(self): - """ - Return the graded commutative algebra corresponding to self. + r""" + Return the graded commutative algebra corresponding to ``self``. EXAMPLES:: From 9e82ccab86b9ec5ac8d82f42c837d4dccf950484 Mon Sep 17 00:00:00 2001 From: miguelmarco <mmarco@unizar.es> Date: Mon, 19 Jun 2023 23:50:36 +0200 Subject: [PATCH 111/228] Update src/sage/algebras/orlik_solomon.py Co-authored-by: Travis Scrimshaw <clfrngrown@aol.com> --- src/sage/algebras/orlik_solomon.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index 9516814de15..fffd990b86d 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -455,7 +455,8 @@ def as_gca(self): sage: H = hyperplane_arrangements.braid(3) sage: O = H.orlik_solomon_algebra(QQ) sage: O.as_gca() - Graded Commutative Algebra with generators ('e0', 'e1', 'e2') in degrees (1, 1, 1) with relations [e0*e1 - e0*e2 + e1*e2] over Rational Field + Graded Commutative Algebra with generators ('e0', 'e1', 'e2') in degrees (1, 1, 1) + with relations [e0*e1 - e0*e2 + e1*e2] over Rational Field """ from sage.algebras.commutative_dga import GradedCommutativeAlgebra gens = list(self.algebra_generators()) From 9ca7024d024430c6697ed2dadb1cf0f3e87d024d Mon Sep 17 00:00:00 2001 From: Aram Dermenjian <aram.dermenjian.math@gmail.com> Date: Mon, 19 Jun 2023 23:51:29 +0100 Subject: [PATCH 112/228] Fix unicode data --- src/sage_docbuild/conf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage_docbuild/conf.py b/src/sage_docbuild/conf.py index 9b6b37480bf..2fdd1225382 100644 --- a/src/sage_docbuild/conf.py +++ b/src/sage_docbuild/conf.py @@ -621,7 +621,8 @@ def set_intersphinx_mappings(app, config): \DeclareUnicodeCharacter{2534}{+} % uh \DeclareUnicodeCharacter{253C}{+} % vh \DeclareUnicodeCharacter{2571}{/} % upper right to lower left - \DeclareUnicodeCharacter{2571}{\setminus} % upper left to lower right + \DeclareUnicodeCharacter{2572}{\ensuremath{\setminus}} % upper left to lower right + \DeclareUnicodeCharacter{2573}{X} % diagonal cross \DeclareUnicodeCharacter{25CF}{\ensuremath{\bullet}} % medium black circle \DeclareUnicodeCharacter{26AC}{\ensuremath{\circ}} % medium small white circle From 620a143d2ab26fea4d4ae4797f9fe2722dde64d4 Mon Sep 17 00:00:00 2001 From: Miguel Marco <mmarco@unizar.es> Date: Tue, 20 Jun 2023 01:22:35 +0200 Subject: [PATCH 113/228] Fix missing blankline --- src/sage/algebras/commutative_dga.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/algebras/commutative_dga.py b/src/sage/algebras/commutative_dga.py index 17aa8429ede..9f3b8c2c585 100644 --- a/src/sage/algebras/commutative_dga.py +++ b/src/sage/algebras/commutative_dga.py @@ -2605,6 +2605,7 @@ def minimal_model(self, i=3, max_iterations=3, partial_result=False): b --> 0 c --> 0 Defn: (x1_0, x1_1, x1_2, y1_0, y1_1, y1_2) --> (a, b, c, 0, 0, 0) + REFERENCES: - [Fel2001]_ From d8e5a89253d377a505b7eb3854ad720812148b01 Mon Sep 17 00:00:00 2001 From: Sebastian Oehms <47305845+soehms@users.noreply.github.com> Date: Tue, 20 Jun 2023 08:40:15 +0200 Subject: [PATCH 114/228] 35755: clean doctest k7sn Co-authored-by: Travis Scrimshaw <clfrngrown@aol.com> --- src/sage/knots/knotinfo.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index a6a84a11f00..dcb0f32b547 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -1865,9 +1865,8 @@ def link(self, use_item=db.columns().pd_notation, snappy=False): sage: K7 = KnotInfo.K7_2 sage: k7s = K7.link(snappy=True); k7s # optional - snappy <Link: 1 comp; 7 cross> - sage: K7.link(K7.items.name, snappy=True) # optional - snappy + sage: k7sn = K7.link(K7.items.name, snappy=True); k7sn # optional - snappy <Link 7_2: 1 comp; 7 cross> - sage: k7sn = _ # optional - snappy sage: k7s.sage_link().is_isotopic(k7sn) # optional - snappy False sage: k7snm = k7sn.sage_link().mirror_image() # optional - snappy From 5052f63dbcdcf208b831e1657b62f2610bbc1791 Mon Sep 17 00:00:00 2001 From: miguelmarco <mmarco@unizar.es> Date: Tue, 20 Jun 2023 10:04:09 +0200 Subject: [PATCH 115/228] Update src/sage/algebras/orlik_solomon.py Co-authored-by: Travis Scrimshaw <clfrngrown@aol.com> --- src/sage/algebras/orlik_solomon.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index fffd990b86d..cc1f9d6e1ca 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -483,9 +483,9 @@ def rhs(l, m): return A.quotient(I) def as_cdga(self): - """ - Return the commutative differential graded algebra corresponding to self, with - trivial differential. + r""" + Return the commutative differential graded algebra corresponding to ``self`` + with the trivial differential. EXAMPLES:: From 561d61130b52b74d4c03d6e8a0e97d8b6231f5ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Wed, 21 Jun 2023 08:47:46 +0200 Subject: [PATCH 116/228] fix suggested details --- src/sage/calculus/functional.py | 11 +++++------ src/sage/symbolic/expression.pyx | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/sage/calculus/functional.py b/src/sage/calculus/functional.py index 941e5790406..2f769a8f327 100644 --- a/src/sage/calculus/functional.py +++ b/src/sage/calculus/functional.py @@ -32,12 +32,13 @@ def simplify(f, algorithm="maxima", **kwds): r""" Simplify the expression `f`. - See the documentation of the :meth:`simplify` method of symbolic + See the documentation of the + :meth:`~sage.symbolic.expression.Expression.simplify` method of symbolic expressions for details on options. - EXAMPLES: We simplify the expression `i + x - x`. + EXAMPLES: - :: + We simplify the expression `i + x - x`:: sage: f = I + x - x; simplify(f) I @@ -45,9 +46,7 @@ def simplify(f, algorithm="maxima", **kwds): In fact, printing `f` yields the same thing - i.e., the simplified form. - Some simplifications are algorithm-specific : - - :: + Some simplifications are algorithm-specific:: sage: x, t = var("x, t") sage: ex = 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/2/(I*x + I*sqrt(x^2 - 1)) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 255a6cdb5e0..666ab8c3cda 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -10623,20 +10623,20 @@ cdef class Expression(Expression_abc): INPUT: - - ``algorithm`` - one of : + - ``algorithm`` -- one of : - - ``maxima`` : currently, sends the expression to - ``maxima`` and converts it back to Sage. + - ``maxima`` : (default) sends the expression to + ``maxima`` and converts it back to Sage - ``sympy`` : converts the expression to ``sympy``, simplifies it (passing any optional keyword(s)), and - converts the result to Sage. + converts the result to Sage - ``giac`` : converts the expression to ``giac``, - simplifies it, and converts the result to Sage. + simplifies it, and converts the result to Sage - ``fricas`` : converts the expression to ``fricas``, - simplifies it, and converts the result to Sage. + simplifies it, and converts the result to Sage .. SEEALSO:: @@ -10684,13 +10684,13 @@ cdef class Expression(Expression_abc): sage: expr.simplify(algorithm='sympy') 1/5*sqrt(5) - 1/5 """ - if algorithm == "maxima" : + if algorithm == "maxima": return self._parent(self._maxima_()) - if algorithm == "sympy" : + if algorithm == "sympy": return self._sympy_().simplify(**kwds)._sage_() - if algorithm == "giac" : + if algorithm == "giac": return self._giac_().simplify()._sage_() - if algorithm == "fricas" : + if algorithm == "fricas": return self._fricas_().simplify()._sage_() raise ValueError(f"algorithm {algorithm} unknown to simplify") From e81d6273dce10a6c800dd5c2550d8bb42640a5b7 Mon Sep 17 00:00:00 2001 From: OP5642 <ognjenpetrov@yahoo.com> Date: Wed, 21 Jun 2023 12:58:31 +0200 Subject: [PATCH 117/228] Fixed docstring format --- src/sage/topology/simplicial_complex.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/topology/simplicial_complex.py b/src/sage/topology/simplicial_complex.py index a714877a274..f91dd6da056 100644 --- a/src/sage/topology/simplicial_complex.py +++ b/src/sage/topology/simplicial_complex.py @@ -4952,7 +4952,7 @@ def bigraded_betti_number(self, a, b, base_ring=ZZ): def is_golod(self): r""" - Return whether `self` is Golod. + Return whether ``self`` is Golod. A simplicial complex is Golod if multiplication and all higher Massey operations in the associated Tor-algebra are trivial. This @@ -4977,7 +4977,7 @@ def is_golod(self): def is_minimally_non_golod(self): r""" - Return whether `self` is minimally non-Golod. + Return whether ``self`` is minimally non-Golod. If a simplicial complex itself is not Golod, but deleting each vertex gives us a full subcomplex that is Golod, then we say that a simplicial From 37bae2f8b1a2804dd4f9a5170eba8cbd55802f4a Mon Sep 17 00:00:00 2001 From: Sebastian <seb.oehms@gmail.com> Date: Tue, 20 Jun 2023 18:58:53 +0200 Subject: [PATCH 118/228] khovanov_knotjob_adaption initial --- build/pkgs/database_knotinfo/checksums.ini | 6 +- .../database_knotinfo/package-version.txt | 2 +- src/sage/databases/knotinfo_db.py | 86 +++++++++++- src/sage/knots/knotinfo.py | 132 ++++++++++++++---- 4 files changed, 195 insertions(+), 31 deletions(-) diff --git a/build/pkgs/database_knotinfo/checksums.ini b/build/pkgs/database_knotinfo/checksums.ini index 9b521522202..fe398cb7354 100644 --- a/build/pkgs/database_knotinfo/checksums.ini +++ b/build/pkgs/database_knotinfo/checksums.ini @@ -1,5 +1,5 @@ tarball=database_knotinfo-VERSION.tar.gz -sha1=16039d4e399efc78e4b1278527019f4bcdfdde13 -md5=3095993756f6b51d14c35adae5a75930 -cksum=2884062991 +sha1=1c6746a2742b5fb5c6a2803249dd6988d6ec1890 +md5=b2cd3295f179fbbde2a970ba7f0c3db4 +cksum=1079889953 upstream_url=https://pypi.io/packages/source/d/database_knotinfo/database_knotinfo-VERSION.tar.gz diff --git a/build/pkgs/database_knotinfo/package-version.txt b/build/pkgs/database_knotinfo/package-version.txt index eef52011e7f..603f3a6d51a 100644 --- a/build/pkgs/database_knotinfo/package-version.txt +++ b/build/pkgs/database_knotinfo/package-version.txt @@ -1 +1 @@ -2022.7.1 +2023.6.1 diff --git a/src/sage/databases/knotinfo_db.py b/src/sage/databases/knotinfo_db.py index 91255c564c2..2dba694604d 100644 --- a/src/sage/databases/knotinfo_db.py +++ b/src/sage/databases/knotinfo_db.py @@ -811,6 +811,13 @@ def _test_database(self, **options): 'kauffman_polynomial': ['Kauffman', KnotInfoColumnTypes.KnotsAndLinks], 'khovanov_polynomial': ['Khovanov', KnotInfoColumnTypes.KnotsAndLinks], 'khovanov_torsion_polynomial': ['Khovanov Torsion', KnotInfoColumnTypes.OnlyKnots], + 'khovanov_unreduced_integral_polynomial': ['KH Unred Z Poly', KnotInfoColumnTypes.OnlyKnots], + 'khovanov_reduced_integral_polynomial': ['KH Red Z Poly', KnotInfoColumnTypes.OnlyKnots], + 'khovanov_reduced_rational_polynomial': ['KH Red Q Poly', KnotInfoColumnTypes.OnlyKnots], + 'khovanov_reduced_mod2_polynomial': ['KH Red Mod2 Poly', KnotInfoColumnTypes.OnlyKnots], + 'khovanov_odd_integral_polynomial': ['KH Odd Red Z Poly', KnotInfoColumnTypes.OnlyKnots], + 'khovanov_odd_rational_polynomial': ['KH Odd Red Q Poly', KnotInfoColumnTypes.OnlyKnots], + 'khovanov_odd_mod2_polynomial': ['KH Red Odd Mod2 Poly', KnotInfoColumnTypes.OnlyKnots], 'determinant': ['Determinant', KnotInfoColumnTypes.KnotsAndLinks], 'positive': ['Positive', KnotInfoColumnTypes.OnlyKnots], 'fibered': ['Fibered', KnotInfoColumnTypes.OnlyKnots], @@ -1133,5 +1140,82 @@ def _test_database(self, **options): 'Q^(-9)t^(-3)+Q^(-7)t^(-2)+Q^(-5)t^(-1)+Q^(-3)+Qt^2', 'Q^(-5)t^(-2)+Q^(-3)t^(-1)+Q^(-1)+Qt+Q^3t^2+Q^5t^3', 'Q^(-19)t^(-6)+Q^(-15)t^(-4)+Q^(-11)t^(-2)', - 'Q^(-15)t^(-6)+Q^(-11)t^(-4)+Q^(-9)t^(-3)+Q^(-7)t^(-2)+Q^(-5)t^(-1)'] + 'Q^(-15)t^(-6)+Q^(-11)t^(-4)+Q^(-9)t^(-3)+Q^(-7)t^(-2)+Q^(-5)t^(-1)'], + dc.khovanov_unreduced_integral_polynomial: [ + '', + 'q + q^(3) + t^(2) q^(5) + t^(3) q^(9) + t^(3) q^(7) T^(2)', + 't^(-2) q^(-5) + t^(-1) q^(-1) + q^(-1) + q + t q + t^(2) q^(5) + t^(-1) q^(-3) T^(2) + t^(2) q^(3) T^(2)', + 'q^(3) + q^(5) + t^(2) q^(7) + t^(3) q^(11) + t^(4) q^(11) + t^(5) q^(15) + t^(3) q^(9) T^(2) + t^(5) q^(13) T^(2)', + 'q + q^(3) + t q^(3) + t^(2) q^(5) + t^(2) q^(7) + t^(3) q^(9) + t^(4) q^(9) + t^(5) q^(13) + t^(2) q^(5) T^(2) + t^(3) q^(7) T^(2) + t^(5) q^(11) T^(2)', + 't^(-2) q^(-5) + t^(-1) q^(-1) + 2 q^(-1) + q + t q + t q^(3) + t^(2) q^(5) + t^(3) q^(5) + t^(4) q^(9) + t^(-1) q^(-3) T^(2) + t q T^(2) + t^(2) q^(3) T^(2) + t^(4) q^(7) T^(2)', + 't^(-2) q^(-3) + t^(-1) q + 2 q + q^(3) + t q^(3) + t q^(5) + t^(2) q^(5) + t^(2) q^(7) + t^(3) q^(7) + t^(3) q^(9) + t^(4) q^(11) + t^(-1) q^(-1) T^(2) + t q^(3) T^(2) + t^(2) q^(5) T^(2) + t^(3) q^(7) T^(2) + t^(4) q^(9) T^(2)', + 't^(-3) q^(-7) + t^(-2) q^(-5) + t^(-2) q^(-3) + t^(-1) q^(-3) + t^(-1) q^(-1) + 2 q^(-1) + 2 q + t q + t q^(3) + t^(2) q^(3) + t^(2) q^(5) + t^(3) q^(7) + t^(-2) q^(-5) T^(2) + t^(-1) q^(-3) T^(2) + q^(-1) T^(2) + t q T^(2) + t^(2) q^(3) T^(2) + t^(3) q^(5) T^(2)', + 'q^(5) + q^(7) + t^(2) q^(9) + t^(3) q^(13) + t^(4) q^(13) + t^(5) q^(17) + t^(6) q^(17) + t^(7) q^(21) + t^(3) q^(11) T^(2) + t^(5) q^(15) T^(2) + t^(7) q^(19) T^(2)', + 'q + q^(3) + t q^(3) + t^(2) q^(5) + t^(2) q^(7) + t^(3) q^(7) + t^(3) q^(9) + t^(4) q^(9) + t^(4) q^(11) + t^(5) q^(13) + t^(6) q^(13) + t^(7) q^(17) + t^(2) q^(5) T^(2) + t^(3) q^(7) T^(2) + t^(4) q^(9) T^(2) + t^(5) q^(11) T^(2) + t^(7) q^(15) T^(2)'], + dc.khovanov_reduced_integral_polynomial: [ + '', + 'q^(2) + t^(2) q^(6) + t^(3) q^(8)', + 't^(-2) q^(-4) + t^(-1) q^(-2) + 1 + t q^(2) + t^(2) q^(4)', + 'q^(4) + t^(2) q^(8) + t^(3) q^(10) + t^(4) q^(12) + t^(5) q^(14)', + 'q^(2) + t q^(4) + 2 t^(2) q^(6) + t^(3) q^(8) + t^(4) q^(10) + t^(5) q^(12)', + 't^(-2) q^(-4) + t^(-1) q^(-2) + 2 + 2 t q^(2) + t^(2) q^(4) + t^(3) q^(6) + t^(4) q^(8)', + 't^(-2) q^(-2) + t^(-1) + 2 q^(2) + 2 t q^(4) + 2 t^(2) q^(6) + 2 t^(3) q^(8) + t^(4) q^(10)', + 't^(-3) q^(-6) + 2 t^(-2) q^(-4) + 2 t^(-1) q^(-2) + 3 + 2 t q^(2) + 2 t^(2) q^(4) + t^(3) q^(6)', + 'q^(6) + t^(2) q^(10) + t^(3) q^(12) + t^(4) q^(14) + t^(5) q^(16) + t^(6) q^(18) + t^(7) q^(20)', + 'q^(2) + t q^(4) + 2 t^(2) q^(6) + 2 t^(3) q^(8) + 2 t^(4) q^(10) + t^(5) q^(12) + t^(6) q^(14) + t^(7) q^(16)'], + dc.khovanov_reduced_rational_polynomial: [ + '', + ' q^(2) + t^(2) q^(6) + t^(3) q^(8)', + 't^(-2) q^(-4) + t^(-1) q^(-2) + 1 + t q^(2) + t^(2) q^(4)', + ' q^(4) + t^(2) q^(8) + t^(3) q^(10) + t^(4) q^(12) + t^(5) q^(14)', + ' q^(2) + t q^(4) + 2 t^(2) q^(6) + t^(3) q^(8) + t^(4) q^(10) + t^(5) q^(12)', + 't^(-2) q^(-4) + t^(-1) q^(-2) + 2 + 2 t q^(2) + t^(2) q^(4) + t^(3) q^(6) + t^(4) q^(8)', + 't^(-2) q^(-2) + t^(-1) + 2 q^(2) + 2 t q^(4) + 2 t^(2) q^(6) + 2 t^(3) q^(8) + t^(4) q^(10)', + 't^(-3) q^(-6) + 2 t^(-2) q^(-4) + 2 t^(-1) q^(-2) + 3 + 2 t q^(2) + 2 t^(2) q^(4) + t^(3) q^(6)', + ' q^(6) + t^(2) q^(10) + t^(3) q^(12) + t^(4) q^(14) + t^(5) q^(16) + t^(6) q^(18) + t^(7) q^(20)', + ' q^(2) + t q^(4) + 2 t^(2) q^(6) + 2 t^(3) q^(8) + 2 t^(4) q^(10) + t^(5) q^(12) + t^(6) q^(14) + t^(7) q^(16)'], + dc.khovanov_reduced_mod2_polynomial: [ + '', + ' q^(2) + t^(2) q^(6) + t^(3) q^(8)', + 't^(-2) q^(-4) + t^(-1) q^(-2) + 1 + t q^(2) + t^(2) q^(4)', + ' q^(4) + t^(2) q^(8) + t^(3) q^(10) + t^(4) q^(12) + t^(5) q^(14)', + ' q^(2) + t q^(4) + 2 t^(2) q^(6) + t^(3) q^(8) + t^(4) q^(10) + t^(5) q^(12)', + 't^(-2) q^(-4) + t^(-1) q^(-2) + 2 + 2 t q^(2) + t^(2) q^(4) + t^(3) q^(6) + t^(4) q^(8)', + 't^(-2) q^(-2) + t^(-1) + 2 q^(2) + 2 t q^(4) + 2 t^(2) q^(6) + 2 t^(3) q^(8) + t^(4) q^(10)', + 't^(-3) q^(-6) + 2 t^(-2) q^(-4) + 2 t^(-1) q^(-2) + 3 + 2 t q^(2) + 2 t^(2) q^(4) + t^(3) q^(6)', + ' q^(6) + t^(2) q^(10) + t^(3) q^(12) + t^(4) q^(14) + t^(5) q^(16) + t^(6) q^(18) + t^(7) q^(20)', + ' q^(2) + t q^(4) + 2 t^(2) q^(6) + 2 t^(3) q^(8) + 2 t^(4) q^(10) + t^(5) q^(12) + t^(6) q^(14) + t^(7) q^(16)'], + dc.khovanov_odd_integral_polynomial: [ + '', + 'q^(2) + t^(2) q^(6) + t^(3) q^(8)', + 't^(-2) q^(-4) + t^(-1) q^(-2) + 1 + t q^(2) + t^(2) q^(4)', + 'q^(4) + t^(2) q^(8) + t^(3) q^(10) + t^(4) q^(12) + t^(5) q^(14)', + 'q^(2) + t q^(4) + 2 t^(2) q^(6) + t^(3) q^(8) + t^(4) q^(10) + t^(5) q^(12)', + 't^(-2) q^(-4) + t^(-1) q^(-2) + 2 + 2 t q^(2) + t^(2) q^(4) + t^(3) q^(6) + t^(4) q^(8)', + 't^(-2) q^(-2) + t^(-1) + 2 q^(2) + 2 t q^(4) + 2 t^(2) q^(6) + 2 t^(3) q^(8) + t^(4) q^(10)', + 't^(-3) q^(-6) + 2 t^(-2) q^(-4) + 2 t^(-1) q^(-2) + 3 + 2 t q^(2) + 2 t^(2) q^(4) + t^(3) q^(6)', + 'q^(6) + t^(2) q^(10) + t^(3) q^(12) + t^(4) q^(14) + t^(5) q^(16) + t^(6) q^(18) + t^(7) q^(20)', + 'q^(2) + t q^(4) + 2 t^(2) q^(6) + 2 t^(3) q^(8) + 2 t^(4) q^(10) + t^(5) q^(12) + t^(6) q^(14) + t^(7) q^(16)'], + dc.khovanov_odd_rational_polynomial: [ + '', + ' q^(2) + t^(2) q^(6) + t^(3) q^(8)', + 't^(-2) q^(-4) + t^(-1) q^(-2) + 1 + t q^(2) + t^(2) q^(4)', + ' q^(4) + t^(2) q^(8) + t^(3) q^(10) + t^(4) q^(12) + t^(5) q^(14)', + ' q^(2) + t q^(4) + 2 t^(2) q^(6) + t^(3) q^(8) + t^(4) q^(10) + t^(5) q^(12)', + 't^(-2) q^(-4) + t^(-1) q^(-2) + 2 + 2 t q^(2) + t^(2) q^(4) + t^(3) q^(6) + t^(4) q^(8)', + 't^(-2) q^(-2) + t^(-1) + 2 q^(2) + 2 t q^(4) + 2 t^(2) q^(6) + 2 t^(3) q^(8) + t^(4) q^(10)', + 't^(-3) q^(-6) + 2 t^(-2) q^(-4) + 2 t^(-1) q^(-2) + 3 + 2 t q^(2) + 2 t^(2) q^(4) + t^(3) q^(6)', + ' q^(6) + t^(2) q^(10) + t^(3) q^(12) + t^(4) q^(14) + t^(5) q^(16) + t^(6) q^(18) + t^(7) q^(20)', + ' q^(2) + t q^(4) + 2 t^(2) q^(6) + 2 t^(3) q^(8) + 2 t^(4) q^(10) + t^(5) q^(12) + t^(6) q^(14) + t^(7) q^(16)'], + dc.khovanov_odd_mod2_polynomial: [ + '', + ' q^(2) + t^(2) q^(6) + t^(3) q^(8)', + 't^(-2) q^(-4) + t^(-1) q^(-2) + 1 + t q^(2) + t^(2) q^(4)', + ' q^(4) + t^(2) q^(8) + t^(3) q^(10) + t^(4) q^(12) + t^(5) q^(14)', + ' q^(2) + t q^(4) + 2 t^(2) q^(6) + t^(3) q^(8) + t^(4) q^(10) + t^(5) q^(12)', + 't^(-2) q^(-4) + t^(-1) q^(-2) + 2 + 2 t q^(2) + t^(2) q^(4) + t^(3) q^(6) + t^(4) q^(8)', + 't^(-2) q^(-2) + t^(-1) + 2 q^(2) + 2 t q^(4) + 2 t^(2) q^(6) + 2 t^(3) q^(8) + t^(4) q^(10)', + 't^(-3) q^(-6) + 2 t^(-2) q^(-4) + 2 t^(-1) q^(-2) + 3 + 2 t q^(2) + 2 t^(2) q^(4) + t^(3) q^(6)', + ' q^(6) + t^(2) q^(10) + t^(3) q^(12) + t^(4) q^(14) + t^(5) q^(16) + t^(6) q^(18) + t^(7) q^(20)', + ' q^(2) + t q^(4) + 2 t^(2) q^(6) + 2 t^(3) q^(8) + 2 t^(4) q^(10) + t^(5) q^(12) + t^(6) q^(14) + t^(7) q^(16)'] } diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index 2b8ddf86ff3..b15b82ac74d 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -1683,7 +1683,7 @@ def conway_polynomial(self, var='t', original=False): return R(eval_knotinfo(conway_polynomial, locals=lc)) @cached_method - def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False): + def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False, reduced=False, odd=False, KhoHo=False): r""" Return the Khovanov polynomial according to the value of column ``khovanov_polynomial`` for this knot or link as an instance of @@ -1695,8 +1695,16 @@ def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False): - ``var2`` -- (default: ``'t'``) the second variable - ``base_ring`` -- (default: ``ZZ``) the ring of the polynomial's coefficients - - ``original`` -- boolean (optional, default ``False``) if set to + - ``original`` -- boolean (default: ``False``) if set to ``True`` the original table entry is returned as a string + - ``reduced`` -- boolean (default: ``False``) if set to ``True`` + the reduced version of the homology is used. + - ``odd`` -- boolean (default: ``False``) if set to ``True`` + the odd version of the homology is used. + - ``KhoHo`` -- boolean (default: ``False``for knots and ``True`` + for multi-component links) if set to ``True`` the data calculated + using `KhoHo <https://github.com/AShumakovitch/KhoHo>`__ is used + (see the note below). OUTPUT: @@ -1706,23 +1714,25 @@ def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False): .. NOTE :: - The data used here were calculated with the program - `KhoHo <https://github.com/AShumakovitch/KhoHo>`__. They are no longer - visible on the website as of October 30, 2022. Instead, data - computed with `KnotJob <https://www.maths.dur.ac.uk/users/dirk.schuetz/knotjob.html>`__ - are now displayed. The latter program is more accurate in terms of - orientation and reflection as it is based on ``PD`` code. - - Even if they are not visible on the website, the data produced by - ``KhoHo`` are still available in the database. But maybe this will be - discontinued (check out the `Python wrapper <https://github.com/soehms/database_knotinfo#readme>`__ for updated information). - This interface will be adapted to the changes in an upcoming - release. - - Since the results of ``KhoHo`` were computed using the ``DT`` notation, - the Khovanov polynomial returned by this method belongs to the + The data used for multi-component links were calculated with the program + `KhoHo <https://github.com/AShumakovitch/KhoHo>`__. These can still be + used for knots by setting the optional argument ``KhoHo`` to ``True``, + even though they will no longer be visible on the Knot website as of + October 30, 2022. Otherwise, for knots data calculated with + `KnotJob <https://www.maths.dur.ac.uk/users/dirk.schuetz/knotjob.html>`__ + are used. The latter program is more accurate in terms of orientation + and reflection as it is based on ``PD`` code. + + Note that in the future columns that are not visible on the web page may + also be removed in the database (see the + `Python wrapper <https://github.com/soehms/database_knotinfo#readme>`__ + for updated information). Therefore, the ``KhoHo`` option cannot be + guaranteed to work after upgrading the ``database_knotinfo``-SPKG. + + Furthermore, since the results of ``KhoHo`` were computed using the ``DT`` + notation, the Khovanov polynomial returned by this option belongs to the mirror image of the given knot for a `list of 140 exceptions - <https://raw.githubusercontent.com/soehms/database_knotinfo/ main /hints/list_of_mirrored_khovanov_polynonmial.txt>`__. + <https://raw.githubusercontent.com/soehms/database_knotinfo/main/hints/list_of_mirrored_khovanov_polynonmial.txt>`__. EXAMPLES:: @@ -1737,6 +1747,35 @@ def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False): sage: L = KnotInfo.L5a1_0 sage: Lk = L.khovanov_polynomial(); Lk q^4*t^2 + t + 2 + 2*q^-2 + q^-2*t^-1 + q^-4*t^-2 + q^-6*t^-2 + q^-8*t^-3 + sage: L.khovanov_polynomial(original=True) + '2 + 2/q^2 + 1/(q^8*t^3) + 1/(q^6*t^2) + 1/(q^4*t^2) + 1/(q^2*t) + t + q^4*t^2' + + Obtaining the reduced homology (for knots only):: + + sage: Kkr = K.khovanov_polynomial(reduced=True); Kkr + q^6*t^3 + 2*q^4*t^2 + 2*q^2*t + 3 + 2*q^-2*t^-1 + 2*q^-4*t^-2 + q^-6*t^-3 + sage: K.khovanov_polynomial(base_ring=QQ, reduced=True) == Kkr + True + sage: Kkr2 = K.khovanov_polynomial(base_ring=GF(2), reduced=True); Kkr2 + q^6*t^3 + 1 + q^-6*t^-3 + sage: KnotInfo.K8_19.inject() # optional database_knotinfo + Defining K8_19 + sage: K8kr = K8_19.khovanov_polynomial(reduced=True); K8kr # optional database_knotinfo + q^16*t^5 + q^12*t^4 + q^12*t^3 + q^10*t^2 + q^6 + + Obtaining the odd Khovanov homology (for knots only):: + + sage: K.khovanov_polynomial(odd=True) == Kkr + True + sage: K.khovanov_polynomial(base_ring=QQ, odd=True) == Kkr + True + sage: K.khovanov_polynomial(base_ring=GF(2), odd=True) == Kkr2 + True + sage: K8ko = K8_19.khovanov_polynomial(odd=True); K8ko # optional database_knotinfo + q^16*t^5 + q^10*t^2 + q^6 + sage: K8kr == K8ko + False + Comparision to Sage's results:: @@ -1746,8 +1785,42 @@ def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False): True sage: Lk == L.link().khovanov_polynomial() True + + REFERENCES: + + - :wikipedia:`Khovanov_homology` + - :wikipedia:`Reduced_homology` + - [ORS2013]_ """ - khovanov_polynomial = self[self.items.khovanov_polynomial] + ch = base_ring.characteristic() + integral = ch == 0 and base_ring.is_field() + if not self.is_knot(): + # KnotJob calculated results only available for knots + KhoHo = True + if KhoHo: + # use the old results obtained by the KhoHo software + khovanov_polynomial = self[self.items.khovanov_polynomial] + else: + if reduced: + if integral: + khovanov_polynomial = self[self.items.khovanov_reduced_integral_polynomial] + elif ch == 0: + khovanov_polynomial = self[self.items.khovanov_reduced_rational_polynomial] + elif ch == 2: + khovanov_polynomial = self[self.items.khovanov_reduced_mod2_polynomial] + else: + raise ValueError('Characteristic %s of base ring is not supported' % ch) + elif odd: + if integral: + khovanov_polynomial = self[self.items.khovanov_odd_integral_polynomial] + elif ch == 0: + khovanov_polynomial = self[self.items.khovanov_odd_rational_polynomial] + elif ch == 2: + khovanov_polynomial = self[self.items.khovanov_odd_mod2_polynomial] + else: + raise ValueError('Characteristic %s of base ring is not supported' % ch) + else: + khovanov_polynomial = self[self.items.khovanov_unreduced_integral_polynomial] if original: return khovanov_polynomial @@ -1757,15 +1830,18 @@ def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False): R = LaurentPolynomialRing(base_ring, var_names) if not khovanov_polynomial and self.crossing_number() == 0: - return R({(1, 0): 1, (-1, 0): 1}) + if reduced or odd: + return R.one() + else: + return R({(1, 0): 1, (-1, 0): 1}) - ch = base_ring.characteristic() if ch == 2: if not self.is_knot(): raise NotImplementedError('Khovanov polynomial available only for knots in characteristic 2') - khovanov_torsion_polynomial = self[self.items.khovanov_torsion_polynomial] - khovanov_torsion_polynomial = khovanov_torsion_polynomial.replace('Q', 'q') - khovanov_polynomial = '%s + %s' % (khovanov_polynomial, khovanov_torsion_polynomial) + if KhoHo: + khovanov_torsion_polynomial = self[self.items.khovanov_torsion_polynomial] + khovanov_torsion_polynomial = khovanov_torsion_polynomial.replace('Q', 'q') + khovanov_polynomial = '%s + %s' % (khovanov_polynomial, khovanov_torsion_polynomial) if not khovanov_polynomial: # given just for links with less than 12 crossings @@ -1774,14 +1850,18 @@ def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False): from sage.repl.preparse import implicit_mul # since implicit_mul does not know about the choice of variable names # we have to insert * between them separately - for i in ['q', 't',')']: - for j in ['q', 't', '(']: + for i in ['q', 't', 'T', ')']: + for j in ['q', 't', 'T', '(']: khovanov_polynomial = khovanov_polynomial.replace('%s%s' % (i, j), '%s*%s' % (i, j)) khovanov_polynomial = implicit_mul(khovanov_polynomial) gens = R.gens_dict() lc = {} lc['q'] = gens[var1] lc['t'] = gens[var2] + if ch == 2: + lc['T'] = 1 + else: + lc['T'] = 0 return R(eval_knotinfo(khovanov_polynomial, locals=lc)) From 070fc2457d656952402826e69233605565c8b11d Mon Sep 17 00:00:00 2001 From: Sebastian Oehms <seb.oehms@gmail.com> Date: Tue, 20 Jun 2023 22:43:25 +0200 Subject: [PATCH 119/228] 35800: add missing citation --- src/doc/en/reference/references/index.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index 3ba888945d7..9551f10f0d3 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -4946,6 +4946,11 @@ REFERENCES: Electronic Journal of Linear Algebra, 34:444-458, 2018, :doi:`10.13001/1081-3810.3782`. +.. [ORS2013] Peter Ozsvath, Jacob Rasmussen, Zoltan Szabo, + *Odd Khovanov homology*, + Algebraic & Geometric Topology 13 (2013) 1465–1488, + :doi:`10.2140/agt.2013.13.1465`. + .. [ORV] Grigori Olshanski, Amitai Regev, Anatoly Vershik, *Frobenius-Schur functions*, :arxiv:`math/0110077v1`. From a8b443a0c338723fa2adc2363b27e360da8dcf57 Mon Sep 17 00:00:00 2001 From: Sebastian Oehms <seb.oehms@gmail.com> Date: Wed, 21 Jun 2023 06:20:01 +0200 Subject: [PATCH 120/228] 35800: add missing "optional"-tag --- src/sage/knots/knotinfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index b15b82ac74d..1d9fe7a505d 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -1773,7 +1773,7 @@ def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False, True sage: K8ko = K8_19.khovanov_polynomial(odd=True); K8ko # optional database_knotinfo q^16*t^5 + q^10*t^2 + q^6 - sage: K8kr == K8ko + sage: K8kr == K8ko # optional database_knotinfo False From b9ce1ff13dc9fda18e0e3504477fb853c53b618f Mon Sep 17 00:00:00 2001 From: Sebastian <seb.oehms@gmail.com> Date: Wed, 21 Jun 2023 08:01:19 +0200 Subject: [PATCH 121/228] 35800: add missing white-space in RST format --- src/sage/knots/knotinfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index 1d9fe7a505d..b344d20a9fe 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -1701,7 +1701,7 @@ def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False, the reduced version of the homology is used. - ``odd`` -- boolean (default: ``False``) if set to ``True`` the odd version of the homology is used. - - ``KhoHo`` -- boolean (default: ``False``for knots and ``True`` + - ``KhoHo`` -- boolean (default: ``False`` for knots and ``True`` for multi-component links) if set to ``True`` the data calculated using `KhoHo <https://github.com/AShumakovitch/KhoHo>`__ is used (see the note below). From 9874e641be85a4729da0728cca5315af8a891b98 Mon Sep 17 00:00:00 2001 From: Sebastian <seb.oehms@gmail.com> Date: Wed, 21 Jun 2023 18:57:13 +0200 Subject: [PATCH 122/228] 35800: make codecov happy --- src/sage/knots/knotinfo.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index b344d20a9fe..b0aedde6e5e 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -1786,6 +1786,29 @@ def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False, sage: Lk == L.link().khovanov_polynomial() True + TESTS: + + sage: KnotInfo.K0_1.inject() + Defining K0_1 + sage: K0_1.khovanov_polynomial() + q + q^-1 + sage: K0_1.khovanov_polynomial(reduced=True) + 1 + sage: K0_1.khovanov_polynomial(odd=True) + 1 + sage: K0_1.khovanov_polynomial(base_ring=GF(3), reduced=True) + Traceback (most recent call last): + ... + ValueError: Characteristic 3 of base ring is not valid + sage: K0_1.khovanov_polynomial(base_ring=GF(3), odd=True) + Traceback (most recent call last): + ... + ValueError: Characteristic 3 of base ring is not valid + sage: L.khovanov_polynomial(base_ring=GF(2)) + Traceback (most recent call last): + ... + NotImplementedError: Khovanov polynomial available only for knots in characteristic 2 + REFERENCES: - :wikipedia:`Khovanov_homology` @@ -1809,7 +1832,7 @@ def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False, elif ch == 2: khovanov_polynomial = self[self.items.khovanov_reduced_mod2_polynomial] else: - raise ValueError('Characteristic %s of base ring is not supported' % ch) + raise ValueError('Characteristic %s of base ring is not valid' % ch) elif odd: if integral: khovanov_polynomial = self[self.items.khovanov_odd_integral_polynomial] @@ -1818,7 +1841,7 @@ def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False, elif ch == 2: khovanov_polynomial = self[self.items.khovanov_odd_mod2_polynomial] else: - raise ValueError('Characteristic %s of base ring is not supported' % ch) + raise ValueError('Characteristic %s of base ring is not valid' % ch) else: khovanov_polynomial = self[self.items.khovanov_unreduced_integral_polynomial] From e057b27343f491fff228f840c04e7624e9a1bf03 Mon Sep 17 00:00:00 2001 From: David Einstein <deinst@gmail.com> Date: Wed, 21 Jun 2023 23:00:06 -0400 Subject: [PATCH 123/228] Mind the GAP The generators for the classes Tuples and UnorderedTuples used the GAP for generating Tuples. This could be done much more simply using itertools. Also fixed a bug where if the underlying list had multiple identical elements then redundant tuples were generated. --- src/sage/combinat/tuple.py | 39 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/src/sage/combinat/tuple.py b/src/sage/combinat/tuple.py index 7e7f85c61ef..254ce7f5ff4 100644 --- a/src/sage/combinat/tuple.py +++ b/src/sage/combinat/tuple.py @@ -16,12 +16,13 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.libs.gap.libgap import libgap +#from sage.libs.gap.libgap import libgap +from sage.arith.misc import binomial from sage.rings.integer_ring import ZZ from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets - +from itertools import product, combinations_with_replacement class Tuples(Parent, UniqueRepresentation): """ @@ -75,7 +76,7 @@ def __init__(self, S, k): """ self.S = S self.k = k - self._index_list = [S.index(s) for s in S] + self._index_list = list(dict.fromkeys(S.index(s) for s in S)) category = FiniteEnumeratedSets() Parent.__init__(self, category=category) @@ -105,22 +106,9 @@ def __iter__(self): ['i', 'i'], ['n', 'i'], ['s', 'n'], ['t', 'n'], ['e', 'n'], ['i', 'n'], ['n', 'n']] """ - S = self.S - k = self.k - import copy - if k <= 0: - yield [] - return - if k == 1: - for x in S: - yield [x] - return - - for s in S: - for x in Tuples(S, k - 1): - y = copy.copy(x) - y.append(s) - yield y + + for p in product(self._index_list, repeat=self.k): + yield [self.S[i] for i in reversed(p)] def cardinality(self): """ @@ -133,7 +121,7 @@ def cardinality(self): sage: Tuples(S,2).cardinality() 25 """ - return ZZ(libgap.NrTuples(self._index_list, ZZ(self.k))) + return ZZ(len(self._index_list)).__pow__(self.k) Tuples_sk = Tuples @@ -178,7 +166,7 @@ def __init__(self, S, k): """ self.S = S self.k = k - self._index_list = [S.index(s) for s in S] + self._index_list = list(dict.fromkeys(S.index(s) for s in S)) category = FiniteEnumeratedSets() Parent.__init__(self, category=category) @@ -191,7 +179,7 @@ def __repr__(self): """ return "Unordered tuples of %s of length %s" % (self.S, self.k) - def list(self): + def __iter__(self): """ EXAMPLES:: @@ -202,8 +190,9 @@ def list(self): [['a', 'a'], ['a', 'b'], ['a', 'c'], ['b', 'b'], ['b', 'c'], ['c', 'c']] """ - ans = libgap.UnorderedTuples(self._index_list, ZZ(self.k)) - return [[self.S[i] for i in l] for l in ans] + for ans in combinations_with_replacement(self._index_list, self.k): + yield [self.S[i] for i in ans] + def cardinality(self): """ @@ -213,7 +202,7 @@ def cardinality(self): sage: UnorderedTuples(S,2).cardinality() 15 """ - return ZZ(libgap.NrUnorderedTuples(self._index_list, ZZ(self.k))) + return binomial(len(self._index_list) + self.k - 1, self.k) UnorderedTuples_sk = UnorderedTuples From fb0908efba48d906536e25153b08dca0c703537e Mon Sep 17 00:00:00 2001 From: Max Horn <max@quendi.de> Date: Mon, 19 Jun 2023 08:46:25 +0200 Subject: [PATCH 124/228] gap: switch more code to offical libgap APIs --- src/sage/libs/gap/element.pyx | 30 +++++++++++++-------------- src/sage/libs/gap/gap_includes.pxd | 33 +++++++++++++++--------------- src/sage/libs/gap/util.pyx | 8 ++++---- 3 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index 3576e871db6..3484749a7b0 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -125,7 +125,7 @@ cdef char *capture_stdout(Obj func, Obj obj): CALL_WITH_STREAM = GAP_ValueGlobalVariable("CALL_WITH_STREAM") CALL_3ARGS(CALL_WITH_STREAM, stream, func, l) - return CSTR_STRING(s) + return GAP_CSTR_STRING(s) finally: GAP_Leave() @@ -247,7 +247,7 @@ cdef Obj make_gap_string(sage_string) except NULL: try: GAP_Enter() b = str_to_bytes(sage_string) - result = MakeStringWithLen(b, len(b)) + result = GAP_MakeStringWithLen(b, len(b)) return result finally: GAP_Leave() @@ -937,7 +937,7 @@ cdef class GapElement(RingElement): sig_on() try: GAP_Enter() - return EQ(self.value, c_other.value) + return GAP_EQ(self.value, c_other.value) finally: GAP_Leave() sig_off() @@ -959,7 +959,7 @@ cdef class GapElement(RingElement): sig_on() try: GAP_Enter() - return LT(self.value, c_other.value) + return GAP_LT(self.value, c_other.value) finally: GAP_Leave() sig_off() @@ -987,7 +987,7 @@ cdef class GapElement(RingElement): try: sig_GAP_Enter() sig_on() - result = SUM(self.value, (<GapElement>right).value) + result = GAP_SUM(self.value, (<GapElement>right).value) sig_off() finally: GAP_Leave() @@ -1015,7 +1015,7 @@ cdef class GapElement(RingElement): try: sig_GAP_Enter() sig_on() - result = DIFF(self.value, (<GapElement>right).value) + result = GAP_DIFF(self.value, (<GapElement>right).value) sig_off() finally: GAP_Leave() @@ -1045,7 +1045,7 @@ cdef class GapElement(RingElement): try: sig_GAP_Enter() sig_on() - result = PROD(self.value, (<GapElement>right).value) + result = GAP_PROD(self.value, (<GapElement>right).value) sig_off() finally: GAP_Leave() @@ -1079,7 +1079,7 @@ cdef class GapElement(RingElement): try: sig_GAP_Enter() sig_on() - result = QUO(self.value, (<GapElement>right).value) + result = GAP_QUO(self.value, (<GapElement>right).value) sig_off() finally: GAP_Leave() @@ -1106,7 +1106,7 @@ cdef class GapElement(RingElement): try: sig_GAP_Enter() sig_on() - result = MOD(self.value, (<GapElement>right).value) + result = GAP_MOD(self.value, (<GapElement>right).value) sig_off() finally: GAP_Leave() @@ -1155,7 +1155,7 @@ cdef class GapElement(RingElement): try: sig_GAP_Enter() sig_on() - result = POW(self.value, (<GapElement>other).value) + result = GAP_POW(self.value, (<GapElement>other).value) sig_off() finally: GAP_Leave() @@ -2334,7 +2334,7 @@ cdef class GapElement_String(GapElement): sage: type(_) <class 'str'> """ - s = char_to_str(CSTR_STRING(self.value)) + s = char_to_str(GAP_CSTR_STRING(self.value)) return s sage = __str__ @@ -2477,8 +2477,8 @@ cdef class GapElement_Function(GapElement): GAPError: Error, no method found! Error, no 1st choice method found for `SumOp' on 2 arguments - sage: for i in range(0,100): - ....: rnd = [ randint(-10,10) for i in range(0,randint(0,7)) ] + sage: for i in range(100): + ....: rnd = [ randint(-10,10) for i in range(randint(0,7)) ] ....: # compute the sum in GAP ....: _ = libgap.Sum(rnd) ....: try: @@ -2884,7 +2884,7 @@ cdef class GapElement_List(GapElement): else: celt= self.parent()(elt) - ASS_LIST(obj, j+1, celt.value) + GAP_AssList(obj, j+1, celt.value) def sage(self, **kwds): r""" @@ -3288,7 +3288,7 @@ cdef class GapElement_RecordIterator(): raise StopIteration # note the abs: negative values mean the rec keys are not sorted key_index = abs(GET_RNAM_PREC(self.rec.value, i)) - key = char_to_str(CSTR_STRING(NAME_RNAM(key_index))) + key = char_to_str(GAP_CSTR_STRING(NAME_RNAM(key_index))) cdef Obj result = GET_ELM_PREC(self.rec.value,i) val = make_any_gap_element(self.rec.parent(), result) self.i += 1 diff --git a/src/sage/libs/gap/gap_includes.pxd b/src/sage/libs/gap/gap_includes.pxd index cc0a47dafd2..61b7af39d38 100644 --- a/src/sage/libs/gap/gap_includes.pxd +++ b/src/sage/libs/gap/gap_includes.pxd @@ -22,17 +22,6 @@ cdef extern from "gap/system.h" nogil: ctypedef void* Obj -cdef extern from "gap/ariths.h" nogil: - Obj SUM(Obj, Obj) - Obj DIFF(Obj, Obj) - Obj PROD(Obj, Obj) - Obj QUO(Obj, Obj) - Obj POW(Obj, Obj) - Obj MOD(Obj, Obj) - bint EQ(Obj opL, Obj opR) - bint LT(Obj opL, Obj opR) - - cdef extern from "gap/calls.h" nogil: bint IS_FUNC(Obj) Obj CALL_0ARGS(Obj f) # 0 arguments @@ -71,6 +60,16 @@ cdef extern from "gap/libgap-api.h" nogil: void GAP_MarkBag(Obj bag) void GAP_CollectBags(UInt full) + Obj GAP_SUM(Obj, Obj) + Obj GAP_DIFF(Obj, Obj) + Obj GAP_PROD(Obj, Obj) + Obj GAP_QUO(Obj, Obj) + Obj GAP_POW(Obj, Obj) + Obj GAP_MOD(Obj, Obj) + bint GAP_EQ(Obj opL, Obj opR) + bint GAP_LT(Obj opL, Obj opR) + bint GAP_IN(Obj opL, Obj opR) + cdef Obj GAP_True cdef Obj GAP_False @@ -89,11 +88,16 @@ cdef extern from "gap/libgap-api.h" nogil: bint GAP_IsRecord(Obj obj) Obj GAP_NewPrecord(Int capacity) + bint GAP_IsString(Obj obj) + UInt GAP_LenString(Obj string) + char* GAP_CSTR_STRING(Obj list) + Obj GAP_MakeStringWithLen(const char* buf, UInt len) + + Int GAP_ValueOfChar(Obj obj) + cdef extern from "gap/lists.h" nogil: Obj ELM_LIST(Obj lst, int pos) - Obj ELM0_LIST(Obj lst, int pos) - void ASS_LIST(Obj lst, int pos, Obj elt) cdef extern from "gap/listfunc.h" nogil: @@ -117,7 +121,6 @@ cdef extern from "gap/objects.h" nogil: T_BOOL T_CHAR T_FUNCTION - T_PLIST T_COMOBJ T_POSOBJ @@ -147,8 +150,6 @@ cdef extern from "gap/records.h" nogil: cdef extern from "gap/stringobj.h" nogil: - char* CSTR_STRING(Obj list) bint IS_STRING(Obj obj) bint IsStringConv(Obj obj) Obj NEW_STRING(Int) - Obj MakeStringWithLen(const char* buf, size_t len) diff --git a/src/sage/libs/gap/util.pyx b/src/sage/libs/gap/util.pyx index c282a59cb96..3c286d2020d 100644 --- a/src/sage/libs/gap/util.pyx +++ b/src/sage/libs/gap/util.pyx @@ -374,9 +374,9 @@ cdef Obj gap_eval(str gap_string) except? NULL: raise GAPError("can only evaluate a single statement") # Get the result of the first statement - result = ELM0_LIST(result, 1) # 1-indexed! + result = GAP_ElmList(result, 1) # 1-indexed! - if ELM0_LIST(result, 1) != GAP_True: + if GAP_ElmList(result, 1) != GAP_True: # An otherwise unhandled error occurred in GAP (such as a # syntax error). Try running the error handler manually # to capture the error output, if any. @@ -388,7 +388,7 @@ cdef Obj gap_eval(str gap_string) except? NULL: # 0 is returned without setting a Python exception, so we should treat # this like returning None) - return ELM0_LIST(result, 2) + return GAP_ElmList(result, 2) finally: GAP_Leave() sig_off() @@ -416,7 +416,7 @@ cdef str extract_libgap_errout(): # Grab a pointer to the C string underlying the GAP string libgap_errout # then copy it to a Python str (char_to_str contains an implicit strcpy) - msg = CSTR_STRING(r) + msg = GAP_CSTR_STRING(r) if msg != NULL: msg_py = char_to_str(msg) msg_py = msg_py.replace('For debugging hints type ?Recovery from ' From 1fb903f50909e856c37837f005164298282f5933 Mon Sep 17 00:00:00 2001 From: Miguel Marco <mmarco@unizar.es> Date: Thu, 22 Jun 2023 11:51:23 +0200 Subject: [PATCH 125/228] Allow case where generators are not indexed by 0..ny --- src/sage/algebras/orlik_solomon.py | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index cc1f9d6e1ca..2eb7c851d8b 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -457,29 +457,40 @@ def as_gca(self): sage: O.as_gca() Graded Commutative Algebra with generators ('e0', 'e1', 'e2') in degrees (1, 1, 1) with relations [e0*e1 - e0*e2 + e1*e2] over Rational Field + + :: + + sage: N = matroids.named_matroids.Fano() + sage: O = N.orlik_solomon_algebra(QQ) + sage: O.as_gca() + Graded Commutative Algebra with generators ('e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6') in degrees (1, 1, 1, 1, 1, 1, 1) with relations [e1*e2 - e1*e3 + e2*e3, e0*e2 - e0*e4 + e2*e4, e0*e1 - e0*e5 + e1*e5, e3*e4 - e3*e5 + e4*e5, e0*e3 - e0*e6 + e3*e6, e1*e4 - e1*e6 + e4*e6, e2*e5 - e2*e6 + e5*e6] over Rational Field + """ from sage.algebras.commutative_dga import GradedCommutativeAlgebra - gens = list(self.algebra_generators()) + gens = self.algebra_generators() + gkeys = gens.keys() names = ['e{}'.format(i) for i in range(len(gens))] A = GradedCommutativeAlgebra(self.base_ring(), names) B = self.basis() bas2 = [] non_basis = [] - for j, gj in enumerate(gens): - for i in range(j): - if gens[i] * gj in B: - bas2.append((i, j)) + for (j, gj) in gens.items(): + for i in range(gkeys.index(j)): + indi = gkeys[i] + gi = gens[indi] + if gi * gj in B: + bas2.append((indi, j)) else: - non_basis.append((i, j)) + non_basis.append((indi, j)) AG = A.gens() - AGbas = {(i, j): AG[i] * AG[j] for (i, j) in bas2} + AGbas = {(i, j): AG[gkeys.index(i)] * AG[gkeys.index(j)] for (i, j) in bas2} gij = {(i, j): gens[i] * gens[j] for (i, j) in bas2} def rhs(l, m): P = gens[l] * gens[m] return A.sum(P.coefficient(frozenset(p)) * AGbas[p] for p in bas2) - I = A.ideal([AG[l]*AG[m] - rhs(l, m) for (l,m) in non_basis]) + I = A.ideal([AG[gkeys.index(l)]*AG[gkeys.index(m)] - rhs(l, m) for (l,m) in non_basis]) return A.quotient(I) def as_cdga(self): From 9775853c639b84756c04d6c0cf2e6cf9b3b7e947 Mon Sep 17 00:00:00 2001 From: Max Horn <max@quendi.de> Date: Thu, 22 Jun 2023 16:01:15 +0200 Subject: [PATCH 126/228] gap: use libgap API for int conversion --- src/sage/groups/perm_gps/permgroup_element.pyx | 4 ++-- src/sage/libs/gap/element.pyx | 10 ++-------- src/sage/libs/gap/gap_includes.pxd | 7 ++----- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/sage/groups/perm_gps/permgroup_element.pyx b/src/sage/groups/perm_gps/permgroup_element.pyx index 5144a0ee009..ee17c6c9655 100644 --- a/src/sage/groups/perm_gps/permgroup_element.pyx +++ b/src/sage/groups/perm_gps/permgroup_element.pyx @@ -138,7 +138,7 @@ from sage.libs.gap.gap_includes cimport (UInt, UInt2, UInt4, T_PERM2, T_PERM4, from sage.libs.gap.util cimport initialize from sage.libs.gap.element cimport (GapElement, GapElement_List, GapElement_String, GapElement_Permutation, make_GapElement_Permutation) -from sage.libs.gap.gap_includes cimport Obj, INT_INTOBJ, ELM_LIST +from sage.libs.gap.gap_includes cimport Obj, GAP_ValueInt, ELM_LIST import operator @@ -1361,7 +1361,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): assert vn <= self.n for i in range(vn): - j = INT_INTOBJ(ELM_LIST(obj, i+1)) + j = GAP_ValueInt(ELM_LIST(obj, i+1)) new.perm[i] = j - 1 for i in range(vn, self.n): new.perm[i] = i diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index 3576e871db6..02a32e78948 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -217,13 +217,7 @@ cdef Obj make_gap_integer(sage_int) except NULL: sage: libgap(1) # indirect doctest 1 """ - cdef Obj result - try: - GAP_Enter() - result = INTOBJ_INT(<int>sage_int) - return result - finally: - GAP_Leave() + return GAP_NewObjIntFromInt(<int>sage_int) cdef Obj make_gap_string(sage_string) except NULL: @@ -1502,7 +1496,7 @@ cdef class GapElement_Integer(GapElement): if ring is None: ring = ZZ if self.is_C_int(): - return ring(INT_INTOBJ(self.value)) + return ring(GAP_ValueInt(self.value)) else: # TODO: waste of time! # gap integers are stored as a mp_limb_t and we have a much more direct diff --git a/src/sage/libs/gap/gap_includes.pxd b/src/sage/libs/gap/gap_includes.pxd index cc0a47dafd2..36adcad5b5c 100644 --- a/src/sage/libs/gap/gap_includes.pxd +++ b/src/sage/libs/gap/gap_includes.pxd @@ -45,11 +45,6 @@ cdef extern from "gap/calls.h" nogil: Obj CALL_XARGS(Obj f, Obj args) # more than 6 arguments -cdef extern from "gap/intobj.h" nogil: - Obj INTOBJ_INT(Int) - Int INT_INTOBJ(Obj) - - cdef extern from "gap/libgap-api.h" nogil: """ #define sig_GAP_Enter() {int t = GAP_Enter(); if (!t) sig_error();} @@ -79,6 +74,8 @@ cdef extern from "gap/libgap-api.h" nogil: bint GAP_IsInt(Obj) bint GAP_IsSmallInt(Obj) + Obj GAP_NewObjIntFromInt(Int val) + Int GAP_ValueInt(Obj) bint GAP_IsList(Obj lst) UInt GAP_LenList(Obj lst) From 3bcfa28c4a9073838d3baff7f4aedd7e97d8adb6 Mon Sep 17 00:00:00 2001 From: Miguel Marco <mmarco@unizar.es> Date: Thu, 22 Jun 2023 18:23:52 +0200 Subject: [PATCH 127/228] Add relations for all broken circuits --- src/sage/algebras/commutative_dga.py | 13 +++++--- src/sage/algebras/orlik_solomon.py | 49 +++++++++++++++------------- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/sage/algebras/commutative_dga.py b/src/sage/algebras/commutative_dga.py index 9f3b8c2c585..953364d6813 100644 --- a/src/sage/algebras/commutative_dga.py +++ b/src/sage/algebras/commutative_dga.py @@ -2439,10 +2439,10 @@ def minimal_model(self, i=3, max_iterations=3, partial_result=False): iterations of the method at each degree. If the algorithm does not finish in this many iterations at each degree, an error is raised, or the partial result computed up to that point is returned, deppending - on the `partial_result` flag. + on the ``partial_result`` flag. - - ``partial_result`` -- boolean (default: `False`); wether to return - the partial result if the `max_iterations` limit is reached. + - ``partial_result`` -- boolean (default: ``False``); wether to return + the partial result if the ``max_iterations`` limit is reached. OUTPUT: @@ -2593,14 +2593,17 @@ def minimal_model(self, i=3, max_iterations=3, partial_result=False): ValueError: could not cover all relations in max iterations in degree 2 sage: S.minimal_model(partial_result=True) Commutative Differential Graded Algebra morphism: - From: Commutative Differential Graded Algebra with generators ('x1_0', 'x1_1', 'x1_2', 'y1_0', 'y1_1', 'y1_2') in degrees (1, 1, 1, 1, 1, 1) over Rational Field with differential: + From: Commutative Differential Graded Algebra with generators + ('x1_0', 'x1_1', 'x1_2', 'y1_0', 'y1_1', 'y1_2') in degrees (1, 1, 1, 1, 1, 1) + over Rational Field with differential: x1_0 --> 0 x1_1 --> 0 x1_2 --> 0 y1_0 --> x1_0*x1_1 - x1_0*x1_2 + x1_1*x1_2 y1_1 --> x1_0*y1_0 - x1_2*y1_0 y1_2 --> x1_1*y1_0 - x1_2*y1_0 - To: Commutative Differential Graded Algebra with generators ('a', 'b', 'c') in degrees (1, 1, 1) with relations [a*b - a*c + b*c] over Rational Field with differential: + To: Commutative Differential Graded Algebra with generators ('a', 'b', 'c') + in degrees (1, 1, 1) with relations [a*b - a*c + b*c] over Rational Field with differential: a --> 0 b --> 0 c --> 0 diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index 2eb7c851d8b..8e1e4b1c3f2 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -463,7 +463,16 @@ def as_gca(self): sage: N = matroids.named_matroids.Fano() sage: O = N.orlik_solomon_algebra(QQ) sage: O.as_gca() - Graded Commutative Algebra with generators ('e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6') in degrees (1, 1, 1, 1, 1, 1, 1) with relations [e1*e2 - e1*e3 + e2*e3, e0*e2 - e0*e4 + e2*e4, e0*e1 - e0*e5 + e1*e5, e3*e4 - e3*e5 + e4*e5, e0*e3 - e0*e6 + e3*e6, e1*e4 - e1*e6 + e4*e6, e2*e5 - e2*e6 + e5*e6] over Rational Field + Graded Commutative Algebra with generators ('e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6') + in degrees (1, 1, 1, 1, 1, 1, 1) with relations + [e0*e1 - e0*e2 + e1*e2, -e0*e1*e2 + e0*e1*e3 - e0*e2*e3 + e1*e2*e3, + e0*e1 - e0*e2 + e1*e2, e0*e1 - e0*e2 + e1*e2, + -e0*e1*e2 + e0*e1*e3 - e0*e2*e3 + e1*e2*e3, -e0*e1*e2 + e0*e1*e3 - e0*e2*e3 + e1*e2*e3, + e0*e1 - e0*e2 + e1*e2, e0*e1 - e0*e2 + e1*e2, -e0*e1*e2 + e0*e1*e3 - e0*e2*e3 + e1*e2*e3, + -e0*e1*e2 + e0*e1*e3 - e0*e2*e3 + e1*e2*e3, e0*e1 - e0*e2 + e1*e2, + -e0*e1*e2 + e0*e1*e3 - e0*e2*e3 + e1*e2*e3, e0*e1 - e0*e2 + e1*e2, + -e0*e1*e2 + e0*e1*e3 - e0*e2*e3 + e1*e2*e3] over Rational Field + """ from sage.algebras.commutative_dga import GradedCommutativeAlgebra @@ -471,26 +480,20 @@ def as_gca(self): gkeys = gens.keys() names = ['e{}'.format(i) for i in range(len(gens))] A = GradedCommutativeAlgebra(self.base_ring(), names) - B = self.basis() - bas2 = [] - non_basis = [] - for (j, gj) in gens.items(): - for i in range(gkeys.index(j)): - indi = gkeys[i] - gi = gens[indi] - if gi * gj in B: - bas2.append((indi, j)) - else: - non_basis.append((indi, j)) - AG = A.gens() - AGbas = {(i, j): AG[gkeys.index(i)] * AG[gkeys.index(j)] for (i, j) in bas2} - gij = {(i, j): gens[i] * gens[j] for (i, j) in bas2} - - def rhs(l, m): - P = gens[l] * gens[m] - return A.sum(P.coefficient(frozenset(p)) * AGbas[p] for p in bas2) - - I = A.ideal([AG[gkeys.index(l)]*AG[gkeys.index(m)] - rhs(l, m) for (l,m) in non_basis]) + rels = [] + for bc in self._broken_circuits.items(): + bclist = [bc[1]] + list(bc[0]) + indices = [gkeys.index(el) for el in bclist] + indices.sort() + rel = A.zero() + for i in range(len(indices)): + mon = A.one() + for j in range(len(indices)): + if j != i: + mon *= A.gen(j) + rel += (-1)**i *mon + rels.append(rel) + I = A.ideal(rels) return A.quotient(I) def as_cdga(self): @@ -503,7 +506,9 @@ def as_cdga(self): sage: H = hyperplane_arrangements.braid(3) sage: O = H.orlik_solomon_algebra(QQ) sage: O.as_cdga() - Commutative Differential Graded Algebra with generators ('e0', 'e1', 'e2') in degrees (1, 1, 1) with relations [e0*e1 - e0*e2 + e1*e2] over Rational Field with differential: + Commutative Differential Graded Algebra with generators ('e0', 'e1', 'e2') + in degrees (1, 1, 1) with relations [e0*e1 - e0*e2 + e1*e2] over Rational Field + with differential: e0 --> 0 e1 --> 0 e2 --> 0 From 9905d4e4f11c5c821c3d340310e92d2fa83ceda2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Thu, 22 Jun 2023 10:59:40 -0700 Subject: [PATCH 128/228] .github/workflows/doc-build.yml: Save/restore the git repo of the built documentation around running doc-clean --- .github/workflows/doc-build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 01748c3c823..3eb935a634e 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -80,7 +80,10 @@ jobs: # incremental docbuild may introduce broken links (inter-file references) though build succeeds run: | set -ex - make doc-clean doc-uninstall sagelib-clean && git clean -fx src/sage && ./config.status && make doc-html + mv /sage/local/share/doc/sage/html/en/.git /sage/.git-doc + make doc-clean doc-uninstall sagelib-clean && git clean -fx src/sage + mkdir -p /sage/local/share/doc/sage/html/en/ && mv /sage/.git-doc /sage/local/share/doc/sage/html/en/ + ./config.status && make doc-html working-directory: ./worktree-image env: MAKE: make -j2 From 8493ce2dbcd2ec4dff360d9a5612298388f3d803 Mon Sep 17 00:00:00 2001 From: Jing Guo <dev.guoj@gmail.com> Date: Thu, 22 Jun 2023 19:50:39 +0000 Subject: [PATCH 129/228] projective_morphism.py: First impl for LCM in `normalize_coordinates` --- .../schemes/projective/projective_morphism.py | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index cd484292859..e2f443a8f35 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -915,6 +915,18 @@ def normalize_coordinates(self, **kwds): 3-adic Field with capped relative precision 20 Defn: Defined on coordinates by sending (x : y) to (x^2 + (2 + O(3^20))*y^2 : (3 + O(3^21))*x*y) + + :: + + sage: R.<x> = QQ[] + sage: K.<a> = NumberField(3*x^2 + 1) + sage: P.<z,w> = ProjectiveSpace(K, 1) + sage: f = DynamicalSystem_projective([a*(z^2 + w^2), z*w]) + sage: f.normalize_coordinates(); f + Dynamical System of Projective Space of dimension 1 over + Number Field in a with defining polynomial 3*x^2 + 1 + Defn: Defined on coordinates by sending (z : w) to + ((3*a)*z^2 + (3*a)*w^2 : z*w) """ # if ideal or valuation is specified, we scale according the norm defined by the ideal/valuation ideal = kwds.pop('ideal', None) @@ -967,12 +979,32 @@ def normalize_coordinates(self, **kwds): self.scale_by(uniformizer**(-1 * min_val)) return - # clear any denominators from the coefficients + R = self.domain().base_ring() + K = self.base_ring() N = self.codomain().ambient_space().dimension_relative() + 1 - LCM = lcm([self[i].denominator() for i in range(N)]) - self.scale_by(LCM) - R = self.domain().base_ring() + # Only clear denominators from the coefficients in the ring of integers + if R in NumberFields(): + denom_list = [] + + for entry in self: + if entry == 0: + continue + + O = R.maximal_order() + + if O is ZZ: + denom_list.append(entry.denominator()) + elif is_NumberFieldOrder(O): + frac_ideal = O.fractional_ideal(entry) + if K.is_relative(): + frac_ideal_norm = frac_ideal.absolute_norm() + else: + frac_ideal_norm = frac_ideal.norm() + + denom_list.append(frac_ideal_norm.denominator()) + + self.scale_by(lcm(denom_list)) # There are cases, such as the example above over GF(7), # where we want to compute GCDs, but NOT in the case From 6467855ae3fb0e3552b6fa29f955db40b6aab68d Mon Sep 17 00:00:00 2001 From: Jing Guo <dev.guoj@gmail.com> Date: Thu, 22 Jun 2023 20:08:28 +0000 Subject: [PATCH 130/228] projective_morphism.py: Simplify LCM of `normalize_coordinates` --- .../schemes/projective/projective_morphism.py | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index e2f443a8f35..6b22c6b3c02 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -985,26 +985,14 @@ def normalize_coordinates(self, **kwds): # Only clear denominators from the coefficients in the ring of integers if R in NumberFields(): - denom_list = [] - - for entry in self: - if entry == 0: - continue - - O = R.maximal_order() - - if O is ZZ: - denom_list.append(entry.denominator()) - elif is_NumberFieldOrder(O): - frac_ideal = O.fractional_ideal(entry) - if K.is_relative(): - frac_ideal_norm = frac_ideal.absolute_norm() - else: - frac_ideal_norm = frac_ideal.norm() + O = R.maximal_order() - denom_list.append(frac_ideal_norm.denominator()) + if O is ZZ: + denom = lcm([self[i].denominator() for i in range(len(list(self)))]) + else: + denom = R.ideal(list(self)).absolute_norm().denominator() - self.scale_by(lcm(denom_list)) + self.scale_by(denom) # There are cases, such as the example above over GF(7), # where we want to compute GCDs, but NOT in the case From aba3954b02055c4019e308d17eee1e1e1971b73b Mon Sep 17 00:00:00 2001 From: David Einstein <deinst@gmail.com> Date: Thu, 22 Jun 2023 17:40:14 -0400 Subject: [PATCH 131/228] Finish decoupling tuple.py from GAP. This commit is just a cosmetic change from the last (deleting a commented out line). This should finish bug #35784. --- src/sage/combinat/tuple.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/combinat/tuple.py b/src/sage/combinat/tuple.py index 254ce7f5ff4..543160597f0 100644 --- a/src/sage/combinat/tuple.py +++ b/src/sage/combinat/tuple.py @@ -16,7 +16,6 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -#from sage.libs.gap.libgap import libgap from sage.arith.misc import binomial from sage.rings.integer_ring import ZZ from sage.structure.parent import Parent From 5702830e6b2cb3071385e9590a560aaeadc6a5e3 Mon Sep 17 00:00:00 2001 From: David Einstein <deinst@gmail.com> Date: Thu, 22 Jun 2023 22:06:12 -0400 Subject: [PATCH 132/228] Added testcases to Tuples for undelying lists with duplicates Also removed a blank line that irritated the linter. --- src/sage/combinat/tuple.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/tuple.py b/src/sage/combinat/tuple.py index 543160597f0..9002e5d7fb3 100644 --- a/src/sage/combinat/tuple.py +++ b/src/sage/combinat/tuple.py @@ -104,8 +104,10 @@ def __iter__(self): ['n', 'e'], ['s', 'i'], ['t', 'i'], ['e', 'i'], ['i', 'i'], ['n', 'i'], ['s', 'n'], ['t', 'n'], ['e', 'n'], ['i', 'n'], ['n', 'n']] + sage: Tuples([1,1,2],3).list() + [[1, 1, 1], [2, 1, 1], [1, 2, 1], [2, 2, 1], [1, 1, 2], + [2, 1, 2], [1, 2, 2], [2, 2, 2]] """ - for p in product(self._index_list, repeat=self.k): yield [self.S[i] for i in reversed(p)] @@ -188,11 +190,12 @@ def __iter__(self): sage: UnorderedTuples(["a","b","c"],2).list() [['a', 'a'], ['a', 'b'], ['a', 'c'], ['b', 'b'], ['b', 'c'], ['c', 'c']] + sage: UnorderedTuples([1,1,2],3).list() + [[1, 1, 1], [1, 1, 2], [1, 2, 2], [2, 2, 2]] """ for ans in combinations_with_replacement(self._index_list, self.k): yield [self.S[i] for i in ans] - def cardinality(self): """ EXAMPLES:: From ff5de23adc6171820be58c9916d737a6b2760d2e Mon Sep 17 00:00:00 2001 From: Miguel Marco <mmarco@unizar.es> Date: Fri, 23 Jun 2023 10:28:45 +0200 Subject: [PATCH 133/228] Fix indices to compute monomials --- src/sage/algebras/orlik_solomon.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index 8e1e4b1c3f2..6ebaaa8b52f 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -486,9 +486,9 @@ def as_gca(self): indices = [gkeys.index(el) for el in bclist] indices.sort() rel = A.zero() - for i in range(len(indices)): + for i in indices: mon = A.one() - for j in range(len(indices)): + for j in indices: if j != i: mon *= A.gen(j) rel += (-1)**i *mon From 2c07edcd81212180e32e681a55c4b25071ad2d91 Mon Sep 17 00:00:00 2001 From: Miguel Marco <mmarco@unizar.es> Date: Fri, 23 Jun 2023 10:38:28 +0200 Subject: [PATCH 134/228] Fix doctest --- src/sage/algebras/orlik_solomon.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index 6ebaaa8b52f..abf4fa18e81 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -465,14 +465,14 @@ def as_gca(self): sage: O.as_gca() Graded Commutative Algebra with generators ('e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6') in degrees (1, 1, 1, 1, 1, 1, 1) with relations - [e0*e1 - e0*e2 + e1*e2, -e0*e1*e2 + e0*e1*e3 - e0*e2*e3 + e1*e2*e3, - e0*e1 - e0*e2 + e1*e2, e0*e1 - e0*e2 + e1*e2, - -e0*e1*e2 + e0*e1*e3 - e0*e2*e3 + e1*e2*e3, -e0*e1*e2 + e0*e1*e3 - e0*e2*e3 + e1*e2*e3, - e0*e1 - e0*e2 + e1*e2, e0*e1 - e0*e2 + e1*e2, -e0*e1*e2 + e0*e1*e3 - e0*e2*e3 + e1*e2*e3, - -e0*e1*e2 + e0*e1*e3 - e0*e2*e3 + e1*e2*e3, e0*e1 - e0*e2 + e1*e2, - -e0*e1*e2 + e0*e1*e3 - e0*e2*e3 + e1*e2*e3, e0*e1 - e0*e2 + e1*e2, - -e0*e1*e2 + e0*e1*e3 - e0*e2*e3 + e1*e2*e3] over Rational Field - + [-e1*e2 + e1*e3 - e2*e3, e0*e1*e3 - e0*e1*e4 - e0*e3*e4 + e1*e3*e4, + e0*e2 + e0*e4 + e2*e4, -e3*e4 + e3*e5 - e4*e5, + -e1*e2*e4 + e1*e2*e5 + e1*e4*e5 - e2*e4*e5, + -e0*e2*e3 - e0*e2*e5 + e0*e3*e5 + e2*e3*e5, -e0*e1 - e0*e5 + e1*e5, + e2*e5 - e2*e6 + e5*e6, e1*e3*e5 - e1*e3*e6 - e1*e5*e6 - e3*e5*e6, + e0*e4*e5 - e0*e4*e6 + e0*e5*e6 + e4*e5*e6, e1*e4 + e1*e6 - e4*e6, + e2*e3*e4 + e2*e3*e6 - e2*e4*e6 + e3*e4*e6, e0*e3 - e0*e6 + e3*e6, + e0*e1*e2 + e0*e1*e6 - e0*e2*e6 + e1*e2*e6] over Rational Field """ from sage.algebras.commutative_dga import GradedCommutativeAlgebra From 936251f888f9efb750b3d15e9ddf716d49b4c41e Mon Sep 17 00:00:00 2001 From: Miguel Marco <mmarco@unizar.es> Date: Fri, 23 Jun 2023 10:59:45 +0200 Subject: [PATCH 135/228] Fix sign convention --- src/sage/algebras/orlik_solomon.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index abf4fa18e81..db51f464a26 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -465,14 +465,14 @@ def as_gca(self): sage: O.as_gca() Graded Commutative Algebra with generators ('e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6') in degrees (1, 1, 1, 1, 1, 1, 1) with relations - [-e1*e2 + e1*e3 - e2*e3, e0*e1*e3 - e0*e1*e4 - e0*e3*e4 + e1*e3*e4, - e0*e2 + e0*e4 + e2*e4, -e3*e4 + e3*e5 - e4*e5, - -e1*e2*e4 + e1*e2*e5 + e1*e4*e5 - e2*e4*e5, - -e0*e2*e3 - e0*e2*e5 + e0*e3*e5 + e2*e3*e5, -e0*e1 - e0*e5 + e1*e5, - e2*e5 - e2*e6 + e5*e6, e1*e3*e5 - e1*e3*e6 - e1*e5*e6 - e3*e5*e6, - e0*e4*e5 - e0*e4*e6 + e0*e5*e6 + e4*e5*e6, e1*e4 + e1*e6 - e4*e6, - e2*e3*e4 + e2*e3*e6 - e2*e4*e6 + e3*e4*e6, e0*e3 - e0*e6 + e3*e6, - e0*e1*e2 + e0*e1*e6 - e0*e2*e6 + e1*e2*e6] over Rational Field + [e1*e2 - e1*e3 + e2*e3, e0*e1*e3 - e0*e1*e4 + e0*e3*e4 - e1*e3*e4, + e0*e2 - e0*e4 + e2*e4, e3*e4 - e3*e5 + e4*e5, + e1*e2*e4 - e1*e2*e5 + e1*e4*e5 - e2*e4*e5, + e0*e2*e3 - e0*e2*e5 + e0*e3*e5 - e2*e3*e5, e0*e1 - e0*e5 + e1*e5, + e2*e5 - e2*e6 + e5*e6, e1*e3*e5 - e1*e3*e6 + e1*e5*e6 - e3*e5*e6, + e0*e4*e5 - e0*e4*e6 + e0*e5*e6 - e4*e5*e6, e1*e4 - e1*e6 + e4*e6, + e2*e3*e4 - e2*e3*e6 + e2*e4*e6 - e3*e4*e6, e0*e3 - e0*e6 + e3*e6, + e0*e1*e2 - e0*e1*e6 + e0*e2*e6 - e1*e2*e6] over Rational Field """ from sage.algebras.commutative_dga import GradedCommutativeAlgebra @@ -486,12 +486,14 @@ def as_gca(self): indices = [gkeys.index(el) for el in bclist] indices.sort() rel = A.zero() + sign = -(-1)**len(indices) for i in indices: mon = A.one() for j in indices: if j != i: mon *= A.gen(j) - rel += (-1)**i *mon + rel += sign *mon + sign = -sign rels.append(rel) I = A.ideal(rels) return A.quotient(I) From 396229bf054f86790dcc0768e78dd0a6a3187b38 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Fri, 23 Jun 2023 08:44:37 -0700 Subject: [PATCH 136/228] Fixup --- .github/workflows/doc-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 3eb935a634e..f65a0e4db0e 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -82,7 +82,7 @@ jobs: set -ex mv /sage/local/share/doc/sage/html/en/.git /sage/.git-doc make doc-clean doc-uninstall sagelib-clean && git clean -fx src/sage - mkdir -p /sage/local/share/doc/sage/html/en/ && mv /sage/.git-doc /sage/local/share/doc/sage/html/en/ + mkdir -p /sage/local/share/doc/sage/html/en/ && mv /sage/.git-doc /sage/local/share/doc/sage/html/en/.git ./config.status && make doc-html working-directory: ./worktree-image env: From 30d4209d907e0bdbab0745778dffc51ba3474bc4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Fri, 23 Jun 2023 09:31:57 -0700 Subject: [PATCH 137/228] sage.misc.timing: Split out from sage.misc.misc --- pkgs/sagemath-objects/MANIFEST.in | 1 + src/sage/coding/binary_code.pyx | 2 +- src/sage/databases/cremona.py | 2 +- src/sage/doctest/forker.py | 6 +- src/sage/doctest/util.py | 2 +- src/sage/geometry/fan.py | 2 +- src/sage/geometry/fan_morphism.py | 1 + .../perm_gps/partn_ref/refinement_binary.pyx | 1 + .../partn_ref/refinement_matrices.pyx | 1 + src/sage/interfaces/tests.py | 2 +- src/sage/matrix/benchmark.py | 2 +- src/sage/matrix/matrix_integer_dense.pyx | 2 +- src/sage/matrix/matrix_integer_dense_hnf.py | 2 +- .../matrix/matrix_modn_dense_template.pxi | 2 +- src/sage/misc/all__sagemath_objects.py | 2 + src/sage/misc/misc.py | 227 +--------------- src/sage/misc/profiler.py | 2 +- src/sage/misc/timing.py | 247 ++++++++++++++++++ src/sage/misc/verbose.py | 2 +- src/sage/modular/arithgroup/tests.py | 2 +- src/sage/modular/modform/eis_series.py | 2 +- src/sage/modular/modsym/tests.py | 2 +- .../modular/overconvergent/hecke_series.py | 2 +- src/sage/modular/quatalg/brandt.py | 2 +- src/sage/parallel/use_fork.py | 2 +- .../rings/number_field/splitting_field.py | 2 +- src/sage/rings/padics/lattice_precision.py | 2 +- src/sage/rings/padics/pow_computer_ext.pyx | 2 +- src/sage/rings/polynomial/polynomial_gf2x.pyx | 2 +- 29 files changed, 280 insertions(+), 248 deletions(-) create mode 100644 src/sage/misc/timing.py diff --git a/pkgs/sagemath-objects/MANIFEST.in b/pkgs/sagemath-objects/MANIFEST.in index eced95ea865..d67bb6591a5 100644 --- a/pkgs/sagemath-objects/MANIFEST.in +++ b/pkgs/sagemath-objects/MANIFEST.in @@ -83,6 +83,7 @@ graft sage/libs/gmp ## FIXME: Needed for doctesting include sage/misc/misc.* # walltime, cputime used in sage.doctest +include sage/misc/timing.p* global-exclude *.c diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index 59d69cd65af..c3f9433d07f 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -47,7 +47,7 @@ from cpython.object cimport PyObject_RichCompare from cysignals.memory cimport sig_malloc, sig_realloc, sig_free from sage.structure.element import is_Matrix -from sage.misc.misc import cputime +from sage.misc.timing import cputime from sage.rings.integer cimport Integer from copy import copy from sage.data_structures.bitset_base cimport * diff --git a/src/sage/databases/cremona.py b/src/sage/databases/cremona.py index 11a081e0ad0..19cd672bb0f 100644 --- a/src/sage/databases/cremona.py +++ b/src/sage/databases/cremona.py @@ -51,7 +51,7 @@ import sage.schemes.elliptic_curves.constructor as elliptic from .sql_db import SQLDatabase, verify_column from sage.features.databases import DatabaseCremona -from sage.misc.misc import walltime +from sage.misc.timing import walltime import re import string diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py index 6a62fdccb83..24ede7eeb9c 100644 --- a/src/sage/doctest/forker.py +++ b/src/sage/doctest/forker.py @@ -54,7 +54,7 @@ import IPython.lib.pretty import sage.misc.randstate as randstate -from sage.misc.misc import walltime +from sage.misc.timing import walltime from .util import Timer, RecordingDict, count_noun from .sources import DictAsObject from .parsing import OriginalSource, reduce_hex, unparse_optional_tags @@ -1275,7 +1275,7 @@ def report_success(self, out, test, example, got, *, check_duration=0): sage: from sage.doctest.forker import SageDocTestRunner sage: from sage.doctest.sources import FileDocTestSource sage: from sage.doctest.control import DocTestDefaults; DD = DocTestDefaults() - sage: from sage.misc.misc import walltime + sage: from sage.misc.timing import walltime sage: from sage.env import SAGE_SRC sage: import doctest, sys, os sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=True, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) @@ -1449,7 +1449,7 @@ def report_overtime(self, out, test, example, got, *, check_duration=0): sage: from sage.doctest.forker import SageDocTestRunner sage: from sage.doctest.sources import FileDocTestSource sage: from sage.doctest.control import DocTestDefaults; DD = DocTestDefaults() - sage: from sage.misc.misc import walltime + sage: from sage.misc.timing import walltime sage: from sage.env import SAGE_SRC sage: import doctest, sys, os sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=True, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) diff --git a/src/sage/doctest/util.py b/src/sage/doctest/util.py index f056ceb21b0..029611497a3 100644 --- a/src/sage/doctest/util.py +++ b/src/sage/doctest/util.py @@ -19,7 +19,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.misc.misc import walltime, cputime +from sage.misc.timing import walltime, cputime def count_noun(number, noun, plural=None, pad_number=False, pad_noun=False): diff --git a/src/sage/geometry/fan.py b/src/sage/geometry/fan.py index 93364df67d6..3f04faf2e4d 100644 --- a/src/sage/geometry/fan.py +++ b/src/sage/geometry/fan.py @@ -253,7 +253,7 @@ from sage.graphs.digraph import DiGraph from sage.matrix.constructor import matrix from sage.misc.cachefunc import cached_method -from sage.misc.misc import walltime +from sage.misc.timing import walltime from sage.misc.misc_c import prod from sage.modules.free_module import span from sage.modules.free_module_element import vector diff --git a/src/sage/geometry/fan_morphism.py b/src/sage/geometry/fan_morphism.py index ddc4aa3fee9..2302c7551ee 100644 --- a/src/sage/geometry/fan_morphism.py +++ b/src/sage/geometry/fan_morphism.py @@ -677,6 +677,7 @@ def _subdivide_domain_fan(self, check, verbose): domain_fan = self._domain_fan lattice_dim = self.domain().dimension() if verbose: + from sage.misc.timing import walltime start = walltime() print("Placing ray images", end=" ") # Figure out where 1-dimensional cones (i.e. rays) are mapped. diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx index f521d76b1db..d66eb088461 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx @@ -1063,6 +1063,7 @@ def random_tests(num=50, n_max=50, k_max=6, nwords_max=200, perms_per_code=10, d sage: sage.groups.perm_gps.partn_ref.refinement_binary.random_tests() # long time (up to 5s on sage.math, 2012) All passed: ... random tests on ... codes. """ + from sage.misc.timing import walltime from sage.misc.prandom import random, randint from sage.combinat.permutation import Permutations from sage.matrix.constructor import random_matrix, matrix diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_matrices.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_matrices.pyx index 36883bf8832..bb88ce09df5 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_matrices.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_matrices.pyx @@ -331,6 +331,7 @@ def random_tests(n=10, nrows_max=50, ncols_max=50, nsymbols_max=10, perms_per_ma sage: sage.groups.perm_gps.partn_ref.refinement_matrices.random_tests() # long time (up to 30s on sage.math, 2011) All passed: ... random tests on ... matrices. """ + from sage.misc.timing import walltime from sage.misc.prandom import random, randint from sage.combinat.permutation import Permutations from sage.matrix.constructor import random_matrix, matrix diff --git a/src/sage/interfaces/tests.py b/src/sage/interfaces/tests.py index 7e1fa9d68db..559855d9f85 100644 --- a/src/sage/interfaces/tests.py +++ b/src/sage/interfaces/tests.py @@ -43,7 +43,7 @@ """ from .all import * -from sage.misc.misc import cputime, walltime +from sage.misc.timing import cputime, walltime import sys def manyvars(s, num=70000, inlen=1, step=2000): diff --git a/src/sage/matrix/benchmark.py b/src/sage/matrix/benchmark.py index 40675c3f615..51fad23a874 100644 --- a/src/sage/matrix/benchmark.py +++ b/src/sage/matrix/benchmark.py @@ -21,7 +21,7 @@ from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF -from sage.misc.misc import cputime +from sage.misc.timing import cputime from cysignals.alarm import AlarmInterrupt, alarm, cancel_alarm from sage.interfaces.magma import magma diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx index 89bd3075db8..7ccf6b16ab6 100644 --- a/src/sage/matrix/matrix_integer_dense.pyx +++ b/src/sage/matrix/matrix_integer_dense.pyx @@ -75,7 +75,7 @@ from sage.libs.gmp.mpz cimport * from sage.modules.vector_integer_dense cimport Vector_integer_dense -from sage.misc.misc import cputime +from sage.misc.timing import cputime from sage.misc.verbose import verbose, get_verbose from sage.arith.misc import previous_prime diff --git a/src/sage/matrix/matrix_integer_dense_hnf.py b/src/sage/matrix/matrix_integer_dense_hnf.py index 01bfe9c2691..a899ae9f6e0 100644 --- a/src/sage/matrix/matrix_integer_dense_hnf.py +++ b/src/sage/matrix/matrix_integer_dense_hnf.py @@ -10,7 +10,7 @@ from sage.arith.misc import CRT_list, previous_prime from sage.matrix.constructor import identity_matrix, matrix, random_matrix -from sage.misc.misc import cputime +from sage.misc.timing import cputime from sage.misc.verbose import verbose from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ diff --git a/src/sage/matrix/matrix_modn_dense_template.pxi b/src/sage/matrix/matrix_modn_dense_template.pxi index 68b869ce314..ca3382859f5 100644 --- a/src/sage/matrix/matrix_modn_dense_template.pxi +++ b/src/sage/matrix/matrix_modn_dense_template.pxi @@ -115,7 +115,7 @@ from sage.structure.element cimport (Element, Vector, Matrix, from sage.matrix.matrix_dense cimport Matrix_dense from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense from sage.rings.finite_rings.integer_mod cimport IntegerMod_int, IntegerMod_abstract -from sage.misc.misc import cputime +from sage.misc.timing import cputime from sage.misc.verbose import verbose, get_verbose from sage.rings.integer cimport Integer from sage.rings.integer_ring import ZZ diff --git a/src/sage/misc/all__sagemath_objects.py b/src/sage/misc/all__sagemath_objects.py index 3090b5a8913..43a9c1c06d5 100644 --- a/src/sage/misc/all__sagemath_objects.py +++ b/src/sage/misc/all__sagemath_objects.py @@ -32,3 +32,5 @@ from .cachefunc import CachedFunction, cached_function, cached_method, cached_in_parent_method, disk_cached_function from .abstract_method import abstract_method + +from .timing import walltime, cputime diff --git a/src/sage/misc/misc.py b/src/sage/misc/misc.py index ac285817431..691c77f81df 100644 --- a/src/sage/misc/misc.py +++ b/src/sage/misc/misc.py @@ -39,8 +39,6 @@ # **************************************************************************** import os -import time -import resource import pdb import warnings @@ -61,6 +59,9 @@ lazy_import("sage.misc.repr", ["coeff_repr", "repr_lincomb"], deprecation=29892) +lazy_import("sage.misc.timing", ["cputime", "GlobalCputime", "walltime"], + deprecation=35816) + LOCAL_IDENTIFIER = '%s.%s' % (HOSTNAME, os.getpid()) ################################################################# @@ -299,228 +300,6 @@ def SPYX_TMP(): ################################################################# -def cputime(t=0, subprocesses=False): - """ - Return the time in CPU seconds since Sage started, or with - optional argument ``t``, return the time since ``t``. This is how - much time Sage has spent using the CPU. If ``subprocesses=False`` - this does not count time spent in subprocesses spawned by Sage - (e.g., Gap, Singular, etc.). If ``subprocesses=True`` this - function tries to take all subprocesses with a working - ``cputime()`` implementation into account. - - The measurement for the main Sage process is done via a call to - :func:`resource.getrusage()`, so it avoids the wraparound problems in - :func:`time.clock()` on Cygwin. - - INPUT: - - - ``t`` - (optional) time in CPU seconds, if ``t`` is a result - from an earlier call with ``subprocesses=True``, then - ``subprocesses=True`` is assumed. - - - subprocesses -- (optional), include subprocesses (default: - ``False``) - - OUTPUT: - - - ``float`` - time in CPU seconds if ``subprocesses=False`` - - - :class:`GlobalCputime` - object which holds CPU times of - subprocesses otherwise - - EXAMPLES:: - - sage: t = cputime() - sage: F = gp.factor(2^199-1) - sage: cputime(t) # somewhat random - 0.010999000000000092 - - sage: t = cputime(subprocesses=True) - sage: F = gp.factor(2^199-1) - sage: cputime(t) # somewhat random - 0.091999 - - sage: w = walltime() - sage: F = gp.factor(2^199-1) - sage: walltime(w) # somewhat random - 0.58425593376159668 - - .. NOTE:: - - Even with ``subprocesses=True`` there is no guarantee that the - CPU time is reported correctly because subprocesses can be - started and terminated at any given time. - """ - if isinstance(t, GlobalCputime): - subprocesses = True - - if not subprocesses: - try: - t = float(t) - except TypeError: - t = 0.0 - u, s = resource.getrusage(resource.RUSAGE_SELF)[:2] - return u + s - t - else: - from sage.interfaces.quit import expect_objects - if t == 0: - ret = GlobalCputime(cputime()) - for s in expect_objects: - S = s() - if S and S.is_running(): - try: - ct = S.cputime() - ret.total += ct - ret.interfaces[s] = ct - except NotImplementedError: - pass - return ret - else: - if not isinstance(t, GlobalCputime): - t = GlobalCputime(t) - ret = GlobalCputime(cputime() - t.local) - for s in expect_objects: - S = s() - if S and S.is_running(): - try: - ct = S.cputime() - t.interfaces.get(s, 0.0) - ret.total += ct - ret.interfaces[s] = ct - except NotImplementedError: - pass - return ret - - -class GlobalCputime: - """ - Container for CPU times of subprocesses. - - AUTHOR: - - - Martin Albrecht - (2008-12): initial version - - EXAMPLES: - - Objects of this type are returned if ``subprocesses=True`` is - passed to :func:`cputime`:: - - sage: cputime(subprocesses=True) # indirect doctest, output random - 0.2347431 - - We can use it to keep track of the CPU time spent in Singular for - example:: - - sage: t = cputime(subprocesses=True) - sage: P = PolynomialRing(QQ,7,'x') - sage: I = sage.rings.ideal.Katsura(P) - sage: gb = I.groebner_basis() # calls Singular - sage: cputime(subprocesses=True) - t # output random - 0.462987 - - For further processing we can then convert this container to a - float:: - - sage: t = cputime(subprocesses=True) - sage: float(t) #output somewhat random - 2.1088339999999999 - - .. SEEALSO:: - - :func:`cputime` - """ - def __init__(self, t): - """ - Create a new CPU time object which also keeps track of - subprocesses. - - EXAMPLES:: - - sage: from sage.misc.misc import GlobalCputime - sage: ct = GlobalCputime(0.0); ct - 0.0... - """ - self.total = t - self.local = t - self.interfaces = {} - - def __repr__(self): - """ - EXAMPLES:: - - sage: cputime(subprocesses=True) # indirect doctest, output random - 0.2347431 - """ - return str(self.total) - - def __add__(self, other): - """ - EXAMPLES:: - - sage: t = cputime(subprocesses=True) - sage: P = PolynomialRing(QQ,7,'x') - sage: I = sage.rings.ideal.Katsura(P) - sage: gb = I.groebner_basis() # calls Singular - sage: cputime(subprocesses=True) + t # output random - 2.798708 - """ - if not isinstance(other, GlobalCputime): - other = GlobalCputime(other) - ret = GlobalCputime(self.total + other.total) - return ret - - def __sub__(self, other): - """ - EXAMPLES:: - - sage: t = cputime(subprocesses=True) - sage: P = PolynomialRing(QQ,7,'x') - sage: I = sage.rings.ideal.Katsura(P) - sage: gb = I.groebner_basis() # calls Singular - sage: cputime(subprocesses=True) - t # output random - 0.462987 - """ - if not isinstance(other, GlobalCputime): - other = GlobalCputime(other) - ret = GlobalCputime(self.total - other.total) - return ret - - def __float__(self): - """ - EXAMPLES:: - - sage: t = cputime(subprocesses=True) - sage: float(t) #output somewhat random - 2.1088339999999999 - """ - return float(self.total) - - -def walltime(t=0): - """ - Return the wall time in second, or with optional argument t, return - the wall time since time t. "Wall time" means the time on a wall - clock, i.e., the actual time. - - INPUT: - - - - ``t`` - (optional) float, time in CPU seconds - - OUTPUT: - - - ``float`` - time in seconds - - - EXAMPLES:: - - sage: w = walltime() - sage: F = factor(2^199-1) - sage: walltime(w) # somewhat random - 0.8823847770690918 - """ - return time.time() - t - def union(x, y=None): """ diff --git a/src/sage/misc/profiler.py b/src/sage/misc/profiler.py index 6fac3e4c095..48c0d0cbbea 100644 --- a/src/sage/misc/profiler.py +++ b/src/sage/misc/profiler.py @@ -15,7 +15,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.misc.misc import cputime +from sage.misc.timing import cputime import inspect import sys diff --git a/src/sage/misc/timing.py b/src/sage/misc/timing.py new file mode 100644 index 00000000000..e4cebc5fc68 --- /dev/null +++ b/src/sage/misc/timing.py @@ -0,0 +1,247 @@ +r""" +Timing functions +""" + +# **************************************************************************** +# Copyright (C) 2006 William Stein <wstein@gmail.com> +# 2006 Gonzalo Tornaria +# 2008 Martin Albrecht +# 2009 Mike Hansen +# 2018 Frédéric Chapoton +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + + +import resource +import time + + +def cputime(t=0, subprocesses=False): + """ + Return the time in CPU seconds since Sage started, or with + optional argument ``t``, return the time since ``t``. This is how + much time Sage has spent using the CPU. If ``subprocesses=False`` + this does not count time spent in subprocesses spawned by Sage + (e.g., Gap, Singular, etc.). If ``subprocesses=True`` this + function tries to take all subprocesses with a working + ``cputime()`` implementation into account. + + The measurement for the main Sage process is done via a call to + :func:`resource.getrusage()`, so it avoids the wraparound problems in + :func:`time.clock()` on Cygwin. + + INPUT: + + - ``t`` - (optional) time in CPU seconds, if ``t`` is a result + from an earlier call with ``subprocesses=True``, then + ``subprocesses=True`` is assumed. + + - subprocesses -- (optional), include subprocesses (default: + ``False``) + + OUTPUT: + + - ``float`` - time in CPU seconds if ``subprocesses=False`` + + - :class:`GlobalCputime` - object which holds CPU times of + subprocesses otherwise + + EXAMPLES:: + + sage: t = cputime() + sage: F = gp.factor(2^199-1) + sage: cputime(t) # somewhat random + 0.010999000000000092 + + sage: t = cputime(subprocesses=True) + sage: F = gp.factor(2^199-1) + sage: cputime(t) # somewhat random + 0.091999 + + sage: w = walltime() + sage: F = gp.factor(2^199-1) + sage: walltime(w) # somewhat random + 0.58425593376159668 + + .. NOTE:: + + Even with ``subprocesses=True`` there is no guarantee that the + CPU time is reported correctly because subprocesses can be + started and terminated at any given time. + """ + if isinstance(t, GlobalCputime): + subprocesses = True + + if not subprocesses: + try: + t = float(t) + except TypeError: + t = 0.0 + u, s = resource.getrusage(resource.RUSAGE_SELF)[:2] + return u + s - t + else: + try: + from sage.interfaces.quit import expect_objects + except ImportError: + expect_objects = () + if t == 0: + ret = GlobalCputime(cputime()) + for s in expect_objects: + S = s() + if S and S.is_running(): + try: + ct = S.cputime() + ret.total += ct + ret.interfaces[s] = ct + except NotImplementedError: + pass + return ret + else: + if not isinstance(t, GlobalCputime): + t = GlobalCputime(t) + ret = GlobalCputime(cputime() - t.local) + for s in expect_objects: + S = s() + if S and S.is_running(): + try: + ct = S.cputime() - t.interfaces.get(s, 0.0) + ret.total += ct + ret.interfaces[s] = ct + except NotImplementedError: + pass + return ret + + +class GlobalCputime: + """ + Container for CPU times of subprocesses. + + AUTHOR: + + - Martin Albrecht - (2008-12): initial version + + EXAMPLES: + + Objects of this type are returned if ``subprocesses=True`` is + passed to :func:`cputime`:: + + sage: cputime(subprocesses=True) # indirect doctest, output random + 0.2347431 + + We can use it to keep track of the CPU time spent in Singular for + example:: + + sage: t = cputime(subprocesses=True) + sage: P = PolynomialRing(QQ,7,'x') + sage: I = sage.rings.ideal.Katsura(P) + sage: gb = I.groebner_basis() # calls Singular + sage: cputime(subprocesses=True) - t # output random + 0.462987 + + For further processing we can then convert this container to a + float:: + + sage: t = cputime(subprocesses=True) + sage: float(t) #output somewhat random + 2.1088339999999999 + + .. SEEALSO:: + + :func:`cputime` + """ + def __init__(self, t): + """ + Create a new CPU time object which also keeps track of + subprocesses. + + EXAMPLES:: + + sage: from sage.misc.timing import GlobalCputime + sage: ct = GlobalCputime(0.0); ct + 0.0... + """ + self.total = t + self.local = t + self.interfaces = {} + + def __repr__(self): + """ + EXAMPLES:: + + sage: cputime(subprocesses=True) # indirect doctest, output random + 0.2347431 + """ + return str(self.total) + + def __add__(self, other): + """ + EXAMPLES:: + + sage: t = cputime(subprocesses=True) + sage: P = PolynomialRing(QQ,7,'x') + sage: I = sage.rings.ideal.Katsura(P) + sage: gb = I.groebner_basis() # calls Singular + sage: cputime(subprocesses=True) + t # output random + 2.798708 + """ + if not isinstance(other, GlobalCputime): + other = GlobalCputime(other) + ret = GlobalCputime(self.total + other.total) + return ret + + def __sub__(self, other): + """ + EXAMPLES:: + + sage: t = cputime(subprocesses=True) + sage: P = PolynomialRing(QQ,7,'x') + sage: I = sage.rings.ideal.Katsura(P) + sage: gb = I.groebner_basis() # calls Singular + sage: cputime(subprocesses=True) - t # output random + 0.462987 + """ + if not isinstance(other, GlobalCputime): + other = GlobalCputime(other) + ret = GlobalCputime(self.total - other.total) + return ret + + def __float__(self): + """ + EXAMPLES:: + + sage: t = cputime(subprocesses=True) + sage: float(t) #output somewhat random + 2.1088339999999999 + """ + return float(self.total) + + +def walltime(t=0): + """ + Return the wall time in second, or with optional argument t, return + the wall time since time t. "Wall time" means the time on a wall + clock, i.e., the actual time. + + INPUT: + + + - ``t`` - (optional) float, time in CPU seconds + + OUTPUT: + + - ``float`` - time in seconds + + + EXAMPLES:: + + sage: w = walltime() + sage: F = factor(2^199-1) + sage: walltime(w) # somewhat random + 0.8823847770690918 + """ + return time.time() - t diff --git a/src/sage/misc/verbose.py b/src/sage/misc/verbose.py index b7016d08116..d29d7310758 100644 --- a/src/sage/misc/verbose.py +++ b/src/sage/misc/verbose.py @@ -145,7 +145,7 @@ def verbose(mesg="", t=0, level=1, caller_name=None): VERBOSE1 (william): This is Sage. (time = 0.0) sage: set_verbose(0) """ - from sage.misc.misc import cputime + from sage.misc.timing import cputime if level > LEVEL: return cputime() diff --git a/src/sage/modular/arithgroup/tests.py b/src/sage/modular/arithgroup/tests.py index ef9818b39aa..be49c7d41d2 100644 --- a/src/sage/modular/arithgroup/tests.py +++ b/src/sage/modular/arithgroup/tests.py @@ -19,7 +19,7 @@ from sage.rings.finite_rings.integer_mod_ring import Zmod import sage.misc.prandom as prandom -from sage.misc.misc import cputime +from sage.misc.timing import cputime def random_even_arithgroup(index, nu2_max=None, nu3_max=None): diff --git a/src/sage/modular/modform/eis_series.py b/src/sage/modular/modform/eis_series.py index 6b2e6d187ea..fbdee194cfa 100644 --- a/src/sage/modular/modform/eis_series.py +++ b/src/sage/modular/modform/eis_series.py @@ -14,7 +14,7 @@ from sage.arith.functions import lcm from sage.arith.misc import bernoulli, divisors, is_squarefree -from sage.misc.misc import cputime +from sage.misc.timing import cputime from sage.modular.arithgroup.congroup_gammaH import GammaH_class from sage.modular.dirichlet import DirichletGroup from sage.rings.integer import Integer diff --git a/src/sage/modular/modsym/tests.py b/src/sage/modular/modsym/tests.py index c50bdeddb2c..48a45be55ed 100644 --- a/src/sage/modular/modsym/tests.py +++ b/src/sage/modular/modsym/tests.py @@ -30,7 +30,7 @@ from . import modsym import sage.modular.dirichlet as dirichlet import sage.modular.arithgroup.all as arithgroup -from sage.misc.misc import cputime +from sage.misc.timing import cputime class Test: diff --git a/src/sage/modular/overconvergent/hecke_series.py b/src/sage/modular/overconvergent/hecke_series.py index f9c18c87043..fa66f2aa0a3 100644 --- a/src/sage/modular/overconvergent/hecke_series.py +++ b/src/sage/modular/overconvergent/hecke_series.py @@ -74,7 +74,7 @@ from sage.matrix.constructor import matrix, random_matrix from sage.matrix.matrix_space import MatrixSpace from sage.misc.functional import dimension, transpose, charpoly -from sage.misc.misc import cputime +from sage.misc.timing import cputime from sage.misc.verbose import verbose from sage.modular.dims import dimension_modular_forms from sage.modular.modform.all import ModularForms, ModularFormsRing, delta_qexp, eisenstein_series_qexp diff --git a/src/sage/modular/quatalg/brandt.py b/src/sage/modular/quatalg/brandt.py index e16f53fccdb..81381adef3d 100644 --- a/src/sage/modular/quatalg/brandt.py +++ b/src/sage/modular/quatalg/brandt.py @@ -1690,7 +1690,7 @@ def benchmark_sage(levels, silent=False): ('sage', 43, 2, ...) ('sage', 97, 2, ...) """ - from sage.misc.misc import cputime + from sage.misc.timing import cputime ans = [] for p, M in levels: t = cputime() diff --git a/src/sage/parallel/use_fork.py b/src/sage/parallel/use_fork.py index 69f2ede8420..bf38df167f9 100644 --- a/src/sage/parallel/use_fork.py +++ b/src/sage/parallel/use_fork.py @@ -17,7 +17,7 @@ from cysignals.alarm import AlarmInterrupt, alarm, cancel_alarm from sage.interfaces.process import ContainChildren -from sage.misc.misc import walltime +from sage.misc.timing import walltime class WorkerData(): diff --git a/src/sage/rings/number_field/splitting_field.py b/src/sage/rings/number_field/splitting_field.py index 933660d629a..190ea239092 100644 --- a/src/sage/rings/number_field/splitting_field.py +++ b/src/sage/rings/number_field/splitting_field.py @@ -340,7 +340,7 @@ def splitting_field(poly, name, map=False, degree_multiple=None, abort_degree=No To: Number Field in x with defining polynomial x Defn: 1 |--> 1) """ - from sage.misc.misc import cputime + from sage.misc.timing import cputime from sage.misc.verbose import verbose degree_multiple = Integer(degree_multiple or 0) diff --git a/src/sage/rings/padics/lattice_precision.py b/src/sage/rings/padics/lattice_precision.py index c855e3bd25c..d2ad57b869d 100644 --- a/src/sage/rings/padics/lattice_precision.py +++ b/src/sage/rings/padics/lattice_precision.py @@ -32,7 +32,7 @@ from collections import defaultdict -from sage.misc.misc import walltime +from sage.misc.timing import walltime from sage.structure.sage_object import SageObject from sage.structure.unique_representation import UniqueRepresentation diff --git a/src/sage/rings/padics/pow_computer_ext.pyx b/src/sage/rings/padics/pow_computer_ext.pyx index 060e22719df..1626990a051 100644 --- a/src/sage/rings/padics/pow_computer_ext.pyx +++ b/src/sage/rings/padics/pow_computer_ext.pyx @@ -60,7 +60,7 @@ from cysignals.signals cimport sig_on, sig_off include "sage/libs/ntl/decl.pxi" -from sage.misc.misc import cputime +from sage.misc.timing import cputime from sage.libs.gmp.mpz cimport * from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_factory from sage.libs.ntl.ntl_ZZ_pContext import ZZ_pContext_factory diff --git a/src/sage/rings/polynomial/polynomial_gf2x.pyx b/src/sage/rings/polynomial/polynomial_gf2x.pyx index 552e6d72de6..4f3df0d8dd3 100644 --- a/src/sage/rings/polynomial/polynomial_gf2x.pyx +++ b/src/sage/rings/polynomial/polynomial_gf2x.pyx @@ -143,7 +143,7 @@ cdef class Polynomial_GF2X(Polynomial_template): if g.parent() is not self.parent() or h.parent() is not self.parent(): raise TypeError("Parents of the first three parameters must match.") - from sage.misc.misc import cputime + from sage.misc.timing import cputime from sage.misc.verbose import verbose from sage.arith.misc import integer_ceil as ceil from sage.matrix.constructor import Matrix From 80c1824bd9e6968ae903c1753f38e3da5dee084d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Fri, 23 Jun 2023 10:18:12 -0700 Subject: [PATCH 138/228] Doctest cosmetics, add '# optional' --- src/sage/misc/misc.py | 5 ----- src/sage/misc/timing.py | 50 ++++++++++++++++++++--------------------- 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/src/sage/misc/misc.py b/src/sage/misc/misc.py index 691c77f81df..d7eec3a8cda 100644 --- a/src/sage/misc/misc.py +++ b/src/sage/misc/misc.py @@ -295,11 +295,6 @@ def SPYX_TMP(): except KeyError: pass -################################################################# -# timing -################################################################# - - def union(x, y=None): """ diff --git a/src/sage/misc/timing.py b/src/sage/misc/timing.py index e4cebc5fc68..64d8547e64d 100644 --- a/src/sage/misc/timing.py +++ b/src/sage/misc/timing.py @@ -37,7 +37,7 @@ def cputime(t=0, subprocesses=False): INPUT: - - ``t`` - (optional) time in CPU seconds, if ``t`` is a result + - ``t`` -- (optional) time in CPU seconds, if ``t`` is a result from an earlier call with ``subprocesses=True``, then ``subprocesses=True`` is assumed. @@ -46,26 +46,26 @@ def cputime(t=0, subprocesses=False): OUTPUT: - - ``float`` - time in CPU seconds if ``subprocesses=False`` + - ``float`` -- time in CPU seconds if ``subprocesses=False`` - - :class:`GlobalCputime` - object which holds CPU times of + - :class:`GlobalCputime` -- object which holds CPU times of subprocesses otherwise EXAMPLES:: sage: t = cputime() - sage: F = gp.factor(2^199-1) - sage: cputime(t) # somewhat random + sage: F = gp.factor(2^199-1) # optional - sage.libs.pari + sage: cputime(t) # somewhat random 0.010999000000000092 sage: t = cputime(subprocesses=True) - sage: F = gp.factor(2^199-1) - sage: cputime(t) # somewhat random + sage: F = gp.factor(2^199-1) # optional - sage.libs.pari + sage: cputime(t) # somewhat random 0.091999 sage: w = walltime() - sage: F = gp.factor(2^199-1) - sage: walltime(w) # somewhat random + sage: F = gp.factor(2^199-1) # optional - sage.libs.pari + sage: walltime(w) # somewhat random 0.58425593376159668 .. NOTE:: @@ -130,7 +130,7 @@ class GlobalCputime: Objects of this type are returned if ``subprocesses=True`` is passed to :func:`cputime`:: - sage: cputime(subprocesses=True) # indirect doctest, output random + sage: cputime(subprocesses=True) # indirect doctest, output random 0.2347431 We can use it to keep track of the CPU time spent in Singular for @@ -138,16 +138,16 @@ class GlobalCputime: sage: t = cputime(subprocesses=True) sage: P = PolynomialRing(QQ,7,'x') - sage: I = sage.rings.ideal.Katsura(P) - sage: gb = I.groebner_basis() # calls Singular - sage: cputime(subprocesses=True) - t # output random + sage: I = sage.rings.ideal.Katsura(P) # optional - sage.libs.singular + sage: gb = I.groebner_basis() # calls Singular # optional - sage.libs.singular + sage: cputime(subprocesses=True) - t # output random 0.462987 For further processing we can then convert this container to a float:: sage: t = cputime(subprocesses=True) - sage: float(t) #output somewhat random + sage: float(t) # output somewhat random 2.1088339999999999 .. SEEALSO:: @@ -173,7 +173,7 @@ def __repr__(self): """ EXAMPLES:: - sage: cputime(subprocesses=True) # indirect doctest, output random + sage: cputime(subprocesses=True) # indirect doctest, output random 0.2347431 """ return str(self.total) @@ -184,8 +184,8 @@ def __add__(self, other): sage: t = cputime(subprocesses=True) sage: P = PolynomialRing(QQ,7,'x') - sage: I = sage.rings.ideal.Katsura(P) - sage: gb = I.groebner_basis() # calls Singular + sage: I = sage.rings.ideal.Katsura(P) # optional - sage.libs.singular + sage: gb = I.groebner_basis() # calls Singular # optional - sage.libs.singular sage: cputime(subprocesses=True) + t # output random 2.798708 """ @@ -200,8 +200,8 @@ def __sub__(self, other): sage: t = cputime(subprocesses=True) sage: P = PolynomialRing(QQ,7,'x') - sage: I = sage.rings.ideal.Katsura(P) - sage: gb = I.groebner_basis() # calls Singular + sage: I = sage.rings.ideal.Katsura(P) # optional - sage.libs.singular + sage: gb = I.groebner_basis() # calls Singular # optional - sage.libs.singular sage: cputime(subprocesses=True) - t # output random 0.462987 """ @@ -215,7 +215,7 @@ def __float__(self): EXAMPLES:: sage: t = cputime(subprocesses=True) - sage: float(t) #output somewhat random + sage: float(t) # output somewhat random 2.1088339999999999 """ return float(self.total) @@ -223,24 +223,24 @@ def __float__(self): def walltime(t=0): """ - Return the wall time in second, or with optional argument t, return - the wall time since time t. "Wall time" means the time on a wall + Return the wall time in second, or with optional argument ``t``, return + the wall time since time ``t``. "Wall time" means the time on a wall clock, i.e., the actual time. INPUT: - - ``t`` - (optional) float, time in CPU seconds + - ``t`` -- (optional) float, time in CPU seconds OUTPUT: - - ``float`` - time in seconds + - ``float`` -- time in seconds EXAMPLES:: sage: w = walltime() - sage: F = factor(2^199-1) + sage: F = factor(2^199-1) # optional - sage.libs.pari sage: walltime(w) # somewhat random 0.8823847770690918 """ From e61fac94abaefc6f02a3741db4711c8011961bb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Fri, 23 Jun 2023 20:14:42 +0200 Subject: [PATCH 139/228] fully get rid of xrange() in pyx files --- .../letterplace/free_algebra_letterplace.pyx | 4 +-- .../quatalg/quaternion_algebra_cython.pyx | 4 +-- src/sage/graphs/convexity_properties.pyx | 2 +- src/sage/graphs/generic_graph_pyx.pyx | 12 +++---- src/sage/libs/ntl/ntl_GF2X_linkage.pxi | 2 +- src/sage/libs/ntl/ntl_mat_GF2E.pyx | 16 ++++----- src/sage/matrix/matrix0.pyx | 8 ++--- src/sage/matrix/matrix2.pyx | 34 +++++++++---------- src/sage/matrix/matrix_integer_dense.pyx | 10 +++--- src/sage/matrix/matrix_integer_sparse.pyx | 2 +- src/sage/matrix/matrix_mpolynomial_dense.pyx | 8 ++--- src/sage/matrix/matrix_symbolic_dense.pyx | 4 +-- src/sage/matrix/matrix_symbolic_sparse.pyx | 4 +-- src/sage/modular/pollack_stevens/dist.pyx | 2 +- src/sage/numerical/backends/glpk_backend.pyx | 2 +- src/sage/rings/complex_arb.pyx | 2 +- src/sage/rings/complex_mpc.pyx | 2 +- src/sage/rings/finite_rings/element_base.pyx | 2 +- .../rings/finite_rings/element_pari_ffelt.pyx | 4 +-- src/sage/rings/finite_rings/integer_mod.pyx | 4 +-- .../rings/laurent_series_ring_element.pyx | 4 +-- .../number_field/number_field_element.pyx | 4 +-- .../rings/padics/padic_generic_element.pyx | 2 +- src/sage/rings/polynomial/cyclotomic.pyx | 8 ++--- .../rings/polynomial/laurent_polynomial.pyx | 4 +-- .../rings/polynomial/multi_polynomial.pyx | 4 +-- .../multi_polynomial_libsingular.pyx | 2 +- .../rings/polynomial/polynomial_element.pyx | 6 ++-- src/sage/rings/polynomial/polynomial_gf2x.pyx | 6 ++-- src/sage/rings/polynomial/real_roots.pyx | 14 ++++---- src/sage/rings/power_series_ring_element.pyx | 4 +-- src/sage/rings/tate_algebra_element.pyx | 2 +- 32 files changed, 94 insertions(+), 94 deletions(-) diff --git a/src/sage/algebras/letterplace/free_algebra_letterplace.pyx b/src/sage/algebras/letterplace/free_algebra_letterplace.pyx index 806c25202f1..365f5a218fe 100644 --- a/src/sage/algebras/letterplace/free_algebra_letterplace.pyx +++ b/src/sage/algebras/letterplace/free_algebra_letterplace.pyx @@ -594,7 +594,7 @@ cdef class FreeAlgebra_letterplace(Algebra): cdef list tmp for i from 0<=i<nblocks: base = i*ngens - tmp = [(j,E[base+j]) for j in xrange(ngens) if E[base+j]] + tmp = [(j,E[base+j]) for j in range(ngens) if E[base+j]] if not tmp: continue var_ind, exp = tmp[0] @@ -627,7 +627,7 @@ cdef class FreeAlgebra_letterplace(Algebra): cdef list names = self.latex_variable_names() for i from 0<=i<nblocks: base = i*ngens - tmp = [(j,E[base+j]) for j in xrange(ngens) if E[base+j]] + tmp = [(j,E[base+j]) for j in range(ngens) if E[base+j]] if not tmp: continue var_ind, exp = tmp[0] diff --git a/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx b/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx index bce313b46bc..d9d53c600e4 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx +++ b/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx @@ -226,9 +226,9 @@ def rational_quaternions_from_integral_matrix_and_denom(A, Matrix_integer_dense mpz_init(tmp) if reverse: - rng = xrange(H.nrows()-1, -1, -1) + rng = range(H.nrows()-1, -1, -1) else: - rng = xrange(H.nrows()) + rng = range(H.nrows()) for i in rng: x = <QuaternionAlgebraElement_rational_field> QuaternionAlgebraElement_rational_field.__new__(QuaternionAlgebraElement_rational_field) diff --git a/src/sage/graphs/convexity_properties.pyx b/src/sage/graphs/convexity_properties.pyx index 8c901b5cf94..b2a96335d44 100644 --- a/src/sage/graphs/convexity_properties.pyx +++ b/src/sage/graphs/convexity_properties.pyx @@ -435,7 +435,7 @@ cdef class ConvexityProperties: p.add_variables(self._n, 0, None, True, False, False, 1, None) # We know that at least 2 vertices are required to cover the whole graph - p.add_linear_constraint([(i, 1) for i in xrange(self._n)], 2, None) + p.add_linear_constraint([(i, 1) for i in range(self._n)], 2, None) # The set of vertices generated by the current LP solution cdef bitset_t current_hull diff --git a/src/sage/graphs/generic_graph_pyx.pyx b/src/sage/graphs/generic_graph_pyx.pyx index 520ea4283e2..90ed8f64383 100644 --- a/src/sage/graphs/generic_graph_pyx.pyx +++ b/src/sage/graphs/generic_graph_pyx.pyx @@ -529,7 +529,7 @@ def length_and_string_from_graph6(s): else: # only first byte is N o = ord(s[0]) if o > 126 or o < 63: - raise RuntimeError("the string seems corrupt: valid characters are \n" + ''.join(chr(i) for i in xrange(63, 127))) + raise RuntimeError("the string seems corrupt: valid characters are \n" + ''.join(chr(i) for i in range(63, 127))) n = o - 63 s = s[1:] return n, s @@ -568,7 +568,7 @@ def binary_string_from_graph6(s, n): for i in range(len(s)): o = ord(s[i]) if o > 126 or o < 63: - raise RuntimeError("the string seems corrupt: valid characters are \n" + ''.join(chr(i) for i in xrange(63, 127))) + raise RuntimeError("the string seems corrupt: valid characters are \n" + ''.join(chr(i) for i in range(63, 127))) a = int_to_binary_string(o - 63) l.append('0'*(6 - len(a)) + a) m = "".join(l) @@ -606,7 +606,7 @@ def binary_string_from_dig6(s, n): for i in range(len(s)): o = ord(s[i]) if o > 126 or o < 63: - raise RuntimeError("the string seems corrupt: valid characters are \n" + ''.join(chr(i) for i in xrange(63, 127))) + raise RuntimeError("the string seems corrupt: valid characters are \n" + ''.join(chr(i) for i in range(63, 127))) a = int_to_binary_string(o - 63) l.append('0'*(6 - len(a)) + a) m = "".join(l) @@ -862,14 +862,14 @@ cdef class SubgraphSearch: # line_h_out[i] represents the adjacency sequence of vertex i # in h relative to vertices 0, 1, ..., i-1 - for i in xrange(self.nh): + for i in range(self.nh): self.line_h_out[i] = self.line_h_out[0] + i*self.nh self.h.adjacency_sequence_out(i, self.vertices, i, self.line_h_out[i]) # Similarly in the opposite direction (only useful if the # graphs are directed) if self.directed: - for i in xrange(self.nh): + for i in range(self.nh): self.line_h_in[i] = self.line_h_in[0] + i*self.nh self.h.adjacency_sequence_in(i, self.vertices, i, self.line_h_in[i]) @@ -935,7 +935,7 @@ cdef class SubgraphSearch: if self.active == self.nh-1: sig_off() return [self.g_vertices[self.stack[l]] - for l in xrange(self.nh)] + for l in range(self.nh)] # We are still missing several vertices ... else: diff --git a/src/sage/libs/ntl/ntl_GF2X_linkage.pxi b/src/sage/libs/ntl/ntl_GF2X_linkage.pxi index b67fc23c3a4..3f01c91ab00 100644 --- a/src/sage/libs/ntl/ntl_GF2X_linkage.pxi +++ b/src/sage/libs/ntl/ntl_GF2X_linkage.pxi @@ -180,7 +180,7 @@ cdef inline int celement_cmp(GF2X_c *a, GF2X_c *b, long parent) except -2: elif diff < 0: return -1 else: - for i in xrange(GF2X_NumBits(a[0])-1, -1, -1): + for i in range(GF2X_NumBits(a[0])-1, -1, -1): ca = GF2_conv_to_long(GF2X_coeff(a[0], i)) cb = GF2_conv_to_long(GF2X_coeff(b[0], i)) if ca < cb: diff --git a/src/sage/libs/ntl/ntl_mat_GF2E.pyx b/src/sage/libs/ntl/ntl_mat_GF2E.pyx index f88f20c63c6..46a5c9bc59e 100644 --- a/src/sage/libs/ntl/ntl_mat_GF2E.pyx +++ b/src/sage/libs/ntl/ntl_mat_GF2E.pyx @@ -726,27 +726,27 @@ cdef class ntl_mat_GF2E(): if not nonzero: if _density == 1.0: - for i in xrange(self.x.NumRows()): - for j in xrange(self.x.NumCols()): + for i in range(self.x.NumRows()): + for j in range(self.x.NumCols()): tmp = GF2E_random() mat_GF2E_setitem(&self.x, i, j, &tmp) else: - for i in xrange(self.x.NumRows()): - for j in xrange(self.x.NumCols()): + for i in range(self.x.NumRows()): + for j in range(self.x.NumCols()): if rstate.c_rand_double() <= _density: tmp = GF2E_random() mat_GF2E_setitem(&self.x, i, j, &tmp) else: if _density == 1.0: - for i in xrange(self.x.NumRows()): - for j in xrange(self.x.NumCols()): + for i in range(self.x.NumRows()): + for j in range(self.x.NumCols()): tmp = GF2E_random() while GF2E_IsZero(tmp): tmp = GF2E_random() mat_GF2E_setitem(&self.x, i, j, &tmp) else: - for i in xrange(self.x.NumRows()): - for j in xrange(self.x.NumCols()): + for i in range(self.x.NumRows()): + for j in range(self.x.NumCols()): if rstate.c_rand_double() <= _density: tmp = GF2E_random() while GF2E_IsZero(tmp): diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index 5547cea4dba..572936b9c42 100644 --- a/src/sage/matrix/matrix0.pyx +++ b/src/sage/matrix/matrix0.pyx @@ -3760,7 +3760,7 @@ cdef class Matrix(sage.structure.element.Matrix): else: L.extend( L_prime ) if return_diag: - return [d[i] for i in xrange(self._nrows)] + return [d[i] for i in range(self._nrows)] else: return True @@ -4685,7 +4685,7 @@ cdef class Matrix(sage.structure.element.Matrix): X = set(self.pivots()) np = [] - for j in xrange(self.ncols()): + for j in range(self.ncols()): if j not in X: np.append(j) np = tuple(np) @@ -5073,7 +5073,7 @@ cdef class Matrix(sage.structure.element.Matrix): raise ArithmeticError("number of rows of matrix must equal degree of vector") cdef Py_ssize_t i return sum([v[i] * self.row(i, from_list=True) - for i in xrange(self._nrows)], M(0)) + for i in range(self._nrows)], M(0)) cdef _matrix_times_vector_(self, Vector v): """ @@ -5107,7 +5107,7 @@ cdef class Matrix(sage.structure.element.Matrix): raise ArithmeticError("number of columns of matrix must equal degree of vector") cdef Py_ssize_t i return sum([self.column(i, from_list=True) * v[i] - for i in xrange(self._ncols)], M(0)) + for i in range(self._ncols)], M(0)) def iterates(self, v, n, rows=True): r""" diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index d5402d5c3b0..e1cf073d6ae 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -3171,24 +3171,24 @@ cdef class Matrix(Matrix1): A = [R.zero()] * n F[0] = - M.get_unsafe(0, 0) - for t in xrange(1,n): + for t in range(1,n): # Set a(1, t) to be M(<=t, t) # - for i in xrange(t+1): + for i in range(t+1): a.set_unsafe(0, i, M.get_unsafe(i, t)) # Set A[1, t] to be the (t)th entry in a[1, t] # A[0] = M.get_unsafe(t, t) - for p in xrange(1, t): + for p in range(1, t): # Set a(p, t) to the product of M[<=t, <=t] * a(p-1, t) # - for i in xrange(t+1): + for i in range(t+1): s = R.zero() - for j in xrange(t+1): + for j in range(t+1): s = s + M.get_unsafe(i, j) * a.get_unsafe(p-1, j) a.set_unsafe(p, i, s) @@ -3199,13 +3199,13 @@ cdef class Matrix(Matrix1): # Set A[t, t] to be M[t, <=t] * a(p-1, t) # s = R.zero() - for j in xrange(t+1): + for j in range(t+1): s = s + M.get_unsafe(t, j) * a.get_unsafe(t-1, j) A[t] = s - for p in xrange(t+1): + for p in range(t+1): s = F[p] - for k in xrange(p): + for k in range(p): s = s - A[k] * F[p-k-1] F[p] = s - A[p] @@ -6690,7 +6690,7 @@ cdef class Matrix(Matrix1): warn("Using generic algorithm for an inexact ring, which will probably give incorrect results due to numerical precision issues.") if not extend: - return Sequence(r for r,m in self.charpoly().roots() for _ in xrange(m)) + return Sequence(r for r,m in self.charpoly().roots() for _ in range(m)) # now we need to find a natural algebraic closure for the base ring K = self.base_ring() @@ -11329,7 +11329,7 @@ cdef class Matrix(Matrix1): C = B*C ranks.append(C.rank()) i += 1 - diagram = [ranks[i]-ranks[i+1] for i in xrange(len(ranks)-1)] + diagram = [ranks[i]-ranks[i+1] for i in range(len(ranks)-1)] blocks.extend([(eval, i) for i in Partition(diagram).conjugate()]) @@ -15474,7 +15474,7 @@ cdef class Matrix(Matrix1): """ d = self.smith_form(transformation=False) r = min(self.nrows(), self.ncols()) - return [d[i,i] for i in xrange(r)] + return [d[i,i] for i in range(r)] def smith_form(self, transformation=True, integral=None, exact=True): r""" @@ -16005,7 +16005,7 @@ cdef class Matrix(Matrix1): try: - for i in xrange(1, len(pivs)): + for i in range(1, len(pivs)): y = a[i][pivs[i]] I = ideal_or_fractional(R, y) s = a[0][pivs[i]] @@ -17747,7 +17747,7 @@ def _smith_diag(d, transformation=True): right = d.new_matrix(d.ncols(), d.ncols(), 1) else: left = right = None - for i in xrange(n): + for i in range(n): I = ideal_or_fractional(R, dp[i,i]) if I == ideal_or_fractional(R, 1): @@ -17757,7 +17757,7 @@ def _smith_diag(d, transformation=True): dp[i,i] = R(1) continue - for j in xrange(i+1,n): + for j in range(i+1,n): if dp[j,j] not in I: t = ideal_or_fractional(R, [dp[i,i], dp[j,j]]).gens_reduced() if len(t) > 1: @@ -17842,7 +17842,7 @@ def _generic_clear_column(m): # is invertible over R I = ideal_or_fractional(R, a[0, 0]) # need to make sure we change this when a[0,0] changes - for k in xrange(1, a.nrows()): + for k in range(1, a.nrows()): if a[k,0] not in I: try: v = ideal_or_fractional(R, a[0,0], a[k,0]).gens_reduced() @@ -17889,7 +17889,7 @@ def _generic_clear_column(m): raise ArithmeticError # now everything in column 0 is divisible by the pivot - for i in xrange(1,a.nrows()): + for i in range(1,a.nrows()): s = R( a[i, 0]/a[0, 0]) a.add_multiple_of_row(i, 0, -s ) left_mat.add_multiple_of_row(i, 0, -s) @@ -17942,7 +17942,7 @@ def _smith_onestep(m): # test if everything to the right of the pivot in row 0 is good as well isdone = True - for jj in xrange(j+1, a.ncols()): + for jj in range(j+1, a.ncols()): if a[0,jj] != 0: isdone = False diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx index 89bd3075db8..7054ebaf4af 100644 --- a/src/sage/matrix/matrix_integer_dense.pyx +++ b/src/sage/matrix/matrix_integer_dense.pyx @@ -2454,10 +2454,10 @@ cdef class Matrix_integer_dense(Matrix_dense): :meth:`elementary_divisors` """ - X = self.matrix_space()([self[i,j] for i in xrange(self._nrows-1,-1,-1) for j in xrange(self._ncols-1,-1,-1)]) + X = self.matrix_space()([self[i,j] for i in range(self._nrows-1,-1,-1) for j in range(self._ncols-1,-1,-1)]) v = X.__pari__().matsnf(1).sage() # need to reverse order of rows of U, columns of V, and both of D. - D = self.matrix_space()([v[2][i,j] for i in xrange(self._nrows-1,-1,-1) for j in xrange(self._ncols-1,-1,-1)]) + D = self.matrix_space()([v[2][i,j] for i in range(self._nrows-1,-1,-1) for j in range(self._ncols-1,-1,-1)]) if not transformation: return D @@ -2471,13 +2471,13 @@ cdef class Matrix_integer_dense(Matrix_dense): # silly special cases for matrices with 0 columns (PARI has a unique empty matrix) U = self.matrix_space(ncols = self._nrows)(1) else: - U = self.matrix_space(ncols = self._nrows)([v[0][i,j] for i in xrange(self._nrows-1,-1,-1) for j in xrange(self._nrows-1,-1,-1)]) + U = self.matrix_space(ncols = self._nrows)([v[0][i,j] for i in range(self._nrows-1,-1,-1) for j in range(self._nrows-1,-1,-1)]) if self._nrows == 0: # silly special cases for matrices with 0 rows (PARI has a unique empty matrix) V = self.matrix_space(nrows = self._ncols)(1) else: - V = self.matrix_space(nrows = self._ncols)([v[1][i,j] for i in xrange(self._ncols-1,-1,-1) for j in xrange(self._ncols-1,-1,-1)]) + V = self.matrix_space(nrows = self._ncols)([v[1][i,j] for i in range(self._ncols-1,-1,-1) for j in range(self._ncols-1,-1,-1)]) return D, U, V @@ -3310,7 +3310,7 @@ cdef class Matrix_integer_dense(Matrix_dense): #For any $i<d$, we have $\delta |b_i^*|^2 <= |b_{i+1}^* + mu_{i+1, i} b_i^* |^2$ norms = [G[i].norm()**2 for i in range(len(G))] - for i in xrange(1,self.nrows()): + for i in range(1,self.nrows()): if norms[i] < (delta - mu[i,i-1]**2) * norms[i-1]: return False return True diff --git a/src/sage/matrix/matrix_integer_sparse.pyx b/src/sage/matrix/matrix_integer_sparse.pyx index 49ed3403fca..a41677c7b6a 100644 --- a/src/sage/matrix/matrix_integer_sparse.pyx +++ b/src/sage/matrix/matrix_integer_sparse.pyx @@ -348,7 +348,7 @@ cdef class Matrix_integer_sparse(Matrix_sparse): if copy: return list(x) return x - nzc = [[] for _ in xrange(self._ncols)] + nzc = [[] for _ in range(self._ncols)] cdef Py_ssize_t i, j for i from 0 <= i < self._nrows: for j from 0 <= j < self._matrix[i].num_nonzero: diff --git a/src/sage/matrix/matrix_mpolynomial_dense.pyx b/src/sage/matrix/matrix_mpolynomial_dense.pyx index 814e0d0b135..d8819bdc7cc 100644 --- a/src/sage/matrix/matrix_mpolynomial_dense.pyx +++ b/src/sage/matrix/matrix_mpolynomial_dense.pyx @@ -265,13 +265,13 @@ cdef class Matrix_mpolynomial_dense(Matrix_generic_dense): m = len(E) n = len(E[0]) - for r in xrange(m): + for r in range(m): for c in range(n): self.set_unsafe(r, c, E[r][c]) - for c in xrange(n, self.ncols()): + for c in range(n, self.ncols()): self.set_unsafe(r, c, R._zero_element) - for r in xrange(m, self.nrows()): - for c in xrange(self.ncols()): + for r in range(m, self.nrows()): + for c in range(self.ncols()): self.set_unsafe(r, c, R._zero_element) from sage.rings.integer_ring import ZZ diff --git a/src/sage/matrix/matrix_symbolic_dense.pyx b/src/sage/matrix/matrix_symbolic_dense.pyx index 0df43084de2..b4f6f4f748f 100644 --- a/src/sage/matrix/matrix_symbolic_dense.pyx +++ b/src/sage/matrix/matrix_symbolic_dense.pyx @@ -575,7 +575,7 @@ cdef class Matrix_symbolic_dense(Matrix_generic_dense): if mp is None: mp = self._maxima_lib_().jordan().minimalPoly().expand() d = mp.hipow('x') - mp = [mp.coeff('x', i) for i in xrange(int(d) + 1)] + mp = [mp.coeff('x', i) for i in range(int(d) + 1)] mp = PolynomialRing(self.base_ring(), 'x')(mp) self.cache('minpoly', mp) return mp.change_variable_name(var) @@ -711,7 +711,7 @@ cdef class Matrix_symbolic_dense(Matrix_generic_dense): J = jordan_info.dispJordan()._sage_() if subdivide: v = [x[1] for x in jordan_info] - w = [sum(v[0:i]) for i in xrange(1, len(v))] + w = [sum(v[0:i]) for i in range(1, len(v))] J.subdivide(w, w) if transformation: P = A.diag_mode_matrix(jordan_info)._sage_() diff --git a/src/sage/matrix/matrix_symbolic_sparse.pyx b/src/sage/matrix/matrix_symbolic_sparse.pyx index 80ba1417285..29f29a04dd1 100644 --- a/src/sage/matrix/matrix_symbolic_sparse.pyx +++ b/src/sage/matrix/matrix_symbolic_sparse.pyx @@ -582,7 +582,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): if mp is None: mp = self._maxima_lib_().jordan().minimalPoly().expand() d = mp.hipow('x') - mp = [mp.coeff('x', i) for i in xrange(int(d) + 1)] + mp = [mp.coeff('x', i) for i in range(int(d) + 1)] mp = PolynomialRing(self.base_ring(), 'x')(mp) self.cache('minpoly', mp) return mp.change_variable_name(var) @@ -718,7 +718,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): J = matrix(jordan_info.dispJordan()._sage_(), sparse=True) if subdivide: v = [x[1] for x in jordan_info] - w = [sum(v[0:i]) for i in xrange(1, len(v))] + w = [sum(v[0:i]) for i in range(1, len(v))] J.subdivide(w, w) if transformation: P = A.diag_mode_matrix(jordan_info)._sage_() diff --git a/src/sage/modular/pollack_stevens/dist.pyx b/src/sage/modular/pollack_stevens/dist.pyx index f0238bc0f79..eeb93f5f8e7 100644 --- a/src/sage/modular/pollack_stevens/dist.pyx +++ b/src/sage/modular/pollack_stevens/dist.pyx @@ -277,7 +277,7 @@ cdef class Dist(ModuleElement): use_arg = False if not z: return False - for a in xrange(1, n): + for a in range(1, n): if usearg: try: z = self._unscaled_moment(a).is_zero(M - a) diff --git a/src/sage/numerical/backends/glpk_backend.pyx b/src/sage/numerical/backends/glpk_backend.pyx index 498bc869230..4b90438bc8c 100644 --- a/src/sage/numerical/backends/glpk_backend.pyx +++ b/src/sage/numerical/backends/glpk_backend.pyx @@ -549,7 +549,7 @@ cdef class GLPKBackend(GenericBackend): cdef int * rows = <int *>sig_malloc((m + 1) * sizeof(int *)) cdef int nrows = glp_get_num_rows(self.lp) - for i in xrange(m): + for i in range(m): c = constraints[i] if c < 0 or c >= nrows: diff --git a/src/sage/rings/complex_arb.pyx b/src/sage/rings/complex_arb.pyx index ee74779b208..ef432c1e945 100644 --- a/src/sage/rings/complex_arb.pyx +++ b/src/sage/rings/complex_arb.pyx @@ -3928,7 +3928,7 @@ cdef class ComplexBall(RingElement): cdef acb_ptr vec_a = _acb_vec_init(p - s) cdef acb_ptr vec_b = _acb_vec_init(q + 1 - s) cdef long j = 0 - for i in xrange(p): + for i in range(p): if i != i1: tmp = self._parent.coerce(a[i]) acb_set(&(vec_a[j]), tmp.value) diff --git a/src/sage/rings/complex_mpc.pyx b/src/sage/rings/complex_mpc.pyx index 388d37a692f..b3681ff724f 100644 --- a/src/sage/rings/complex_mpc.pyx +++ b/src/sage/rings/complex_mpc.pyx @@ -2183,7 +2183,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): tt= RealNumber(R) cdef list zlist = [z] - for i in xrange(1,n): + for i in range(1,n): z = self._new() mpfr_mul_ui(tt.value, t.value, i, rrnd) mpfr_add(tt.value, tt.value, a.value, rrnd) diff --git a/src/sage/rings/finite_rings/element_base.pyx b/src/sage/rings/finite_rings/element_base.pyx index 2050cd46256..5dc87c95f49 100755 --- a/src/sage/rings/finite_rings/element_base.pyx +++ b/src/sage/rings/finite_rings/element_base.pyx @@ -445,7 +445,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): columns = [] - for i in xrange(d): + for i in range(d): columns.append( (self * x)._vector_(reverse=reverse) ) x *= a diff --git a/src/sage/rings/finite_rings/element_pari_ffelt.pyx b/src/sage/rings/finite_rings/element_pari_ffelt.pyx index 5d16aa857b0..57c48ac2858 100644 --- a/src/sage/rings/finite_rings/element_pari_ffelt.pyx +++ b/src/sage/rings/finite_rings/element_pari_ffelt.pyx @@ -468,13 +468,13 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): if t == t_FF_FpXQ: f = cgetg(n + 2, t_POL) set_gel(f, 1, gmael(g, 2, 1)) - for i in xrange(n): + for i in range(n): xi = Integer(x[i]) set_gel(f, i + 2, _new_GEN_from_mpz_t(xi.value)) elif t == t_FF_Flxq or t == t_FF_F2xq: f = cgetg(n + 2, t_VECSMALL) set_gel(f, 1, gmael(g, 2, 1)) - for i in xrange(n): + for i in range(n): set_uel(f, i + 2, x[i]) if t == t_FF_F2xq: f = Flx_to_F2x(f) diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index 3590fa34eb7..9a77aadd7c3 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -1232,7 +1232,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): if all and e > 1 and not self.is_unit(): if self.is_zero(): # All multiples of p^ciel(e/2) vanish - return [self._parent(x) for x in xrange(0, self.__modulus.sageInteger, p**((e+1)/2))] + return [self._parent(x) for x in range(0, self.__modulus.sageInteger, p**((e+1)/2))] else: z = self.lift() val = z.valuation(p)/2 # square => valuation is even @@ -1254,7 +1254,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): p_exp = p**exp w = [self._parent(a.lift() * p_val + b) for a in u.sqrt(all=True) - for b in xrange(0, self.__modulus.sageInteger, p_exp)] + for b in range(0, self.__modulus.sageInteger, p_exp)] if p == 2: w = list(set(w)) w.sort() diff --git a/src/sage/rings/laurent_series_ring_element.pyx b/src/sage/rings/laurent_series_ring_element.pyx index 7be60fb4bff..3fac79ca180 100644 --- a/src/sage/rings/laurent_series_ring_element.pyx +++ b/src/sage/rings/laurent_series_ring_element.pyx @@ -336,7 +336,7 @@ cdef class LaurentSeries(AlgebraElement): X = self._parent.variable_name() atomic_repr = self._parent.base_ring()._repr_option('element_is_atomic') first = True - for n in xrange(m): + for n in range(m): x = v[n] e = n + valuation x = str(x) @@ -459,7 +459,7 @@ cdef class LaurentSeries(AlgebraElement): X = self._parent.latex_variable_names()[0] atomic_repr = self._parent.base_ring()._repr_option('element_is_atomic') first = True - for n in xrange(m): + for n in range(m): x = v[n] e = n + valuation x = sage.misc.latex.latex(x) diff --git a/src/sage/rings/number_field/number_field_element.pyx b/src/sage/rings/number_field/number_field_element.pyx index cc896b641ee..c8c8aa8b0ca 100644 --- a/src/sage/rings/number_field/number_field_element.pyx +++ b/src/sage/rings/number_field/number_field_element.pyx @@ -193,9 +193,9 @@ def _inverse_mod_generic(elt, I): raise ZeroDivisionError("%s is not invertible modulo %s" % (elt, I)) v = R.coordinates(1) y = R(0) - for j in xrange(n): + for j in range(n): if v[j] != 0: - y += v[j] * sum([b[j,i+n] * B[i] for i in xrange(n)]) + y += v[j] * sum([b[j,i+n] * B[i] for i in range(n)]) return I.small_residue(y) diff --git a/src/sage/rings/padics/padic_generic_element.pyx b/src/sage/rings/padics/padic_generic_element.pyx index a1beaa5110a..f68405dcc6f 100644 --- a/src/sage/rings/padics/padic_generic_element.pyx +++ b/src/sage/rings/padics/padic_generic_element.pyx @@ -2422,7 +2422,7 @@ cdef class pAdicGenericElement(LocalGenericElement): while True: # we compute the sum for the possible values for u using Horner's method inner_sum = R.zero() - for u in xrange(upper_u,0,-1): + for u in range(upper_u,0,-1): # We want u to be a p-adic unit if u%p==0: new_term = R.zero() diff --git a/src/sage/rings/polynomial/cyclotomic.pyx b/src/sage/rings/polynomial/cyclotomic.pyx index ed0558413ea..3657b929c8f 100644 --- a/src/sage/rings/polynomial/cyclotomic.pyx +++ b/src/sage/rings/polynomial/cyclotomic.pyx @@ -336,10 +336,10 @@ def cyclotomic_value(n, x): mu = 1 num = x - 1 den = 1 - for i in xrange(L): + for i in range(L): ti = 1 << i p = primes[i] - for j in xrange(ti): + for j in range(ti): xpow = xd[j]**p xd.append(xpow) md[ti + j] = -md[j] @@ -370,7 +370,7 @@ def cyclotomic_value(n, x): # If root_of_unity = (1<<L) - (1<<(i-1)) - 1 for some i < L, # then n/d == primes[i] and we need to multiply by primes[i], # otherwise n/d is composite and nothing more needs to be done. - for i in xrange(L): + for i in range(L): if root_of_unity + (1 << i) + 1 == 1 << L: ans *= primes[i] break @@ -393,4 +393,4 @@ def bateman_bound(nn): _, n = nn.val_unit(2) primes = [p for p, _ in factor(n)] j = len(primes) - return prod(primes[k] ** (2 ** (j - k - 2) - 1) for k in xrange(j - 2)) + return prod(primes[k] ** (2 ** (j - k - 2) - 1) for k in range(j - 2)) diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index 1634e061d28..b9aa5a69f8e 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -572,7 +572,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): X = self._parent.variable_name() atomic_repr = self._parent.base_ring()._repr_option('element_is_atomic') first = True - for n in xrange(m): + for n in range(m): x = v[n] e = n + valuation x = str(x) @@ -633,7 +633,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): X = self._parent.latex_variable_names()[0] atomic_repr = self._parent.base_ring()._repr_option('element_is_atomic') first = True - for n in xrange(m): + for n in range(m): x = v[n] e = n + valuation x = latex(x) diff --git a/src/sage/rings/polynomial/multi_polynomial.pyx b/src/sage/rings/polynomial/multi_polynomial.pyx index bab2f670687..a6c586f685e 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pyx +++ b/src/sage/rings/polynomial/multi_polynomial.pyx @@ -2848,12 +2848,12 @@ def _is_M_convex_(points): if p2 == p1: continue delta = list(x2 - x1 for x1, x2 in zip(p1, p2)) - for i in xrange(dim): + for i in range(dim): if p2[i] > p1[i]: # modify list_p1 to represent point p1 + e_i - e_j for various i, j list_p1[i] += 1 # add e_i # check exchange condition is satisfied by some index j - for j in xrange(dim): + for j in range(dim): if p2[j] < p1[j]: list_p1[j] -= 1 # subtract e_j exch = tuple(list_p1) # p1 + e_i - e_j diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 977989b5978..45e14eb320d 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -2728,7 +2728,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): if std_grading: result = 0 while p: - result = max(result, sum([p_GetExp(p,i,r) for i in xrange(1,r.N+1)])) + result = max(result, sum([p_GetExp(p,i,r) for i in range(1,r.N+1)])) p = pNext(p) return result return singular_polynomial_deg(p, NULL, r) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index aca24e19bd9..d0c61ab9d11 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -900,7 +900,7 @@ cdef class Polynomial(CommutativePolynomial): if pol._compiled is None: if d < 4 or d > 50000: result = pol.get_unsafe(d) - for i in xrange(d - 1, -1, -1): + for i in range(d - 1, -1, -1): result = result * a + pol.get_unsafe(i) return result pol._compiled = CompiledPolynomialFunction(pol.list()) @@ -4035,7 +4035,7 @@ cdef class Polynomial(CommutativePolynomial): cdef dict X = {} cdef list Y = self.list(copy=False) cdef Py_ssize_t i - for i in xrange(len(Y)): + for i in range(len(Y)): c = Y[i] if c: X[i] = c @@ -11549,7 +11549,7 @@ cdef class Polynomial_generic_dense(Polynomial): raise IndexError("polynomial coefficient index must be nonnegative") elif value != 0: zero = self.base_ring().zero() - for _ in xrange(len(self.__coeffs), n): + for _ in range(len(self.__coeffs), n): self.__coeffs.append(zero) self.__coeffs.append(value) diff --git a/src/sage/rings/polynomial/polynomial_gf2x.pyx b/src/sage/rings/polynomial/polynomial_gf2x.pyx index 552e6d72de6..40caf649443 100644 --- a/src/sage/rings/polynomial/polynomial_gf2x.pyx +++ b/src/sage/rings/polynomial/polynomial_gf2x.pyx @@ -308,7 +308,7 @@ def GF2X_BuildIrred_list(n): cdef GF2X_c f GF2 = FiniteField(2) GF2X_BuildIrred(f, int(n)) - return [GF2(not GF2_IsZero(GF2X_coeff(f, i))) for i in xrange(n + 1)] + return [GF2(not GF2_IsZero(GF2X_coeff(f, i))) for i in range(n + 1)] def GF2X_BuildSparseIrred_list(n): """ @@ -328,7 +328,7 @@ def GF2X_BuildSparseIrred_list(n): cdef GF2X_c f GF2 = FiniteField(2) GF2X_BuildSparseIrred(f, int(n)) - return [GF2(not GF2_IsZero(GF2X_coeff(f, i))) for i in xrange(n + 1)] + return [GF2(not GF2_IsZero(GF2X_coeff(f, i))) for i in range(n + 1)] def GF2X_BuildRandomIrred_list(n): """ @@ -350,4 +350,4 @@ def GF2X_BuildRandomIrred_list(n): current_randstate().set_seed_ntl(False) GF2X_BuildSparseIrred(tmp, int(n)) GF2X_BuildRandomIrred(f, tmp) - return [GF2(not GF2_IsZero(GF2X_coeff(f, i))) for i in xrange(n + 1)] + return [GF2(not GF2_IsZero(GF2X_coeff(f, i))) for i in range(n + 1)] diff --git a/src/sage/rings/polynomial/real_roots.pyx b/src/sage/rings/polynomial/real_roots.pyx index a5deae72c1c..55363a1c00c 100644 --- a/src/sage/rings/polynomial/real_roots.pyx +++ b/src/sage/rings/polynomial/real_roots.pyx @@ -874,7 +874,7 @@ cdef class interval_bernstein_polynomial_integer(interval_bernstein_polynomial): indicator = '=' if bitsize(err) > 17: shift = bitsize(err) - 15 - for i in xrange(len(ribp)): + for i in range(len(ribp)): ribp[i] = ribp[i] >> shift max_err = max_err >> shift err = -((-err) >> shift) @@ -943,7 +943,7 @@ cdef class interval_bernstein_polynomial_integer(interval_bernstein_polynomial): <IBP: ((0, 3, 12, 28) + [0 .. 1)) * 2^5> """ p = self.coeffs.__copy__() - for i in xrange(len(p)): + for i in range(len(p)): p[i] = p[i] >> bits return interval_bernstein_polynomial_integer(p, self.lower, self.upper, self.lsign, self.usign, -((-self.error) >> bits), self.scale_log2 + bits, self.level, self.slope_err) @@ -2038,7 +2038,7 @@ def precompute_degree_reduction_cache(n): # polynomial, and be fairly certain (absolutely certain?) that # the error in the reduced polynomial will be no better # than this product. - expected_err = max([sum([abs(x) for x in bd.row(k)]) for k in xrange(next+1)]) + expected_err = max([sum([abs(x) for x in bd.row(k)]) for k in range(next+1)]) # bdd = bd.denominator() # bdi = MatrixSpace(ZZ, next+1, samps, sparse=False)(bd * bdd) @@ -2207,7 +2207,7 @@ def cl_maximum_root_first_lambda(cl): negCounter = 0 pos = [] neg = [] - for j in xrange(n-1, -2, -1): + for j in range(n-1, -2, -1): if j < 0: coeff = 1 else: @@ -2231,7 +2231,7 @@ def cl_maximum_root_first_lambda(cl): return RIF.upper_field().zero() max_ub_log = RIF('-infinity') - for j in xrange(len(neg)): + for j in range(len(neg)): cur_ub_log = (-neg[j][0] / pos[j][0]).log() / (pos[j][1] - neg[j][1]) max_ub_log = max_ub_log.union(cur_ub_log) @@ -2283,7 +2283,7 @@ def cl_maximum_root_local_max(cl): max_pos_uses = 0 max_ub_log = RIF('-infinity') - for j in xrange(n-1, -1, -1): + for j in range(n-1, -1, -1): if cl[j] < 0: max_pos_uses = max_pos_uses+1 cur_ub_log = (-cl[j] / (max_pos_coeff >> max_pos_uses)).log() / (max_pos_exp - j) @@ -2362,7 +2362,7 @@ def root_bounds(p): ub = cl_maximum_root(cl) neg_cl = copy(cl) - for j in xrange(n-1, -1, -2): + for j in range(n-1, -1, -2): neg_cl[j] = -neg_cl[j] lb = -cl_maximum_root(neg_cl) diff --git a/src/sage/rings/power_series_ring_element.pyx b/src/sage/rings/power_series_ring_element.pyx index 857d398d75e..85ad48798eb 100644 --- a/src/sage/rings/power_series_ring_element.pyx +++ b/src/sage/rings/power_series_ring_element.pyx @@ -697,7 +697,7 @@ cdef class PowerSeries(AlgebraElement): v = self.list() m = len(v) first = True - for n in xrange(m): + for n in range(m): x = v[n] x = repr(x) if x != '0': @@ -760,7 +760,7 @@ cdef class PowerSeries(AlgebraElement): X = self._parent.latex_variable_names()[0] atomic_repr = self._parent.base_ring()._repr_option('element_is_atomic') first = True - for n in xrange(m): + for n in range(m): x = v[n] x = sage.misc.latex.latex(x) if x != '0': diff --git a/src/sage/rings/tate_algebra_element.pyx b/src/sage/rings/tate_algebra_element.pyx index 46ba3c27117..b9be89b99b6 100644 --- a/src/sage/rings/tate_algebra_element.pyx +++ b/src/sage/rings/tate_algebra_element.pyx @@ -2663,7 +2663,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): while True: # we compute the sum for the possible values for u using Horner's method inner_sum = R.zero() - for u in xrange(upper_u,0,-1): + for u in range(upper_u,0,-1): # We want u to be a p-adic unit if u % p==0: new_term = R.zero() From df4e0705300ff4290ca5e9fa7959724f5b60935e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Fri, 23 Jun 2023 20:38:33 +0200 Subject: [PATCH 140/228] advance the linter (add more checks) --- src/tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tox.ini b/src/tox.ini index 7b99e519ff7..0ceca18bd9a 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -126,8 +126,8 @@ description = # W605: invalid escape sequence ‘x’ # See https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes deps = pycodestyle -commands = pycodestyle --select E111,E21,E227,E271,E303,E306,E401,E502,E701,E702,E703,E71,E72,W291,W293,W391,W605 {posargs:{toxinidir}/sage/} - pycodestyle --select E111,E306,E401,E703,W29,W391,W605,E712,E713,E714,E721,E722 --filename *.pyx {posargs:{toxinidir}/sage/} +commands = pycodestyle --select E111,E21,E222,E227,E251,E271,E303,E306,E401,E502,E701,E702,E703,E71,E72,W291,W293,W391,W605 {posargs:{toxinidir}/sage/} + pycodestyle --select E111,E271,E275,E306,E401,E703,E712,E713,E714,E72,W29,W391,W605, --filename *.pyx {posargs:{toxinidir}/sage/} [pycodestyle] max-line-length = 160 From edcf896e649315401bfe5526a96f0945fb89fcb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Fri, 23 Jun 2023 20:47:20 +0200 Subject: [PATCH 141/228] fix E222 --- src/doc/en/website/conf.py | 6 +++--- src/sage_docbuild/conf.py | 17 +++++++++-------- src/sage_setup/autogen/giacpy-mkkeywords.py | 8 ++++---- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/doc/en/website/conf.py b/src/doc/en/website/conf.py index 099a10865c4..38f31e5d46f 100644 --- a/src/doc/en/website/conf.py +++ b/src/doc/en/website/conf.py @@ -21,7 +21,7 @@ html_static_path = [] + html_common_static_path # General information about the project. -project = "Documentation" +project = "Documentation" # The name for this set of Sphinx documents. html_title = project @@ -33,8 +33,8 @@ # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). latex_documents = [ - ('index', 'sage_documentation.tex', 'Documentation', - 'The Sage Development Team', 'manual'), + ('index', 'sage_documentation.tex', 'Documentation', + 'The Sage Development Team', 'manual'), ] # Note that this effectively replaces the index.html generated from index.rst. diff --git a/src/sage_docbuild/conf.py b/src/sage_docbuild/conf.py index 9b6b37480bf..5763d28f96d 100644 --- a/src/sage_docbuild/conf.py +++ b/src/sage_docbuild/conf.py @@ -715,7 +715,7 @@ def call_intersphinx(app, env, node, contnode): """ debug_inf(app, "???? Trying intersphinx for %s" % node['reftarget']) builder = app.builder - res = intersphinx.missing_reference( + res = intersphinx.missing_reference( app, env, node, contnode) if res: # Replace absolute links to $SAGE_DOC by relative links: this @@ -737,7 +737,7 @@ def find_sage_dangling_links(app, env, node, contnode): debug_inf(app, "==================== find_sage_dangling_links ") reftype = node['reftype'] - reftarget = node['reftarget'] + reftarget = node['reftarget'] try: doc = node['refdoc'] except KeyError: @@ -753,17 +753,18 @@ def find_sage_dangling_links(app, env, node, contnode): res = call_intersphinx(app, env, node, contnode) if res: - debug_inf(app, "++ DONE %s"%(res['refuri'])) + debug_inf(app, "++ DONE %s" % (res['refuri'])) return res - if node.get('refdomain') != 'py': # not a python file + if node.get('refdomain') != 'py': # not a python file return None try: module = node['py:module'] - cls = node['py:class'] + cls = node['py:class'] except KeyError: - debug_inf(app, "-- no module or class for :%s:%s"%(reftype, reftarget)) + debug_inf(app, "-- no module or class for :%s:%s" % (reftype, + reftarget)) return None basename = reftarget.split(".")[0] @@ -789,10 +790,10 @@ def find_sage_dangling_links(app, env, node, contnode): # adapted from sphinx/domains/python.py builder = app.builder searchmode = node.hasattr('refspecific') and 1 or 0 - matches = builder.env.domains['py'].find_obj( + matches = builder.env.domains['py'].find_obj( builder.env, module, cls, newtarget, reftype, searchmode) if not matches: - debug_inf(app, "?? no matching doc for %s"%newtarget) + debug_inf(app, "?? no matching doc for %s" % newtarget) return call_intersphinx(app, env, node, contnode) elif len(matches) > 1: env.warn(target_module, diff --git a/src/sage_setup/autogen/giacpy-mkkeywords.py b/src/sage_setup/autogen/giacpy-mkkeywords.py index b62f5ca2dc0..5d2acee1b93 100644 --- a/src/sage_setup/autogen/giacpy-mkkeywords.py +++ b/src/sage_setup/autogen/giacpy-mkkeywords.py @@ -73,14 +73,14 @@ s+='\n You almost certainly want to use one of the derived class\n :class:`Pygen` instead.\n """\n\n' Mi.write(s) -for i in mostkeywords+moremethods: +for i in mostkeywords + moremethods: p = Popen(["cas_help", i], stdout=PIPE, stderr=PIPE, universal_newlines=True) doc = p.communicate()[0] doc = doc.replace("\n", "\n ") # Indent doc - s = " def "+i+"(self,*args):\n" - s += " r'''From Giac's documentation:\n "+doc+"\n '''\n" - s += " return GiacMethods['"+i+"'](self,*args)\n\n" + s = " def " + i + "(self,*args):\n" + s += " r'''From Giac's documentation:\n " + doc + "\n '''\n" + s += " return GiacMethods['" + i + "'](self,*args)\n\n" Mi.write(s) Mi.close() From 0aaede250e60819b488c196ab412a4338f08a7b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Fri, 23 Jun 2023 20:53:29 +0200 Subject: [PATCH 142/228] remove E275 check in pyx --- src/tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tox.ini b/src/tox.ini index 0ceca18bd9a..dcd6209e503 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -127,7 +127,7 @@ description = # See https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes deps = pycodestyle commands = pycodestyle --select E111,E21,E222,E227,E251,E271,E303,E306,E401,E502,E701,E702,E703,E71,E72,W291,W293,W391,W605 {posargs:{toxinidir}/sage/} - pycodestyle --select E111,E271,E275,E306,E401,E703,E712,E713,E714,E72,W29,W391,W605, --filename *.pyx {posargs:{toxinidir}/sage/} + pycodestyle --select E111,E271,E306,E401,E703,E712,E713,E714,E72,W29,W391,W605, --filename *.pyx {posargs:{toxinidir}/sage/} [pycodestyle] max-line-length = 160 From af0fefe39d7da8d95159c3935dde563b6a1312b8 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Fri, 23 Jun 2023 15:49:35 -0700 Subject: [PATCH 143/228] src/sage/misc/all.py: Update imports --- src/sage/misc/all.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/all.py b/src/sage/misc/all.py index b58c90e5c22..da4bebdf62e 100644 --- a/src/sage/misc/all.py +++ b/src/sage/misc/all.py @@ -6,9 +6,8 @@ from .all__sagemath_repl import * from .misc import (BackslashOperator, - cputime, exists, forall, is_iterator, - random_sublist, walltime, + random_sublist, pad_zeros, SAGE_DB, newton_method_sizes, compose, @@ -135,6 +134,8 @@ from .prandom import * +from .timing import walltime, cputime + from .explain_pickle import explain_pickle, unpickle_newobj, unpickle_global, unpickle_build, unpickle_instantiate, unpickle_persistent, unpickle_extension, unpickle_appends lazy_import('sage.misc.inline_fortran', 'fortran') From 1fcdde370d7e586a57d032c940536a5f42d751f9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Fri, 23 Jun 2023 16:46:04 -0700 Subject: [PATCH 144/228] sage.features: Declare type='standard' explicitly, check against SPKG type if SAGE_ROOT/build/pkgs is available --- src/sage/features/__init__.py | 29 ++++++++++++++++------- src/sage/features/databases.py | 3 ++- src/sage/features/gfan.py | 2 +- src/sage/features/join_feature.py | 13 +++++++++-- src/sage/features/mip_backends.py | 3 ++- src/sage/features/nauty.py | 3 ++- src/sage/features/palp.py | 4 ++-- src/sage/features/sagemath.py | 38 ++++++++++++++++++------------- src/sage/features/singular.py | 2 +- src/sage/features/sphinx.py | 2 +- src/sage/features/standard.py | 32 +++++++++++++------------- src/sage/misc/package.py | 12 ++++++---- 12 files changed, 88 insertions(+), 55 deletions(-) diff --git a/src/sage/features/__init__.py b/src/sage/features/__init__.py index 30ae1701784..3e53e376217 100644 --- a/src/sage/features/__init__.py +++ b/src/sage/features/__init__.py @@ -124,6 +124,8 @@ class Feature(TrivialUniqueRepresentation): - ``url`` -- a URL for the upstream package providing the feature + - ``type`` -- (string) one of ``'standard'``, ``'optional'`` (default), ``'experimental'`` + Overwrite :meth:`_is_present` to add feature checks. EXAMPLES:: @@ -137,7 +139,7 @@ class Feature(TrivialUniqueRepresentation): sage: GapPackage("grape") is GapPackage("grape") True """ - def __init__(self, name, spkg=None, url=None, description=None): + def __init__(self, name, spkg=None, url=None, description=None, type='optional'): r""" TESTS:: @@ -154,6 +156,19 @@ def __init__(self, name, spkg=None, url=None, description=None): self._cache_is_present = None self._cache_resolution = None self._hidden = False + self._type = type + + try: + from sage.misc.package import spkg_type + except ImportError: # may be butchered in a downstream distribution + pass + else: + if spkg and (t := spkg_type(spkg)) not in (type, None): + from warnings import warn + warn(f'Feature {name} is declared {type}, ' + f'but it is provided by {spkg}, ' + f'which is declared {t} in SAGE_ROOT/build/pkgs', + stacklevel=3) def is_present(self): r""" @@ -246,7 +261,10 @@ def __repr__(self): def _spkg_type(self): r""" - Return the type of the SPKG corresponding to this feature. + Return the type of this feature. + + For features provided by an SPKG in the Sage distribution, + this should match the SPKG type, or a warning will be issued. EXAMPLES:: @@ -257,13 +275,8 @@ def _spkg_type(self): OUTPUT: The type as a string in ``('base', 'standard', 'optional', 'experimental')``. - If no SPKG corresponds to this feature ``None`` is returned. """ - from sage.misc.package import _spkg_type - spkg = self.spkg - if not spkg: - spkg = self.name - return _spkg_type(spkg) + return self._type def resolution(self): r""" diff --git a/src/sage/features/databases.py b/src/sage/features/databases.py index 216dbb04af3..f9b297b1e30 100644 --- a/src/sage/features/databases.py +++ b/src/sage/features/databases.py @@ -52,7 +52,8 @@ def __init__(self): filename='conway_polynomials.p', search_path=search_path, spkg='conway_polynomials', - description="Frank Luebeck's database of Conway polynomials") + description="Frank Luebeck's database of Conway polynomials", + type='standard') CREMONA_DATA_DIRS = set([CREMONA_MINI_DATA_DIR, CREMONA_LARGE_DATA_DIR]) diff --git a/src/sage/features/gfan.py b/src/sage/features/gfan.py index 040ea64ec5d..a58090b4c91 100644 --- a/src/sage/features/gfan.py +++ b/src/sage/features/gfan.py @@ -30,7 +30,7 @@ def __init__(self, cmd=None): name = "gfan" else: name = f"gfan_{cmd}" - Executable.__init__(self, name, executable=name, spkg="gfan") + Executable.__init__(self, name, executable=name, spkg="gfan", type='standard') def all_features(): diff --git a/src/sage/features/join_feature.py b/src/sage/features/join_feature.py index 36e8e557546..802cb433ba3 100644 --- a/src/sage/features/join_feature.py +++ b/src/sage/features/join_feature.py @@ -47,7 +47,8 @@ class JoinFeature(Feature): FeatureTestResult('xxyyyy', False) """ - def __init__(self, name, features, spkg=None, url=None, description=None): + def __init__(self, name, features, spkg=None, url=None, description=None, type=None, + **kwds): """ TESTS: @@ -69,7 +70,15 @@ def __init__(self, name, features, spkg=None, url=None, description=None): raise ValueError('given features have more than one url; provide url argument') elif len(urls) == 1: url = next(iter(urls)) - super().__init__(name, spkg=spkg, url=url, description=description) + if type is None: + if any(f._spkg_type() == 'experimental' for f in features): + type = 'experimental' + elif any(f._spkg_type() == 'optional' for f in features): + type = 'optional' + else: + type = 'standard' + + super().__init__(name, spkg=spkg, url=url, description=description, type=type, **kwds) self._features = features def _is_present(self): diff --git a/src/sage/features/mip_backends.py b/src/sage/features/mip_backends.py index d276e25abe8..98b4766c1f5 100644 --- a/src/sage/features/mip_backends.py +++ b/src/sage/features/mip_backends.py @@ -102,7 +102,8 @@ def __init__(self): JoinFeature.__init__(self, 'cvxopt', [MIPBackend('CVXOPT'), PythonModule('cvxopt')], - spkg='cvxopt') + spkg='cvxopt', + type='standard') def all_features(): diff --git a/src/sage/features/nauty.py b/src/sage/features/nauty.py index f57b5de2363..ebd2daeb311 100644 --- a/src/sage/features/nauty.py +++ b/src/sage/features/nauty.py @@ -37,7 +37,8 @@ def __init__(self, name): """ Executable.__init__(self, name=f"nauty_{name}", executable=f"{SAGE_NAUTY_BINS_PREFIX}{name}", - spkg="nauty") + spkg="nauty", + type="standard") class Nauty(JoinFeature): diff --git a/src/sage/features/palp.py b/src/sage/features/palp.py index 35758a0ecc7..b58a8fc2e54 100644 --- a/src/sage/features/palp.py +++ b/src/sage/features/palp.py @@ -36,11 +36,11 @@ def __init__(self, palpprog, suff=None): if suff: Executable.__init__(self, f"palp_{palpprog}_{suff}d", executable=f"{palpprog}-{suff}d.x", - spkg="palp") + spkg="palp", type="standard") else: Executable.__init__(self, f"palp_{palpprog}", executable=f"{palpprog}.x", - spkg="palp") + spkg="palp", type="standard") class Palp(JoinFeature): r""" diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index 969747b34e8..580be376237 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -40,7 +40,8 @@ def __init__(self): StaticFile.__init__(self, 'sagemath_doc_html', filename='html', search_path=(SAGE_DOC,), - spkg='sagemath_doc_html') + spkg='sagemath_doc_html', + type='standard') class sage__combinat(JoinFeature): @@ -67,7 +68,7 @@ def __init__(self): # Hence, we test a Python module within the package. JoinFeature.__init__(self, 'sage.combinat', [PythonModule('sage.combinat.tableau')], - spkg='sagemath_combinat') + spkg='sagemath_combinat', type="standard") class sage__geometry__polyhedron(PythonModule): @@ -90,7 +91,7 @@ def __init__(self): True """ PythonModule.__init__(self, 'sage.geometry.polyhedron', - spkg='sagemath_polyhedra') + spkg='sagemath_polyhedra', type="standard") class sage__graphs(JoinFeature): @@ -113,7 +114,7 @@ def __init__(self): """ JoinFeature.__init__(self, 'sage.graphs', [PythonModule('sage.graphs.graph')], - spkg='sagemath_graphs') + spkg='sagemath_graphs', type="standard") class sage__modular(JoinFeature): @@ -136,7 +137,7 @@ def __init__(self): """ JoinFeature.__init__(self, 'sage.modular', [PythonModule('sage.modular.modform.eisenstein_submodule')], - spkg='sagemath_schemes') + spkg='sagemath_schemes', type='standard') class sage__groups(JoinFeature): @@ -158,7 +159,8 @@ def __init__(self): True """ JoinFeature.__init__(self, 'sage.groups', - [PythonModule('sage.groups.perm_gps.permgroup')]) + [PythonModule('sage.groups.perm_gps.permgroup')], + spkg='sagemath_groups', type='standard') class sage__libs__flint(JoinFeature): @@ -183,7 +185,7 @@ def __init__(self): JoinFeature.__init__(self, 'sage.libs.flint', [PythonModule('sage.libs.flint.flint'), PythonModule('sage.libs.arb.arith')], - spkg='sagemath_flint') + spkg='sagemath_flint', type='standard') class sage__libs__ntl(JoinFeature): @@ -207,7 +209,7 @@ def __init__(self): """ JoinFeature.__init__(self, 'sage.libs.ntl', [PythonModule('sage.libs.ntl.convert')], - spkg='sagemath_ntl') + spkg='sagemath_ntl', type='standard') class sage__libs__pari(JoinFeature): @@ -230,7 +232,7 @@ def __init__(self): """ JoinFeature.__init__(self, 'sage.libs.pari', [PythonModule('sage.libs.pari.convert_sage')], - spkg='sagemath_pari') + spkg='sagemath_pari', type='standard') class sage__modules(JoinFeature): @@ -253,7 +255,7 @@ def __init__(self): """ JoinFeature.__init__(self, 'sage.modules', [PythonModule('sage.modules.free_module')], - spkg='sagemath_modules') + spkg='sagemath_modules', type='standard') class sage__plot(JoinFeature): @@ -276,7 +278,7 @@ def __init__(self): """ JoinFeature.__init__(self, 'sage.plot', [PythonModule('sage.plot.plot')], - spkg='sagemath_symbolics') + spkg='sagemath_symbolics', type='standard') class sage__rings__finite_rings(JoinFeature): @@ -299,7 +301,8 @@ def __init__(self): True """ JoinFeature.__init__(self, 'sage.rings.finite_rings', - [PythonModule('sage.rings.finite_rings.element_pari_ffelt')]) + [PythonModule('sage.rings.finite_rings.element_pari_ffelt')], + type='standard') class sage__rings__function_field(JoinFeature): @@ -322,7 +325,8 @@ def __init__(self): """ JoinFeature.__init__(self, 'sage.rings.function_field', [PythonModule('sage.rings.function_field.function_field_polymod'), - sage__libs__singular()]) + sage__libs__singular()], + type='standard') class sage__rings__number_field(JoinFeature): @@ -344,7 +348,8 @@ def __init__(self): True """ JoinFeature.__init__(self, 'sage.rings.number_field', - [PythonModule('sage.rings.number_field.number_field_element')]) + [PythonModule('sage.rings.number_field.number_field_element')], + type='standard') class sage__rings__padics(JoinFeature): @@ -366,7 +371,8 @@ def __init__(self): True """ JoinFeature.__init__(self, 'sage.rings.padics', - [PythonModule('sage.rings.padics.factory')]) + [PythonModule('sage.rings.padics.factory')], + type='standard') class sage__rings__polynomial__pbori(JoinFeature): @@ -389,7 +395,7 @@ def __init__(self): """ JoinFeature.__init__(self, 'sage.rings.polynomial.pbori', [PythonModule('sage.rings.polynomial.pbori.pbori')], - spkg='sagemath_brial') + spkg='sagemath_brial', type='standard') class sage__rings__real_double(PythonModule): diff --git a/src/sage/features/singular.py b/src/sage/features/singular.py index 5c83ff8a099..64a24320044 100644 --- a/src/sage/features/singular.py +++ b/src/sage/features/singular.py @@ -35,7 +35,7 @@ def __init__(self): True """ Executable.__init__(self, "singular", SINGULAR_BIN, - spkg='singular') + spkg='singular', type='standard') class sage__libs__singular(JoinFeature): diff --git a/src/sage/features/sphinx.py b/src/sage/features/sphinx.py index c83370cf28a..a70e8a11eee 100644 --- a/src/sage/features/sphinx.py +++ b/src/sage/features/sphinx.py @@ -35,7 +35,7 @@ def __init__(self): sage: isinstance(Sphinx(), Sphinx) True """ - PythonModule.__init__(self, 'sphinx', spkg='sphinx') + PythonModule.__init__(self, 'sphinx', spkg='sphinx', type='standard') def all_features(): diff --git a/src/sage/features/standard.py b/src/sage/features/standard.py index 54d1f804cef..c2090fc53a4 100644 --- a/src/sage/features/standard.py +++ b/src/sage/features/standard.py @@ -18,19 +18,19 @@ def all_features(): - return [PythonModule('cvxopt', spkg='cvxopt'), - PythonModule('fpylll', spkg='fpylll'), - JoinFeature('ipython', (PythonModule('IPython'),), spkg='ipython'), - JoinFeature('lrcalc_python', (PythonModule('lrcalc'),), spkg='lrcalc_python'), - PythonModule('mpmath', spkg='mpmath'), - PythonModule('networkx', spkg='networkx'), - PythonModule('numpy', spkg='numpy'), - PythonModule('pexpect', spkg='pexpect'), - JoinFeature('pillow', (PythonModule('PIL'),), spkg='pillow'), - JoinFeature('pplpy', (PythonModule('ppl'),), spkg='pplpy'), - PythonModule('primecountpy', spkg='primecountpy'), - PythonModule('ptyprocess', spkg='ptyprocess'), - PythonModule('pyparsing', spkg='pyparsing'), - PythonModule('requests', spkg='requests'), - PythonModule('scipy', spkg='scipy'), - PythonModule('sympy', spkg='sympy')] + return [PythonModule('cvxopt', spkg='cvxopt', type='standard'), + PythonModule('fpylll', spkg='fpylll', type='standard'), + JoinFeature('ipython', (PythonModule('IPython'),), spkg='ipython', type='standard'), + JoinFeature('lrcalc_python', (PythonModule('lrcalc'),), spkg='lrcalc_python', type='standard'), + PythonModule('mpmath', spkg='mpmath', type='standard'), + PythonModule('networkx', spkg='networkx', type='standard'), + PythonModule('numpy', spkg='numpy', type='standard'), + PythonModule('pexpect', spkg='pexpect', type='standard'), + JoinFeature('pillow', (PythonModule('PIL'),), spkg='pillow', type='standard'), + JoinFeature('pplpy', (PythonModule('ppl'),), spkg='pplpy', type='standard'), + PythonModule('primecountpy', spkg='primecountpy', type='standard'), + PythonModule('ptyprocess', spkg='ptyprocess', type='standard'), + PythonModule('pyparsing', spkg='pyparsing', type='standard'), + PythonModule('requests', spkg='requests', type='standard'), + PythonModule('scipy', spkg='scipy', type='standard'), + PythonModule('sympy', spkg='sympy', type='standard')] diff --git a/src/sage/misc/package.py b/src/sage/misc/package.py index f6c7cccc113..86d2ced7173 100644 --- a/src/sage/misc/package.py +++ b/src/sage/misc/package.py @@ -124,7 +124,8 @@ def pip_remote_version(pkg, pypi_url=DEFAULT_PYPI, ignore_URLError=False): stable_releases = [v for v in info['releases'] if 'a' not in v and 'b' not in v] return max(stable_releases) -def _spkg_type(name): + +def spkg_type(name): r""" Return the type of the Sage package with the given name. @@ -135,14 +136,15 @@ def _spkg_type(name): EXAMPLES:: - sage: from sage.misc.package import _spkg_type - sage: _spkg_type('pip') + sage: from sage.misc.package import spkg_type + sage: spkg_type('pip') 'standard' OUTPUT: The type as a string in ``('base', 'standard', 'optional', 'experimental')``. - If no ``SPKG`` exists with the given name ``None`` is returned. + If no ``SPKG`` exists with the given name (or the directory ``SAGE_PKGS`` is + not avaialble), ``None`` is returned. """ spkg_type = None from sage.env import SAGE_PKGS @@ -342,7 +344,7 @@ def list_packages(*pkg_types: str, pkg_sources: List[str] = ['normal', 'pip', 's for p in lp: - typ = _spkg_type(p) + typ = spkg_type(p) if not typ: continue From fd8a32d3db7b1d0d90c1f1306bd49bd0fba4d2df Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Fri, 23 Jun 2023 20:23:23 -0700 Subject: [PATCH 145/228] Terminology change --- src/sage/features/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/features/__init__.py b/src/sage/features/__init__.py index 3e53e376217..121aaf03804 100644 --- a/src/sage/features/__init__.py +++ b/src/sage/features/__init__.py @@ -160,7 +160,7 @@ def __init__(self, name, spkg=None, url=None, description=None, type='optional') try: from sage.misc.package import spkg_type - except ImportError: # may be butchered in a downstream distribution + except ImportError: # may have been surgically removed in a downstream distribution pass else: if spkg and (t := spkg_type(spkg)) not in (type, None): From f89e4964a1ae5c5abfbfd3a9b1368ef8936f2e69 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Fri, 23 Jun 2023 23:18:10 -0700 Subject: [PATCH 146/228] src/sage/quadratic_forms/quadratic_form__theta.py: Update import --- src/sage/quadratic_forms/quadratic_form__theta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/quadratic_forms/quadratic_form__theta.py b/src/sage/quadratic_forms/quadratic_form__theta.py index c706d7e4de5..98b955f60e4 100644 --- a/src/sage/quadratic_forms/quadratic_form__theta.py +++ b/src/sage/quadratic_forms/quadratic_form__theta.py @@ -307,7 +307,7 @@ def theta_series_degree_2(Q, prec): """ from sage.arith.misc import integer_floor as floor from sage.misc.functional import sqrt - from sage.misc.misc import cputime + from sage.misc.timing import cputime from sage.misc.verbose import verbose if Q.base_ring() != ZZ: From f142ede062bb35a8a03ad3b705439a7092a8a30f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Sat, 24 Jun 2023 08:50:40 +0200 Subject: [PATCH 147/228] tweaks for config --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 65a3dcbacb8..30b331ec665 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -27,7 +27,7 @@ "python.linting.enabled": true, // The following pycodestyle arguments are the same as the pycodestyle-minimal // tox environnment, see the file SAGE_ROOT/src/tox.ini - "python.linting.pycodestyleArgs": ["--select= E111,E211,E271,E303,E306,E401,E502,E701,E702,E703,E714,W291,W293,W391,W605,E711,E712,E713,E721,E722"], + "python.linting.pycodestyleArgs": ["--select= E111,E21,E222,E227,E251,E271,E303,E306,E401,E502,E701,E702,E703,E71,E72,W291,W293,W391,W605"], "cSpell.words": [ "furo", "Conda", From 89b31c0a56e709ee602c7b29eed54b2ed8326acf Mon Sep 17 00:00:00 2001 From: Dima Pasechnik <dimpase@gmail.com> Date: Sat, 24 Jun 2023 10:20:10 +0100 Subject: [PATCH 148/228] move bliss_find_automorphisms.h to subdir --- src/sage/graphs/bliss.pyx | 2 +- src/sage/graphs/{ => bliss_cpp}/bliss_find_automorphisms.h | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/sage/graphs/{ => bliss_cpp}/bliss_find_automorphisms.h (100%) diff --git a/src/sage/graphs/bliss.pyx b/src/sage/graphs/bliss.pyx index b9880972b92..373b99f4d5e 100644 --- a/src/sage/graphs/bliss.pyx +++ b/src/sage/graphs/bliss.pyx @@ -59,7 +59,7 @@ cdef extern from "bliss/digraph.hh" namespace "bliss": const unsigned int* canonical_form(Stats&) unsigned int get_hash() -cdef extern from "bliss_find_automorphisms.h": +cdef extern from "bliss_cpp/bliss_find_automorphisms.h": void bliss_find_automorphisms(Graph*, void (*)(void*, unsigned int, const unsigned int*), void*, Stats&) void bliss_find_automorphisms(Digraph*, void (*)(void*, unsigned int, const unsigned int*), void*, Stats&) diff --git a/src/sage/graphs/bliss_find_automorphisms.h b/src/sage/graphs/bliss_cpp/bliss_find_automorphisms.h similarity index 100% rename from src/sage/graphs/bliss_find_automorphisms.h rename to src/sage/graphs/bliss_cpp/bliss_find_automorphisms.h From 50205e192b9f2ebd114f80694770b7cdb4ed651f Mon Sep 17 00:00:00 2001 From: Jing Guo <dev.guoj@gmail.com> Date: Sat, 24 Jun 2023 13:10:02 +0000 Subject: [PATCH 149/228] projective_morphism.py: Format doc --- src/sage/schemes/projective/projective_morphism.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 6b22c6b3c02..2d786a3db39 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -928,7 +928,8 @@ def normalize_coordinates(self, **kwds): Defn: Defined on coordinates by sending (z : w) to ((3*a)*z^2 + (3*a)*w^2 : z*w) """ - # if ideal or valuation is specified, we scale according the norm defined by the ideal/valuation + # If ideal or valuation is specified, we scale according the norm + # defined by the ideal/valuation ideal = kwds.pop('ideal', None) if ideal is not None: from sage.rings.number_field.number_field_ideal import NumberFieldFractionalIdeal @@ -960,6 +961,7 @@ def normalize_coordinates(self, **kwds): min_val = min(valuations) self.scale_by(uniformizer**(-1 * min_val)) return + valuation = kwds.pop('valuation', None) if valuation is not None: from sage.rings.padics.padic_valuation import pAdicValuation_base @@ -980,8 +982,6 @@ def normalize_coordinates(self, **kwds): return R = self.domain().base_ring() - K = self.base_ring() - N = self.codomain().ambient_space().dimension_relative() + 1 # Only clear denominators from the coefficients in the ring of integers if R in NumberFields(): @@ -1007,6 +1007,8 @@ def normalize_coordinates(self, **kwds): GCD = gcd(self[0], self[1]) index = 2 + N = self.codomain().ambient_space().dimension_relative() + 1 + while GCD != 1 and index < N: GCD = gcd(GCD, self[index]) index += +1 From ad202baceeabac24a1170a24c8de9b8dbef52ca4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sat, 24 Jun 2023 09:39:34 -0700 Subject: [PATCH 150/228] Add 'type=standard' in more places --- src/sage/features/__init__.py | 2 +- src/sage/groups/braid.py | 2 +- src/sage/misc/lazy_import.pyx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/features/__init__.py b/src/sage/features/__init__.py index 121aaf03804..5deb0085a63 100644 --- a/src/sage/features/__init__.py +++ b/src/sage/features/__init__.py @@ -870,7 +870,7 @@ class CythonFeature(Feature): ....: ....: assert fabs(-1) == 1 ....: ''' - sage: fabs = CythonFeature("fabs", test_code=fabs_test_code, spkg="gcc", url="https://gnu.org") + sage: fabs = CythonFeature("fabs", test_code=fabs_test_code, spkg="gcc", url="https://gnu.org", type="standard") sage: fabs.is_present() FeatureTestResult('fabs', True) diff --git a/src/sage/groups/braid.py b/src/sage/groups/braid.py index 67f1f8e4dd9..f4ad632b332 100644 --- a/src/sage/groups/braid.py +++ b/src/sage/groups/braid.py @@ -93,7 +93,7 @@ ['leftnormalform', 'rightnormalform', 'centralizer', 'supersummitset', 'greatestcommondivisor', 'leastcommonmultiple', 'conjugatingbraid', 'ultrasummitset', 'thurston_type', 'rigidity', 'sliding_circuits'], - feature=PythonModule('sage.libs.braiding', spkg='libbraiding')) + feature=PythonModule('sage.libs.braiding', spkg='libbraiding', type='standard')) class Braid(FiniteTypeArtinGroupElement): diff --git a/src/sage/misc/lazy_import.pyx b/src/sage/misc/lazy_import.pyx index cec4114a25c..3ab404ffd02 100644 --- a/src/sage/misc/lazy_import.pyx +++ b/src/sage/misc/lazy_import.pyx @@ -1089,7 +1089,7 @@ def lazy_import(module, names, as_=None, *, An example of an import relying on a feature:: sage: from sage.features import PythonModule - sage: lazy_import('ppl', 'equation', feature=PythonModule('ppl', spkg='pplpy')) + sage: lazy_import('ppl', 'equation', feature=PythonModule('ppl', spkg='pplpy', type='standard')) sage: equation <built-in function equation> sage: lazy_import('PyNormaliz', 'NmzListConeProperties', feature=PythonModule('PyNormaliz', spkg='pynormaliz')) # optional - pynormaliz From cdd675dc0ade30c4831b3329358265da03ace9d6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sat, 24 Jun 2023 10:10:25 -0700 Subject: [PATCH 151/228] .github/workflows/doc-build.yml: For CHANGES.html, ignore git, image, index files --- .github/workflows/doc-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index f65a0e4db0e..607ec16172c 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -50,7 +50,7 @@ jobs: if [ ! -f worktree-image/.gitignore ]; then cp .gitignore worktree-image/; fi (cd worktree-image && git add -A && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) # Keep track of changes to built HTML - (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git init && (echo ".buildinfo"; echo ".inv") > .gitignore; git add -A && git commit --quiet -m "old") + (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git init && (echo "*.svg binary"; echo "*.pdf binary") >> .gitattributes && (echo ".buildinfo"; echo '*.inv'; echo '.git*'; echo '*.svg'; echo '*.pdf'; echo '*.png'; echo 'searchindex.js') > .gitignore; git add -A && git commit --quiet -m "old") - name: Incremental build id: incremental From af7bcf642815fa57c0a2cde8d3af743e8e9210c2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sat, 24 Jun 2023 15:55:56 -0700 Subject: [PATCH 152/228] pkgs/sagemath-objects/MANIFEST.in: Update comments --- pkgs/sagemath-objects/MANIFEST.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/sagemath-objects/MANIFEST.in b/pkgs/sagemath-objects/MANIFEST.in index d67bb6591a5..00c5e0dc4a1 100644 --- a/pkgs/sagemath-objects/MANIFEST.in +++ b/pkgs/sagemath-objects/MANIFEST.in @@ -82,8 +82,8 @@ graft sage/libs/gmp ## FIXME: Needed for doctesting -include sage/misc/misc.* # walltime, cputime used in sage.doctest -include sage/misc/timing.p* +include sage/misc/misc.* # some_tuples used in sage.misc.sage_unittest +include sage/misc/timing.p* # walltime, cputime used in sage.doctest global-exclude *.c From f49ec305141f026079a83e3a4e14389f3a7994eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= <tornaria@cmat.edu.uy> Date: Mon, 19 Jun 2023 20:08:09 -0300 Subject: [PATCH 153/228] Fix tests for singular 4.3.2p2 --- .../asymptotics_multivariate_generating_functions.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py b/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py index ea027e8a716..a1fe036917e 100644 --- a/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +++ b/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py @@ -1251,7 +1251,7 @@ def leinartas_decomposition(self): sage: H = R(f.denominator()) sage: ff = FFPD(G, H.factor()) sage: decomp = ff.leinartas_decomposition() - sage: decomp + sage: decomp # random - non canonical depends on singular version (0, []) + (-(x*y^2*sin(x) + x^2*y + x*y + y*sin(x) + x)*y, [(y, 1)]) + ((x*y^2*sin(x) + x^2*y + x*y + y*sin(x) + x)*x*y, [(x*y + 1, 1)]) + @@ -1611,9 +1611,7 @@ def asymptotics(self, p, alpha, N, asy_var=None, numerical=0, (-16, [(x + 2*y + z - 4, 1), (2*x + y + z - 4, 2)]) sage: alpha = [3, 3, 2] sage: decomp = F.asymptotic_decomposition(alpha); decomp - (0, []) + - (16*r*(3/x - 2/z) + 16/x - 16/z, - [(x + 2*y + z - 4, 1), (2*x + y + z - 4, 1)]) + (0, []) + (..., [(x + 2*y + z - 4, 1), (2*x + y + z - 4, 1)]) sage: F1 = decomp[1] sage: p = {x: 1, y: 1, z: 1} sage: asy = F1.asymptotics(p, alpha, 2, verbose=True) # long time From 941ca85b749cd2d6057ca709c6cf69e6d866881d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= <tornaria@cmat.edu.uy> Date: Tue, 20 Jun 2023 16:48:57 -0300 Subject: [PATCH 154/228] Fixes to support numpy 1.25.0 Mostly due to a deprecation warning: `Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)`. Also fix: - a change of output in `numpy.linalg.eig()` - a change in an exception class --- src/sage/calculus/desolvers.py | 4 ++-- src/sage/matrix/matrix2.pyx | 4 ++-- src/sage/matrix/matrix_numpy_dense.pyx | 5 +++-- src/sage/plot/plot3d/list_plot3d.py | 2 +- src/sage/plot/plot3d/plot3d.py | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/sage/calculus/desolvers.py b/src/sage/calculus/desolvers.py index 55ed3a0fe10..4cfa22a97e4 100644 --- a/src/sage/calculus/desolvers.py +++ b/src/sage/calculus/desolvers.py @@ -1598,7 +1598,7 @@ def desolve_odeint(des, ics, times, dvars, ivar=None, compute_jac=False, args=() sage: ic=epsilon sage: t=srange(0,2/epsilon,1) sage: sol=desolve_odeint(f,ic,t,y,rtol=1e-9,atol=1e-10,compute_jac=True) - sage: p=points(zip(t,sol)) + sage: p=points(zip(t,sol[:,0])) sage: p.show() Another stiff system with some optional parameters with no @@ -1637,7 +1637,7 @@ def desolve_odeint_inner(ivar): J = fast_float(J, dvar, ivar) def Dfun(y, t): - return [J(y, t)] + return [J(y.item(), t)] # n-dimensional systems: else: diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index d5402d5c3b0..a00912951c5 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -430,12 +430,12 @@ cdef class Matrix(Matrix1): try: return self.transpose().solve_right(B, check=check) except ValueError as e: - raise ValueError(str(e).replace('row', 'column')) + raise e.__class__(str(e).replace('row', 'column')) else: try: return self.transpose().solve_right(B.transpose(), check=check).transpose() except ValueError as e: - raise ValueError(str(e).replace('row', 'column')) + raise e.__class__(str(e).replace('row', 'column')) def solve_right(self, B, check=True): r""" diff --git a/src/sage/matrix/matrix_numpy_dense.pyx b/src/sage/matrix/matrix_numpy_dense.pyx index 5b75ed133ff..17867f9a65c 100644 --- a/src/sage/matrix/matrix_numpy_dense.pyx +++ b/src/sage/matrix/matrix_numpy_dense.pyx @@ -382,8 +382,9 @@ cdef class Matrix_numpy_dense(Matrix_dense): sage: m = matrix(RDF,[[1,2],[3,4]]) sage: n = m.numpy() sage: import numpy - sage: numpy.linalg.eig(n) - (array([-0.37228132, 5.37228132]), array([[-0.82456484, -0.41597356], + sage: tuple(numpy.linalg.eig(n)) + (array([-0.37228132, 5.37228132]), + array([[-0.82456484, -0.41597356], [ 0.56576746, -0.90937671]])) sage: m = matrix(RDF, 2, range(6)); m [0.0 1.0 2.0] diff --git a/src/sage/plot/plot3d/list_plot3d.py b/src/sage/plot/plot3d/list_plot3d.py index d64b766001e..0158f856dbb 100644 --- a/src/sage/plot/plot3d/list_plot3d.py +++ b/src/sage/plot/plot3d/list_plot3d.py @@ -602,7 +602,7 @@ def g(x, y): from .parametric_surface import ParametricSurface def g(x, y): - z = f([x, y]) + z = f([x, y]).item() return (x, y, z) G = ParametricSurface(g, (list(numpy.r_[xmin:xmax:num_points * j]), list(numpy.r_[ymin:ymax:num_points * j])), diff --git a/src/sage/plot/plot3d/plot3d.py b/src/sage/plot/plot3d/plot3d.py index e9bbfaa8370..9ba89595d70 100644 --- a/src/sage/plot/plot3d/plot3d.py +++ b/src/sage/plot/plot3d/plot3d.py @@ -378,7 +378,7 @@ def to_cartesian(self, func, params=None): ....: [ 0.16763356, 0.19993708, 0.31403568, 0.47359696, 0.55282422], ....: [ 0.16763356, 0.25683223, 0.16649297, 0.10594339, 0.55282422]]) sage: import scipy.interpolate - sage: f=scipy.interpolate.RectBivariateSpline(v_phi,v_theta,m_r) + sage: f=scipy.interpolate.RectBivariateSpline(v_phi,v_theta,m_r).ev sage: spherical_plot3d(f,(0,2*pi),(0,pi)) Graphics3d Object From 62ad2a36fcc204792bbf35dd3516a2492c60d76b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sat, 24 Jun 2023 21:30:30 -0700 Subject: [PATCH 155/228] Add 'type=standard' in more places that use pplpy --- src/sage/geometry/cone.py | 4 ++-- src/sage/geometry/lattice_polytope.py | 4 ++-- src/sage/geometry/polyhedron/backend_ppl.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index 80c7dc63613..d37a444a564 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -237,9 +237,9 @@ from sage.features import PythonModule lazy_import('ppl', ['C_Polyhedron', 'Generator_System', 'Constraint_System', 'Linear_Expression', 'Poly_Con_Relation'], - feature=PythonModule("ppl", spkg="pplpy")) + feature=PythonModule("ppl", spkg="pplpy", type="standard")) lazy_import('ppl', ['ray', 'point'], as_=['PPL_ray', 'PPL_point'], - feature=PythonModule("ppl", spkg="pplpy")) + feature=PythonModule("ppl", spkg="pplpy", type="standard")) def is_Cone(x): diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index f7e4e69db63..921b0004dfe 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -119,9 +119,9 @@ from sage.features import PythonModule from sage.features.palp import PalpExecutable lazy_import('ppl', ['C_Polyhedron', 'Generator_System', 'Linear_Expression'], - feature=PythonModule("ppl", spkg="pplpy")) + feature=PythonModule("ppl", spkg="pplpy", type="standard")) lazy_import('ppl', 'point', as_='PPL_point', - feature=PythonModule("ppl", spkg="pplpy")) + feature=PythonModule("ppl", spkg="pplpy", type="standard")) from sage.matrix.constructor import matrix from sage.structure.element import is_Matrix diff --git a/src/sage/geometry/polyhedron/backend_ppl.py b/src/sage/geometry/polyhedron/backend_ppl.py index 791d1a4417b..a4012616deb 100644 --- a/src/sage/geometry/polyhedron/backend_ppl.py +++ b/src/sage/geometry/polyhedron/backend_ppl.py @@ -16,7 +16,7 @@ from sage.features import PythonModule lazy_import('ppl', ['C_Polyhedron', 'Generator_System', 'Constraint_System', 'Linear_Expression', 'line', 'ray', 'point'], - feature=PythonModule("ppl", spkg="pplpy")) + feature=PythonModule("ppl", spkg="pplpy", type="standard")) ######################################################################### From ebde7302beb160526afd824b199670b15ece10ea Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sat, 24 Jun 2023 21:40:17 -0700 Subject: [PATCH 156/228] .github/workflows/doc-build.yml: Only patch versions in the old HTML output --- .github/workflows/doc-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 607ec16172c..ee2fde3db54 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -50,7 +50,7 @@ jobs: if [ ! -f worktree-image/.gitignore ]; then cp .gitignore worktree-image/; fi (cd worktree-image && git add -A && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) # Keep track of changes to built HTML - (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git init && (echo "*.svg binary"; echo "*.pdf binary") >> .gitattributes && (echo ".buildinfo"; echo '*.inv'; echo '.git*'; echo '*.svg'; echo '*.pdf'; echo '*.png'; echo 'searchindex.js') > .gitignore; git add -A && git commit --quiet -m "old") + new_version=$(cat src/VERSION.txt); (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage '$new_version' /'; git init && (echo "*.svg binary"; echo "*.pdf binary") >> .gitattributes && (echo ".buildinfo"; echo '*.inv'; echo '.git*'; echo '*.svg'; echo '*.pdf'; echo '*.png'; echo 'searchindex.js') > .gitignore; git add -A && git commit --quiet -m "old") - name: Incremental build id: incremental @@ -97,7 +97,7 @@ jobs: mkdir -p ./docs # Create changelog echo '## Preview of CHANGES.html' - (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git diff --name-only) | tee ./docs/CHANGES.txt + (cd /sage/local/share/doc/sage/html/en && git diff --name-only) | tee ./docs/CHANGES.txt (cd /sage/local/share/doc/sage/html/en && git diff; rm -rf .git) > ./docs/html.diff echo '## Preview of html.diff'; head -n 400 ./docs/html.diff (echo '<p><a href="html.diff">HTML diff</a>'; sed -E 's,(.*),<p><a href="\1">\1</a>,' ./docs/CHANGES.txt) > ./docs/CHANGES.html From 4d0a929316948f0e42f061a30ce6ad75a92cd9b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Sat, 24 Jun 2023 11:15:55 +0200 Subject: [PATCH 157/228] most cython-lint suggestions fixed in algebras/ --- .../lie_algebras/lie_algebra_element.pyx | 40 ++++++++------ .../quatalg/quaternion_algebra_cython.pyx | 46 ++++++++-------- .../quatalg/quaternion_algebra_element.pyx | 55 ++++++++----------- 3 files changed, 71 insertions(+), 70 deletions(-) diff --git a/src/sage/algebras/lie_algebras/lie_algebra_element.pyx b/src/sage/algebras/lie_algebras/lie_algebra_element.pyx index 98aa1bf653b..ec8dafeec66 100644 --- a/src/sage/algebras/lie_algebras/lie_algebra_element.pyx +++ b/src/sage/algebras/lie_algebras/lie_algebra_element.pyx @@ -17,7 +17,6 @@ AUTHORS: # https://www.gnu.org/licenses/ # **************************************************************************** -from copy import copy from cpython.object cimport Py_EQ, Py_NE, Py_GT, Py_GE from sage.misc.repr import repr_lincomb @@ -119,9 +118,11 @@ cdef class LieAlgebraElement(IndexedFreeModuleElement): return s names = self.parent().variable_names() if base_map is None: - base_map = lambda x: x + def base_map(x): + return x + return codomain.sum(base_map(c) * t._im_gens_(codomain, im_gens, names) - for t, c in self._monomial_coefficients.iteritems()) + for t, c in self._monomial_coefficients.items()) cpdef lift(self): """ @@ -166,10 +167,10 @@ cdef class LieAlgebraElement(IndexedFreeModuleElement): # does not match the generators index set of the UEA. if hasattr(self._parent, '_UEA_names_map'): names_map = self._parent._UEA_names_map - for t, c in self._monomial_coefficients.iteritems(): + for t, c in self._monomial_coefficients.items(): s += c * gen_dict[names_map[t]] else: - for t, c in self._monomial_coefficients.iteritems(): + for t, c in self._monomial_coefficients.items(): s += c * gen_dict[t] return s @@ -459,7 +460,7 @@ cdef class LieAlgebraElementWrapper(ElementWrapper): ((1,3,2), 1), ((1,3), 1)] """ cdef dict d = self.value.monomial_coefficients(copy=False) - yield from d.iteritems() + yield from d.items() # TODO: Also used for vectors, find a better name @@ -598,7 +599,8 @@ cdef class LieSubalgebraElementWrapper(LieAlgebraElementWrapper): if self._monomial_coefficients is None: sm = self.parent().module() v = sm.coordinate_vector(self.to_vector()) - self._monomial_coefficients = {k: v[k] for k in range(len(v)) if v[k]} + self._monomial_coefficients = {k: v[k] for k in range(len(v)) + if v[k]} if copy: return dict(self._monomial_coefficients) return self._monomial_coefficients @@ -861,7 +863,7 @@ cdef class StructureCoefficientsElement(LieAlgebraMatrixWrapper): """ UEA = self._parent.universal_enveloping_algebra() gens = UEA.gens() - return UEA.sum(c * gens[i] for i, c in self.value.iteritems()) + return UEA.sum(c * gens[i] for i, c in self.value.items()) cpdef dict monomial_coefficients(self, bint copy=True): """ @@ -878,7 +880,7 @@ cdef class StructureCoefficientsElement(LieAlgebraMatrixWrapper): {'x': 2, 'z': -3/2} """ I = self._parent._indices - return {I[i]: v for i, v in self.value.iteritems()} + return {I[i]: v for i, v in self.value.items()} def __getitem__(self, i): """ @@ -1066,7 +1068,8 @@ cdef class UntwistedAffineLieAlgebraElement(Element): ( alpha[1] - alphacheck[1] + 2·-alpha[1] )⊗t⁰ + ( -alpha[1] )⊗t¹ + 3⋅c + -2⋅d """ from sage.typeset.unicode_art import unicode_art, unicode_superscript - return self._repr_generic(unicode_art, unicode_art, lambda t: "t" + unicode_superscript(t), + return self._repr_generic(unicode_art, unicode_art, + lambda t: "t" + unicode_superscript(t), unicode_art('⋅'), unicode_art('⊗')) cpdef dict t_dict(self): @@ -1269,7 +1272,7 @@ cdef class UntwistedAffineLieAlgebraElement(Element): """ cdef dict d = {} for t, g in self._t_dict.items(): - for k, c in g.monomial_coefficients(copy=False).iteritems(): + for k, c in g.monomial_coefficients(copy=False).items(): d[k, t] = c if self._c_coeff: d['c'] = self._c_coeff @@ -1437,7 +1440,7 @@ class FreeLieAlgebraElement(LieAlgebraElement): if not self: return s gen_dict = UEA.gens_dict() - for t, c in self._monomial_coefficients.iteritems(): + for t, c in self._monomial_coefficients.items(): s += c * t.lift(gen_dict) return s @@ -1446,6 +1449,7 @@ class FreeLieAlgebraElement(LieAlgebraElement): Return ``self`` as a list of pairs ``(m, c)`` where ``m`` is a basis key (i.e., a key of one of the basis elements) and ``c`` is its coefficient. + This list is sorted from highest to lowest degree. EXAMPLES:: @@ -1455,8 +1459,10 @@ class FreeLieAlgebraElement(LieAlgebraElement): sage: elt.list() [([x, y], -1), (x, 1)] """ - k = lambda x: (-x[0]._grade, x[0]) if isinstance(x[0], GradedLieBracket) else (-1, x[0]) - return sorted((<dict>self._monomial_coefficients).iteritems(), key=k) + def k(x): + y = x[0] + return (-y._grade, y) if isinstance(y, GradedLieBracket) else (-1, y) + return sorted((<dict>self._monomial_coefficients).items(), key=k) def _bracket_(self, y): """ @@ -1479,8 +1485,8 @@ class FreeLieAlgebraElement(LieAlgebraElement): cdef dict d = {} zero = self.base_ring().zero() - for ml, cl in self._monomial_coefficients.iteritems(): # The left monomials - for mr, cr in y._monomial_coefficients.iteritems(): # The right monomials + for ml, cl in self._monomial_coefficients.items(): # The left monomials + for mr, cr in y._monomial_coefficients.items(): # The right monomials if ml == mr: continue if ml < mr: # Make sure ml < mr @@ -1488,7 +1494,7 @@ class FreeLieAlgebraElement(LieAlgebraElement): else: a, b = mr, ml cr = -cr - for b_elt, coeff in self.parent()._rewrite_bracket(a, b).iteritems(): + for b_elt, coeff in self.parent()._rewrite_bracket(a, b).items(): d[b_elt] = d.get(b_elt, zero) + cl * cr * coeff if d[b_elt] == zero: del d[b_elt] diff --git a/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx b/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx index bce313b46bc..a2b466f6392 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx +++ b/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx @@ -43,6 +43,7 @@ from sage.libs.flint.fmpz cimport fmpz_set_mpz from sage.libs.flint.fmpq cimport fmpq_canonicalise from sage.libs.flint.fmpq_mat cimport fmpq_mat_entry_num, fmpq_mat_entry_den, fmpq_mat_entry + def integral_matrix_and_denom_from_rational_quaternions(v, reverse=False): r""" Given a list of rational quaternions, return matrix `A` over `\ZZ` @@ -95,7 +96,6 @@ def integral_matrix_and_denom_from_rational_quaternions(v, reverse=False): # Now fill in each row x of A, multiplying it by q = d/denom(x) cdef mpz_t q - cdef mpz_t* row cdef mpz_t tmp mpz_init(q) mpz_init(tmp) @@ -104,26 +104,27 @@ def integral_matrix_and_denom_from_rational_quaternions(v, reverse=False): mpz_fdiv_q(q, d.value, x.d) if reverse: mpz_mul(tmp, q, x.x) - A.set_unsafe_mpz(n-i-1,3,tmp) + A.set_unsafe_mpz(n-i-1, 3, tmp) mpz_mul(tmp, q, x.y) - A.set_unsafe_mpz(n-i-1,2,tmp) + A.set_unsafe_mpz(n-i-1, 2, tmp) mpz_mul(tmp, q, x.z) - A.set_unsafe_mpz(n-i-1,1,tmp) + A.set_unsafe_mpz(n-i-1, 1, tmp) mpz_mul(tmp, q, x.w) - A.set_unsafe_mpz(n-i-1,0,tmp) + A.set_unsafe_mpz(n-i-1, 0, tmp) else: mpz_mul(tmp, q, x.x) - A.set_unsafe_mpz(i,0,tmp) + A.set_unsafe_mpz(i, 0, tmp) mpz_mul(tmp, q, x.y) - A.set_unsafe_mpz(i,1,tmp) + A.set_unsafe_mpz(i, 1, tmp) mpz_mul(tmp, q, x.z) - A.set_unsafe_mpz(i,2,tmp) + A.set_unsafe_mpz(i, 2, tmp) mpz_mul(tmp, q, x.w) - A.set_unsafe_mpz(i,3,tmp) + A.set_unsafe_mpz(i, 3, tmp) mpz_clear(q) mpz_clear(tmp) return A, d + def rational_matrix_from_rational_quaternions(v, reverse=False): r""" Return matrix over the rationals whose rows have entries the @@ -165,7 +166,7 @@ def rational_matrix_from_rational_quaternions(v, reverse=False): fmpz_set_mpz(fmpq_mat_entry_num(A._matrix, n-i-1, 1), x.z) fmpz_set_mpz(fmpq_mat_entry_num(A._matrix, n-i-1, 0), x.w) - if mpz_cmp_si(x.d,1): + if mpz_cmp_si(x.d, 1): for j in range(4): fmpz_set_mpz(fmpq_mat_entry_den(A._matrix, n-i-1, j), x.d) fmpq_canonicalise(fmpq_mat_entry(A._matrix, n-i-1, j)) @@ -177,13 +178,14 @@ def rational_matrix_from_rational_quaternions(v, reverse=False): fmpz_set_mpz(fmpq_mat_entry_num(A._matrix, i, 2), x.z) fmpz_set_mpz(fmpq_mat_entry_num(A._matrix, i, 3), x.w) - if mpz_cmp_si(x.d,1): + if mpz_cmp_si(x.d, 1): for j in range(4): fmpz_set_mpz(fmpq_mat_entry_den(A._matrix, i, j), x.d) fmpq_canonicalise(fmpq_mat_entry(A._matrix, i, j)) return A + def rational_quaternions_from_integral_matrix_and_denom(A, Matrix_integer_dense H, Integer d, reverse=False): r""" Given an integral matrix and denominator, returns a list of @@ -221,7 +223,7 @@ def rational_quaternions_from_integral_matrix_and_denom(A, Matrix_integer_dense cdef Integer a, b a = Integer(A.invariants()[0]) b = Integer(A.invariants()[1]) - cdef Py_ssize_t i, j + cdef Py_ssize_t i cdef mpz_t tmp mpz_init(tmp) @@ -236,26 +238,26 @@ def rational_quaternions_from_integral_matrix_and_denom(A, Matrix_integer_dense mpz_set(x.a, a.value) mpz_set(x.b, b.value) if reverse: - H.get_unsafe_mpz(i,3,tmp) + H.get_unsafe_mpz(i, 3, tmp) mpz_init_set(x.x, tmp) - H.get_unsafe_mpz(i,2,tmp) + H.get_unsafe_mpz(i, 2, tmp) mpz_init_set(x.y, tmp) - H.get_unsafe_mpz(i,1,tmp) + H.get_unsafe_mpz(i, 1, tmp) mpz_init_set(x.z, tmp) - H.get_unsafe_mpz(i,0,tmp) + H.get_unsafe_mpz(i, 0, tmp) mpz_init_set(x.w, tmp) else: - H.get_unsafe_mpz(i,0,tmp) + H.get_unsafe_mpz(i, 0, tmp) mpz_init_set(x.x, tmp) - H.get_unsafe_mpz(i,1,tmp) + H.get_unsafe_mpz(i, 1, tmp) mpz_init_set(x.y, tmp) - H.get_unsafe_mpz(i,2,tmp) + H.get_unsafe_mpz(i, 2, tmp) mpz_init_set(x.z, tmp) - H.get_unsafe_mpz(i,3,tmp) + H.get_unsafe_mpz(i, 3, tmp) mpz_init_set(x.w, tmp) mpz_init_set(x.d, d.value) - # WARNING -- we do *not* canonicalize the entries in the quaternion. This is - # I think _not_ needed for quaternion_element.pyx + # WARNING -- we do *not* canonicalize the entries in the quaternion. + # This is I think _not_ needed for quaternion_element.pyx v.append(x) mpz_clear(tmp) return v diff --git a/src/sage/algebras/quatalg/quaternion_algebra_element.pyx b/src/sage/algebras/quatalg/quaternion_algebra_element.pyx index c02c9c87c58..f6e87440fe9 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra_element.pyx +++ b/src/sage/algebras/quatalg/quaternion_algebra_element.pyx @@ -348,21 +348,21 @@ cdef class QuaternionAlgebraElement_abstract(AlgebraElement): """ cdef bint atomic = self._parent._base._repr_option('element_is_atomic') v = [] - i,j,k = self._parent.variable_names() + i, j, k = self._parent.variable_names() if x: v.append(str(x)) - c = print_coeff(y,i,atomic) + c = print_coeff(y, i, atomic) if c: v.append(c) - c = print_coeff(z,j,atomic) + c = print_coeff(z, j, atomic) if c: v.append(c) - c = print_coeff(w,k,atomic) + c = print_coeff(w, k, atomic) if c: v.append(c) if not v: return '0' - return ' + '.join(v).replace('+ -','- ') + return ' + '.join(v).replace('+ -', '- ') def _repr_(self): """ @@ -466,7 +466,8 @@ cdef class QuaternionAlgebraElement_abstract(AlgebraElement): sage: theta.reduced_norm() w^2*a*b - y^2*a - z^2*b + x^2 """ - a,b,x,y,z,w = self._parent._a,self._parent._b,self[0],self[1],self[2],self[3] + a, b = self._parent._a, self._parent._b + x, y, z, w = self[0], self[1], self[2], self[3] return w*w*a*b - y*y*a - z*z*b + x*x def __invert__(self): @@ -820,10 +821,10 @@ cdef class QuaternionAlgebraElement_generic(QuaternionAlgebraElement_abstract): x1, y1, z1, w1 = self.x, self.y, self.z, self.w x2, y2, z2, w2 = right.x, right.y, right.z, right.w - #x = x1*x2 + y1*y2*a + z1*z2*b - w1*w2*a*b - #y = x1*y2 + y1*x2 - z1*w2*b + w1*z2*b - #z = x1*z2 + y1*w2 + z1*x2 - w1*y2*a - #w = x1*w2 + y1*z2 - z1*y2 + w1*x2 + # x = x1*x2 + y1*y2*a + z1*z2*b - w1*w2*a*b + # y = x1*y2 + y1*x2 - z1*w2*b + w1*z2*b + # z = x1*z2 + y1*w2 + z1*x2 - w1*y2*a + # w = x1*w2 + y1*z2 - z1*y2 + w1*x2 t1 = x1 * x2 t2 = y1 * y2 @@ -835,7 +836,7 @@ cdef class QuaternionAlgebraElement_generic(QuaternionAlgebraElement_abstract): t8 = y1 * w2 x = t1 + a * t2 + b * (t3 - a*t4) - y = (x1 + y1)*(x2 + y2) - t1 - t2 + b*( (z1 + w1)*(z2 - w2) - t3 + t4) + y = (x1 + y1)*(x2 + y2) - t1 - t2 + b*((z1 + w1)*(z2 - w2) - t3 + t4) z = t5 - a*t6 + t7 + a*t8 w = (x2 - y2)*(z1 + w1) - t5 + t6 + (x1 + y1)*(z2 + w2) - t7 - t8 @@ -1041,7 +1042,7 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst cdef Rational x, y, z, w cdef mpz_t lcm cdef mpq_t lcm_rat - if not isinstance(v, (list,tuple)): + if not isinstance(v, (list, tuple)): try: x = Rational(v) mpz_set(self.x, mpq_numref(x.value)) @@ -1061,7 +1062,7 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst z = Rational(v[2]) w = Rational(v[3]) else: - x,y,z,w = v + x, y, z, w = v mpz_init(lcm) mpz_lcm(lcm, mpq_denref(x.value), mpq_denref(y.value)) mpz_lcm(lcm, lcm, mpq_denref(z.value)) @@ -1173,7 +1174,7 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst mpz_mul(U2, right.w, self.d) # U2 = w2 * d1 mpz_add(result.w, U1, U2) # w3 = w1 * d2 + w2 * d1 - mpz_mul(result.d, self.d, right.d) # d3 = d1 * d2 + mpz_mul(result.d, self.d, right.d) # d3 = d1 * d2 result.canonicalize() @@ -1287,7 +1288,7 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst mpz_add(s1, self.x, self.y) # s1 = x1 + y1 mpz_add(s2, self.z, self.w) # s2 = z1 + w1 - #------------------ + # ------------------ mpz_mul(U1, self.a, t4) mpz_sub(U1, t3, U1) @@ -1296,7 +1297,7 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst mpz_add(result.x, T1, U2) mpz_add(result.x, result.x, U1) - #------------------ + # ------------------ mpz_sub(U1, right.z, right.w) mpz_mul(U1, U1, s2) @@ -1309,7 +1310,7 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst mpz_mul(U2, s1, U2) mpz_add(result.y, U1, U2) - #------------------ + # ------------------ mpz_mul(U1, self.a, t8) mpz_add(U1, U1, t7) @@ -1317,7 +1318,7 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst mpz_sub(U1, U1, U2) mpz_add(result.z, U1, t5) - #------------------ + # ------------------ mpz_add(U1, right.z, right.w) mpz_mul(U1, U1, s1) @@ -1329,8 +1330,6 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst mpz_mul(U2, U2, s2) mpz_add(result.w, U1, U2) - - mpz_mul(result.d, self.d, right.d) result.canonicalize() @@ -1426,8 +1425,6 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst sage: a.reduced_trace() 2/3 """ - #return 2*self[0] - mpz_mul_si(U1, self.x, 2) cdef Rational result = Rational.__new__(Rational) mpq_set_num(result.value, U1) @@ -1456,7 +1453,6 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst # Implementation-wise, we compute the GCD's one at a time, # and quit if it ever becomes one - mpz_gcd(U1, self.d, self.x) if mpz_cmp_ui(U1, 1) != 0: mpz_gcd(U1, U1, self.y) @@ -1553,8 +1549,6 @@ cdef class QuaternionAlgebraElement_rational_field(QuaternionAlgebraElement_abst return (x, y, z, w) - - def coefficient_tuple(self): """ Return 4-tuple of rational numbers which are the coefficients of this quaternion. @@ -1733,7 +1727,7 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra fmpz_poly_set_ZZX(self.a, a.__numerator) # we will assume that the denominator of a and b are 1 fmpz_poly_set_ZZX(self.b, b.__numerator) - fmpz_poly_set_ZZX(self.modulus, (<NumberFieldElement>x).__fld_numerator.x) # and same for the modulus + fmpz_poly_set_ZZX(self.modulus, (<NumberFieldElement>x).__fld_numerator.x) # and same for the modulus def __getitem__(self, int i): """ @@ -1886,7 +1880,6 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra cdef QuaternionAlgebraElement_number_field right = _right cdef QuaternionAlgebraElement_number_field result = <QuaternionAlgebraElement_number_field> QuaternionAlgebraElement_number_field.__new__(QuaternionAlgebraElement_number_field) - fmpz_poly_set(result.a, self.a) fmpz_poly_set(result.b, self.b) fmpz_poly_set(result.modulus, self.modulus) @@ -1984,7 +1977,7 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra fmpz_poly_add(fs1, self.x, self.y) # s1 = x1 + y1 fmpz_poly_add(fs2, self.z, self.w) # s2 = z1 + w - #------------------ + # ------------------ fmpz_poly_mul(fU1, self.a, ft4) fmpz_poly_sub(fU1, ft3, fU1) @@ -1993,7 +1986,7 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra fmpz_poly_add(result.x, fT1, fU2) fmpz_poly_add(result.x, result.x, fU1) - #------------------ + # ------------------ fmpz_poly_sub(fU1, right.z, right.w) fmpz_poly_mul(fU1, fU1, fs2) @@ -2006,7 +1999,7 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra fmpz_poly_mul(fU2, fs1, fU2) fmpz_poly_add(result.y, fU1, fU2) - #------------------ + # ------------------ fmpz_poly_mul(fU1, self.a, ft8) fmpz_poly_add(fU1, fU1, ft7) @@ -2014,7 +2007,7 @@ cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstra fmpz_poly_sub(fU1, fU1, fU2) fmpz_poly_add(result.z, fU1, ft5) - #------------------ + # ------------------ fmpz_poly_add(fU1, right.z, right.w) fmpz_poly_mul(fU1, fU1, fs1) From 98a8664cc3866084ef05e35bf4eca55c32aa31e0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sat, 24 Jun 2023 23:46:43 -0700 Subject: [PATCH 158/228] src/sage/features/cddlib.py: Add type='standard' --- src/sage/features/cddlib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/features/cddlib.py b/src/sage/features/cddlib.py index b37f0304948..b8fdb6fed8e 100644 --- a/src/sage/features/cddlib.py +++ b/src/sage/features/cddlib.py @@ -34,4 +34,4 @@ def __init__(self, name='cddexec_gmp'): True """ Executable.__init__(self, name=name, executable=name, spkg="cddlib", - url="https://github.com/cddlib/cddlib") + url="https://github.com/cddlib/cddlib", type="standard") From f418290aa606fa8404c7641da1fb4b3ae22e69c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Sun, 25 Jun 2023 08:59:06 +0200 Subject: [PATCH 159/228] some pep8 fixes in symbolic (E305 and others) --- src/sage/symbolic/callable.py | 30 +- src/sage/symbolic/constants.py | 72 +- src/sage/symbolic/operators.py | 15 +- src/sage/symbolic/random_tests.py | 48 +- src/sage/symbolic/units.py | 1237 +++++++++++++++-------------- 5 files changed, 720 insertions(+), 682 deletions(-) diff --git a/src/sage/symbolic/callable.py b/src/sage/symbolic/callable.py index 787d151b38e..dc093716a34 100644 --- a/src/sage/symbolic/callable.py +++ b/src/sage/symbolic/callable.py @@ -60,14 +60,15 @@ ... SyntaxError: can...t assign to function call... """ - import sage.rings.abc from sage.symbolic.ring import SymbolicRing, SR from sage.categories.pushout import ConstructionFunctor +from sage.structure.factory import UniqueFactory -######################################################################################### + +###################################################################### # Callable functions -######################################################################################### +###################################################################### def is_CallableSymbolicExpressionRing(x): """ Return ``True`` if ``x`` is a callable symbolic expression ring. @@ -96,10 +97,10 @@ def is_CallableSymbolicExpressionRing(x): deprecation(32665, 'is_CallableSymbolicExpressionRing is deprecated; use isinstance(..., sage.rings.abc.CallableSymbolicExpressionRing instead') return isinstance(x, CallableSymbolicExpressionRing_class) + def is_CallableSymbolicExpression(x): r""" - Returns ``True`` if ``x`` is a callable symbolic - expression. + Return ``True`` if ``x`` is a callable symbolic expression. EXAMPLES:: @@ -125,6 +126,7 @@ def is_CallableSymbolicExpression(x): from sage.structure.element import Expression return isinstance(x, Expression) and isinstance(x.parent(), CallableSymbolicExpressionRing_class) + class CallableSymbolicExpressionFunctor(ConstructionFunctor): def __init__(self, arguments): """ @@ -157,7 +159,7 @@ def __repr__(self): sage: CallableSymbolicExpressionFunctor((x,y)) CallableSymbolicExpressionFunctor(x, y) """ - return "CallableSymbolicExpressionFunctor%s"%repr(self.arguments()) + return "CallableSymbolicExpressionFunctor%s" % repr(self.arguments()) def merge(self, other): """ @@ -373,9 +375,10 @@ def _repr_(self): def arguments(self): """ - Returns the arguments of ``self``. The order that the - variables appear in ``self.arguments()`` is the order that - is used in evaluating the elements of ``self``. + Return the arguments of ``self``. + + The order that the variables appear in ``self.arguments()`` is + the order that is used in evaluating the elements of ``self``. EXAMPLES:: @@ -393,7 +396,7 @@ def arguments(self): def _repr_element_(self, x): """ - Returns the string representation of the Expression ``x``. + Return the string representation of the Expression ``x``. EXAMPLES:: @@ -468,7 +471,7 @@ def _call_element_(self, _the_element, *args, **kwds): sage: f(z=100) a + 2*x + 3*y + 100 """ - if any(type(arg).__module__ == 'numpy' and type(arg).__name__ == "ndarray" for arg in args): # avoid importing + if any(type(arg).__module__ == 'numpy' and type(arg).__name__ == "ndarray" for arg in args): # avoid importing raise NotImplementedError("Numpy arrays are not supported as arguments for symbolic expressions") d = dict(zip([repr(_) for _ in self.arguments()], args)) @@ -479,7 +482,6 @@ def _call_element_(self, _the_element, *args, **kwds): __reduce__ = object.__reduce__ -from sage.structure.factory import UniqueFactory class CallableSymbolicExpressionRingFactory(UniqueFactory): def create_key(self, args, check=True): """ @@ -501,8 +503,7 @@ def create_key(self, args, check=True): def create_object(self, version, key, **extra_args): """ - Returns a CallableSymbolicExpressionRing given a version and a - key. + Return a CallableSymbolicExpressionRing given a version and a key. EXAMPLES:: @@ -512,4 +513,5 @@ def create_object(self, version, key, **extra_args): """ return CallableSymbolicExpressionRing_class(key) + CallableSymbolicExpressionRing = CallableSymbolicExpressionRingFactory('sage.symbolic.callable.CallableSymbolicExpressionRing') diff --git a/src/sage/symbolic/constants.py b/src/sage/symbolic/constants.py index fe99c7a6656..77783b4a75c 100644 --- a/src/sage/symbolic/constants.py +++ b/src/sage/symbolic/constants.py @@ -220,6 +220,8 @@ from sage.rings.infinity import (infinity, minus_infinity, unsigned_infinity) from sage.structure.richcmp import richcmp_method, op_EQ, op_GE, op_LE +from sage.symbolic.expression import register_symbol, init_pynac_I +from sage.symbolic.expression import E constants_table = {} constants_name_table = {} @@ -227,20 +229,18 @@ constants_name_table[repr(unsigned_infinity)] = unsigned_infinity constants_name_table[repr(minus_infinity)] = minus_infinity -from sage.symbolic.expression import register_symbol, init_pynac_I - I = init_pynac_I() -register_symbol(infinity, {'maxima':'inf'}, 0) -register_symbol(minus_infinity, {'maxima':'minf'}, 0) -register_symbol(unsigned_infinity, {'maxima':'infinity'}, 0) -register_symbol(I, {'mathematica':'I'}, 0) -register_symbol(True, {'giac':'true', - 'mathematica':'True', - 'maxima':'true'}, 0) -register_symbol(False, {'giac':'false', - 'mathematica':'False', - 'maxima':'false'}, 0) +register_symbol(infinity, {'maxima': 'inf'}, 0) +register_symbol(minus_infinity, {'maxima': 'minf'}, 0) +register_symbol(unsigned_infinity, {'maxima': 'infinity'}, 0) +register_symbol(I, {'mathematica': 'I'}, 0) +register_symbol(True, {'giac': 'true', + 'mathematica': 'True', + 'maxima': 'true'}, 0) +register_symbol(False, {'giac': 'false', + 'mathematica': 'False', + 'maxima': 'false'}, 0) def unpickle_Constant(class_name, name, conversions, latex, mathml, domain): @@ -271,6 +271,7 @@ def unpickle_Constant(class_name, name, conversions, latex, mathml, domain): cls = globals()[class_name] return cls(name=name) + @richcmp_method class Constant(): def __init__(self, name, conversions=None, latex=None, mathml="", @@ -290,8 +291,8 @@ def __init__(self, name, conversions=None, latex=None, mathml="", self._domain = domain for system, value in self._conversions.items(): - setattr(self, "_%s_"%system, partial(self._generic_interface, value)) - setattr(self, "_%s_init_"%system, partial(self._generic_interface_init, value)) + setattr(self, "_%s_" % system, partial(self._generic_interface, value)) + setattr(self, "_%s_init_" % system, partial(self._generic_interface_init, value)) from .expression import PynacConstant self._pynac = PynacConstant(self._name, self._latex, self._domain) @@ -510,7 +511,7 @@ def _interface_(self, I): pass try: - return getattr(self, "_%s_"%(I.name()))(I) + return getattr(self, "_%s_" % (I.name()))(I) except AttributeError: pass @@ -529,7 +530,7 @@ def _gap_(self, gap): sage: gap(p) p """ - return gap('"%s"'%self) + return gap('"%s"' % self) def _singular_(self, singular): """ @@ -546,7 +547,7 @@ def _singular_(self, singular): sage: singular(p) p """ - return singular('"%s"'%self) + return singular('"%s"' % self) class Pi(Constant): @@ -598,7 +599,7 @@ def _real_double_(self, R): def _sympy_(self): """ - Converts pi to sympy pi. + Convert pi to sympy pi. EXAMPLES:: @@ -609,6 +610,7 @@ def _sympy_(self): import sympy return sympy.pi + pi = Pi().expression() """ @@ -687,12 +689,12 @@ def _sympy_(self): # The base of the natural logarithm, e, is not a constant in GiNaC/Sage. It is # represented by exp(1). A dummy class to make this work with arithmetic and # coercion is implemented in the module sage.symbolic.expression for speed. -from sage.symbolic.expression import E e = E() # Allow for backtranslation to this symbol from Mathematica (#29833). register_symbol(e, {'mathematica': 'E'}) + class NotANumber(Constant): """ Not a Number @@ -704,7 +706,7 @@ def __init__(self, name="NaN"): sage: loads(dumps(NaN)) NaN """ - conversions=dict(matlab='NaN') + conversions = dict(matlab='NaN') Constant.__init__(self, name, conversions=conversions) def __float__(self): @@ -716,7 +718,7 @@ def __float__(self): """ return float('nan') - def _mpfr_(self,R): + def _mpfr_(self, R): """ EXAMPLES:: @@ -725,7 +727,7 @@ def _mpfr_(self,R): sage: type(_) <class 'sage.rings.real_mpfr.RealNumber'> """ - return R('NaN') #??? nan in mpfr: void mpfr_set_nan (mpfr_t x) + return R('NaN') # ??? nan in mpfr: void mpfr_set_nan (mpfr_t x) def _real_double_(self, R): """ @@ -751,8 +753,10 @@ def _sympy_(self): import sympy return sympy.nan + NaN = NotANumber().expression() + class GoldenRatio(Constant): """ The number (1+sqrt(5))/2 @@ -806,7 +810,7 @@ def __float__(self): sage: golden_ratio.__float__() 1.618033988749895 """ - return float(0.5)*(float(1.0)+math.sqrt(float(5.0))) + return 0.5 + math.sqrt(1.25) def _real_double_(self, R): """ @@ -817,7 +821,7 @@ def _real_double_(self, R): """ return R('1.61803398874989484820458') - def _mpfr_(self,R): + def _mpfr_(self, R): """ EXAMPLES:: @@ -826,7 +830,7 @@ def _mpfr_(self,R): sage: RealField(100)(golden_ratio) 1.6180339887498948482045868344 """ - return (R(1)+R(5).sqrt())/R(2) + return (R(1) + R(5).sqrt()) / R(2) def _algebraic_(self, field): """ @@ -853,8 +857,10 @@ def _sympy_(self): import sympy return sympy.GoldenRatio + golden_ratio = GoldenRatio().expression() + class Log2(Constant): """ The natural logarithm of the real number 2. @@ -918,7 +924,7 @@ def _real_double_(self, R): """ return R.log2() - def _mpfr_(self,R): + def _mpfr_(self, R): """ EXAMPLES:: @@ -929,8 +935,10 @@ def _mpfr_(self,R): """ return R.log2() + log2 = Log2().expression() + class EulerGamma(Constant): """ The limiting difference between the harmonic series and the natural @@ -964,7 +972,7 @@ def __init__(self, name='euler_gamma'): Constant.__init__(self, name, conversions=conversions, latex=r'\gamma', domain='positive') - def _mpfr_(self,R): + def _mpfr_(self, R): """ EXAMPLES:: @@ -1006,8 +1014,10 @@ def _sympy_(self): import sympy return sympy.EulerGamma + euler_gamma = EulerGamma().expression() + class Catalan(Constant): """ A number appearing in combinatorics defined as the Dirichlet beta @@ -1025,7 +1035,7 @@ def __init__(self, name='catalan'): sage: loads(dumps(catalan)) catalan """ - #kash: R is default prec + # kash: R is default prec conversions = dict(mathematica='Catalan', kash='Catalan(R)', maple='Catalan', maxima='catalan', pynac='Catalan') @@ -1074,8 +1084,10 @@ def _sympy_(self): import sympy return sympy.Catalan + catalan = Catalan().expression() + class Khinchin(Constant): """ The geometric mean of the continued fraction expansion of any @@ -1126,8 +1138,10 @@ def __float__(self): """ return 2.6854520010653064453097148355 + khinchin = Khinchin().expression() + class TwinPrime(Constant): r""" The Twin Primes constant is defined as @@ -1173,6 +1187,7 @@ def __float__(self): """ return 0.66016181584686957392781211001 + twinprime = TwinPrime().expression() @@ -1222,6 +1237,7 @@ def __float__(self): """ return 0.26149721284764278375542683861 + mertens = Mertens().expression() diff --git a/src/sage/symbolic/operators.py b/src/sage/symbolic/operators.py index e89d32f1424..738f792f853 100644 --- a/src/sage/symbolic/operators.py +++ b/src/sage/symbolic/operators.py @@ -64,12 +64,13 @@ def mul_vararg(first, *rest): operator.floordiv: '//', operator.pow: '^'} -relation_operators = {operator.eq:'==', - operator.lt:'<', - operator.gt:'>', - operator.ne:'!=', - operator.le:'<=', - operator.ge:'>='} +relation_operators = {operator.eq: '==', + operator.lt: '<', + operator.gt: '>', + operator.ne: '!=', + operator.le: '<=', + operator.ge: '>='} + class FDerivativeOperator(): r""" @@ -200,6 +201,7 @@ def parameter_set(self): """ return self._parameter_set + class DerivativeOperator(): """ Derivative operator. @@ -262,4 +264,5 @@ def __getitem__(self, args): args = (args,) return self.DerivativeOperatorWithParameters(args) + D = DerivativeOperator() diff --git a/src/sage/symbolic/random_tests.py b/src/sage/symbolic/random_tests.py index 18ef715cbc3..ebed9407776 100644 --- a/src/sage/symbolic/random_tests.py +++ b/src/sage/symbolic/random_tests.py @@ -8,7 +8,7 @@ # Copyright (C) 2008 Burcin Erocal <burcin@erocal.org> # Distributed under the terms of the GNU General Public License (GPL), # version 2 or any later version. The full text of the GPL is available at: -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ ############################################################################### @@ -22,9 +22,10 @@ from sage.functions.hypergeometric import hypergeometric from sage.functions.other import (cases, element_of) -################################################################### -### Generate random expressions for doctests ###################### -################################################################### + +############################################################## +# Generate random expressions for doctests # +############################################################## def _mk_full_functions(): r""" @@ -52,8 +53,9 @@ def _mk_full_functions(): return [(1.0, f, f.number_of_arguments()) for (name, f) in items if hasattr(f, 'number_of_arguments') and - f.number_of_arguments() > 0 and - f not in excluded] + f.number_of_arguments() > 0 and + f not in excluded] + # For creating simple expressions @@ -73,6 +75,7 @@ def _mk_full_functions(): full_internal = [(0.6, full_binary, 2), (0.2, full_unary, 1), (0.2, full_functions)] + def normalize_prob_list(pl, extra=()): r""" INPUT: @@ -118,11 +121,12 @@ def normalize_prob_list(pl, extra=()): if isinstance(val, list): norm_val = normalize_prob_list(val, extra=p_extra) for np in norm_val: - result.append(((prob/total)*np[0], np[1]) + np[2:]) + result.append(((prob / total) * np[0], np[1]) + np[2:]) else: - result.append(((prob/total), val) + p_extra) + result.append(((prob / total), val) + p_extra) return result + def choose_from_prob_list(lst): r""" INPUT: @@ -155,12 +159,13 @@ def choose_from_prob_list(lst): ....: more_samples() """ r = random() - for i in range(len(lst)-1): + for i in range(len(lst) - 1): if r < lst[i][0]: return lst[i] r -= lst[i][0] return lst[-1] + def random_integer_vector(n, length): r""" Give a random list of length *length*, consisting of nonnegative @@ -210,10 +215,11 @@ def random_integer_vector(n, length): return [n] elif length == 2: v = randint(0, n) - return [v, n-v] + return [v, n - v] else: - v = randint(0, 2*n//length) - return [v] + random_integer_vector(n-v, length-1) + v = randint(0, 2 * n // length) + return [v] + random_integer_vector(n - v, length - 1) + def random_expr_helper(n_nodes, internal, leaves, verbose): r""" @@ -256,11 +262,13 @@ def random_expr_helper(n_nodes, internal, leaves, verbose): if n_spare_nodes <= 0: n_spare_nodes = 0 nodes_per_child = random_integer_vector(n_spare_nodes, n_children) - children = [random_expr_helper(n+1, internal, leaves, verbose) for n in nodes_per_child] + children = [random_expr_helper(n + 1, internal, leaves, verbose) + for n in nodes_per_child] if verbose: print("About to apply %r to %r" % (r[1], children)) return r[1](*children) + def random_expr(size, nvars=1, ncoeffs=None, var_frac=0.5, internal=full_internal, nullary=full_nullary, nullary_frac=0.2, @@ -305,7 +313,7 @@ def random_expr(size, nvars=1, ncoeffs=None, var_frac=0.5, sgn(v1) + 1/31 """ - vars = [(1.0, SR.var('v%d' % (n+1))) for n in range(nvars)] + vars = [(1.0, SR.var('v%d' % (n + 1))) for n in range(nvars)] if ncoeffs is None: ncoeffs = size coeffs = [(1.0, coeff_generator()) for _ in range(ncoeffs)] @@ -317,9 +325,9 @@ def random_expr(size, nvars=1, ncoeffs=None, var_frac=0.5, return random_expr_helper(size, internal, leaves, verbose) -################################################################### -### Test the ordering of operands ################################# -################################################################### +##################################### +# Test the ordering of operands # +##################################### def assert_strict_weak_order(a, b, c, cmp_func): r""" @@ -435,7 +443,7 @@ def test_symbolic_expression_order(repetitions=100): nullary_frac = 0.05 def coeff_generator(): - return randint(-100,100)/randint(1,100) + return randint(-100, 100) / randint(1, 100) def make_random_expr(): while True: @@ -452,5 +460,5 @@ def make_random_expr(): b = make_random_expr() c = make_random_expr() assert_strict_weak_order(a, b, c, mixed_order) - assert_strict_weak_order(a, b, c, lambda x,y: x._cmp_add(y)) - assert_strict_weak_order(a, b, c, lambda x,y: x._cmp_mul(y)) + assert_strict_weak_order(a, b, c, lambda x, y: x._cmp_add(y)) + assert_strict_weak_order(a, b, c, lambda x, y: x._cmp_mul(y)) diff --git a/src/sage/symbolic/units.py b/src/sage/symbolic/units.py index d01c2a894e3..437d3de1b45 100644 --- a/src/sage/symbolic/units.py +++ b/src/sage/symbolic/units.py @@ -83,7 +83,7 @@ # William Stein <wstein@gmail.com> # Distributed under the terms of the GNU General Public License (GPL), # version 2 or any later version. The full text of the GPL is available at: -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ ############################################################################### # standard Python libraries @@ -101,391 +101,392 @@ unitdict = { 'acceleration': - {'gal':'1/100', - 'galileo':'1/100', - 'gravity':'9.80665000000000'}, + {'gal': '1/100', + 'galileo': '1/100', + 'gravity': '9.80665000000000'}, 'amount_of_substance': - {'elementary_entity':'1/6.02214129000000e23', - 'mole':'1'}, + {'elementary_entity': '1/6.02214129000000e23', + 'mole': '1'}, 'angles': - {'arc_minute':'1/10800*pi', - 'arc_second':'1/648000*pi', - 'degree':'1/180*pi', - 'grade':'1/200*pi', - 'quadrant':'1/2*pi', - 'radian':'1', - 'right_angle':'1/2*pi'}, + {'arc_minute': '1/10800*pi', + 'arc_second': '1/648000*pi', + 'degree': '1/180*pi', + 'grade': '1/200*pi', + 'quadrant': '1/2*pi', + 'radian': '1', + 'right_angle': '1/2*pi'}, 'area': - {'acre':'316160658/78125', - 'are':'100', - 'barn':'1/10000000000000000000000000000', - 'hectare':'10000', - 'rood':'158080329/156250', - 'section':'40468564224/15625', - 'square_chain':'158080329/390625', - 'square_meter':'1', - 'township':'1456868312064/15625'}, + {'acre': '316160658/78125', + 'are': '100', + 'barn': '1/10000000000000000000000000000', + 'hectare': '10000', + 'rood': '158080329/156250', + 'section': '40468564224/15625', + 'square_chain': '158080329/390625', + 'square_meter': '1', + 'township': '1456868312064/15625'}, 'capacitance': - {'abfarad':'1000000000', - 'farad':'1', - 'statfarad':'25000/22468879468420441'}, + {'abfarad': '1000000000', + 'farad': '1', + 'statfarad': '25000/22468879468420441'}, 'charge': - {'abcoulomb':'10', - 'coulomb':'1', - 'elementary_charge':'1.60217646200000e-19', - 'faraday':'96485.3399000000', - 'franklin':'1/2997924580', - 'statcoulomb':'1/2997924580'}, + {'abcoulomb': '10', + 'coulomb': '1', + 'elementary_charge': '1.60217646200000e-19', + 'faraday': '96485.3399000000', + 'franklin': '1/2997924580', + 'statcoulomb': '1/2997924580'}, 'conductance': - {'abmho':'1000000000', - 'mho':'1', - 'siemens':'1'}, + {'abmho': '1000000000', + 'mho': '1', + 'siemens': '1'}, 'current': - {'abampere':'10', - 'amp':'1', - 'ampere':'1', - 'biot':'10', - 'statampere':'1/2997924580'}, + {'abampere': '10', + 'amp': '1', + 'ampere': '1', + 'biot': '10', + 'statampere': '1/2997924580'}, 'electric_potential': - {'abvolt':'1/100000000', - 'statvolt':'149896229/500000', - 'volt':'1'}, + {'abvolt': '1/100000000', + 'statvolt': '149896229/500000', + 'volt': '1'}, 'energy': - {'british_thermal_unit':'52752792631/50000000', - 'btu':'52752792631/50000000', - 'calorie':'10467/2500', - 'electron_volt':'1.60217733000000e-19', - 'erg':'1/10000000', - 'ev':'1.60217733000000e-19', - 'joule':'1', - 'rydberg':'2.17987200000000e-18', - 'therm':'52752792631/500'}, + {'british_thermal_unit': '52752792631/50000000', + 'btu': '52752792631/50000000', + 'calorie': '10467/2500', + 'electron_volt': '1.60217733000000e-19', + 'erg': '1/10000000', + 'ev': '1.60217733000000e-19', + 'joule': '1', + 'rydberg': '2.17987200000000e-18', + 'therm': '52752792631/500'}, 'fiber_linear_mass_density': - {'denier':'1/9000000', - 'tex':'1/1000000'}, + {'denier': '1/9000000', + 'tex': '1/1000000'}, 'force': - {'dyne':'1/100000', - 'gram_weight':'196133/20000000', - 'kilogram_force':'196133/20000', - 'kilogram_weight':'196133/20000', - 'newton':'1', - 'pound_force':'8896443230521/2000000000000', - 'pound_weight':'8896443230521/2000000000000', - 'poundal':'17281869297/125000000000', - 'ton_force':'8896443230521/1000000000'}, + {'dyne': '1/100000', + 'gram_weight': '196133/20000000', + 'kilogram_force': '196133/20000', + 'kilogram_weight': '196133/20000', + 'newton': '1', + 'pound_force': '8896443230521/2000000000000', + 'pound_weight': '8896443230521/2000000000000', + 'poundal': '17281869297/125000000000', + 'ton_force': '8896443230521/1000000000'}, 'frequency': - {'1/second':'1', - 'hertz':'1'}, + {'1/second': '1', + 'hertz': '1'}, 'illuminance': - {'foot_candle':'1562500/145161', - 'lux':'1', - 'phot':'10000'}, + {'foot_candle': '1562500/145161', + 'lux': '1', + 'phot': '10000'}, 'inductance': - {'abhenry':'1/1000000000', - 'henry':'1', - 'stathenry':'22468879468420441/25000'}, + {'abhenry': '1/1000000000', + 'henry': '1', + 'stathenry': '22468879468420441/25000'}, 'information': - {'bit':'1', - 'byte':'8', - 'nibble':'4'}, + {'bit': '1', + 'byte': '8', + 'nibble': '4'}, 'information_rate': - {'baud':'1'}, + {'baud': '1'}, 'inverse_length': - {'diopter':'1', - 'kayser':'100'}, + {'diopter': '1', + 'kayser': '100'}, 'length': - {'angstrom':'1/10000000000', - 'astronomical_unit':'149597870691', - 'bolt':'4572/125', - 'cable_international':'926/5', - 'cable_us':'27432/125', - 'caliber':'127/500000', - 'centimeter':'1/100', - 'chain':'12573/625', - 'cicero':'125/27706', - 'cubit':'1143/2500', - 'didot':'125/332472', - 'dtp_point':'127/360000', - 'ell':'1143/1000', - 'fathom':'1143/625', - 'feet':'381/1250', - 'fermi':'1/1000000000000000', - 'foot':'381/1250', - 'furlong':'25146/125', - 'hand':'127/1250', - 'inch':'127/5000', - 'kilometer':'1000', - 'league':'603504/125', - 'light_year':'9460730472580800', - 'link':'12573/62500', - 'meter':'1', - 'micron':'1/1000000', - 'mil':'127/5000000', - 'millimeter':'1/1000', - 'mile':'201168/125', - 'nautical_mile':'1852', - 'parsec':'3.08570000000000e16', - 'perch':'12573/2500', - 'pica':'127/30000', - 'pole':'12573/2500', - 'rod':'12573/2500', - 'rope':'762/125', - 'skein':'13716/125', - 'stadion':'118491/625', - 'stadium':'115443/625', - 'statute_mile':'201168/125', - 'survey_foot':'1200/3937', - 'survey_mile':'6336000/3937', - 'x_unit':'1.00210000000000e-13', - 'yard':'1143/1250'}, + {'angstrom': '1/10000000000', + 'astronomical_unit': '149597870691', + 'bolt': '4572/125', + 'cable_international': '926/5', + 'cable_us': '27432/125', + 'caliber': '127/500000', + 'centimeter': '1/100', + 'chain': '12573/625', + 'cicero': '125/27706', + 'cubit': '1143/2500', + 'didot': '125/332472', + 'dtp_point': '127/360000', + 'ell': '1143/1000', + 'fathom': '1143/625', + 'feet': '381/1250', + 'fermi': '1/1000000000000000', + 'foot': '381/1250', + 'furlong': '25146/125', + 'hand': '127/1250', + 'inch': '127/5000', + 'kilometer': '1000', + 'league': '603504/125', + 'light_year': '9460730472580800', + 'link': '12573/62500', + 'meter': '1', + 'micron': '1/1000000', + 'mil': '127/5000000', + 'millimeter': '1/1000', + 'mile': '201168/125', + 'nautical_mile': '1852', + 'parsec': '3.08570000000000e16', + 'perch': '12573/2500', + 'pica': '127/30000', + 'pole': '12573/2500', + 'rod': '12573/2500', + 'rope': '762/125', + 'skein': '13716/125', + 'stadion': '118491/625', + 'stadium': '115443/625', + 'statute_mile': '201168/125', + 'survey_foot': '1200/3937', + 'survey_mile': '6336000/3937', + 'x_unit': '1.00210000000000e-13', + 'yard': '1143/1250'}, 'luminance': - {'apostilb':'1/pi', - 'lambert':'10000/pi', - 'nit':'1', - 'stilb':'10000'}, + {'apostilb': '1/pi', + 'lambert': '10000/pi', + 'nit': '1', + 'stilb': '10000'}, 'luminous_energy': - {'lumerg':'1', - 'talbot':'1'}, + {'lumerg': '1', + 'talbot': '1'}, 'luminous_flux': - {'lumen':'1'}, + {'lumen': '1'}, 'luminous_intensity': - {'candela':'1', - 'candle':'1', - 'hefnerkerze':'1019/1128'}, + {'candela': '1', + 'candle': '1', + 'hefnerkerze': '1019/1128'}, 'magnetic_field': - {'gauss':'1/10000', - 'tesla':'1'}, + {'gauss': '1/10000', + 'tesla': '1'}, 'magnetic_flux': - {'maxwell':'1/100000000', - 'weber':'1'}, + {'maxwell': '1/100000000', + 'weber': '1'}, 'magnetic_intensity': - {'oersted':'250/pi'}, + {'oersted': '250/pi'}, 'magnetic_moment': - {'bohr_magneton':'9.27400915000000e-24', - 'nuclear_magneton':'5.05078324000000e-27'}, + {'bohr_magneton': '9.27400915000000e-24', + 'nuclear_magneton': '5.05078324000000e-27'}, 'magnetomotive_force': - {'ampere_turn':'1', - 'gilbert':'5/2/pi'}, + {'ampere_turn': '1', + 'gilbert': '5/2/pi'}, 'mass': - {'amu':'1.66053878200000e-27', - 'assay_ton':'7/240', - 'atomic_mass_unit':'1.66053878200000e-27', - 'avoirdupois_ounce':'45359237/1600000000', - 'avoirdupois_pound':'45359237/100000000', - 'bale':'45359237/200000', - 'carat':'1/5000', - 'cental':'45359237/1000000', - 'dalton':'1.66053878200000e-27', - 'drachma':"(0.00429234000000000, {'greek':1})", - 'geepound':'14593903/1000000', - 'grain':'6479891/100000000000', - 'gram':'1/1000', - 'gross_hundredweight':'317514659/6250000', - 'hundredweight':'317514659/6250000', - 'kilogram':'1', - 'libra':'0.325971000000000', - 'long_ton':'317514659/312500', - 'metric_ton':'1000', - 'mina':"(0.429234000000000, {'greek':100})", - 'net_hundredweight':'45359237/1000000', - 'obol':"(0.000715380000000000,{'greek':1/6})", - 'ounce':'45359237/1600000000', - 'ounce_troy':'19439673/625000000', - 'pennyweight':'19439673/12500000000', - 'pondus':'0.325969000000000', - 'pound':'45359237/100000000', - 'pound_troy':'58319019/156250000', - 'quintal':'100', - 'shekel':'0.0141000000000000', - 'short_hundredweight':'45359237/1000000', - 'short_ton':'45359237/50000', - 'slug':'14593903/1000000', - 'solar_mass':'1.98892000000000e30', - 'stone':'317514659/50000000', - 'talent':"(25.7540400000000, {'greek':6000})", - 'ton':'45359237/50000', - 'tonne':'1000', - 'wey':'2857631931/25000000'}, + {'amu': '1.66053878200000e-27', + 'assay_ton': '7/240', + 'atomic_mass_unit': '1.66053878200000e-27', + 'avoirdupois_ounce': '45359237/1600000000', + 'avoirdupois_pound': '45359237/100000000', + 'bale': '45359237/200000', + 'carat': '1/5000', + 'cental': '45359237/1000000', + 'dalton': '1.66053878200000e-27', + 'drachma': "(0.00429234000000000, {'greek':1})", + 'geepound': '14593903/1000000', + 'grain': '6479891/100000000000', + 'gram': '1/1000', + 'gross_hundredweight': '317514659/6250000', + 'hundredweight': '317514659/6250000', + 'kilogram': '1', + 'libra': '0.325971000000000', + 'long_ton': '317514659/312500', + 'metric_ton': '1000', + 'mina': "(0.429234000000000, {'greek':100})", + 'net_hundredweight': '45359237/1000000', + 'obol': "(0.000715380000000000,{'greek':1/6})", + 'ounce': '45359237/1600000000', + 'ounce_troy': '19439673/625000000', + 'pennyweight': '19439673/12500000000', + 'pondus': '0.325969000000000', + 'pound': '45359237/100000000', + 'pound_troy': '58319019/156250000', + 'quintal': '100', + 'shekel': '0.0141000000000000', + 'short_hundredweight': '45359237/1000000', + 'short_ton': '45359237/50000', + 'slug': '14593903/1000000', + 'solar_mass': '1.98892000000000e30', + 'stone': '317514659/50000000', + 'talent': "(25.7540400000000, {'greek':6000})", + 'ton': '45359237/50000', + 'tonne': '1000', + 'wey': '2857631931/25000000'}, 'power': - {'cheval_vapeur':'588399/800', - 'horsepower':'37284993579113511/50000000000000', - 'watt':'1'}, + {'cheval_vapeur': '588399/800', + 'horsepower': '37284993579113511/50000000000000', + 'watt': '1'}, 'pressure': - {'atmosphere':'101325', - 'bar':'100000', - 'barye':'1/10', - 'inch_mercury':'3386.38900000000', - 'millimeter_mercury':'133.322400000000', - 'mmhg':'133.322400000000', - 'pa':'1', - 'pascal':'1', - 'pounds_per_square_inch':'8896443230521/1290320000', - 'psi':'8896443230521/1290320000', - 'torr':'20265/152'}, + {'atmosphere': '101325', + 'bar': '100000', + 'barye': '1/10', + 'inch_mercury': '3386.38900000000', + 'millimeter_mercury': '133.322400000000', + 'mmhg': '133.322400000000', + 'pa': '1', + 'pascal': '1', + 'pounds_per_square_inch': '8896443230521/1290320000', + 'psi': '8896443230521/1290320000', + 'torr': '20265/152'}, 'radiation': - {'becquerel':'1', - 'curie':'37000000000', - 'rutherford':'1000000'}, + {'becquerel': '1', + 'curie': '37000000000', + 'rutherford': '1000000'}, 'radiation_absorbed': - {'gray':'1', - 'rad':'1/100'}, + {'gray': '1', + 'rad': '1/100'}, 'radiation_ionizing': - {'roentgen':'0.000258000000000000', - 'rontgen':'0.000258000000000000'}, + {'roentgen': '0.000258000000000000', + 'rontgen': '0.000258000000000000'}, 'resistance': - {'abohm':'1/1000000000', - 'ohm':'1', - 'statohm':'22468879468420441/25000'}, + {'abohm': '1/1000000000', + 'ohm': '1', + 'statohm': '22468879468420441/25000'}, 'si_prefixes': - {'atto':'1/1000000000000000000', - 'centi':'1/100', - 'deca':'10', - 'deci':'1/10', - 'exa':'1000000000000000000', - 'femto':'1/1000000000000000', - 'giga':'1000000000', - 'hecto':'100', - 'kilo':'1000', - 'mega':'1000000', - 'micro':'1/1000000', - 'milli':'1/1000', - 'nano':'1/1000000000', - 'peta':'1000000000000000', - 'pico':'1/1000000000000', - 'tera':'1000000000000', - 'yocto':'1/1000000000000000000000000', - 'yotta':'1000000000000000000000000', - 'zepto':'1/1000000000000000000000', - 'zetta':'1000000000000000000000'}, + {'atto': '1/1000000000000000000', + 'centi': '1/100', + 'deca': '10', + 'deci': '1/10', + 'exa': '1000000000000000000', + 'femto': '1/1000000000000000', + 'giga': '1000000000', + 'hecto': '100', + 'kilo': '1000', + 'mega': '1000000', + 'micro': '1/1000000', + 'milli': '1/1000', + 'nano': '1/1000000000', + 'peta': '1000000000000000', + 'pico': '1/1000000000000', + 'tera': '1000000000000', + 'yocto': '1/1000000000000000000000000', + 'yotta': '1000000000000000000000000', + 'zepto': '1/1000000000000000000000', + 'zetta': '1000000000000000000000'}, 'solid_angle': - {'steradian':'1'}, + {'steradian': '1'}, 'temperature': - {'celsius':'(x + 273.15), (x), (x*9/5 + 32), ((x+273.15)*9/5)', - 'centigrade':'(x + 273.15), (x), (x*9/5 + 32), ((x+273.15)*9/5)', - 'fahrenheit':'(5/9*(x + 459.67)), ((x - 32)*5/9), (x), (x+459.67)', - 'kelvin':'(x), (x - 273.15), (x*9/5 - 459.67), (x*9/5)', - 'rankine':'(5/9*x), ((x-491.67)*5/9), (x-459.67), (x)'}, + {'celsius': '(x + 273.15), (x), (x*9/5 + 32), ((x+273.15)*9/5)', + 'centigrade': '(x + 273.15), (x), (x*9/5 + 32), ((x+273.15)*9/5)', + 'fahrenheit': '(5/9*(x + 459.67)), ((x - 32)*5/9), (x), (x+459.67)', + 'kelvin': '(x), (x - 273.15), (x*9/5 - 459.67), (x*9/5)', + 'rankine': '(5/9*x), ((x-491.67)*5/9), (x-459.67), (x)'}, 'time': - {'century':'3153600000', - 'day':'86400', - 'decade':'315360000', - 'fortnight':'1209600', - 'hour':'3600', - 'millenium':'31536000000', - 'minute':'60', - 'month':'2628000', - 'second':'1', - 'sidereal_day':"(86164.0905308330, {'sidereal':86400})", - 'sidereal_second':"(0.997269566329086, {'sidereal':1})", - 'sidereal_year':'3.15581497632000e7', - 'tropical_year':'3.15569251779840e7', - 'week':'604800', - 'year':'31536000'}, + {'century': '3153600000', + 'day': '86400', + 'decade': '315360000', + 'fortnight': '1209600', + 'hour': '3600', + 'millenium': '31536000000', + 'minute': '60', + 'month': '2628000', + 'second': '1', + 'sidereal_day': "(86164.0905308330, {'sidereal':86400})", + 'sidereal_second': "(0.997269566329086, {'sidereal':1})", + 'sidereal_year': '3.15581497632000e7', + 'tropical_year': '3.15569251779840e7', + 'week': '604800', + 'year': '31536000'}, 'unit_multipliers': - {'bakers_dozen':'13', - 'dozen':'12', - 'gross':'144', - 'percent':'1/100'}, + {'bakers_dozen': '13', + 'dozen': '12', + 'gross': '144', + 'percent': '1/100'}, 'velocity': - {'knot':'463/900'}, + {'knot': '463/900'}, 'viscosity_absolute': - {'poise':'1/10', - 'reyn':'8896443230521/1290320000'}, + {'poise': '1/10', + 'reyn': '8896443230521/1290320000'}, 'viscosity_kinematic': - {'stokes':'1/10000'}, + {'stokes': '1/10000'}, 'viscosity_other': - {'rhes':'10'}, + {'rhes': '10'}, 'volume': - {'bag':'660732565629/6250000000000', - 'barrel':'9936705933/62500000000', - 'board_foot':'18435447/7812500000', - 'bucket':'473176473/31250000000', - 'bushel':'220244188543/6250000000000', - 'butt':'29810117799/62500000000', - 'cord':'884901456/244140625', - 'cubic_meter':'1', - 'cup':'473176473/2000000000000', - 'ephah':'1982197696887/50000000000000', - 'fifth':'473176473/625000000000', - 'firkin':'4091481/100000000', - 'fluid_dram':'473176473/128000000000000', - 'fluid_ounce':'473176473/16000000000000', - 'gallon':'473176473/125000000000', - 'gill':'473176473/4000000000000', - 'hogshead':'29810117799/125000000000', - 'imperial_gallon':'454609/100000000', - 'imperial_pint':'454609/800000000', - 'jeroboam':'473176473/156250000000', - 'jigger':'1419529419/32000000000000', - 'liter':'1/1000', - 'magnum':'473176473/250000000000', - 'minim':'157725491/2560000000000000', - 'noggin':'473176473/4000000000000', - 'omer':'1982197696887/500000000000000', - 'peck':'220244188543/25000000000000', - 'pint':'473176473/1000000000000', - 'pony':'1419529419/64000000000000', - 'puncheon':'9936705933/31250000000', - 'quart':'473176473/500000000000', - 'register_ton':'55306341/19531250', - 'seam':'220244188543/781250000000', - 'shot':'473176473/16000000000000', - 'stere':'1', - 'tablespoon':'473176473/32000000000000', - 'teaspoon':'157725491/32000000000000', - 'tun':'29810117799/31250000000', - 'uk_gallon':'454609/100000000', - 'uk_pint':'454609/800000000', - 'wine_bottle':'3/4000'} + {'bag': '660732565629/6250000000000', + 'barrel': '9936705933/62500000000', + 'board_foot': '18435447/7812500000', + 'bucket': '473176473/31250000000', + 'bushel': '220244188543/6250000000000', + 'butt': '29810117799/62500000000', + 'cord': '884901456/244140625', + 'cubic_meter': '1', + 'cup': '473176473/2000000000000', + 'ephah': '1982197696887/50000000000000', + 'fifth': '473176473/625000000000', + 'firkin': '4091481/100000000', + 'fluid_dram': '473176473/128000000000000', + 'fluid_ounce': '473176473/16000000000000', + 'gallon': '473176473/125000000000', + 'gill': '473176473/4000000000000', + 'hogshead': '29810117799/125000000000', + 'imperial_gallon': '454609/100000000', + 'imperial_pint': '454609/800000000', + 'jeroboam': '473176473/156250000000', + 'jigger': '1419529419/32000000000000', + 'liter': '1/1000', + 'magnum': '473176473/250000000000', + 'minim': '157725491/2560000000000000', + 'noggin': '473176473/4000000000000', + 'omer': '1982197696887/500000000000000', + 'peck': '220244188543/25000000000000', + 'pint': '473176473/1000000000000', + 'pony': '1419529419/64000000000000', + 'puncheon': '9936705933/31250000000', + 'quart': '473176473/500000000000', + 'register_ton': '55306341/19531250', + 'seam': '220244188543/781250000000', + 'shot': '473176473/16000000000000', + 'stere': '1', + 'tablespoon': '473176473/32000000000000', + 'teaspoon': '157725491/32000000000000', + 'tun': '29810117799/31250000000', + 'uk_gallon': '454609/100000000', + 'uk_pint': '454609/800000000', + 'wine_bottle': '3/4000'} } unit_to_type = {} value_to_unit = {} + def evalunitdict(): """ Replace all the string values of the unitdict variable by their @@ -499,7 +500,7 @@ def evalunitdict(): """ from sage.misc.sage_eval import sage_eval for key, value in unitdict.items(): - unitdict[key] = dict([(a,sage_eval(repr(b))) for a, b in value.items()]) + unitdict[key] = {a: sage_eval(repr(b)) for a, b in value.items()} # FEATURE IDEA: create a function that would allow users to add # new entries to the table without having to know anything about @@ -526,363 +527,363 @@ def evalunitdict(): unit_docs = { 'acceleration_docs': - {'gal':'Abbreviation for galileo.\nDefined to be 1/100 meter/second^2.', - 'galileo':'Defined to be 1/100 meter/second^2.', - 'gravity':'Also called standard gravity.\nPhysical constant defined to be 9.80665 meter/second^2.'}, + {'gal': 'Abbreviation for galileo.\nDefined to be 1/100 meter/second^2.', + 'galileo': 'Defined to be 1/100 meter/second^2.', + 'gravity': 'Also called standard gravity.\nPhysical constant defined to be 9.80665 meter/second^2.'}, 'amount_of_substance_docs': - {'elementary_entity':'Defined to be one elementary unit of choice, usually atoms or other elementary particles.\nApproximately equal to 1.6605e-24 moles.', - 'mole':'SI base unit of quantity.\nDefined to be the amount of substance that has an equal number of elementary entities as there are atoms in 12 grams of carbon-12.\nEquivalent to Avogadros constant elementary entities or approximately equal to 6.022*10^23 elementary entities.'}, + {'elementary_entity': 'Defined to be one elementary unit of choice, usually atoms or other elementary particles.\nApproximately equal to 1.6605e-24 moles.', + 'mole': 'SI base unit of quantity.\nDefined to be the amount of substance that has an equal number of elementary entities as there are atoms in 12 grams of carbon-12.\nEquivalent to Avogadros constant elementary entities or approximately equal to 6.022*10^23 elementary entities.'}, 'angles_docs': - {'arc_minute':'Defined to be 1/60 of a degree or pi/10800 radians.', - 'arc_second':'Defined to be 1/3600 of a degree or pi/648000 radians.', - 'degree':'Defined to be pi/180 radians.', - 'grade':'Defined to be pi/200 radians.', - 'quadrant':'Equivalent to a right angle.\nDefined to be pi/2 radians.', - 'radian':'SI derived unit of angle.\nDefined to be the angle subtended at the center of a circle by an arc that is equal in length to the radius of the circle.', - 'right_angle':'Equivalent to a quadrant.\nDefined to be pi/2 radians.'}, + {'arc_minute': 'Defined to be 1/60 of a degree or pi/10800 radians.', + 'arc_second': 'Defined to be 1/3600 of a degree or pi/648000 radians.', + 'degree': 'Defined to be pi/180 radians.', + 'grade': 'Defined to be pi/200 radians.', + 'quadrant': 'Equivalent to a right angle.\nDefined to be pi/2 radians.', + 'radian': 'SI derived unit of angle.\nDefined to be the angle subtended at the center of a circle by an arc that is equal in length to the radius of the circle.', + 'right_angle': 'Equivalent to a quadrant.\nDefined to be pi/2 radians.'}, 'area_docs': - {'acre':'Defined to be 10 square chains or 4840 square yards.\nApproximately equal to 4046.856 square meters.', - 'are':'Defined to be 100 square meters.', - 'barn':'Defined to be 100 square femtometers or 10^-28 square meters.', - 'hectare':'Defined to be 10000 square meters.', - 'rood':'Defined to be 1/4 of an acre.\nApproximately equal to 1011.714 square meters.', - 'section':'Equivalent to a square mile.\nApproximately equal to 2.59*10^6 square meters.', - 'square_chain':'Defined to be 4356 square feet.\nApproximately equal to 404.9856 square meters.', - 'square_meter':'SI derived unit of area.\nDefined to be meter^2.', - 'township':'Defined to be 36 square miles.\nApproximately equal to 9.324*10^7 square meters.'}, + {'acre': 'Defined to be 10 square chains or 4840 square yards.\nApproximately equal to 4046.856 square meters.', + 'are': 'Defined to be 100 square meters.', + 'barn': 'Defined to be 100 square femtometers or 10^-28 square meters.', + 'hectare': 'Defined to be 10000 square meters.', + 'rood': 'Defined to be 1/4 of an acre.\nApproximately equal to 1011.714 square meters.', + 'section': 'Equivalent to a square mile.\nApproximately equal to 2.59*10^6 square meters.', + 'square_chain': 'Defined to be 4356 square feet.\nApproximately equal to 404.9856 square meters.', + 'square_meter': 'SI derived unit of area.\nDefined to be meter^2.', + 'township': 'Defined to be 36 square miles.\nApproximately equal to 9.324*10^7 square meters.'}, 'capacitance_docs': - {'abfarad':'Defined to be 10^9 farads.', - 'farad':'SI derived unit of capacitance.\nDefined to be the charge in coulombs a capacitor will accept for the potential across it to change one volt.\nEquivalent to coulomb/volt.', - 'statfarad':'CGS unit defined to be statcoulomb/statvolt.\nApproximately equal to 1.11265*10^-12 farads.'}, + {'abfarad': 'Defined to be 10^9 farads.', + 'farad': 'SI derived unit of capacitance.\nDefined to be the charge in coulombs a capacitor will accept for the potential across it to change one volt.\nEquivalent to coulomb/volt.', + 'statfarad': 'CGS unit defined to be statcoulomb/statvolt.\nApproximately equal to 1.11265*10^-12 farads.'}, 'charge_docs': - {'abcoulomb':'CGS unit defined to be 10 coulombs.', - 'coulomb':'SI derived unit of charge.\nDefined to be the amount of electric charge transported by 1 ampere in 1 second.', - 'elementary_charge':'Defined to be the amount of electric charge carried by a single proton or negative charge carried by a single electron.\nApproximately equal to 1.602176462*10^-19 coulombs.', - 'faraday':'Defined to be the magnitude of electric charge in one mole of electrons.\nApproximately equal to 96485.3399 coulombs.', - 'franklin':'CGS unit defined to be the amount of electric charge necessary such that if two stationary objects placed one centimeter apart had one franklin of charge each they would repel each other with a force of one dyne.\nApproximately equal to 3.3356*10^-10 coulombs.', - 'statcoulomb':'Equivalent to franklin.\nApproximately equal to 3.3356*10^-10 coulombs.'}, + {'abcoulomb': 'CGS unit defined to be 10 coulombs.', + 'coulomb': 'SI derived unit of charge.\nDefined to be the amount of electric charge transported by 1 ampere in 1 second.', + 'elementary_charge': 'Defined to be the amount of electric charge carried by a single proton or negative charge carried by a single electron.\nApproximately equal to 1.602176462*10^-19 coulombs.', + 'faraday': 'Defined to be the magnitude of electric charge in one mole of electrons.\nApproximately equal to 96485.3399 coulombs.', + 'franklin': 'CGS unit defined to be the amount of electric charge necessary such that if two stationary objects placed one centimeter apart had one franklin of charge each they would repel each other with a force of one dyne.\nApproximately equal to 3.3356*10^-10 coulombs.', + 'statcoulomb': 'Equivalent to franklin.\nApproximately equal to 3.3356*10^-10 coulombs.'}, 'conductance_docs': - {'abmho':'Defined to be 10^9 siemens.', - 'mho':'Equivalent to siemens.', - 'siemens':'SI derived unit of conductance.\nDefined to be an ampere per volt or 1/ohm.'}, + {'abmho': 'Defined to be 10^9 siemens.', + 'mho': 'Equivalent to siemens.', + 'siemens': 'SI derived unit of conductance.\nDefined to be an ampere per volt or 1/ohm.'}, 'current_docs': - {'abampere':'CGS unit defined to be 10 amperes.', - 'amp':'Abbreviation for ampere.', - 'ampere':'SI base unit of current.\nDefined to be the constant current which will produce an attractive force of 2*10^-7 newtons per meter between two straight, parallel conductors of infinite length and negligible circular cross section placed one meter apart in free space.', - 'biot':'Equivalent to abampere.\nEqual to 10 amperes.', - 'statampere':'CGS unit defined to be statcoulomb/second.\nApproximately equal to 3.335641*10^-10 amperes.'}, + {'abampere': 'CGS unit defined to be 10 amperes.', + 'amp': 'Abbreviation for ampere.', + 'ampere': 'SI base unit of current.\nDefined to be the constant current which will produce an attractive force of 2*10^-7 newtons per meter between two straight, parallel conductors of infinite length and negligible circular cross section placed one meter apart in free space.', + 'biot': 'Equivalent to abampere.\nEqual to 10 amperes.', + 'statampere': 'CGS unit defined to be statcoulomb/second.\nApproximately equal to 3.335641*10^-10 amperes.'}, 'electric_potential_docs': - {'abvolt':'Defined to be 10^-8 volts.', - 'statvolt':'CGS unit defined to be the speed of light in a vacuum/10^6 volts or approximately 299.792 volts.', - 'volt':'SI derived unit of electric potential.\nDefined to be the value of voltage across a conductor when a current of one ampere dissipates one watt of power.'}, + {'abvolt': 'Defined to be 10^-8 volts.', + 'statvolt': 'CGS unit defined to be the speed of light in a vacuum/10^6 volts or approximately 299.792 volts.', + 'volt': 'SI derived unit of electric potential.\nDefined to be the value of voltage across a conductor when a current of one ampere dissipates one watt of power.'}, 'energy_docs': - {'british_thermal_unit':'Defined to be the amount of energy required to raise the temperature of one pound of liquid water from 60 degrees Fahrenheit to 61 degrees Fahrenheit at a constant pressure of one atmosphere.\nApproximately equal to 1055.05585 joules.', - 'btu':'Abbreviation for British thermal unit.\nApproximately equal to 1055.05585 joules.', - 'calorie':'Defined to be the amount of energy required to raise the temperature of one gram of liquid water one degree Celsius.\nEqual to 4.1868 joules.', - 'electron_volt':'Defined to be the amount of kinetic energy gained by a single unbound electron when it accelerates through an electrostatic potential difference of 1 volt.\nApproximately equal to 1.602*10^-19 joules.', - 'erg':'CGS unit for energy defined to be gram*centimeter^2/second^2.\nEqual to 10^-7 joules.', - 'ev':'Abbreviation for electron volt.\nApproximately equal to 1.602*10^-19 joules.', - 'joule':'SI derived unit of energy.\nDefined to be kilogram*meter^2/second^2.', - 'rydberg':'Defined to be the absolute value of the binding energy of the electron in the ground state hydrogen atom.\nApproximately equal to 2.17987*10^-18 joules.', - 'therm':'Defined to be 100,000 British thermal units.\nApproximately equal to 1.05505585*10^8 joules.'}, + {'british_thermal_unit': 'Defined to be the amount of energy required to raise the temperature of one pound of liquid water from 60 degrees Fahrenheit to 61 degrees Fahrenheit at a constant pressure of one atmosphere.\nApproximately equal to 1055.05585 joules.', + 'btu': 'Abbreviation for British thermal unit.\nApproximately equal to 1055.05585 joules.', + 'calorie': 'Defined to be the amount of energy required to raise the temperature of one gram of liquid water one degree Celsius.\nEqual to 4.1868 joules.', + 'electron_volt': 'Defined to be the amount of kinetic energy gained by a single unbound electron when it accelerates through an electrostatic potential difference of 1 volt.\nApproximately equal to 1.602*10^-19 joules.', + 'erg': 'CGS unit for energy defined to be gram*centimeter^2/second^2.\nEqual to 10^-7 joules.', + 'ev': 'Abbreviation for electron volt.\nApproximately equal to 1.602*10^-19 joules.', + 'joule': 'SI derived unit of energy.\nDefined to be kilogram*meter^2/second^2.', + 'rydberg': 'Defined to be the absolute value of the binding energy of the electron in the ground state hydrogen atom.\nApproximately equal to 2.17987*10^-18 joules.', + 'therm': 'Defined to be 100,000 British thermal units.\nApproximately equal to 1.05505585*10^8 joules.'}, 'fiber_linear_mass_density_docs': - {'denier':'Defined to be 1 gram per 9000 meters.\nEqual to 1/9000000 of a kilogram/meter.', - 'tex':'Defined to be 1 gram per 1000 meters.\nEqual to 1/1000000 of a kilogram/meter.'}, + {'denier': 'Defined to be 1 gram per 9000 meters.\nEqual to 1/9000000 of a kilogram/meter.', + 'tex': 'Defined to be 1 gram per 1000 meters.\nEqual to 1/1000000 of a kilogram/meter.'}, 'force_docs': - {'dyne':'CGS unit for force defined to be gram*centimeter/second^2.\nEqual to 10^-5 newtons.', - 'gram_weight':'Defined to be the magnitude of the force exerted on one gram of mass by a 9.80665 meter/second^2 gravitational field.\nEqual to 1/1000 of a kilogram weight.\nEqual to 0.00980665 newtons.', - 'kilogram_force':'Equivalent to a kilogram weight.\nEqual to 9.80665 newtons.', - 'kilogram_weight':'Defined to be the magnitude of the force exerted on one kilogram of mass by a 9.80665 meter/second^2 gravitational field.\nEqual to 9.80665 newtons.', - 'newton':'SI derived unit of force.\nDefined to be kilogram*meter/second^2.', - 'pound_force':'Equivalent to a pound weight.\nApproximately equal to 4.44822 newtons.', - 'pound_weight':'Defined to be the magnitude of the force exerted on one pound of mass by a 9.80665 meter/second^2 gravitational field.\nApproximately equal to 4.44822 newtons.', - 'poundal':'Defined to be pound*foot/second^2.\nApproximately equal to 0.13825 newtons.', - 'ton_force':'Defined to be 2000 pounds of force.\nApproximately equal to 8896.4432 newtons.'}, + {'dyne': 'CGS unit for force defined to be gram*centimeter/second^2.\nEqual to 10^-5 newtons.', + 'gram_weight': 'Defined to be the magnitude of the force exerted on one gram of mass by a 9.80665 meter/second^2 gravitational field.\nEqual to 1/1000 of a kilogram weight.\nEqual to 0.00980665 newtons.', + 'kilogram_force': 'Equivalent to a kilogram weight.\nEqual to 9.80665 newtons.', + 'kilogram_weight': 'Defined to be the magnitude of the force exerted on one kilogram of mass by a 9.80665 meter/second^2 gravitational field.\nEqual to 9.80665 newtons.', + 'newton': 'SI derived unit of force.\nDefined to be kilogram*meter/second^2.', + 'pound_force': 'Equivalent to a pound weight.\nApproximately equal to 4.44822 newtons.', + 'pound_weight': 'Defined to be the magnitude of the force exerted on one pound of mass by a 9.80665 meter/second^2 gravitational field.\nApproximately equal to 4.44822 newtons.', + 'poundal': 'Defined to be pound*foot/second^2.\nApproximately equal to 0.13825 newtons.', + 'ton_force': 'Defined to be 2000 pounds of force.\nApproximately equal to 8896.4432 newtons.'}, 'frequency_docs': - {'hertz':'SI derived unit of frequency.\nDefined to be one complete cycle per second.'}, + {'hertz': 'SI derived unit of frequency.\nDefined to be one complete cycle per second.'}, 'illuminance_docs': - {'foot_candle':'Defined to be lumen/foot^2.\nApproximately equal to 10.764 lux.', - 'lux':'SI derived unit of illuminance.\nDefined to be lumen/meter^2.', - 'phot':'CGS unit defined to be 10000 lux.'}, + {'foot_candle': 'Defined to be lumen/foot^2.\nApproximately equal to 10.764 lux.', + 'lux': 'SI derived unit of illuminance.\nDefined to be lumen/meter^2.', + 'phot': 'CGS unit defined to be 10000 lux.'}, 'inductance_docs': - {'abhenry':'Defined to be 10^-9 henries.', - 'henry':'SI derived unit of inductance./nDefined to be a volt per ampere per second.', - 'stathenry':'CGS unit defined to be one statvolt*second/statampere.\nApproximately equal to 8.98758*10^11 henries.'}, + {'abhenry': 'Defined to be 10^-9 henries.', + 'henry': 'SI derived unit of inductance./nDefined to be a volt per ampere per second.', + 'stathenry': 'CGS unit defined to be one statvolt*second/statampere.\nApproximately equal to 8.98758*10^11 henries.'}, 'information_docs': - {'bit':'Base unit of information.\nDefined to be the maximum amount of information that can be stored by a device of other physical system that can normally exist in only two distinct states.', - 'byte':'Defined to be 8 bits.', - 'nibble':'Defined to be 4 bits.'}, + {'bit': 'Base unit of information.\nDefined to be the maximum amount of information that can be stored by a device of other physical system that can normally exist in only two distinct states.', + 'byte': 'Defined to be 8 bits.', + 'nibble': 'Defined to be 4 bits.'}, 'information_rate_docs': - {'baud':'Defined to be 1 bit/second.'}, + {'baud': 'Defined to be 1 bit/second.'}, 'inverse_length_docs': - {'diopter':'Defined to be 1/meter.', - 'kayser':'Defined to be 100/meter.'}, + {'diopter': 'Defined to be 1/meter.', + 'kayser': 'Defined to be 100/meter.'}, 'length_docs': - {'angstrom':'Defined to be 10^-10 meters.', - 'astronomical_unit':'Originally defined as the length of the semi-major axis of the elliptical orbit of the Earth around the Sun.\nRedefined for accuracy to be the radius of an unperturbed circular Newtonian orbit about the Sun of a particle having infinitesimal mass, moving with a mean motion of 0.01720209895 radians per day.\nApproximately equal to 1.496*10^11 meters.', - 'bolt':'Defined to be 40 yards.\nEqual to 36.576 meters.', - 'cable_international':'Nautical unit defined to be 1/10 of a nautical mile.\nEqual to 185.2 meters.', - 'cable_us':'Nautical unit defined to be equal to 720 feet or 120 fathoms.\nEqual to 219.456 meters.', - 'caliber':'Equal to 1/100 of an inch.\nEqual to 0.000254 meters.', - 'centimeter':'Equal to 1/100 of a meter.', - 'chain':'Surveying unit defined to be 66 feet.\nApproximately equal to 20.12 meters.', - 'cicero':'Printing unit defined to be 12 didot points.\nApproximately equal to 0.004512 meters.', - 'cubit':'Ancient unit of length defined to be 18 inches.\nEqual to 0.4572 meters.', - 'didot':'Printing unit equal to 1/12 of a cicero.\nApproximately equal to 0.00037597 meters.', - 'dtp_point':'The desktop publishing point is defined to be 1/72 of an inch.\nApproximately equal to 0.0003528 meters.', - 'ell':'Ancient unit of length defined to be 45 inches.\nEqual to 1.143 meters.', - 'fathom':'Nautical unit defined to be 6 feet.\nEqual to 1.8288 meters.', - 'feet':'Equal to 12 inches.\nDefined to be 0.3048 meters.', - 'fermi':'Equivalent to a femtometer.\nEqual to 10^-15 meters.', - 'foot':'Equal to 12 inches.\nDefined to be 0.3048 meters.', - 'furlong':'Defined to be 660 feet, or 1/8 of a mile.\nEqual to 201.168 meters.', - 'hand':'Defined to be 4 inches.\nEqual to 0.1016 meters.', - 'inch':'Equal to 1/12 of a foot.\nEqual to 0.0254 meters.', - 'kilometer':'Equal to 1000 meters.\nEqual to 3280.8399 feet.', - 'league':'Defined to be 3 miles.\nConventionally equal to the distance a person or horse can walk in one hour.\nEqual to 4828.032 meters.', - 'light_year':'Defined to be the distance light travels in vacuum in 365.25 days.\nApproximately equal to 9.4607*10^15 meters.', - 'link':'Surveying unit defined to be 1/100 of a chain.\nEqual to 0.201168 meters.', - 'meter':'SI base unit of length.\nDefined to be the distance light travels in vacuum in 1/299792458 of a second.', - 'micron':'Defined to be 10^-6 meters.', - 'mil':'Defined to be 1/1000 of an inch.\nEqual to 0.0000254 meters.', - 'millimeter':'Defined to be 1/1000 of a meter.\nEqual to 0.001 meters.', - 'mile':'Defined to be 5280 feet.\nEqual to 1609.344 meters.', - 'nautical_mile':'Nautical unit defined to be 1852 meters.', - 'parsec':'Defined to be the length of the adjacent side of a right triangle whose angle is 1 arcsecond and opposite side equal to 1 astronomical unit, or 1 AU/arctan(1 arcsecond).\nApproximately equal to 30.857*10^15 meters.', - 'perch':'Equivalent to rod.\nDefined to be 16.5 feet.\nEqual to 5.0292 meters.', - 'pica':'Printing unit defined to be 12 dtp points.\nEqual to 1/72 of a foot.\nApproximately equal to 0.004233 meters.', - 'pole':'Equivalent to rod.\nDefined to be 16.5 feet.\nEqual to 5.0292 meters.', - 'rod':'Defined to be 16.5 feet.\nEqual to 5.0292 meters.', - 'rope':'Defined to be 20 feet.\nEqual to 6.096 meters.', - 'skein':'Defined to be 360 feet.\nEqual to 109.728 meters.', - 'stadion':'Ancient unit of length defined to be 622 feet.\nEqual to 189.5856 meters.', - 'stadium':'Defined to be 202 yards or 606 feet.\nEqual to 184.7088 meters.', - 'statute_mile':'Equivalent to mile.\nDefined to be 5280 feet.\nEqual to 1609.344 meters.', - 'survey_foot':'Defined to be 1200/3937 or approximately 0.3048006 meters.', - 'survey_mile':'Defined to be 5280 survey feet.\nApproximately equal to 1609.347 meters.', - 'x_unit':'Unit of length used to quote wavelengths of X-rays and gamma rays.\nApproximately equal to 1.0021*10^-13 meters.', - 'yard':'Defined to be 3 feet.\nEqual to 0.9144 meters.'}, + {'angstrom': 'Defined to be 10^-10 meters.', + 'astronomical_unit': 'Originally defined as the length of the semi-major axis of the elliptical orbit of the Earth around the Sun.\nRedefined for accuracy to be the radius of an unperturbed circular Newtonian orbit about the Sun of a particle having infinitesimal mass, moving with a mean motion of 0.01720209895 radians per day.\nApproximately equal to 1.496*10^11 meters.', + 'bolt': 'Defined to be 40 yards.\nEqual to 36.576 meters.', + 'cable_international': 'Nautical unit defined to be 1/10 of a nautical mile.\nEqual to 185.2 meters.', + 'cable_us': 'Nautical unit defined to be equal to 720 feet or 120 fathoms.\nEqual to 219.456 meters.', + 'caliber': 'Equal to 1/100 of an inch.\nEqual to 0.000254 meters.', + 'centimeter': 'Equal to 1/100 of a meter.', + 'chain': 'Surveying unit defined to be 66 feet.\nApproximately equal to 20.12 meters.', + 'cicero': 'Printing unit defined to be 12 didot points.\nApproximately equal to 0.004512 meters.', + 'cubit': 'Ancient unit of length defined to be 18 inches.\nEqual to 0.4572 meters.', + 'didot': 'Printing unit equal to 1/12 of a cicero.\nApproximately equal to 0.00037597 meters.', + 'dtp_point': 'The desktop publishing point is defined to be 1/72 of an inch.\nApproximately equal to 0.0003528 meters.', + 'ell': 'Ancient unit of length defined to be 45 inches.\nEqual to 1.143 meters.', + 'fathom': 'Nautical unit defined to be 6 feet.\nEqual to 1.8288 meters.', + 'feet': 'Equal to 12 inches.\nDefined to be 0.3048 meters.', + 'fermi': 'Equivalent to a femtometer.\nEqual to 10^-15 meters.', + 'foot': 'Equal to 12 inches.\nDefined to be 0.3048 meters.', + 'furlong': 'Defined to be 660 feet, or 1/8 of a mile.\nEqual to 201.168 meters.', + 'hand': 'Defined to be 4 inches.\nEqual to 0.1016 meters.', + 'inch': 'Equal to 1/12 of a foot.\nEqual to 0.0254 meters.', + 'kilometer': 'Equal to 1000 meters.\nEqual to 3280.8399 feet.', + 'league': 'Defined to be 3 miles.\nConventionally equal to the distance a person or horse can walk in one hour.\nEqual to 4828.032 meters.', + 'light_year': 'Defined to be the distance light travels in vacuum in 365.25 days.\nApproximately equal to 9.4607*10^15 meters.', + 'link': 'Surveying unit defined to be 1/100 of a chain.\nEqual to 0.201168 meters.', + 'meter': 'SI base unit of length.\nDefined to be the distance light travels in vacuum in 1/299792458 of a second.', + 'micron': 'Defined to be 10^-6 meters.', + 'mil': 'Defined to be 1/1000 of an inch.\nEqual to 0.0000254 meters.', + 'millimeter': 'Defined to be 1/1000 of a meter.\nEqual to 0.001 meters.', + 'mile': 'Defined to be 5280 feet.\nEqual to 1609.344 meters.', + 'nautical_mile': 'Nautical unit defined to be 1852 meters.', + 'parsec': 'Defined to be the length of the adjacent side of a right triangle whose angle is 1 arcsecond and opposite side equal to 1 astronomical unit, or 1 AU/arctan(1 arcsecond).\nApproximately equal to 30.857*10^15 meters.', + 'perch': 'Equivalent to rod.\nDefined to be 16.5 feet.\nEqual to 5.0292 meters.', + 'pica': 'Printing unit defined to be 12 dtp points.\nEqual to 1/72 of a foot.\nApproximately equal to 0.004233 meters.', + 'pole': 'Equivalent to rod.\nDefined to be 16.5 feet.\nEqual to 5.0292 meters.', + 'rod': 'Defined to be 16.5 feet.\nEqual to 5.0292 meters.', + 'rope': 'Defined to be 20 feet.\nEqual to 6.096 meters.', + 'skein': 'Defined to be 360 feet.\nEqual to 109.728 meters.', + 'stadion': 'Ancient unit of length defined to be 622 feet.\nEqual to 189.5856 meters.', + 'stadium': 'Defined to be 202 yards or 606 feet.\nEqual to 184.7088 meters.', + 'statute_mile': 'Equivalent to mile.\nDefined to be 5280 feet.\nEqual to 1609.344 meters.', + 'survey_foot': 'Defined to be 1200/3937 or approximately 0.3048006 meters.', + 'survey_mile': 'Defined to be 5280 survey feet.\nApproximately equal to 1609.347 meters.', + 'x_unit': 'Unit of length used to quote wavelengths of X-rays and gamma rays.\nApproximately equal to 1.0021*10^-13 meters.', + 'yard': 'Defined to be 3 feet.\nEqual to 0.9144 meters.'}, 'luminance_docs': - {'apostilb':'Defined to be 10^-4 lamberts.\nEqual to 1/pi*candela/meter^2.', - 'lambert':'Defined to be 10^4/pi candela/meter^2.', - 'nit':'Equivalent to candela/meter^2.', - 'stilb':'CGS unit equal to 10000 candela/meter^2.'}, + {'apostilb': 'Defined to be 10^-4 lamberts.\nEqual to 1/pi*candela/meter^2.', + 'lambert': 'Defined to be 10^4/pi candela/meter^2.', + 'nit': 'Equivalent to candela/meter^2.', + 'stilb': 'CGS unit equal to 10000 candela/meter^2.'}, 'luminous_energy_docs': - {'lumerg':'Equivalent to lumen*second', - 'talbot':'Equivalent to lumen*second.'}, + {'lumerg': 'Equivalent to lumen*second', + 'talbot': 'Equivalent to lumen*second.'}, 'luminous_flux_docs': - {'lumen':'SI derived unit of luminous flux.\nDefined to be candela*steradian.'}, + {'lumen': 'SI derived unit of luminous flux.\nDefined to be candela*steradian.'}, 'luminous_intensity_docs': - {'candela':'SI base unit of luminous intensity.\nDefined to be the luminous intensity, in a given direction, of a source that emits monochromatic radiation of frequency 540*10^12 hertz and that has a radiant intensity in that direction of 1/683 watt per steradian.', - 'candle':'Equivalent to candela.', - 'hefnerkerze':'Old German unit defined to be a 8 millimeter wick burning amyl acetate with a flame height of 40 millimeters.\nApproximately equal to 0.9034 candelas.'}, + {'candela': 'SI base unit of luminous intensity.\nDefined to be the luminous intensity, in a given direction, of a source that emits monochromatic radiation of frequency 540*10^12 hertz and that has a radiant intensity in that direction of 1/683 watt per steradian.', + 'candle': 'Equivalent to candela.', + 'hefnerkerze': 'Old German unit defined to be a 8 millimeter wick burning amyl acetate with a flame height of 40 millimeters.\nApproximately equal to 0.9034 candelas.'}, 'magnetic_field_docs': - {'gauss':'CGS unit defined to be a maxwell/centimeter^2.\nEqual to 1/10000 of a tesla.', - 'tesla':'SI derived unit of magnetic field.\nDefined to be the magnitude of a magnetic field such that a particle with a charge of 1 coulomb passing through that field at 1 meter/second will experience a force of 1 newton.'}, + {'gauss': 'CGS unit defined to be a maxwell/centimeter^2.\nEqual to 1/10000 of a tesla.', + 'tesla': 'SI derived unit of magnetic field.\nDefined to be the magnitude of a magnetic field such that a particle with a charge of 1 coulomb passing through that field at 1 meter/second will experience a force of 1 newton.'}, 'magnetic_flux_docs': - {'maxwell':'CGS unit defined to be a gauss*centimeter^2 or 10^-8 webers.', - 'weber':'SI derived unit of magnetic flux.\nDefined to be a change in magnetic flux of 1 weber per second will induce an electromotive force of 1 volt.'}, + {'maxwell': 'CGS unit defined to be a gauss*centimeter^2 or 10^-8 webers.', + 'weber': 'SI derived unit of magnetic flux.\nDefined to be a change in magnetic flux of 1 weber per second will induce an electromotive force of 1 volt.'}, 'magnetic_intensity_docs': - {'oersted':'CGS unit defined to be 1000/(4*pi) amperes per meter of flux path.'}, + {'oersted': 'CGS unit defined to be 1000/(4*pi) amperes per meter of flux path.'}, 'magnetic_moment_docs': - {'bohr_magneton':'Physical constant defined to be the magnetic moment of an electron, or elementary_charge*h_bar/2*electron_rest_mass.\nApproximately equal to 9.274*10^-24 joules/tesla.', - 'nuclear_magneton':'Physical constant defined to be the magnetic moment of a proton, or elementary_charge*h_bar/2*proton_rest_mass.\nApproximately equal to 5.05078324*10^-27 joules/tesla.'}, + {'bohr_magneton': 'Physical constant defined to be the magnetic moment of an electron, or elementary_charge*h_bar/2*electron_rest_mass.\nApproximately equal to 9.274*10^-24 joules/tesla.', + 'nuclear_magneton': 'Physical constant defined to be the magnetic moment of a proton, or elementary_charge*h_bar/2*proton_rest_mass.\nApproximately equal to 5.05078324*10^-27 joules/tesla.'}, 'magnetomotive_force_docs': - {'ampere_turn':'SI derived unit of magnetomotive force.\nDefined to be a direct current of 1 ampere flowing through a single turn loop in a vacuum.', - 'gilbert':'CGS unit defined to be 10/(4*pi) ampere turns.'}, + {'ampere_turn': 'SI derived unit of magnetomotive force.\nDefined to be a direct current of 1 ampere flowing through a single turn loop in a vacuum.', + 'gilbert': 'CGS unit defined to be 10/(4*pi) ampere turns.'}, 'mass_docs': - {'amu':'Abbreviation for atomic mass unit.\nApproximately equal to 1.660538782*10^-27 kilograms.', - 'assay_ton':'Defined to be milligram*short_ton/ounce_troy.\nEqual to 7/240 of a kilogram.', - 'atomic_mass_unit':'Defined to be one twelfth of the mass of an isolated atom of carbon-12 at rest and in its ground state.\nApproximately equal to 1.660538782*10^-27 kilograms.', - 'avoirdupois_ounce':'Equivalent to ounce.\nEqual to 1/16 of an avoirdupois pound.\nApproximately equal to 0.02835 kilograms.', - 'avoirdupois_pound':'Equivalent to pound.\nEqual to 16 avoirdupois ounces.\nApproximately equal to 0.45359 kilograms.', - 'bale':'Equal to 500 pounds.\nApproximately equal to 226.796 kilograms.', - 'carat':'Defined to be equal to 200 milligrams.\nCommonly denoted ct.', - 'cental':'Equal to 100 pounds.\nApproximately equal to 45.36 kilograms.', - 'dalton':'Equivalent to atomic_mass_unit.\nApproximately equal to 1.660538782*10^-27 kilograms.', - 'drachma':'Ancient Greek unit of mass.\nEqual to 6 obols.\nApproximately equal to 0.00429234 kilograms.', - 'geepound':'Equivalent to slug.\nApproximately equal to 14.5939 kilograms.', - 'grain':'Historically based on the average mass of a single seed of a typical cereal.\nDefined in 1958 to be 64.79891 milligrams.', - 'gram':'Equal to 0.0001 kilograms.', - 'gross_hundredweight':'Equivalent to hundredweight.\nEqual to 112 pounds.\nApproximately equal to 50.802 kilograms.', - 'hundredweight':'Defined to be 112 pounds.\nApproximately equal to 50.802 kilograms.', - 'kilogram':'SI base unit of mass.\nDefined to be equal to the mass of the International Prototype Kilogram.\nAlmost exactly equal to the amount of mass in one liter of water.', - 'libra':'Ancient Roman unit of mass.\nApproximately equal to 0.325971 kilogram.', - 'long_ton':'Defined to be 2240 pounds.\nApproximately equal to 1016.05 kilograms.', - 'metric_ton':'Defined to be 1000 kilograms.', - 'mina':'Ancient Greek unit of mass.\nEqual to 100 drachma.\nApproximately equal to 0.429234 kilograms.', - 'net_hundredweight':'Equivalent to cental.\nEqual to 100 pounds.\nApproximately equal to 45.36 kilograms.', - 'obol':'Ancient Greek unit of mass.\nEqual to 1/6 of drachma.\nApproximately equal to 0.00071538 kilograms.', - 'ounce':'Equal to 1/16 of pound.\nCommonly abbreviated oz.\nApproximately equal to 0.02835 kilograms.', - 'ounce_troy':'Equal to 1/12 of pound_troy.\nApproximately equal to 0.031103 kilograms.', - 'pennyweight':'Equal to 1/20 of ounce_troy.\nCommonly abbreviated dwt.\nApproximately equal to 0.001555 kilograms.', - 'pondus':'Ancient Roman unit of mass.\nApproximately equal to 0.325969 kilograms.', - 'pound':'Equal to 16 ounces.\nDefined to be exactly 0.45359237 kilograms.', - 'pound_troy':'Equal to 12 ounce_troy.\nApproximately equal to 0.37324 kilograms.', - 'quintal':'Equal to 100 kilograms.', - 'shekel':'Ancient Hebrew unit of mass.\nApproximately equal to 0.0141 kilograms.', - 'short_hundredweight':'Equivalent to cental.\nEqual to 100 pounds.\nApproximately equal to 45.36 kilograms.', - 'short_ton':'Equivalent to ton.\nEqual to 2000 pounds.\nApproximately equal to 907.18 kilograms.', - 'slug':'Defined to be a mass that is accelerated 1 ft/s^2 when 1 pound_force is exerted on it.\nApproximately equal to 14.5939 kilograms.', - 'solar_mass':'Defined to be the mass of the Sun.\nAbout 332,950 times the mass of the Earth or 1,048 times the mass of Jupiter.\nApproximately equal to 1.98892*10^30 kilograms.', - 'stone':'Defined to be 14 pounds.\nApproximately equal to 6.35 kilograms.', - 'talent':'Ancient Greek unit of mass.\nEqual to 6000 drachmae.\nApproximately equal to 25.754 kilograms.', - 'ton':'Equal to 2000 pounds.\nApproximately equal to 907.18 kilograms.', - 'tonne':'Equivalent to metric_ton.\nDefined to be 1000 kilograms.', - 'wey':'Defined to be 252 pounds.\nApproximately equal to 114.305 kilograms.'}, + {'amu': 'Abbreviation for atomic mass unit.\nApproximately equal to 1.660538782*10^-27 kilograms.', + 'assay_ton': 'Defined to be milligram*short_ton/ounce_troy.\nEqual to 7/240 of a kilogram.', + 'atomic_mass_unit': 'Defined to be one twelfth of the mass of an isolated atom of carbon-12 at rest and in its ground state.\nApproximately equal to 1.660538782*10^-27 kilograms.', + 'avoirdupois_ounce': 'Equivalent to ounce.\nEqual to 1/16 of an avoirdupois pound.\nApproximately equal to 0.02835 kilograms.', + 'avoirdupois_pound': 'Equivalent to pound.\nEqual to 16 avoirdupois ounces.\nApproximately equal to 0.45359 kilograms.', + 'bale': 'Equal to 500 pounds.\nApproximately equal to 226.796 kilograms.', + 'carat': 'Defined to be equal to 200 milligrams.\nCommonly denoted ct.', + 'cental': 'Equal to 100 pounds.\nApproximately equal to 45.36 kilograms.', + 'dalton': 'Equivalent to atomic_mass_unit.\nApproximately equal to 1.660538782*10^-27 kilograms.', + 'drachma': 'Ancient Greek unit of mass.\nEqual to 6 obols.\nApproximately equal to 0.00429234 kilograms.', + 'geepound': 'Equivalent to slug.\nApproximately equal to 14.5939 kilograms.', + 'grain': 'Historically based on the average mass of a single seed of a typical cereal.\nDefined in 1958 to be 64.79891 milligrams.', + 'gram': 'Equal to 0.0001 kilograms.', + 'gross_hundredweight': 'Equivalent to hundredweight.\nEqual to 112 pounds.\nApproximately equal to 50.802 kilograms.', + 'hundredweight': 'Defined to be 112 pounds.\nApproximately equal to 50.802 kilograms.', + 'kilogram': 'SI base unit of mass.\nDefined to be equal to the mass of the International Prototype Kilogram.\nAlmost exactly equal to the amount of mass in one liter of water.', + 'libra': 'Ancient Roman unit of mass.\nApproximately equal to 0.325971 kilogram.', + 'long_ton': 'Defined to be 2240 pounds.\nApproximately equal to 1016.05 kilograms.', + 'metric_ton': 'Defined to be 1000 kilograms.', + 'mina': 'Ancient Greek unit of mass.\nEqual to 100 drachma.\nApproximately equal to 0.429234 kilograms.', + 'net_hundredweight': 'Equivalent to cental.\nEqual to 100 pounds.\nApproximately equal to 45.36 kilograms.', + 'obol': 'Ancient Greek unit of mass.\nEqual to 1/6 of drachma.\nApproximately equal to 0.00071538 kilograms.', + 'ounce': 'Equal to 1/16 of pound.\nCommonly abbreviated oz.\nApproximately equal to 0.02835 kilograms.', + 'ounce_troy': 'Equal to 1/12 of pound_troy.\nApproximately equal to 0.031103 kilograms.', + 'pennyweight': 'Equal to 1/20 of ounce_troy.\nCommonly abbreviated dwt.\nApproximately equal to 0.001555 kilograms.', + 'pondus': 'Ancient Roman unit of mass.\nApproximately equal to 0.325969 kilograms.', + 'pound': 'Equal to 16 ounces.\nDefined to be exactly 0.45359237 kilograms.', + 'pound_troy': 'Equal to 12 ounce_troy.\nApproximately equal to 0.37324 kilograms.', + 'quintal': 'Equal to 100 kilograms.', + 'shekel': 'Ancient Hebrew unit of mass.\nApproximately equal to 0.0141 kilograms.', + 'short_hundredweight': 'Equivalent to cental.\nEqual to 100 pounds.\nApproximately equal to 45.36 kilograms.', + 'short_ton': 'Equivalent to ton.\nEqual to 2000 pounds.\nApproximately equal to 907.18 kilograms.', + 'slug': 'Defined to be a mass that is accelerated 1 ft/s^2 when 1 pound_force is exerted on it.\nApproximately equal to 14.5939 kilograms.', + 'solar_mass': 'Defined to be the mass of the Sun.\nAbout 332,950 times the mass of the Earth or 1,048 times the mass of Jupiter.\nApproximately equal to 1.98892*10^30 kilograms.', + 'stone': 'Defined to be 14 pounds.\nApproximately equal to 6.35 kilograms.', + 'talent': 'Ancient Greek unit of mass.\nEqual to 6000 drachmae.\nApproximately equal to 25.754 kilograms.', + 'ton': 'Equal to 2000 pounds.\nApproximately equal to 907.18 kilograms.', + 'tonne': 'Equivalent to metric_ton.\nDefined to be 1000 kilograms.', + 'wey': 'Defined to be 252 pounds.\nApproximately equal to 114.305 kilograms.'}, 'power_docs': - {'cheval_vapeur':'Defined to be 75 kilogram force*meter/second.\nAlso known as metric horsepower.\nEqual to 735.49875 watts.', - 'horsepower':'Defined to be 550 feet*pound force/second.\nApproximately equal to 745.7 watts.', - 'watt':'SI derived unit of power.\nDefined to be joule/second or, in base units, kilogram*meter^2/second^3.'}, + {'cheval_vapeur': 'Defined to be 75 kilogram force*meter/second.\nAlso known as metric horsepower.\nEqual to 735.49875 watts.', + 'horsepower': 'Defined to be 550 feet*pound force/second.\nApproximately equal to 745.7 watts.', + 'watt': 'SI derived unit of power.\nDefined to be joule/second or, in base units, kilogram*meter^2/second^3.'}, 'pressure_docs': - {'atmosphere':'Defined to be 101325 pascals.', - 'bar':'Defined to be 100000 pascals.', - 'barye':'CGS unit defined to be dyne/centimeter^2.\nEqual to 1/10 of a pascal.', - 'inch_mercury':'Defined to be 13595.1 kilogram/meter^3*inch*gravity.\nApproximately equal to 3386.389 pascals.', - 'millimeter_mercury':'Defined to be 13595.1 kilogram/meter^3*millimeter*gravity.\nApproximately equal to 133.3224 pascals.', - 'mmhg':'Abbreviation for millimeter mercury.\nApproximately equal to 133.3224 pascals.', - 'pa':'Abbreviation for pascal.', - 'pascal':'SI derived unit of pressure.\nDefined to be newton/meter^2 or, in base units, kilogram/(meter*second^2).', - 'pounds_per_square_inch':'Defined to be pound force/inch^2.\nApproximately equal to 6894.76 pascals.', - 'psi':'Abbreviation for pounds per square inch.\nApproximately equal to 6894.76 pascals.', - 'torr':'Defined to be 1/760 of an atmosphere.\nApproximately equal to 133.322 pascals.'}, + {'atmosphere': 'Defined to be 101325 pascals.', + 'bar': 'Defined to be 100000 pascals.', + 'barye': 'CGS unit defined to be dyne/centimeter^2.\nEqual to 1/10 of a pascal.', + 'inch_mercury': 'Defined to be 13595.1 kilogram/meter^3*inch*gravity.\nApproximately equal to 3386.389 pascals.', + 'millimeter_mercury': 'Defined to be 13595.1 kilogram/meter^3*millimeter*gravity.\nApproximately equal to 133.3224 pascals.', + 'mmhg': 'Abbreviation for millimeter mercury.\nApproximately equal to 133.3224 pascals.', + 'pa': 'Abbreviation for pascal.', + 'pascal': 'SI derived unit of pressure.\nDefined to be newton/meter^2 or, in base units, kilogram/(meter*second^2).', + 'pounds_per_square_inch': 'Defined to be pound force/inch^2.\nApproximately equal to 6894.76 pascals.', + 'psi': 'Abbreviation for pounds per square inch.\nApproximately equal to 6894.76 pascals.', + 'torr': 'Defined to be 1/760 of an atmosphere.\nApproximately equal to 133.322 pascals.'}, 'radiation_absorbed_docs': - {'gray':'SI derived unit of absorbed radiation.\nDefined to be the absorption of one joule of ionizing radiation by one kilogram of matter.', - 'rad':'Defined to be 1/100 of a gray.'}, + {'gray': 'SI derived unit of absorbed radiation.\nDefined to be the absorption of one joule of ionizing radiation by one kilogram of matter.', + 'rad': 'Defined to be 1/100 of a gray.'}, 'radiation_docs': - {'becquerel':'SI derived unit of radiation.\nDefined to be the activity of a quantity of radioactive material in which one nucleus decays per second.', - 'curie':'Defined to be 37*10^9 becquerels.', - 'rutherford':'Defined to be 10^6 becquerels.'}, + {'becquerel': 'SI derived unit of radiation.\nDefined to be the activity of a quantity of radioactive material in which one nucleus decays per second.', + 'curie': 'Defined to be 37*10^9 becquerels.', + 'rutherford': 'Defined to be 10^6 becquerels.'}, 'radiation_ionizing_docs': - {'roentgen':'Defined to be .000258 coulombs/kilogram.', - 'rontgen':'Equivalent to roentgen.\nDefined to be .000258 coulombs/kilogram.'}, + {'roentgen': 'Defined to be .000258 coulombs/kilogram.', + 'rontgen': 'Equivalent to roentgen.\nDefined to be .000258 coulombs/kilogram.'}, 'resistance_docs': - {'abohm':'Defined to be 10^-9 ohms.', - 'ohm':'SI derived unit of resistance.\nDefined to be a volt per ampere.', - 'statohm':'CGS unit defined to be statvolt/statampere.\nApproximately equal to 8.98758*10^11 ohms.'}, + {'abohm': 'Defined to be 10^-9 ohms.', + 'ohm': 'SI derived unit of resistance.\nDefined to be a volt per ampere.', + 'statohm': 'CGS unit defined to be statvolt/statampere.\nApproximately equal to 8.98758*10^11 ohms.'}, 'solid_angle_docs': - {'steradian':'SI derived unit of solid angle.\nDefined to be the solid angle subtended at the center of a sphere of radius r by a portion of the surface of the sphere having an area of r^2.'}, + {'steradian': 'SI derived unit of solid angle.\nDefined to be the solid angle subtended at the center of a sphere of radius r by a portion of the surface of the sphere having an area of r^2.'}, 'temperature_docs': - {'celsius':'Defined to be -273.15 at absolute zero and 0.01 at the triple point of Vienna Standard Mean Ocean Water.\nCelsius is related to kelvin by the equation K = 273.15 + degrees Celsius.\nA change of 1 degree Celsius is equivalent to a change of 1 degree kelvin.', - 'centigrade':'Equivalent to celsius.', - 'fahrenheit':'Defined to be 32 degrees at the freezing point of water and 212 degrees at the boiling point of water, both at standard pressure (1 atmosphere).\nFahrenheit is related to kelvin by the equation K = 5/9*(degrees Fahrenheit + 459.67).\nA change of 1 degree fahrenheit is equal to a change of 5/9 kelvin.', - 'kelvin':'SI base unit of temperature.\nDefined to be exactly 0 at absolute zero and 273.16 at the triple point of Vienna Standard Mean Ocean Water.', - 'rankine':'Defined to be 0 at absolute zero and to have the same degree increment as Fahrenheit.\nRankine is related to kelvin by the equation K = 5/9*R.'}, + {'celsius': 'Defined to be -273.15 at absolute zero and 0.01 at the triple point of Vienna Standard Mean Ocean Water.\nCelsius is related to kelvin by the equation K = 273.15 + degrees Celsius.\nA change of 1 degree Celsius is equivalent to a change of 1 degree kelvin.', + 'centigrade': 'Equivalent to celsius.', + 'fahrenheit': 'Defined to be 32 degrees at the freezing point of water and 212 degrees at the boiling point of water, both at standard pressure (1 atmosphere).\nFahrenheit is related to kelvin by the equation K = 5/9*(degrees Fahrenheit + 459.67).\nA change of 1 degree fahrenheit is equal to a change of 5/9 kelvin.', + 'kelvin': 'SI base unit of temperature.\nDefined to be exactly 0 at absolute zero and 273.16 at the triple point of Vienna Standard Mean Ocean Water.', + 'rankine': 'Defined to be 0 at absolute zero and to have the same degree increment as Fahrenheit.\nRankine is related to kelvin by the equation K = 5/9*R.'}, 'time_docs': - {'century':'Defined to be 100 years.\nEqual to 3153600000 seconds.', - 'day':'Defined to be 24 hours.\nEqual to 86400 seconds.', - 'decade':'Defined to be 10 years.\nEqual to 315360000 seconds.', - 'fortnight':'Defined to be 2 weeks or 14 days.\nEqual to 1209600 seconds.', - 'hour':'Defined to be 60 minutes.\nEqual to 3600 seconds.', - 'millenium':'Defined to be 1000 years.\nEqual to 31536000000 seconds.', - 'minute':'Defined to be 60 seconds.', - 'month':'Defined to be 30 days.\nEqual to 2628000 seconds.', - 'second':'SI base unit of time.\nDefined to be the duration of 9,192,631,770 periods of the radiation corresponding to the transition between the two hyperfine levels of the ground state of the caesium 133 atom.', - 'sidereal_day':'Defined to be the time it takes for the Earth to make one complete rotation relative to the stars.\nApproximately equal to 86164.09 seconds.', - 'sidereal_second':'Defined to be 1/86400 of a sidereal day.\nApproximately equal to 0.997269566329086 seconds.', - 'sidereal_year':'Defined to be the time taken by the Earth to orbit the Sun once with respect to the fixed stars.\nApproximately equal to 31558149.7632 seconds.', - 'tropical_year':'Defined to be the length of time that the Sun takes to return to the same position in the cycle of seasons, as seen from the Earth.\nApproximately equal to 31556925.1779840 seconds.', - 'week':'Defined to be 7 days.\nEqual to 604800 seconds.', - 'year':'Defined to be 365 days.\nEqual to 31536000 seconds.'}, + {'century': 'Defined to be 100 years.\nEqual to 3153600000 seconds.', + 'day': 'Defined to be 24 hours.\nEqual to 86400 seconds.', + 'decade': 'Defined to be 10 years.\nEqual to 315360000 seconds.', + 'fortnight': 'Defined to be 2 weeks or 14 days.\nEqual to 1209600 seconds.', + 'hour': 'Defined to be 60 minutes.\nEqual to 3600 seconds.', + 'millenium': 'Defined to be 1000 years.\nEqual to 31536000000 seconds.', + 'minute': 'Defined to be 60 seconds.', + 'month': 'Defined to be 30 days.\nEqual to 2628000 seconds.', + 'second': 'SI base unit of time.\nDefined to be the duration of 9,192,631,770 periods of the radiation corresponding to the transition between the two hyperfine levels of the ground state of the caesium 133 atom.', + 'sidereal_day': 'Defined to be the time it takes for the Earth to make one complete rotation relative to the stars.\nApproximately equal to 86164.09 seconds.', + 'sidereal_second': 'Defined to be 1/86400 of a sidereal day.\nApproximately equal to 0.997269566329086 seconds.', + 'sidereal_year': 'Defined to be the time taken by the Earth to orbit the Sun once with respect to the fixed stars.\nApproximately equal to 31558149.7632 seconds.', + 'tropical_year': 'Defined to be the length of time that the Sun takes to return to the same position in the cycle of seasons, as seen from the Earth.\nApproximately equal to 31556925.1779840 seconds.', + 'week': 'Defined to be 7 days.\nEqual to 604800 seconds.', + 'year': 'Defined to be 365 days.\nEqual to 31536000 seconds.'}, 'unit_multipliers_docs': - {'bakers_dozen':'Defined to be 13 items.', - 'dozen':'Defined to be 12 items.', - 'gross':'Defined to be 144 items.', - 'percent':'Defined to be 1/100 of a quantity.'}, + {'bakers_dozen': 'Defined to be 13 items.', + 'dozen': 'Defined to be 12 items.', + 'gross': 'Defined to be 144 items.', + 'percent': 'Defined to be 1/100 of a quantity.'}, 'velocity_docs': - {'knot':'Nautical unit of velocity defined to be a nautical mile per hour.\nApproximately equal to 0.5144 meter/second.'}, + {'knot': 'Nautical unit of velocity defined to be a nautical mile per hour.\nApproximately equal to 0.5144 meter/second.'}, 'viscosity_absolute_docs': - {'poise':'CGS unit defined to be 1/10 of pascal*second.', - 'reyn':'Defined to be a pound_force*second/inch^2.\nApproximately equal to 6894.76 pascal*second.'}, + {'poise': 'CGS unit defined to be 1/10 of pascal*second.', + 'reyn': 'Defined to be a pound_force*second/inch^2.\nApproximately equal to 6894.76 pascal*second.'}, 'viscosity_kinematic_docs': - {'stokes':'CGS unit defined to be 1/10000 of meter^2/second.'}, + {'stokes': 'CGS unit defined to be 1/10000 of meter^2/second.'}, 'viscosity_other_docs': - {'rhes':'Defined to be 1/poise or 10/(pascal*second).'}, + {'rhes': 'Defined to be 1/poise or 10/(pascal*second).'}, 'volume_docs': - {'bag':'Defined to be 3 bushels.\nApproximately equal to 0.10572 cubic meters.', - 'barrel':'Defined to be 42 gallons.\nApproximately equal to 0.15899 cubic meters.', - 'board_foot':'Defined to be 144 cubic inches.\nApproximately equal to 0.0023597 cubic meters.', - 'bucket':'Defined to be 4 gallons.\nApproximately equal to 0.0151416 cubic meters.', - 'bushel':'Defined to be 2150.42 cubic inches.\nEquivalent to 4 pecks.\nApproximately equal to 0.035239 cubic meters.', - 'butt':'Old English unit of wine casks defined to be 2 hogsheads or 126 gallons.\nApproximately equal to 0.476962 cubic meters.', - 'cord':'Defined to be 8 feet x 8 feet x 4 feet.\nApproximately equal to 3.624556 cubic meters.', - 'cubic_meter':'SI derived unit of volume.\nDefined to be meter^3.', - 'cup':'Defined to be 8 fluid ounces.\nApproximately equal to 0.000236588 cubic meters.', - 'ephah':'Ancient Hebrew unit of volume equal to 10 omers.\nApproximately equal to 0.03964 cubic meters.', - 'fifth':'Defined to be 1/5 of a gallon.\nApproximately equal to 0.00075708 cubic meters.', - 'firkin':'Defined to be 9 imperial gallons.\nApproximately equal to 0.04091 cubic meters.', - 'fluid_dram':'Defined to be 1/8 of a fluid ounce.\nApproximately equal to 3.69669*10^-6 cubic meters.', - 'fluid_ounce':'Defined to be 1/128 of a gallon.\nApproximately equal to 0.000029574 cubic meters.', - 'gallon':'Defined to be 231 cubic inches.\nApproximately equal to 0.0037854 cubic meters.', - 'gill':'Defined to be 4 fluid ounces.\nApproximately equal to 0.00011829 cubic meters.', - 'hogshead':'Old English unit of wine casks defined to be 63 gallons.\nApproximately equal to 0.23848 cubic meters.', - 'imperial_gallon':'Defined to be 4.54609 liters.\nEqual to 0.00454609 cubic meters.', - 'imperial_pint':'Defined to be 1/8 of an imperial gallon.\nApproximately equal to 0.00056826 cubic meters.', - 'jeroboam':'Defined to be 4/5 of a gallon.\nApproximately equal to 0.0030283 cubic meters.', - 'jigger':'Defined to be 1 1/2 fluid ounces.\nApproximately equal to 0.00004436 cubic meters.', - 'liter':'Defined to be 1 decimeter^3.\nEqual to 1/1000 of a cubic meter.', - 'magnum':'Defined to be 1/2 a gallon.\nApproximately equal to 0.0018927 cubic meters.', - 'minim':'Defined to be 1/480 of a fluid ounce.\nApproximately equal to 6.16115*10^-8 cubic meters.', - 'noggin':'Equivalent to gill.\nDefined to be 4 fluid ounces.\nApproximately equal to 0.00011829 cubic meters.', - 'omer':'Ancient Hebrew unit of volume equal to 9/20 of a peck.\nApproximately equal to 0.0039644 cubic meters.', - 'peck':'Defined to be 1/4 of a bushel.\nApproximately equal to 0.0088098 cubic meters.', - 'pint':'Defined to be 1/8 of a gallon.\nApproximately equal to 0.00047318 cubic meters.', - 'pony':'Defined to be 3/4 of a fluid ounce.\nApproximately equal to 0.00002218 cubic meters.', - 'puncheon':'Old English unit of wine casks defined to be 84 gallons.\nApproximately equal to 0.31797 cubic meters.', - 'quart':'Defined to be 1/4 of a gallon.\nApproximately equal to 0.00094635 cubic meters.', - 'register_ton':'Defined to be 100 cubic feet.\nApproximately equal to 2.83168 cubic meters.', - 'seam':'Defined to be 8 bushels.\nApproximately equal to 0.281913 cubic meters.', - 'shot':'Defined to be 1 fluid ounce.\nApproximately equal to 0.000029574 cubic meters.', - 'stere':'Equivalent to cubic meter.', - 'tablespoon':'Defined to be 1/2 of a fluid ounce.\nApproximately equal to 0.000014787 cubic meters.', - 'teaspoon':'Defined to be 1/6 of a fluid ounce.\nEqual to 1/3 of a tablespoon.\nApproximately equal to 4.9289*10^-6 cubic meters.', - 'tun':'Old English unit of wine casks defined to be 252 gallons.\nApproximately equal to 0.95392 cubic meters.', - 'uk_gallon':'Equivalent to an imperial gallon.\nEqual to 0.00454609 cubic meters.', - 'uk_pint':'Equivalent to and imperial pint.\nApproximately equal to 0.00056826 cubic meters.', - 'wine_bottle':'Defined to be 750 milliliters.\nEqual to 0.00075 cubic meters.'} + {'bag': 'Defined to be 3 bushels.\nApproximately equal to 0.10572 cubic meters.', + 'barrel': 'Defined to be 42 gallons.\nApproximately equal to 0.15899 cubic meters.', + 'board_foot': 'Defined to be 144 cubic inches.\nApproximately equal to 0.0023597 cubic meters.', + 'bucket': 'Defined to be 4 gallons.\nApproximately equal to 0.0151416 cubic meters.', + 'bushel': 'Defined to be 2150.42 cubic inches.\nEquivalent to 4 pecks.\nApproximately equal to 0.035239 cubic meters.', + 'butt': 'Old English unit of wine casks defined to be 2 hogsheads or 126 gallons.\nApproximately equal to 0.476962 cubic meters.', + 'cord': 'Defined to be 8 feet x 8 feet x 4 feet.\nApproximately equal to 3.624556 cubic meters.', + 'cubic_meter': 'SI derived unit of volume.\nDefined to be meter^3.', + 'cup': 'Defined to be 8 fluid ounces.\nApproximately equal to 0.000236588 cubic meters.', + 'ephah': 'Ancient Hebrew unit of volume equal to 10 omers.\nApproximately equal to 0.03964 cubic meters.', + 'fifth': 'Defined to be 1/5 of a gallon.\nApproximately equal to 0.00075708 cubic meters.', + 'firkin': 'Defined to be 9 imperial gallons.\nApproximately equal to 0.04091 cubic meters.', + 'fluid_dram': 'Defined to be 1/8 of a fluid ounce.\nApproximately equal to 3.69669*10^-6 cubic meters.', + 'fluid_ounce': 'Defined to be 1/128 of a gallon.\nApproximately equal to 0.000029574 cubic meters.', + 'gallon': 'Defined to be 231 cubic inches.\nApproximately equal to 0.0037854 cubic meters.', + 'gill': 'Defined to be 4 fluid ounces.\nApproximately equal to 0.00011829 cubic meters.', + 'hogshead': 'Old English unit of wine casks defined to be 63 gallons.\nApproximately equal to 0.23848 cubic meters.', + 'imperial_gallon': 'Defined to be 4.54609 liters.\nEqual to 0.00454609 cubic meters.', + 'imperial_pint': 'Defined to be 1/8 of an imperial gallon.\nApproximately equal to 0.00056826 cubic meters.', + 'jeroboam': 'Defined to be 4/5 of a gallon.\nApproximately equal to 0.0030283 cubic meters.', + 'jigger': 'Defined to be 1 1/2 fluid ounces.\nApproximately equal to 0.00004436 cubic meters.', + 'liter': 'Defined to be 1 decimeter^3.\nEqual to 1/1000 of a cubic meter.', + 'magnum': 'Defined to be 1/2 a gallon.\nApproximately equal to 0.0018927 cubic meters.', + 'minim': 'Defined to be 1/480 of a fluid ounce.\nApproximately equal to 6.16115*10^-8 cubic meters.', + 'noggin': 'Equivalent to gill.\nDefined to be 4 fluid ounces.\nApproximately equal to 0.00011829 cubic meters.', + 'omer': 'Ancient Hebrew unit of volume equal to 9/20 of a peck.\nApproximately equal to 0.0039644 cubic meters.', + 'peck': 'Defined to be 1/4 of a bushel.\nApproximately equal to 0.0088098 cubic meters.', + 'pint': 'Defined to be 1/8 of a gallon.\nApproximately equal to 0.00047318 cubic meters.', + 'pony': 'Defined to be 3/4 of a fluid ounce.\nApproximately equal to 0.00002218 cubic meters.', + 'puncheon': 'Old English unit of wine casks defined to be 84 gallons.\nApproximately equal to 0.31797 cubic meters.', + 'quart': 'Defined to be 1/4 of a gallon.\nApproximately equal to 0.00094635 cubic meters.', + 'register_ton': 'Defined to be 100 cubic feet.\nApproximately equal to 2.83168 cubic meters.', + 'seam': 'Defined to be 8 bushels.\nApproximately equal to 0.281913 cubic meters.', + 'shot': 'Defined to be 1 fluid ounce.\nApproximately equal to 0.000029574 cubic meters.', + 'stere': 'Equivalent to cubic meter.', + 'tablespoon': 'Defined to be 1/2 of a fluid ounce.\nApproximately equal to 0.000014787 cubic meters.', + 'teaspoon': 'Defined to be 1/6 of a fluid ounce.\nEqual to 1/3 of a tablespoon.\nApproximately equal to 4.9289*10^-6 cubic meters.', + 'tun': 'Old English unit of wine casks defined to be 252 gallons.\nApproximately equal to 0.95392 cubic meters.', + 'uk_gallon': 'Equivalent to an imperial gallon.\nEqual to 0.00454609 cubic meters.', + 'uk_pint': 'Equivalent to and imperial pint.\nApproximately equal to 0.00056826 cubic meters.', + 'wine_bottle': 'Defined to be 750 milliliters.\nEqual to 0.00075 cubic meters.'} } @@ -890,38 +891,38 @@ def evalunitdict(): # Dictionary for converting from derived units to base SI units. ############################################################################### -unit_derivations = {'acceleration':'length/time^2', - 'area':'length^2', - 'capacitance':'time^4*current^2/(length^2*mass)', - 'charge':'current*time', - 'conductance':'current^2*time^3/(mass*length^2)', - 'electric_potential':'mass*length^2/(current*time^3)', - 'energy':'mass*length^2/time^2', - 'fiber_linear_mass_density':'mass/length', - 'force':'mass*length/time^2', - 'frequency':'1/time', - 'illuminance':'luminous_intensity*solid_angle/length^2', - 'inductance':'length^2*mass/(time^2*current^2)', - 'information_rate':'information/time', - 'inverse_length':'1/length', - 'luminance':'luminous_intensity/length^2', - 'luminous_energy':'luminous_intensity*solid_angle*time', - 'luminous_flux':'luminous_intensity*solid_angle', - 'magnetic_field':'mass/(current*time^2)', - 'magnetic_flux':'mass*length^2/(current*time^2)', - 'magnetic_intensity':'current/length', - 'magnetic_moment':'current*length^2', - 'power':'mass*length^2/time^3', - 'pressure':'mass/(length*time^2)', - 'radiation':'1/time', - 'radiation_absorbed':'length^2/time^2', - 'radiation_ionizing':'current*time/mass', - 'resistance':'mass*length^2/(current^2*time^3)', - 'velocity':'length/time', - 'viscosity_absolute':'mass/(length*time)', - 'viscosity_kinematic':'length^2/time', - 'viscosity_other':'length*time/mass', - 'volume':'length^3' +unit_derivations = {'acceleration': 'length/time^2', + 'area': 'length^2', + 'capacitance': 'time^4*current^2/(length^2*mass)', + 'charge': 'current*time', + 'conductance': 'current^2*time^3/(mass*length^2)', + 'electric_potential': 'mass*length^2/(current*time^3)', + 'energy': 'mass*length^2/time^2', + 'fiber_linear_mass_density': 'mass/length', + 'force': 'mass*length/time^2', + 'frequency': '1/time', + 'illuminance': 'luminous_intensity*solid_angle/length^2', + 'inductance': 'length^2*mass/(time^2*current^2)', + 'information_rate': 'information/time', + 'inverse_length': '1/length', + 'luminance': 'luminous_intensity/length^2', + 'luminous_energy': 'luminous_intensity*solid_angle*time', + 'luminous_flux': 'luminous_intensity*solid_angle', + 'magnetic_field': 'mass/(current*time^2)', + 'magnetic_flux': 'mass*length^2/(current*time^2)', + 'magnetic_intensity': 'current/length', + 'magnetic_moment': 'current*length^2', + 'power': 'mass*length^2/time^3', + 'pressure': 'mass/(length*time^2)', + 'radiation': '1/time', + 'radiation_absorbed': 'length^2/time^2', + 'radiation_ionizing': 'current*time/mass', + 'resistance': 'mass*length^2/(current^2*time^3)', + 'velocity': 'length/time', + 'viscosity_absolute': 'mass/(length*time)', + 'viscosity_kinematic': 'length^2/time', + 'viscosity_other': 'length*time/mass', + 'volume': 'length^3' } @@ -945,6 +946,7 @@ def vars_in_str(s): """ return re.findall('[a-z|_]+', s) + def unit_derivations_expr(v): """ Given derived units name, returns the corresponding units @@ -975,8 +977,8 @@ def unit_derivations_expr(v): """ v = str(v) Z = unit_derivations[v] - if isinstance(Z,str): - d = dict([(x,str_to_unit(x)) for x in vars_in_str(Z)]) + if isinstance(Z, str): + d = {x: str_to_unit(x) for x in vars_in_str(Z)} from sage.misc.sage_eval import sage_eval Z = sage_eval(Z, d) unit_derivations[v] = Z @@ -1013,6 +1015,7 @@ def _instancedoc_(self): """ return unitdocs(self) + def str_to_unit(name): """ Create the symbolic unit with given name. A symbolic unit is a @@ -1037,6 +1040,7 @@ class that derives from symbolic expression, and has a specialized """ return UnitExpression(SR, SR.var(name)) + class Units(ExtraTabCompletion): """ A collection of units of some type. @@ -1195,8 +1199,10 @@ def __repr__(self): name = ' of ' + self.__name if self.__name else '' return "Collection of units{0}: {1}".format(name, ' '.join(sorted([str(x) for x in self.__data]))) + units = Units(unitdict, '') + def unitdocs(unit): r""" Returns docstring for the given unit. @@ -1221,16 +1227,16 @@ def unitdocs(unit): sage: sage.symbolic.units.unitdocs('earth') Traceback (most recent call last): ... - ValueError: No documentation exists for the unit earth. + ValueError: no documentation exists for the unit earth """ if is_unit(unit): - return unit_docs[unit_to_type[str(unit)]+"_docs"][str(unit)] - else: - raise ValueError("No documentation exists for the unit %s."%unit) + return unit_docs[unit_to_type[str(unit)] + "_docs"][str(unit)] + raise ValueError("no documentation exists for the unit %s" % unit) + -def is_unit(s): +def is_unit(s) -> bool: """ - Returns a boolean when asked whether the input is in the list of units. + Return a boolean when asked whether the input is in the list of units. INPUT: @@ -1260,6 +1266,7 @@ def is_unit(s): """ return str(s) in unit_to_type + def convert(expr, target): """ Converts units between expr and target. If target is None then converts to SI base units. @@ -1344,7 +1351,7 @@ def convert(expr, target): if is_unit(y): tz[y] = base_units(y) base_target = base_target.subs(tz) - coeff = (expr/base_target).expand() + coeff = (expr / base_target).expand() for variable in coeff.variables(): if is_unit(str(variable)): @@ -1352,6 +1359,7 @@ def convert(expr, target): return coeff.mul(target, hold=True) + def base_units(unit): """ Converts unit to base SI units. @@ -1396,12 +1404,13 @@ def base_units(unit): if str(v) in unit_derivations: base = unit_derivations_expr(v) for i in base.variables(): - base = base.subs({i:SR.var(value_to_unit[str(i)]['1'])}) - return base*sage_eval(unitdict[str(v)][str(unit)]) + base = base.subs({i: SR.var(value_to_unit[str(i)]['1'])}) + return base * sage_eval(unitdict[str(v)][str(unit)]) else: - base = SR.var(value_to_unit[str(v)]['1'])*sage_eval(unitdict[str(v)][str(unit)]) + base = SR.var(value_to_unit[str(v)]['1']) * sage_eval(unitdict[str(v)][str(unit)]) return base + def convert_temperature(expr, target): """ Function for converting between temperatures. @@ -1452,18 +1461,18 @@ def convert_temperature(expr, target): elif target is None or unit_to_type[str(target)] == 'temperature': from sage.misc.sage_eval import sage_eval expr_temp = expr.variables()[0] - coeff = expr/expr_temp + coeff = expr / expr_temp if target is not None: target_temp = target.variables()[0] a = sage_eval(unitdict['temperature'][str(expr_temp)], locals={'x': coeff}) if target is None or target_temp == units.temperature.kelvin: - return a[0]*units.temperature.kelvin + return a[0] * units.temperature.kelvin elif target_temp == units.temperature.celsius or target_temp == units.temperature.centigrade: - return a[1]*target_temp + return a[1] * target_temp elif target_temp == units.temperature.fahrenheit: - return a[2]*units.temperature.fahrenheit + return a[2] * units.temperature.fahrenheit elif target_temp == units.temperature.rankine: - return a[3]*target_temp + return a[3] * target_temp else: raise ValueError("cannot convert") From dffe683fbc823507ef46f4a9c03e7ba4a79c4dfd Mon Sep 17 00:00:00 2001 From: David Einstein <deinst@gmail.com> Date: Sun, 25 Jun 2023 09:15:26 -0400 Subject: [PATCH 160/228] Have tuple.py return tuples instead of lists This has Tuples and UnorderedTuples return tuples. Need to fix up schemes/projective/projective_space.py as it assumes the tuples are lists. --- src/sage/combinat/tuple.py | 57 +++++++++---------- .../schemes/projective/projective_space.py | 4 +- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/sage/combinat/tuple.py b/src/sage/combinat/tuple.py index 9002e5d7fb3..61449b98e00 100644 --- a/src/sage/combinat/tuple.py +++ b/src/sage/combinat/tuple.py @@ -35,23 +35,23 @@ class Tuples(Parent, UniqueRepresentation): sage: S = [1,2] sage: Tuples(S,3).list() - [[1, 1, 1], [2, 1, 1], [1, 2, 1], [2, 2, 1], [1, 1, 2], - [2, 1, 2], [1, 2, 2], [2, 2, 2]] + [(1, 1, 1), (2, 1, 1), (1, 2, 1), (2, 2, 1), (1, 1, 2), + (2, 1, 2), (1, 2, 2), (2, 2, 2)] sage: mset = ["s","t","e","i","n"] sage: Tuples(mset,2).list() - [['s', 's'], ['t', 's'], ['e', 's'], ['i', 's'], ['n', 's'], - ['s', 't'], ['t', 't'], ['e', 't'], ['i', 't'], ['n', 't'], - ['s', 'e'], ['t', 'e'], ['e', 'e'], ['i', 'e'], ['n', 'e'], - ['s', 'i'], ['t', 'i'], ['e', 'i'], ['i', 'i'], ['n', 'i'], - ['s', 'n'], ['t', 'n'], ['e', 'n'], ['i', 'n'], ['n', 'n']] + [('s', 's'), ('t', 's'), ('e', 's'), ('i', 's'), ('n', 's'), + ('s', 't'), ('t', 't'), ('e', 't'), ('i', 't'), ('n', 't'), + ('s', 'e'), ('t', 'e'), ('e', 'e'), ('i', 'e'), ('n', 'e'), + ('s', 'i'), ('t', 'i'), ('e', 'i'), ('i', 'i'), ('n', 'i'), + ('s', 'n'), ('t', 'n'), ('e', 'n'), ('i', 'n'), ('n', 'n')] :: sage: K.<a> = GF(4, 'a') sage: mset = [x for x in K if x != 0] sage: Tuples(mset,2).list() - [[a, a], [a + 1, a], [1, a], [a, a + 1], [a + 1, a + 1], [1, a + 1], - [a, 1], [a + 1, 1], [1, 1]] + [(a, a), (a + 1, a), (1, a), (a, a + 1), (a + 1, a + 1), (1, a + 1), + (a, 1), (a + 1, 1), (1, 1)] """ @staticmethod def __classcall_private__(cls, S, k): @@ -94,22 +94,21 @@ def __iter__(self): sage: S = [1,2] sage: Tuples(S,3).list() - [[1, 1, 1], [2, 1, 1], [1, 2, 1], [2, 2, 1], [1, 1, 2], - [2, 1, 2], [1, 2, 2], [2, 2, 2]] + [(1, 1, 1), (2, 1, 1), (1, 2, 1), (2, 2, 1), (1, 1, 2), + (2, 1, 2), (1, 2, 2), (2, 2, 2)] sage: mset = ["s","t","e","i","n"] sage: Tuples(mset,2).list() - [['s', 's'], ['t', 's'], ['e', 's'], ['i', 's'], ['n', 's'], - ['s', 't'], ['t', 't'], ['e', 't'], ['i', 't'], - ['n', 't'], ['s', 'e'], ['t', 'e'], ['e', 'e'], ['i', 'e'], - ['n', 'e'], ['s', 'i'], ['t', 'i'], ['e', 'i'], - ['i', 'i'], ['n', 'i'], ['s', 'n'], ['t', 'n'], ['e', 'n'], - ['i', 'n'], ['n', 'n']] - sage: Tuples([1,1,2],3).list() - [[1, 1, 1], [2, 1, 1], [1, 2, 1], [2, 2, 1], [1, 1, 2], - [2, 1, 2], [1, 2, 2], [2, 2, 2]] + [('s', 's'), ('t', 's'), ('e', 's'), ('i', 's'), ('n', 's'), + ('s', 't'), ('t', 't'), ('e', 't'), ('i', 't'), ('n', 't'), + ('s', 'e'), ('t', 'e'), ('e', 'e'), ('i', 'e'), ('n', 'e'), + ('s', 'i'), ('t', 'i'), ('e', 'i'), ('i', 'i'), ('n', 'i'), + ('s', 'n'), ('t', 'n'), ('e', 'n'), ('i', 'n'), ('n', 'n')] + sage: Tuples((1,1,2),3).list() + [(1, 1, 1), (2, 1, 1), (1, 2, 1), (2, 2, 1), (1, 1, 2), + (2, 1, 2), (1, 2, 2), (2, 2, 2)] """ for p in product(self._index_list, repeat=self.k): - yield [self.S[i] for i in reversed(p)] + yield tuple(self.S[i] for i in reversed(p)) def cardinality(self): """ @@ -140,10 +139,10 @@ class UnorderedTuples(Parent, UniqueRepresentation): sage: S = [1,2] sage: UnorderedTuples(S,3).list() - [[1, 1, 1], [1, 1, 2], [1, 2, 2], [2, 2, 2]] + [(1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)] sage: UnorderedTuples(["a","b","c"],2).list() - [['a', 'a'], ['a', 'b'], ['a', 'c'], ['b', 'b'], ['b', 'c'], - ['c', 'c']] + [('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), + ('c', 'c')] """ @staticmethod def __classcall_private__(cls, S, k): @@ -186,15 +185,15 @@ def __iter__(self): sage: S = [1,2] sage: UnorderedTuples(S,3).list() - [[1, 1, 1], [1, 1, 2], [1, 2, 2], [2, 2, 2]] + [(1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)] sage: UnorderedTuples(["a","b","c"],2).list() - [['a', 'a'], ['a', 'b'], ['a', 'c'], ['b', 'b'], ['b', 'c'], - ['c', 'c']] + [('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), + ('c', 'c')] sage: UnorderedTuples([1,1,2],3).list() - [[1, 1, 1], [1, 1, 2], [1, 2, 2], [2, 2, 2]] + [(1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)] """ for ans in combinations_with_replacement(self._index_list, self.k): - yield [self.S[i] for i in ans] + yield tuple(self.S[i] for i in ans) def cardinality(self): """ diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 221dca45981..67552b90ab8 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -2068,7 +2068,7 @@ def subscheme_from_Chow_form(self, Ch, dim): L1 = [] for t in UnorderedTuples(list(range(n + 1)), dim + 1): if all(t[i] < t[i + 1] for i in range(dim)): - L1.append(t) + L1.append(list(t)) # create the dual brackets L2 = [] signs = [] @@ -2374,7 +2374,7 @@ def rational_points(self, bound=0): for ai in R: P[i] = ai for tup in S[i - 1]: - if gcd([ai] + tup) == 1: + if gcd([ai] + list(tup)) == 1: for j in range(i): P[j] = tup[j] pts.append(self(P)) From 472074f39f136afcf7c324564595c6a7ef91ac85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= <tornaria@cmat.edu.uy> Date: Sun, 25 Jun 2023 10:20:57 -0300 Subject: [PATCH 161/228] Support setuptools 68.0.0 In setuptools 68.0.0 deprecation warnings for pkg_resources are issued with `stacklevel=2` so they belong to the calling module instead of pkg_resources. The deprecation warning we filter is reported on `setuptools.sandbox`. We fix this, otherwise lots of doctests will fail. --- src/sage/all__sagemath_repl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/all__sagemath_repl.py b/src/sage/all__sagemath_repl.py index 6800eb9a27b..8d0b43679ca 100644 --- a/src/sage/all__sagemath_repl.py +++ b/src/sage/all__sagemath_repl.py @@ -44,7 +44,7 @@ warnings.filterwarnings('ignore', category=DeprecationWarning, message='pkg_resources is deprecated as an API|' 'Deprecated call to `pkg_resources.declare_namespace(.*)`', - module='pkg_resources') + module='pkg_resources|setuptools.sandbox') warnings.filterwarnings('ignore', category=DeprecationWarning, message='msvccompiler is deprecated and slated to be removed', module='distutils.msvccompiler') From b7427769025aef7400161cca8160d13463f02f12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= <tornaria@cmat.edu.uy> Date: Sun, 25 Jun 2023 11:51:00 -0300 Subject: [PATCH 162/228] Make sure #26968 is not unfixed after #35707. Calling initialize-runtime-globals will run set-pathnames and be subject to the issue described in #26968. Thus the workaround introduced in #35195 has to be done before anything that may call set-pathnames (e.g. initialize-runtime-globals). --- src/sage/interfaces/maxima_lib.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/sage/interfaces/maxima_lib.py b/src/sage/interfaces/maxima_lib.py index c90196a0a48..cd1be891872 100644 --- a/src/sage/interfaces/maxima_lib.py +++ b/src/sage/interfaces/maxima_lib.py @@ -133,12 +133,12 @@ ecl_eval("(require 'maxima \"{}\")".format(MAXIMA_FAS)) else: ecl_eval("(require 'maxima)") -ecl_eval("(maxima::initialize-runtime-globals)") ecl_eval("(in-package :maxima)") -ecl_eval("(setq $nolabels t))") -ecl_eval("(defvar *MAXIMA-LANG-SUBDIR* NIL)") ecl_eval("(set-locale-subdir)") +# This workaround has to happen before any call to (set-pathnames). +# To be safe please do not call anything other than +# (set-locale-subdir) before this block. try: ecl_eval("(set-pathnames)") except RuntimeError: @@ -155,6 +155,8 @@ # Call `(set-pathnames)` again to complete its job. ecl_eval("(set-pathnames)") +ecl_eval("(initialize-runtime-globals)") +ecl_eval("(setq $nolabels t))") ecl_eval("(defun add-lineinfo (x) x)") ecl_eval('(defun principal nil (cond ($noprincipal (diverg)) ((not pcprntd) (merror "Divergent Integral"))))') ecl_eval("(remprop 'mfactorial 'grind)") # don't use ! for factorials (#11539) From 14e75408bd152d24979ff83e2772ab157f0b52a3 Mon Sep 17 00:00:00 2001 From: David Einstein <deinst@gmail.com> Date: Sun, 25 Jun 2023 11:07:08 -0400 Subject: [PATCH 163/228] Switch tuple to list in projective_space.py Part of the ongoing project to free Tuple of GAP. --- src/sage/schemes/projective/projective_space.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 67552b90ab8..744cb779fc4 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -2374,7 +2374,7 @@ def rational_points(self, bound=0): for ai in R: P[i] = ai for tup in S[i - 1]: - if gcd([ai] + list(tup)) == 1: + if gcd((ai,) + tup) == 1: for j in range(i): P[j] = tup[j] pts.append(self(P)) From 4eddb7c8502fd1d1cc6ff5957776b130751262ca Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sun, 25 Jun 2023 09:01:08 -0700 Subject: [PATCH 164/228] src/sage/misc/package.py: Do not fail if SAGE_PKGS is not set --- src/sage/misc/package.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/misc/package.py b/src/sage/misc/package.py index 86d2ced7173..110f6b36d7b 100644 --- a/src/sage/misc/package.py +++ b/src/sage/misc/package.py @@ -137,7 +137,7 @@ def spkg_type(name): EXAMPLES:: sage: from sage.misc.package import spkg_type - sage: spkg_type('pip') + sage: spkg_type('pip') # optional - sage_spkg 'standard' OUTPUT: @@ -148,6 +148,8 @@ def spkg_type(name): """ spkg_type = None from sage.env import SAGE_PKGS + if not SAGE_PKGS: + return None try: f = open(os.path.join(SAGE_PKGS, name, "type")) except IOError: From de0a59893108ea406d25750c376f5881eea19fe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Sun, 25 Jun 2023 20:47:06 +0200 Subject: [PATCH 165/228] some pep8 for E272 in quadratic forms --- src/sage/quadratic_forms/constructions.py | 2 +- ...dratic_form__mass__Conway_Sloane_masses.py | 86 ++++++------ .../quadratic_form__mass__Siegel_densities.py | 127 +++++++++--------- .../quadratic_form__reduction_theory.py | 124 ++++++++--------- src/sage/quadratic_forms/special_values.py | 4 +- 5 files changed, 168 insertions(+), 175 deletions(-) diff --git a/src/sage/quadratic_forms/constructions.py b/src/sage/quadratic_forms/constructions.py index e21613de790..48a4d056e28 100644 --- a/src/sage/quadratic_forms/constructions.py +++ b/src/sage/quadratic_forms/constructions.py @@ -90,4 +90,4 @@ def HyperbolicPlane_quadratic_form(R, r=1): raise TypeError("the multiplicity r must be a natural number") H = QuadraticForm(R, 2, [0, 1, 0]) - return sum([H for i in range(r - 1)], H) + return sum([H for i in range(r - 1)], H) diff --git a/src/sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py b/src/sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py index 08543c49629..2c8adf9cf6c 100644 --- a/src/sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py +++ b/src/sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py @@ -83,7 +83,7 @@ def parity(self, allow_rescaling_flag=True): # Identify the correct Jordan component to use. Jordan_list = self.jordan_blocks_by_scale_and_unimodular(2) - scale_pow_list = [J[0] for J in Jordan_list] + scale_pow_list = [J[0] for J in Jordan_list] min_scale_pow = min(scale_pow_list) if allow_rescaling_flag: ind = scale_pow_list.index(min_scale_pow) @@ -104,13 +104,12 @@ def parity(self, allow_rescaling_flag=True): # convention of the local_normal_form routine will appear first). if Q0.dim() == 1: return "odd" - elif Q0[0,1] == 0: + if Q0[0, 1] == 0: return "odd" - else: - return "even" + return "even" -def is_even(self, allow_rescaling_flag=True): +def is_even(self, allow_rescaling_flag=True) -> bool: r""" Return true iff after rescaling by some appropriate factor, the form represents no odd integers. For more details, see :meth:`parity`. @@ -125,7 +124,6 @@ def is_even(self, allow_rescaling_flag=True): sage: Q = QuadraticForm(ZZ, 2, [1, 1, 1]) sage: Q.is_even() True - """ return self.parity(allow_rescaling_flag) == "even" @@ -274,17 +272,17 @@ def conway_species_list_at_2(self): if jordan_list[i].is_even(): two_t = d else: - two_t = ZZ(2) * ((d-1) // 2) + two_t = ZZ(2) * ((d - 1) // 2) # Determine if the form is bound if len(jordan_list) == 1: is_bound = False elif i == 0: - is_bound = jordan_list[i+1].is_odd() + is_bound = jordan_list[i + 1].is_odd() elif i == len(jordan_list) - 1: - is_bound = jordan_list[i-1].is_odd() + is_bound = jordan_list[i - 1].is_odd() else: - is_bound = jordan_list[i-1].is_odd() or jordan_list[i+1].is_odd() + is_bound = jordan_list[i - 1].is_odd() or jordan_list[i + 1].is_odd() # Determine the species octane = jordan_list[i].conway_octane_of_this_unimodular_Jordan_block_at_2() @@ -338,16 +336,16 @@ def conway_octane_of_this_unimodular_Jordan_block_at_2(self): # Deal with 'odd' forms by diagonalizing, and then computing the octane. n = self.dim() - u = self[0,0] - tmp_diag_vec = [None for i in range(n)] + u = self[0, 0] + tmp_diag_vec = [None for i in range(n)] tmp_diag_vec[0] = u # This should be an odd integer! - ind = 1 # The next index to diagonalize + ind = 1 # The next index to diagonalize # Use u to diagonalize the form -- WHAT ARE THE POSSIBLE LOCAL NORMAL FORMS? while ind < n: # Check for a 1x1 block and diagonalize it - if (ind == (n-1)) or (self[ind, ind+1] == 0): + if ind == (n - 1) or self[ind, ind + 1] == 0: tmp_diag_vec[ind] = self[ind, ind] ind += 1 @@ -406,7 +404,7 @@ def conway_diagonal_factor(self, p): sage: Q.conway_diagonal_factor(3) 81/256 """ - # Get the species list at p + # Get the species list at p if p == 2: species_list = self.conway_species_list_at_2() else: @@ -418,9 +416,11 @@ def conway_diagonal_factor(self, p): if s == 0: pass elif s % 2 == 1: # Note: Here always s > 0. - diag_factor = diag_factor / (2 * prod([1 - QQ(p)**(-i) for i in range(2, s, 2)])) + diag_factor = diag_factor / (2 * prod([1 - QQ(p)**(-i) + for i in range(2, s, 2)])) else: - diag_factor = diag_factor / (2 * prod([1 - QQ(p)**(-i) for i in range(2, abs(s), 2)])) + diag_factor = diag_factor / (2 * prod([1 - QQ(p)**(-i) + for i in range(2, abs(s), 2)])) s_sign = ZZ(s / abs(s)) diag_factor = diag_factor / (ZZ(1) - s_sign * QQ(p) ** ZZ(-abs(s) / ZZ(2))) @@ -455,13 +455,10 @@ def conway_cross_product_doubled_power(self, p): sage: Q.conway_cross_product_doubled_power(13) 0 """ - doubled_power = 0 - dim_list = [J.dim() for J in self.jordan_blocks_in_unimodular_list_by_scale_power(p)] - for i in range(len(dim_list)): - for j in range(i): - doubled_power += (i-j) * dim_list[i] * dim_list[j] - - return doubled_power + dim_list = [J.dim() for J in self.jordan_blocks_in_unimodular_list_by_scale_power(p)] + return sum((i - j) * dimi * dim_list[j] + for i, dimi in enumerate(dim_list) + for j in range(i)) def conway_type_factor(self): @@ -477,8 +474,9 @@ def conway_type_factor(self): 4 """ jordan_list = self.jordan_blocks_in_unimodular_list_by_scale_power(2) - n2 = sum([J.dim() for J in jordan_list if J.is_even()]) - n11 = sum([1 for i in range(len(jordan_list) - 1) if jordan_list[i].is_odd() and jordan_list[i+1].is_odd()]) + n2 = sum([J.dim() for J in jordan_list if J.is_even()]) + n11 = sum([1 for i in range(len(jordan_list) - 1) + if jordan_list[i].is_odd() and jordan_list[i + 1].is_odd()]) return ZZ(2)**(n11 - n2) @@ -533,18 +531,19 @@ def conway_standard_p_mass(self, p): if n % 2 == 0: s = n // 2 else: - s = (n+1) // 2 + s = (n + 1) // 2 # Compute the inverse of the generic p-mass - p_mass_inv = 2 * prod([1-p**(-i) for i in range(2, 2*s, 2)]) + p_mass_inv = 2 * prod([1 - p**(-i) for i in range(2, 2 * s, 2)]) if n % 2 == 0: - D = (-1)**s * self.det() * (2**n) # We should have something like D = (-1)**s * self.det() / (2**n), but that's not an integer and here we only care about the square-class. - #d = self.det() # Note: No normalizing power of 2 is needed since the power is even. - #if not ((p == 2) or (d % p == 0)): + D = (-1)**s * self.det() * (2**n) + # We should have something like D = (-1)**s * self.det() / (2**n), but that's not an integer and here we only care about the square-class. + # d = self.det() # Note: No normalizing power of 2 is needed since the power is even. + # if not ((p == 2) or (d % p == 0)): p_mass_inv *= (1 - kronecker_symbol(fundamental_discriminant(D), p) * p**(-s)) # Return the standard p-mass - return ZZ(1) / p_mass_inv + return ZZ.one() / p_mass_inv def conway_standard_mass(self): @@ -572,14 +571,16 @@ def conway_standard_mass(self): if n % 2 == 0: s = n // 2 else: - s = (n+1) // 2 + s = (n + 1) // 2 - generic_mass = 2 * pi**((-1) * n * (n+1) / ZZ(4)) \ - * prod([gamma__exact(j / ZZ(2)) for j in range(1, n+1)]) \ - * prod([zeta__exact(2*k) for k in range(1, s)]) + generic_mass = 2 * pi**((-1) * n * (n + 1) / ZZ(4)) \ + * prod([gamma__exact(j / ZZ(2)) for j in range(1, n + 1)]) \ + * prod([zeta__exact(2 * k) for k in range(1, s)]) if n % 2 == 0: - D = (-1)**s * self.det() * (2**n) # We should have something like D = (-1)**s * self.det() / (2**n), but that's not an integer and here we only care about the square-class. + D = (-1)**s * self.det() * (2**n) + # We should have something like D = (-1)**s * self.det() / (2**n), but + # that's not an integer and here we only care about the square-class. generic_mass *= quadratic_L_function__exact(s, D) return generic_mass @@ -621,7 +622,7 @@ def conway_mass(self): # Adjust the p-masses when p|2d d = self.det() - for p in prime_divisors(2*d): + for p in prime_divisors(2 * d): mass *= (Q.conway_p_mass(p) / Q.conway_standard_p_mass(p)) # Cache and return the (simplified) result @@ -629,7 +630,7 @@ def conway_mass(self): return self.__conway_mass -#def conway_generic_mass(self): +# def conway_generic_mass(self): # """ # Computes the generic mass given as # 2 \pi^{-n(n+1)/4} \prod_{j=1}^{n} \Gamma\(\tfrac{j}{2}\) @@ -664,10 +665,3 @@ def conway_mass(self): # # # Return the answer # return ans - - -#def conway_p_mass_adjustment(self, p): -# """ -# Computes the adjustment to give the p-mass from the generic mass. -# """ -# pass diff --git a/src/sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py b/src/sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py index d0a668381b8..2281139adaf 100644 --- a/src/sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py +++ b/src/sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py @@ -2,7 +2,7 @@ Local Masses and Siegel Densities """ ######################################################################## -# Computes the local masses (rep'n densities of a form by itself) for a quadratic forms over ZZ +# Computes the local masses (rep'n densities of a form by itself) for a quadratic form over ZZ # using the papers of Pall [PSPUM VIII (1965), pp95--105] for p>2, and Watson [Mathematika # 23, no. 1, (1976), pp 94--106] for p=2. These formulas will also work for any local field # which is unramified at p=2. @@ -64,28 +64,28 @@ def mass__by_Siegel_densities(self, odd_algorithm="Pall", even_algorithm="Watson # Setup n = self.dim() - s = (n-1) // 2 + s = (n - 1) // 2 if n % 2 != 0: - char_d = squarefree_part(2*self.det()) # Accounts for the det as a QF + char_d = squarefree_part(2 * self.det()) # Accounts for the det as a QF else: char_d = squarefree_part(self.det()) # Form the generic zeta product - generic_prod = ZZ(2) * (pi)**(-ZZ(n) * (n+1) / 4) + generic_prod = ZZ(2) * (pi)**(-ZZ(n) * (n + 1) / 4) ########################################## - generic_prod *= (self.det())**(ZZ(n+1)/2) # ***** This uses the Hessian Determinant ******** + generic_prod *= self.det()**(ZZ(n + 1) / 2) # ***** This uses the Hessian Determinant ******** ########################################## - generic_prod *= prod([gamma__exact(ZZ(j)/2) for j in range(1,n+1)]) - generic_prod *= prod([zeta__exact(ZZ(j)) for j in range(2, 2*s+1, 2)]) - if (n % 2 == 0): - generic_prod *= quadratic_L_function__exact(n//2, ZZ(-1)**(n//2) * char_d) + generic_prod *= prod([gamma__exact(ZZ(j) / 2) for j in range(1, n + 1)]) + generic_prod *= prod([zeta__exact(ZZ(j)) for j in range(2, 2 * s + 1, 2)]) + if n % 2 == 0: + generic_prod *= quadratic_L_function__exact(n // 2, ZZ(-1)**(n // 2) * char_d) # Determine the adjustment factors adj_prod = ZZ.one() for p in prime_divisors(2 * self.det()): # Cancel out the generic factors - p_adjustment = prod([1 - ZZ(p)**(-j) for j in range(2, 2*s+1, 2)]) - if (n % 2 == 0): - p_adjustment *= (1 - kronecker((-1)**(n//2) * char_d, p) * ZZ(p)**(-n//2)) + p_adjustment = prod([1 - ZZ(p)**(-j) for j in range(2, 2 * s + 1, 2)]) + if n % 2 == 0: + p_adjustment *= (1 - kronecker((-1)**(n // 2) * char_d, p) * ZZ(p)**(-n // 2)) # Insert the new mass factors if p == 2: if even_algorithm == "Kitaoka": @@ -104,7 +104,7 @@ def mass__by_Siegel_densities(self, odd_algorithm="Pall", even_algorithm="Watson adj_prod *= p_adjustment # Extra adjustment for the case of a 2-dimensional form. - #if (n == 2): + # if (n == 2): # generic_prod *= 2 # Return the mass @@ -145,24 +145,24 @@ def Pall_mass_density_at_odd_prime(self, p): # Step 1: Obtain a p-adic (diagonal) local normal form, and # compute the invariants for each Jordan block. jordan_list = self.jordan_blocks_by_scale_and_unimodular(p) - modified_jordan_list = [(a, Q.dim(), Q.det()) for (a,Q) in jordan_list] # List of pairs (scale, det) + modified_jordan_list = [(a, Q.dim(), Q.det()) for a, Q in jordan_list] # List of pairs (scale, det) # Step 2: Compute the list of local masses for each Jordan block jordan_mass_list = [] - for (s,n,d) in modified_jordan_list: - generic_factor = prod([1 - p**(-2*j) for j in range(1, (n-1)//2+1)]) - if (n % 2 == 0): - m = n/2 + for (s, n, d) in modified_jordan_list: + generic_factor = prod([1 - p**(-2 * j) for j in range(1, (n - 1) // 2 + 1)]) + if n % 2 == 0: + m = n // 2 generic_factor *= (1 + legendre_symbol(((-1)**m) * d, p) * p**(-m)) jordan_mass_list = jordan_mass_list + [generic_factor] # Step 3: Compute the local mass $\al_p$ at p. MJL = modified_jordan_list s = len(modified_jordan_list) - M = [sum([MJL[j][1] for j in range(i, s)]) for i in range(s-1)] # Note: It's s-1 since we don't need the last M. - nu = sum([M[i] * MJL[i][0] * MJL[i][1] for i in range(s-1)]) - ZZ(sum([J[0] * J[1] * (J[1]-1) for J in MJL]))/ZZ(2) + M = [sum([MJL[j][1] for j in range(i, s)]) for i in range(s - 1)] # Note: It's s-1 since we don't need the last M. + nu = sum([M[i] * MJL[i][0] * MJL[i][1] for i in range(s - 1)]) - ZZ(sum([J[0] * J[1] * (J[1] - 1) for J in MJL])) / ZZ(2) p_mass = prod(jordan_mass_list) - p_mass *= 2**(s-1) * p**nu + p_mass *= 2**(s - 1) * p**nu print(jordan_list, MJL, jordan_mass_list, p_mass) @@ -183,7 +183,6 @@ def Watson_mass_at_2(self): sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1]) sage: Q.Watson_mass_at_2() # WARNING: WE NEED TO CHECK THIS CAREFULLY! # optional - sage.symbolic 384 - """ from sage.functions.all import sgn @@ -193,48 +192,49 @@ def Watson_mass_at_2(self): # Step 0: Compute Jordan blocks and bounds of the scales to keep track of Jordan_Blocks = self.jordan_blocks_by_scale_and_unimodular(2) - scale_list = [B[0] for B in Jordan_Blocks] + scale_list = [B[0] for B in Jordan_Blocks] s_min = min(scale_list) s_max = max(scale_list) # Step 1: Compute dictionaries of the diagonal block and 2x2 block for each scale - diag_dict = dict((i, Null_Form) for i in range(s_min-2, s_max + 4)) # Initialize with the zero form - dim2_dict = dict((i, Null_Form) for i in range(s_min, s_max + 4)) # Initialize with the zero form - for (s,L) in Jordan_Blocks: + diag_dict = dict((i, Null_Form) for i in range(s_min - 2, s_max + 4)) # Initialize with the zero form + dim2_dict = dict((i, Null_Form) for i in range(s_min, s_max + 4)) # Initialize with the zero form + for s, L in Jordan_Blocks: i = 0 - while (i < L.dim()-1) and (L[i,i+1] == 0): # Find where the 2x2 blocks start - i = i + 1 - if i < (L.dim() - 1): + while i < L.dim() - 1 and L[i, i + 1] == 0: # Find where the 2x2 blocks start + i += 1 + if i < L.dim() - 1: diag_dict[s] = L.extract_variables(range(i)) # Diagonal Form - dim2_dict[s+1] = L.extract_variables(range(i, L.dim())) # Non-diagonal Form + dim2_dict[s + 1] = L.extract_variables(range(i, L.dim())) # Non-diagonal Form else: diag_dict[s] = L # Step 2: Compute three dictionaries of invariants (for n_j, m_j, nu_j) - n_dict = dict((j,0) for j in range(s_min+1, s_max+2)) - m_dict = dict((j,0) for j in range(s_min, s_max+4)) - for (s,L) in Jordan_Blocks: - n_dict[s+1] = L.dim() + n_dict = dict((j, 0) for j in range(s_min + 1, s_max + 2)) + m_dict = dict((j, 0) for j in range(s_min, s_max + 4)) + for s, L in Jordan_Blocks: + n_dict[s + 1] = L.dim() if diag_dict[s].dim() == 0: - m_dict[s+1] = ZZ.one()/ZZ(2) * L.dim() + m_dict[s + 1] = ZZ.one() / ZZ(2) * L.dim() else: - m_dict[s+1] = ZZ(L.dim() - 1) // ZZ(2) + m_dict[s + 1] = ZZ(L.dim() - 1) // ZZ(2) - nu_dict = dict((j,n_dict[j+1] - 2*m_dict[j+1]) for j in range(s_min, s_max+1)) - nu_dict[s_max+1] = 0 + nu_dict = dict((j, n_dict[j + 1] - 2 * m_dict[j + 1]) + for j in range(s_min, s_max + 1)) + nu_dict[s_max + 1] = 0 # Step 3: Compute the e_j dictionary eps_dict = {} - for j in range(s_min, s_max+3): - two_form = (diag_dict[j-2] + diag_dict[j] + dim2_dict[j]).scale_by_factor(2) - j_form = (two_form + diag_dict[j-1]).change_ring(IntegerModRing(4)) + for j in range(s_min, s_max + 3): + two_form = (diag_dict[j - 2] + diag_dict[j] + dim2_dict[j]).scale_by_factor(2) + j_form = (two_form + diag_dict[j - 1]).change_ring(IntegerModRing(4)) if j_form.dim() == 0: eps_dict[j] = 1 else: iter_vec = [4] * j_form.dim() - alpha = sum([True for x in mrange(iter_vec) if j_form(x) == 0]) - beta = sum([True for x in mrange(iter_vec) if j_form(x) == 2]) + alpha = sum(1 for x in mrange(iter_vec) if j_form(x) == 0) + beta = sum(1 for x in mrange(iter_vec) if j_form(x) == 2) if alpha > beta: eps_dict[j] = 1 elif alpha == beta: @@ -244,10 +244,10 @@ def Watson_mass_at_2(self): # Step 4: Compute the quantities nu, q, P, E for the local mass at 2 nu = sum([j * n_dict[j] * (ZZ(n_dict[j] + 1) / ZZ(2) + - sum([n_dict[r] for r in range(j+1, s_max+2)])) for j in range(s_min+1, s_max+2)]) - q = sum([sgn(nu_dict[j-1] * (n_dict[j] + sgn(nu_dict[j]))) for j in range(s_min+1, s_max+2)]) - P = prod([prod([1 - QQ(4)**(-k) for k in range(1, m_dict[j]+1)]) for j in range(s_min+1, s_max+2)]) - E = prod([ZZ(1)/ZZ(2) * (1 + eps_dict[j] * QQ(2)**(-m_dict[j])) for j in range(s_min, s_max+3)]) + sum([n_dict[r] for r in range(j + 1, s_max + 2)])) for j in range(s_min + 1, s_max + 2)]) + q = sum([sgn(nu_dict[j - 1] * (n_dict[j] + sgn(nu_dict[j]))) for j in range(s_min + 1, s_max + 2)]) + P = prod([prod([1 - QQ(4)**(-k) for k in range(1, m_dict[j] + 1)]) for j in range(s_min + 1, s_max + 2)]) + E = prod([ZZ(1) / ZZ(2) * (1 + eps_dict[j] * QQ(2)**(-m_dict[j])) for j in range(s_min, s_max + 3)]) # Step 5: Compute the local mass for the prime 2. mass_at_2 = QQ(2)**(nu - q) * P / E @@ -275,30 +275,30 @@ def Kitaoka_mass_at_2(self): # Step 0: Compute Jordan blocks and bounds of the scales to keep track of Jordan_Blocks = self.jordan_blocks_by_scale_and_unimodular(2) - scale_list = [B[0] for B in Jordan_Blocks] + scale_list = [B[0] for B in Jordan_Blocks] s_min = min(scale_list) s_max = max(scale_list) # Step 1: Compute dictionaries of the diagonal block and 2x2 block for each scale - diag_dict = dict((i, Null_Form) for i in range(s_min-2, s_max + 4)) # Initialize with the zero form - dim2_dict = dict((i, Null_Form) for i in range(s_min, s_max + 4)) # Initialize with the zero form - for (s,L) in Jordan_Blocks: + diag_dict = dict((i, Null_Form) for i in range(s_min - 2, s_max + 4)) # Initialize with the zero form + dim2_dict = dict((i, Null_Form) for i in range(s_min, s_max + 4)) # Initialize with the zero form + for s, L in Jordan_Blocks: i = 0 - while (i < L.dim()-1) and (L[i,i+1] == 0): # Find where the 2x2 blocks start - i = i + 1 - if i < (L.dim() - 1): + while i < L.dim() - 1 and L[i, i + 1] == 0: # Find where the 2x2 blocks start + i += 1 + if i < L.dim() - 1: diag_dict[s] = L.extract_variables(range(i)) # Diagonal Form - dim2_dict[s+1] = L.extract_variables(range(i, L.dim())) # Non-diagonal Form + dim2_dict[s + 1] = L.extract_variables(range(i, L.dim())) # Non-diagonal Form else: diag_dict[s] = L - ################# START EDITING HERE ################## + # ################ START EDITING HERE ################## # Compute q := sum of the q_j q = 0 for j in range(s_min, s_max + 1): if diag_dict[j].dim() > 0: # Check that N_j is odd (i.e. rep'ns an odd #) - if diag_dict[j+1].dim() == 0: + if diag_dict[j + 1].dim() == 0: q += Jordan_Blocks[j][1].dim() # When N_{j+1} is "even", add n_j else: q += Jordan_Blocks[j][1].dim() + 1 # When N_{j+1} is "odd", add n_j + 1 @@ -312,8 +312,8 @@ def Kitaoka_mass_at_2(self): # Compute the product E := prod_j (1 / E_j) E = QQ.one() for j in range(s_min - 1, s_max + 2): - if (diag_dict[j-1].dim() == 0) and (diag_dict[j+1].dim() == 0) and \ - ((diag_dict[j].dim() != 2) or (((diag_dict[j][0,0] - diag_dict[j][1,1]) % 4) != 0)): + if (diag_dict[j - 1].dim() == 0) and (diag_dict[j + 1].dim() == 0) and \ + ((diag_dict[j].dim() != 2) or (((diag_dict[j][0, 0] - diag_dict[j][1, 1]) % 4) != 0)): # Deal with the complicated case: tmp_m = dim2_dict[j].dim() // 2 @@ -327,9 +327,9 @@ def Kitaoka_mass_at_2(self): # Compute the exponent w w = QQ.zero() - for j in range(s_min, s_max+1): + for j in range(s_min, s_max + 1): n_j = Jordan_Blocks[j][1].dim() - for k in range(j+1, s_max+1): + for k in range(j + 1, s_max + 1): n_k = Jordan_Blocks[k][1].dim() w += j * n_j * (n_k + QQ(n_j + 1) / 2) @@ -367,6 +367,5 @@ def mass_at_two_by_counting_mod_power(self, k): n = self.dim() MS = MatrixSpace(R, n) - ct = sum([1 for x in mrange([2**k] * (n**2)) if Q1(MS(x)) == Q1]) # Count the solutions mod 2^k - two_mass = ZZ(1)/2 * (ZZ(ct) / ZZ(2)**(k*n*(n-1)/2)) - return two_mass + ct = sum(1 for x in mrange([2**k] * (n**2)) if Q1(MS(x)) == Q1) # Count the solutions mod 2^k + return ZZ.one() / 2 * (ZZ(ct) / ZZ(2)**(k * n * (n - 1) / 2)) diff --git a/src/sage/quadratic_forms/quadratic_form__reduction_theory.py b/src/sage/quadratic_forms/quadratic_form__reduction_theory.py index 03fab299d48..584f7374b75 100644 --- a/src/sage/quadratic_forms/quadratic_form__reduction_theory.py +++ b/src/sage/quadratic_forms/quadratic_form__reduction_theory.py @@ -4,10 +4,10 @@ from copy import deepcopy from sage.matrix.constructor import matrix from sage.misc.lazy_import import lazy_import -lazy_import("sage.functions.all", "floor") from sage.misc.mrange import mrange from sage.modules.free_module_element import vector from sage.rings.integer_ring import ZZ +lazy_import("sage.functions.all", "floor") def reduced_binary_form1(self): @@ -34,22 +34,22 @@ def reduced_binary_form1(self): R = self.base_ring() interior_reduced_flag = False Q = deepcopy(self) - M = matrix(R, 2, 2, [1,0,0,1]) + M = matrix(R, 2, 2, [1, 0, 0, 1]) while not interior_reduced_flag: interior_reduced_flag = True # Arrange for a <= c - if Q[0,0] > Q[1,1]: - M_new = matrix(R,2,2,[0, -1, 1, 0]) + if Q[0, 0] > Q[1, 1]: + M_new = matrix(R, 2, 2, [0, -1, 1, 0]) Q = Q(M_new) M = M * M_new interior_reduced_flag = False # Arrange for |b| <= a - if abs(Q[0,1]) > Q[0,0]: - r = R(floor(round(Q[0,1]/(2*Q[0,0])))) - M_new = matrix(R,2,2,[1, -r, 0, 1]) + if abs(Q[0, 1]) > Q[0, 0]: + r = R(floor(round(Q[0, 1] / (2 * Q[0, 0])))) + M_new = matrix(R, 2, 2, [1, -r, 0, 1]) Q = Q(M_new) M = M * M_new interior_reduced_flag = False @@ -96,35 +96,35 @@ def reduced_binary_form(self): Q = deepcopy(self) M = matrix(R, n, n) for i in range(n): - M[i,i] = 1 + M[i, i] = 1 while not interior_reduced_flag: interior_reduced_flag = True # Arrange for (weakly) increasing diagonal entries for i in range(n): - for j in range(i+1,n): - if Q[i,i] > Q[j,j]: - M_new = matrix(R,n,n) + for j in range(i + 1, n): + if Q[i, i] > Q[j, j]: + M_new = matrix(R, n, n) for k in range(n): - M_new[k,k] = 1 - M_new[i,j] = -1 - M_new[j,i] = 1 - M_new[i,i] = 0 - M_new[j,j] = 1 + M_new[k, k] = 1 + M_new[i, j] = -1 + M_new[j, i] = 1 + M_new[i, i] = 0 + M_new[j, j] = 1 Q = Q(M_new) M = M * M_new interior_reduced_flag = False # Arrange for |b| <= a - if abs(Q[i,j]) > Q[i,i]: - r = R(floor(round(Q[i,j]/(2*Q[i,i])))) + if abs(Q[i, j]) > Q[i, i]: + r = R(floor(round(Q[i, j] / (2 * Q[i, i])))) - M_new = matrix(R,n,n) + M_new = matrix(R, n, n) for k in range(n): - M_new[k,k] = 1 - M_new[i,j] = -r + M_new[k, k] = 1 + M_new[i, j] = -r Q = Q(M_new) M = M * M_new @@ -232,10 +232,10 @@ def minkowski_reduction(self): # Loop through possible shorted vectors until done_flag = True - for j in range(n-1, -1, -1): - for a_first in mrange([3 for i in range(j)]): - y = [x-1 for x in a_first] + [1] + [0 for k in range(n-1-j)] - e_j = [0 for k in range(n)] + for j in range(n - 1, -1, -1): + for a_first in mrange([3 for i in range(j)]): + y = [x - 1 for x in a_first] + [1] + [0] * (n - 1 - j) + e_j = [0] * n e_j[j] = 1 # Reduce if a shorter vector is found @@ -244,12 +244,12 @@ def minkowski_reduction(self): # Create the transformation matrix M_new = matrix(R, n, n) for k in range(n): - M_new[k,k] = 1 + M_new[k, k] = 1 for k in range(n): - M_new[k,j] = y[k] + M_new[k, j] = y[k] # Perform the reduction and restart the loop - Q = QuadraticForm(M_new.transpose()*Q.matrix()*M_new) + Q = QuadraticForm(M_new.transpose() * Q.matrix() * M_new) M = M * M_new done_flag = False @@ -323,10 +323,10 @@ def minkowski_reduction_for_4vars__SP(self): # Loop through possible shorter vectors done_flag = True - for j in range(n-1, -1, -1): - for a_first in mrange([2 for i in range(j)]): - y = [x-1 for x in a_first] + [1] + [0 for k in range(n-1-j)] - e_j = [0 for k in range(n)] + for j in range(n - 1, -1, -1): + for a_first in mrange([2 for i in range(j)]): + y = [x - 1 for x in a_first] + [1] + [0] * (n - 1 - j) + e_j = [0] * n e_j[j] = 1 # Reduce if a shorter vector is found @@ -334,22 +334,22 @@ def minkowski_reduction_for_4vars__SP(self): # Further n=4 computations B_y_vec = Q.matrix() * vector(ZZ, y) - # SP's B = our self.matrix()/2 - # SP's A = coeff matrix of his B - # Here we compute the double of both and compare. - B_sum = sum([abs(B_y_vec[i]) for i in range(4) if i != j]) - A_sum = sum([abs(Q[i,j]) for i in range(4) if i != j]) - B_max = max([abs(B_y_vec[i]) for i in range(4) if i != j]) - A_max = max([abs(Q[i,j]) for i in range(4) if i != j]) + # SP's B = our self.matrix()/2 + # SP's A = coeff matrix of his B + # Here we compute the double of both and compare. + B_sum = sum([abs(B_y_vec[i]) for i in range(4) if i != j]) + A_sum = sum([abs(Q[i, j]) for i in range(4) if i != j]) + B_max = max(abs(B_y_vec[i]) for i in range(4) if i != j) + A_max = max(abs(Q[i, j]) for i in range(4) if i != j) - if (B_sum < A_sum) or ((B_sum == A_sum) and (B_max < A_max)): + if B_sum < A_sum or (B_sum == A_sum and B_max < A_max): # Create the transformation matrix M_new = matrix(R, n, n) for k in range(n): - M_new[k,k] = 1 + M_new[k, k] = 1 for k in range(n): - M_new[k,j] = y[k] + M_new[k, j] = y[k] # Perform the reduction and restart the loop Q = Q(M_new) @@ -364,34 +364,34 @@ def minkowski_reduction_for_4vars__SP(self): # Step 2: Order A by certain criteria for i in range(4): - for j in range(i+1,4): + for j in range(i + 1, 4): # Condition (a) - if (Q[i,i] > Q[j,j]): - Q.swap_variables(i,j,in_place=True) - M_new = matrix(R,n,n) - M_new[i,j] = -1 - M_new[j,i] = 1 + if Q[i, i] > Q[j, j]: + Q.swap_variables(i, j, in_place=True) + M_new = matrix(R, n, n) + M_new[i, j] = -1 + M_new[j, i] = 1 for r in range(4): - if (r == i) or (r == j): - M_new[r,r] = 0 + if r == i or r == j: + M_new[r, r] = 0 else: - M_new[r,r] = 1 + M_new[r, r] = 1 M = M * M_new - elif (Q[i,i] == Q[j,j]): - i_sum = sum([abs(Q[i,k]) for k in range(4) if k != i]) - j_sum = sum([abs(Q[j,k]) for k in range(4) if k != j]) + elif Q[i, i] == Q[j, j]: + i_sum = sum([abs(Q[i, k]) for k in range(4) if k != i]) + j_sum = sum([abs(Q[j, k]) for k in range(4) if k != j]) # Condition (b) - if (i_sum > j_sum): - Q.swap_variables(i,j,in_place=True) - M_new = matrix(R,n,n) - M_new[i,j] = -1 - M_new[j,i] = 1 + if i_sum > j_sum: + Q.swap_variables(i, j, in_place=True) + M_new = matrix(R, n, n) + M_new[i, j] = -1 + M_new[j, i] = 1 for r in range(4): - if (r == i) or (r == j): - M_new[r,r] = 0 + if r == i or r == j: + M_new[r, r] = 0 else: M_new[r, r] = 1 M = M * M_new @@ -410,7 +410,7 @@ def minkowski_reduction_for_4vars__SP(self): M_new[i, j] = -1 M_new[j, i] = 1 for r in range(4): - if (r == i) or (r == j): + if r == i or r == j: M_new[r, r] = 0 else: M_new[r, r] = 1 diff --git a/src/sage/quadratic_forms/special_values.py b/src/sage/quadratic_forms/special_values.py index 99e2152dfcf..93a56c45c8c 100644 --- a/src/sage/quadratic_forms/special_values.py +++ b/src/sage/quadratic_forms/special_values.py @@ -192,8 +192,8 @@ def QuadraticBernoulliNumber(k, d): bp = bernoulli_polynomial(x, k) # Make the k-th quadratic Bernoulli number - total = sum([kronecker_symbol(d1, i) * bp(i/f) for i in range(f)]) - total *= (f ** (k-1)) + total = sum([kronecker_symbol(d1, i) * bp(i / f) for i in range(f)]) + total *= f**(k - 1) return total From 96b7b4e2469daabf685c33b30af37a926ccd054c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Mon, 26 Jun 2023 11:24:26 +0200 Subject: [PATCH 166/228] enhance coverage a little bit --- .../quadratic_form__reduction_theory.py | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/sage/quadratic_forms/quadratic_form__reduction_theory.py b/src/sage/quadratic_forms/quadratic_form__reduction_theory.py index 584f7374b75..06ac9d887a4 100644 --- a/src/sage/quadratic_forms/quadratic_form__reduction_theory.py +++ b/src/sage/quadratic_forms/quadratic_form__reduction_theory.py @@ -27,9 +27,21 @@ def reduced_binary_form1(self): [ 0 -1] [ 1 1] ) + + TESTS:: + + sage: QuadraticForm(ZZ, 2, [4,-7,6]).reduced_binary_form1()[0] # optional - sage.symbolic + Quadratic form in 2 variables over Integer Ring with coefficients: + [ 3 -1 ] + [ * 4 ] + + sage: QuadraticForm(ZZ, 3, [1,2,3,4,5,6]).reduced_binary_form1() # optional - sage.symbolic + Traceback (most recent call last): + ... + TypeError: only available for binary forms """ if self.dim() != 2: - raise TypeError("This must be a binary form for now...") + raise TypeError("only available for binary forms") R = self.base_ring() interior_reduced_flag = False @@ -94,9 +106,7 @@ def reduced_binary_form(self): n = self.dim() interior_reduced_flag = False Q = deepcopy(self) - M = matrix(R, n, n) - for i in range(n): - M[i, i] = 1 + M = matrix(R, n, n, 1) while not interior_reduced_flag: interior_reduced_flag = True @@ -105,9 +115,7 @@ def reduced_binary_form(self): for i in range(n): for j in range(i + 1, n): if Q[i, i] > Q[j, j]: - M_new = matrix(R, n, n) - for k in range(n): - M_new[k, k] = 1 + M_new = matrix(R, n, n, 1) M_new[i, j] = -1 M_new[j, i] = 1 M_new[i, i] = 0 @@ -121,9 +129,7 @@ def reduced_binary_form(self): if abs(Q[i, j]) > Q[i, i]: r = R(floor(round(Q[i, j] / (2 * Q[i, i])))) - M_new = matrix(R, n, n) - for k in range(n): - M_new[k, k] = 1 + M_new = matrix(R, n, n, 1) M_new[i, j] = -r Q = Q(M_new) @@ -136,6 +142,7 @@ def reduced_binary_form(self): def minkowski_reduction(self): r""" Find a Minkowski-reduced form equivalent to the given one. + This means that .. MATH:: From e3506cb6a3029710d34dcd844bd22f9013c0862b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Mon, 26 Jun 2023 11:42:45 +0200 Subject: [PATCH 167/228] still more coverage --- .../quadratic_form__reduction_theory.py | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/sage/quadratic_forms/quadratic_form__reduction_theory.py b/src/sage/quadratic_forms/quadratic_form__reduction_theory.py index 06ac9d887a4..ebf18b15adc 100644 --- a/src/sage/quadratic_forms/quadratic_form__reduction_theory.py +++ b/src/sage/quadratic_forms/quadratic_form__reduction_theory.py @@ -207,6 +207,8 @@ def minkowski_reduction(self): [0 0 0 1] ) + TESTS:: + sage: Q = QuadraticForm(ZZ,5,[2,2,0,0,0,2,2,0,0,2,2,0,2,2,2]) sage: Q.Gram_matrix() [2 1 0 0 0] @@ -218,6 +220,12 @@ def minkowski_reduction(self): Traceback (most recent call last): ... NotImplementedError: this algorithm is only for dimensions less than 5 + + sage: Q = QuadraticForm(ZZ,2,[4,-11,6]) + sage: Q.minkowski_reduction() + Traceback (most recent call last): + ... + TypeError: Minkowski reduction only works for positive definite forms """ from sage.quadratic_forms.quadratic_form import QuadraticForm from sage.quadratic_forms.quadratic_form import matrix @@ -229,9 +237,7 @@ def minkowski_reduction(self): R = self.base_ring() n = self.dim() Q = deepcopy(self) - M = matrix(R, n, n) - for i in range(n): - M[i, i] = 1 + M = matrix(R, n, n, 1) # Begin the reduction done_flag = False @@ -249,9 +255,7 @@ def minkowski_reduction(self): if Q(y) < Q(e_j): # Create the transformation matrix - M_new = matrix(R, n, n) - for k in range(n): - M_new[k, k] = 1 + M_new = matrix(R, n, n, 1) for k in range(n): M_new[k, j] = y[k] @@ -312,13 +316,19 @@ def minkowski_reduction_for_4vars__SP(self): [ 0 0 1 0] [ 0 0 0 1] ) + + TESTS:: + + sage: Q = QuadraticForm(ZZ, 2, [3,4,5]) + sage: Q.minkowski_reduction_for_4vars__SP() + Traceback (most recent call last): + ... + TypeError: the given quadratic form has 2 != 4 variables """ R = self.base_ring() n = self.dim() Q = deepcopy(self) - M = matrix(R, n, n) - for i in range(n): - M[i, i] = 1 + M = matrix(R, n, n, 1) # Only allow 4-variable forms if n != 4: @@ -352,9 +362,7 @@ def minkowski_reduction_for_4vars__SP(self): if B_sum < A_sum or (B_sum == A_sum and B_max < A_max): # Create the transformation matrix - M_new = matrix(R, n, n) - for k in range(n): - M_new[k, k] = 1 + M_new = matrix(R, n, n, 1) for k in range(n): M_new[k, j] = y[k] From 9a1de5ecea28e36caca18d862dd4a2f496631fa0 Mon Sep 17 00:00:00 2001 From: Miguel Marco <mmarco@unizar.es> Date: Mon, 26 Jun 2023 11:53:49 +0200 Subject: [PATCH 168/228] Add test to check betti numbers match coefficients of poincare polynomial --- src/sage/algebras/orlik_solomon.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index db51f464a26..52dae24fee3 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -474,6 +474,16 @@ def as_gca(self): e2*e3*e4 - e2*e3*e6 + e2*e4*e6 - e3*e4*e6, e0*e3 - e0*e6 + e3*e6, e0*e1*e2 - e0*e1*e6 + e0*e2*e6 - e1*e2*e6] over Rational Field + TESTS:: + + sage: H = hyperplane_arrangements.Catalan(3,QQ).cone() + sage: O = H.orlik_solomon_algebra(QQ) + sage: A = O.as_gca() + sage: H.poincare_polynomial() + 20*x^3 + 29*x^2 + 10*x + 1 + sage: [len(A.basis(i)) for i in range(5)] + [1, 10, 29, 20, 0] + """ from sage.algebras.commutative_dga import GradedCommutativeAlgebra gens = self.algebra_generators() From 89fde7a23be75ddd334f5ba9d73c9fd4a05f081a Mon Sep 17 00:00:00 2001 From: Jing Guo <dev.guoj@gmail.com> Date: Mon, 26 Jun 2023 17:30:47 +0000 Subject: [PATCH 169/228] projective_morphism.py: Restore LCM for elts not in number fields and create the right ideals for a list of polys --- .../schemes/projective/projective_morphism.py | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 2d786a3db39..916d63d27c3 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -926,7 +926,19 @@ def normalize_coordinates(self, **kwds): Dynamical System of Projective Space of dimension 1 over Number Field in a with defining polynomial 3*x^2 + 1 Defn: Defined on coordinates by sending (z : w) to - ((3*a)*z^2 + (3*a)*w^2 : z*w) + ((-3/2*a + 1/2)*z^2 + (-3/2*a + 1/2)*w^2 : (-3/2*a - 3/2)*z*w) + + :: + + sage: R.<a,b> = QQ[] + sage: P.<x,y,z> = ProjectiveSpace(FractionField(R), 2) + sage: H = End(P) + sage: f = H([a/b*(x*z + y^2)*x^2, a*b*(x*z + y^2)*y^2, a*(x*z + y^2)*z^2]) + sage: f.normalize_coordinates(); f + Scheme endomorphism of Projective Space of dimension 2 over Fraction + Field of Multivariate Polynomial Ring in a, b over Rational Field + Defn: Defined on coordinates by sending (x : y : z) to + (x^2 : (b^2)*y^2 : b*z^2) """ # If ideal or valuation is specified, we scale according the norm # defined by the ideal/valuation @@ -981,18 +993,22 @@ def normalize_coordinates(self, **kwds): self.scale_by(uniformizer**(-1 * min_val)) return + N = self.codomain().ambient_space().dimension_relative() + 1 + R = self.domain().base_ring() - # Only clear denominators from the coefficients in the ring of integers + # Clear any denominators from the coefficients if R in NumberFields(): O = R.maximal_order() if O is ZZ: - denom = lcm([self[i].denominator() for i in range(len(list(self)))]) + denom = lcm([self[i].denominator() for i in range(N)]) else: - denom = R.ideal(list(self)).absolute_norm().denominator() + denom = R.ideal([c for poly in self for c in poly.coefficients()]).norm().denominator() self.scale_by(denom) + else: + self.scale_by(lcm([self[i].denominator() for i in range(N)])) # There are cases, such as the example above over GF(7), # where we want to compute GCDs, but NOT in the case @@ -1007,8 +1023,6 @@ def normalize_coordinates(self, **kwds): GCD = gcd(self[0], self[1]) index = 2 - N = self.codomain().ambient_space().dimension_relative() + 1 - while GCD != 1 and index < N: GCD = gcd(GCD, self[index]) index += +1 From 5ca23a5d96970831d0041bcb0d53c91a8dccc72d Mon Sep 17 00:00:00 2001 From: Jing Guo <dev.guoj@gmail.com> Date: Mon, 26 Jun 2023 17:33:53 +0000 Subject: [PATCH 170/228] projective_morphism.py: Simplify code --- src/sage/schemes/projective/projective_morphism.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 916d63d27c3..c01b9c14c40 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -999,9 +999,7 @@ def normalize_coordinates(self, **kwds): # Clear any denominators from the coefficients if R in NumberFields(): - O = R.maximal_order() - - if O is ZZ: + if R.maximal_order() is ZZ: denom = lcm([self[i].denominator() for i in range(N)]) else: denom = R.ideal([c for poly in self for c in poly.coefficients()]).norm().denominator() From bcb89e4b61d6d2ffb6abf2178927f443fc0b8a75 Mon Sep 17 00:00:00 2001 From: OP5642 <ognjenpetrov@yahoo.com> Date: Mon, 26 Jun 2023 21:45:06 +0200 Subject: [PATCH 171/228] Fixed the docstring --- src/sage/topology/simplicial_complex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/topology/simplicial_complex.py b/src/sage/topology/simplicial_complex.py index f91dd6da056..bc2684cfa43 100644 --- a/src/sage/topology/simplicial_complex.py +++ b/src/sage/topology/simplicial_complex.py @@ -4998,7 +4998,7 @@ def is_minimally_non_golod(self): sage: Y.is_golod() False sage: Y.is_minimally_non_golod() - True + False """ L = self.vertices() n = len(L) From 660653c7f07067c544aa3f65310a120903dbd532 Mon Sep 17 00:00:00 2001 From: David Einstein <deinst@gmail.com> Date: Mon, 26 Jun 2023 16:11:09 -0400 Subject: [PATCH 172/228] Change dict to set The use of the python dict guarantee of insertion order of keys was confusing. There was no compelling reason (other than an aversion to change) for keeping insertion order. --- src/sage/combinat/tuple.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/tuple.py b/src/sage/combinat/tuple.py index 61449b98e00..17d285606dd 100644 --- a/src/sage/combinat/tuple.py +++ b/src/sage/combinat/tuple.py @@ -75,7 +75,7 @@ def __init__(self, S, k): """ self.S = S self.k = k - self._index_list = list(dict.fromkeys(S.index(s) for s in S)) + self._index_list = list(set(S.index(s) for s in S)) category = FiniteEnumeratedSets() Parent.__init__(self, category=category) @@ -166,7 +166,7 @@ def __init__(self, S, k): """ self.S = S self.k = k - self._index_list = list(dict.fromkeys(S.index(s) for s in S)) + self._index_list = list(set(S.index(s) for s in S)) category = FiniteEnumeratedSets() Parent.__init__(self, category=category) From 064e157b2391ff00ee69c35256470b622c49e82d Mon Sep 17 00:00:00 2001 From: Antonio Rojas <arojas@archlinux.org> Date: Mon, 26 Jun 2023 22:58:05 +0200 Subject: [PATCH 173/228] Fix tests with scipy 1.11 --- src/doc/en/faq/faq-usage.rst | 2 +- src/doc/it/faq/faq-usage.rst | 2 +- src/sage/numerical/optimize.py | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/doc/en/faq/faq-usage.rst b/src/doc/en/faq/faq-usage.rst index 40e4be5ddec..cd4feb44a1b 100644 --- a/src/doc/en/faq/faq-usage.rst +++ b/src/doc/en/faq/faq-usage.rst @@ -322,7 +322,7 @@ ints. For example:: sage: RealNumber = float; Integer = int sage: from scipy import stats sage: stats.ttest_ind([1,2,3,4,5], [2,3,4,5,.6]) - Ttest_indResult(statistic=0.0767529..., pvalue=0.940704...) + Ttest...Result(statistic=0.0767529..., pvalue=0.940704...) sage: stats.uniform(0,15).ppf([0.5,0.7]) array([ 7.5, 10.5]) diff --git a/src/doc/it/faq/faq-usage.rst b/src/doc/it/faq/faq-usage.rst index 0b6c75644ce..ef08c8835b0 100644 --- a/src/doc/it/faq/faq-usage.rst +++ b/src/doc/it/faq/faq-usage.rst @@ -304,7 +304,7 @@ anziché Integer di Sage. Ad esempio:: sage: RealNumber = float; Integer = int sage: from scipy import stats sage: stats.ttest_ind([1,2,3,4,5], [2,3,4,5,.6]) - Ttest_indResult(statistic=0.0767529..., pvalue=0.940704...) + Ttest...Result(statistic=0.0767529..., pvalue=0.940704...) sage: stats.uniform(0,15).ppf([0.5,0.7]) array([ 7.5, 10.5]) diff --git a/src/sage/numerical/optimize.py b/src/sage/numerical/optimize.py index 5bb9793a9bf..0f578f4e52b 100644 --- a/src/sage/numerical/optimize.py +++ b/src/sage/numerical/optimize.py @@ -155,7 +155,8 @@ def find_root(f, a, b, xtol=10e-13, rtol=2.0**-50, maxiter=100, full_output=Fals b = max(s_1, s_2) import scipy.optimize - brentqRes = scipy.optimize.brentq(f, a, b, + g = lambda x: float(f(x)) + brentqRes = scipy.optimize.brentq(g, a, b, full_output=full_output, xtol=xtol, rtol=rtol, maxiter=maxiter) # A check following :trac:`4942`, to ensure we actually found a root # Maybe should use a different tolerance here? From 13a0d2fe740f48d306b1d5d06bbf4632efbdac7b Mon Sep 17 00:00:00 2001 From: Daniel Khodabakhsh <d.khodabakhsh@gmail.com> Date: Mon, 26 Jun 2023 16:42:37 -0700 Subject: [PATCH 174/228] Add a WSL prerequisites section. --- src/doc/en/installation/source.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/doc/en/installation/source.rst b/src/doc/en/installation/source.rst index bd4b406baf1..f4b0526eb95 100644 --- a/src/doc/en/installation/source.rst +++ b/src/doc/en/installation/source.rst @@ -257,9 +257,11 @@ Some additional optional packages are taken care of by: .. literalinclude:: homebrew-optional.txt +WSL prerequisites +^^^^^^^^^^^^^^^^^ Ubuntu on Windows Subsystem for Linux (WSL) prerequisite installation -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sage can be installed onto Linux running on Windows Subsystem for Linux (WSL). These instructions describe a fresh install of Ubuntu 20.10, but other distributions or installation methods should work too, though have not been tested. @@ -283,11 +285,17 @@ Sage can be installed onto Linux running on Windows Subsystem for Linux (WSL). T From this point on, follow the instructions in the :ref:`sec-installation-from-sources-linux-recommended-installation` section. It is strongly recommended to put the Sage source files in the Linux file system, for example, in the ``/home/username/sage`` directory, and not in the Windows file system (e.g. ``/mnt/c/...``). +WSL permission denied error when building `packaging` package. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + You may encounter permission errors of the kind ``"[Errno 13] Permission denied: 'build/bdist.linux-x86_64/wheel/<package>.dist-info'"`` during ``make``. This usually comes from a permission conflict between the Windows and Linux file system. To fix it create a temporary build folder in the Linux file system using ``mkdir -p ~/tmp/sage`` and use it for building by ``eval SAGE_BUILD_DIR="~/tmp/sage" make``. Also see the `related Github issue <https://github.com/pypa/packaging-problems/issues/258>`_ for other workarounds. +WSL post-installation notes +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + When the installation is complete, you may be interested in :ref:`sec-launching-wsl-post-installation`. .. _section_cygwinprereqs: From aaacb9c3e545154272676813d1a7a8c1dde56dc2 Mon Sep 17 00:00:00 2001 From: Jing Guo <dev.guoj@gmail.com> Date: Tue, 27 Jun 2023 09:37:56 +0000 Subject: [PATCH 175/228] projective_morphis.py: Reformat some docstrings and comments --- .../schemes/projective/projective_morphism.py | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index c01b9c14c40..fd11fcab728 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -792,25 +792,24 @@ def scale_by(self, t): def normalize_coordinates(self, **kwds): """ - Ensures that this morphism has integral coefficients, and, - if the coordinate ring has a GCD, then it ensures that the + Ensures that this morphism has integral coefficients. + If the coordinate ring has a GCD, then it ensures that the coefficients have no common factor. - Also, makes the leading coefficients of the first polynomial + It also makes the leading coefficients of the first polynomial positive (if positive has meaning in the coordinate ring). This is done in place. - When ``ideal`` or ``valuation`` is specified, - normalization occurs with respect to the absolute value - defined by the ``ideal`` or ``valuation``. That is, the - coefficients are scaled such that one coefficient has - absolute value 1 while the others have absolute value - less than or equal to 1. Only supported when the base - ring is a number field. + When ``ideal`` or ``valuation`` is specified, normalization occurs + with respect to the absolute value defined by the ``ideal`` or + ``valuation``. That is, the coefficients are scaled such that + one coefficient has absolute value 1 while the others have + absolute value less than or equal to 1. + Only supported when the base ring is a number field. INPUT: - keywords: + kwds: - ``ideal`` -- (optional) a prime ideal of the base ring of this morphism. @@ -926,7 +925,7 @@ def normalize_coordinates(self, **kwds): Dynamical System of Projective Space of dimension 1 over Number Field in a with defining polynomial 3*x^2 + 1 Defn: Defined on coordinates by sending (z : w) to - ((-3/2*a + 1/2)*z^2 + (-3/2*a + 1/2)*w^2 : (-3/2*a - 3/2)*z*w) + ((-3/2*a + 1/2)*z^2 + (-3/2*a + 1/2)*w^2 : (-3/2*a - 3/2)*z*w) :: @@ -1027,7 +1026,7 @@ def normalize_coordinates(self, **kwds): if GCD != 1: self.scale_by(R(1) / GCD) - # scales by 1/gcd of the coefficients. + # Scale by 1/GCD of the coefficients. if R in _NumberFields: O = R.maximal_order() elif isinstance(R, FiniteField): @@ -1042,8 +1041,9 @@ def normalize_coordinates(self, **kwds): if GCD != 1: self.scale_by(1 / GCD) + + # If R is not p-adic, we make the first coordinate positive from sage.rings.padics.padic_base_generic import pAdicGeneric - # if R is not padic, we make the first coordinate positive if not isinstance(R, pAdicGeneric): if self[0].lc() < 0: self.scale_by(-1) From fbefbc5bf32f3450ab24734890ed1214d74ea448 Mon Sep 17 00:00:00 2001 From: Jing Guo <dev.guoj@gmail.com> Date: Tue, 27 Jun 2023 09:42:37 +0000 Subject: [PATCH 176/228] projective_morphism.py: Remove trailing whitespaces --- src/sage/schemes/projective/projective_morphism.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index fd11fcab728..9e6123f83ce 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -800,7 +800,7 @@ def normalize_coordinates(self, **kwds): positive (if positive has meaning in the coordinate ring). This is done in place. - When ``ideal`` or ``valuation`` is specified, normalization occurs + When ``ideal`` or ``valuation`` is specified, normalization occurs with respect to the absolute value defined by the ``ideal`` or ``valuation``. That is, the coefficients are scaled such that one coefficient has absolute value 1 while the others have From c93cd1bf890dd67a4fb7be5662931bb93e512a78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Tue, 27 Jun 2023 17:49:30 +0200 Subject: [PATCH 177/228] little details --- .../quadratic_form__mass__Conway_Sloane_masses.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py b/src/sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py index 2c8adf9cf6c..86e33d1d9c9 100644 --- a/src/sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py +++ b/src/sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py @@ -204,9 +204,9 @@ def conway_species_list_at_odd_prime(self, p): d = tmp_Q.det() # Determine the species - if (n % 2 != 0): # Deal with odd dim'l forms + if n % 2 != 0: # Deal with odd dim'l forms species = n - elif (n % 4 == 2) and (p % 4 == 3): # Deal with even dim'l forms + elif n % 4 == 2 and p % 4 == 3: # Deal with even dim'l forms species = (-1) * legendre_symbol(d, p) * n else: species = legendre_symbol(d, p) * n @@ -329,7 +329,7 @@ def conway_octane_of_this_unimodular_Jordan_block_at_2(self): # Deal with 'even' forms if self.parity() == "even": d = self.Gram_matrix().det() - if (d % 8 == 1) or (d % 8 == 7): + if d % 8 == 1 or d % 8 == 7: return 0 else: return 4 @@ -337,7 +337,7 @@ def conway_octane_of_this_unimodular_Jordan_block_at_2(self): # Deal with 'odd' forms by diagonalizing, and then computing the octane. n = self.dim() u = self[0, 0] - tmp_diag_vec = [None for i in range(n)] + tmp_diag_vec = [None] * n tmp_diag_vec[0] = u # This should be an odd integer! ind = 1 # The next index to diagonalize @@ -345,7 +345,7 @@ def conway_octane_of_this_unimodular_Jordan_block_at_2(self): while ind < n: # Check for a 1x1 block and diagonalize it - if ind == (n - 1) or self[ind, ind + 1] == 0: + if ind == n - 1 or self[ind, ind + 1] == 0: tmp_diag_vec[ind] = self[ind, ind] ind += 1 From 94ef4f6b9bc1d6243cfa6d208383373cfe28c638 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Tue, 27 Jun 2023 09:41:56 -0700 Subject: [PATCH 178/228] Integer.{perfect_power,is_prime_power}: Check easy cases first before calling PARI --- src/sage/rings/integer.pyx | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 7473969a6ac..ea3e59040e8 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -4829,6 +4829,20 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: (-64).perfect_power() # optional - sage.libs.pari (-4, 3) """ + cdef long n + # Fast PARI-free path + if mpz_fits_slong_p(self.value): + n = mpz_get_si(self.value) + if -8 < n < 4: + return self, one + if n >= 4: + if not (n & 1): + if mpz_popcount(self.value) == 1: + return smallInteger(2), mpz_sizeinbase(self.value, 2) - 1 + if n < 1000: + if _small_primes_table[n >> 1]: + return self, one + parians = self.__pari__().ispower() return Integer(parians[1]), Integer(parians[0]) @@ -5165,10 +5179,22 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: n.is_prime_power() # optional - sage.libs.pari True """ + cdef long n + if mpz_sgn(self.value) <= 0: return (self, zero) if get_data else False if mpz_fits_slong_p(self.value): + # Fast PARI-free path + n = mpz_get_si(self.value) + if not (n & 1): + if mpz_popcount(self.value) != 1: + return (self, zero) if get_data else False + return (smallInteger(2), mpz_sizeinbase(self.value, 2) - 1) if get_data else True + if n < 1000: + if _small_primes_table[n >> 1]: + return (self, one) if get_data else True + global pari_is_prime_power if pari_is_prime_power is None: try: @@ -5178,7 +5204,6 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): if pari_is_prime_power is not None: return pari_is_prime_power(self, get_data) - cdef long n if proof is None: from sage.structure.proof.proof import get_flag proof = get_flag(proof, "arithmetic") From b35e5568206d4eef3f69a33f7cab13ec70407215 Mon Sep 17 00:00:00 2001 From: Ognjen Petrov <58434709+OP5642@users.noreply.github.com> Date: Tue, 27 Jun 2023 16:58:33 +0000 Subject: [PATCH 179/228] Improvements to speed efficiency Co-authored-by: Travis Scrimshaw <clfrngrown@aol.com> --- src/sage/topology/simplicial_complex.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/sage/topology/simplicial_complex.py b/src/sage/topology/simplicial_complex.py index bc2684cfa43..caefd344d77 100644 --- a/src/sage/topology/simplicial_complex.py +++ b/src/sage/topology/simplicial_complex.py @@ -4968,12 +4968,10 @@ def is_golod(self): True """ H = set(a+b for (a, b) in self.bigraded_betti_numbers()) + if 0 in H: + H.remove(0) - for i in H: - for j in H: - if i+j in H and i != 0 and j != 0: - return False - return True + return all(i + j in H for i in H for j in H) def is_minimally_non_golod(self): r""" @@ -5000,14 +4998,12 @@ def is_minimally_non_golod(self): sage: Y.is_minimally_non_golod() False """ - L = self.vertices() - n = len(L) + def test(v): + X = copy(self) + X.delete_vertex(v) + return X.is_golod() - for x in combinations(L, n-1): - if not self.generated_subcomplex(x).is_golod(): - return False - - return True + return (not self.is_golod()) and all(test(v) for v in self.vertices()) # Miscellaneous utility functions. From 6425e9e7b5b4b5f4cc420782c59ca60b99dea792 Mon Sep 17 00:00:00 2001 From: Jing Guo <dev.guoj@gmail.com> Date: Tue, 27 Jun 2023 18:41:30 +0000 Subject: [PATCH 180/228] projective_morphism.py: Add `check #35797 is fixed` to docstring --- src/sage/schemes/projective/projective_morphism.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 9e6123f83ce..ddbaa072962 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -915,7 +915,7 @@ def normalize_coordinates(self, **kwds): Defn: Defined on coordinates by sending (x : y) to (x^2 + (2 + O(3^20))*y^2 : (3 + O(3^21))*x*y) - :: + Check that #35797 is fixed:: sage: R.<x> = QQ[] sage: K.<a> = NumberField(3*x^2 + 1) From 1db16b84cbe177d83cf5badc0bc4ddbd42de3e7c Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" <jhpalmieri64@gmail.com> Date: Tue, 27 Jun 2023 11:46:44 -0700 Subject: [PATCH 181/228] Remove mention of defunct magic command "%bg" from the tutorial --- src/doc/en/tutorial/interactive_shell.rst | 27 ---------------------- src/doc/fr/tutorial/interactive_shell.rst | 28 ----------------------- src/doc/ja/tutorial/interactive_shell.rst | 27 ---------------------- src/doc/pt/tutorial/interactive_shell.rst | 28 ----------------------- 4 files changed, 110 deletions(-) diff --git a/src/doc/en/tutorial/interactive_shell.rst b/src/doc/en/tutorial/interactive_shell.rst index 4c06c6a6255..c870098943a 100644 --- a/src/doc/en/tutorial/interactive_shell.rst +++ b/src/doc/en/tutorial/interactive_shell.rst @@ -383,33 +383,6 @@ IPython documentation <http://ipython.scipy.org/moin/Documentation>`_. Meanwhile, here are some fun tricks -- these are called "Magic commands" in IPython: -- You can use ``%bg`` to run a command in the background, and then use - ``jobs`` to access the results, as follows. (The comments ``not - tested`` are here because the ``%bg`` syntax doesn't work well with - Sage's automatic testing facility. If you type this in yourself, it - should work as written. This is of course most useful with commands - which take a while to complete.) - - :: - - sage: def quick(m): return 2*m - sage: %bg quick(20) # not tested - Starting job # 0 in a separate thread. - sage: jobs.status() # not tested - Completed jobs: - 0 : quick(20) - sage: jobs[0].result # the actual answer, not tested - 40 - - Note that jobs run in the background don't use the Sage preparser -- - see :ref:`section-mathannoy` for more information. One - (perhaps awkward) way to get around this would be to run :: - - sage: %bg eval(preparse('quick(20)')) # not tested - - It is safer and easier, though, to just use ``%bg`` on commands - which don't require the preparser. - - You can use ``%edit`` (or ``%ed`` or ``ed``) to open an editor, if you want to type in some complex code. Before you start Sage, make sure that the :envvar:`EDITOR` environment variable is set to your diff --git a/src/doc/fr/tutorial/interactive_shell.rst b/src/doc/fr/tutorial/interactive_shell.rst index 81235ccaab9..8b22343eda5 100644 --- a/src/doc/fr/tutorial/interactive_shell.rst +++ b/src/doc/fr/tutorial/interactive_shell.rst @@ -387,34 +387,6 @@ celui-ci. Vous voudrez peut-être consulter la `documentation complète de IPyth astuces utiles -- qui reposent sur ce que IPython appelle des « commandes magiques » : -- La commande magique ``%bg`` lance une commande en arrière-plan. Le résultat - sera ensuite accessible à travers l'objet ``jobs``, comme dans l'exemple - ci-dessous. (Les commentaires « not tested » sont là parce que ``%bg`` ne - fonctionne pas correctement dans l'infrastructure de test automatisé de Sage, - mais si vous reproduisez l'exemple, il devrait fonctionner comme indiqué. - Naturellement, ``%bg`` est surtout utile pour les commandes dont l'exécution - prend beaucoup de temps.) - - :: - - sage: def quick(m): return 2*m - sage: %bg quick(20) # not tested - Starting job # 0 in a separate thread. - sage: jobs.status() # not tested - Completed jobs: - 0 : quick(20) - sage: jobs[0].result # the actual answer, not tested - 40 - - Attention, les tâches lancées en arrière-plan ignorent le préprocesseur Sage - (voir section :ref:`section-mathannoy`). Une manière (certes pas très - commode) de contourner le problème est la suivante :: - - sage: %bg eval(preparse('quick(20)')) # not tested - - Mais il est plus simple et plus sûr de réserver ``%bg`` aux commandes en pur - Python, qui ne font pas appel au préprocesseur. - - Lorsque l'on souhaite saisir un morceau de code complexe, on peut utiliser ``%edit`` (ou ``%ed``, ou ``ed``) pour ouvrir un éditeur de texte. Assurez-vous que la variable d'environnement :envvar:`EDITOR` est réglée à diff --git a/src/doc/ja/tutorial/interactive_shell.rst b/src/doc/ja/tutorial/interactive_shell.rst index 38a5c2c4d3f..cb1660e0a10 100644 --- a/src/doc/ja/tutorial/interactive_shell.rst +++ b/src/doc/ja/tutorial/interactive_shell.rst @@ -353,33 +353,6 @@ IPythonトリック <http://ipython.scipy.org/moin/Documentation>`_ を読んみてほしい. そのかわり,ここではIPythonの「マジックコマンド」と呼ばれる,お便利なトリックをいくつか紹介させていただこう: -- ``%bg`` を使えばコマンドをバックグラウンドで実行し, 結果には ``jobs`` でアクセスすることができる.(この機能は ``not tested`` とコメントされている.というのは ``%bg`` 書法がSageの自動テスト機能とは余り相性が良くないからだ.ユーザ各自が入力してやれば,その通り動作するはずである.もちろん,この機能が最も役立つのは実行に時間のかかるコマンドと組み合わせる場合である.) - - 使用例を以下に示す. - - :: - - sage: def quick(m): return 2*m - sage: %bg quick(20) # not tested - Starting job # 0 in a separate thread. - sage: jobs.status() # not tested - Completed jobs: - 0 : quick(20) - sage: jobs[0].result # the actual answer, not tested - 40 - - バックグラウンドに送られるジョブはSageの前処理パーサを経由しないことに注意 -- 詳細は :ref:`section-mathannoy` 節を参照されたい. - パーサを通すための(不器用であるけれども)1つの方法は - - :: - - sage: %bg eval(preparse('quick(20)')) # not tested - - とすることだろう. - - ただし,より安全で簡単なのは前処理パーサを必要としないコマンドで ``%bg`` を使うことだろう. - - - ``%edit`` (``%ed`` や ``ed`` でもいい)を使ってエディタを起動すれば,複雑なコードの入力が楽になる. Sageの使用前に,環境変数 :envvar:`EDITOR` に好みのエディタ名を設定しておこう(``export EDITOR=/usr/bin/emacs`` または ``export EDITOR=/usr/bin/vim`` とするか, ``.profile`` ファイルなどで同様の設定をする). するとSageプロンプトで ``%edit`` を実行すれば設定したエディタが起動する.そのエディタで関数 diff --git a/src/doc/pt/tutorial/interactive_shell.rst b/src/doc/pt/tutorial/interactive_shell.rst index 67d27269a1e..296701752d2 100644 --- a/src/doc/pt/tutorial/interactive_shell.rst +++ b/src/doc/pt/tutorial/interactive_shell.rst @@ -372,34 +372,6 @@ pode usar quaisquer comandos e recursos do IPython. Você pode ler a `Documentação completa do IPython <http://ipython.scipy.org/moin/Documentation>`_ (em inglês). -- Você pode usar ``%bg`` para executar um comando no background, e - então usar ``jobs`` para acessar os resultados, da seguinte forma. - (Os comentários ``not tested`` estão aqui porque a sintaxe ``%bg`` - não funciona bem com o sistema de testes automáticos do Sage. Se - você digitar esses comandos, eles devem funcionar. Isso é obviamente - mais útil com comandos que demoram para serem completados.) - - :: - - sage: def quick(m): return 2*m - sage: %bg quick(20) # not tested - Starting job # 0 in a separate thread. - sage: jobs.status() # not tested - Completed jobs: - 0 : quick(20) - sage: jobs[0].result # the actual answer, not tested - 40 - - Note que os comandos executados no background não usam o - pre-processador (preparser) do Sage -- veja :ref:`section-mathannoy` - para mais informações. Uma forma (estranha talvez) de contornar esse - problema seria executar :: - - sage: %bg eval(preparse('quick(20)')) # not tested - - É mais seguro e simples, todavia, usar ``%bg`` apenas em comandos - que não requerem o pre-processador (preparser). - - Você pode usar ``%edit`` (ou ``%ed`` ou ``ed``) para abrir um editor, se você desejar digitar algum código mais complexo. Antes de iniciar o Sage, certifique-se de que a variável de ambiente From f01b0c2f8664862506338ec9f0ab9119e6ea304a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Tue, 27 Jun 2023 12:31:43 -0700 Subject: [PATCH 182/228] Integer.{perfect_power,is_prime_power}: Fix up return type --- src/sage/rings/integer.pyx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index ea3e59040e8..3421cdd3612 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -4812,15 +4812,15 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: 144.perfect_power() # optional - sage.libs.pari (12, 2) - sage: 1.perfect_power() # optional - sage.libs.pari + sage: 1.perfect_power() (1, 1) - sage: 0.perfect_power() # optional - sage.libs.pari + sage: 0.perfect_power() (0, 1) - sage: (-1).perfect_power() # optional - sage.libs.pari + sage: (-1).perfect_power() (-1, 1) sage: (-8).perfect_power() # optional - sage.libs.pari (-2, 3) - sage: (-4).perfect_power() # optional - sage.libs.pari + sage: (-4).perfect_power() (-4, 1) sage: (101^29).perfect_power() # optional - sage.libs.pari (101, 29) @@ -4838,7 +4838,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): if n >= 4: if not (n & 1): if mpz_popcount(self.value) == 1: - return smallInteger(2), mpz_sizeinbase(self.value, 2) - 1 + return smallInteger(2), smallInteger(mpz_sizeinbase(self.value, 2) - 1) if n < 1000: if _small_primes_table[n >> 1]: return self, one @@ -5190,7 +5190,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): if not (n & 1): if mpz_popcount(self.value) != 1: return (self, zero) if get_data else False - return (smallInteger(2), mpz_sizeinbase(self.value, 2) - 1) if get_data else True + return (smallInteger(2), smallInteger(mpz_sizeinbase(self.value, 2) - 1)) if get_data else True if n < 1000: if _small_primes_table[n >> 1]: return (self, one) if get_data else True From 5afd4bbadf5cef9493d0e45e5523bb391e0fc9aa Mon Sep 17 00:00:00 2001 From: marizee <mfly282@gmail.com> Date: Tue, 27 Jun 2023 21:48:18 +0200 Subject: [PATCH 183/228] extend max_modulus --- src/sage/matrix/matrix_modn_dense_double.pyx | 10 +++++----- src/sage/matrix/matrix_space.py | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/sage/matrix/matrix_modn_dense_double.pyx b/src/sage/matrix/matrix_modn_dense_double.pyx index 0c6ca7fee25..12bc79159d3 100644 --- a/src/sage/matrix/matrix_modn_dense_double.pyx +++ b/src/sage/matrix/matrix_modn_dense_double.pyx @@ -4,7 +4,7 @@ # distutils: include_dirs = CBLAS_INCDIR # distutils: extra_compile_args = -D_XPG6 r""" -Dense matrices over `\ZZ/n\ZZ` for `n < 2^{23}` using LinBox's ``Modular<double>`` +Dense matrices over `\ZZ/n\ZZ` for `n < 94906266` using LinBox's ``Modular<double>`` AUTHORS: @@ -38,7 +38,7 @@ from sage.libs.linbox.fflas cimport \ ctypedef Poly1Dom[ModField, Dense] ModDensePolyRing # Limit for LinBox Modular<double> -MAX_MODULUS = 2**23 +MAX_MODULUS = 94906266 from sage.rings.finite_rings.integer_mod cimport IntegerMod_int64 @@ -47,11 +47,11 @@ include "matrix_modn_dense_template.pxi" cdef class Matrix_modn_dense_double(Matrix_modn_dense_template): r""" - Dense matrices over `\ZZ/n\ZZ` for `n < 2^{23}` using LinBox's ``Modular<double>`` + Dense matrices over `\ZZ/n\ZZ` for `n < 94906266` using LinBox's ``Modular<double>`` These are matrices with integer entries mod ``n`` represented as floating-point numbers in a 64-bit word for use with LinBox routines. - This allows for ``n`` up to `2^{23}`. By default, the analogous + This allows for ``n`` up to `94906266`. By default, the analogous ``Matrix_modn_dense_float`` class is used for smaller moduli, specifically for ``n`` up to `2^{8}`. @@ -70,7 +70,7 @@ cdef class Matrix_modn_dense_double(Matrix_modn_dense_template): <class 'sage.rings.finite_rings.integer_mod.IntegerMod_int64'> """ self._get_template = self._base_ring.zero() - # note that INTEGER_MOD_INT32_LIMIT is ceil(sqrt(2^31-1)) < 2^23 + # note that INTEGER_MOD_INT32_LIMIT is ceil(sqrt(2^31-1)) < 94906266 self._fits_int32 = ((<Matrix_modn_dense_template>self).p <= INTEGER_MOD_INT32_LIMIT) cdef void set_unsafe_int(self, Py_ssize_t i, Py_ssize_t j, int value): diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 5de43333072..16346a19d2f 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -166,7 +166,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: get_matrix_class(Zmod(2**30), 2, 2, False, 'linbox-double') Traceback (most recent call last): ... - ValueError: 'linbox-double' matrices can only deal with order < 8388608 + ValueError: 'linbox-double' matrices can only deal with order < 94906266 sage: type(matrix(SR, 2, 2, 0)) <class 'sage.matrix.matrix_symbolic_dense.Matrix_symbolic_dense'> @@ -617,7 +617,8 @@ def __init__(self, base_ring, nrows, ncols, sparse, implementation): - ``linbox-float`` - for integer mod rings up to `2^8 = 256` - - ``linbox-double`` - for integer mod rings up to `2^23 = 8388608` + - ``linbox-double`` - for integer mod rings up to + `floor(2^26*sqrt(2) + 1/2) = 94906266` - ``numpy`` - for real and complex floating point numbers From 543749185a3cd0d3bf30fa1887bc27d67f8bb69e Mon Sep 17 00:00:00 2001 From: OP5642 <ognjenpetrov@yahoo.com> Date: Tue, 27 Jun 2023 22:37:03 +0200 Subject: [PATCH 184/228] Minor fixes to the logic and syntax --- src/sage/topology/simplicial_complex.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/topology/simplicial_complex.py b/src/sage/topology/simplicial_complex.py index caefd344d77..e352a604cb2 100644 --- a/src/sage/topology/simplicial_complex.py +++ b/src/sage/topology/simplicial_complex.py @@ -4971,7 +4971,7 @@ def is_golod(self): if 0 in H: H.remove(0) - return all(i + j in H for i in H for j in H) + return not any(i + j in H for i in H for j in H) def is_minimally_non_golod(self): r""" @@ -5000,7 +5000,7 @@ def is_minimally_non_golod(self): """ def test(v): X = copy(self) - X.delete_vertex(v) + X.remove_face([v]) return X.is_golod() return (not self.is_golod()) and all(test(v) for v in self.vertices()) From 0d9fa92bf31c4a1cd6becb15c331b9994edb28f8 Mon Sep 17 00:00:00 2001 From: Jun-Hee-Lee <kkami920523@gmail.com> Date: Wed, 28 Jun 2023 11:34:29 +0900 Subject: [PATCH 185/228] Fix typos on the link to the walkthrough.html --- src/doc/en/installation/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/en/installation/index.rst b/src/doc/en/installation/index.rst index 2253ac4f97b..9baf654f457 100644 --- a/src/doc/en/installation/index.rst +++ b/src/doc/en/installation/index.rst @@ -25,7 +25,7 @@ macOS Obtain the SageMath sources via ``git`` as described in `The Sage Developer's Guide - <https://doc.sagemath.org/html/en/developer/walk_through.html#chapter-walkthrough>`_. + <https://doc.sagemath.org/html/en/developer/walkthrough.html#chapter-walkthrough>`_. - Then build SageMath from source as described in section :ref:`sec-installation-from-sources`. @@ -93,7 +93,7 @@ Linux Obtain the SageMath sources via ``git`` as described in `The Sage Developer's Guide - <https://doc.sagemath.org/html/en/developer/walk_through.html#chapter-walkthrough>`_. + <https://doc.sagemath.org/html/en/developer/walkthrough.html#chapter-walkthrough>`_. - Then build SageMath from source as described in section :ref:`sec-installation-from-sources`. From 7b4c107239696233123cbb1dfda08fcca6ab67a1 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik <dima@pasechnik.info> Date: Wed, 28 Jun 2023 21:54:03 +0100 Subject: [PATCH 186/228] correct deprecation messages --- src/sage/rings/polynomial/multi_polynomial.pyx | 2 +- src/sage/rings/polynomial/polynomial_element.pyx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial.pyx b/src/sage/rings/polynomial/multi_polynomial.pyx index bab2f670687..9493719c42d 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pyx +++ b/src/sage/rings/polynomial/multi_polynomial.pyx @@ -21,7 +21,7 @@ from sage.misc.misc_c import prod def is_MPolynomial(x): from sage.misc.superseded import deprecation - deprecation(32709, "the function is_MPolynomial is deprecated; use isinstance(x, sage.structure.element.MPolynomial) instead") + deprecation(32709, "the function is_MPolynomial is deprecated; use isinstance(x, sage.rings.polynomial.multi_polynomial.MPolynomial) instead") return isinstance(x, MPolynomial) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index aca24e19bd9..112f065ec3f 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -176,7 +176,7 @@ cpdef is_Polynomial(f): False """ from sage.misc.superseded import deprecation - deprecation(32709, "the function is_Polynomial is deprecated; use isinstance(x, sage.structure.element.Polynomial) instead") + deprecation(32709, "the function is_Polynomial is deprecated; use isinstance(x, sage.rings.polynomial.polynomial_element.Polynomial) instead") return isinstance(f, Polynomial) From c3ca120cbf2057854da982b35fe0ff51cef5c2b3 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik <dima@pasechnik.info> Date: Wed, 28 Jun 2023 22:04:09 +0100 Subject: [PATCH 187/228] fix doctest --- src/sage/rings/polynomial/polynomial_element.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 112f065ec3f..99fd4574b49 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -150,7 +150,7 @@ cpdef is_Polynomial(f): sage: R.<x> = ZZ[] sage: is_Polynomial(x^3 + x + 1) doctest:...: DeprecationWarning: the function is_Polynomial is deprecated; - use isinstance(x, sage.structure.element.Polynomial) instead + use isinstance(x, sage.rings.polynomial.polynomial_element.Polynomial) instead See https://github.com/sagemath/sage/issues/32709 for details. True sage: S.<y> = R[] From 30c0836dfa76c4202e0a177933424957bc021874 Mon Sep 17 00:00:00 2001 From: Vincent Neiger <vneiger@users.noreply.github.com> Date: Wed, 28 Jun 2023 23:05:02 +0200 Subject: [PATCH 188/228] rational rounding: keep default mode as away for now, but add deprecation warning --- src/sage/rings/rational.pyx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index 29286b0db3f..4739b4c586a 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -3338,10 +3338,11 @@ cdef class Rational(sage.structure.element.FieldElement): mpz_tdiv_q(n.value, mpq_numref(self.value), mpq_denref(self.value)) return n - def round(Rational self, mode="even"): + def round(Rational self, mode=None): """ - Return the nearest integer to ``self``, rounding to even by - default for consistency with the builtin Python round. + Return the nearest integer to ``self``, rounding away by default. + Deprecation: in the future the default will be changed to rounding to + even, for consistency with the builtin Python round. INPUT: @@ -3356,19 +3357,20 @@ cdef class Rational(sage.structure.element.FieldElement): - 'even' rounds toward the even integer - 'odd' rounds toward the odd integer - OUTPUT: Integer EXAMPLES:: sage: (9/2).round() - 4 + doctest:...: DeprecationWarning: the default rounding for rationals, currently `away`, will be changed to `even`. + See https://github.com/sagemath/sage/issues/35473 for details. + 5 sage: n = 4/3; n.round() 1 sage: n = -17/4; n.round() -4 sage: n = -5/2; n.round() - -2 + -3 sage: n.round("away") -3 sage: n.round("up") @@ -3380,6 +3382,11 @@ cdef class Rational(sage.structure.element.FieldElement): sage: n.round("odd") -3 """ + if mode is None: + from sage.misc.superseded import deprecation + deprecation(35473, + "the default rounding for rationals, currently `away`, will be changed to `even`.") + mode = "away" if not (mode in ['toward', 'away', 'up', 'down', 'even', 'odd']): raise ValueError("rounding mode must be one of 'toward', 'away', 'up', 'down', 'even', or 'odd'") if self.denominator() == 1: From 61843fb872b87c3bee0cc6afe5bcb3aac2b9e2f4 Mon Sep 17 00:00:00 2001 From: Ognjen Petrov <58434709+OP5642@users.noreply.github.com> Date: Wed, 28 Jun 2023 21:30:09 +0000 Subject: [PATCH 189/228] Improvements to the is_golod() method Co-authored-by: Travis Scrimshaw <clfrngrown@aol.com> --- src/sage/topology/simplicial_complex.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/topology/simplicial_complex.py b/src/sage/topology/simplicial_complex.py index e352a604cb2..bb4bc67aab9 100644 --- a/src/sage/topology/simplicial_complex.py +++ b/src/sage/topology/simplicial_complex.py @@ -4969,9 +4969,11 @@ def is_golod(self): """ H = set(a+b for (a, b) in self.bigraded_betti_numbers()) if 0 in H: - H.remove(0) + HL = list(H.difference([0])) + else: + HL = list(H) - return not any(i + j in H for i in H for j in H) + return not any(i + j in H for ii, i in enumerate(HL) for j in HL[ii:]) def is_minimally_non_golod(self): r""" From 3fe1ad3dfc2a673fd262c0ed5bd456c2fa694bc5 Mon Sep 17 00:00:00 2001 From: Vincent Neiger <vneiger@users.noreply.github.com> Date: Wed, 28 Jun 2023 23:44:44 +0200 Subject: [PATCH 190/228] updating doc / doctests for number field elements --- src/sage/rings/number_field/number_field_element.pyx | 5 ++++- .../number_field/number_field_element_quadratic.pyx | 11 +++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/number_field/number_field_element.pyx b/src/sage/rings/number_field/number_field_element.pyx index d80c87ea00c..90e64069c62 100644 --- a/src/sage/rings/number_field/number_field_element.pyx +++ b/src/sage/rings/number_field/number_field_element.pyx @@ -1253,7 +1253,8 @@ cdef class NumberFieldElement(NumberFieldElement_base): def round(self): r""" - Return the round (nearest integer) of this number field element. + Return the round (nearest integer) of this number field element. In case + of ties, this relies on the default rounding for rational numbers. EXAMPLES:: @@ -1289,6 +1290,8 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: p = x**5 - 3 sage: K.<a> = NumberField(p) sage: [K(k/3).round() for k in range(-3,4)] + doctest...: DeprecationWarning: the default rounding for rationals, currently `away`, will be changed to `even`. + See https://github.com/sagemath/sage/issues/35473 for details. [-1, -1, 0, 0, 0, 1, 1] sage: a.round() Traceback (most recent call last): 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 f0a99c02fe0..7f8600fb5be 100644 --- a/src/sage/rings/number_field/number_field_element_quadratic.pyx +++ b/src/sage/rings/number_field/number_field_element_quadratic.pyx @@ -2310,7 +2310,8 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): def round(self): r""" - Returns the round (nearest integer, away from zero in case of ties). + Return the round (nearest integer) of this number field element. In case + of ties, this relies on the default rounding for rational numbers. EXAMPLES:: @@ -2332,12 +2333,14 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): sage: for _ in range(100): ....: a = QQ.random_element(1000,20) ....: b = QQ.random_element(1000,20) - ....: assert a.round("away") == round(K2(a)), a - ....: assert a.round("away") == round(K3(a)), a - ....: assert a.round("away") == round(K5(a)), a + ....: assert a.round() == round(K2(a)), a + ....: assert a.round() == round(K3(a)), a + ....: assert a.round() == round(K5(a)), a ....: assert round(a+b*sqrt(2.)) == round(a+b*sqrt2), (a, b) ....: assert round(a+b*sqrt(3.)) == round(a+b*sqrt3), (a, b) ....: assert round(a+b*sqrt(5.)) == round(a+b*sqrt5), (a, b) + doctest...: DeprecationWarning: the default rounding for rationals, currently `away`, will be changed to `even`. + See https://github.com/sagemath/sage/issues/35473 for details. """ n = self.floor() test = 2 * (self - n).abs() From 3ee76161f28c1a506987fdb773a53f283dc7f3aa Mon Sep 17 00:00:00 2001 From: Dima Pasechnik <dimpase@gmail.com> Date: Thu, 29 Jun 2023 11:56:01 +0100 Subject: [PATCH 191/228] add # distutils: extra_compile_args --- src/sage/graphs/bliss.pyx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/graphs/bliss.pyx b/src/sage/graphs/bliss.pyx index 373b99f4d5e..d8c50f220e3 100644 --- a/src/sage/graphs/bliss.pyx +++ b/src/sage/graphs/bliss.pyx @@ -1,4 +1,5 @@ # distutils: language = c++ +# distutils: extra_compile_args = -std=c++11 # distutils: libraries = bliss # sage_setup: distribution = sagemath-bliss From 9537d3fe761ebd38bbf2aec4b4cc08439fbdcbfb Mon Sep 17 00:00:00 2001 From: marizee <mfly282@gmail.com> Date: Thu, 29 Jun 2023 17:43:32 +0200 Subject: [PATCH 192/228] fixes trailing whitespace --- src/sage/matrix/matrix_space.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 16346a19d2f..a2e28d883bc 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -617,7 +617,7 @@ def __init__(self, base_ring, nrows, ncols, sparse, implementation): - ``linbox-float`` - for integer mod rings up to `2^8 = 256` - - ``linbox-double`` - for integer mod rings up to + - ``linbox-double`` - for integer mod rings up to `floor(2^26*sqrt(2) + 1/2) = 94906266` - ``numpy`` - for real and complex floating point numbers From 413f251a8ebfe04138eb25f5bd1a6cf48a5a1d7c Mon Sep 17 00:00:00 2001 From: marizee <mfly282@gmail.com> Date: Thu, 29 Jun 2023 18:02:43 +0200 Subject: [PATCH 193/228] fixes missing indent --- src/sage/matrix/matrix_space.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index a2e28d883bc..f3952cecda7 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -618,7 +618,7 @@ def __init__(self, base_ring, nrows, ncols, sparse, implementation): - ``linbox-float`` - for integer mod rings up to `2^8 = 256` - ``linbox-double`` - for integer mod rings up to - `floor(2^26*sqrt(2) + 1/2) = 94906266` + `floor(2^26*sqrt(2) + 1/2) = 94906266` - ``numpy`` - for real and complex floating point numbers From c5624f484f47a14e18506b93c1ff89d3331cad41 Mon Sep 17 00:00:00 2001 From: Vincent Neiger <vneiger@users.noreply.github.com> Date: Fri, 30 Jun 2023 14:14:20 +0200 Subject: [PATCH 194/228] deprecation warning only in case of ties; specifying rounding mode explicitly in cusps.py to avoid deprecation warnings in many tests --- src/sage/modular/cusps.py | 2 +- src/sage/rings/rational.pyx | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sage/modular/cusps.py b/src/sage/modular/cusps.py index 27147942a6a..71192ec80b2 100644 --- a/src/sage/modular/cusps.py +++ b/src/sage/modular/cusps.py @@ -621,7 +621,7 @@ def is_gamma0_equiv(self, other, N, transformation=None): if C % (M * v1 * v2) == 0: k = - C // (M * v1 * v2) else: - k = - (C / (M * v1 * v2)).round() + k = - (C / (M * v1 * v2)).round("away") s1pp = s1p + k * M * v1 # C += k*M*v1*v2 # is now the smallest in absolute value diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index a41387b0651..86cbf198875 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -3383,9 +3383,10 @@ cdef class Rational(sage.structure.element.FieldElement): -3 """ if mode is None: - from sage.misc.superseded import deprecation - deprecation(35473, - "the default rounding for rationals, currently `away`, will be changed to `even`.") + if self.denominator() == 2: + from sage.misc.superseded import deprecation + deprecation(35473, + "the default rounding for rationals, currently `away`, will be changed to `even`.") mode = "away" if not (mode in ['toward', 'away', 'up', 'down', 'even', 'odd']): raise ValueError("rounding mode must be one of 'toward', 'away', 'up', 'down', 'even', or 'odd'") From ed93eda5404ce8421c246ab7ef4adef67fd4cc76 Mon Sep 17 00:00:00 2001 From: David Einstein <deinst@gmail.com> Date: Fri, 30 Jun 2023 09:46:39 -0400 Subject: [PATCH 195/228] Return subgraphs with exactly k vertices In response to issue #35857 modified connected_subgraph_iterator to just return the subgraphs of order k. - Added a parameter 'exactly_k --- src/sage/graphs/base/static_dense_graph.pyx | 99 +++++++++++---------- 1 file changed, 54 insertions(+), 45 deletions(-) diff --git a/src/sage/graphs/base/static_dense_graph.pyx b/src/sage/graphs/base/static_dense_graph.pyx index 99bf7a8a117..59b456762a9 100644 --- a/src/sage/graphs/base/static_dense_graph.pyx +++ b/src/sage/graphs/base/static_dense_graph.pyx @@ -745,7 +745,8 @@ def connected_full_subgraphs(G, edges_only=False, labels=False, def connected_subgraph_iterator(G, k=None, bint vertices_only=False, - edges_only=False, labels=False, induced=True): + edges_only=False, labels=False, induced=True, + exactly_k=False): r""" Return an terator over the induced connected subgraphs of order at most `k`. @@ -783,6 +784,10 @@ def connected_subgraph_iterator(G, k=None, bint vertices_only=False, connected sub(di)graph only or also non-induced sub(di)graphs. This parameter can be set to ``False`` for simple (di)graphs only. + - ``exactly_k`` -- boolean (default: ``False``); ``True`` if we only + return graphs of order ``k``, ``False`` if we return graphs of order + at most ``k``. + EXAMPLES:: sage: G = DiGraph([(1, 2), (2, 3), (3, 4), (4, 2)]) @@ -811,6 +816,8 @@ def connected_subgraph_iterator(G, k=None, bint vertices_only=False, Subgraph of (): Digraph on 1 vertex, Subgraph of (): Digraph on 2 vertices, Subgraph of (): Digraph on 1 vertex] + sage: list(G.connected_subgraph_iterator(k=3, vertices_only=True, exactly_k=True)) + [[1, 2, 3], [1, 2, 4], [2, 3, 4]] sage: list(G.connected_subgraph_iterator(k=2, vertices_only=True)) [[1], [1, 2], [2], [2, 3], [2, 4], [3], [3, 4], [4]] @@ -921,14 +928,15 @@ def connected_subgraph_iterator(G, k=None, bint vertices_only=False, sig_check() vertices = [int_to_vertex[u]] - if vertices_only: - yield vertices - else: - H = G.subgraph(vertices) - if edges_only: - yield H.edges(sort=False, labels=labels) + if not exactly_k or mk == 1: + if vertices_only: + yield vertices else: - yield H + H = G.subgraph(vertices) + if edges_only: + yield H.edges(sort=False, labels=labels) + else: + yield H # We initialize the loop with vertices u in current, {u+1, ..., n-1} # in left, and N(u) in boundary @@ -970,45 +978,46 @@ def connected_subgraph_iterator(G, k=None, bint vertices_only=False, # We yield that new subset vertices = [int_to_vertex[a] for a in range(u, n) if bitset_in(stack.rows[level], a)] - if vertices_only: - yield vertices - else: - H = G.subgraph(vertices) - if induced: - if edges_only: - yield H.edges(sort=False, labels=labels) - else: - yield H + if not exactly_k or bitset_len(current) == mk - 1: + if vertices_only: + yield vertices else: - # We use a decomposition into biconnected components to - # work on smaller graphs. - if H.is_directed(): - blocks = H.to_undirected().blocks_and_cut_vertices()[0] - else: - blocks = H.blocks_and_cut_vertices()[0] - if len(blocks) == 1: - # H is strongly connected or biconnected - yield from connected_full_subgraphs(H, edges_only=edges_only, - labels=labels) + H = G.subgraph(vertices) + if induced: + if edges_only: + yield H.edges(sort=False, labels=labels) + else: + yield H else: - L = [] - for bloc in blocks: - if len(bloc) == 2: - bb = [[e] for e in H.edge_boundary(bloc, bloc, labels=labels)] - if len(bb) == 2: - # H is directed with edges (u, v) and (v, u) - bb.append(H.edge_boundary(bloc, bloc, labels=labels)) - L.append(bb) - else: - L.append(connected_full_subgraphs(H.subgraph(vertices=bloc), - edges_only=True, labels=labels)) - - for edges in product(*L): - good_edges = flatten(edges, ltypes=list) - if edges_only: - yield list(good_edges) - else: - yield H.subgraph(vertices=H, edges=good_edges) + # We use a decomposition into biconnected components to + # work on smaller graphs. + if H.is_directed(): + blocks = H.to_undirected().blocks_and_cut_vertices()[0] + else: + blocks = H.blocks_and_cut_vertices()[0] + if len(blocks) == 1: + # H is strongly connected or biconnected + yield from connected_full_subgraphs(H, edges_only=edges_only, + labels=labels) + else: + L = [] + for bloc in blocks: + if len(bloc) == 2: + bb = [[e] for e in H.edge_boundary(bloc, bloc, labels=labels)] + if len(bb) == 2: + # H is directed with edges (u, v) and (v, u) + bb.append(H.edge_boundary(bloc, bloc, labels=labels)) + L.append(bb) + else: + L.append(connected_full_subgraphs(H.subgraph(vertices=bloc), + edges_only=True, labels=labels)) + + for edges in product(*L): + good_edges = flatten(edges, ltypes=list) + if edges_only: + yield list(good_edges) + else: + yield H.subgraph(vertices=H, edges=good_edges) else: # We cannot extend the current subset, either due to a lack of From 4f0ebacea6bbdfac625235890965eb4c246a7d04 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Fri, 30 Jun 2023 06:33:11 -0700 Subject: [PATCH 196/228] .github/workflows/{build,doc-build}.yml: Fix handling of added files --- .github/workflows/build.yml | 4 +++- .github/workflows/doc-build.yml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ea2cb1aa79d..8d936616077 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -60,11 +60,13 @@ jobs: # (This keeps mtimes of unchanged files unchanged and mtimes of changed files newer than unchanged files.) # Finally we reset the index to "old". (This keeps all mtimes unchanged.) # The changed files now show up as uncommitted changes. + # The final "git add -N" makes sure that files that were added in "new" do not show + # as untracked files, which would be removed by "git clean -fx". git worktree add --detach worktree-image rm -rf /sage/.git && mv worktree-image/.git /sage/ rm -rf worktree-image && ln -s /sage worktree-image if [ ! -f worktree-image/.gitignore ]; then cp .gitignore worktree-image/; fi - (cd worktree-image && git add -A && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) + (cd worktree-image && git add -A && git commit --quiet --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset --quiet old && git add -N . && git status) - name: Incremental build, test changed files (sage -t --new) id: incremental diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 01748c3c823..140a6ba0ced 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -44,11 +44,13 @@ jobs: # (This keeps mtimes of unchanged files unchanged and mtimes of changed files newer than unchanged files.) # Finally we reset the index to "old". (This keeps all mtimes unchanged.) # The changed files now show up as uncommitted changes. + # The final "git add -N" makes sure that files that were added in "new" do not show + # as untracked files, which would be removed by "git clean -fx". git worktree add --detach worktree-image rm -rf /sage/.git && mv worktree-image/.git /sage/ rm -rf worktree-image && ln -s /sage worktree-image if [ ! -f worktree-image/.gitignore ]; then cp .gitignore worktree-image/; fi - (cd worktree-image && git add -A && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) + (cd worktree-image && git add -A && git commit --quiet --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset --quiet old && git add -N . && git status) # Keep track of changes to built HTML (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git init && (echo ".buildinfo"; echo ".inv") > .gitignore; git add -A && git commit --quiet -m "old") From 955c9f4238faa47216d74368e1ef5bc1e33d6a92 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Mon, 19 Jun 2023 10:20:50 -0700 Subject: [PATCH 197/228] m4/setup_cfg_metadata.m4: New, m4-include it in setup.cfg files to reduce boilerplate --- build/pkgs/sagelib/bootstrap | 1 + m4/setup_cfg_metadata.m4 | 21 +++++++++++++++++++++ pkgs/sagemath-categories/setup.cfg.m4 | 20 +------------------- pkgs/sagemath-environment/setup.cfg.m4 | 20 +------------------- pkgs/sagemath-objects/setup.cfg.m4 | 20 +------------------- pkgs/sagemath-repl/setup.cfg.m4 | 20 +------------------- src/setup.cfg.m4 | 20 +------------------- 7 files changed, 27 insertions(+), 95 deletions(-) create mode 100644 m4/setup_cfg_metadata.m4 diff --git a/build/pkgs/sagelib/bootstrap b/build/pkgs/sagelib/bootstrap index 08f9002f8f5..5a186d79c8b 100755 --- a/build/pkgs/sagelib/bootstrap +++ b/build/pkgs/sagelib/bootstrap @@ -1,5 +1,6 @@ #! /bin/sh set -e +export M4PATH="$SAGE_ROOT/m4" for infile in src/*.m4; do if [ -f "$infile" ]; then outfile="src/$(basename $infile .m4)" diff --git a/m4/setup_cfg_metadata.m4 b/m4/setup_cfg_metadata.m4 new file mode 100644 index 00000000000..ca042345499 --- /dev/null +++ b/m4/setup_cfg_metadata.m4 @@ -0,0 +1,21 @@ +dnl Standard metadata of SageMath distribution packages +dnl +license = GNU General Public License (GPL) v2 or later +author = The Sage Developers +author_email = sage-support@googlegroups.com +url = https://www.sagemath.org + +classifiers = + Development Status :: 6 - Mature + Intended Audience :: Education + Intended Audience :: Science/Research + License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+) + Operating System :: POSIX + Operating System :: MacOS :: MacOS X + Programming Language :: Python :: 3 :: Only + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 + Programming Language :: Python :: 3.11 + Programming Language :: Python :: Implementation :: CPython + Topic :: Scientific/Engineering :: Mathematics diff --git a/pkgs/sagemath-categories/setup.cfg.m4 b/pkgs/sagemath-categories/setup.cfg.m4 index 62aca5af44f..d5c6a957e2c 100644 --- a/pkgs/sagemath-categories/setup.cfg.m4 +++ b/pkgs/sagemath-categories/setup.cfg.m4 @@ -5,25 +5,7 @@ version = file: VERSION.txt description = Sage: Open Source Mathematics Software: Sage categories and basic rings long_description = file: README.rst long_description_content_type = text/x-rst -license = GNU General Public License (GPL) v2 or later -author = The Sage Developers -author_email = sage-support@googlegroups.com -url = https://www.sagemath.org - -classifiers = - Development Status :: 6 - Mature - Intended Audience :: Education - Intended Audience :: Science/Research - License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+) - Operating System :: POSIX - Operating System :: MacOS :: MacOS X - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Programming Language :: Python :: Implementation :: CPython - Topic :: Scientific/Engineering :: Mathematics +include(`setup_cfg_metadata.m4')dnl' [options] python_requires = >=3.8, <3.12 diff --git a/pkgs/sagemath-environment/setup.cfg.m4 b/pkgs/sagemath-environment/setup.cfg.m4 index 919a5b576cd..901b81e268d 100644 --- a/pkgs/sagemath-environment/setup.cfg.m4 +++ b/pkgs/sagemath-environment/setup.cfg.m4 @@ -5,25 +5,7 @@ version = file: VERSION.txt description = Sage: Open Source Mathematics Software: System and software environment long_description = file: README.rst long_description_content_type = text/x-rst -license = GNU General Public License (GPL) v2 or later -author = The Sage Developers -author_email = sage-support@googlegroups.com -url = https://www.sagemath.org - -classifiers = - Development Status :: 6 - Mature - Intended Audience :: Education - Intended Audience :: Science/Research - License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+) - Operating System :: POSIX - Operating System :: MacOS :: MacOS X - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Programming Language :: Python :: Implementation :: CPython - Topic :: Scientific/Engineering :: Mathematics +include(`setup_cfg_metadata.m4')dnl' [options] python_requires = >=3.8, <3.12 diff --git a/pkgs/sagemath-objects/setup.cfg.m4 b/pkgs/sagemath-objects/setup.cfg.m4 index 88246c422f2..1952fb8c2eb 100644 --- a/pkgs/sagemath-objects/setup.cfg.m4 +++ b/pkgs/sagemath-objects/setup.cfg.m4 @@ -5,25 +5,7 @@ version = file: VERSION.txt description = Sage: Open Source Mathematics Software: Sage objects, elements, parents, categories, coercion, metaclasses long_description = file: README.rst long_description_content_type = text/x-rst -license = GNU General Public License (GPL) v2 or later -author = The Sage Developers -author_email = sage-support@googlegroups.com -url = https://www.sagemath.org - -classifiers = - Development Status :: 6 - Mature - Intended Audience :: Education - Intended Audience :: Science/Research - License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+) - Operating System :: POSIX - Operating System :: MacOS :: MacOS X - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Programming Language :: Python :: Implementation :: CPython - Topic :: Scientific/Engineering :: Mathematics +include(`setup_cfg_metadata.m4')dnl' [options] python_requires = >=3.8, <3.12 diff --git a/pkgs/sagemath-repl/setup.cfg.m4 b/pkgs/sagemath-repl/setup.cfg.m4 index 2367fda7b9a..9078624e0a7 100644 --- a/pkgs/sagemath-repl/setup.cfg.m4 +++ b/pkgs/sagemath-repl/setup.cfg.m4 @@ -5,25 +5,7 @@ version = file: VERSION.txt description = Sage: Open Source Mathematics Software: System and software environment long_description = file: README.rst long_description_content_type = text/x-rst -license = GNU General Public License (GPL) v2 or later -author = The Sage Developers -author_email = sage-support@googlegroups.com -url = https://www.sagemath.org - -classifiers = - Development Status :: 6 - Mature - Intended Audience :: Education - Intended Audience :: Science/Research - License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+) - Operating System :: POSIX - Operating System :: MacOS :: MacOS X - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Programming Language :: Python :: Implementation :: CPython - Topic :: Scientific/Engineering :: Mathematics +include(`setup_cfg_metadata.m4')dnl' [options] python_requires = >=3.8, <3.12 diff --git a/src/setup.cfg.m4 b/src/setup.cfg.m4 index bbd9133902e..a50719a78ab 100644 --- a/src/setup.cfg.m4 +++ b/src/setup.cfg.m4 @@ -5,26 +5,8 @@ version = file: VERSION.txt description = Sage: Open Source Mathematics Software: Standard Python Library long_description = file: README.rst long_description_content_type = text/x-rst -license = GNU General Public License (GPL) v2 or later license_files = LICENSE.txt -author = The Sage Developers -author_email = sage-support@googlegroups.com -url = https://www.sagemath.org - -classifiers = - Development Status :: 6 - Mature - Intended Audience :: Education - Intended Audience :: Science/Research - License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+) - Operating System :: POSIX - Operating System :: MacOS :: MacOS X - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Programming Language :: Python :: Implementation :: CPython - Topic :: Scientific/Engineering :: Mathematics +include(`setup_cfg_metadata.m4')dnl' [options] python_requires = >=3.8, <3.12 From d7d19e8c7928d3b03e0769f245aaf8978b220bfb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Mon, 19 Jun 2023 17:36:07 -0700 Subject: [PATCH 198/228] bootstrap: Generate m4/sage_spkg_versions.m4, use in pkgs/*/setup.cfg.m4 --- .gitignore | 1 + bootstrap | 7 +- pkgs/sagemath-categories/setup.cfg.m4 | 8 +-- pkgs/sagemath-environment/setup.cfg.m4 | 27 +++++--- pkgs/sagemath-objects/setup.cfg.m4 | 7 +- pkgs/sagemath-repl/setup.cfg.m4 | 12 ++-- src/sage/modules/all__sagemath_objects.py | 0 src/setup.cfg.m4 | 84 +++++++++-------------- 8 files changed, 69 insertions(+), 77 deletions(-) create mode 100644 src/sage/modules/all__sagemath_objects.py diff --git a/.gitignore b/.gitignore index cdb9c373c37..767dc3d5941 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ /confdefs.h /m4/sage_spkg_configures.m4 +/m4/sage_spkg_versions.m4 # no longer generated, but may still be in user worktrees /src/lib/pkgconfig diff --git a/bootstrap b/bootstrap index 48c4801d4b5..acb0f4f7a61 100755 --- a/bootstrap +++ b/bootstrap @@ -37,8 +37,10 @@ CONFVERSION=$(cat $PKG/package-version.txt) bootstrap () { if [ "${BOOTSTRAP_QUIET}" = "no" ]; then echo "bootstrap:$LINENO: installing 'm4/sage_spkg_configures.m4'" + echo "bootstrap:$LINENO: installing 'm4/sage_spkg_versions.m4'" fi - rm -f m4/sage_spkg_configures.m4 + rm -f m4/sage_spkg_configures.m4 m4/sage_spkg_versions.m4 + echo "# Generated by SAGE_ROOT/bootstrap; do not edit" > m4/sage_spkg_versions.m4 spkg_configures="" # initialize SAGE_ENABLE... options for standard packages for pkgname in $(sage-package list :standard: | sort); do @@ -92,6 +94,9 @@ SAGE_SPKG_CONFIGURE_$(echo ${pkgname} | tr '[a-z]' '[A-Z]')" if test -f "$DIR/requirements.txt" -o -f "$DIR/install-requires.txt"; then # A Python package SPKG_TREE_VAR=SAGE_VENV + if test -f "$DIR/install-requires.txt"; then + echo 'define(`SPKG_INSTALL_REQUIRES_'${pkgname}"'"', `'$(echo $(sage-get-system-packages install-requires ${pkgname}))"')dnl" >> m4/sage_spkg_versions.m4 + fi fi fi spkg_configures="$spkg_configures diff --git a/pkgs/sagemath-categories/setup.cfg.m4 b/pkgs/sagemath-categories/setup.cfg.m4 index d5c6a957e2c..2539a8aafb5 100644 --- a/pkgs/sagemath-categories/setup.cfg.m4 +++ b/pkgs/sagemath-categories/setup.cfg.m4 @@ -1,4 +1,4 @@ -# -*- conf-unix -*- +include(`sage_spkg_versions.m4')dnl' -*- conf-unix -*- [metadata] name = sagemath-categories version = file: VERSION.txt @@ -10,9 +10,7 @@ include(`setup_cfg_metadata.m4')dnl' [options] python_requires = >=3.8, <3.12 install_requires = - esyscmd(`sage-get-system-packages install-requires \ - sagemath_objects \ - | sed "2,\$s/^/ /;"')dnl + SPKG_INSTALL_REQUIRES_sagemath_objects [options.extras_require] -test = sagemath-repl +test = SPKG_INSTALL_REQUIRES_sagemath_repl diff --git a/pkgs/sagemath-environment/setup.cfg.m4 b/pkgs/sagemath-environment/setup.cfg.m4 index 901b81e268d..deb74565b3b 100644 --- a/pkgs/sagemath-environment/setup.cfg.m4 +++ b/pkgs/sagemath-environment/setup.cfg.m4 @@ -1,4 +1,4 @@ -# -*- conf-unix -*- +include(`sage_spkg_versions.m4')dnl' -*- conf-unix -*- [metadata] name = sagemath-environment version = file: VERSION.txt @@ -10,8 +10,6 @@ include(`setup_cfg_metadata.m4')dnl' [options] python_requires = >=3.8, <3.12 install_requires = - esyscmd(`sage-get-system-packages install-requires \ - | sed "2,\$s/^/ /;"')dnl py_modules = sage.all__sagemath_environment @@ -43,16 +41,25 @@ scripts = [options.extras_require] # sage.env can optionally use sage_conf -conf = esyscmd(`sage-get-system-packages install-requires sage_conf') +conf = SPKG_INSTALL_REQUIRES_sage_conf + # For "sage --docbuild" -docbuild = esyscmd(`sage-get-system-packages install-requires sage_docbuild') +docbuild = SPKG_INSTALL_REQUIRES_sage_docbuild + # For "sage", "sage -t", ... -sage = esyscmd(`sage-get-system-packages install-requires sagelib') +sage = SPKG_INSTALL_REQUIRES_sagelib + # For "sage --cython" -cython = esyscmd(`sage-get-system-packages install-requires cython') +cython = SPKG_INSTALL_REQUIRES_cython + # For "sage --pytest" -pytest = esyscmd(`sage-get-system-packages install-requires pytest') +pytest = SPKG_INSTALL_REQUIRES_pytest + # For "sage --rst2ipynb" -rst2ipynb = esyscmd(`sage-get-system-packages install-requires rst2ipynb') +rst2ipynb = SPKG_INSTALL_REQUIRES_rst2ipynb + +# For "sage --tox" +tox = SPKG_INSTALL_REQUIRES_tox + # For "sage --sws2rst" -sws2rst = esyscmd(`sage-get-system-packages install-requires sage_sws2rst') +sws2rst = SPKG_INSTALL_REQUIRES_sage_sws2rst diff --git a/pkgs/sagemath-objects/setup.cfg.m4 b/pkgs/sagemath-objects/setup.cfg.m4 index 1952fb8c2eb..94ec7f63024 100644 --- a/pkgs/sagemath-objects/setup.cfg.m4 +++ b/pkgs/sagemath-objects/setup.cfg.m4 @@ -8,12 +8,11 @@ long_description_content_type = text/x-rst include(`setup_cfg_metadata.m4')dnl' [options] +include(`sage_spkg_versions.m4')dnl' python_requires = >=3.8, <3.12 install_requires = - esyscmd(`sage-get-system-packages install-requires \ - gmpy2 \ - cysignals \ - | sed "2,\$s/^/ /;"')dnl + SPKG_INSTALL_REQUIRES_gmpy2 + SPKG_INSTALL_REQUIRES_cysignals [options.extras_require] # Currently we do not use the sage doctester to test sagemath-objects, diff --git a/pkgs/sagemath-repl/setup.cfg.m4 b/pkgs/sagemath-repl/setup.cfg.m4 index 9078624e0a7..8c7e11777b8 100644 --- a/pkgs/sagemath-repl/setup.cfg.m4 +++ b/pkgs/sagemath-repl/setup.cfg.m4 @@ -1,4 +1,4 @@ -# -*- conf-unix -*- +include(`sage_spkg_versions.m4')dnl' -*- conf-unix -*- [metadata] name = sagemath-repl version = file: VERSION.txt @@ -10,12 +10,10 @@ include(`setup_cfg_metadata.m4')dnl' [options] python_requires = >=3.8, <3.12 install_requires = - esyscmd(`sage-get-system-packages install-requires \ - sagemath_objects \ - sagemath_environment \ - ipython \ - ipywidgets \ - | sed "2,\$s/^/ /;"')dnl + SPKG_INSTALL_REQUIRES_sagemath_objects + SPKG_INSTALL_REQUIRES_sagemath_environment + SPKG_INSTALL_REQUIRES_ipython + SPKG_INSTALL_REQUIRES_ipywidgets py_modules = sage.all__sagemath_repl diff --git a/src/sage/modules/all__sagemath_objects.py b/src/sage/modules/all__sagemath_objects.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/setup.cfg.m4 b/src/setup.cfg.m4 index a50719a78ab..abf5aa4ada9 100644 --- a/src/setup.cfg.m4 +++ b/src/setup.cfg.m4 @@ -1,4 +1,4 @@ -# -*- conf-unix -*- +include(`sage_spkg_versions.m4')dnl' -*- conf-unix -*- [metadata] name = sagemath-standard version = file: VERSION.txt @@ -11,56 +11,43 @@ include(`setup_cfg_metadata.m4')dnl' [options] python_requires = >=3.8, <3.12 install_requires = - esyscmd(`sage-get-system-packages install-requires \ - sage_conf \ - six \ - | sed "2,\$s/^/ /;"')dnl' + SPKG_INSTALL_REQUIRES_sage_conf + SPKG_INSTALL_REQUIRES_six dnl From build/pkgs/sagelib/dependencies - esyscmd(`sage-get-system-packages install-requires \ - cypari \ - cysignals \ - cython \ - gmpy2 \ - importlib_metadata \ - importlib_resources \ - jinja2 \ - jupyter_core \ - lrcalc_python \ - memory_allocator \ - numpy \ - pkgconfig \ - pplpy \ - primecountpy \ - requests \ - typing_extensions \ - | sed "2,\$s/^/ /;"')dnl' + SPKG_INSTALL_REQUIRES_cypari + SPKG_INSTALL_REQUIRES_cysignals + SPKG_INSTALL_REQUIRES_cython + SPKG_INSTALL_REQUIRES_gmpy2 + SPKG_INSTALL_REQUIRES_importlib_metadata + SPKG_INSTALL_REQUIRES_importlib_resources + SPKG_INSTALL_REQUIRES_jinja2 + SPKG_INSTALL_REQUIRES_jupyter_core + SPKG_INSTALL_REQUIRES_lrcalc_python + SPKG_INSTALL_REQUIRES_memory_allocator + SPKG_INSTALL_REQUIRES_numpy + SPKG_INSTALL_REQUIRES_pkgconfig + SPKG_INSTALL_REQUIRES_pplpy + SPKG_INSTALL_REQUIRES_primecountpy + SPKG_INSTALL_REQUIRES_requests + SPKG_INSTALL_REQUIRES_typing_extensions dnl From Makefile.in: SAGERUNTIME - esyscmd(`sage-get-system-packages install-requires \ - ipython \ - pexpect \ - | sed "2,\$s/^/ /;"')dnl' + SPKG_INSTALL_REQUIRES_ipython + SPKG_INSTALL_REQUIRES_pexpect dnl From Makefile.in: DOC_DEPENDENCIES - esyscmd(`sage-get-system-packages install-requires \ - sphinx \ - networkx \ - scipy \ - sympy \ - matplotlib \ - pillow \ - mpmath \ - ipykernel \ - jupyter_client \ - ipywidgets \ - | sed "2,\$s/^/ /;"')dnl' -dnl Other Python packages that are standard spkg, used in doctests - esyscmd(`sage-get-system-packages install-requires \ - fpylll \ - | sed "2,\$s/^/ /;"')dnl' + SPKG_INSTALL_REQUIRES_sphinx + SPKG_INSTALL_REQUIRES_networkx + SPKG_INSTALL_REQUIRES_scipy + SPKG_INSTALL_REQUIRES_sympy + SPKG_INSTALL_REQUIRES_matplotlib + SPKG_INSTALL_REQUIRES_pillow + SPKG_INSTALL_REQUIRES_mpmath + SPKG_INSTALL_REQUIRES_ipykernel + SPKG_INSTALL_REQUIRES_jupyter_client + SPKG_INSTALL_REQUIRES_ipywidgets + SPKG_INSTALL_REQUIRES_fpylll dnl pycryptosat # Sage distribution installs it as part of cryptominisat. According to its README on https://pypi.org/project/pycryptosat/: "The pycryptosat python package compiles while compiling CryptoMiniSat. It cannot be compiled on its own, it must be compiled at the same time as CryptoMiniSat." dnl Packages with important upper version bounds - esyscmd(`sage-get-system-packages install-requires \ - ptyprocess \ - | sed "2,\$s/^/ /;"')dnl' + SPKG_INSTALL_REQUIRES_ptyprocess scripts = # The sage script @@ -71,7 +58,6 @@ scripts = bin/sage-runtests bin/sage-fixdoctests bin/sage-coverage - # The following is deprecated but might still be used in user package install scripts bin/sage-cython # Helper scripts invoked by sage script # (they would actually belong to something like libexec) @@ -147,6 +133,4 @@ sage = ext_data/threejs/* [options.extras_require] -R = esyscmd(`sage-get-system-packages install-requires \ - rpy2 \ - | sed "2,\$s/^/ /;"')dnl' +R = SPKG_INSTALL_REQUIRES_rpy2 From 66a053f24e20fbb74fc82b68468dbbb6e89360f3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Tue, 20 Jun 2023 11:19:31 -0700 Subject: [PATCH 199/228] bootstrap: Flag bad uses of SPKG_INSTALL_REQUIRES_ macros; fall back to requirements.txt --- bootstrap | 4 +--- build/bin/sage-get-system-packages | 8 ++++---- build/pkgs/sagelib/bootstrap | 6 ++++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/bootstrap b/bootstrap index acb0f4f7a61..db1373029b6 100755 --- a/bootstrap +++ b/bootstrap @@ -94,9 +94,7 @@ SAGE_SPKG_CONFIGURE_$(echo ${pkgname} | tr '[a-z]' '[A-Z]')" if test -f "$DIR/requirements.txt" -o -f "$DIR/install-requires.txt"; then # A Python package SPKG_TREE_VAR=SAGE_VENV - if test -f "$DIR/install-requires.txt"; then - echo 'define(`SPKG_INSTALL_REQUIRES_'${pkgname}"'"', `'$(echo $(sage-get-system-packages install-requires ${pkgname}))"')dnl" >> m4/sage_spkg_versions.m4 - fi + echo 'define(`SPKG_INSTALL_REQUIRES_'${pkgname}"'"', `'$(echo $(sage-get-system-packages install-requires ${pkgname}))"')dnl" >> m4/sage_spkg_versions.m4 fi fi spkg_configures="$spkg_configures diff --git a/build/bin/sage-get-system-packages b/build/bin/sage-get-system-packages index b5153c53694..c51c36ceab9 100755 --- a/build/bin/sage-get-system-packages +++ b/build/bin/sage-get-system-packages @@ -12,16 +12,16 @@ if [ -z "$SAGE_ROOT" ]; then fi case "$SYSTEM" in install-requires) - # Collect install-requires.txt and output it in the format + # Collect install-requires.txt (falling back to requirements.txt) and output it in the format # needed by setup.cfg [options] install_requires= - SYSTEM_PACKAGES_FILE_NAMES="install-requires.txt" + SYSTEM_PACKAGES_FILE_NAMES="install-requires.txt requirements.txt" STRIP_COMMENTS="sed s/#.*//;/^[[:space:]]*$/d;" COLLECT= ;; install-requires-toml) - # Collect install-requires.txt and output it in the format + # Collect install-requires.txt (falling back to requirements.txt) and output it in the format # needed by pyproject.toml [build-system] requires= - SYSTEM_PACKAGES_FILE_NAMES="install-requires.txt" + SYSTEM_PACKAGES_FILE_NAMES="install-requires.txt requirements.txt" STRIP_COMMENTS="sed s/#.*//;/^[[:space:]]*$/d;s/^/'/;s/$/',/;" COLLECT= ;; diff --git a/build/pkgs/sagelib/bootstrap b/build/pkgs/sagelib/bootstrap index 5a186d79c8b..2c9b3f78974 100755 --- a/build/pkgs/sagelib/bootstrap +++ b/build/pkgs/sagelib/bootstrap @@ -1,6 +1,7 @@ #! /bin/sh set -e export M4PATH="$SAGE_ROOT/m4" +MACRO_PATTERN='SPKG_' for infile in src/*.m4; do if [ -f "$infile" ]; then outfile="src/$(basename $infile .m4)" @@ -8,5 +9,10 @@ for infile in src/*.m4; do echo "$0: installing $(pwd)/$outfile" fi m4 "$infile" > "$outfile" + if sed 's/#.*//' "$outfile" | grep -q -E "$MACRO_PATTERN"; then + echo >&2 "$(pwd)/$infile: error: Unrecognized SPKG_ macro:" + grep -E "$MACRO_PATTERN" "$outfile" >&2 + exit 1 + fi fi done From 0dd1e0920c6f21d8a77a8baada213c180aaa40ff Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Tue, 20 Jun 2023 13:22:50 -0700 Subject: [PATCH 200/228] bootstrap: Write m4/sage_spkg_versions_toml.m4 and use it in pkgs/*/pyproject.toml.m4 --- .gitignore | 2 +- bootstrap | 15 ++++++++++++--- pkgs/sagemath-categories/pyproject.toml.m4 | 21 ++++++++++----------- pkgs/sagemath-environment/pyproject.toml.m4 | 8 ++++---- pkgs/sagemath-objects/pyproject.toml.m4 | 18 +++++++++--------- pkgs/sagemath-repl/pyproject.toml.m4 | 8 ++++---- 6 files changed, 40 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index 767dc3d5941..0c1c9086cf7 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,7 @@ /confdefs.h /m4/sage_spkg_configures.m4 -/m4/sage_spkg_versions.m4 +/m4/sage_spkg_versions*.m4 # no longer generated, but may still be in user worktrees /src/lib/pkgconfig diff --git a/bootstrap b/bootstrap index db1373029b6..e05092b32ce 100755 --- a/bootstrap +++ b/bootstrap @@ -39,8 +39,13 @@ bootstrap () { echo "bootstrap:$LINENO: installing 'm4/sage_spkg_configures.m4'" echo "bootstrap:$LINENO: installing 'm4/sage_spkg_versions.m4'" fi - rm -f m4/sage_spkg_configures.m4 m4/sage_spkg_versions.m4 - echo "# Generated by SAGE_ROOT/bootstrap; do not edit" > m4/sage_spkg_versions.m4 + for a in m4/sage_spkg_configures.m4 m4/sage_spkg_versions.m4 m4/sage_spkg_versions_toml.m4; do + rm -f $a + echo "# Generated by SAGE_ROOT/bootstrap; do not edit" > $a + done + for a in m4/sage_spkg_versions.m4 m4/sage_spkg_versions_toml.m4; do + echo 'changequote(`>>>'"'"', `<<<'"')dnl" >> $a + done spkg_configures="" # initialize SAGE_ENABLE... options for standard packages for pkgname in $(sage-package list :standard: | sort); do @@ -94,13 +99,17 @@ SAGE_SPKG_CONFIGURE_$(echo ${pkgname} | tr '[a-z]' '[A-Z]')" if test -f "$DIR/requirements.txt" -o -f "$DIR/install-requires.txt"; then # A Python package SPKG_TREE_VAR=SAGE_VENV - echo 'define(`SPKG_INSTALL_REQUIRES_'${pkgname}"'"', `'$(echo $(sage-get-system-packages install-requires ${pkgname}))"')dnl" >> m4/sage_spkg_versions.m4 + echo "define(>>>SPKG_INSTALL_REQUIRES_${pkgname}<<<, >>>$(echo $(sage-get-system-packages install-requires ${pkgname}))<<<)dnl" >> m4/sage_spkg_versions.m4 + echo "define(>>>SPKG_INSTALL_REQUIRES_${pkgname}<<<, >>>$(echo $(sage-get-system-packages install-requires-toml ${pkgname}))<<<)dnl" >> m4/sage_spkg_versions_toml.m4 fi fi spkg_configures="$spkg_configures SAGE_SPKG_FINALIZE([$pkgname], [$pkgtype], [$SPKG_SOURCE], [$SPKG_TREE_VAR])" done echo "$spkg_configures" >> m4/sage_spkg_configures.m4 + for a in m4/sage_spkg_versions.m4 m4/sage_spkg_versions_toml.m4; do + echo 'changequote(>>>`<<<, >>>'"'"'<<<)dnl' >> $a + done for pkgname in $(sage-package list --has-file bootstrap); do (cd build/pkgs/$pkgname && ./bootstrap) || exit 1 diff --git a/pkgs/sagemath-categories/pyproject.toml.m4 b/pkgs/sagemath-categories/pyproject.toml.m4 index 0afd7849de5..818d0be369f 100644 --- a/pkgs/sagemath-categories/pyproject.toml.m4 +++ b/pkgs/sagemath-categories/pyproject.toml.m4 @@ -1,14 +1,13 @@ -[build-system] +include(`sage_spkg_versions_toml.m4')dnl' -*- conf-toml -*- # Minimum requirements for the build system to execute. requires = [ - esyscmd(`sage-get-system-packages install-requires-toml \ - setuptools \ - wheel \ - sage_setup \ - sagemath_environment \ - sagemath_objects \ - cython \ - gmpy2 \ - cysignals \ - ')] + SPKG_INSTALL_REQUIRES_setuptools + SPKG_INSTALL_REQUIRES_wheel + SPKG_INSTALL_REQUIRES_sage_setup + SPKG_INSTALL_REQUIRES_sagemath_environment + SPKG_INSTALL_REQUIRES_sagemath_objects + SPKG_INSTALL_REQUIRES_cython + SPKG_INSTALL_REQUIRES_gmpy2 + SPKG_INSTALL_REQUIRES_cysignals +] build-backend = "setuptools.build_meta" diff --git a/pkgs/sagemath-environment/pyproject.toml.m4 b/pkgs/sagemath-environment/pyproject.toml.m4 index 686515673fc..7f62a86cd69 100644 --- a/pkgs/sagemath-environment/pyproject.toml.m4 +++ b/pkgs/sagemath-environment/pyproject.toml.m4 @@ -1,8 +1,8 @@ +include(`sage_spkg_versions_toml.m4')dnl' -*- conf-toml -*- [build-system] # Minimum requirements for the build system to execute. requires = [ - esyscmd(`sage-get-system-packages install-requires-toml \ - setuptools \ - wheel \ - ')] + SPKG_INSTALL_REQUIRES_setuptools + SPKG_INSTALL_REQUIRES_wheel +] build-backend = "setuptools.build_meta" diff --git a/pkgs/sagemath-objects/pyproject.toml.m4 b/pkgs/sagemath-objects/pyproject.toml.m4 index c13665be51d..0c5558f3412 100644 --- a/pkgs/sagemath-objects/pyproject.toml.m4 +++ b/pkgs/sagemath-objects/pyproject.toml.m4 @@ -1,13 +1,13 @@ +include(`sage_spkg_versions_toml.m4')dnl' -*- conf-toml -*- [build-system] # Minimum requirements for the build system to execute. requires = [ - esyscmd(`sage-get-system-packages install-requires-toml \ - setuptools \ - wheel \ - sage_setup \ - sagemath_environment \ - cython \ - gmpy2 \ - cysignals \ - ')] + SPKG_INSTALL_REQUIRES_setuptools + SPKG_INSTALL_REQUIRES_wheel + SPKG_INSTALL_REQUIRES_sage_setup + SPKG_INSTALL_REQUIRES_sagemath_environment + SPKG_INSTALL_REQUIRES_cython + SPKG_INSTALL_REQUIRES_gmpy2 + SPKG_INSTALL_REQUIRES_cysignals +] build-backend = "setuptools.build_meta" diff --git a/pkgs/sagemath-repl/pyproject.toml.m4 b/pkgs/sagemath-repl/pyproject.toml.m4 index 686515673fc..7f62a86cd69 100644 --- a/pkgs/sagemath-repl/pyproject.toml.m4 +++ b/pkgs/sagemath-repl/pyproject.toml.m4 @@ -1,8 +1,8 @@ +include(`sage_spkg_versions_toml.m4')dnl' -*- conf-toml -*- [build-system] # Minimum requirements for the build system to execute. requires = [ - esyscmd(`sage-get-system-packages install-requires-toml \ - setuptools \ - wheel \ - ')] + SPKG_INSTALL_REQUIRES_setuptools + SPKG_INSTALL_REQUIRES_wheel +] build-backend = "setuptools.build_meta" From f17b341ed2d3caf95d910e2093fc7a68eedbc669 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Tue, 20 Jun 2023 14:35:53 -0700 Subject: [PATCH 201/228] bootstrap: Update 'Installing...' messages --- bootstrap | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/bootstrap b/bootstrap index e05092b32ce..aaf853d305c 100755 --- a/bootstrap +++ b/bootstrap @@ -35,11 +35,10 @@ CONFVERSION=$(cat $PKG/package-version.txt) bootstrap () { - if [ "${BOOTSTRAP_QUIET}" = "no" ]; then - echo "bootstrap:$LINENO: installing 'm4/sage_spkg_configures.m4'" - echo "bootstrap:$LINENO: installing 'm4/sage_spkg_versions.m4'" - fi for a in m4/sage_spkg_configures.m4 m4/sage_spkg_versions.m4 m4/sage_spkg_versions_toml.m4; do + if [ "${BOOTSTRAP_QUIET}" = "no" ]; then + echo "bootstrap:$LINENO: installing '"$a"'" + fi rm -f $a echo "# Generated by SAGE_ROOT/bootstrap; do not edit" > $a done From a7884857d4140a6073c95b3b9fe20c155c64f97e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Thu, 22 Jun 2023 17:17:15 -0700 Subject: [PATCH 202/228] bootstrap: Write m4/sage_spkg_versions_toml.m4 and use it in pkgs/*/pyproject.toml.m4 (fixup) --- pkgs/sagemath-categories/pyproject.toml.m4 | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/sagemath-categories/pyproject.toml.m4 b/pkgs/sagemath-categories/pyproject.toml.m4 index 818d0be369f..6ce29ddcb71 100644 --- a/pkgs/sagemath-categories/pyproject.toml.m4 +++ b/pkgs/sagemath-categories/pyproject.toml.m4 @@ -1,4 +1,5 @@ include(`sage_spkg_versions_toml.m4')dnl' -*- conf-toml -*- +[build-system] # Minimum requirements for the build system to execute. requires = [ SPKG_INSTALL_REQUIRES_setuptools From 6adc33fe69fb40170797f066b96dcc9a715730f1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Fri, 30 Jun 2023 08:38:47 -0700 Subject: [PATCH 203/228] src/setup.cfg.m4: Back out unintended change --- src/setup.cfg.m4 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/setup.cfg.m4 b/src/setup.cfg.m4 index abf5aa4ada9..b82631a5e4c 100644 --- a/src/setup.cfg.m4 +++ b/src/setup.cfg.m4 @@ -58,6 +58,7 @@ scripts = bin/sage-runtests bin/sage-fixdoctests bin/sage-coverage + # The following is deprecated but might still be used in user package install scripts bin/sage-cython # Helper scripts invoked by sage script # (they would actually belong to something like libexec) From 69106462a8b2efef22c3824a0c8edee283324557 Mon Sep 17 00:00:00 2001 From: Aram Dermenjian <aram.dermenjian.math@gmail.com> Date: Fri, 30 Jun 2023 18:00:23 +0100 Subject: [PATCH 204/228] Fix typo in Category primer --- src/sage/categories/primer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/categories/primer.py b/src/sage/categories/primer.py index 84ab37f34b7..334cb157cb4 100644 --- a/src/sage/categories/primer.py +++ b/src/sage/categories/primer.py @@ -578,7 +578,7 @@ class implements: - Group, Monoid, Semigroup, Magma, ... - GroupElement, MonoidElement, SemigroupElement, MagmaElement, ... -- GroupMorphism, SemigroupElement, SemigroupMorphism, MagmaMorphism, ... +- GroupMorphism, MonoidMorphism, SemigroupMorphism, MagmaMorphism, ... (and in fact many more as we will see). From 0dcd557a464e6a600b55c3ca2de1d91a93aeac56 Mon Sep 17 00:00:00 2001 From: David Einstein <deinst@gmail.com> Date: Fri, 30 Jun 2023 13:17:58 -0400 Subject: [PATCH 205/228] Fix formatting in documentation of connected_subgraph_iterator --- src/sage/graphs/base/static_dense_graph.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/base/static_dense_graph.pyx b/src/sage/graphs/base/static_dense_graph.pyx index 59b456762a9..2014289457d 100644 --- a/src/sage/graphs/base/static_dense_graph.pyx +++ b/src/sage/graphs/base/static_dense_graph.pyx @@ -785,8 +785,8 @@ def connected_subgraph_iterator(G, k=None, bint vertices_only=False, This parameter can be set to ``False`` for simple (di)graphs only. - ``exactly_k`` -- boolean (default: ``False``); ``True`` if we only - return graphs of order ``k``, ``False`` if we return graphs of order - at most ``k``. + return graphs of order `k`, ``False`` if we return graphs of order + at most `k`. EXAMPLES:: From 5b53f874ff535bdf42668577c586dcbc2128cb13 Mon Sep 17 00:00:00 2001 From: Vincent Neiger <vneiger@users.noreply.github.com> Date: Fri, 30 Jun 2023 20:23:44 +0200 Subject: [PATCH 206/228] forgot to remove the warning in doctest in last commit --- src/sage/rings/number_field/number_field_element.pyx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sage/rings/number_field/number_field_element.pyx b/src/sage/rings/number_field/number_field_element.pyx index d9df03a2e4b..3f5f84fd8f5 100644 --- a/src/sage/rings/number_field/number_field_element.pyx +++ b/src/sage/rings/number_field/number_field_element.pyx @@ -1305,8 +1305,6 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: p = x**5 - 3 sage: K.<a> = NumberField(p) sage: [K(k/3).round() for k in range(-3,4)] - doctest...: DeprecationWarning: the default rounding for rationals, currently `away`, will be changed to `even`. - See https://github.com/sagemath/sage/issues/35473 for details. [-1, -1, 0, 0, 0, 1, 1] sage: a.round() Traceback (most recent call last): From 5ecf106c38e61d8d2a5d97008e10ece4d1c7a43c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Fri, 30 Jun 2023 11:28:43 -0700 Subject: [PATCH 207/228] Remove file added by mistake --- src/sage/modules/all__sagemath_objects.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/sage/modules/all__sagemath_objects.py diff --git a/src/sage/modules/all__sagemath_objects.py b/src/sage/modules/all__sagemath_objects.py deleted file mode 100644 index e69de29bb2d..00000000000 From ab81af050c9075b3ba2ee8c961ffc76e5705c2f3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Fri, 30 Jun 2023 17:43:16 -0700 Subject: [PATCH 208/228] Integer.is_irreducible: Delegate to is_prime, so that easy cases are done without PARI --- src/sage/rings/integer.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 3421cdd3612..024ff87c9a9 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -5387,7 +5387,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): True """ cdef Integer n = self if self >= 0 else -self - return n.__pari__().isprime() + return self.is_prime(proof=True) def is_pseudoprime(self): r""" From 053f1a2fc197e03c10c270517cd0c9c6ddef165b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Fri, 30 Jun 2023 21:27:42 -0700 Subject: [PATCH 209/228] Integer.is_irreducible: Delegate to is_prime, so that easy cases are done without PARI (fixup) --- src/sage/rings/integer.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 024ff87c9a9..4ff89eb1702 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -5387,7 +5387,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): True """ cdef Integer n = self if self >= 0 else -self - return self.is_prime(proof=True) + return n.is_prime(proof=True) def is_pseudoprime(self): r""" From 5ca035ed8894458d3199b768ce5f0928d644ba64 Mon Sep 17 00:00:00 2001 From: Vincent Neiger <vneiger@users.noreply.github.com> Date: Sat, 1 Jul 2023 20:32:58 +0200 Subject: [PATCH 210/228] fix trailing whitespace --- src/sage/matrix/matrix_polynomial_dense.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_polynomial_dense.pyx b/src/sage/matrix/matrix_polynomial_dense.pyx index 60a3faf7373..4ed1ef549ef 100644 --- a/src/sage/matrix/matrix_polynomial_dense.pyx +++ b/src/sage/matrix/matrix_polynomial_dense.pyx @@ -1671,7 +1671,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): for pos in leading_positions] # leading positions should not have duplicates, which is equivalent to: # once sorted, it doesn't contain a pair of equal successive entries - # (we do not sort if we want to test + # (we do not sort if we want to test if not ordered: leading_positions.sort() # check that there is no zero vector, if it is forbidden From b86791dd16c60cab4a7be4c73e099df704732789 Mon Sep 17 00:00:00 2001 From: OP5642 <ognjenpetrov@yahoo.com> Date: Sat, 1 Jul 2023 21:55:45 +0200 Subject: [PATCH 211/228] Minor changes to is_golod method --- src/sage/topology/simplicial_complex.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/sage/topology/simplicial_complex.py b/src/sage/topology/simplicial_complex.py index bb4bc67aab9..126ae1a4b44 100644 --- a/src/sage/topology/simplicial_complex.py +++ b/src/sage/topology/simplicial_complex.py @@ -4967,13 +4967,11 @@ def is_golod(self): sage: Y.is_golod() True """ - H = set(a+b for (a, b) in self.bigraded_betti_numbers()) + H = list(a+b for (a, b) in self.bigraded_betti_numbers()) if 0 in H: - HL = list(H.difference([0])) - else: - HL = list(H) + H.remove(0) - return not any(i + j in H for ii, i in enumerate(HL) for j in HL[ii:]) + return not any(i+j in H for ii, i in enumerate(H) for j in H[ii:]) def is_minimally_non_golod(self): r""" From 853d07099ce6b4dce3aab2d690111a07034adee9 Mon Sep 17 00:00:00 2001 From: Release Manager <release@sagemath.org> Date: Sat, 1 Jul 2023 22:58:24 +0200 Subject: [PATCH 212/228] Updated SageMath version to 10.1.beta5 --- CITATION.cff | 4 ++-- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 6 +++--- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sage_conf/install-requires.txt | 2 +- build/pkgs/sage_docbuild/install-requires.txt | 2 +- build/pkgs/sage_setup/install-requires.txt | 2 +- build/pkgs/sage_sws2rst/install-requires.txt | 2 +- build/pkgs/sagelib/install-requires.txt | 2 +- build/pkgs/sagemath_categories/install-requires.txt | 2 +- build/pkgs/sagemath_environment/install-requires.txt | 2 +- build/pkgs/sagemath_objects/install-requires.txt | 2 +- build/pkgs/sagemath_repl/install-requires.txt | 2 +- pkgs/sage-conf/VERSION.txt | 2 +- pkgs/sage-conf_pypi/VERSION.txt | 2 +- pkgs/sage-docbuild/VERSION.txt | 2 +- pkgs/sage-setup/VERSION.txt | 2 +- pkgs/sage-sws2rst/VERSION.txt | 2 +- pkgs/sagemath-categories/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 25 files changed, 32 insertions(+), 32 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index 1e4a3f7e84b..11b90ae405b 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -4,8 +4,8 @@ title: SageMath abstract: SageMath is a free open-source mathematics software system. authors: - name: "The SageMath Developers" -version: 10.1.beta4 +version: 10.1.beta5 doi: 10.5281/zenodo.593563 -date-released: 2023-06-21 +date-released: 2023-07-01 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index d91304debdc..90f410c9eef 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.1.beta4, Release Date: 2023-06-21 +SageMath version 10.1.beta5, Release Date: 2023-07-01 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index b3b5e42dd54..5343807fdf7 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=2852935b61f22d59a640dfe33a5f5bab10512296 -md5=b87baf9857489d7a70f5d9bee8322b64 -cksum=3781755388 +sha1=1b0149d4cc9bc0ca1bff27d84e8495143866225f +md5=3aacea16772e577bcab91ab773ff1aa6 +cksum=6323298 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 185d8ccc808..f2b6495542b 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -0779dd250ceb081a3a116c34a0a6b732de215bdf +9161c6c27bfd10f49de79e02c21347b1084a0c77 diff --git a/build/pkgs/sage_conf/install-requires.txt b/build/pkgs/sage_conf/install-requires.txt index dc86a0083d1..2c0f37f4268 100644 --- a/build/pkgs/sage_conf/install-requires.txt +++ b/build/pkgs/sage_conf/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-conf ~= 10.1b4 +sage-conf ~= 10.1b5 diff --git a/build/pkgs/sage_docbuild/install-requires.txt b/build/pkgs/sage_docbuild/install-requires.txt index 09fa2357f61..7cfebf2845f 100644 --- a/build/pkgs/sage_docbuild/install-requires.txt +++ b/build/pkgs/sage_docbuild/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-docbuild ~= 10.1b4 +sage-docbuild ~= 10.1b5 diff --git a/build/pkgs/sage_setup/install-requires.txt b/build/pkgs/sage_setup/install-requires.txt index feb29568e37..2c48bba5343 100644 --- a/build/pkgs/sage_setup/install-requires.txt +++ b/build/pkgs/sage_setup/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-setup ~= 10.1b4 +sage-setup ~= 10.1b5 diff --git a/build/pkgs/sage_sws2rst/install-requires.txt b/build/pkgs/sage_sws2rst/install-requires.txt index 499c62fc0a0..828f77192e0 100644 --- a/build/pkgs/sage_sws2rst/install-requires.txt +++ b/build/pkgs/sage_sws2rst/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-sws2rst ~= 10.1b4 +sage-sws2rst ~= 10.1b5 diff --git a/build/pkgs/sagelib/install-requires.txt b/build/pkgs/sagelib/install-requires.txt index 128dfc286e3..863164d3036 100644 --- a/build/pkgs/sagelib/install-requires.txt +++ b/build/pkgs/sagelib/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagelib ~= 10.1b4 +sagelib ~= 10.1b5 diff --git a/build/pkgs/sagemath_categories/install-requires.txt b/build/pkgs/sagemath_categories/install-requires.txt index f84b868badb..a8adae5a62d 100644 --- a/build/pkgs/sagemath_categories/install-requires.txt +++ b/build/pkgs/sagemath_categories/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-categories ~= 10.1b4 +sagemath-categories ~= 10.1b5 diff --git a/build/pkgs/sagemath_environment/install-requires.txt b/build/pkgs/sagemath_environment/install-requires.txt index 7bc9628f15a..f9e03a69316 100644 --- a/build/pkgs/sagemath_environment/install-requires.txt +++ b/build/pkgs/sagemath_environment/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-environment ~= 10.1b4 +sagemath-environment ~= 10.1b5 diff --git a/build/pkgs/sagemath_objects/install-requires.txt b/build/pkgs/sagemath_objects/install-requires.txt index 351d5cbe6f7..83bc3826a15 100644 --- a/build/pkgs/sagemath_objects/install-requires.txt +++ b/build/pkgs/sagemath_objects/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-objects ~= 10.1b4 +sagemath-objects ~= 10.1b5 diff --git a/build/pkgs/sagemath_repl/install-requires.txt b/build/pkgs/sagemath_repl/install-requires.txt index 9b633de75f0..77f2bab84c4 100644 --- a/build/pkgs/sagemath_repl/install-requires.txt +++ b/build/pkgs/sagemath_repl/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-repl ~= 10.1b4 +sagemath-repl ~= 10.1b5 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 8dc27b1ee06..a5c4d64bf3e 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.1.beta4 +10.1.beta5 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 8dc27b1ee06..a5c4d64bf3e 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.1.beta4 +10.1.beta5 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 8dc27b1ee06..a5c4d64bf3e 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.1.beta4 +10.1.beta5 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 8dc27b1ee06..a5c4d64bf3e 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.1.beta4 +10.1.beta5 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 8dc27b1ee06..a5c4d64bf3e 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.1.beta4 +10.1.beta5 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 8dc27b1ee06..a5c4d64bf3e 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.1.beta4 +10.1.beta5 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 8dc27b1ee06..a5c4d64bf3e 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.1.beta4 +10.1.beta5 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 8dc27b1ee06..a5c4d64bf3e 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.1.beta4 +10.1.beta5 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 8dc27b1ee06..a5c4d64bf3e 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.1.beta4 +10.1.beta5 diff --git a/src/VERSION.txt b/src/VERSION.txt index 8dc27b1ee06..a5c4d64bf3e 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.1.beta4 +10.1.beta5 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 6555188b84c..7c4069094c4 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -4,6 +4,6 @@ # which stops "setup.py develop" from rewriting it as a Python file. : # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='10.1.beta4' -SAGE_RELEASE_DATE='2023-06-21' -SAGE_VERSION_BANNER='SageMath version 10.1.beta4, Release Date: 2023-06-21' +SAGE_VERSION='10.1.beta5' +SAGE_RELEASE_DATE='2023-07-01' +SAGE_VERSION_BANNER='SageMath version 10.1.beta5, Release Date: 2023-07-01' diff --git a/src/sage/version.py b/src/sage/version.py index 8b362f1de6a..45c4a54f784 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '10.1.beta4' -date = '2023-06-21' -banner = 'SageMath version 10.1.beta4, Release Date: 2023-06-21' +version = '10.1.beta5' +date = '2023-07-01' +banner = 'SageMath version 10.1.beta5, Release Date: 2023-07-01' From bdfdab91dd232aec50df2c52e997d437118d09c5 Mon Sep 17 00:00:00 2001 From: Dave Witte Morris <Dave.Morris@uleth.ca> Date: Sat, 1 Jul 2023 19:06:08 -0600 Subject: [PATCH 213/228] issue 35860: correct parent for square root of constant polynomial --- src/sage/rings/laurent_series_ring_element.pyx | 8 ++++++++ src/sage/rings/polynomial/polynomial_element.pyx | 8 +++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/laurent_series_ring_element.pyx b/src/sage/rings/laurent_series_ring_element.pyx index 3fac79ca180..8e950478045 100644 --- a/src/sage/rings/laurent_series_ring_element.pyx +++ b/src/sage/rings/laurent_series_ring_element.pyx @@ -751,6 +751,14 @@ cdef class LaurentSeries(AlgebraElement): t^-3 + t^3 + O(t^9) ALGORITHM: Shift the unit parts to align them, then add. + + TESTS: + + Verify that :trac:`35860` is fixed:: + + sage: R.<t> = LaurentPolynomialRing(ZZ) + sage: sqrt(t^2) + t^-1 + t^-1 + t """ cdef LaurentSeries right = <LaurentSeries>right_m cdef long m diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 159d307605b..fcf63acf7fa 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -1988,6 +1988,12 @@ cdef class Polynomial(CommutativePolynomial): False sage: R(0).is_square() True + + Make sure :trac:`35860` is fixed:: + + sage: S.<x> = PolynomialRing(ZZ) + sage: is_square(S(1), True)[1].parent() + Univariate Polynomial Ring in x over Integer Ring """ if self.is_zero(): return (True, self) if root else True @@ -2000,7 +2006,7 @@ cdef class Polynomial(CommutativePolynomial): u = self._parent.base_ring()(f.unit()) if all(a[1] % 2 == 0 for a in f) and u.is_square(): - g = u.sqrt() + g = self._parent(u.sqrt()) for a in f: g *= a[0] ** (a[1] // 2) return (True, g) if root else True From 9193cbcb32137a99c938947b4d40a87d5d21f253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Sun, 2 Jul 2023 10:56:14 +0200 Subject: [PATCH 214/228] cython-lint:some care for groups/perm_gps --- .../automorphism_group_canonical_label.pyx | 16 +++-- .../partn_ref/canonical_augmentation.pyx | 3 +- .../perm_gps/partn_ref/data_structures.pyx | 47 ++++++++++----- .../perm_gps/partn_ref/double_coset.pyx | 20 ++++--- .../perm_gps/partn_ref/refinement_binary.pyx | 56 ++++++++++-------- .../perm_gps/partn_ref/refinement_graphs.pyx | 58 +++++++++++-------- .../perm_gps/partn_ref/refinement_lists.pyx | 7 ++- .../partn_ref/refinement_matrices.pyx | 35 ++++++----- .../perm_gps/partn_ref/refinement_python.pyx | 7 +-- .../perm_gps/partn_ref/refinement_sets.pyx | 21 +++---- .../groups/perm_gps/permgroup_element.pyx | 24 ++++---- 11 files changed, 169 insertions(+), 125 deletions(-) diff --git a/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx b/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx index 7cc848695d3..d174874194f 100644 --- a/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +++ b/src/sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx @@ -116,9 +116,12 @@ from .data_structures cimport * from sage.data_structures.bitset_base cimport * cdef inline int agcl_cmp(int a, int b): - if a < b: return -1 - elif a == b: return 0 - else: return 1 + if a < b: + return -1 + elif a == b: + return 0 + else: + return 1 # Functions @@ -212,9 +215,10 @@ cdef int compare_perms(int *gamma_1, int *gamma_2, void *S1, void *S2, int degre cdef list MS1 = <list> S1 cdef list MS2 = <list> S2 cdef int i, j - for i from 0 <= i < degree: + for i in range(degree): j = agcl_cmp(MS1[gamma_1[i]], MS2[gamma_2[i]]) - if j != 0: return j + if j != 0: + return j return 0 def coset_rep(list perm=[0,1,2,3,4,5], list gens=[[1,2,3,4,5,0]]): @@ -480,7 +484,7 @@ cdef aut_gp_and_can_lab *get_aut_gp_and_can_lab(void *S, cdef int i, j, k, ell, b cdef bint discrete, automorphism, update_label - cdef bint backtrack, new_vertex, narrow, mem_err = 0 + cdef bint backtrack, new_vertex, mem_err = 0 cdef aut_gp_and_can_lab *output cdef agcl_work_space *work_space diff --git a/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx b/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx index 41d132d8fb7..d6cc56d585a 100644 --- a/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +++ b/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx @@ -211,7 +211,8 @@ cdef void *canonical_generator_next(void *can_gen_data, int *degree, bint *mem_e aug, cgd.object_stack[cgd.level], &cgd.degree_stack[cgd.level], &cgd.mem_err) cgd.object_stack[cgd.level] = next_candidate - if cgd.mem_err: continue + if cgd.mem_err: + continue next_cand_deg = cgd.degree_stack[cgd.level] if cgd.agcl_work_spaces[cgd.level] is NULL: # allocate a work space if it hasn't been allocated already diff --git a/src/sage/groups/perm_gps/partn_ref/data_structures.pyx b/src/sage/groups/perm_gps/partn_ref/data_structures.pyx index 6707d26db3d..065c5f3365a 100644 --- a/src/sage/groups/perm_gps/partn_ref/data_structures.pyx +++ b/src/sage/groups/perm_gps/partn_ref/data_structures.pyx @@ -23,7 +23,7 @@ REFERENCES: # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** from libc.math cimport log, ceil @@ -134,7 +134,8 @@ def OP_represent(int n, merges, perm): if not OP_find(OP, i) == i: print("Failed at i = %d!" % i) good = False - if good: print("Each element reports itself as its root.") + if good: + print("Each element reports itself as its root.") print("Merging:") for i,j in merges: OP_join(OP, i, j) @@ -296,14 +297,16 @@ cdef int PS_first_smallest(PartitionStack *PS, bitset_t b, int *second_pos=NULL, n = i - j + 1 location = j j = i + 1 - if PS.levels[i] == -1: break + if PS.levels[i] == -1: + break i += 1 # location now points to the beginning of the first, smallest, # nontrivial cell i = location while 1: bitset_flip(b, PS.entries[i]) - if PS.levels[i] <= PS.depth: break + if PS.levels[i] <= PS.depth: + break i += 1 if second_pos != NULL: @@ -480,7 +483,8 @@ def PS_represent(partition, splits): if not PS.degree == n or not PS.depth == 0: print("Incorrect degree or depth!") good = False - if good: print("Everything seems in order, deallocating.") + if good: + print("Everything seems in order, deallocating.") PS_dealloc(PS) print("Deallocated.") print("Creating PartitionStack from partition %s."%partition) @@ -633,11 +637,13 @@ cdef inline int SC_realloc_gens(StabilizerChain *SC, int level, int size): cdef int n = SC.degree temp = <int *> sig_realloc( SC.generators[level], n * size * sizeof(int) ) - if temp is NULL: return 1 + if temp is NULL: + return 1 SC.generators[level] = temp temp = <int *> sig_realloc( SC.gen_inverses[level], n * size * sizeof(int) ) - if temp is NULL: return 1 + if temp is NULL: + return 1 SC.gen_inverses[level] = temp SC.array_size[level] = size @@ -751,7 +757,8 @@ cdef int SC_realloc_bitsets(StabilizerChain *SC, unsigned long size): Returns 1 in case of an allocation failure. """ cdef unsigned long size_old = SC.gen_used.size - if size <= size_old: return 0 + if size <= size_old: + return 0 cdef unsigned long new_size = size_old while new_size < size: new_size *= 2 @@ -1041,8 +1048,10 @@ cdef int SC_insert_and_sift(StabilizerChain *SC, int level, int *pi, int num_per break else: bitset_set(&SC.gen_is_id, perm_gen_index) - if b != -1: break - if b == -1: return 0 + if b != -1: + break + if b == -1: + return 0 if sift and level == SC.base_size: SC_add_base_point(SC, b) else: @@ -1064,18 +1073,22 @@ cdef int SC_insert_and_sift(StabilizerChain *SC, int level, int *pi, int num_per for i from 0 <= i < SC.orbit_sizes[level]: x = SC.base_orbits[level][i] for perm_gen_index from 0 <= perm_gen_index < num_perms: - if sift and bitset_check(&SC.gen_is_id, perm_gen_index): continue + if sift and bitset_check(&SC.gen_is_id, perm_gen_index): + continue perm = pi + n*perm_gen_index if SC.parents[level][perm[x]] == -1: # now we have an x which maps to a new point under perm, re_treed = 1 - if sift: bitset_set(&SC.gen_used, perm_gen_index) + if sift: + bitset_set(&SC.gen_used, perm_gen_index) if SC_re_tree(SC, level, perm, x): return 1 start_over = 1 # we must look anew break - if start_over: break - if not re_treed: continue + if start_over: + break + if not re_treed: + continue for perm_gen_index from 0 <= perm_gen_index < old_num_gens: perm = SC.generators[level] + n*perm_gen_index if SC.parents[level][perm[x]] == -1: @@ -1084,7 +1097,8 @@ cdef int SC_insert_and_sift(StabilizerChain *SC, int level, int *pi, int num_per return 1 start_over = 1 # we must look anew break - if start_over: break + if start_over: + break for j from level < j < SC.base_size: for perm_gen_index from 0 <= perm_gen_index < SC.num_gens[j]: perm = SC.generators[j] + n*perm_gen_index @@ -1361,7 +1375,8 @@ def SC_test_list_perms(list L, int n, int limit, bint gap, bint limit_complain, if gap: G = PermutationGroup([[i+1 for i in p] for p in L]) if G.order() > limit: - if limit_complain: print('TOO BIG') + if limit_complain: + print('TOO BIG') return SC = SC_new(n) cdef int *perm = <int *>sig_malloc(n * (len(L)+3) * sizeof(int)) diff --git a/src/sage/groups/perm_gps/partn_ref/double_coset.pyx b/src/sage/groups/perm_gps/partn_ref/double_coset.pyx index 1d8aa42c28d..56a97f6ece4 100644 --- a/src/sage/groups/perm_gps/partn_ref/double_coset.pyx +++ b/src/sage/groups/perm_gps/partn_ref/double_coset.pyx @@ -110,9 +110,10 @@ cdef int compare_perms(int *gamma_1, int *gamma_2, void *S1, void *S2, int degre cdef list MS1 = <list> S1 cdef list MS2 = <list> S2 cdef int i, j - for i from 0 <= i < degree: + for i in range(degree): j = int_cmp(MS1[gamma_1[i]], MS2[gamma_2[i]]) - if j != 0: return j + if j != 0: + return j return 0 def coset_eq(list perm1=[0,1,2,3,4,5], list perm2=[1,2,3,4,5,0], list gens=[[1,2,3,4,5,0]]): @@ -351,8 +352,8 @@ cdef int double_coset(void *S1, void *S2, PartitionStack *partition1, int *order cdef StabilizerChain *tmp_gp cdef int i, j, k, ell, b - cdef bint discrete, automorphism, update_label - cdef bint backtrack, new_vertex, narrow, mem_err = 0 + cdef bint automorphism + cdef bint new_vertex, mem_err = 0 if n == 0: return 0 @@ -591,7 +592,7 @@ cdef int double_coset(void *S1, void *S2, PartitionStack *partition1, int *order # (same!) primary orbit, then all children of the first # stack at this point are equivalent. j = 0 - for i from 0 <= i < n: + for i in range(n): if bitset_check(vertices_to_split[current_ps.depth], i): j += 1 if j == subgroup_primary_orbit_size and first_kids_are_same == current_ps.depth+1: @@ -608,7 +609,6 @@ cdef int double_coset(void *S1, void *S2, PartitionStack *partition1, int *order # II. Refine down to a discrete partition, or until # we leave the part of the tree we are interested in - discrete = 0 while True: i = current_ps.depth while True: @@ -642,7 +642,8 @@ cdef int double_coset(void *S1, void *S2, PartitionStack *partition1, int *order possible = 1 vertices_determining_current_stack[i] = j current_ps.depth -= 1 # reset for next refinement - else: break + else: + break if not possible: break if PS_is_discrete(current_ps): @@ -682,7 +683,7 @@ cdef int double_coset(void *S1, void *S2, PartitionStack *partition1, int *order index_in_fp_and_mcr += 1 bitset_zero(fixed_points_of_generators[index_in_fp_and_mcr]) bitset_zero(minimal_cell_reps_of_generators[index_in_fp_and_mcr]) - for i from 0 <= i < n: + for i in range(n): if permutation[i] == i: bitset_set(fixed_points_of_generators[index_in_fp_and_mcr], i) bitset_set(minimal_cell_reps_of_generators[index_in_fp_and_mcr], i) @@ -691,7 +692,8 @@ cdef int double_coset(void *S1, void *S2, PartitionStack *partition1, int *order k = i j = permutation[i] while j != i: - if j < k: k = j + if j < k: + k = j j = permutation[j] if k == i: bitset_set(minimal_cell_reps_of_generators[index_in_fp_and_mcr], i) diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx index d66eb088461..3616decd7e4 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx @@ -23,7 +23,7 @@ REFERENCE: # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** from sage.data_structures.bitset_base cimport * @@ -63,16 +63,18 @@ cdef class LinearBinaryCodeStruct(BinaryCodeStruct): raise MemoryError cdef bint memerr = 0 - for i from 0 <= i < self.dimension: - try: bitset_init(&self.basis[i], self.degree) + for i in range(self.dimension): + try: + bitset_init(&self.basis[i], self.degree) except MemoryError: for j from 0 <= j < i: bitset_free(&self.basis[j]) memerr = 1 break if not memerr: - for i from 0 <= i < 2*self.dimension+2: - try: bitset_init(&self.scratch_bitsets[i], self.degree) + for i in range(2*self.dimension+2): + try: + bitset_init(&self.scratch_bitsets[i], self.degree) except MemoryError: for j from 0 <= j < i: bitset_free(&self.scratch_bitsets[j]) @@ -81,7 +83,8 @@ cdef class LinearBinaryCodeStruct(BinaryCodeStruct): memerr = 1 break if not memerr: - try: bitset_init(self.alpha_is_wd, self.nwords + self.degree) + try: + bitset_init(self.alpha_is_wd, self.nwords + self.degree) except MemoryError: for j from 0 <= j < 2*self.dimension+2: bitset_free(&self.scratch_bitsets[j]) @@ -98,7 +101,7 @@ cdef class LinearBinaryCodeStruct(BinaryCodeStruct): for j from 0 <= j < self.dimension: bitset_zero(&self.basis[j]) - for i,j in matrix.nonzero_positions(): + for i, j in matrix.nonzero_positions(): bitset_set(&self.basis[i], j) self.output = NULL @@ -265,11 +268,11 @@ cdef class LinearBinaryCodeStruct(BinaryCodeStruct): if self.output is NULL: self.run() generators = [] - for i from 0 <= i < self.output.num_gens: + for i in range(self.output.num_gens): generators.append([self.output.generators[i*self.degree + j] for j from 0 <= j < self.degree]) order = Integer() SC_order(self.output.group, 0, order.value) - base = [self.output.group.base_orbits[i][0] for i from 0 <= i < self.output.group.base_size] + base = [self.output.group.base_orbits[i][0] for i in range(self.output.group.base_size)] return generators, order, base def canonical_relabeling(self): @@ -294,7 +297,7 @@ cdef class LinearBinaryCodeStruct(BinaryCodeStruct): cdef int i if self.output is NULL: self.run() - return [self.output.relabeling[i] for i from 0 <= i < self.degree] + return [self.output.relabeling[i] for i in range(self.degree)] def is_isomorphic(self, LinearBinaryCodeStruct other): """ @@ -322,7 +325,7 @@ cdef class LinearBinaryCodeStruct(BinaryCodeStruct): sig_free(ordering) sig_free(output) raise MemoryError - for i from 0 <= i < n: + for i in range(n): ordering[i] = i self.first_time = 1 other.first_time = 1 @@ -332,7 +335,7 @@ cdef class LinearBinaryCodeStruct(BinaryCodeStruct): PS_dealloc(part) sig_free(ordering) if isomorphic: - output_py = [output[i] for i from 0 <= i < n] + output_py = [output[i] for i in range(n)] else: output_py = False sig_free(output) @@ -391,16 +394,18 @@ cdef class NonlinearBinaryCodeStruct(BinaryCodeStruct): raise MemoryError cdef bint memerr = 0 - for i from 0 <= i < self.nwords: - try: bitset_init(&self.words[i], self.degree) + for i in range(self.nwords): + try: + bitset_init(&self.words[i], self.degree) except MemoryError: for j from 0 <= j < i: bitset_free(&self.words[j]) memerr = 1 break if not memerr: - for i from 0 <= i < 4*self.nwords: - try: bitset_init(&self.scratch_bitsets[i], self.degree) + for i in range(4*self.nwords): + try: + bitset_init(&self.scratch_bitsets[i], self.degree) except MemoryError: for j from 0 <= j < i: bitset_free(&self.scratch_bitsets[j]) @@ -409,7 +414,8 @@ cdef class NonlinearBinaryCodeStruct(BinaryCodeStruct): memerr = 1 break if not memerr: - try: bitset_init(&self.scratch_bitsets[4*self.nwords], self.nwords) + try: + bitset_init(&self.scratch_bitsets[4*self.nwords], self.nwords) except MemoryError: for j from 0 <= j < 4*self.nwords: bitset_free(&self.scratch_bitsets[j]) @@ -417,7 +423,8 @@ cdef class NonlinearBinaryCodeStruct(BinaryCodeStruct): bitset_free(&self.words[j]) memerr = 1 if not memerr: - try: bitset_init(self.alpha_is_wd, self.nwords + self.degree) + try: + bitset_init(self.alpha_is_wd, self.nwords + self.degree) except MemoryError: for j from 0 <= j < 4*self.nwords + 1: bitset_free(&self.scratch_bitsets[j]) @@ -435,7 +442,7 @@ cdef class NonlinearBinaryCodeStruct(BinaryCodeStruct): bitset_zero(&self.words[j]) if is_Matrix(arg): - for i,j in arg.nonzero_positions(): + for i, j in arg.nonzero_positions(): bitset_set(&self.words[i], j) self.output = NULL @@ -534,11 +541,11 @@ cdef class NonlinearBinaryCodeStruct(BinaryCodeStruct): if self.output is NULL: self.run() generators = [] - for i from 0 <= i < self.output.num_gens: + for i in range(self.output.num_gens): generators.append([self.output.generators[i*self.degree + j] for j from 0 <= j < self.degree]) order = Integer() SC_order(self.output.group, 0, order.value) - base = [self.output.group.base_orbits[i][0] for i from 0 <= i < self.output.group.base_size] + base = [self.output.group.base_orbits[i][0] for i in range(self.output.group.base_size)] return generators, order, base def canonical_relabeling(self): @@ -557,7 +564,7 @@ cdef class NonlinearBinaryCodeStruct(BinaryCodeStruct): cdef int i if self.output is NULL: self.run() - return [self.output.relabeling[i] for i from 0 <= i < self.degree] + return [self.output.relabeling[i] for i in range(self.degree)] def is_isomorphic(self, NonlinearBinaryCodeStruct other): """ @@ -585,7 +592,7 @@ cdef class NonlinearBinaryCodeStruct(BinaryCodeStruct): sig_free(ordering) sig_free(output) raise MemoryError - for i from 0 <= i < n: + for i in range(n): ordering[i] = i self.first_time = 1 other.first_time = 1 @@ -595,7 +602,7 @@ cdef class NonlinearBinaryCodeStruct(BinaryCodeStruct): PS_dealloc(part) sig_free(ordering) if isomorphic: - output_py = [output[i] for i from 0 <= i < n] + output_py = [output[i] for i in range(n)] else: output_py = False sig_free(output) @@ -1063,7 +1070,6 @@ def random_tests(num=50, n_max=50, k_max=6, nwords_max=200, perms_per_code=10, d sage: sage.groups.perm_gps.partn_ref.refinement_binary.random_tests() # long time (up to 5s on sage.math, 2012) All passed: ... random tests on ... codes. """ - from sage.misc.timing import walltime from sage.misc.prandom import random, randint from sage.combinat.permutation import Permutations from sage.matrix.constructor import random_matrix, matrix diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx index 1e1858891d3..17ddfce42db 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx @@ -105,12 +105,12 @@ def isomorphic(G1, G2, partn, ordering2, dig, use_indicator_function, sparse=Fal else: G = DenseGraph(n) if G_in.is_directed(): - for i,j in G_in.edge_iterator(labels=False): - G.add_arc(i,j) + for i, j in G_in.edge_iterator(labels=False): + G.add_arc(i, j) else: - for i,j in G_in.edge_iterator(labels=False): - G.add_arc(i,j) - G.add_arc(j,i) + for i, j in G_in.edge_iterator(labels=False): + G.add_arc(i, j) + G.add_arc(j, i) elif isinstance(G_in, CGraph): G = <CGraph> G_in if n == -1: @@ -118,18 +118,23 @@ def isomorphic(G1, G2, partn, ordering2, dig, use_indicator_function, sparse=Fal elif n != <int>G.num_verts: return False if not loops: - for i from 0 <= i < n: + for i in range(n): if G.has_arc_unsafe(i,i): loops = 1 to = {} - for a in G.verts(): to[a]=a + for a in G.verts(): + to[a] = a frm = to if first: partition = partn else: raise TypeError("G must be a Sage graph") - if first: frm1=frm;to1=to - else: frm2=frm;to2=to + if first: + frm1 = frm + to1 = to + else: + frm2 = frm + to2 = to GS.G = G GS.directed = 1 if dig else 0 GS.loops = 1 @@ -399,21 +404,22 @@ def search_tree(G_in, partition, lab=True, dig=False, dict_rep=False, certificat else: G = DenseGraph(n) if G_in.is_directed(): - for i,j in G_in.edge_iterator(labels=False): - G.add_arc(i,j) + for i, j in G_in.edge_iterator(labels=False): + G.add_arc(i, j) else: - for i,j in G_in.edge_iterator(labels=False): - G.add_arc(i,j) - G.add_arc(j,i) + for i, j in G_in.edge_iterator(labels=False): + G.add_arc(i, j) + G.add_arc(j, i) elif isinstance(G_in, CGraph): G = <CGraph> G_in n = G.num_verts loops = 0 - for i from 0 <= i < n: - if G.has_arc_unsafe(i,i): + for i in range(n): + if G.has_arc_unsafe(i, i): loops = 1 to = {} - for a in G.verts(): to[a]=a + for a in G.verts(): + to[a] = a frm = to else: raise TypeError("G must be a Sage graph") @@ -932,7 +938,8 @@ def orbit_partition(gamma, list_perm=False): l = [] for i in range(1,n+1): orb = gamma.orbit(i) - if orb not in l: l.append(orb) + if orb not in l: + l.append(orb) for i in l: for j in range(len(i)): if i[j] == n: @@ -1080,7 +1087,8 @@ cdef void *dg_edge_gen_next(void *data, int *degree, bint *mem_err): else: u = bitset_first(&edge_candidate.bits) v = bitset_next(&edge_candidate.bits, u+1) - if v == -1: v = u + if v == -1: + v = u if graph.G.has_arc_unsafe(u, v): reject = 1 if not reject: @@ -1350,7 +1358,8 @@ def generate_dense_graphs_edge_addition(int n, bint loops, G=None, depth=None, if construct: while True: thing = graph_iterator.next(graph_iterator.data, NULL, &mem_err) - if thing is NULL: break + if thing is NULL: + break ODG = (<GraphStruct>thing).G G = Graph(0, implementation='c_graph', sparse=False) DG = DenseGraph(ODG.active_vertices.size, extra_vertices=0) @@ -1360,7 +1369,8 @@ def generate_dense_graphs_edge_addition(int n, bint loops, G=None, depth=None, else: while True: thing = graph_iterator.next(graph_iterator.data, NULL, &mem_err) - if thing is NULL: break + if thing is NULL: + break number += 1 free_dg_edge_gen(graph_iterator) @@ -1625,7 +1635,8 @@ def generate_dense_graphs_vert_addition(int n, base_G=None, if construct: while True: thing = graph_iterator.next(graph_iterator.data, NULL, &mem_err) - if thing is NULL: break + if thing is NULL: + break ODG = (<GraphStruct>thing).G G = Graph(0, implementation='c_graph', sparse=False) DG = DenseGraph(ODG.active_vertices.size, extra_vertices=0) @@ -1635,7 +1646,8 @@ def generate_dense_graphs_vert_addition(int n, base_G=None, else: while True: thing = graph_iterator.next(graph_iterator.data, NULL, &mem_err) - if thing is NULL: break + if thing is NULL: + break number += 1 free_dg_vert_gen(graph_iterator) diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_lists.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_lists.pyx index 5d8e3ff032a..5942edd5438 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_lists.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_lists.pyx @@ -15,7 +15,7 @@ EXAMPLES:: # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** from cysignals.memory cimport sig_malloc, sig_free @@ -75,7 +75,8 @@ cdef int compare_lists(int *gamma_1, int *gamma_2, void *S1, void *S2, int degre cdef list MS1 = <list> S1 cdef list MS2 = <list> S2 cdef int i, j - for i from 0 <= i < degree: + for i in range(degree): j = int_cmp(MS1[gamma_1[i]], MS2[gamma_2[i]]) - if j != 0: return j + if j != 0: + return j return 0 diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_matrices.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_matrices.pyx index bb88ce09df5..e2388616a34 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_matrices.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_matrices.pyx @@ -23,7 +23,7 @@ REFERENCE: # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** from libc.string cimport memcmp @@ -59,7 +59,7 @@ cdef class MatrixStruct: PS_dealloc(self.temp_col_ps) raise MemoryError - for i from 0 <= i < self.nsymbols: + for i in range(self.nsymbols): num_rows[i] = 0 for row in self.matrix.rows(): row = set(row.list()) @@ -67,11 +67,11 @@ cdef class MatrixStruct: row.remove(0) for s in row: num_rows[self.symbols.index(s)] += 1 - for i from 0 <= i < self.nsymbols: + for i in range(self.nsymbols): S_temp = NonlinearBinaryCodeStruct( (self.degree, num_rows[i]) ) self.symbol_structs.append(S_temp) - for i from 0 <= i < self.nsymbols: + for i in range(self.nsymbols): num_rows[i] = 0 for row in self.matrix.rows(): row_list = row.list() @@ -118,7 +118,7 @@ cdef class MatrixStruct: cdef NonlinearBinaryCodeStruct S_temp for S in self.symbol_structs: S_temp = <NonlinearBinaryCodeStruct>S - for i from 0 <= i < S_temp.nwords: + for i in range(S_temp.nwords): print(bitset_string(&S_temp.words[i])) print(self.symbols[j]) print("") @@ -158,7 +158,7 @@ cdef class MatrixStruct: cdef int i, n = self.degree cdef PartitionStack *part cdef NonlinearBinaryCodeStruct S_temp - for i from 0 <= i < self.nsymbols: + for i in range(self.nsymbols): S_temp = <NonlinearBinaryCodeStruct> self.symbol_structs[i] S_temp.first_time = 1 @@ -197,11 +197,11 @@ cdef class MatrixStruct: if self.output is NULL: self.run() generators = [] - for i from 0 <= i < self.output.num_gens: + for i in range(self.output.num_gens): generators.append([self.output.generators[i*self.degree + j] for j from 0 <= j < self.degree]) order = Integer() SC_order(self.output.group, 0, order.value) - base = [self.output.group.base_orbits[i][0] for i from 0 <= i < self.output.group.base_size] + base = [self.output.group.base_orbits[i][0] for i in range(self.output.group.base_size)] return generators, order, base def canonical_relabeling(self): @@ -222,7 +222,7 @@ cdef class MatrixStruct: cdef int i if self.output is NULL: self.run() - return [self.output.relabeling[i] for i from 0 <= i < self.degree] + return [self.output.relabeling[i] for i in range(self.degree)] def is_isomorphic(self, MatrixStruct other): """ @@ -237,12 +237,12 @@ cdef class MatrixStruct: [0, 2, 4, 1, 3, 5] """ - cdef int i, j, n = self.degree + cdef int i, n = self.degree cdef int *output cdef int *ordering cdef PartitionStack *part cdef NonlinearBinaryCodeStruct S_temp - for i from 0 <= i < self.nsymbols: + for i in range(self.nsymbols): S_temp = self.symbol_structs[i] S_temp.first_time = 1 S_temp = other.symbol_structs[i] @@ -255,7 +255,7 @@ cdef class MatrixStruct: sig_free(ordering) sig_free(output) raise MemoryError - for i from 0 <= i < self.degree: + for i in range(self.degree): ordering[i] = i cdef bint isomorphic = double_coset(<void *> self, <void *> other, part, ordering, self.degree, &all_matrix_children_are_equivalent, &refine_matrix, &compare_matrices, NULL, NULL, output) @@ -263,7 +263,7 @@ cdef class MatrixStruct: PS_dealloc(part) sig_free(ordering) if isomorphic: - output_py = [output[i] for i from 0 <= i < self.degree] + output_py = [output[i] for i in range(self.degree)] else: output_py = False sig_free(output) @@ -271,7 +271,7 @@ cdef class MatrixStruct: cdef int refine_matrix(PartitionStack *PS, void *S, int *cells_to_refine_by, int ctrb_len): cdef MatrixStruct M = <MatrixStruct> S - cdef int i, temp_inv, invariant = 1 + cdef int temp_inv, invariant = 1 cdef bint changed = 1 while changed: PS_copy_from_to(PS, M.temp_col_ps) @@ -290,7 +290,7 @@ cdef int compare_matrices(int *gamma_1, int *gamma_2, void *S1, void *S2, int de cdef int i MM1 = Matrix(M1.base_ring(), M1.nrows(), M1.ncols(), sparse=M1.is_sparse()) MM2 = Matrix(M2.base_ring(), M2.nrows(), M2.ncols(), sparse=M2.is_sparse()) - for i from 0 <= i < degree: + for i in range(degree): MM1.set_column(i, M1.column(gamma_1[i])) MM2.set_column(i, M2.column(gamma_2[i])) rows1 = sorted(MM1.rows()) @@ -331,13 +331,12 @@ def random_tests(n=10, nrows_max=50, ncols_max=50, nsymbols_max=10, perms_per_ma sage: sage.groups.perm_gps.partn_ref.refinement_matrices.random_tests() # long time (up to 30s on sage.math, 2011) All passed: ... random tests on ... matrices. """ - from sage.misc.timing import walltime from sage.misc.prandom import random, randint from sage.combinat.permutation import Permutations from sage.matrix.constructor import random_matrix, matrix from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF from sage.arith.misc import next_prime - cdef int h, i, j, nrows, k, num_tests = 0, num_matrices = 0 + cdef int i, j, nrows, num_tests = 0, num_matrices = 0 cdef MatrixStruct M, N for m in range(n): p = random()*(density_range[1]-density_range[0]) + density_range[0] @@ -349,7 +348,7 @@ def random_tests(n=10, nrows_max=50, ncols_max=50, nsymbols_max=10, perms_per_ma M = MatrixStruct( MM ) M.run() - for i from 0 <= i < perms_per_matrix: + for i in range(perms_per_matrix): perm = [a-1 for a in list(S.random_element())] NN = matrix(GF(nsymbols), nrows, ncols) for j from 0 <= j < ncols: diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx index bf4eae44469..4d53f3a0332 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx @@ -471,7 +471,6 @@ def aut_gp_and_can_lab_python(S, partition, n, """ obj_wrapper = PythonObjectWrapper(S, all_children_are_equivalent, refine_and_return_invariant, compare_structures, n) cdef aut_gp_and_can_lab *output - cdef PythonPartitionStack Py_PS = PythonPartitionStack(n) cdef int i, j cdef Integer I @@ -486,11 +485,11 @@ def aut_gp_and_can_lab_python(S, partition, n, canonical_label, NULL, NULL, NULL) list_of_gens = [] - for i from 0 <= i < output.num_gens: - list_of_gens.append([output.generators[j+i*n] for j from 0 <= j < n]) + for i in range(output.num_gens): + list_of_gens.append([output.generators[j+i*n] for j in range(n)]) return_tuple = [list_of_gens] if canonical_label: - return_tuple.append([output.relabeling[i] for i from 0 <= i < n]) + return_tuple.append([output.relabeling[i] for i in range(n)]) if base: return_tuple.append([output.group.base_orbits[i][0] for i from 0 <= i < output.group.base_size]) if order: diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_sets.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_sets.pyx index 912c9a31a0d..04aed5a296b 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_sets.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_sets.pyx @@ -453,7 +453,7 @@ cdef int refine_set(PartitionStack *PS, void *S, int *cells_to_refine_by, int ct return 0 cdef subset *subset1 = <subset *> S cdef int *scratch = subset1.scratch - cdef int start, i, n = PS.degree, x + cdef int start, i, n = PS.degree start = 0 while start < n: i = 0 @@ -463,7 +463,7 @@ cdef int refine_set(PartitionStack *PS, void *S, int *cells_to_refine_by, int ct break i += 1 sort_by_function(PS, start, scratch) - start += i+1 + start += i + 1 return 0 cdef inline int _bint_cmp(bint a, bint b): @@ -478,9 +478,10 @@ cdef int compare_sets(int *gamma_1, int *gamma_2, void *S1, void *S2, int degree cdef bitset_s set1 = subset1.bits cdef bitset_s set2 = subset2.bits cdef int i, j - for i from 0 <= i < degree: + for i in range(degree): j = _bint_cmp(bitset_in(&set1, gamma_1[i]), bitset_in(&set2, gamma_2[i])) - if j != 0: return j + if j != 0: + return j return 0 cdef void *allocate_subset(int n): @@ -554,12 +555,11 @@ cdef int generate_child_subsets(void *S, aut_gp_and_can_lab *group, iterator *ch Sets up an iterator of augmentations, i.e., elements to add to the given set. """ cdef subset *subset1 = <subset *> S - cdef bitset_s set1 = subset1.bits cdef int i, j, n = group.group.degree cdef subset_generator_data *sgd = <subset_generator_data *> child_iterator.data OP_clear(sgd.orbits) - for i from 0 <= i < group.num_gens: - for j from 0 <= j < n: + for i in range(group.num_gens): + for j in range(n): OP_join(sgd.orbits, j, group.generators[n*i + j]) i = bitset_first(&subset1.bits) j = bitset_next(&subset1.bits, i+1) @@ -594,7 +594,6 @@ cdef void *canonical_set_parent(void *child, void *parent, int *permutation, int storing the result to ``parent``. """ cdef subset *set1 = <subset *> child - cdef bitset_t can_par cdef int i, max_in_can_lab, max_loc, n = set1.bits.size cdef subset *par if parent is NULL: @@ -659,7 +658,8 @@ cdef void free_subset_gen(iterator *subset_gen): r""" Frees the iterator of subsets. """ - if subset_gen is NULL: return + if subset_gen is NULL: + return cdef canonical_generator_data *cgd = <canonical_generator_data *> subset_gen.data deallocate_cgd(cgd) sig_free(subset_gen) @@ -844,7 +844,8 @@ def sets_modulo_perm_group(list generators, int max_size, start_canonical_generator(group, NULL, n, subset_gen) while not mem_err: thing = <subset *> subset_iterator.next(subset_iterator.data, NULL, &mem_err) - if thing is NULL: break + if thing is NULL: + break out_list.append( bitset_list(&thing.bits) ) free_subset_gen(subset_gen) SC_dealloc(group) diff --git a/src/sage/groups/perm_gps/permgroup_element.pyx b/src/sage/groups/perm_gps/permgroup_element.pyx index ee17c6c9655..efc5e502cc0 100644 --- a/src/sage/groups/perm_gps/permgroup_element.pyx +++ b/src/sage/groups/perm_gps/permgroup_element.pyx @@ -451,7 +451,6 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): ValueError: permutation (1,2) not in Permutation Group with generators [(1,2,3)] """ cdef int i, degree = parent.degree() - cdef PermutationGroupElement g_pge self._parent = parent self._alloc(degree) @@ -1572,8 +1571,9 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): cdef int cycle_len cdef int i, k cdef bint* seen = <bint *>sig_malloc(sizeof(bint) * self.n) - for i from 0 <= i < self.n: seen[i] = 0 - for i from 0 <= i < self.n: + for i in range(self.n): + seen[i] = 0 + for i in range(self.n): if seen[i] or self.perm[i] == i: continue k = self.perm[i] @@ -1646,8 +1646,9 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): cdef int cycle_len_sum = 0 cdef int i, k cdef bint* seen = <bint *>sig_malloc(sizeof(bint) * self.n) - for i from 0 <= i < self.n: seen[i] = 0 - for i from 0 <= i < self.n: + for i in range(self.n): + seen[i] = 0 + for i in range(self.n): if seen[i] or self.perm[i] == i: continue k = self.perm[i] @@ -1721,12 +1722,14 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): cdef PermutationGroupElement cycle cdef int i, j, k, next_k cdef bint* seen = <bint *>sig_malloc(sizeof(bint) * self.n) - for i from 0 <= i < self.n: seen[i] = 0 - for i from 0 <= i < self.n: + for i in range(self.n): + seen[i] = 0 + for i in range(self.n): if seen[i] or self.perm[i] == i: continue cycle = self._new_c() - for j from 0 <= j < self.n: cycle.perm[j] = j + for j in range(self.n): + cycle.perm[j] = j k = cycle.perm[i] = self.perm[i] while k != i: seen[k] = 1 @@ -1772,8 +1775,9 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): L = [] cdef int i, k cdef bint* seen = <bint *>sig_malloc(sizeof(bint) * self.n) - for i from 0 <= i < self.n: seen[i] = 0 - for i from 0 <= i < self.n: + for i in range(self.n): + seen[i] = 0 + for i in range(self.n): if seen[i]: continue if self.perm[i] == i: From e1c34dd752fd47da8fbe8febda465dd7191f2858 Mon Sep 17 00:00:00 2001 From: Max Horn <max@quendi.de> Date: Mon, 19 Jun 2023 09:01:10 +0200 Subject: [PATCH 215/228] gap: stop using T_CHAR --- src/sage/libs/gap/element.pyx | 6 +++--- src/sage/libs/gap/gap_includes.pxd | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index 6341a37c85f..c8a4bc52a19 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -262,9 +262,9 @@ cdef GapElement make_any_gap_element(parent, Obj obj): TESTS:: - sage: T_CHAR = libgap.eval("'c'"); T_CHAR + sage: x = libgap.eval("'c'"); x "c" - sage: type(T_CHAR) + sage: type(x) <class 'sage.libs.gap.element.GapElement_String'> sage: libgap.eval("['a', 'b', 'c']") # gap strings are also lists of chars @@ -320,7 +320,7 @@ cdef GapElement make_any_gap_element(parent, Obj obj): return make_GapElement_String(parent, obj) elif GAP_IsList(obj): return make_GapElement_List(parent, obj) - elif num == T_CHAR: + elif GAP_ValueOfChar(obj) != -1: ch = make_GapElement(parent, obj).IntChar().sage() return make_GapElement_String(parent, make_gap_string(chr(ch))) result = make_GapElement(parent, obj) diff --git a/src/sage/libs/gap/gap_includes.pxd b/src/sage/libs/gap/gap_includes.pxd index 8198ef5b6bb..6c6c37f58c0 100644 --- a/src/sage/libs/gap/gap_includes.pxd +++ b/src/sage/libs/gap/gap_includes.pxd @@ -116,7 +116,6 @@ cdef extern from "gap/objects.h" nogil: T_PERM2 T_PERM4 T_BOOL - T_CHAR T_FUNCTION T_COMOBJ T_POSOBJ From 648f21bddd2458cac03b589b26856a55c7708b3f Mon Sep 17 00:00:00 2001 From: Vincent Neiger <vneiger@users.noreply.github.com> Date: Sun, 2 Jul 2023 13:10:01 +0200 Subject: [PATCH 216/228] fix leftover from previous version --- src/sage/matrix/matrix_polynomial_dense.pyx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/matrix/matrix_polynomial_dense.pyx b/src/sage/matrix/matrix_polynomial_dense.pyx index 4ed1ef549ef..532350bdc66 100644 --- a/src/sage/matrix/matrix_polynomial_dense.pyx +++ b/src/sage/matrix/matrix_polynomial_dense.pyx @@ -1671,7 +1671,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): for pos in leading_positions] # leading positions should not have duplicates, which is equivalent to: # once sorted, it doesn't contain a pair of equal successive entries - # (we do not sort if we want to test if not ordered: leading_positions.sort() # check that there is no zero vector, if it is forbidden From 5f897675839fa217226ef5de09bbfe21bb6d35ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Sun, 2 Jul 2023 13:38:26 +0200 Subject: [PATCH 217/228] various cython-lint fixes in algebras,arith,calculus,categories --- .../free_algebra_element_letterplace.pyx | 2 -- .../letterplace/free_algebra_letterplace.pyx | 4 ++-- src/sage/algebras/octonion_algebra.pyx | 13 ++++++------- .../quatalg/quaternion_algebra_element.pxd | 6 +++--- src/sage/arith/functions.pxd | 1 - src/sage/arith/multi_modular.pxd | 2 +- src/sage/arith/multi_modular.pyx | 7 ++----- src/sage/calculus/interpolation.pyx | 6 +++--- src/sage/calculus/interpolators.pyx | 8 ++++++-- src/sage/calculus/ode.pxd | 2 -- src/sage/calculus/ode.pyx | 15 ++++----------- src/sage/calculus/riemann.pyx | 12 +++++++----- src/sage/calculus/transforms/dwt.pyx | 5 ++++- src/sage/calculus/transforms/fft.pyx | 17 +++++++++-------- src/sage/categories/functor.pyx | 7 +++---- 15 files changed, 50 insertions(+), 57 deletions(-) diff --git a/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx b/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx index 3dabaa2a798..9029a8b07a5 100644 --- a/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx +++ b/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx @@ -164,7 +164,6 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): """ cdef list L = [] cdef FreeAlgebra_letterplace P = self._parent - cdef int ngens = P.__ngens if P._base._repr_option('element_is_atomic'): for E, c in zip(self._poly.exponents(), self._poly.coefficients()): monstr = P.exponents_to_string(E) @@ -239,7 +238,6 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): """ cdef list L = [] cdef FreeAlgebra_letterplace P = self._parent - cdef int ngens = P.__ngens from sage.misc.latex import latex if P._base._repr_option('element_is_atomic'): for E, c in zip(self._poly.exponents(), self._poly.coefficients()): diff --git a/src/sage/algebras/letterplace/free_algebra_letterplace.pyx b/src/sage/algebras/letterplace/free_algebra_letterplace.pyx index 365f5a218fe..ab158fdf5ec 100644 --- a/src/sage/algebras/letterplace/free_algebra_letterplace.pyx +++ b/src/sage/algebras/letterplace/free_algebra_letterplace.pyx @@ -594,7 +594,7 @@ cdef class FreeAlgebra_letterplace(Algebra): cdef list tmp for i from 0<=i<nblocks: base = i*ngens - tmp = [(j,E[base+j]) for j in range(ngens) if E[base+j]] + tmp = [(j, E[base+j]) for j in range(ngens) if E[base+j]] if not tmp: continue var_ind, exp = tmp[0] @@ -627,7 +627,7 @@ cdef class FreeAlgebra_letterplace(Algebra): cdef list names = self.latex_variable_names() for i from 0<=i<nblocks: base = i*ngens - tmp = [(j,E[base+j]) for j in range(ngens) if E[base+j]] + tmp = [(j, E[base+j]) for j in range(ngens) if E[base+j]] if not tmp: continue var_ind, exp = tmp[0] diff --git a/src/sage/algebras/octonion_algebra.pyx b/src/sage/algebras/octonion_algebra.pyx index 562867f0023..18101c48f66 100644 --- a/src/sage/algebras/octonion_algebra.pyx +++ b/src/sage/algebras/octonion_algebra.pyx @@ -389,7 +389,6 @@ cdef class Octonion_generic(AlgebraElement): 0 """ cdef int i - a, b, c = self._parent._params cdef tuple table = self._parent._mult_table ret = self.vec.get_unsafe(0) ** 2 for i in range(1, 8): @@ -782,13 +781,13 @@ class OctonionAlgebra(UniqueRepresentation, Parent): g = a * b * c self._mult_table = ( ((0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (6, 1), (7, 1)), - ((1, 1), (0, a), (3,-1), (2,-a), (5,-1), (4,-a), (7, 1), (6, a)), - ((2, 1), (3, 1), (0, b), (1, b), (6,-1), (7,-1), (4,-b), (5,-b)), - ((3, 1), (2, a), (1,-b), (0,-d), (7,-1), (6,-a), (5, b), (4, d)), + ((1, 1), (0, a), (3, -1), (2, -a), (5, -1), (4, -a), (7, 1), (6, a)), + ((2, 1), (3, 1), (0, b), (1, b), (6, -1), (7, -1), (4, -b), (5, -b)), + ((3, 1), (2, a), (1, -b), (0, -d), (7, -1), (6, -a), (5, b), (4, d)), ((4, 1), (5, 1), (6, 1), (7, 1), (0, c), (1, c), (2, c), (3, c)), - ((5, 1), (4, a), (7, 1), (6, a), (1,-c), (0,-e), (3,-c), (2,-e)), - ((6, 1), (7,-1), (4, b), (5,-b), (2,-c), (3, c), (0,-f), (1, f)), - ((7, 1), (6,-a), (5, b), (4,-d), (3,-c), (2, e), (1,-f), (0, g)), + ((5, 1), (4, a), (7, 1), (6, a), (1, -c), (0, -e), (3, -c), (2, -e)), + ((6, 1), (7, -1), (4, b), (5, -b), (2, -c), (3, c), (0, -f), (1, f)), + ((7, 1), (6, -a), (5, b), (4, -d), (3, -c), (2, e), (1, -f), (0, g)), ) def _test_alternative(self, **options): diff --git a/src/sage/algebras/quatalg/quaternion_algebra_element.pxd b/src/sage/algebras/quatalg/quaternion_algebra_element.pxd index 8ffc4722d9c..243cae8e222 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra_element.pxd +++ b/src/sage/algebras/quatalg/quaternion_algebra_element.pxd @@ -8,15 +8,15 @@ from sage.categories.morphism cimport Morphism cdef class QuaternionAlgebraElement_abstract(AlgebraElement): cpdef bint is_constant(self) - cdef _do_print(self, x,y,z,w) + cdef _do_print(self, x, y, z, w) cpdef conjugate(self) cpdef reduced_norm(self) cpdef reduced_trace(self) cdef class QuaternionAlgebraElement_generic(QuaternionAlgebraElement_abstract): cdef object x, y, z, w - # we will assume that our element has the representation - # x + yi + zj + wk, where i^2 = a, j^2 = b + # we will assume that our element has the representation + # x + yi + zj + wk, where i^2 = a, j^2 = b cdef class QuaternionAlgebraElement_number_field(QuaternionAlgebraElement_abstract): cdef fmpz_poly_t x, y, z, w, a, b, modulus diff --git a/src/sage/arith/functions.pxd b/src/sage/arith/functions.pxd index b883b489be1..9ddfc38b38b 100644 --- a/src/sage/arith/functions.pxd +++ b/src/sage/arith/functions.pxd @@ -1,4 +1,3 @@ cpdef LCM_list(v) cdef LCM_generic(itr, ret) - diff --git a/src/sage/arith/multi_modular.pxd b/src/sage/arith/multi_modular.pxd index ca7a95581e7..2b2dae1c7d9 100644 --- a/src/sage/arith/multi_modular.pxd +++ b/src/sage/arith/multi_modular.pxd @@ -4,7 +4,7 @@ from sage.libs.gmp.types cimport mpz_t cdef class MultiModularBasis_base(): cdef int n cdef mod_int* moduli - cdef mpz_t* partial_products + cdef mpz_t* partial_products cdef mod_int* C # precomputed values for CRT cdef mpz_t product cdef mpz_t half_product diff --git a/src/sage/arith/multi_modular.pyx b/src/sage/arith/multi_modular.pyx index 17505583fca..50b79b016c1 100644 --- a/src/sage/arith/multi_modular.pyx +++ b/src/sage/arith/multi_modular.pyx @@ -194,7 +194,6 @@ cdef class MultiModularBasis_base(): the allowed interval; we will not return a prime in known_primes. """ - cdef Py_ssize_t i cdef mod_int p while True: if len(known_primes) >= self._num_primes: @@ -372,11 +371,10 @@ cdef class MultiModularBasis_base(): return self.n # find new prime moduli - cdef int i new_moduli = [] new_partial_products = [] - cdef Integer M # keeps current height - cdef mod_int p # keeps current prime moduli + cdef Integer M # keeps current height + cdef mod_int p # keeps current prime moduli if self.n == 0: M = smallInteger(1) @@ -633,7 +631,6 @@ cdef class MultiModularBasis_base(): if mpz_cmp(z[j], self.half_product) > 0: mpz_sub(z[j], z[j], self.product) - cdef Integer zz zz = PY_NEW(Integer) mpz_set(zz.value, self.half_product) diff --git a/src/sage/calculus/interpolation.pyx b/src/sage/calculus/interpolation.pyx index e703f78d7c0..e31d3606cc4 100644 --- a/src/sage/calculus/interpolation.pyx +++ b/src/sage/calculus/interpolation.pyx @@ -92,7 +92,7 @@ cdef class Spline: ... ValueError: Order of derivative must be 1 or 2. """ - def __init__(self, v=[]): + def __init__(self, v=None): """ EXAMPLES:: @@ -101,7 +101,7 @@ cdef class Spline: sage: type(S) <class 'sage.calculus.interpolation.Spline'> """ - self.v = list(v) + self.v = [] if v is None else list(v) self.started = 0 def __dealloc__(self): @@ -136,7 +136,7 @@ cdef class Spline: self.v[i] = xy else: for j from len(self.v) <= j <= i: - self.v.append((0,0)) + self.v.append((0, 0)) self.v[i] = xy self.stop_interp() diff --git a/src/sage/calculus/interpolators.pyx b/src/sage/calculus/interpolators.pyx index 124b9a6f909..ded37516d62 100644 --- a/src/sage/calculus/interpolators.pyx +++ b/src/sage/calculus/interpolators.pyx @@ -29,6 +29,7 @@ cimport numpy as np from math import pi cdef double TWOPI = 2*pi + def polygon_spline(pts): """ Creates a polygon from a set of complex or `(x,y)` points. The polygon @@ -61,6 +62,7 @@ def polygon_spline(pts): """ return PSpline(pts) + cdef class PSpline: """ A ``CCSpline`` object contains a polygon interpolation of a figure @@ -160,6 +162,7 @@ cdef class PSpline: pt2 = self.pts[(int(t1) + 1) % self.N] return (pt2 - pt1) * self.N / TWOPI + def complex_cubic_spline(pts): """ Creates a cubic spline interpolated figure from a set of complex or @@ -192,6 +195,7 @@ def complex_cubic_spline(pts): """ return CCSpline(pts) + cdef class CCSpline: """ A ``CCSpline`` object contains a cubic interpolation of a figure @@ -209,7 +213,7 @@ cdef class CCSpline: (0.9549296...-0.9549296...j) """ cdef int N - cdef np.ndarray avec,bvec,cvec,dvec + cdef np.ndarray avec, bvec, cvec, dvec #standard cubic interpolation method def __init__(self, pts): @@ -222,7 +226,7 @@ cdef class CCSpline: if isinstance(pts[0], tuple): pts = np.array( [complex(pt[0], pt[1]) for pt in pts], dtype=np.complex128) - cdef int N, i, k + cdef int N, i N = len(pts) yvec = np.zeros(N, dtype=np.complex128) for i in range(N): diff --git a/src/sage/calculus/ode.pxd b/src/sage/calculus/ode.pxd index a897f33b16e..e517fe0c401 100644 --- a/src/sage/calculus/ode.pxd +++ b/src/sage/calculus/ode.pxd @@ -1,6 +1,4 @@ cdef class ode_system: cdef int c_j(self,double , double *, double *,double *) - cdef int c_f(self,double t, double* , double* ) - diff --git a/src/sage/calculus/ode.pyx b/src/sage/calculus/ode.pyx index 544556ddf72..ea26f16998a 100644 --- a/src/sage/calculus/ode.pyx +++ b/src/sage/calculus/ode.pyx @@ -435,7 +435,6 @@ class ode_solver(): wrapper.the_parameters = self.params wrapper.y_n = dim - cdef double t cdef double t_end cdef double *y @@ -477,14 +476,12 @@ class ode_solver(): else: raise TypeError("algorithm not valid") - cdef gsl_odeiv_step * s s = gsl_odeiv_step_alloc (T, dim) if s==NULL: sig_free(y) raise MemoryError("error setting up solver") - cdef gsl_odeiv_control * c if not self.a and not self.a_dydt: @@ -506,7 +503,6 @@ class ode_solver(): sig_free(scale_abs_array) raise MemoryError("error setting up solver") - cdef gsl_odeiv_evolve * e e = gsl_odeiv_evolve_alloc(dim) @@ -517,7 +513,6 @@ class ode_solver(): sig_free(scale_abs_array) raise MemoryError("error setting up solver") - cdef gsl_odeiv_system sys if type: # The user has passed a class with a compiled function, use that for the system sys.function = c_f_compiled @@ -530,7 +525,6 @@ class ode_solver(): sys.params = <void *> wrapper sys.dimension = dim - cdef int status import copy cdef int n @@ -592,12 +586,11 @@ class ode_solver(): sig_free(scale_abs_array) raise ValueError("error solving") - for j from 0<=j<dim: - v[j]=<double> y[j] - result.append( (t,copy.copy(v)) ) - - t=self.t_span[i] + for j in range(dim): + v[j] = <double> y[j] + result.append((t, copy.copy(v))) + t = self.t_span[i] gsl_odeiv_evolve_free (e) gsl_odeiv_control_free (c) diff --git a/src/sage/calculus/riemann.pyx b/src/sage/calculus/riemann.pyx index 5350f04e707..46e2964eade 100644 --- a/src/sage/calculus/riemann.pyx +++ b/src/sage/calculus/riemann.pyx @@ -293,7 +293,9 @@ cdef class Riemann_Map: cdef _generate_theta_array(self): """ Generates the essential data for the Riemann map, primarily the - Szego kernel and boundary correspondence. See [KT1986]_ for the algorithm. + Szegő kernel and boundary correspondence. + + See [KT1986]_ for the algorithm. TESTS:: @@ -301,16 +303,16 @@ cdef class Riemann_Map: sage: fprime(t) = I*e^(I*t) + 0.5*I*e^(-I*t) sage: m = Riemann_Map([f], [fprime], 0, N = 10) """ - cdef np.ndarray[COMPLEX_T,ndim =1] cp = self.cps.flatten() - cdef np.ndarray[COMPLEX_T,ndim =1] dp = self.dps.flatten() + cdef np.ndarray[COMPLEX_T, ndim=1] cp = self.cps.flatten() + cdef np.ndarray[COMPLEX_T, ndim=1] dp = self.dps.flatten() cdef int N = self.N cdef int NB = N * self.B cdef int B = self.B cdef int i, k cdef FLOAT_T saa, t0 cdef np.ndarray[FLOAT_T, ndim=1] adp, sadp - cdef np.ndarray[COMPLEX_T,ndim =1] h, hconj, g, normalized_dp, C, phi - cdef np.ndarray[COMPLEX_T,ndim =2] K + cdef np.ndarray[COMPLEX_T, ndim=1] h, hconj, g, normalized_dp, C, phi + cdef np.ndarray[COMPLEX_T, ndim=2] K cdef np.ndarray[FLOAT_T, ndim=2] theta_array # Setting things up to use the Nystrom method adp = abs(dp) diff --git a/src/sage/calculus/transforms/dwt.pyx b/src/sage/calculus/transforms/dwt.pyx index 61e0f83d331..9296afb7824 100644 --- a/src/sage/calculus/transforms/dwt.pyx +++ b/src/sage/calculus/transforms/dwt.pyx @@ -21,6 +21,7 @@ AUTHOR: # https://www.gnu.org/licenses/ # **************************************************************************** + def WaveletTransform(n, wavelet_type, wavelet_k): r""" This function initializes an GSLDoubleArray of length n which @@ -94,8 +95,10 @@ def WaveletTransform(n, wavelet_type, wavelet_k): raise NotImplementedError("discrete wavelet transform only implemented when n is a 2-power") return DiscreteWaveletTransform(_n,1,wavelet_type,_k) + DWT = WaveletTransform + cdef class DiscreteWaveletTransform(GSLDoubleArray): """ Discrete wavelet transform class. @@ -151,6 +154,6 @@ cdef class DiscreteWaveletTransform(GSLDoubleArray): def is2pow(unsigned int n): - while n != 0 and n%2 == 0: + while n and not n % 2: n = n >> 1 return n == 1 diff --git a/src/sage/calculus/transforms/fft.pyx b/src/sage/calculus/transforms/fft.pyx index f0df57f05ec..05db8f5e3e7 100644 --- a/src/sage/calculus/transforms/fft.pyx +++ b/src/sage/calculus/transforms/fft.pyx @@ -77,8 +77,10 @@ def FastFourierTransform(size, base_ring=None): """ return FastFourierTransform_complex(int(size)) + FFT = FastFourierTransform + cdef class FastFourierTransform_base: pass @@ -250,15 +252,15 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): cdef int i v = [] - pi = sage.symbolic.constants.pi.n() - I = sage.symbolic.constants.I.n() - s = 1/(3*pi) # so arg gets scaled between -1/3 and 1/3. + pi = sage.symbolic.constants.pi.n() + I = sage.symbolic.constants.I.n() + s = 1/(3*pi) # so arg gets scaled between -1/3 and 1/3 for i from xmin <= i < xmax: z = self.data[2*i] + I*self.data[2*i+1] mag = z.abs() arg = z.arg()*s - v.append(point((i,mag), hue=arg, **args)) + v.append(point((i, mag), hue=arg, **args)) return sum(v) def _plot_rect(self, xmin, xmax, **args): @@ -282,18 +284,17 @@ cdef class FastFourierTransform_complex(FastFourierTransform_base): sage: a = FastFourierTransform(4) sage: a._plot_rect(0,3) Graphics object consisting of 3 graphics primitives - """ cdef int i - cdef double pr_x, x, h + cdef double x, h v = [] point = sage.plot.all.point - for i from xmin <= i < xmax: + for i in range(xmin, xmax): x = self.data[2*i] h = self.data[2*i+1] - v.append(point((i,x), hue=h, **args)) + v.append(point((i, x), hue=h, **args)) return sum(v) def plot(self, style='rect', xmin=None, xmax=None, **args): diff --git a/src/sage/categories/functor.pyx b/src/sage/categories/functor.pyx index 58ff4cb21bf..823d3a2132f 100644 --- a/src/sage/categories/functor.pyx +++ b/src/sage/categories/functor.pyx @@ -55,7 +55,7 @@ def _Functor_unpickle(Cl, D, domain, codomain): """ F = Functor.__new__(Cl) - Functor.__init__(F,domain,codomain) + Functor.__init__(F, domain, codomain) for s, v in D: setattr(F, s, v) return F @@ -268,12 +268,11 @@ cdef class Functor(SageObject): Defn: a |--> 4*a + 1 sage: fF((a^2+a)*t^2/(a*t - a^2)) # optional - sage.rings.finite_rings ((4*a + 2)*t^2)/(t + a + 4) - """ try: return self(f.domain()).hom(f, self(f.codomain())) except Exception: - raise TypeError('unable to transform %s into a morphism in %s' % (f,self.codomain())) + raise TypeError(f'unable to transform {f} into a morphism in {self.codomain()}') def _coerce_into_domain(self, x): """ @@ -541,7 +540,7 @@ class ForgetfulFunctor_generic(Functor): sage: F1 != QQ True """ - return not self == other + return not self == other class IdentityFunctor_generic(ForgetfulFunctor_generic): From 68826a45d3b590440ac180f54b086616099baf11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Sun, 2 Jul 2023 14:10:11 +0200 Subject: [PATCH 218/228] cylint: some fixes in combinat/(crystals,matrices,words) --- src/sage/combinat/crystals/letters.pyx | 3 ++ src/sage/combinat/crystals/pbw_datum.pxd | 1 - src/sage/combinat/crystals/pbw_datum.pyx | 12 ++++--- src/sage/combinat/crystals/spins.pxd | 1 - src/sage/combinat/crystals/spins.pyx | 10 ++++-- .../crystals/tensor_product_element.pxd | 1 - .../crystals/tensor_product_element.pyx | 4 +-- src/sage/combinat/matrices/dancing_links.pyx | 31 +++++++++---------- src/sage/combinat/words/word_char.pyx | 10 +++--- src/sage/combinat/words/word_datatypes.pxd | 1 - src/sage/combinat/words/word_datatypes.pyx | 14 +++------ 11 files changed, 45 insertions(+), 43 deletions(-) diff --git a/src/sage/combinat/crystals/letters.pyx b/src/sage/combinat/crystals/letters.pyx index 36edb9c8f86..921be80c434 100644 --- a/src/sage/combinat/crystals/letters.pyx +++ b/src/sage/combinat/crystals/letters.pyx @@ -319,6 +319,7 @@ class ClassicalCrystalOfLetters(UniqueRepresentation, Parent): # temporary workaround while an_element is overridden by Parent _an_element_ = EnumeratedSets.ParentMethods._an_element_ + # Utility. Note: much of this class should be factored out at some point! cdef class Letter(Element): r""" @@ -2571,6 +2572,7 @@ class CrystalOfBKKLetters(ClassicalCrystalOfLetters): Element = BKKLetter + ################# # Type q(n) queer ################# @@ -2981,6 +2983,7 @@ cdef class LetterWrapped(Element): """ return self.value.phi(i) + class ClassicalCrystalOfLettersWrapped(ClassicalCrystalOfLetters): r""" Crystal of letters by wrapping another crystal. diff --git a/src/sage/combinat/crystals/pbw_datum.pxd b/src/sage/combinat/crystals/pbw_datum.pxd index 039c197ea90..9c3aab083df 100644 --- a/src/sage/combinat/crystals/pbw_datum.pxd +++ b/src/sage/combinat/crystals/pbw_datum.pxd @@ -1,4 +1,3 @@ cpdef tuple compute_new_lusztig_datum(list enhanced_braid_chain, initial_lusztig_datum) cpdef tuple tropical_plucker_relation(tuple a, lusztig_datum) cpdef list enhance_braid_move_chain(braid_move_chain, cartan_type) - diff --git a/src/sage/combinat/crystals/pbw_datum.pyx b/src/sage/combinat/crystals/pbw_datum.pyx index 5dbdf59d722..dd27d91294a 100644 --- a/src/sage/combinat/crystals/pbw_datum.pyx +++ b/src/sage/combinat/crystals/pbw_datum.pyx @@ -30,6 +30,7 @@ from sage.combinat.root_system.braid_move_calculator import BraidMoveCalculator cimport cython + class PBWDatum(): """ Helper class which represents a PBW datum. @@ -277,7 +278,8 @@ class PBWData(): # UniqueRepresentation? w0 = self.weyl_group.long_element() return tuple([i] + (si * w0).reduced_word()) -#enhanced_braid_chain is an ugly data structure. + +# enhanced_braid_chain is an ugly data structure. @cython.boundscheck(False) @cython.wraparound(False) cpdef tuple compute_new_lusztig_datum(list enhanced_braid_chain, initial_lusztig_datum): @@ -314,17 +316,18 @@ cpdef tuple compute_new_lusztig_datum(list enhanced_braid_chain, initial_lusztig """ cdef tuple interval_of_change # Does not currently check that len(initial_lusztig_datum) is appropriate - cdef list new_lusztig_datum = list(initial_lusztig_datum) #shallow copy + cdef list new_lusztig_datum = list(initial_lusztig_datum) # shallow copy cdef int i for i in range(1, len(enhanced_braid_chain)): interval_of_change, type_data = enhanced_braid_chain[i] - a,b = interval_of_change + a, b = interval_of_change old_interval_datum = new_lusztig_datum[a:b] new_interval_datum = tropical_plucker_relation(type_data, old_interval_datum) new_lusztig_datum[a:b] = new_interval_datum return tuple(new_lusztig_datum) -# The tropical plucker relations + +# The tropical Plücker relations @cython.boundscheck(False) @cython.wraparound(False) cpdef tuple tropical_plucker_relation(tuple a, lusztig_datum): @@ -395,6 +398,7 @@ cpdef tuple tropical_plucker_relation(tuple a, lusztig_datum): return tuple(reversed(tropical_plucker_relation((a[1], a[0]), reversed_lusztig_datum))) + # Maybe we need to be more specific, and pass not the Cartan type, but the root lattice? # TODO: Move to PBW_data? @cython.boundscheck(False) diff --git a/src/sage/combinat/crystals/spins.pxd b/src/sage/combinat/crystals/spins.pxd index 4ca5f8a7082..a486aaa2518 100644 --- a/src/sage/combinat/crystals/spins.pxd +++ b/src/sage/combinat/crystals/spins.pxd @@ -18,4 +18,3 @@ cdef class Spin_crystal_type_D_element(Spin): cpdef Spin f(self, int i) cpdef int epsilon(self, int i) cpdef int phi(self, int i) - diff --git a/src/sage/combinat/crystals/spins.pyx b/src/sage/combinat/crystals/spins.pyx index 7473db8eb1d..0798a534077 100644 --- a/src/sage/combinat/crystals/spins.pyx +++ b/src/sage/combinat/crystals/spins.pyx @@ -99,6 +99,7 @@ def CrystalOfSpins(ct): else: raise NotImplementedError + ######################### # Type D spins ######################### @@ -135,6 +136,7 @@ def CrystalOfSpinsPlus(ct): else: raise NotImplementedError + def CrystalOfSpinsMinus(ct): r""" Return the minus spin crystal of the given type D. @@ -168,6 +170,7 @@ def CrystalOfSpinsMinus(ct): else: raise NotImplementedError + class GenericCrystalOfSpins(UniqueRepresentation, Parent): """ A generic crystal of spins. @@ -181,11 +184,11 @@ class GenericCrystalOfSpins(UniqueRepresentation, Parent): """ self._cartan_type = CartanType(ct) if case == "spins": - self.rename("The crystal of spins for type %s"%ct) + self.rename("The crystal of spins for type %s" % ct) elif case == "plus": - self.rename("The plus crystal of spins for type %s"%ct) + self.rename("The plus crystal of spins for type %s" % ct) else: - self.rename("The minus crystal of spins for type %s"%ct) + self.rename("The minus crystal of spins for type %s" % ct) self.Element = element_class Parent.__init__(self, category=ClassicalCrystals()) @@ -250,6 +253,7 @@ class GenericCrystalOfSpins(UniqueRepresentation, Parent): raise ValueError("both elements must be in this crystal") return self._digraph_closure.has_edge(x, y) + cdef class Spin(Element): """ A spin letter in the crystal of spins. diff --git a/src/sage/combinat/crystals/tensor_product_element.pxd b/src/sage/combinat/crystals/tensor_product_element.pxd index 53a60d5a327..aae31eb7a03 100644 --- a/src/sage/combinat/crystals/tensor_product_element.pxd +++ b/src/sage/combinat/crystals/tensor_product_element.pxd @@ -32,4 +32,3 @@ cdef class InfinityQueerCrystalOfTableauxElement(TensorProductOfQueerSuperCrysta cdef list _row_lengths cdef Py_ssize_t count_leading(list row, letter) - diff --git a/src/sage/combinat/crystals/tensor_product_element.pyx b/src/sage/combinat/crystals/tensor_product_element.pyx index a130ff71cb6..a95d2060b4b 100644 --- a/src/sage/combinat/crystals/tensor_product_element.pyx +++ b/src/sage/combinat/crystals/tensor_product_element.pyx @@ -1158,7 +1158,7 @@ cdef class InfinityCrystalOfTableauxElementTypeD(InfinityCrystalOfTableauxElemen return ret ##################################################################### -## BKK crystal elements +# BKK crystal elements cdef class TensorProductOfSuperCrystalsElement(TensorProductOfRegularCrystalsElement): r""" @@ -1405,7 +1405,7 @@ cdef class CrystalOfBKKTableauxElement(TensorProductOfSuperCrystalsElement): return Tableau(tab).conjugate() ##################################################################### -## Queer crystal elements +# Queer crystal elements cdef class TensorProductOfQueerSuperCrystalsElement(TensorProductOfRegularCrystalsElement): r""" diff --git a/src/sage/combinat/matrices/dancing_links.pyx b/src/sage/combinat/matrices/dancing_links.pyx index c468c83231f..df6cb7915f8 100644 --- a/src/sage/combinat/matrices/dancing_links.pyx +++ b/src/sage/combinat/matrices/dancing_links.pyx @@ -330,7 +330,6 @@ cdef class dancing_linksWrapper: """ return PyObject_RichCompare(left._rows, right._rows, op) - def get_solution(self): """ Return the current solution. @@ -473,7 +472,7 @@ cdef class dancing_linksWrapper: from copy import copy rows = copy(self._rows) ncols = self.ncols() - for i,row_index in enumerate(indices): + for i, row_index in enumerate(indices): # in the line below we want the creation of a new list rows[row_index] = rows[row_index] + [ncols+i] return dlx_solver(rows) @@ -546,8 +545,8 @@ cdef class dancing_linksWrapper: if not 0 <= column < self.ncols(): raise ValueError("column(={}) must be in range(ncols) " "where ncols={}".format(column, self.ncols())) - indices = [i for (i,row) in enumerate(self._rows) if column in row] - return {i:self.restrict([i]) for i in indices} + indices = (i for i, row in enumerate(self._rows) if column in row) + return {i: self.restrict([i]) for i in indices} def solutions_iterator(self): r""" @@ -792,7 +791,7 @@ cdef class dancing_linksWrapper: L.append(dlx.get_solution()) return L - indices = [i for (i,row) in enumerate(self._rows) if column in row] + indices = [i for i, row in enumerate(self._rows) if column in row] L = [] for (args_kwds, val) in all_solutions(indices): L.extend(val) @@ -892,7 +891,7 @@ cdef class dancing_linksWrapper: N += 1 return N - indices = [i for (i,row) in enumerate(self._rows) if column in row] + indices = [i for i, row in enumerate(self._rows) if column in row] return sum(val for (args_kwds, val) in nb_sol(indices)) @cached_method @@ -935,7 +934,7 @@ cdef class dancing_linksWrapper: # Note that row number i is associated to SAT variable i+1 to # avoid a variable zero columns = [[] for _ in range(self.ncols())] - for i,row in enumerate(self.rows(), start=1): + for i, row in enumerate(self.rows(), start=1): for a in row: columns[a].append(i) @@ -946,8 +945,8 @@ cdef class dancing_linksWrapper: # At most one 1 in each column import itertools for clause in columns: - for p,q in itertools.combinations(clause, 2): - sub_clause = [-p,-q] + for p, q in itertools.combinations(clause, 2): + sub_clause = [-p, -q] s.add_clause(sub_clause) return s @@ -995,13 +994,12 @@ cdef class dancing_linksWrapper: sage: d = dlx_solver(rows) sage: d.one_solution_using_sat_solver() is None True - """ sat_solver = self.to_sat_solver(solver) solution = sat_solver() if not solution: return None - return [key for (key,val) in enumerate(solution, start=-1) if val] + return [key for key, val in enumerate(solution, start=-1) if val] @cached_method def to_milp(self, solver=None): @@ -1123,18 +1121,17 @@ cdef class dancing_linksWrapper: sage: d = dlx_solver(rows) sage: d.one_solution_using_milp_solver() is None True - """ from sage.numerical.mip import MIPSolverException - p,x = self.to_milp(solver) + p, x = self.to_milp(solver) try: p.solve() except MIPSolverException: return None - else: - soln = p.get_values(x, convert=bool, tolerance=integrality_tolerance) - support = sorted(key for key in soln if soln[key]) - return support + + soln = p.get_values(x, convert=bool, tolerance=integrality_tolerance) + return sorted(key for key in soln if soln[key]) + def dlx_solver(rows): """ diff --git a/src/sage/combinat/words/word_char.pyx b/src/sage/combinat/words/word_char.pyx index 942aa6d1bc3..433aae3f4db 100644 --- a/src/sage/combinat/words/word_char.pyx +++ b/src/sage/combinat/words/word_char.pyx @@ -32,6 +32,7 @@ import itertools # the maximum value of a size_t cdef size_t SIZE_T_MAX = -(<size_t> 1) + def reversed_word_iterator(WordDatatype_char w): r""" This function exists only because it is not possible to use yield in the @@ -48,6 +49,7 @@ def reversed_word_iterator(WordDatatype_char w): for i in range(w._length-1, -1, -1): yield w._data[i] + cdef class WordDatatype_char(WordDatatype): r""" A Fast class for words represented by an array ``unsigned char *``. @@ -361,7 +363,7 @@ cdef class WordDatatype_char(WordDatatype): """ cdef Py_ssize_t i, start, stop, step, slicelength cdef unsigned char * data - cdef size_t j,k + cdef size_t j, k if isinstance(key, slice): # here the key is a slice PySlice_GetIndicesEx(key, @@ -374,7 +376,7 @@ cdef class WordDatatype_char(WordDatatype): return self._new_c(self._data+start, stop-start, self) data = <unsigned char *>check_allocarray(slicelength, sizeof(unsigned char)) j = 0 - for k in range(start,stop,step): + for k in range(start, stop, step): data[j] = self._data[k] j += 1 return self._new_c(data, slicelength, None) @@ -392,7 +394,7 @@ cdef class WordDatatype_char(WordDatatype): def __iter__(self): r""" - Iterator over the letter of self + Iterator over the letters of ``self``. EXAMPLES:: @@ -406,7 +408,7 @@ cdef class WordDatatype_char(WordDatatype): def __reversed__(self): r""" - Reversed iterator over the letter of self + Reversed iterator over the letters of ``self``. EXAMPLES:: diff --git a/src/sage/combinat/words/word_datatypes.pxd b/src/sage/combinat/words/word_datatypes.pxd index d7e4d74cca0..c3329bd5a78 100644 --- a/src/sage/combinat/words/word_datatypes.pxd +++ b/src/sage/combinat/words/word_datatypes.pxd @@ -1,4 +1,3 @@ cdef class WordDatatype(): cdef public _parent cdef _hash - diff --git a/src/sage/combinat/words/word_datatypes.pyx b/src/sage/combinat/words/word_datatypes.pyx index b39c1b2e925..900f86ad51a 100644 --- a/src/sage/combinat/words/word_datatypes.pyx +++ b/src/sage/combinat/words/word_datatypes.pyx @@ -64,7 +64,7 @@ cdef class WordDatatype(): cdef int res if self._hash is None: res = 5381 - for s in islice(self,1024): + for s in islice(self, 1024): res = ((res << 5) + res) + hash(s) self._hash = res return self._hash @@ -94,10 +94,9 @@ cdef class WordDatatype_list(WordDatatype): sage: w = Word([0,1,1,0]) sage: isinstance(w, sage.combinat.words.word_datatypes.WordDatatype_list) True - """ self._parent = parent - if isinstance(data,list): + if isinstance(data, list): self._data = data else: self._data = list(data) @@ -867,14 +866,12 @@ cdef class WordDatatype_str(WordDatatype): True sage: abba.is_prefix(ab) False - """ if isinstance(other, WordDatatype_str): return other._data.startswith(self._data) - if isinstance(other ,str): + if isinstance(other, str): return other.startswith(self._data) - else: - return super().is_prefix(other) + return super().is_prefix(other) def has_prefix(self, other): r""" @@ -940,10 +937,9 @@ cdef class WordDatatype_tuple(WordDatatype): sage: u = Word([0,1,1,0], datatype='tuple') sage: isinstance(u, sage.combinat.words.word_datatypes.WordDatatype_tuple) True - """ self._parent = parent - if isinstance(data,tuple): + if isinstance(data, tuple): self._data = data else: self._data = tuple(data) From d2c9c5efd2c1a8b4a41623452781ad66922eee82 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe <mkoeppe@math.ucdavis.edu> Date: Sun, 2 Jul 2023 11:13:21 -0700 Subject: [PATCH 219/228] src/sage/rings/integer.pyx (is_prime_power, perfect_power): Add doctests for powers of 2 --- src/sage/rings/integer.pyx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 4ff89eb1702..3fcc7a9960c 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -4828,6 +4828,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): (-3, 5) sage: (-64).perfect_power() # optional - sage.libs.pari (-4, 3) + + TESTS:: + + sage: 4.perfect_power() + (2, 2) + sage: 256.perfect_power() + (2, 8) """ cdef long n # Fast PARI-free path @@ -5178,6 +5185,15 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: n = 150607571^14 sage: n.is_prime_power() # optional - sage.libs.pari True + + TESTS:: + + sage: 2.is_prime_power(get_data=True) + (2, 1) + sage: 4.is_prime_power(get_data=True) + (2, 2) + sage: 512.is_prime_power(get_data=True) + (2, 9) """ cdef long n From 1f4f8cad06a107f7d438ca1a8988695d9c3fa0cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Mon, 3 Jul 2023 21:34:58 +0200 Subject: [PATCH 220/228] fixing some pep8 warnings in schemes/toric --- src/sage/schemes/toric/fano_variety.py | 15 +++-- src/sage/schemes/toric/ideal.py | 14 ++--- src/sage/schemes/toric/library.py | 64 +++++++++++--------- src/sage/schemes/toric/morphism.py | 22 +++---- src/sage/schemes/toric/variety.py | 49 ++++++++------- src/sage/schemes/toric/weierstrass_higher.py | 22 +++---- 6 files changed, 95 insertions(+), 91 deletions(-) diff --git a/src/sage/schemes/toric/fano_variety.py b/src/sage/schemes/toric/fano_variety.py index e3433787106..06e942c5336 100644 --- a/src/sage/schemes/toric/fano_variety.py +++ b/src/sage/schemes/toric/fano_variety.py @@ -107,15 +107,14 @@ # The first example of the tutorial is taken from # CPRFanoToricVariety_field.anticanonical_hypersurface - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2010 Andrey Novoseltsev <novoselt@gmail.com> # Copyright (C) 2010 William Stein <wstein@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import re @@ -527,7 +526,7 @@ def CPRFanoToricVariety(Delta=None, raise ValueError("the origin (point #%d) cannot be used for a " "coordinate!\nGot: %s" % (Delta_polar.origin(), coordinate_points)) - point_to_ray = dict() + point_to_ray = {} for n, point in enumerate(coordinate_points): point_to_ray[point] = n # This can be simplified if LatticePolytopeClass is adjusted. @@ -568,7 +567,7 @@ def CPRFanoToricVariety(Delta=None, make_simplicial=make_simplicial) # Now create yet another fan making sure that the order of the rays is # the same as requested (it is a bit difficult to get it from the start) - trans = dict() + trans = {} for n, ray in enumerate(fan.rays()): trans[n] = rays.index(ray) cones = tuple(tuple(sorted(trans[r] for r in cone.ambient_ray_indices())) @@ -1147,7 +1146,7 @@ def cartesian_product(self, other, Delta_polar = LatticePolytope(fan.rays()) points = Delta_polar.points() - point_to_ray = dict() + point_to_ray = {} coordinate_points = [] for ray_index, ray in enumerate(fan.rays()): point = points.index(ray) @@ -1230,7 +1229,7 @@ def resolve(self, **kwds): "subdivision!" % Delta_polar.origin()) if new_points: coordinate_points = coordinate_points + new_points - point_to_ray = dict() + point_to_ray = {} for n, point in enumerate(coordinate_points): point_to_ray[point] = n else: diff --git a/src/sage/schemes/toric/ideal.py b/src/sage/schemes/toric/ideal.py index c598d05f3ed..d2f0b094f5a 100644 --- a/src/sage/schemes/toric/ideal.py +++ b/src/sage/schemes/toric/ideal.py @@ -227,9 +227,9 @@ def __init__(self, A, """ self._A = matrix(ZZ, A) if polynomial_ring: - if (names!='z') or (base_ring is not QQ): + if names != 'z' or base_ring is not QQ: raise ValueError('you must not specify both variable names and a polynomial ring') - self._names = [str(_) for _ in polynomial_ring.gens()] + self._names = [str(g) for g in polynomial_ring.gens()] self._base_ring = polynomial_ring.base_ring() ring = polynomial_ring else: @@ -237,7 +237,7 @@ def __init__(self, A, self._base_ring = base_ring ring = self._init_ring('degrevlex') - if algorithm=='HostenSturmfels': + if algorithm == 'HostenSturmfels': ideal = self._ideal_HostenSturmfels() else: raise ValueError(f'algorithm = {algorithm} is not known') @@ -396,9 +396,9 @@ def _ideal_quotient_by_variable(self, ring, ideal, n): """ N = self.nvariables() y = list(ring.gens()) - x = [ y[i-n] for i in range(N) ] - y_to_x = dict(zip(x,y)) - x_to_y = dict(zip(y,x)) + x = [y[i - n] for i in range(N)] + y_to_x = dict(zip(x, y)) + x_to_y = dict(zip(y, x)) # swap variables such that the n-th variable becomes the last one J = ideal.subs(y_to_x) @@ -410,7 +410,7 @@ def _ideal_quotient_by_variable(self, ring, ideal, n): # x_n = y[0] # the cheapest variable in the revlex order def subtract(e, power): l = list(e) - return tuple([l[0]-power] + l[1:]) + return tuple([l[0] - power] + l[1:]) def divide_by_x_n(p): d_old = p.dict() diff --git a/src/sage/schemes/toric/library.py b/src/sage/schemes/toric/library.py index 8e1a9dfb732..e4344334d81 100644 --- a/src/sage/schemes/toric/library.py +++ b/src/sage/schemes/toric/library.py @@ -27,7 +27,7 @@ Multivariate Polynomial Ring in x, y, z over Rational Field """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2010 Volker Braun <vbraun.name@gmail.com> # Copyright (C) 2010 Andrey Novoseltsev <novoselt@gmail.com> # @@ -35,8 +35,8 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.structure.sage_object import SageObject @@ -121,30 +121,30 @@ (-1, -1, -1), (-1, 1, -1), (1, -1, -1), (1, 1, -1)], [[0,1,2,3],[4,5,6,7],[0,1,7,6],[4,5,3,2],[0,2,5,7],[4,6,1,3]] ], 'BCdlOG':[ - [(-1, 0, 0, 2, 3), # 0 - ( 0,-1, 0, 2, 3), # 1 - ( 0, 0,-1, 2, 3), # 2 - ( 0, 0,-1, 1, 2), # 3 - ( 0, 0, 0,-1, 0), # 4 - ( 0, 0, 0, 0,-1), # 5 - ( 0, 0, 0, 2, 3), # 6 - ( 0, 0, 1, 2, 3), # 7 - ( 0, 0, 2, 2, 3), # 8 - ( 0, 0, 1, 1, 1), # 9 + [(-1, 0, 0, 2, 3), # 0 + ( 0,-1, 0, 2, 3), # 1 + ( 0, 0,-1, 2, 3), # 2 + ( 0, 0,-1, 1, 2), # 3 + ( 0, 0, 0,-1, 0), # 4 + ( 0, 0, 0, 0,-1), # 5 + ( 0, 0, 0, 2, 3), # 6 + ( 0, 0, 1, 2, 3), # 7 + ( 0, 0, 2, 2, 3), # 8 + ( 0, 0, 1, 1, 1), # 9 ( 0, 1, 2, 2, 3), # 10 ( 0, 1, 3, 2, 3), # 11 - ( 1, 0, 4, 2, 3)], # 12 - [ [0,6,7,1,4], [0,6,10,2,4], [0,6,1,2,4], [0,9,7,1,5], [0,6,7,1,5], - [0,6,10,2,5], [0,6,1,2,5], [0,9,1,4,5], [0,6,10,4,11],[0,6,7,4,11], - [0,6,10,5,11], [0,9,7,5,11], [0,6,7,5,11], [0,9,4,5,11], [0,10,4,5,11], - [0,9,7,1,8], [0,9,1,4,8], [0,7,1,4,8], [0,9,7,11,8], [0,9,4,11,8], - [0,7,4,11,8], [0,10,2,4,3], [0,1,2,4,3], [0,10,2,5,3], [0,1,2,5,3], - [0,10,4,5,3], [0,1,4,5,3], [12,6,7,1,4], [12,6,10,2,4],[12,6,1,2,4], - [12,9,7,1,5], [12,6,7,1,5], [12,6,10,2,5], [12,6,1,2,5], [12,9,1,4,5], + ( 1, 0, 4, 2, 3)], # 12 + [ [0,6,7,1,4], [0,6,10,2,4], [0,6,1,2,4], [0,9,7,1,5], [0,6,7,1,5], + [0,6,10,2,5], [0,6,1,2,5], [0,9,1,4,5], [0,6,10,4,11],[0,6,7,4,11], + [0,6,10,5,11], [0,9,7,5,11], [0,6,7,5,11], [0,9,4,5,11], [0,10,4,5,11], + [0,9,7,1,8], [0,9,1,4,8], [0,7,1,4,8], [0,9,7,11,8], [0,9,4,11,8], + [0,7,4,11,8], [0,10,2,4,3], [0,1,2,4,3], [0,10,2,5,3], [0,1,2,5,3], + [0,10,4,5,3], [0,1,4,5,3], [12,6,7,1,4], [12,6,10,2,4],[12,6,1,2,4], + [12,9,7,1,5], [12,6,7,1,5], [12,6,10,2,5], [12,6,1,2,5], [12,9,1,4,5], [12,6,10,4,11],[12,6,7,4,11], [12,6,10,5,11],[12,9,7,5,11],[12,6,7,5,11], - [12,9,4,5,11], [12,10,4,5,11],[12,9,7,1,8], [12,9,1,4,8], [12,7,1,4,8], + [12,9,4,5,11], [12,10,4,5,11],[12,9,7,1,8], [12,9,1,4,8], [12,7,1,4,8], [12,9,7,11,8], [12,9,4,11,8], [12,7,4,11,8], [12,10,2,4,3],[12,1,2,4,3], - [12,10,2,5,3], [12,1,2,5,3], [12,10,4,5,3], [12,1,4,5,3] ] ], + [12,10,2,5,3], [12,1,2,5,3], [12,10,4,5,3], [12,1,4,5,3] ] ], 'BCdlOG_base':[ [(-1, 0, 0), ( 0,-1, 0), @@ -535,7 +535,7 @@ def P(self, n, names='z+', base_ring=QQ): if n <= 0: raise ValueError("only projective spaces of positive dimension " "can be constructed!\nGot: %s" % n) - m = identity_matrix(n).augment(matrix(n, 1, [-1]*n)) + m = identity_matrix(n).augment(matrix(n, 1, [-1] * n)) charts = [list(range(i)) + list(range(i + 1, n + 1)) for i in range(n + 1)] return CPRFanoToricVariety( @@ -935,9 +935,15 @@ def Cube_deformation(self,k, names=None, base_ring=QQ): if k < 0: raise ValueError("cube deformations X_k are defined only for " "non-negative k!\nGot: %s" % k) - rays = lambda kappa: matrix([[ 1, 1, 2*kappa+1],[ 1,-1, 1],[-1, 1, 1],[-1,-1, 1], - [-1,-1,-1],[-1, 1,-1],[ 1,-1,-1],[ 1, 1,-1]]) - cones = [[0,1,2,3],[4,5,6,7],[0,1,7,6],[4,5,3,2],[0,2,5,7],[4,6,1,3]] + + def rays(kappa): + return matrix([[1, 1, 2 * kappa + 1], [1, -1, 1], + [-1, 1, 1], [-1, -1, 1], + [-1, -1, -1], [-1, 1, -1], + [1, -1, -1], [1, 1, -1]]) + + cones = [[0, 1, 2, 3], [4, 5, 6, 7], [0, 1, 7, 6], + [4, 5, 3, 2], [0, 2, 5, 7], [4, 6, 1, 3]] fan = Fan(cones, rays(k)) return ToricVariety(fan, coordinate_names=names) @@ -1277,7 +1283,7 @@ def WP(self, *q, **kw): L = ToricLattice(m) L_sub = L.submodule([L(q)]) - Q = L/L_sub + Q = L / L_sub rays = [] cones = [] w = list(range(m)) @@ -1286,7 +1292,7 @@ def WP(self, *q, **kw): b = L_basis[i] v = Q.coordinate_vector(Q(b)) rays = rays + [v] - w_c = w[:i] + w[i+1:] + w_c = w[:i] + w[i + 1:] cones = cones + [tuple(w_c)] fan = Fan(cones,rays) return ToricVariety(fan, coordinate_names=names, base_ring=base_ring) diff --git a/src/sage/schemes/toric/morphism.py b/src/sage/schemes/toric/morphism.py index 5b494b07be6..9a9f87a9b5e 100644 --- a/src/sage/schemes/toric/morphism.py +++ b/src/sage/schemes/toric/morphism.py @@ -344,7 +344,7 @@ 1 connected components over (1, 2), each with 2 irreducible components. """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2011 Volker Braun <vbraun.name@gmail.com> # Copyright (C) 2010 Andrey Novoseltsev <novoselt@gmail.com> # Copyright (C) 2006 William Stein <wstein@gmail.com> @@ -353,8 +353,8 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** # For now, the scheme morphism base class cannot derive from Morphism # since this would clash with elliptic curves. So we derive only on @@ -640,7 +640,7 @@ def _reverse_ray_map(self): """ orbit = self.parent().domain() codomain_fan = self.parent().codomain().fan() - reverse_ray_dict = dict() + reverse_ray_dict = {} for n1, n2 in self._ray_map.items(): ray_index = codomain_fan.rays().index(n1) if n2.is_zero(): @@ -760,7 +760,7 @@ def pullback_divisor(self, divisor): codomain_rays = self.codomain().fan().rays() for ray in self.domain().fan().rays(): ray = codomain_rays[self._reverse_ray_map()[ray]] - value = divisor.function_value(ray) - m*ray + value = divisor.function_value(ray) - m * ray values.append(value) return self.domain().divisor(values) @@ -855,9 +855,9 @@ def __init__(self, parent, fan_morphism, check=True): to Rational polyhedral fan in 1-d lattice N. """ SchemeMorphism.__init__(self, parent) - if check and self.domain().fan()!=fan_morphism.domain_fan(): + if check and self.domain().fan() != fan_morphism.domain_fan(): raise ValueError('the fan morphism domain must be the fan of the domain') - if check and self.codomain().fan()!=fan_morphism.codomain_fan(): + if check and self.codomain().fan() != fan_morphism.codomain_fan(): raise ValueError('the fan morphism codomain must be the fan of the codomain') self._fan_morphism = fan_morphism @@ -1816,7 +1816,7 @@ def _make_fiber_component(self): ker = fm.kernel().basis() m = fm.matrix() * base_cone.lattice().basis_matrix() base_cone_preimg = [m.solve_left(r) for r in base_cone.rays()] - L = fm.domain_fan().lattice().span(ker+base_cone_preimg).saturation() + L = fm.domain_fan().lattice().span(ker + base_cone_preimg).saturation() cone_L = Cone([L.coordinates(r) for r in defining_cone.rays()]) L_quotient = cone_L.sublattice_quotient() @@ -1833,7 +1833,7 @@ def projection(ray): cones.append(Cone(projected_rays)) fiber_fan = Fan(cones) - ray_index_map = dict() + ray_index_map = {} for ray in star_rays: ray_index = fm.domain_fan().rays().index(ray) projected_ray = fiber_fan.lattice()(projection(ray)) @@ -1939,7 +1939,7 @@ def _image_ray_multiplicity(self, fiber_ray): d = gcd(ray) if d * fiber_ray != ray: continue - if multiplicity is not None and d>multiplicity: + if multiplicity is not None and d > multiplicity: continue multiplicity = d image_ray_index = index @@ -1984,7 +1984,7 @@ def pullback_divisor(self, divisor): for ray in self.domain().fan().rays(): image_ray_index, multiplicity = self._image_ray_multiplicity(ray) image_ray = codomain_rays[image_ray_index] - value = divisor.function_value(image_ray) - m*image_ray + value = divisor.function_value(image_ray) - m * image_ray value /= multiplicity values.append(value) return self.domain().divisor(values) diff --git a/src/sage/schemes/toric/variety.py b/src/sage/schemes/toric/variety.py index c594610f15d..eabb25ca4a1 100644 --- a/src/sage/schemes/toric/variety.py +++ b/src/sage/schemes/toric/variety.py @@ -288,7 +288,7 @@ implementing them on your own as a patch for inclusion! """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2010 Volker Braun <vbraun.name@gmail.com> # Copyright (C) 2010 Andrey Novoseltsev <novoselt@gmail.com> # Copyright (C) 2010 William Stein <wstein@gmail.com> @@ -297,8 +297,8 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import sys @@ -725,8 +725,7 @@ def _check_satisfies_equations(self, coordinates): possible_charts.intersection_update(fan._ray_to_cones(i)) if possible_charts: return True # All zeros are inside one generating cone - raise TypeError("coordinates %s are in the exceptional set" - % str(coordinates)) # Need str, coordinates is a tuple + raise TypeError(f"coordinates {coordinates} are in the exceptional set") def _point_homset(self, *args, **kwds): r""" @@ -994,7 +993,7 @@ def affine_patch(self, i): try: return self._affine_patches[i] except AttributeError: - self._affine_patches = dict() + self._affine_patches = {} except KeyError: pass cone = self.fan().generating_cone(i) @@ -1009,7 +1008,7 @@ def affine_patch(self, i): embedding_coordinates = [1] * n for k, ray in enumerate(cone.ambient_ray_indices()): embedding_coordinates[ray] = patch.gen(k) - if t > 0: # Passing "-0" gives unintended result + if t > 0: # Passing "-0" gives unintended result embedding_coordinates.extend(patch.gens()[-t:]) patch._embedding_morphism = patch.hom(embedding_coordinates, self) self._affine_patches[i] = patch @@ -1936,7 +1935,7 @@ def cohomology_ring(self): sage: loads(dumps(variety)) == variety True """ - if self.base_ring().characteristic()>0: + if self.base_ring().characteristic() > 0: raise NotImplementedError('only characteristic 0 base fields ' 'are implemented') return CohomologyRing(self) @@ -2249,19 +2248,19 @@ def Todd_class(self, deg=None): sage: dP6.integrate( dP6.Td() ) 1 """ - Td = QQ(1) + Td = QQ.one() if self.dimension() >= 1: c1 = self.Chern_class(1) - Td += QQ(1)/2 * c1 + Td += QQ.one() / 2 * c1 if self.dimension() >= 2: c2 = self.Chern_class(2) - Td += QQ(1)/12 * (c1**2 + c2) + Td += QQ.one() / 12 * (c1**2 + c2) if self.dimension() >= 3: - Td += QQ(1)/24 * c1*c2 + Td += QQ.one() / 24 * c1*c2 if self.dimension() >= 4: c3 = self.Chern_class(3) c4 = self.Chern_class(4) - Td += -QQ(1)/720 * (c1**4 -4*c1**2*c2 -3*c2**2 -c1*c3 +c4) + Td += -QQ.one() / 720 * (c1**4 - 4*c1**2*c2 - 3*c2**2 - c1*c3 + c4) if self.dimension() >= 5: raise NotImplementedError('Todd class is currently only implemented up to degree 4') if deg is None: @@ -2297,7 +2296,7 @@ def Euler_number(self): if self.is_complete(): chi = self.integrate(self.Chern_class()) else: - chi=0 + chi = 0 H = self.cohomology_basis() for d in range(self.dimension()+1): chi += (-1)**d * len(H[d]) @@ -2375,7 +2374,7 @@ def divisor(self, arg, base_ring=None, check=True, reduce=True): # Divisor by a ray index - must be treated here, see Issue #12812. if arg in ZZ: arg = [(1, self.gen(arg))] - check = True # 1 must be coerced into the coefficient ring + check = True # 1 must be coerced into the coefficient ring reduce = False from sage.schemes.toric.divisor import ToricDivisor return ToricDivisor(self, ring=base_ring, arg=arg, @@ -2652,14 +2651,14 @@ def _orbit_closure_projection(self, cone, x): return result assert isinstance(x, sage.geometry.abc.ConvexRationalPolyhedralCone) - rays = [ vector(quot(r)) for r in x.rays() ] + rays = [vector(quot(r)) for r in x.rays()] return Cone(rays) # TODO: make the following work nicely. - #if x in cone.lattice(): - #return quot(x) - #assert is_Cone(x) - #return Cone(x.rays(), lattice=quot) + # if x in cone.lattice(): + # return quot(x) + # assert is_Cone(x) + # return Cone(x.rays(), lattice=quot) def orbit_closure(self, cone): r""" @@ -3003,7 +3002,7 @@ def normalize_names(names=None, ngens=None, prefix=None, indices=None, return names -#***************************************************************** +# ***************************************************************** class CohomologyRing(QuotientRing_generic, UniqueRepresentation): r""" The (even) cohomology ring of a toric variety. @@ -3191,7 +3190,7 @@ def _element_constructor_(self,x): [z^2 + z + 1] """ fan = self._variety.fan() - if isinstance(x, CohomologyClass) and x.parent()==self: + if isinstance(x, CohomologyClass) and x.parent() == self: return x if isinstance(x, QuotientRingElement): x = x.lift() @@ -3274,7 +3273,7 @@ def gen(self, i): return CohomologyClass(self, self._polynomial_ring.gen(i)) -#***************************************************************** +# ***************************************************************** def is_CohomologyClass(x): r""" Check whether ``x`` is a cohomology class of a toric variety. @@ -3300,10 +3299,10 @@ def is_CohomologyClass(x): sage: is_CohomologyClass('z') False """ - return isinstance(x,CohomologyClass) + return isinstance(x, CohomologyClass) -#***************************************************************** +# ***************************************************************** class CohomologyClass(QuotientRingElement): r""" An element of the :class:`CohomologyRing`. diff --git a/src/sage/schemes/toric/weierstrass_higher.py b/src/sage/schemes/toric/weierstrass_higher.py index 64ae772ab27..af9d56233db 100644 --- a/src/sage/schemes/toric/weierstrass_higher.py +++ b/src/sage/schemes/toric/weierstrass_higher.py @@ -20,14 +20,14 @@ X^3 - \frac{1}{4} X Z^4`. """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2012 Volker Braun <vbraun.name@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.invariants.invariant_theory import invariant_theory @@ -168,9 +168,9 @@ def _biquadratic_syzygy_quartic(quadratic1, quadratic2, variables=None): # construct auxiliary polynomial ring to work with the rhs of the syzygy R = biquadratic.ring() n = R.ngens() - R_aux = PolynomialRing(R.base_ring(), n+2, 'aux') - to_aux = dict() - from_aux = dict() + R_aux = PolynomialRing(R.base_ring(), n + 2, 'aux') + to_aux = {} + from_aux = {} for var, var_aux in zip(R.gens(), R_aux.gens()[0:n]): to_aux[var] = var_aux from_aux[var_aux] = var @@ -181,9 +181,9 @@ def _biquadratic_syzygy_quartic(quadratic1, quadratic2, variables=None): # Syzygy is J^2 = syz_rhs + (terms that vanish on the biquadratic) with # J = biquadratic.J_covariant() syz_rhs = T**4 * biquadratic.Delta_invariant().subs(to_aux) \ - - T**3*T_prime * biquadratic.Theta_invariant().subs(to_aux) \ - + T**2*T_prime**2 * biquadratic.Phi_invariant().subs(to_aux) \ - - T*T_prime**3 * biquadratic.Theta_prime_invariant().subs(to_aux) \ + - T**3 * T_prime * biquadratic.Theta_invariant().subs(to_aux) \ + + T**2 * T_prime**2 * biquadratic.Phi_invariant().subs(to_aux) \ + - T * T_prime**3 * biquadratic.Theta_prime_invariant().subs(to_aux) \ + T_prime**4 * biquadratic.Delta_prime_invariant().subs(to_aux) quartic = invariant_theory.binary_quartic(syz_rhs, [T, T_prime]) return (biquadratic, quartic, from_aux) @@ -224,7 +224,7 @@ def WeierstrassForm_P3(quadratic1, quadratic2, variables=None): _biquadratic_syzygy_quartic(quadratic1, quadratic2, variables=variables) a = quartic.EisensteinD().subs(from_aux) b = quartic.EisensteinE().subs(from_aux) - return (-4*a, 16*b) + return (-4 * a, 16 * b) ###################################################################### @@ -287,4 +287,4 @@ def WeierstrassMap_P3(quadratic1, quadratic2, variables=None): J = biquadratic.J_covariant() g = quartic.g_covariant().subs(from_aux) h = quartic.h_covariant().subs(from_aux) - return (4*g, 4*h, J) + return (4 * g, 4 * h, J) From c715f0c872de480b5f36b849888803c77e9d319b Mon Sep 17 00:00:00 2001 From: Max Horn <max@quendi.de> Date: Tue, 4 Jul 2023 14:34:07 +0200 Subject: [PATCH 221/228] gap: make libgap APIs for function calls available ... and use them in two places. The rest will be dealt with in a future PR. --- src/sage/libs/gap/element.pyx | 4 ++-- src/sage/libs/gap/gap_includes.pxd | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index 6341a37c85f..30374674e0d 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -118,13 +118,13 @@ cdef char *capture_stdout(Obj func, Obj obj): GAP_Enter() s = NEW_STRING(0) output_text_string = GAP_ValueGlobalVariable("OutputTextString") - stream = CALL_2ARGS(output_text_string, s, GAP_True) + stream = GAP_CallFunc2Args(output_text_string, s, GAP_True) l = GAP_NewPlist(1) GAP_AssList(l, 1, obj) CALL_WITH_STREAM = GAP_ValueGlobalVariable("CALL_WITH_STREAM") - CALL_3ARGS(CALL_WITH_STREAM, stream, func, l) + GAP_CallFunc3Args(CALL_WITH_STREAM, stream, func, l) return GAP_CSTR_STRING(s) finally: GAP_Leave() diff --git a/src/sage/libs/gap/gap_includes.pxd b/src/sage/libs/gap/gap_includes.pxd index 8198ef5b6bb..edb52490ac6 100644 --- a/src/sage/libs/gap/gap_includes.pxd +++ b/src/sage/libs/gap/gap_includes.pxd @@ -68,6 +68,13 @@ cdef extern from "gap/libgap-api.h" nogil: cdef Obj GAP_True cdef Obj GAP_False + Obj GAP_CallFuncList(Obj func, Obj args); + Obj GAP_CallFuncArray(Obj func, UInt narg, Obj * args); + Obj GAP_CallFunc0Args(Obj func); + Obj GAP_CallFunc1Args(Obj func, Obj a1); + Obj GAP_CallFunc2Args(Obj func, Obj a1, Obj a2); + Obj GAP_CallFunc3Args(Obj func, Obj a1, Obj a2, Obj a3); + bint GAP_IsMacFloat(Obj obj) double GAP_ValueMacFloat(Obj obj) From bfa7615f9c3b796d383752021ae0a14cb0865bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <fchapoton2@gmail.com> Date: Tue, 4 Jul 2023 20:36:48 +0200 Subject: [PATCH 222/228] Update multi_modular.pxd details in one pxd file --- src/sage/arith/multi_modular.pxd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/arith/multi_modular.pxd b/src/sage/arith/multi_modular.pxd index 2b2dae1c7d9..ca43eb3e23f 100644 --- a/src/sage/arith/multi_modular.pxd +++ b/src/sage/arith/multi_modular.pxd @@ -2,12 +2,12 @@ from sage.ext.mod_int cimport * from sage.libs.gmp.types cimport mpz_t cdef class MultiModularBasis_base(): - cdef int n + cdef int n cdef mod_int* moduli cdef mpz_t* partial_products - cdef mod_int* C # precomputed values for CRT - cdef mpz_t product - cdef mpz_t half_product + cdef mod_int* C # precomputed values for CRT + cdef mpz_t product + cdef mpz_t half_product cdef unsigned long _l_bound cdef unsigned long _u_bound cdef unsigned long _num_primes From d87b9379c7da919a8457acd6475707f3992512a8 Mon Sep 17 00:00:00 2001 From: Sebastian Oehms <47305845+soehms@users.noreply.github.com> Date: Wed, 5 Jul 2023 08:06:12 +0200 Subject: [PATCH 223/228] 35800: rst syntax Co-authored-by: Travis Scrimshaw <clfrngrown@aol.com> --- src/sage/knots/knotinfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index 760d84c5fde..1b0697ef332 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -1787,7 +1787,7 @@ def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False, sage: Lk == L.link().khovanov_polynomial() True - TESTS: + TESTS:: sage: KnotInfo.K0_1.inject() Defining K0_1 From 83ecdfc3022a1ee6ef98c6d69727f92b43e33443 Mon Sep 17 00:00:00 2001 From: Sebastian Oehms <47305845+soehms@users.noreply.github.com> Date: Wed, 5 Jul 2023 08:07:19 +0200 Subject: [PATCH 224/228] 35800: doku fixes Co-authored-by: Travis Scrimshaw <clfrngrown@aol.com> --- src/sage/knots/knotinfo.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index 1b0697ef332..fc2f53081e3 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -1696,16 +1696,16 @@ def khovanov_polynomial(self, var1='q', var2='t', base_ring=ZZ, original=False, - ``var2`` -- (default: ``'t'``) the second variable - ``base_ring`` -- (default: ``ZZ``) the ring of the polynomial's coefficients - - ``original`` -- boolean (default: ``False``) if set to + - ``original`` -- boolean (default: ``False``); if set to ``True`` the original table entry is returned as a string - - ``reduced`` -- boolean (default: ``False``) if set to ``True`` - the reduced version of the homology is used. - - ``odd`` -- boolean (default: ``False``) if set to ``True`` - the odd version of the homology is used. + - ``reduced`` -- boolean (default: ``False``); if set to ``True`` + the reduced version of the homology is used + - ``odd`` -- boolean (default: ``False``); if set to ``True`` + the odd version of the homology is used - ``KhoHo`` -- boolean (default: ``False`` for knots and ``True`` - for multi-component links) if set to ``True`` the data calculated + for multi-component links); if set to ``True`` the data calculated using `KhoHo <https://github.com/AShumakovitch/KhoHo>`__ is used - (see the note below). + (see the note below) OUTPUT: From d7904e3d8cc2a0289c9bbf30c7162c08cadbe2af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Thu, 6 Jul 2023 16:15:10 +0200 Subject: [PATCH 225/228] fix some pep8 in symbolic folder --- src/sage/symbolic/assumptions.py | 14 +++---- src/sage/symbolic/expression_conversions.py | 4 +- src/sage/symbolic/integration/external.py | 7 ++-- src/sage/symbolic/maxima_wrapper.py | 4 +- src/sage/symbolic/pynac_constant.py | 6 +-- src/sage/symbolic/relation.py | 46 ++++++++++----------- src/sage/symbolic/subring.py | 20 ++++----- src/sage/symbolic/substitution_map.py | 6 +-- src/sage/symbolic/tests.py | 8 ++-- 9 files changed, 54 insertions(+), 61 deletions(-) diff --git a/src/sage/symbolic/assumptions.py b/src/sage/symbolic/assumptions.py index cca7f6182af..7dcb15f0d85 100644 --- a/src/sage/symbolic/assumptions.py +++ b/src/sage/symbolic/assumptions.py @@ -261,7 +261,7 @@ def assume(self): cur = maxima.get("context") # Redeclaring on the existing context does not seem to trigger # inconsistency checking. - ## maxima.set("context", self._context._maxima_init_()) + # maxima.set("context", self._context._maxima_init_()) # Instead, use a temporary context for this purpose context = maxima.newcontext('context' + maxima._next_var_name()) must_declare = True @@ -272,7 +272,7 @@ def assume(self): try: maxima.eval("declare(%s, %s)" % (self._var._maxima_init_(), self._assumption)) except RuntimeError as mess: - if 'inconsistent' in str(mess): # note Maxima doesn't tell you if declarations are redundant + if 'inconsistent' in str(mess): # note Maxima doesn't tell you if declarations are redundant # Inconsistency with one of the active contexts. raise ValueError("Assumption is inconsistent") else: @@ -316,9 +316,9 @@ def forget(self): except KeyError: return maxima.deactivate(self._context) - else: # trying to forget a declaration explicitly rather than implicitly + else: # trying to forget a declaration explicitly rather than implicitly for x in _assumptions: - if repr(self) == repr(x): # so by implication x is also a GenericDeclaration + if repr(self) == repr(x): # so by implication x is also a GenericDeclaration x.forget() break return @@ -945,8 +945,8 @@ def __init__(self, *args, **kwds): sage: bool(x>-1) False """ - self.replace=kwds.pop("replace",False) - self.Ass=args + self.replace = kwds.pop("replace", False) + self.Ass = args def __enter__(self): r""" @@ -964,7 +964,7 @@ def __enter__(self): False """ if self.replace: - self.OldAss=assumptions() + self.OldAss = assumptions() forget(assumptions()) assume(self.Ass) diff --git a/src/sage/symbolic/expression_conversions.py b/src/sage/symbolic/expression_conversions.py index 6073110887a..3dd93e032f7 100644 --- a/src/sage/symbolic/expression_conversions.py +++ b/src/sage/symbolic/expression_conversions.py @@ -582,7 +582,7 @@ def derivative(self, ex, operator): raise NotImplementedError args = ex.operands() if (not all(isinstance(v, Expression) and v.is_symbol() for v in args) or - len(args) != len(set(args))): + len(args) != len(set(args))): # An evaluated derivative of the form f'(1) is not a # symbolic variable, yet we would like to treat it like # one. So, we replace the argument `1` with a temporary @@ -1106,7 +1106,7 @@ def derivative(self, ex, operator): params_set = set(params) mult = ",".join(str(params.count(i)) for i in params_set) if (not all(isinstance(v, Expression) and v.is_symbol() for v in args) or - len(args) != len(set(args))): + len(args) != len(set(args))): # An evaluated derivative of the form f'(1) is not a # symbolic variable, yet we would like to treat it like # one. So, we replace the argument `1` with a temporary diff --git a/src/sage/symbolic/integration/external.py b/src/sage/symbolic/integration/external.py index 0760f20920b..55e658513e5 100644 --- a/src/sage/symbolic/integration/external.py +++ b/src/sage/symbolic/integration/external.py @@ -117,7 +117,8 @@ def mma_free_integrator(expression, v, a=None, b=None): input = "Integrate[{},{}]".format(math_expr, variable) elif a is not None and b is not None: input = "Integrate[{},{{{},{},{}}}]".format(math_expr, variable, - a._mathematica_init_(), b._mathematica_init_()) + a._mathematica_init_(), + b._mathematica_init_()) else: raise ValueError('a(={}) and b(={}) should be both None' ' or both defined'.format(a, b)) @@ -252,8 +253,8 @@ def giac_integrator(expression, v, a=None, b=None): result = ex.integrate(v._giac_(), a._giac_(), b._giac_()) if 'integrate' in format(result) or 'integration' in format(result): return expression.integrate(v, a, b, hold=True) - else: - return result._sage_() + return result._sage_() + def libgiac_integrator(expression, v, a=None, b=None): r""" diff --git a/src/sage/symbolic/maxima_wrapper.py b/src/sage/symbolic/maxima_wrapper.py index 76a0de446ad..ca30af3efcf 100644 --- a/src/sage/symbolic/maxima_wrapper.py +++ b/src/sage/symbolic/maxima_wrapper.py @@ -5,7 +5,7 @@ # Copyright (C) 2010 Burcin Erocal <burcin@erocal.org> # Distributed under the terms of the GNU General Public License (GPL), # version 2 or any later version. The full text of the GPL is available at: -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ ############################################################################### from sage.structure.sage_object import SageObject @@ -158,4 +158,4 @@ def _repr_(self): sage: u._repr_() 'MaximaWrapper(log(sqrt(2) + 1) + log(sqrt(2) - 1))' """ - return "MaximaWrapper(%s)"%(self._exp) + return "MaximaWrapper(%s)" % (self._exp) diff --git a/src/sage/symbolic/pynac_constant.py b/src/sage/symbolic/pynac_constant.py index 01d60ae4863..080cc7637be 100644 --- a/src/sage/symbolic/pynac_constant.py +++ b/src/sage/symbolic/pynac_constant.py @@ -2,7 +2,7 @@ Wrapper around Pynac's constants """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 William Stein <wstein@gmail.com> # Copyright (C) 2008 Burcin Erocal <burcin@erocal.org> # Copyright (C) 2009 Mike Hansen <mhansen@gmail.com> @@ -11,8 +11,8 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.misc.lazy_import import lazy_import lazy_import('sage.symbolic.expression', 'PynacConstant', deprecation=32386) diff --git a/src/sage/symbolic/relation.py b/src/sage/symbolic/relation.py index 51dcaf8d847..66e88706e84 100644 --- a/src/sage/symbolic/relation.py +++ b/src/sage/symbolic/relation.py @@ -502,7 +502,7 @@ def test_relation_maxima(relation): except TypeError: raise ValueError("unable to evaluate the predicate '%s'" % repr(relation)) - elif relation.operator() == operator.ne: # operator is not equal + elif relation.operator() == operator.ne: # operator is not equal try: s = m.parent()._eval_line('is (notequal(%s,%s))' % (repr(m.lhs()), repr(m.rhs()))) @@ -518,7 +518,7 @@ def test_relation_maxima(relation): if s == 'true': return True elif s == 'false': - return False # if neither of these, s=='unknown' and we try a few other tricks + return False # if neither of these, s=='unknown' and we try a few other tricks if relation.operator() != operator.eq: return False @@ -1064,7 +1064,7 @@ def solve(f, *args, **kwds): "symbolic expression or a list of symbolic " "expressions.") - if isinstance(f, Expression): # f is a single expression + if isinstance(f, Expression): # f is a single expression return _solve_expression(f, x, explicit_solutions, multiplicities, to_poly_solve, solution_dict, algorithm, domain) if not isinstance(f, (list, tuple)): @@ -1094,7 +1094,7 @@ def solve(f, *args, **kwds): if algorithm == 'sympy': from sympy import solve as ssolve from sage.interfaces.sympy import sympy_set_to_list - if isinstance(f, Expression): # f is a single expression + if isinstance(f, Expression): # f is a single expression sympy_f = f._sympy_() else: sympy_f = [s._sympy_() for s in f] @@ -1145,27 +1145,27 @@ def solve(f, *args, **kwds): else: raise - if len(s) == 0: # if Maxima's solve gave no solutions, try its to_poly_solve + if len(s) == 0: # if Maxima's solve gave no solutions, try its to_poly_solve try: s = m.to_poly_solve(variables) - except Exception: # if that gives an error, stick with no solutions + except Exception: # if that gives an error, stick with no solutions s = [] - if len(s) == 0: # if to_poly_solve gave no solutions, try use_grobner + if len(s) == 0: # if to_poly_solve gave no solutions, try use_grobner try: s = m.to_poly_solve(variables, 'use_grobner=true') - except Exception: # if that gives an error, stick with no solutions + except Exception: # if that gives an error, stick with no solutions s = [] sol_list = string_to_list_of_solutions(repr(s)) # Relaxed form suggested by Mike Hansen (#8553): if kwds.get('solution_dict', None): - if not sol_list: # fixes IndexError on empty solution list (#8553) + if not sol_list: # fixes IndexError on empty solution list (#8553) return [] if isinstance(sol_list[0], list): sol_dict = [{eq.left(): eq.right() for eq in solution} - for solution in sol_list] + for solution in sol_list] else: sol_dict = [{eq.left(): eq.right()} for eq in sol_list] @@ -1175,7 +1175,7 @@ def solve(f, *args, **kwds): def _solve_expression(f, x, explicit_solutions, multiplicities, - to_poly_solve, solution_dict, algorithm, domain): + to_poly_solve, solution_dict, algorithm, domain): """ Solve an expression ``f``. For more information, see :func:`solve`. @@ -1305,7 +1305,7 @@ def has_integer_assumption(v): alist = assumptions() return any(isinstance(a, GenericDeclaration) and a.has(v) and a._assumption in ['even', 'odd', 'integer', 'integervalued'] - for a in alist) + for a in alist) if len(ex.variables()) and all(has_integer_assumption(var) for var in ex.variables()): return f.solve_diophantine(x, solution_dict=solution_dict) @@ -1332,13 +1332,13 @@ def has_integer_assumption(v): m = ex._maxima_() P = m.parent() if explicit_solutions: - P.eval('solveexplicit: true') # switches Maxima to looking for only explicit solutions + P.eval('solveexplicit: true') # switches Maxima to looking for only explicit solutions try: if to_poly_solve != 'force': s = m.solve(x).str() - else: # omit Maxima's solve command + else: # omit Maxima's solve command s = str([]) - except TypeError as mess: # if Maxima's solve has an error, we catch it + except TypeError as mess: # if Maxima's solve has an error, we catch it if "Error executing code in Maxima" in str(mess): s = str([]) else: @@ -1356,9 +1356,9 @@ def has_integer_assumption(v): else: return ans - X = string_to_list_of_solutions(s) # our initial list of solutions + X = string_to_list_of_solutions(s) # our initial list of solutions - if multiplicities: # to_poly_solve does not return multiplicities, so in this case we end here + if multiplicities: # to_poly_solve does not return multiplicities, so in this case we end here if len(X) == 0: return X, [] else: @@ -1397,7 +1397,7 @@ def has_integer_assumption(v): "unable to make sense of Maxima expression" in \ str(mess): if not explicit_solutions: - X.append(eq) # we keep this implicit solution + X.append(eq) # we keep this implicit solution else: raise @@ -1565,8 +1565,6 @@ def solve_mod(eqns, modulus, solution_dict=False): [(0,)] sage: solve_mod([2*x^2+x*y, -x*y+2*y^2+x-2*y, -2*x^2+2*x*y-y^2-x-y], 1) [(0, 0)] - - """ from sage.rings.finite_rings.integer_mod_ring import Integers from sage.rings.integer import Integer @@ -1585,7 +1583,7 @@ def solve_mod(eqns, modulus, solution_dict=False): vars = list(set(sum([list(e.variables()) for e in eqns], []))) vars.sort(key=repr) - if modulus == 1: # degenerate case + if modulus == 1: # degenerate case ans = [tuple(Integers(1)(0) for v in vars)] return ans @@ -1611,10 +1609,8 @@ def solve_mod(eqns, modulus, solution_dict=False): # if solution_dict == True: # Relaxed form suggested by Mike Hansen (#8553): if solution_dict: - sol_dict = [dict(zip(vars, solution)) for solution in ans] - return sol_dict - else: - return ans + return [dict(zip(vars, solution)) for solution in ans] + return ans def _solve_mod_prime_power(eqns, p, m, vars): diff --git a/src/sage/symbolic/subring.py b/src/sage/symbolic/subring.py index 05ec90861fd..f3aad785d3f 100644 --- a/src/sage/symbolic/subring.py +++ b/src/sage/symbolic/subring.py @@ -403,10 +403,6 @@ def _coerce_map_from_(self, P): sage: C.has_coerce_map_from(SR) # indirect doctest False """ - if P == SR: - # Workaround; can be deleted once #19231 is fixed - return False - from sage.rings.infinity import InfinityRing from sage.rings.qqbar import AA, QQbar from sage.rings.real_lazy import RLF, CLF @@ -414,18 +410,18 @@ def _coerce_map_from_(self, P): if isinstance(P, type): return SR._coerce_map_from_(P) - elif RLF.has_coerce_map_from(P) or \ - CLF.has_coerce_map_from(P) or \ - AA.has_coerce_map_from(P) or \ - QQbar.has_coerce_map_from(P): + if RLF.has_coerce_map_from(P) or \ + CLF.has_coerce_map_from(P) or \ + AA.has_coerce_map_from(P) or \ + QQbar.has_coerce_map_from(P): return True - elif (P is InfinityRing or - isinstance(P, (sage.rings.abc.RealIntervalField, - sage.rings.abc.ComplexIntervalField))): + if (P is InfinityRing or + isinstance(P, (sage.rings.abc.RealIntervalField, + sage.rings.abc.ComplexIntervalField))): return True - elif P._is_numerical(): + if P._is_numerical(): return P not in (RLF, CLF, AA, QQbar) def __eq__(self, other): diff --git a/src/sage/symbolic/substitution_map.py b/src/sage/symbolic/substitution_map.py index 7dbdd6d5178..a883d3aecb0 100644 --- a/src/sage/symbolic/substitution_map.py +++ b/src/sage/symbolic/substitution_map.py @@ -7,15 +7,15 @@ back to Python. """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013 Volker Braun <vbraun.name@gmail.com> # # 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/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.misc.lazy_import import lazy_import lazy_import('sage.symbolic.expression', ('SubstitutionMap', 'make_map'), deprecation=32386) diff --git a/src/sage/symbolic/tests.py b/src/sage/symbolic/tests.py index b09ae5cc4b8..c1ef2cd14f2 100644 --- a/src/sage/symbolic/tests.py +++ b/src/sage/symbolic/tests.py @@ -2,15 +2,15 @@ Tests for the Sage/Pynac interaction """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013 Volker Braun <vbraun.name@gmail.com> # # 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/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** def rational_powers_memleak(): @@ -34,7 +34,7 @@ def rational_powers_memleak(): gc.collect() c0 = sum(1 for obj in gc.get_objects()) for i in range(1000): - a = ZZ(2).sqrt() + _ = ZZ(2).sqrt() gc.collect() c1 = sum(1 for obj in gc.get_objects()) # Test that we do not leak an object at each iteration From 4a31eeb47cfd22bc6a08a3a35ea858e043eed0ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= <chapoton@unistra.fr> Date: Thu, 6 Jul 2023 17:02:04 +0200 Subject: [PATCH 226/228] some pep8 fixes in repl/ --- src/sage/repl/display/formatter.py | 3 ++- src/sage/repl/display/util.py | 8 +++--- src/sage/repl/ipython_kernel/install.py | 8 +++--- src/sage/repl/ipython_kernel/interact.py | 2 +- src/sage/repl/ipython_kernel/kernel.py | 12 ++++++--- .../repl/ipython_kernel/widgets_sagenb.py | 16 +++++------ src/sage/repl/rich_output/backend_base.py | 6 ++--- src/sage/repl/rich_output/backend_emacs.py | 4 +-- src/sage/repl/rich_output/backend_ipython.py | 27 +++++++++---------- src/sage/repl/rich_output/display_manager.py | 4 ++- 10 files changed, 48 insertions(+), 42 deletions(-) diff --git a/src/sage/repl/display/formatter.py b/src/sage/repl/display/formatter.py index 7e06656d880..f8a47d3636b 100644 --- a/src/sage/repl/display/formatter.py +++ b/src/sage/repl/display/formatter.py @@ -79,6 +79,7 @@ lazy_import('matplotlib.figure', 'Figure') + class SageDisplayFormatter(DisplayFormatter): def __init__(self, *args, **kwds): @@ -194,7 +195,7 @@ def format(self, obj, include=None, exclude=None): # if it is not plain and dull if (not isinstance(obj, IPYTHON_NATIVE_TYPES) and not set(sage_format.keys()).issubset([PLAIN_TEXT]) and - not isinstance(obj, Figure)): + not isinstance(obj, Figure)): return sage_format, sage_metadata if self.ipython_display_formatter(obj): diff --git a/src/sage/repl/display/util.py b/src/sage/repl/display/util.py index ee99782b6fa..ac8f3191723 100644 --- a/src/sage/repl/display/util.py +++ b/src/sage/repl/display/util.py @@ -6,14 +6,14 @@ methods elsewhere. """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2014 Volker Braun <vbraun.name@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** class TallListFormatter(): @@ -39,7 +39,7 @@ def _tall_list_row(self, running_lines, last_row=False): sage: format_list._tall_list_row(['a b', 'b c', 'c']) ['a b', 'b c', 'c,', ''] """ - s=[] + s = [] for i, line in enumerate(running_lines): if i + 1 != len(running_lines): sep, tail = ' ', '' diff --git a/src/sage/repl/ipython_kernel/install.py b/src/sage/repl/ipython_kernel/install.py index cfb11b51bcf..081599b3452 100644 --- a/src/sage/repl/ipython_kernel/install.py +++ b/src/sage/repl/ipython_kernel/install.py @@ -263,14 +263,14 @@ def check(cls): spec = get_kernel_spec(ident) except NoSuchKernel: warnings.warn(f'no kernel named {ident} is accessible; ' - 'check your Jupyter configuration ' - '(see https://docs.jupyter.org/en/latest/use/jupyter-directories.html)') + 'check your Jupyter configuration ' + '(see https://docs.jupyter.org/en/latest/use/jupyter-directories.html)') else: from pathlib import Path if Path(spec.argv[0]).resolve() != Path(os.path.join(SAGE_VENV, 'bin', 'sage')).resolve(): warnings.warn(f'the kernel named {ident} does not seem to correspond to this ' - 'installation of SageMath; check your Jupyter configuration ' - '(see https://docs.jupyter.org/en/latest/use/jupyter-directories.html)') + 'installation of SageMath; check your Jupyter configuration ' + '(see https://docs.jupyter.org/en/latest/use/jupyter-directories.html)') def have_prerequisites(debug=True): diff --git a/src/sage/repl/ipython_kernel/interact.py b/src/sage/repl/ipython_kernel/interact.py index 4f96a212ab7..f13d488ff93 100644 --- a/src/sage/repl/ipython_kernel/interact.py +++ b/src/sage/repl/ipython_kernel/interact.py @@ -55,8 +55,8 @@ def f(x=(0, 10)): from sage.structure.element import parent import sage.rings.abc from sage.misc.lazy_import import lazy_import -lazy_import("sage.plot.colors", "Color") from sage.structure.element import Matrix +lazy_import("sage.plot.colors", "Color") class sage_interactive(interactive): diff --git a/src/sage/repl/ipython_kernel/kernel.py b/src/sage/repl/ipython_kernel/kernel.py index a4642014e90..73681716aa2 100644 --- a/src/sage/repl/ipython_kernel/kernel.py +++ b/src/sage/repl/ipython_kernel/kernel.py @@ -6,14 +6,14 @@ notebook or remote Jupyter sessions. """ -#***************************************************************************** +# *************************************************************************** # Copyright (C) 2015 Volker Braun <vbraun.name@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# *************************************************************************** import sys from ipykernel.ipkernel import IPythonKernel @@ -24,6 +24,7 @@ from sage.repl.interpreter import SageNotebookInteractiveShell from sage.repl.ipython_extension import SageJupyterCustomizations + class SageZMQInteractiveShell(SageNotebookInteractiveShell, ZMQInteractiveShell): pass @@ -98,7 +99,10 @@ def help_links(self): """ from sage.repl.ipython_kernel.install import SageKernelSpec identifier = SageKernelSpec.identifier() - kernel_url = lambda x: 'kernelspecs/{0}/{1}'.format(identifier, x) + + def kernel_url(x): + return 'kernelspecs/{0}/{1}'.format(identifier, x) + return [ { 'text': 'Sage Documentation', diff --git a/src/sage/repl/ipython_kernel/widgets_sagenb.py b/src/sage/repl/ipython_kernel/widgets_sagenb.py index 01a2bc42d06..cedf713248a 100644 --- a/src/sage/repl/ipython_kernel/widgets_sagenb.py +++ b/src/sage/repl/ipython_kernel/widgets_sagenb.py @@ -29,12 +29,12 @@ # **************************************************************************** from ipywidgets.widgets import (IntSlider, IntRangeSlider, FloatSlider, - FloatRangeSlider, SelectionSlider, - Checkbox, ToggleButtons, Dropdown) + FloatRangeSlider, SelectionSlider, + Checkbox, ToggleButtons, Dropdown) from .widgets import (TransformText, TransformTextarea, - TransformIntSlider, TransformIntRangeSlider, - TransformFloatSlider, TransformFloatRangeSlider, - EvalText, EvalTextarea, SageColorPicker, Grid) + TransformIntSlider, TransformIntRangeSlider, + TransformFloatSlider, TransformFloatRangeSlider, + EvalText, EvalTextarea, SageColorPicker, Grid) from ipywidgets.widgets.interaction import _get_min_max_value from collections.abc import Iterable, Sequence from numbers import Integral, Rational, Real @@ -43,10 +43,10 @@ from sage.arith.srange import srange import sage.rings.abc -Color = None - from .widgets import HTMLText as text_control +Color = None + def input_box(default=None, label=None, type=None, width=80, height=1): """ @@ -153,7 +153,7 @@ def input_box(default=None, label=None, type=None, width=80, height=1): if label is not None: kwds["description"] = label w = cls(**kwds) - w.layout.max_width = str(width+1) + "em" + w.layout.max_width = str(width + 1) + "em" return w diff --git a/src/sage/repl/rich_output/backend_base.py b/src/sage/repl/rich_output/backend_base.py index e9ca0b4d3ba..73eac559668 100644 --- a/src/sage/repl/rich_output/backend_base.py +++ b/src/sage/repl/rich_output/backend_base.py @@ -39,14 +39,14 @@ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2015 Volker Braun <vbraun.name@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import builtins from io import StringIO diff --git a/src/sage/repl/rich_output/backend_emacs.py b/src/sage/repl/rich_output/backend_emacs.py index c1c54a27ea6..112650270dd 100644 --- a/src/sage/repl/rich_output/backend_emacs.py +++ b/src/sage/repl/rich_output/backend_emacs.py @@ -7,14 +7,14 @@ """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2015 Ivan Andrus <darthandrus@gmail.com> # # 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. # https://www.gnu.org/licenses/ -#***************************************************************************** +# **************************************************************************** from sage.repl.rich_output.backend_ipython import BackendIPythonCommandline from sage.repl.rich_output.output_catalog import * diff --git a/src/sage/repl/rich_output/backend_ipython.py b/src/sage/repl/rich_output/backend_ipython.py index 981ecdf2cb1..6008c61bf39 100644 --- a/src/sage/repl/rich_output/backend_ipython.py +++ b/src/sage/repl/rich_output/backend_ipython.py @@ -6,14 +6,14 @@ :mod:`sage.repl.rich_output`. """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2015 Volker Braun <vbraun.name@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import os import sys @@ -428,8 +428,7 @@ def normpath(p): return '\n<script src="{0}"></script>'.format(script) -IFRAME_TEMPLATE = \ -""" +IFRAME_TEMPLATE = """ <iframe srcdoc="{escaped_html}" width="{width}" height="{height}" @@ -543,35 +542,35 @@ def displayhook(self, plain_text, rich_output): 'text/plain': plain_text.text.get_str(), }, {}) elif isinstance(rich_output, OutputHtml): - data = {'text/html': rich_output.html.get_str(), + data = {'text/html': rich_output.html.get_str(), 'text/plain': plain_text.text.get_str()} if rich_output.latex: data['text/latex'] = rich_output.latex.get_str() return (data, {}) elif isinstance(rich_output, OutputImagePng): - return ({'image/png': rich_output.png.get(), + return ({'image/png': rich_output.png.get(), 'text/plain': plain_text.text.get_str(), }, {}) elif isinstance(rich_output, OutputImageGif): - return ({'text/html': rich_output.html_fragment(), + return ({'text/html': rich_output.html_fragment(), 'text/plain': plain_text.text.get_str(), }, {}) elif isinstance(rich_output, OutputImageJpg): - return ({'image/jpeg': rich_output.jpg.get(), - 'text/plain': plain_text.text.get_str(), + return ({'image/jpeg': rich_output.jpg.get(), + 'text/plain': plain_text.text.get_str(), }, {}) elif isinstance(rich_output, OutputImageSvg): return ({'image/svg+xml': rich_output.svg.get(), - 'text/plain': plain_text.text.get_str(), + 'text/plain': plain_text.text.get_str(), }, {}) elif isinstance(rich_output, OutputImagePdf): - return ({'image/png': rich_output.png.get(), + return ({'image/png': rich_output.png.get(), 'text/plain': plain_text.text.get_str(), }, {}) elif isinstance(rich_output, OutputSceneJmol): from sage.repl.display.jsmol_iframe import JSMolHtml jsmol = JSMolHtml(rich_output, height=500) - return ({'text/html': jsmol.iframe(), + return ({'text/html': jsmol.iframe(), 'text/plain': plain_text.text.get_str(), }, {}) elif isinstance(rich_output, OutputSceneThreejs): @@ -581,7 +580,7 @@ def displayhook(self, plain_text, rich_output): width='100%', height=400, ) - return ({'text/html': iframe, + return ({'text/html': iframe, 'text/plain': plain_text.text.get_str(), }, {}) else: diff --git a/src/sage/repl/rich_output/display_manager.py b/src/sage/repl/rich_output/display_manager.py index f022335f8e6..4d5255c0b3b 100644 --- a/src/sage/repl/rich_output/display_manager.py +++ b/src/sage/repl/rich_output/display_manager.py @@ -30,7 +30,7 @@ # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ # **************************************************************************** @@ -45,6 +45,7 @@ ) from sage.repl.rich_output.preferences import DisplayPreferences + def _required_threejs_version(): """ Return the version of threejs that Sage requires. @@ -60,6 +61,7 @@ def _required_threejs_version(): with open(os.path.join(sage.env.SAGE_EXTCODE, 'threejs', 'threejs-version.txt')) as f: return f.read().strip() + class DisplayException(Exception): """ Base exception for all rich output-related exceptions. From ab44c318c6d0b3b10f0f360ad7a8e3666144828b Mon Sep 17 00:00:00 2001 From: Edgar Costa <edgarc@mit.edu> Date: Thu, 6 Jul 2023 20:54:52 -0400 Subject: [PATCH 227/228] Warning no longer makes sense since https://github.com/sagemath/sage/issues/21212 --- src/sage/rings/power_series_poly.pyx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/sage/rings/power_series_poly.pyx b/src/sage/rings/power_series_poly.pyx index 4cf4d8307ac..7c93168d4b1 100644 --- a/src/sage/rings/power_series_poly.pyx +++ b/src/sage/rings/power_series_poly.pyx @@ -1122,11 +1122,6 @@ cdef class PowerSeries_poly(PowerSeries): a ratio of two polynomials - .. WARNING:: - - The current implementation uses a very slow algorithm and is not - suitable for high orders. - ALGORITHM: This method uses the formula as a quotient of two determinants. From 1ca4a47dbd7c59f09b4840d66f6ced9edde9686a Mon Sep 17 00:00:00 2001 From: Release Manager <release@sagemath.org> Date: Sun, 9 Jul 2023 02:12:07 +0200 Subject: [PATCH 228/228] Updated SageMath version to 10.1.beta6 --- CITATION.cff | 4 ++-- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 6 +++--- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sage_conf/install-requires.txt | 2 +- build/pkgs/sage_docbuild/install-requires.txt | 2 +- build/pkgs/sage_setup/install-requires.txt | 2 +- build/pkgs/sage_sws2rst/install-requires.txt | 2 +- build/pkgs/sagelib/install-requires.txt | 2 +- build/pkgs/sagemath_categories/install-requires.txt | 2 +- build/pkgs/sagemath_environment/install-requires.txt | 2 +- build/pkgs/sagemath_objects/install-requires.txt | 2 +- build/pkgs/sagemath_repl/install-requires.txt | 2 +- pkgs/sage-conf/VERSION.txt | 2 +- pkgs/sage-conf_pypi/VERSION.txt | 2 +- pkgs/sage-docbuild/VERSION.txt | 2 +- pkgs/sage-setup/VERSION.txt | 2 +- pkgs/sage-sws2rst/VERSION.txt | 2 +- pkgs/sagemath-categories/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 25 files changed, 32 insertions(+), 32 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index 11b90ae405b..4c7ac0b3ad1 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -4,8 +4,8 @@ title: SageMath abstract: SageMath is a free open-source mathematics software system. authors: - name: "The SageMath Developers" -version: 10.1.beta5 +version: 10.1.beta6 doi: 10.5281/zenodo.593563 -date-released: 2023-07-01 +date-released: 2023-07-09 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index 90f410c9eef..14b19a1088f 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.1.beta5, Release Date: 2023-07-01 +SageMath version 10.1.beta6, Release Date: 2023-07-09 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index b66a7b2f670..0f430ff9b46 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=3afbceec8baa2721eb67a2ba3a0502e537d92b7c -md5=5a63faed2ead3db1dfe073f62e580646 -cksum=3890301429 +sha1=354d134d4bcdedba55ed2bcb1eac6ea33146ca15 +md5=2143a40fdce9ed5cb8b29a6232be4789 +cksum=304076036 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 3e6c582ac53..ae7e1289148 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -548a870667cf5f407e58affd56ebad6725c6446f +37fa2da8e75716793e91c384237a5e9f67ed83e8 diff --git a/build/pkgs/sage_conf/install-requires.txt b/build/pkgs/sage_conf/install-requires.txt index 2c0f37f4268..8343a24ee05 100644 --- a/build/pkgs/sage_conf/install-requires.txt +++ b/build/pkgs/sage_conf/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-conf ~= 10.1b5 +sage-conf ~= 10.1b6 diff --git a/build/pkgs/sage_docbuild/install-requires.txt b/build/pkgs/sage_docbuild/install-requires.txt index 7cfebf2845f..f2a0a305ff6 100644 --- a/build/pkgs/sage_docbuild/install-requires.txt +++ b/build/pkgs/sage_docbuild/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-docbuild ~= 10.1b5 +sage-docbuild ~= 10.1b6 diff --git a/build/pkgs/sage_setup/install-requires.txt b/build/pkgs/sage_setup/install-requires.txt index 2c48bba5343..af76413bd8c 100644 --- a/build/pkgs/sage_setup/install-requires.txt +++ b/build/pkgs/sage_setup/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-setup ~= 10.1b5 +sage-setup ~= 10.1b6 diff --git a/build/pkgs/sage_sws2rst/install-requires.txt b/build/pkgs/sage_sws2rst/install-requires.txt index 828f77192e0..99d11cf1aed 100644 --- a/build/pkgs/sage_sws2rst/install-requires.txt +++ b/build/pkgs/sage_sws2rst/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-sws2rst ~= 10.1b5 +sage-sws2rst ~= 10.1b6 diff --git a/build/pkgs/sagelib/install-requires.txt b/build/pkgs/sagelib/install-requires.txt index 863164d3036..04e85057c91 100644 --- a/build/pkgs/sagelib/install-requires.txt +++ b/build/pkgs/sagelib/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagelib ~= 10.1b5 +sagelib ~= 10.1b6 diff --git a/build/pkgs/sagemath_categories/install-requires.txt b/build/pkgs/sagemath_categories/install-requires.txt index a8adae5a62d..a21958fa714 100644 --- a/build/pkgs/sagemath_categories/install-requires.txt +++ b/build/pkgs/sagemath_categories/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-categories ~= 10.1b5 +sagemath-categories ~= 10.1b6 diff --git a/build/pkgs/sagemath_environment/install-requires.txt b/build/pkgs/sagemath_environment/install-requires.txt index f9e03a69316..1f595de983c 100644 --- a/build/pkgs/sagemath_environment/install-requires.txt +++ b/build/pkgs/sagemath_environment/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-environment ~= 10.1b5 +sagemath-environment ~= 10.1b6 diff --git a/build/pkgs/sagemath_objects/install-requires.txt b/build/pkgs/sagemath_objects/install-requires.txt index 83bc3826a15..d9d09c2cbfe 100644 --- a/build/pkgs/sagemath_objects/install-requires.txt +++ b/build/pkgs/sagemath_objects/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-objects ~= 10.1b5 +sagemath-objects ~= 10.1b6 diff --git a/build/pkgs/sagemath_repl/install-requires.txt b/build/pkgs/sagemath_repl/install-requires.txt index 77f2bab84c4..9823c179c91 100644 --- a/build/pkgs/sagemath_repl/install-requires.txt +++ b/build/pkgs/sagemath_repl/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-repl ~= 10.1b5 +sagemath-repl ~= 10.1b6 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index a5c4d64bf3e..e6681fde0ae 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.1.beta5 +10.1.beta6 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index a5c4d64bf3e..e6681fde0ae 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.1.beta5 +10.1.beta6 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index a5c4d64bf3e..e6681fde0ae 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.1.beta5 +10.1.beta6 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index a5c4d64bf3e..e6681fde0ae 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.1.beta5 +10.1.beta6 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index a5c4d64bf3e..e6681fde0ae 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.1.beta5 +10.1.beta6 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index a5c4d64bf3e..e6681fde0ae 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.1.beta5 +10.1.beta6 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index a5c4d64bf3e..e6681fde0ae 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.1.beta5 +10.1.beta6 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index a5c4d64bf3e..e6681fde0ae 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.1.beta5 +10.1.beta6 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index a5c4d64bf3e..e6681fde0ae 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.1.beta5 +10.1.beta6 diff --git a/src/VERSION.txt b/src/VERSION.txt index a5c4d64bf3e..e6681fde0ae 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.1.beta5 +10.1.beta6 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 7c4069094c4..2cdfbe761d4 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -4,6 +4,6 @@ # which stops "setup.py develop" from rewriting it as a Python file. : # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='10.1.beta5' -SAGE_RELEASE_DATE='2023-07-01' -SAGE_VERSION_BANNER='SageMath version 10.1.beta5, Release Date: 2023-07-01' +SAGE_VERSION='10.1.beta6' +SAGE_RELEASE_DATE='2023-07-09' +SAGE_VERSION_BANNER='SageMath version 10.1.beta6, Release Date: 2023-07-09' diff --git a/src/sage/version.py b/src/sage/version.py index 45c4a54f784..5a0f022fb17 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '10.1.beta5' -date = '2023-07-01' -banner = 'SageMath version 10.1.beta5, Release Date: 2023-07-01' +version = '10.1.beta6' +date = '2023-07-09' +banner = 'SageMath version 10.1.beta6, Release Date: 2023-07-09'