Homomorphisms of finitely presented modules over the Steenrod algebra#
This class implements construction and basic manipulation of homomorphisms
between finitely presented graded modules
over the mod \(p\) Steenrod algebra.
AUTHORS:
Robert R. Bruner, Michael J. Catanzaro (2012): Initial version.
Sverre Lunoee–Nielsen and Koen van Woerden (2019-11-29): Updated the original software to Sage version 8.9.
Sverre Lunoee–Nielsen (2020-07-01): Refactored the code and added new documentation and tests.
- class sage.modules.fp_graded.steenrod.morphism.SteenrodFPModuleMorphism(parent, values, check=True)#
Bases:
FPModuleMorphism
- cokernel_projection(verbose=False)#
Compute the map to the cokernel of
self
.INPUT:
verbose
– (default:False
) whether log messages are printed
OUTPUT:
The natural projection from the codomain of this homomorphism to its cokernel.
EXAMPLES:
sage: from sage.modules.fp_graded.steenrod.module import SteenrodFPModule sage: A1 = SteenrodAlgebra(2, profile=(2,1)) sage: M = SteenrodFPModule(A1, [0], [[Sq(2)]]) sage: F = SteenrodFPModule(A1, [0]) sage: r = Hom(F, M)([A1.Sq(1)*M.generator(0)]) sage: co = r.cokernel_projection(); co Module morphism: From: Finitely presented left module on 1 generator and 1 relation over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [2, 1] To: Finitely presented left module on 1 generator and 2 relations over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [2, 1] Defn: g[0] |--> g[0] sage: co.domain().is_trivial() False
- image(top_dim=None, verbose=False)#
Return the image of
self
.INPUT:
top_dim
– integer (optional); used by this function to stop the computation at the given degreeverbose
– (default:False
) whether log messages are printed
OUTPUT:
An injective homomorphism into the codomain of
self
which is onto the image ofself
.EXAMPLES:
sage: from sage.modules.fp_graded.steenrod.module import SteenrodFPModule sage: A = SteenrodAlgebra(2) sage: M = SteenrodFPModule(A, [0,1], [[Sq(2),Sq(1)], [0,Sq(2)]]) sage: S = SteenrodFPModule(A, [0], [[Sq(2)]]) sage: f = Hom(S, M)([M([0,1])]) sage: f.is_injective() True sage: i = f.image(); i Module morphism: From: Finitely presented left module on 1 generator and 1 relation over mod 2 Steenrod algebra, milnor basis To: Finitely presented left module on 2 generators and 2 relations over mod 2 Steenrod algebra, milnor basis Defn: g[1] |--> g[1] sage: i.codomain() is M True
Lift the map
f
over the inclusioni
:sage: f_ = f.lift(i) sage: f_.is_injective() True sage: f_.is_surjective() True sage: g = Hom(S, M)([M([Sq(3),Sq(2)])]) sage: j = g.image(); j Module morphism: From: Free graded left module on 0 generators over mod 2 Steenrod algebra, milnor basis To: Finitely presented left module on 2 generators and 2 relations over mod 2 Steenrod algebra, milnor basis
So
g
had to be trivial:sage: g.is_zero() True
- is_injective(top_dim=None, verbose=False)#
Return
True
ifself
is injective.INPUT:
top_dim
– (optional) stop the computation at this degree; if not specified, this is determined usingprofile()
verbose
– (default:False
) whether log messages are printed
EXAMPLES:
sage: from sage.modules.fp_graded.steenrod.module import SteenrodFPModule sage: A = SteenrodAlgebra(2) sage: M = SteenrodFPModule(A, [0,1], [[Sq(2),Sq(1)], [0,Sq(2)]]) sage: S = SteenrodFPModule(A, [0], [[Sq(2)]]) sage: f = Hom(S, M)([M([0,1])]) sage: f.is_injective() True sage: g = Hom(S, M).zero() sage: g.is_injective() False sage: z = Hom(SteenrodFPModule(A, []), M).zero() sage: z.is_injective() True sage: z.is_zero() True
- kernel_inclusion(top_dim=None, verbose=False)#
Return the kernel of
self
as a morphism.INPUT:
top_dim
– (optional) stop the computation at this degree; if not specified, this is determined usingprofile()
verbose
– (default:False
) whether log messages are printed
OUTPUT: An injective homomorphism into the domain
self
which is onto the kernel of this homomorphism.EXAMPLES:
sage: from sage.modules.fp_graded.steenrod.module import SteenrodFPModule sage: A = SteenrodAlgebra(2) sage: M = SteenrodFPModule(A, [0,1], [[Sq(2),Sq(1)], [0,Sq(2)]]) sage: S = SteenrodFPModule(A, [0], [[Sq(2)]]) sage: f = Hom(S, M)([M([0,1])]) sage: f.is_injective() True sage: k = f.kernel_inclusion() sage: k == 0 True
Since k is both trivial and injective, its domain should be the zero module:
sage: k.domain().is_trivial() True sage: g = Hom(S, M)([M([Sq(3),Sq(2)])]) sage: h = g.kernel_inclusion() sage: h.is_identity() True sage: ker = h.domain(); sage: ker is S True
So \(g\) had to be trivial:
sage: g.is_zero() True
- profile()#
Return a finite profile over which
self
can be defined.This is in some ways the key method for these morphisms. As discussed in the “Theoretical background” section of
sage.modules.fp_graded.steenrod.module
, any homomorphism of finitely presented modules over the Steenrod algebra can be defined over a finite-dimensional sub-Hopf algebra, and this method identifies such a sub-Hopf algebra and returns its profile function.EXAMPLES:
sage: from sage.modules.fp_graded.steenrod.module import SteenrodFPModule sage: A = SteenrodAlgebra(2) sage: M = SteenrodFPModule(A, [0,1], [[Sq(2),Sq(1)], [0,Sq(2)]]) sage: one = Hom(M,M).identity() sage: one.profile() (2, 1) sage: zero = Hom(M,M).zero() sage: zero.profile() (2, 1) sage: A_fin = SteenrodAlgebra(2, profile=(2,1)) sage: M_fin = M.change_ring(A_fin)
Change the ring of the module
M
:sage: M_fin.change_ring(A) is M True
We can change rings to the finite sub-Hopf algebra defined by the profile we just computed:
sage: one_fin = one.change_ring(A_fin) sage: one_fin.domain() Finitely presented left module on 2 generators and 2 relations over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [2, 1]
If we change back to the full Steenrod algebra, we are back where we started:
sage: one_fin.change_ring(A) == one True
- class sage.modules.fp_graded.steenrod.morphism.SteenrodFreeModuleMorphism(parent, values)#