This repository has been archived by the owner on Jan 30, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding basic support for subalgebras
- Loading branch information
Travis Scrimshaw
committed
Oct 7, 2015
1 parent
2f7c727
commit 0f159aa
Showing
9 changed files
with
348 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
283 changes: 283 additions & 0 deletions
283
src/sage/categories/finite_dimensional_magmatic_algebras_with_basis.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,283 @@ | ||
r""" | ||
Finite dimensional non-unital non-associative algebras with basis | ||
""" | ||
#***************************************************************************** | ||
# Copyright (C) 2015 Travis Scrimshaw <tscrimsh at umn.edu> | ||
# | ||
# Distributed under the terms of the GNU General Public License (GPL) | ||
# http://www.gnu.org/licenses/ | ||
#****************************************************************************** | ||
|
||
from sage.misc.cachefunc import cached_method | ||
from sage.categories.category_with_axiom import CategoryWithAxiom_over_base_ring | ||
from sage.categories.magmatic_algebras import MagmaticAlgebras | ||
from sage.categories.subobjects import SubobjectsCategory | ||
|
||
class FiniteDimensionalMagmaticAlgebrasWithBasis(CategoryWithAxiom_over_base_ring): | ||
""" | ||
The category of finite-dimensional (non-unital non-associative) | ||
algebras with a distinguished basis over a given base ring. | ||
EXAMPLES:: | ||
sage: from sage.categories.magmatic_algebras import MagmaticAlgebras | ||
sage: C = MagmaticAlgebras(ZZ).FiniteDimensional().WithBasis(); C | ||
Category of finite dimensional magmatic algebras with basis over Integer Ring | ||
sage: C.super_categories() | ||
[Category of magmatic algebras with basis over Integer Ring, | ||
Category of finite dimensional modules with basis over Integer Ring] | ||
TESTS:: | ||
sage: TestSuite(C).run() | ||
""" | ||
_base_category_class_and_axiom = (MagmaticAlgebras.WithBasis, "FiniteDimensional") | ||
|
||
class ParentMethods: | ||
def subalgebra(self, elements, category=None, *args, **opts): | ||
""" | ||
Return the subalgebra generated by ``elements``. | ||
.. WARNING:: | ||
If ``self`` is a unital algebra, then this does **not** | ||
force the unit to be in the subalgebra. | ||
.. TODO:: | ||
Implement a version that lazily constructs the basis and | ||
move the code to construct the basis to the corresponding | ||
subobject category as a ``basis`` method. | ||
EXAMPLES:: | ||
sage: G = groups.misc.WeylGroup(['B',2], prefix='s') | ||
sage: A = G.algebra(QQ) | ||
sage: gen = list(A.algebra_generators())[0] | ||
sage: S = A.subalgebra([gen], prefix='S') | ||
sage: S.basis() | ||
Finite family {0: S[0], 1: S[1]} | ||
sage: [A(b) for b in S.basis()] | ||
[B[1], B[s1]] | ||
sage: A = SymmetricGroupAlgebra(QQ, 3) | ||
sage: S = A.subalgebra([A([1,3,2])]) | ||
sage: [A(b) for b in S.basis()] | ||
[[1, 2, 3], [1, 3, 2]] | ||
""" | ||
from sage.matrix.constructor import matrix | ||
r = 0 | ||
mat = matrix([g._vector_() for g in elements]) | ||
mat.echelonize() | ||
vecs = [v for v in mat if v] | ||
basis = [self.from_vector(v) for v in vecs] | ||
while r != len(basis): | ||
r = len(basis) | ||
mat = matrix(vecs + [(g*h)._vector_() for g in basis for h in basis]) | ||
mat.echelonize() | ||
vecs = [v for v in mat if v] | ||
basis = [self.from_vector(v) for v in vecs] | ||
category = MagmaticAlgebras(self.category().base_ring()).or_subcategory(category) | ||
# We inherit associativity and commutativity | ||
if self in category.Associative(): | ||
category = category.Associative() | ||
if self in category.Commutative(): | ||
category = category.Commutative() | ||
category = category.FiniteDimensional() | ||
return self.submodule(basis, category=category.Subobjects().WithBasis(), | ||
already_echelonized=True, *args, **opts) | ||
|
||
def centralizer_basis(self, S): | ||
r""" | ||
Return a basis of the centralizer of ``S`` in ``self``. | ||
INPUT: | ||
- ``S`` -- a list of elements of ``self`` | ||
OUTPUT: | ||
- a list of elements of ``self`` | ||
.. SEEALSO:: :meth:`centralizer` | ||
EXAMPLES:: | ||
sage: A = SymmetricGroupAlgebra(QQ, 3) | ||
sage: A.center_basis() | ||
[[1, 2, 3], [1, 3, 2] + [2, 1, 3] + [3, 2, 1], [2, 3, 1] + [3, 1, 2]] | ||
sage: A.centralizer_basis([A([1,3,2])]) | ||
[[1, 2, 3], [1, 3, 2], [2, 1, 3] + [3, 2, 1], [2, 3, 1] + [3, 1, 2]] | ||
sage: A.centralizer_basis([A([1,2,3])]) | ||
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] | ||
""" | ||
return self.annihilator_basis(S, self.bracket) | ||
|
||
def centralizer(self, S): | ||
r""" | ||
Return the centralizer of ``S`` in ``self``. | ||
.. SEEALSO:: :meth:`centralizer_basis` | ||
EXAMPLES:: | ||
sage: A = SymmetricGroupAlgebra(QQ, 3) | ||
sage: C = A.centralizer([A([1,3,2])]); C | ||
Centralizer of [[1, 3, 2]] in | ||
Symmetric group algebra of order 3 over Rational Field | ||
sage: C.dimension() | ||
4 | ||
sage: C.basis() | ||
Finite family {0: B[0], 1: B[1], 2: B[2], 3: B[3]} | ||
sage: C.ambient() is A | ||
True | ||
sage: [A(b) for b in C.basis()] | ||
[[1, 2, 3], | ||
[1, 3, 2], | ||
[2, 1, 3] + [3, 2, 1], | ||
[2, 3, 1] + [3, 1, 2]] | ||
.. TODO:: | ||
- Pickling by construction, as ``A.center()``? | ||
- Lazy evaluation of ``_repr_`` | ||
TESTS:: | ||
sage: TestSuite(C).run() | ||
""" | ||
S = tuple(set(S)) | ||
category = MagmaticAlgebras(self.category().base_ring()).FiniteDimensional() | ||
# We inherit associativity, commutativity, and the unit | ||
if self in category.Associative(): | ||
category = category.Associative() | ||
if self in category.Unital(): | ||
category = category.Unital() | ||
if self in category.Commutative(): | ||
category = category.Commutative() | ||
category = category.Subobjects().WithBasis() | ||
center = self.submodule(self.centralizer_basis(S), | ||
category=category, | ||
already_echelonized=True) | ||
center.rename("Centralizer of {} in {}".format(list(S), self)) | ||
return center | ||
|
||
@cached_method | ||
def center_basis(self): | ||
r""" | ||
Return a basis of the center of ``self``. | ||
OUTPUT: | ||
- a list of elements of ``self`` | ||
.. SEEALSO:: :meth:`centralizer_basis` :meth:`center` | ||
EXAMPLES:: | ||
sage: A = Algebras(QQ).FiniteDimensional().WithBasis().example(); A | ||
An example of a finite dimensional algebra with basis: | ||
the path algebra of the Kronecker quiver | ||
(containing the arrows a:x->y and b:x->y) over Rational Field | ||
sage: A.center_basis() | ||
[x + y] | ||
""" | ||
return self.centralizer_basis(self.algebra_generators()) | ||
|
||
@cached_method | ||
def center(self): | ||
r""" | ||
Return the center of ``self``. | ||
.. SEEALSO:: :meth:`center_basis` | ||
EXAMPLES:: | ||
sage: A = Algebras(QQ).FiniteDimensional().WithBasis().example(); A | ||
An example of a finite dimensional algebra with basis: | ||
the path algebra of the Kronecker quiver | ||
(containing the arrows a:x->y and b:x->y) over Rational Field | ||
sage: center = A.center(); center | ||
Center of An example of a finite dimensional algebra with basis: | ||
the path algebra of the Kronecker quiver | ||
(containing the arrows a:x->y and b:x->y) over Rational Field | ||
sage: center in Algebras(QQ).WithBasis().FiniteDimensional().Commutative() | ||
True | ||
sage: center.dimension() | ||
1 | ||
sage: center.basis() | ||
Finite family {0: B[0]} | ||
sage: center.ambient() is A | ||
True | ||
sage: [c.lift() for c in center.basis()] | ||
[x + y] | ||
The center of a semisimple algebra is semisimple:: | ||
sage: DihedralGroup(6).algebra(QQ).center() in Algebras(QQ).Semisimple() | ||
True | ||
.. TODO:: | ||
- Pickling by construction, as ``A.center()``? | ||
- Lazy evaluation of ``_repr_`` | ||
TESTS:: | ||
sage: TestSuite(center).run() | ||
""" | ||
category = MagmaticAlgebras(self.category().base_ring()).FiniteDimensional() | ||
# We inherit associativity and the unit | ||
if self in category.Associative(): | ||
category = category.Associative() | ||
if self in category.Unital(): | ||
category = category.Unital() | ||
category = category.Commutative().Subobjects().WithBasis() | ||
from sage.categories.algebras import Algebras | ||
if self in Algebras.Semisimple: | ||
category = category.Semisimple() | ||
|
||
center = self.submodule(self.center_basis(), | ||
category=category, | ||
already_echelonized=True) | ||
center.rename("Center of {}".format(self)) | ||
return center | ||
|
||
class Subobjects(SubobjectsCategory): | ||
class ParentMethods: | ||
@cached_method | ||
def one(self): | ||
r""" | ||
Return the multiplicative unit element. | ||
EXAMPLES:: | ||
sage: A = SymmetricGroupAlgebra(QQ, 3) | ||
sage: S = A.subalgebra([A([1,2,3]), A([1,3,2])]) | ||
sage: S.one() | ||
B[0] | ||
TESTS: | ||
If the unit does not exist in the image, an error is | ||
raised (although perhaps not the most informative):: | ||
sage: R.<x> = QQ[] | ||
sage: Q = R.quo(x^2 - x) | ||
sage: G = Q.subsemigroup(Q.gen()) | ||
sage: A = G.algebra(QQ, category=Semigroups().Finite()) | ||
sage: b0,b1 = A.algebra_generators() | ||
sage: b1*b1 | ||
B[1] | ||
sage: S = A.subalgebra([b1], prefix='S') | ||
sage: S.basis() | ||
Finite family {0: S[0]} | ||
sage: [A(b) for b in S.basis()] | ||
[B[1]] | ||
sage: S.one() | ||
Traceback (most recent call last): | ||
... | ||
AttributeError: 'CombinatorialFreeModule_with_category' object has no attribute 'one' | ||
""" | ||
return self.retract(self.ambient().one()) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.