Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Merge branch 'public/misc/names_argument_indexed_generators-17039' of…
Browse files Browse the repository at this point in the history
… git://trac.sagemath.org/sage into public/misc/names_argument_indexed_generators-17039
  • Loading branch information
Travis Scrimshaw committed Jun 12, 2017
2 parents ffc8eff + 8f7d3e6 commit 06f1536
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 56 deletions.
62 changes: 56 additions & 6 deletions src/sage/combinat/free_module.py
Expand Up @@ -15,7 +15,7 @@

from sage.structure.unique_representation import UniqueRepresentation
from sage.structure.parent import Parent
from sage.structure.indexed_generators import IndexedGenerators
from sage.structure.indexed_generators import IndexedGenerators, parse_indices_names
from sage.modules.module import Module
from sage.rings.all import Integer
from sage.structure.element import parent
Expand Down Expand Up @@ -236,10 +236,22 @@ class CombinatorialFreeModule(UniqueRepresentation, Module, IndexedGenerators):
sage: g = 2*G.monomial(3) + G.monomial(4)
sage: tensor([f, g])
2*x[1] # y[3] + x[1] # y[4] + 4*x[2] # y[3] + 2*x[2] # y[4]
We check that we can use the shorthand ``C.<a,b,...> = ...``::
sage: C.<x,y,z> = CombinatorialFreeModule(QQ)
sage: C
Free module generated by {'x', 'y', 'z'} over Rational Field
sage: a = x - y + 4*z; a
x - y + 4*z
sage: a.parent() is C
True
"""

@staticmethod
def __classcall_private__(cls, base_ring, basis_keys, category = None, prefix="B", **keywords):
def __classcall_private__(cls, base_ring, basis_keys=None, category=None,
prefix=None, names=None, **keywords):
"""
TESTS::
Expand Down Expand Up @@ -283,7 +295,14 @@ def __classcall_private__(cls, base_ring, basis_keys, category = None, prefix="B
latex_bracket = keywords.get('latex_bracket', None)
if isinstance(latex_bracket, list):
keywords['latex_bracket'] = tuple(latex_bracket)
return super(CombinatorialFreeModule, cls).__classcall__(cls, base_ring, basis_keys, category = category, prefix=prefix, **keywords)

names, basis_keys, prefix = parse_indices_names(names, basis_keys, prefix, keywords)
if prefix is None:
prefix = "B"

return super(CombinatorialFreeModule, cls).__classcall__(cls,
base_ring, basis_keys, category=category, prefix=prefix, names=names,
**keywords)

# We make this explicitly a Python class so that the methods,
# specifically _mul_, from category framework still works. -- TCS
Expand Down Expand Up @@ -325,7 +344,8 @@ def element_class(self):
module=self.__class__.__module__,
inherit=True)

def __init__(self, R, basis_keys, element_class = None, category = None, prefix="B", **kwds):
def __init__(self, R, basis_keys=None, element_class=None, category=None,
prefix=None, names=None, **kwds):
r"""
TESTS::
Expand Down Expand Up @@ -396,6 +416,12 @@ def __init__(self, R, basis_keys, element_class = None, category = None, prefix=
# (e.g. root systems passes lists)
basis_keys = Sets()(basis_keys, enumerated_set=True)

# This is needed for the Cartesian product
# TODO: Remove this duplication from __classcall_private__
names, basis_keys, prefix = parse_indices_names(names, basis_keys, prefix, kwds)
if prefix is None:
prefix = "B"

# ignore the optional 'key' since it only affects CachedRepresentation
kwds.pop('key', None)
# This needs to be first as per #10127
Expand All @@ -418,9 +444,9 @@ def __init__(self, R, basis_keys, element_class = None, category = None, prefix=
if basis_keys in Sets().Finite():
category = category.FiniteDimensional()

Parent.__init__(self, base = R, category = category,
Parent.__init__(self, base=R, category=category, names=names,
# Could we get rid of this?
element_constructor = self._element_constructor_)
element_constructor=self._element_constructor_)

self._order = None

Expand Down Expand Up @@ -673,6 +699,30 @@ def _an_element_impl(self):
"""
return self.element_class(self, {})

def _first_ngens(self, n):
"""
Used by the preparser for ``F.<x> = ...``.
EXAMPLES::
sage: C = CombinatorialFreeModule(QQ, ZZ)
sage: C._first_ngens(3)
(B[0], B[1], B[-1])
sage: R.<x,y> = FreeAlgebra(QQ, 2)
sage: x,y
(x, y)
"""
try:
# Try gens first for compatibility with classes that
# rely on this (e.g., FreeAlgebra)
return tuple(self.gens())[:n]
except (AttributeError, ValueError, TypeError):
pass
B = self.basis()
it = iter(self._indices)
return tuple(B[next(it)] for i in range(n))

def dimension(self):
"""
Return the dimension of the free module (which is given
Expand Down
10 changes: 7 additions & 3 deletions src/sage/monoids/free_monoid.py
Expand Up @@ -107,10 +107,14 @@ def FreeMonoid(index_set=None, names=None, commutative=False, **kwds):
Free abelian monoid on 3 generators (x, y, z)
sage: FreeMonoid(index_set=ZZ, commutative=True)
Free abelian monoid indexed by Integer Ring
TESTS::
sage: FreeMonoid(index_set=ZZ, names='x,y,z')
Free monoid indexed by Integer Ring
"""
if 'abelian' in kwds:
commutative = kwds['abelian']
del kwds['abelian']
commutative = kwds.pop('abelian')

if commutative:
from sage.monoids.free_abelian_monoid import FreeAbelianMonoid
Expand All @@ -127,7 +131,7 @@ def FreeMonoid(index_set=None, names=None, commutative=False, **kwds):

if index_set not in ZZ:
if names is not None:
names = normalize_names(len(names), names)
names = normalize_names(-1, names)
from sage.monoids.indexed_free_monoid import IndexedFreeMonoid
return IndexedFreeMonoid(index_set, names=names, **kwds)

Expand Down
27 changes: 12 additions & 15 deletions src/sage/monoids/indexed_free_monoid.py
Expand Up @@ -20,7 +20,7 @@
from sage.structure.parent import Parent
from sage.structure.unique_representation import UniqueRepresentation
from sage.structure.element import MonoidElement
from sage.structure.indexed_generators import IndexedGenerators
from sage.structure.indexed_generators import IndexedGenerators, parse_indices_names
from sage.structure.richcmp import op_EQ, op_NE, richcmp, rich_to_bool
import sage.data_structures.blas_dict as blas

Expand Down Expand Up @@ -633,7 +633,7 @@ class IndexedMonoid(Parent, IndexedGenerators, UniqueRepresentation):
:class:`~sage.structure.indexed_generators.IndexedGenerators`.
"""
@staticmethod
def __classcall__(cls, indices, prefix="F", **kwds):
def __classcall__(cls, indices, prefix=None, names=None, **kwds):
"""
TESTS::
Expand All @@ -651,16 +651,11 @@ def __classcall__(cls, indices, prefix="F", **kwds):
sage: Groups.Commutative.free()
Traceback (most recent call last):
...
ValueError: no index set specified
ValueError: either the indices or names must be given
"""
if isinstance(indices, str):
indices = FiniteEnumeratedSet(list(indices))
elif isinstance(indices, (list, tuple)):
indices = FiniteEnumeratedSet(indices)
elif indices is None:
if kwds.get('names', None) is None:
raise ValueError("no index set specified")
indices = FiniteEnumeratedSet(kwds['names'])
names, indices, prefix = parse_indices_names(names, indices, prefix, kwds)
if prefix is None:
prefix = "F"

# bracket or latex_bracket might be lists, so convert
# them to tuples so that they're hashable.
Expand All @@ -670,7 +665,9 @@ def __classcall__(cls, indices, prefix="F", **kwds):
latex_bracket = kwds.get('latex_bracket', None)
if isinstance(latex_bracket, list):
kwds['latex_bracket'] = tuple(latex_bracket)
return super(IndexedMonoid, cls).__classcall__(cls, indices, prefix, **kwds)

return super(IndexedMonoid, cls).__classcall__(cls, indices, prefix,
names=names, **kwds)

def __init__(self, indices, prefix, category=None, names=None, **kwds):
"""
Expand Down Expand Up @@ -708,9 +705,9 @@ def _first_ngens(self, n):
EXAMPLES::
sage: F.<x,y,z> = FreeMonoid(index_set=ZZ)
sage: [x, y, z]
[F[0], F[1], F[-1]]
sage: F = FreeMonoid(index_set=ZZ)
sage: F._first_ngens(3)
(F[0], F[1], F[-1])
"""
it = iter(self._indices)
return tuple(self.gen(next(it)) for i in range(n))
Expand Down

0 comments on commit 06f1536

Please sign in to comment.