Skip to content

Commit

Permalink
Trac #8678: Improvements for morphisms of ModulesWithBasis
Browse files Browse the repository at this point in the history
This ticket implements:
 - inverses for morphisms of finite dimensional vector spaces
 - tensor products of morphisms
and improves:
 - triangular morphisms over base rings

Declares CombinatorialFreeModule indexed by a finite set as being finite
dimensional.

URL: http://trac.sagemath.org/8678
Reported by: nthiery
Ticket author(s): Nicolas M. Thiéry
Reviewer(s): Franco Saliola
  • Loading branch information
Release Manager authored and vbraun committed Apr 14, 2015
2 parents c987bf9 + 71b36da commit 8945466
Show file tree
Hide file tree
Showing 20 changed files with 1,994 additions and 998 deletions.
3 changes: 3 additions & 0 deletions src/doc/en/reference/modules/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,7 @@ Modules

sage/modules/diamond_cutting

sage/modules/with_basis/__init__
sage/modules/with_basis/morphism

.. include:: ../footer.txt
2 changes: 1 addition & 1 deletion src/sage/algebras/clifford_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from sage.categories.algebras_with_basis import AlgebrasWithBasis
from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis
from sage.categories.graded_hopf_algebras_with_basis import GradedHopfAlgebrasWithBasis
from sage.categories.modules_with_basis import ModuleMorphismByLinearity
from sage.modules.with_basis.morphism import ModuleMorphismByLinearity
from sage.categories.poor_man_map import PoorManMap
from sage.rings.all import ZZ
from sage.modules.free_module import FreeModule, FreeModule_generic
Expand Down
6 changes: 3 additions & 3 deletions src/sage/algebras/group_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class GroupAlgebraFunctor(ConstructionFunctor):
sage: loads(dumps(F)) == F
True
sage: GroupAlgebra(SU(2, GF(4, 'a')), IntegerModRing(12)).category()
Category of group algebras over Ring of integers modulo 12
Category of finite dimensional group algebras over Ring of integers modulo 12
"""
def __init__(self, group) :
r"""
Expand All @@ -146,7 +146,7 @@ def __init__(self, group) :
sage: from sage.algebras.group_algebra import GroupAlgebraFunctor
sage: GroupAlgebra(SU(2, GF(4, 'a')), IntegerModRing(12)).category()
Category of group algebras over Ring of integers modulo 12
Category of finite dimensional group algebras over Ring of integers modulo 12
"""
self.__group = group

Expand Down Expand Up @@ -234,7 +234,7 @@ class GroupAlgebra(CombinatorialFreeModule):
TypeError: "1" is not a group
sage: GroupAlgebra(SU(2, GF(4, 'a')), IntegerModRing(12)).category()
Category of group algebras over Ring of integers modulo 12
Category of finite dimensional group algebras over Ring of integers modulo 12
sage: GroupAlgebra(KleinFourGroup()) is GroupAlgebra(KleinFourGroup())
True
Expand Down
3 changes: 2 additions & 1 deletion src/sage/algebras/hall_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ def __init__(self, base_ring, q, prefix='H'):
I = self.monomial_basis()
M = I.module_morphism(I._to_natural_on_basis, codomain=self,
triangular='upper', unitriangular=True,
inverse_on_support=lambda x: x.conjugate())
inverse_on_support=lambda x: x.conjugate(),
invertible=True)
M.register_as_coercion()
(~M).register_as_coercion()

Expand Down
2 changes: 1 addition & 1 deletion src/sage/categories/examples/hopf_algebras_with_basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def __init__(self, R, G):
sage: from sage.categories.examples.hopf_algebras_with_basis import MyGroupAlgebra
sage: A = MyGroupAlgebra(QQ, DihedralGroup(6))
sage: A.category()
Category of hopf algebras with basis over Rational Field
Category of finite dimensional hopf algebras with basis over Rational Field
sage: TestSuite(A).run()
"""
self._group = G
Expand Down
8 changes: 4 additions & 4 deletions src/sage/categories/examples/with_realizations.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,13 @@ def __init__(self, R, S):
The subset algebra of {1, 2, 3} over Rational Field
sage: F, In, Out = A.realizations()
sage: type(F.coerce_map_from(In))
<class 'sage.categories.modules_with_basis.TriangularModuleMorphism'>
<class 'sage.modules.with_basis.morphism.TriangularModuleMorphismByLinearity_with_category'>
sage: type(In.coerce_map_from(F))
<class 'sage.categories.modules_with_basis.TriangularModuleMorphism'>
<class 'sage.modules.with_basis.morphism.TriangularModuleMorphismByLinearity_with_category'>
sage: type(F.coerce_map_from(Out))
<class 'sage.categories.modules_with_basis.TriangularModuleMorphism'>
<class 'sage.modules.with_basis.morphism.TriangularModuleMorphismByLinearity_with_category'>
sage: type(Out.coerce_map_from(F))
<class 'sage.categories.modules_with_basis.TriangularModuleMorphism'>
<class 'sage.modules.with_basis.morphism.TriangularModuleMorphismByLinearity_with_category'>
sage: In.coerce_map_from(Out)
Composite map:
From: The subset algebra of {1, 2, 3} over Rational Field in the Out basis
Expand Down
146 changes: 146 additions & 0 deletions src/sage/categories/finite_dimensional_modules_with_basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,149 @@ class ParentMethods:

class ElementMethods:
pass

class MorphismMethods:
def matrix(self, base_ring=None, side="left"):
r"""
Return the matrix of this morphism in the distinguished
bases of the domain and codomain.
INPUT:
- ``base_ring`` -- a ring (default: ``None``, meaning the
base ring of the codomain)
- ``side`` -- "left" or "right" (default: "left")
If ``side`` is "left", this morphism is considered as
acting on the left; i.e. each column of the matrix
represents the image of an element of the basis of the
domain.
The order of the rows and columns matches with the order
in which the bases are enumerated.
.. SEEALSO:: :func:`_from_matrix`
EXAMPLES::
sage: X = CombinatorialFreeModule(ZZ, [1,2]); x = X.basis()
sage: Y = CombinatorialFreeModule(ZZ, [3,4]); y = Y.basis()
sage: phi = X.module_morphism(on_basis = {1: y[3] + 3*y[4], 2: 2*y[3] + 5*y[4]}.__getitem__,
... codomain = Y)
sage: phi.matrix()
[1 2]
[3 5]
sage: phi.matrix(side="right")
[1 3]
[2 5]
sage: phi.matrix().parent()
Full MatrixSpace of 2 by 2 dense matrices over Integer Ring
sage: phi.matrix(QQ).parent()
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
The resulting matrix is immutable::
sage: phi.matrix().is_mutable()
False
The zero morphism has a zero matrix::
sage: Hom(X,Y).zero().matrix()
[0 0]
[0 0]
.. TODO::
Add support for morphisms where the codomain has a
different base ring than the domain::
sage: Y = CombinatorialFreeModule(QQ, [3,4]); y = Y.basis()
sage: phi = X.module_morphism(on_basis = {1: y[3] + 3*y[4], 2: 2*y[3] + 5/2*y[4]}.__getitem__,
... codomain = Y)
sage: phi.matrix().parent() # todo: not implemented
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
This currently does not work because, in this case,
the morphism is just in the category of commutative
additive groups (i.e. the intersection of the
categories of modules over `\ZZ` and over `\QQ`)::
sage: phi.parent().homset_category()
Category of commutative additive semigroups
sage: phi.parent().homset_category() # todo: not implemented
Category of finite dimensional modules with basis over Integer Ring
"""
from sage.matrix.constructor import matrix
if base_ring is None:
base_ring = self.codomain().base_ring()

on_basis = self.on_basis()
basis_keys = self.domain().basis().keys()
m = matrix(base_ring,
[on_basis(x).to_vector() for x in basis_keys])
if side == "left":
m = m.transpose()
m.set_immutable()
return m

def __invert__(self):
"""
Return the inverse morphism of ``self``.
This is achieved by inverting the ``self.matrix()``.
An error is raised if ``self`` is not invertible.
EXAMPLES::
sage: category = FiniteDimensionalModulesWithBasis(ZZ)
sage: X = CombinatorialFreeModule(ZZ, [1,2], category = category); X.rename("X"); x = X.basis()
sage: Y = CombinatorialFreeModule(ZZ, [3,4], category = category); Y.rename("Y"); y = Y.basis()
sage: phi = X.module_morphism(on_basis = {1: y[3] + 3*y[4], 2: 2*y[3] + 5*y[4]}.__getitem__,
... codomain = Y, category = category)
sage: psi = ~phi
sage: psi
Generic morphism:
From: Y
To: X
sage: psi.parent()
Set of Morphisms from Y to X in Category of finite dimensional modules with basis over Integer Ring
sage: psi(y[3])
-5*B[1] + 3*B[2]
sage: psi(y[4])
2*B[1] - B[2]
sage: psi.matrix()
[-5 2]
[ 3 -1]
sage: psi(phi(x[1])), psi(phi(x[2]))
(B[1], B[2])
sage: phi(psi(y[3])), phi(psi(y[4]))
(B[3], B[4])
We check that this function complains if the morphism is not invertible::
sage: phi = X.module_morphism(on_basis = {1: y[3] + y[4], 2: y[3] + y[4]}.__getitem__,
... codomain = Y, category = category)
sage: ~phi
Traceback (most recent call last):
...
RuntimeError: morphism is not invertible
sage: phi = X.module_morphism(on_basis = {1: y[3] + y[4], 2: y[3] + 5*y[4]}.__getitem__,
... codomain = Y, category = category)
sage: ~phi
Traceback (most recent call last):
...
RuntimeError: morphism is not invertible
"""
from sage.categories.homset import Hom
mat = self.matrix()
try:
inv_mat = mat.parent()(~mat)
except (ZeroDivisionError, TypeError):
raise RuntimeError, "morphism is not invertible"
return self.codomain().module_morphism(
matrix=inv_mat,
codomain=self.domain(), category=self.category_for())

2 changes: 1 addition & 1 deletion src/sage/categories/hopf_algebras_with_basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class HopfAlgebrasWithBasis(CategoryWithAxiom_over_base_ring):
An example of Hopf algebra with basis: the group algebra of the Dihedral group of order 6 as a permutation group over Rational Field
sage: A.__custom_name = "A"
sage: A.category()
Category of hopf algebras with basis over Rational Field
Category of finite dimensional hopf algebras with basis over Rational Field
sage: A.one_basis()
()
Expand Down
2 changes: 1 addition & 1 deletion src/sage/categories/magmas.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ def FinitelyGenerated(self):
an additive structure. As of Sage 6.4, this is
correct.
The use of this shorthand should be reserved to casual
The use of this shorthand should be reserved for casual
interactive use or when there is no risk of ambiguity.
"""
from sage.categories.additive_magmas import AdditiveMagmas
Expand Down
Loading

0 comments on commit 8945466

Please sign in to comment.