Skip to content

Commit

Permalink
Trac #30094: Basis-dependent isomorphism from FiniteRankFreeModule to…
Browse files Browse the repository at this point in the history
… an object in the category ModulesWithBasis

(This ticket has been narrowed to the topic mainly discussed in the
comments. The topic originally in title and ticket description has been
moved to #30174)

There are multiple incompatible protocols for dealing with bases of a
free module in Sage (#19346).

One such protocol is defined by the category `ModulesWithBasis`.
`CombinatorialFreeModule` is one of the parent classes in this category.

Another such protocol is defined by the parent class
`FiniteRankFreeModule`, which is in the category `Modules`.
A `FiniteRankFreeModule` can be equipped with a finite list of bases
(each represented by an instance of `FreeModuleBasis`), none of which
are considered distinguished. `FiniteRankFreeModule`s are unique
parents; the operation of equipping a `FiniteRankFreeModule`  does not
change the identity of the parent.

We define a method `FiniteRankFreeModule. isomorphism_with_fixed_basis`
that establishes, given a basis, an isomorphism with a
`CombinatorialFreeModule` (and thus a parent in the category
`ModulesWithBasis`.

URL: https://trac.sagemath.org/30094
Reported by: mkoeppe
Ticket author(s): Matthias Koeppe, Michael Jung
Reviewer(s): Michael Jung, Matthias Koeppe, Eric Gourgoulhon, Travis
Scrimshaw
  • Loading branch information
Release Manager committed Jul 30, 2020
2 parents 653d0f4 + 8a800cc commit d14a2c5
Showing 1 changed file with 100 additions and 0 deletions.
100 changes: 100 additions & 0 deletions src/sage/tensor/modules/finite_rank_free_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -2515,6 +2515,106 @@ def hom(self, codomain, matrix_rep, bases=None, name=None,
return homset(matrix_rep, bases=bases, name=name,
latex_name=latex_name)

def isomorphism_with_fixed_basis(self, basis, codomain=None):
r"""
Construct the canonical isomorphism from the free module ``self``
to a free module in which ``basis`` of ``self`` is mapped to the
distinguished basis of ``codomain``.
INPUT:
- ``basis`` -- the basis of ``self`` which should be mapped to the
distinguished basis on ``codomain``
- ``codomain`` -- (default: ``None``) the codomain of the
isomorphism represented by a free module within the category
:class:`~sage.categories.modules_with_basis.ModulesWithBasis` with
the same rank and base ring as ``self``; if ``None`` a free module
represented by
:class:`~sage.combinat.free_module.CombinatorialFreeModule` is
constructed
OUTPUT:
- a module morphism represented by
:class:`~sage.modules.with_basis.morphism.ModuleMorphismFromFunction`
EXAMPLES::
sage: V = FiniteRankFreeModule(QQ, 3, start_index=1); V
3-dimensional vector space over the Rational Field
sage: basis = e = V.basis("e"); basis
Basis (e_1,e_2,e_3) on the 3-dimensional vector space over the
Rational Field
sage: phi_e = V.isomorphism_with_fixed_basis(basis); phi_e
Generic morphism:
From: 3-dimensional vector space over the Rational Field
To: Free module generated by {1, 2, 3} over Rational Field
sage: phi_e.codomain().category()
Category of finite dimensional vector spaces with basis over
Rational Field
sage: phi_e(e[1] + 2 * e[2])
e[1] + 2*e[2]
sage: abc = V.basis(['a', 'b', 'c'], symbol_dual=['d', 'e', 'f']); abc
Basis (a,b,c) on the 3-dimensional vector space over the Rational Field
sage: phi_abc = V.isomorphism_with_fixed_basis(abc); phi_abc
Generic morphism:
From: 3-dimensional vector space over the Rational Field
To: Free module generated by {1, 2, 3} over Rational Field
sage: phi_abc(abc[1] + 2 * abc[2])
B[1] + 2*B[2]
Providing a codomain::
sage: W = CombinatorialFreeModule(QQ, ['a', 'b', 'c'])
sage: phi_eW = V.isomorphism_with_fixed_basis(basis, codomain=W); phi_eW
Generic morphism:
From: 3-dimensional vector space over the Rational Field
To: Free module generated by {'a', 'b', 'c'} over Rational Field
sage: phi_eW(e[1] + 2 * e[2])
B['a'] + 2*B['b']
TESTS::
sage: V = FiniteRankFreeModule(QQ, 3); V
3-dimensional vector space over the Rational Field
sage: e = V.basis("e")
sage: V.isomorphism_with_fixed_basis(e, codomain=QQ^42)
Traceback (most recent call last):
...
ValueError: domain and codomain must have the same rank
sage: V.isomorphism_with_fixed_basis(e, codomain=RR^3)
Traceback (most recent call last):
...
ValueError: domain and codomain must have the same base ring
"""
base_ring = self.base_ring()
if codomain is None:
from sage.combinat.free_module import CombinatorialFreeModule
if isinstance(basis._symbol, str):
prefix = basis._symbol
else:
prefix = None
codomain = CombinatorialFreeModule(base_ring, list(self.irange()),
prefix=prefix)
else:
if codomain.rank() != self.rank():
raise ValueError("domain and codomain must have the same rank")
if codomain.base_ring() != base_ring:
raise ValueError("domain and codomain must have the same "
"base ring")

codomain_basis = list(codomain.basis())

def _isomorphism(x):
r"""
Concrete isomorphism from ``self`` to ``codomain``.
"""
return codomain.sum(x[basis, i] * codomain_basis[i - self._sindex]
for i in self.irange())

return self.module_morphism(function=_isomorphism, codomain=codomain)

def endomorphism(self, matrix_rep, basis=None, name=None, latex_name=None):
r"""
Construct an endomorphism of the free module ``self``.
Expand Down

0 comments on commit d14a2c5

Please sign in to comment.