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/11111-more_support_for_finite_dimensional_module…
Browse files Browse the repository at this point in the history
…s_and_algebras_with_basis' of trac.sagemath.org:sage into t/11111/more_support_for_finite_dimensional_modules_and_algebras_with_basis
  • Loading branch information
nthiery committed Apr 16, 2015
2 parents af995f4 + cfe399d commit a476501
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 39 deletions.
4 changes: 2 additions & 2 deletions src/sage/categories/finite_dimensional_modules_with_basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,13 @@ def annihilator_basis(self, S, action=operator.mul, side='right'):
By specifying the standard Lie bracket as action, one can
compute the commutator of a subspace of `F`::
sage: F.annihilator_basis([a+b], action = F.bracket)
sage: F.annihilator_basis([a+b], action=F.bracket)
[x + y, a, b]
In particular one can compute a basis of the center of the
algebra. In our example, it is reduced to the identity::
sage: F.annihilator_basis(F.algebra_generators(), action = F.bracket)
sage: F.annihilator_basis(F.algebra_generators(), action=F.bracket)
[x + y]
But see also
Expand Down
16 changes: 15 additions & 1 deletion src/sage/categories/modules_with_basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ def submodule(self, gens,
- ``gens`` -- a list or family of elements of ``self``
- ``check`` -- (default: True) whether to verify that the
- ``check`` -- (default: ``True``) whether to verify that the
elements of ``gens`` are in ``self``.
- ``already_echelonized`` -- (default: ``False``) whether
Expand Down Expand Up @@ -677,6 +677,20 @@ def submodule(self, gens,
...
ValueError: x[0] is not in the image
It is not necessary that the generators of the submodule form
a basis (an explicit basis will be computed)::
sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x")
sage: x = X.basis()
sage: gens = [x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]]; gens
[x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]]
sage: Y = X.submodule(gens, already_echelonized=False)
sage: Y.print_options(prefix='y')
sage: Y
Free module generated by {0, 1} over Rational Field
sage: [b.lift() for b in Y.basis()]
[x[0] - x[2], x[1] - x[2]]
We now implement by hand the center of the algebra of the
symmetric group `S_3`::
Expand Down
18 changes: 9 additions & 9 deletions src/sage/combinat/free_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -1590,11 +1590,11 @@ def set_order(self, order):
the one used in the generation of the elements of self's
associated enumerated set.
.. warning:: many cached methods depend on this order, in
particular for constructing subspaces and
quotients. Changing the order after computing such does
currently not invalidate those cache, and is likely to
bring in inconsistencies.
.. warning:: Many cached methods depend on this order, in
particular for constructing subspaces and quotients.
Changing the order after some computations have been
cached does not invalidate the cache, and is likely to
introduce inconsistencies.
EXAMPLES::
Expand Down Expand Up @@ -1626,7 +1626,7 @@ def get_order(self):

def get_order_cmp(self):
"""
Returns a comparison function on the basis indices which is
Returns a comparison function on the basis indices that is
compatible with the current term order.
EXAMPLES::
Expand Down Expand Up @@ -2068,15 +2068,15 @@ def echelon_form(self, elements, base_ring=None):
INPUT:
- ``elements`` - a list of elements of ``self``.
- ``base_ring`` - ring (default: ``None``): compute the echelon
form over the given ring; if ``base_ring`` is ``None``, then uses
the base ring of ``self``.
OUTPUT:
- list of elements of ``self``
EXAMPLES::
sage: F = CombinatorialFreeModule(ZZ, [1,2,3,4])
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/symmetric_group_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def SymmetricGroupAlgebra(R, W):
True
sage: TestSuite(SGA).run()
sage: SG=SymmetricGroupAlgebra(ZZ,3)
sage: SG = SymmetricGroupAlgebra(ZZ, 3)
sage: SG.group().conjugacy_classes_representatives()
[[1, 2, 3], [2, 1, 3], [2, 3, 1]]
Expand Down
58 changes: 32 additions & 26 deletions src/sage/modules/with_basis/subquotient.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Quotients of Modules With Basis
"""
#*****************************************************************************
# Copyright (C) 2010 Florent Hivert <Florent.Hivert@univ-mlv.fr>
# Copyright (C) 2010-2015 Florent Hivert <Florent.Hivert@univ-mlv.fr>
#
# Distributed under the terms of the GNU General Public License (GPL)
# http://www.gnu.org/licenses/
Expand All @@ -26,7 +26,7 @@ class QuotientModuleWithBasis(CombinatorialFreeModule):
should implement a method ``reduce``. Futheremore its ``lift``
method should have a method ``.cokernel_basis_indices`` that
computes the indexing set of a subset of the basis of ``self``
that spans some suplementary of ``submodule`` in the ambient
that spans some supplementary of ``submodule`` in the ambient
space. Mathematically speaking, ``submodule`` should be a free
submodule whose basis can be put in unitriangular echelon form.
Expand Down Expand Up @@ -57,7 +57,7 @@ class QuotientModuleWithBasis(CombinatorialFreeModule):
@staticmethod
def __classcall_private__(cls, submodule, category=None):
r"""
Normalize the input
Normalize the input.
TESTS::
Expand All @@ -76,18 +76,21 @@ def __classcall_private__(cls, submodule, category=None):

def __init__(self, submodule, category):
r"""
Initialization quotients of a module with basis by a submodule.
TESTS::
sage: from sage.modules.with_basis.subquotient import QuotientModuleWithBasis
sage: X = CombinatorialFreeModule(QQ, range(3)); x = X.basis()
sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x"); x = X.basis()
sage: I = X.submodule( (x[0]-x[1], x[1]-x[2]) )
sage: Y = QuotientModuleWithBasis(I)
sage: Y.print_options(prefix='y')
sage: Y
Free module generated by {2} over Rational Field
sage: Y.category()
Join of Category of finite dimensional modules with basis over Rational Field and Category of vector spaces with basis over Rational Field and Category of quotients of sets
sage: Y.basis().list()
[B[2]]
[y[2]]
sage: TestSuite(Y).run()
"""
self._submodule = submodule
Expand All @@ -104,15 +107,15 @@ def ambient(self):
EXAMPLES::
sage: X = CombinatorialFreeModule(QQ, range(3), prefix = "x"); x = X.basis()
sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x"); x = X.basis()
sage: Y = X.quotient_module((x[0]-x[1], x[1]-x[2]))
sage: Y.ambient() is X
True
"""
return self._ambient

def lift(self, x):
"""
r"""
Lift ``x`` to the ambient space of ``self``.
INPUT:
Expand All @@ -121,8 +124,8 @@ def lift(self, x):
EXAMPLES::
sage: X = CombinatorialFreeModule(QQ, range(3), prefix = "x"); x = X.basis()
sage: Y = X.quotient_module((x[0]-x[1], x[1]-x[2])); y = Y.basis()
sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x"); x = X.basis()
sage: Y = X.quotient_module((x[0]-x[1], x[1]-x[2])); y = Y.basis()
sage: Y.lift(y[2])
x[2]
"""
Expand All @@ -139,8 +142,8 @@ def retract(self, x):
EXAMPLES::
sage: X = CombinatorialFreeModule(QQ, range(3), prefix = "x"); x = X.basis()
sage: Y = X.quotient_module((x[0]-x[1], x[1]-x[2])); y = Y.basis()
sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x"); x = X.basis()
sage: Y = X.quotient_module((x[0]-x[1], x[1]-x[2])); y = Y.basis()
sage: Y.print_options(prefix='y')
sage: Y.retract(x[0])
y[2]
Expand All @@ -159,7 +162,7 @@ class SubmoduleWithBasis(CombinatorialFreeModule):
INPUT:
- ``basis`` -- a family of vectors in echelon form in some
- ``basis`` -- a family of elements in echelon form in some
:class:`module with basis <ModulesWithBasis>` `V`, or data that
can be converted into such a family
Expand Down Expand Up @@ -196,7 +199,7 @@ def __classcall_private__(cls, basis, ambient=None, category=None, *args, **opts
basis = Family(basis)
if ambient is None:
ambient = basis.an_element().parent()
default_category=ModulesWithBasis(ambient.category().base_ring()).Subobjects()
default_category = ModulesWithBasis(ambient.category().base_ring()).Subobjects()
category = default_category.or_subcategory(category, join=True)
return super(SubmoduleWithBasis, cls).__classcall__(
cls, basis, ambient, category, *args, **opts)
Expand All @@ -208,13 +211,14 @@ def __init__(self, basis, ambient, category):
TESTS::
sage: from sage.modules.with_basis.subquotient import SubmoduleWithBasis
sage: X = CombinatorialFreeModule(QQ, range(3)); x = X.basis()
sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x"); x = X.basis()
sage: ybas = (x[0]-x[1], x[1]-x[2])
sage: Y = SubmoduleWithBasis(ybas, X)
sage: Y.print_options(prefix='y')
sage: Y.basis().list()
[B[0], B[1]]
[y[0], y[1]]
sage: [ y.lift() for y in Y.basis() ]
[B[0] - B[1], B[1] - B[2]]
[x[0] - x[1], x[1] - x[2]]
sage: TestSuite(Y).run()
"""
import operator
Expand Down Expand Up @@ -245,20 +249,21 @@ def lift(self):
EXAMPLES::
sage: X = CombinatorialFreeModule(QQ, range(3)); x = X.basis()
sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x"); x = X.basis()
sage: Y = X.submodule((x[0]-x[1], x[1]-x[2]), already_echelonized=True); y = Y.basis()
sage: Y.lift
Generic morphism:
From: Free module generated by {0, 1} over Rational Field
To: Free module generated by {0, 1, 2} over Rational Field
sage: [ Y.lift(u) for u in y ]
[B[0] - B[1], B[1] - B[2]]
[x[0] - x[1], x[1] - x[2]]
sage: (y[0] + y[1]).lift()
B[0] - B[2]
x[0] - x[2]
"""
return self.module_morphism(self.lift_on_basis,
codomain=self.ambient(),
triangular="lower", cmp=self.ambient().get_order_cmp(),
triangular="lower",
cmp=self.ambient().get_order_cmp(),
inverse_on_support="compute")

@lazy_attribute
Expand All @@ -271,14 +276,14 @@ def reduce(self):
EXAMPLES::
sage: X = CombinatorialFreeModule(QQ, range(3)); x = X.basis()
sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x"); x = X.basis()
sage: Y = X.submodule((x[0]-x[1], x[1]-x[2]), already_echelonized=True)
sage: Y.reduce
Generic endomorphism of Free module generated by {0, 1, 2} over Rational Field
sage: Y.reduce(x[1])
B[2]
x[2]
sage: Y.reduce(2*x[0] + x[1])
3*B[2]
3*x[2]
TESTS::
Expand All @@ -294,14 +299,15 @@ def retract(self):
EXAMPLES::
sage: X = CombinatorialFreeModule(QQ, range(3)); x = X.basis()
sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x"); x = X.basis()
sage: Y = X.submodule((x[0]-x[1], x[1]-x[2]), already_echelonized=True)
sage: Y.print_options(prefix='y')
sage: Y.retract
Generic morphism:
From: Free module generated by {0, 1, 2} over Rational Field
To: Free module generated by {0, 1} over Rational Field
sage: Y.retract(x[0] - x[2])
B[0] + B[1]
y[0] + y[1]
TESTS::
Expand Down Expand Up @@ -334,7 +340,7 @@ def is_submodule(self, other):
if other is self.ambient():
return True
if not isinstance(self, SubmoduleWithBasis) and self.ambient() is other.ambient():
raise ValueError("other (=%s) should be a submodule of the same ambient space"%other)
raise ValueError("other (=%s) should be a submodule of the same ambient space" % other)
if not self in ModulesWithBasis.FiniteDimensional:
raise NotImplementedError("is_submodule for infinite dimensional modules")
for b in self.basis():
Expand Down

0 comments on commit a476501

Please sign in to comment.