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

Commit

Permalink
Adding basic support for subalgebras
Browse files Browse the repository at this point in the history
  • Loading branch information
Travis Scrimshaw committed Oct 7, 2015
1 parent 2f7c727 commit 0f159aa
Show file tree
Hide file tree
Showing 9 changed files with 348 additions and 84 deletions.
1 change: 0 additions & 1 deletion src/sage/categories/algebras.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
from sage.categories.quotients import QuotientsCategory
from sage.categories.dual import DualObjectsCategory
from sage.categories.tensor import TensorProductsCategory
from sage.categories.subobjects import SubobjectsCategory
from sage.categories.associative_algebras import AssociativeAlgebras

class Algebras(CategoryWithAxiom_over_base_ring):
Expand Down
76 changes: 1 addition & 75 deletions src/sage/categories/finite_dimensional_algebras_with_basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class FiniteDimensionalAlgebrasWithBasis(CategoryWithAxiom_over_base_ring):
Category of finite dimensional algebras with basis over Rational Field
sage: C.super_categories()
[Category of algebras with basis over Rational Field,
Category of finite dimensional modules with basis over Rational Field]
Category of finite dimensional magmatic algebras with basis over Rational Field]
sage: C.example()
An example of a finite dimensional algebra with basis:
the path algebra of the Kronecker quiver
Expand Down Expand Up @@ -320,80 +320,6 @@ def semisimple_quotient(self):
result.rename("Semisimple quotient of {}".format(self))
return result


@cached_method
def center_basis(self):
r"""
Return a basis of the center of ``self``.
OUTPUT:
- a list of elements of ``self``.
.. SEEALSO:: :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.annihilator_basis(self.algebra_generators(), self.bracket)

@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 = Algebras(self.base_ring()).FiniteDimensional().Subobjects().Commutative().WithBasis()
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

def principal_ideal(self, a, side='left'):
r"""
Construct the ``side`` principal ideal generated by ``a``.
Expand Down
283 changes: 283 additions & 0 deletions src/sage/categories/finite_dimensional_magmatic_algebras_with_basis.py
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())

Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ def annihilator_basis(self, S, action=operator.mul, side='right'):
for s in S:
mat = mat.augment(matrix(self.base_ring(),
[action(s, b)._vector_() for b in self.basis()]))
return map(self.from_vector, mat.left_kernel().basis())
return [self.from_vector(b) for b in mat.left_kernel().basis()]

def quotient_module(self, submodule, check=True, already_echelonized=False, category=None):
r"""
Expand Down
Loading

0 comments on commit 0f159aa

Please sign in to comment.