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
… trac.sagemath.org:sage into public/misc/names_argument_indexed_generators-17039
  • Loading branch information
Travis Scrimshaw committed Apr 10, 2016
2 parents 67521dd + 94f081b commit fc1eb23
Show file tree
Hide file tree
Showing 10 changed files with 235 additions and 48 deletions.
8 changes: 5 additions & 3 deletions src/sage/algebras/associated_graded.py
Expand Up @@ -139,10 +139,10 @@ class AssociatedGradedAlgebra(CombinatorialFreeModule):
``grA`` are isomorphic::
sage: grA(A.an_element())
bar(U['x']^2*U['y']^2*U['z']^3)
bar(U['x']^2*U['y']^2*U['z']^3) + 2*bar(U['x']) + 3*bar(U['y']) + bar(1)
sage: elt = A.an_element() + A.algebra_generators()['x'] + 2
sage: grelt = grA(elt); grelt
bar(U['x']^2*U['y']^2*U['z']^3) + bar(U['x']) + 2*bar(1)
bar(U['x']^2*U['y']^2*U['z']^3) + 3*bar(U['x']) + 3*bar(U['y']) + 3*bar(1)
sage: A(grelt) == elt
True
Expand Down Expand Up @@ -241,8 +241,10 @@ def _element_constructor_(self, x):
sage: grA = A.graded_algebra()
sage: grA(A.an_element())
bar(U['x']^2*U['y']^2*U['z']^3)
+ 2*bar(U['x']) + 3*bar(U['y']) + bar(1)
sage: grA(A.an_element() + A.algebra_generators()['x'] + 2)
bar(U['x']^2*U['y']^2*U['z']^3) + bar(U['x']) + 2*bar(1)
bar(U['x']^2*U['y']^2*U['z']^3)
+ 3*bar(U['x']) + 3*bar(U['y']) + 3*bar(1)
"""
if isinstance(x, CombinatorialFreeModule.Element):
if x.parent() is self._A:
Expand Down
2 changes: 1 addition & 1 deletion src/sage/algebras/jordan_algebra.py
Expand Up @@ -287,7 +287,7 @@ def _an_element_(self):
sage: F.<x,y,z> = FreeAlgebra(QQ)
sage: J = JordanAlgebra(F)
sage: J.an_element()
x
2 + 2*x + 3*y
"""
return self.element_class(self, self._A.an_element())

Expand Down
6 changes: 5 additions & 1 deletion src/sage/categories/examples/filtered_algebras_with_basis.py
Expand Up @@ -114,8 +114,12 @@ def degree_on_basis(self, m):
sage: A.degree_on_basis((x^4).leading_support())
4
sage: a = A.an_element(); a
U['x']^2*U['y']^2*U['z']^3
U['x']^2*U['y']^2*U['z']^3 + 2*U['x'] + 3*U['y'] + 1
sage: A.degree_on_basis(a.leading_support())
1
sage: s = sorted(a.support(), key=str)[2]; s
U['x']^2*U['y']^2*U['z']^3
sage: A.degree_on_basis(s)
7
"""
return len(m)
Expand Down
9 changes: 5 additions & 4 deletions src/sage/categories/filtered_algebras_with_basis.py
Expand Up @@ -131,9 +131,10 @@ def to_graded_conversion(self):
sage: A = Algebras(QQ).WithBasis().Filtered().example()
sage: p = A.an_element() + A.algebra_generators()['x'] + 2; p
U['x']^2*U['y']^2*U['z']^3 + U['x'] + 2
U['x']^2*U['y']^2*U['z']^3 + 3*U['x'] + 3*U['y'] + 3
sage: q = A.to_graded_conversion()(p); q
bar(U['x']^2*U['y']^2*U['z']^3) + bar(U['x']) + 2*bar(1)
bar(U['x']^2*U['y']^2*U['z']^3) + 3*bar(U['x'])
+ 3*bar(U['y']) + 3*bar(1)
sage: q.parent() is A.graded_algebra()
True
"""
Expand All @@ -159,7 +160,7 @@ def from_graded_conversion(self):
sage: A = Algebras(QQ).WithBasis().Filtered().example()
sage: p = A.an_element() + A.algebra_generators()['x'] + 2; p
U['x']^2*U['y']^2*U['z']^3 + U['x'] + 2
U['x']^2*U['y']^2*U['z']^3 + 3*U['x'] + 3*U['y'] + 3
sage: q = A.to_graded_conversion()(p)
sage: A.from_graded_conversion()(q) == p
True
Expand Down Expand Up @@ -190,7 +191,7 @@ def projection(self, i):
sage: A = Algebras(QQ).WithBasis().Filtered().example()
sage: p = A.an_element() + A.algebra_generators()['x'] + 2; p
U['x']^2*U['y']^2*U['z']^3 + U['x'] + 2
U['x']^2*U['y']^2*U['z']^3 + 3*U['x'] + 3*U['y'] + 3
sage: q = A.projection(7)(p); q
bar(U['x']^2*U['y']^2*U['z']^3)
sage: q.parent() is A.graded_algebra()
Expand Down
19 changes: 12 additions & 7 deletions src/sage/categories/filtered_modules_with_basis.py
Expand Up @@ -832,12 +832,14 @@ def homogeneous_component(self, n):
0
sage: A = AlgebrasWithBasis(ZZ).Filtered().example()
sage: g = A.an_element() - 2 * A.algebra_generators()['x'] * A.algebra_generators()['y']; g
sage: G = A.algebra_generators()
sage: g = A.an_element() - 2 * G['x'] * G['y']; g
U['x']^2*U['y']^2*U['z']^3 - 2*U['x']*U['y']
+ 2*U['x'] + 3*U['y'] + 1
sage: g.homogeneous_component(-1)
0
sage: g.homogeneous_component(0)
0
1
sage: g.homogeneous_component(2)
-2*U['x']*U['y']
sage: g.homogeneous_component(5)
Expand Down Expand Up @@ -896,22 +898,25 @@ def truncate(self, n):
2*P[] + 2*P[1] + 3*P[2]
sage: A = AlgebrasWithBasis(ZZ).Filtered().example()
sage: g = A.an_element() - 2 * A.algebra_generators()['x'] * A.algebra_generators()['y']; g
sage: G = A.algebra_generators()
sage: g = A.an_element() - 2 * G['x'] * G['y']; g
U['x']^2*U['y']^2*U['z']^3 - 2*U['x']*U['y']
+ 2*U['x'] + 3*U['y'] + 1
sage: g.truncate(-1)
0
sage: g.truncate(0)
0
sage: g.truncate(2)
0
2*U['x'] + 3*U['y'] + 1
sage: g.truncate(3)
-2*U['x']*U['y']
-2*U['x']*U['y'] + 2*U['x'] + 3*U['y'] + 1
sage: g.truncate(5)
-2*U['x']*U['y']
-2*U['x']*U['y'] + 2*U['x'] + 3*U['y'] + 1
sage: g.truncate(7)
-2*U['x']*U['y']
-2*U['x']*U['y'] + 2*U['x'] + 3*U['y'] + 1
sage: g.truncate(8)
U['x']^2*U['y']^2*U['z']^3 - 2*U['x']*U['y']
+ 2*U['x'] + 3*U['y'] + 1
TESTS:
Expand Down
64 changes: 56 additions & 8 deletions src/sage/combinat/free_module.py
Expand Up @@ -12,7 +12,7 @@
from sage.structure.unique_representation import UniqueRepresentation
from sage.structure.element import Element, have_same_parent
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.misc.misc import repr_lincomb
from sage.modules.module import Module
from sage.rings.all import Integer
Expand Down Expand Up @@ -965,10 +965,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 @@ -1010,11 +1022,17 @@ 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)

basis_keys, names, prefix = parse_indices_names(basis_keys, names, 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)

Element = CombinatorialFreeModuleElement

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 @@ -1085,12 +1103,18 @@ 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__
basis_keys, names, prefix = parse_indices_names(basis_keys, names, 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
if 'monomial_cmp' in kwds:
kwds['generator_cmp'] = kwds['monomial_cmp']
del kwds['monomial_cmp']
kwds['generator_cmp'] = kwds.pop('monomial_cmp')

IndexedGenerators.__init__(self, basis_keys, prefix, **kwds)

if category is None:
Expand All @@ -1100,9 +1124,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 @@ -1338,6 +1362,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: 8 additions & 2 deletions src/sage/monoids/free_monoid.py
Expand Up @@ -106,10 +106,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 @@ -126,6 +130,8 @@ def FreeMonoid(index_set=None, names=None, commutative=False, **kwds):

if index_set not in ZZ:
if names is not None:
if isinstance(names, str):
names = names.split(',')
names = normalize_names(len(names), names)
from sage.monoids.indexed_free_monoid import IndexedFreeMonoid
return IndexedFreeMonoid(index_set, names=names, **kwds)
Expand Down
29 changes: 14 additions & 15 deletions src/sage/monoids/indexed_free_monoid.py
Expand Up @@ -19,12 +19,13 @@
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.sage_object import op_EQ, op_NE, py_rich_to_bool
from sage.combinat.dict_addition import dict_addition

from sage.categories.monoids import Monoids
from sage.categories.poor_man_map import PoorManMap
from sage.categories.sets_cat import Sets
from sage.rings.integer import Integer
from sage.rings.infinity import infinity
from sage.rings.all import ZZ
Expand Down Expand Up @@ -627,7 +628,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 @@ -645,16 +646,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'])
indices, names, prefix = parse_indices_names(indices, names, 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 @@ -664,7 +660,8 @@ 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 All @@ -688,6 +685,8 @@ def __init__(self, indices, prefix, category=None, names=None, **kwds):
category = category.Finite()
else:
category = category.Infinite()
if indices in Sets().Finite():
category = category.FinitelyGeneratedAsMagma()
Parent.__init__(self, names=names, category=category)

# ignore the optional 'key' since it only affects CachedRepresentation
Expand All @@ -700,9 +699,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
19 changes: 17 additions & 2 deletions src/sage/monoids/monoid.py
Expand Up @@ -28,7 +28,7 @@ def is_Monoid(x):
return isinstance(x, Monoid_class)

class Monoid_class(Parent):
def __init__(self,names):
def __init__(self, names):
r"""
EXAMPLES::
Expand All @@ -42,7 +42,8 @@ def __init__(self,names):
sage: TestSuite(F).run()
"""
from sage.categories.monoids import Monoids
Parent.__init__(self, base=self,names=names,category=Monoids())
category = Monoids().FinitelyGeneratedAsMagma()
Parent.__init__(self, base=self, names=names, category=category)

@cached_method
def gens(self):
Expand All @@ -56,3 +57,17 @@ def gens(self):
(a, b, c, d, e)
"""
return tuple(self.gen(i) for i in range(self.ngens()))

def monoid_generators(self):
r"""
Returns the generators for ``self``.
EXAMPLES::
sage: F.<a,b,c,d,e> = FreeMonoid(5)
sage: F.monoid_generators()
Family (a, b, c, d, e)
"""
from sage.sets.family import Family
return Family(self.gens())

0 comments on commit fc1eb23

Please sign in to comment.