Homomorphisms of finitely presented graded modules#

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.morphism.FPModuleMorphism(parent, values, check=True)[source]#

Bases: Morphism

Create a homomorphism between finitely presented graded modules.

INPUT:

  • parent – a homspace of finitely presented graded modules

  • values – a list of elements in the codomain; each element corresponds to a module generator in the domain

  • check – boolean (default: True); if True, check that the morphism is well-defined

change_ring(algebra)[source]#

Change the base ring of self.

INPUT:

  • algebra – a graded algebra

EXAMPLES:

sage: from sage.modules.fp_graded.module import FPModule
sage: A2 = SteenrodAlgebra(2, profile=(3,2,1))
sage: A3 = SteenrodAlgebra(2, profile=(4,3,2,1))
sage: M = FPModule(A2, [0], relations=[[Sq(1)]])
sage: N = FPModule(A2, [0], relations=[[Sq(4)],[Sq(1)]])

sage: f = Hom(M,N)([A2.Sq(3)*N.generator(0)]); f
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 [3, 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 [3, 2, 1]
  Defn: g[0] |--> Sq(3)*g[0]

sage: f.base_ring()
sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [3, 2, 1]

sage: g = f.change_ring(A3)
sage: g.base_ring()
sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
>>> from sage.all import *
>>> from sage.modules.fp_graded.module import FPModule
>>> A2 = SteenrodAlgebra(Integer(2), profile=(Integer(3),Integer(2),Integer(1)))
>>> A3 = SteenrodAlgebra(Integer(2), profile=(Integer(4),Integer(3),Integer(2),Integer(1)))
>>> M = FPModule(A2, [Integer(0)], relations=[[Sq(Integer(1))]])
>>> N = FPModule(A2, [Integer(0)], relations=[[Sq(Integer(4))],[Sq(Integer(1))]])

>>> f = Hom(M,N)([A2.Sq(Integer(3))*N.generator(Integer(0))]); f
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 [3, 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 [3, 2, 1]
  Defn: g[0] |--> Sq(3)*g[0]

>>> f.base_ring()
sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [3, 2, 1]

>>> g = f.change_ring(A3)
>>> g.base_ring()
sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
cokernel_projection()[source]#

Return the map to the cokernel of self.

OUTPUT:

The natural projection from the codomain of this homomorphism to its cokernel.

EXAMPLES:

sage: from sage.modules.fp_graded.module import FPModule
sage: A1 = SteenrodAlgebra(2, profile=(2,1))
sage: M = FPModule(A1, [0], [[Sq(2)]])
sage: F = FPModule(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
>>> from sage.all import *
>>> from sage.modules.fp_graded.module import FPModule
>>> A1 = SteenrodAlgebra(Integer(2), profile=(Integer(2),Integer(1)))
>>> M = FPModule(A1, [Integer(0)], [[Sq(Integer(2))]])
>>> F = FPModule(A1, [Integer(0)])

>>> r = Hom(F, M)([A1.Sq(Integer(1))*M.generator(Integer(0))])
>>> 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]

>>> co.domain().is_trivial()
False
degree()[source]#

The degree of self.

OUTPUT:

The integer degree of self.

EXAMPLES:

sage: from sage.modules.fp_graded.module import *
sage: A = SteenrodAlgebra(2)
sage: M = FPModule(A, [0,1], [[Sq(2), Sq(1)]])
sage: N = FPModule(A, [2], [[Sq(4)]])
sage: homspace = Hom(M, N)

sage: values = [Sq(5)*N.generator(0), Sq(3,1)*N.generator(0)]
sage: f = homspace(values)
sage: f.degree()
7
>>> from sage.all import *
>>> from sage.modules.fp_graded.module import *
>>> A = SteenrodAlgebra(Integer(2))
>>> M = FPModule(A, [Integer(0),Integer(1)], [[Sq(Integer(2)), Sq(Integer(1))]])
>>> N = FPModule(A, [Integer(2)], [[Sq(Integer(4))]])
>>> homspace = Hom(M, N)

>>> values = [Sq(Integer(5))*N.generator(Integer(0)), Sq(Integer(3),Integer(1))*N.generator(Integer(0))]
>>> f = homspace(values)
>>> f.degree()
7

The trivial homomorphism has no degree:

sage: homspace.zero().degree()
Traceback (most recent call last):
...
ValueError: the zero morphism does not have a well-defined degree
>>> from sage.all import *
>>> homspace.zero().degree()
Traceback (most recent call last):
...
ValueError: the zero morphism does not have a well-defined degree
fp_module()[source]#

Create a finitely presented module from self.

OUTPUT:

The finitely presented module having presentation equal to self as long as the domain and codomain are free.

EXAMPLES:

We construct examples with free modules that are presented with a redundant relation:

sage: from sage.modules.fp_graded.module import FPModule
sage: A = SteenrodAlgebra(2)
sage: F1 = FPModule(A, (2,), [[0]])
sage: F2 = FPModule(A, (0,), [[0]])
sage: v = F2([Sq(2)])
sage: pres = Hom(F1, F2)([v])
sage: M = pres.fp_module(); M
Finitely presented left module on 1 generator and 1 relation over
 mod 2 Steenrod algebra, milnor basis
sage: M.generator_degrees()
(0,)
sage: M.relations()
(Sq(2)*g[0],)

sage: F2 = A.free_graded_module((0,))
sage: v = F2([Sq(2)])
sage: pres = Hom(F1, F2)([v])
sage: M = pres.fp_module(); M
Finitely presented left module on 1 generator and 1 relation over
 mod 2 Steenrod algebra, milnor basis
sage: M.generator_degrees()
(0,)
sage: M.relations()
(Sq(2)*g[0],)

sage: F3 = FPModule(A, (0,), [[Sq(4)]])
sage: v = F3([Sq(2)])
sage: pres = Hom(F1, F3)([v])
sage: pres.fp_module()
Traceback (most recent call last):
...
ValueError: this is not a morphism between free modules
>>> from sage.all import *
>>> from sage.modules.fp_graded.module import FPModule
>>> A = SteenrodAlgebra(Integer(2))
>>> F1 = FPModule(A, (Integer(2),), [[Integer(0)]])
>>> F2 = FPModule(A, (Integer(0),), [[Integer(0)]])
>>> v = F2([Sq(Integer(2))])
>>> pres = Hom(F1, F2)([v])
>>> M = pres.fp_module(); M
Finitely presented left module on 1 generator and 1 relation over
 mod 2 Steenrod algebra, milnor basis
>>> M.generator_degrees()
(0,)
>>> M.relations()
(Sq(2)*g[0],)

>>> F2 = A.free_graded_module((Integer(0),))
>>> v = F2([Sq(Integer(2))])
>>> pres = Hom(F1, F2)([v])
>>> M = pres.fp_module(); M
Finitely presented left module on 1 generator and 1 relation over
 mod 2 Steenrod algebra, milnor basis
>>> M.generator_degrees()
(0,)
>>> M.relations()
(Sq(2)*g[0],)

>>> F3 = FPModule(A, (Integer(0),), [[Sq(Integer(4))]])
>>> v = F3([Sq(Integer(2))])
>>> pres = Hom(F1, F3)([v])
>>> pres.fp_module()
Traceback (most recent call last):
...
ValueError: this is not a morphism between free modules
homology(f, top_dim=None, verbose=False)[source]#

Compute the sub-quotient module of \(H(self, f) = \ker(self)/\operatorname{im}(f)\) in a range of degrees.

For a pair of composable morphisms \(f: M\to N\) and \(g: N \to Q\) of finitely presented modules, the homology module is a finitely presented quotient of the kernel sub module \(\ker(g) \subset N\).

INPUT:

  • f – a homomorphism with codomain equal to the domain of self and image contained in the kernel of this homomorphism

  • top_dim – integer (optional); used by this function to stop the computation at the given degree

  • verbose – boolean (default: False); enable progress messages

OUTPUT:

A quotient homomorphism \(\ker(self) \to H\), where \(H\) is isomorphic to \(H(self, f)\) in degrees less than or equal to top_dim.

Note

If the algebra for this module is finite, then no top_dim needs to be specified in order to ensure that this function terminates.

EXAMPLES:

sage: from sage.modules.fp_graded.module import FPModule
sage: A = SteenrodAlgebra(2, profile=(3,2,1))
sage: M = FPModule(A, [0], [[Sq(3)]])
sage: N = FPModule(A, [0], [[Sq(2,2)]])
sage: F = FPModule(A, [0])
sage: f = Hom(M,N)([A.Sq(2)*N.generator(0)])
sage: g = Hom(F, M)([A.Sq(4)*A.Sq(1,2)*M.generator(0)])
sage: ho = f.homology(g)
sage: ho.codomain()
Finitely presented left module on 1 generator and 5 relations over
 sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [3, 2, 1]
sage: ho.codomain().is_trivial()
False
>>> from sage.all import *
>>> from sage.modules.fp_graded.module import FPModule
>>> A = SteenrodAlgebra(Integer(2), profile=(Integer(3),Integer(2),Integer(1)))
>>> M = FPModule(A, [Integer(0)], [[Sq(Integer(3))]])
>>> N = FPModule(A, [Integer(0)], [[Sq(Integer(2),Integer(2))]])
>>> F = FPModule(A, [Integer(0)])
>>> f = Hom(M,N)([A.Sq(Integer(2))*N.generator(Integer(0))])
>>> g = Hom(F, M)([A.Sq(Integer(4))*A.Sq(Integer(1),Integer(2))*M.generator(Integer(0))])
>>> ho = f.homology(g)
>>> ho.codomain()
Finitely presented left module on 1 generator and 5 relations over
 sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [3, 2, 1]
>>> ho.codomain().is_trivial()
False
image(top_dim=None, verbose=False)[source]#

Compute the image of self.

INPUT:

  • top_dim – integer (optional); used by this function to stop the computation at the given degree

  • verbose – boolean (default: False); enable progress messages

OUTPUT:

A homomorphism into \(\operatorname{im}(self)\) that is an isomorphism in degrees less than or equal to top_dim

Note

If the algebra for this module is finite, then no top_dim needs to be specified in order to ensure that this function terminates.

EXAMPLES:

sage: from sage.modules.fp_graded.module import FPModule
sage: A3 = SteenrodAlgebra(2, profile=(4,3,2,1))
sage: F = FPModule(A3, [1,3]);
sage: L = FPModule(A3, [2,3], [[Sq(2),Sq(1)], [0,Sq(2)]]);
sage: H = Hom(F, L);

sage: H([L((A3.Sq(1), 1)), L((0, A3.Sq(2)))]).image() # long time
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 [4, 3, 2, 1]
  To:   Finitely presented left module on 2 generators and 2 relations over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
  Defn: g[3] |--> Sq(1)*g[2] + g[3]

sage: M = FPModule(A3, [0,7], [[Sq(1), 0], [Sq(2), 0], [Sq(4), 0], [Sq(8), Sq(1)], [0, Sq(7)], [0, Sq(0,1,1)+Sq(4,2)]])
sage: F2 = FPModule(A3, [0], [[Sq(1)], [Sq(2)], [Sq(4)], [Sq(8)], [Sq(15)]])
sage: H = Hom(M, F2)
sage: f = H([F2([1]), F2([0])])
sage: K = f.image(verbose=True, top_dim=17)
1. Computing the generators of the image presentation:
Resolving the image in the range of dimensions [0, 17]:
 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17.
2. Computing the relations of the image presentation:
Computing using the profile:
(4, 3, 2, 1)
Resolving the kernel in the range of dimensions [0, 17]:
 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17.

sage: K.is_injective()  # long time
True
sage: K.domain().generator_degrees()
(0,)
sage: K.domain().relations()
(Sq(1)*g[0], Sq(2)*g[0], Sq(4)*g[0], Sq(8)*g[0])
sage: K.domain().is_trivial()
False
>>> from sage.all import *
>>> from sage.modules.fp_graded.module import FPModule
>>> A3 = SteenrodAlgebra(Integer(2), profile=(Integer(4),Integer(3),Integer(2),Integer(1)))
>>> F = FPModule(A3, [Integer(1),Integer(3)]);
>>> L = FPModule(A3, [Integer(2),Integer(3)], [[Sq(Integer(2)),Sq(Integer(1))], [Integer(0),Sq(Integer(2))]]);
>>> H = Hom(F, L);

>>> H([L((A3.Sq(Integer(1)), Integer(1))), L((Integer(0), A3.Sq(Integer(2))))]).image() # long time
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 [4, 3, 2, 1]
  To:   Finitely presented left module on 2 generators and 2 relations over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
  Defn: g[3] |--> Sq(1)*g[2] + g[3]

>>> M = FPModule(A3, [Integer(0),Integer(7)], [[Sq(Integer(1)), Integer(0)], [Sq(Integer(2)), Integer(0)], [Sq(Integer(4)), Integer(0)], [Sq(Integer(8)), Sq(Integer(1))], [Integer(0), Sq(Integer(7))], [Integer(0), Sq(Integer(0),Integer(1),Integer(1))+Sq(Integer(4),Integer(2))]])
>>> F2 = FPModule(A3, [Integer(0)], [[Sq(Integer(1))], [Sq(Integer(2))], [Sq(Integer(4))], [Sq(Integer(8))], [Sq(Integer(15))]])
>>> H = Hom(M, F2)
>>> f = H([F2([Integer(1)]), F2([Integer(0)])])
>>> K = f.image(verbose=True, top_dim=Integer(17))
1. Computing the generators of the image presentation:
Resolving the image in the range of dimensions [0, 17]:
 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17.
2. Computing the relations of the image presentation:
Computing using the profile:
(4, 3, 2, 1)
Resolving the kernel in the range of dimensions [0, 17]:
 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17.

>>> K.is_injective()  # long time
True
>>> K.domain().generator_degrees()
(0,)
>>> K.domain().relations()
(Sq(1)*g[0], Sq(2)*g[0], Sq(4)*g[0], Sq(8)*g[0])
>>> K.domain().is_trivial()
False
is_identity()[source]#

Decide if self is the identity endomorphism.

EXAMPLES:

sage: from sage.modules.fp_graded.module import *
sage: A = SteenrodAlgebra(2)
sage: M = FPModule(A, [0,1], [[Sq(2), Sq(1)]])
sage: N = FPModule(A, [2], [[Sq(4)]])
sage: values = [Sq(5)*N.generator(0), Sq(3,1)*N.generator(0)]

sage: f = Hom(M, N)(values)
sage: f.is_identity()
False

sage: one = Hom(M, M)(M.generators()); one
Module endomorphism of Finitely presented left module on 2 generators and 1 relation over mod 2 Steenrod algebra, milnor basis
  Defn: g[0] |--> g[0]
        g[1] |--> g[1]

sage: one.is_identity()
True

sage: M = A.free_graded_module((0,1))
sage: N = A.free_graded_module((2,))
sage: v = N.generator(0)
sage: values = [Sq(5)*v, Sq(3,1)*v]
sage: f = Hom(M, N)(values)
sage: f.is_identity()
False
sage: one = Hom(M, M)(M.generators()); one
Module endomorphism of Free graded left module on 2 generators over mod 2 Steenrod algebra, milnor basis
  Defn: g[0] |--> g[0]
        g[1] |--> g[1]
sage: one.is_identity()
True
>>> from sage.all import *
>>> from sage.modules.fp_graded.module import *
>>> A = SteenrodAlgebra(Integer(2))
>>> M = FPModule(A, [Integer(0),Integer(1)], [[Sq(Integer(2)), Sq(Integer(1))]])
>>> N = FPModule(A, [Integer(2)], [[Sq(Integer(4))]])
>>> values = [Sq(Integer(5))*N.generator(Integer(0)), Sq(Integer(3),Integer(1))*N.generator(Integer(0))]

>>> f = Hom(M, N)(values)
>>> f.is_identity()
False

>>> one = Hom(M, M)(M.generators()); one
Module endomorphism of Finitely presented left module on 2 generators and 1 relation over mod 2 Steenrod algebra, milnor basis
  Defn: g[0] |--> g[0]
        g[1] |--> g[1]

>>> one.is_identity()
True

>>> M = A.free_graded_module((Integer(0),Integer(1)))
>>> N = A.free_graded_module((Integer(2),))
>>> v = N.generator(Integer(0))
>>> values = [Sq(Integer(5))*v, Sq(Integer(3),Integer(1))*v]
>>> f = Hom(M, N)(values)
>>> f.is_identity()
False
>>> one = Hom(M, M)(M.generators()); one
Module endomorphism of Free graded left module on 2 generators over mod 2 Steenrod algebra, milnor basis
  Defn: g[0] |--> g[0]
        g[1] |--> g[1]
>>> one.is_identity()
True
is_injective(top_dim=None, verbose=False)[source]#

Return True if and only if self has a trivial kernel.

INPUT:

  • top_dim – integer (optional); used by this function to stop the computation at the given degree

  • verbose – boolean (default: False); enable progress messages

EXAMPLES:

sage: from sage.modules.fp_graded.module import FPModule
sage: A = SteenrodAlgebra(2)

sage: K = FPModule(A, [2], [[Sq(2)]])
sage: HZ = FPModule(A, [0], [[Sq(1)]])

sage: f = Hom(K, HZ)([Sq(2)*HZ([1])])
sage: f.is_injective(top_dim=23)
True
>>> from sage.all import *
>>> from sage.modules.fp_graded.module import FPModule
>>> A = SteenrodAlgebra(Integer(2))

>>> K = FPModule(A, [Integer(2)], [[Sq(Integer(2))]])
>>> HZ = FPModule(A, [Integer(0)], [[Sq(Integer(1))]])

>>> f = Hom(K, HZ)([Sq(Integer(2))*HZ([Integer(1)])])
>>> f.is_injective(top_dim=Integer(23))
True
is_surjective()[source]#

Return True if and only if self has a trivial cokernel.

EXAMPLES:

sage: from sage.modules.fp_graded.module import FPModule
sage: A = SteenrodAlgebra(2)
sage: F = FPModule(A, [0])

sage: f = Hom(F,F)([Sq(1)*F.generator(0)])
sage: f.is_surjective()
False
>>> from sage.all import *
>>> from sage.modules.fp_graded.module import FPModule
>>> A = SteenrodAlgebra(Integer(2))
>>> F = FPModule(A, [Integer(0)])

>>> f = Hom(F,F)([Sq(Integer(1))*F.generator(Integer(0))])
>>> f.is_surjective()
False
is_zero()[source]#

Decide if self is the zero homomorphism.

OUTPUT:

The boolean value True if self is trivial and False otherwise.

EXAMPLES:

sage: from sage.modules.fp_graded.module import FPModule
sage: A = SteenrodAlgebra(2)
sage: M = FPModule(A, [0,1], [[Sq(2), Sq(1)]])
sage: N = FPModule(A, [2], [[Sq(4)]])
sage: values = [Sq(5)*N.generator(0), Sq(3,1)*N.generator(0)]

sage: f = Hom(M, N)(values)
sage: f.is_zero()
False

sage: (f-f).is_zero()
True

sage: M = A.free_graded_module((0,1))
sage: N = A.free_graded_module((2,))
sage: v = N.generator(0)
sage: values = [Sq(5)*v, Sq(3,1)*v]
sage: f = Hom(M, N)(values)
sage: f.is_zero()
False
sage: (f-f).is_zero()
True
>>> from sage.all import *
>>> from sage.modules.fp_graded.module import FPModule
>>> A = SteenrodAlgebra(Integer(2))
>>> M = FPModule(A, [Integer(0),Integer(1)], [[Sq(Integer(2)), Sq(Integer(1))]])
>>> N = FPModule(A, [Integer(2)], [[Sq(Integer(4))]])
>>> values = [Sq(Integer(5))*N.generator(Integer(0)), Sq(Integer(3),Integer(1))*N.generator(Integer(0))]

>>> f = Hom(M, N)(values)
>>> f.is_zero()
False

>>> (f-f).is_zero()
True

>>> M = A.free_graded_module((Integer(0),Integer(1)))
>>> N = A.free_graded_module((Integer(2),))
>>> v = N.generator(Integer(0))
>>> values = [Sq(Integer(5))*v, Sq(Integer(3),Integer(1))*v]
>>> f = Hom(M, N)(values)
>>> f.is_zero()
False
>>> (f-f).is_zero()
True
kernel_inclusion(top_dim=None, verbose=False)[source]#

Return the kernel of self.

INPUT:

  • top_dim – integer (optional); used by this function to stop the computation at the given degree

  • verbose – boolean (default: False); enable progress messages

OUTPUT:

A homomorphism into \(\ker(self)\) which is an isomorphism in degrees less than or equal to top_dim.

Note

If the algebra for this module is finite, then no top_dim needs to be specified in order to ensure that this function terminates.

EXAMPLES:

sage: from sage.modules.fp_graded.module import FPModule
sage: A3 = SteenrodAlgebra(2, profile=(4,3,2,1))
sage: F = FPModule(A3, [1,3]);
sage: L = FPModule(A3, [2,3], [[Sq(2),Sq(1)], [0,Sq(2)]]);
sage: H = Hom(F, L);

sage: H([L((A3.Sq(1), 1)), L((0, A3.Sq(2)))]).kernel_inclusion() # long time
Module morphism:
  From: Finitely presented left module on 2 generators and 1 relation over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
  To:   Free graded left module on 2 generators over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
  Defn: g[3] |--> g[3]
        g[4] |--> Sq(0,1)*g[1]

sage: M = FPModule(A3, [0,7], [[Sq(1), 0], [Sq(2), 0], [Sq(4), 0], [Sq(8), Sq(1)], [0, Sq(7)], [0, Sq(0,1,1)+Sq(4,2)]])
sage: F2 = FPModule(A3, [0], [[Sq(1)], [Sq(2)], [Sq(4)], [Sq(8)], [Sq(15)]])
sage: H = Hom(M, F2)
sage: f = H([F2([1]), F2([0])])

sage: K = f.kernel_inclusion(verbose=True, top_dim=17)
1. Computing the generators of the kernel presentation:
Resolving the kernel in the range of dimensions [0, 17]:
 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17.
2. Computing the relations of the kernel presentation:
Computing using the profile:
(4, 3, 2, 1)
Resolving the kernel in the range of dimensions [7, 17]:
 7 8 9 10 11 12 13 14 15 16 17.

sage: K.domain().generators()
(g[7],)
sage: K.domain().relations()
((Sq(0,1)+Sq(3))*g[7],
 (Sq(0,0,1)+Sq(1,2)+Sq(4,1))*g[7],
 Sq(9)*g[7],
 (Sq(0,1,1)+Sq(4,2))*g[7])

sage: K
Module morphism:
  From: Finitely presented left module on 1 generator and 4 relations over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
  To:   Finitely presented left module on 2 generators and 6 relations over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
  Defn: g[7] |--> g[7]
>>> from sage.all import *
>>> from sage.modules.fp_graded.module import FPModule
>>> A3 = SteenrodAlgebra(Integer(2), profile=(Integer(4),Integer(3),Integer(2),Integer(1)))
>>> F = FPModule(A3, [Integer(1),Integer(3)]);
>>> L = FPModule(A3, [Integer(2),Integer(3)], [[Sq(Integer(2)),Sq(Integer(1))], [Integer(0),Sq(Integer(2))]]);
>>> H = Hom(F, L);

>>> H([L((A3.Sq(Integer(1)), Integer(1))), L((Integer(0), A3.Sq(Integer(2))))]).kernel_inclusion() # long time
Module morphism:
  From: Finitely presented left module on 2 generators and 1 relation over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
  To:   Free graded left module on 2 generators over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
  Defn: g[3] |--> g[3]
        g[4] |--> Sq(0,1)*g[1]

>>> M = FPModule(A3, [Integer(0),Integer(7)], [[Sq(Integer(1)), Integer(0)], [Sq(Integer(2)), Integer(0)], [Sq(Integer(4)), Integer(0)], [Sq(Integer(8)), Sq(Integer(1))], [Integer(0), Sq(Integer(7))], [Integer(0), Sq(Integer(0),Integer(1),Integer(1))+Sq(Integer(4),Integer(2))]])
>>> F2 = FPModule(A3, [Integer(0)], [[Sq(Integer(1))], [Sq(Integer(2))], [Sq(Integer(4))], [Sq(Integer(8))], [Sq(Integer(15))]])
>>> H = Hom(M, F2)
>>> f = H([F2([Integer(1)]), F2([Integer(0)])])

>>> K = f.kernel_inclusion(verbose=True, top_dim=Integer(17))
1. Computing the generators of the kernel presentation:
Resolving the kernel in the range of dimensions [0, 17]:
 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17.
2. Computing the relations of the kernel presentation:
Computing using the profile:
(4, 3, 2, 1)
Resolving the kernel in the range of dimensions [7, 17]:
 7 8 9 10 11 12 13 14 15 16 17.

>>> K.domain().generators()
(g[7],)
>>> K.domain().relations()
((Sq(0,1)+Sq(3))*g[7],
 (Sq(0,0,1)+Sq(1,2)+Sq(4,1))*g[7],
 Sq(9)*g[7],
 (Sq(0,1,1)+Sq(4,2))*g[7])

>>> K
Module morphism:
  From: Finitely presented left module on 1 generator and 4 relations over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
  To:   Finitely presented left module on 2 generators and 6 relations over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
  Defn: g[7] |--> g[7]
lift(f, verbose=False)[source]#

Return a lift of this homomorphism over the given homomorphism f.

INPUT:

  • f – a homomorphism with codomain equal to the codomain of self

  • verbose – boolean (default: False); enable progress messages

OUTPUT:

A homomorphism \(g\) with the property that self equals \(f \circ g\). If no lift exist, None is returned.

ALGORITHM:

Let \(s\) be this homomorphism with \(L\) the domain of \(s\). Choose \(x_1, \ldots, x_N\) such that \(f(x_i) = s(g_i)\), where the \(g_i\)’s are the module generators of \(L\).

The linear function sending \(g_i\) to \(x_i\) for every \(i\) is well defined if and only if the vector \(x = (x_1, \ldots, x_N)\) lies in the nullspace of the coefficient matrix \(R = (r_{ij})\) given by the relations of \(L\).

Let \(k \in \ker(f)\) solve the matrix equation:

\[R \cdot k = R \cdot x.\]

Define a module homomorphism by sending the generators of \(L\) to \(x_1 - k_1, \ldots, x_N - k_N\). This is well defined, and is also a lift of this homomorphism over \(f\).

Note that it does not matter how we choose the initial elements \(x_i\): If \(x'\) is another choice then \(x' - x\in \ker(f)\) and \(R\cdot k = R\cdot x\) if and only if \(R\cdot (k + x' - x) = R\cdot x'\).

EXAMPLES:

sage: from sage.modules.fp_graded.module import FPModule
sage: A = SteenrodAlgebra(2)
>>> from sage.all import *
>>> from sage.modules.fp_graded.module import FPModule
>>> A = SteenrodAlgebra(Integer(2))

Lifting a map from a free module is always possible:

sage: M = FPModule(A, [0], [[Sq(3)]])
sage: N = FPModule(A, [0], [[Sq(2,2)]])
sage: F = FPModule(A, [0])
sage: f = Hom(M,N)([Sq(2)*N.generator(0)])
sage: k = Hom(F,N)([Sq(1)*Sq(2)*N.generator(0)])
sage: f_ = k.lift(f)
sage: f*f_ == k
True
sage: f_
Module morphism:
  From: Free graded left module on 1 generator over mod 2 Steenrod algebra, milnor basis
  To:   Finitely presented left module on 1 generator and 1 relation over mod 2 Steenrod algebra, milnor basis
  Defn: g[0] |--> Sq(1)*g[0]
>>> from sage.all import *
>>> M = FPModule(A, [Integer(0)], [[Sq(Integer(3))]])
>>> N = FPModule(A, [Integer(0)], [[Sq(Integer(2),Integer(2))]])
>>> F = FPModule(A, [Integer(0)])
>>> f = Hom(M,N)([Sq(Integer(2))*N.generator(Integer(0))])
>>> k = Hom(F,N)([Sq(Integer(1))*Sq(Integer(2))*N.generator(Integer(0))])
>>> f_ = k.lift(f)
>>> f*f_ == k
True
>>> f_
Module morphism:
  From: Free graded left module on 1 generator over mod 2 Steenrod algebra, milnor basis
  To:   Finitely presented left module on 1 generator and 1 relation over mod 2 Steenrod algebra, milnor basis
  Defn: g[0] |--> Sq(1)*g[0]

A split projection:

sage: A_plus_HZ = FPModule(A, [0,0], [[0, Sq(1)]])
sage: HZ = FPModule(A, [0], [[Sq(1)]])
sage: q = Hom(A_plus_HZ, HZ)([HZ([1]), HZ([1])])
sage: # We can construct a splitting of `q` manually:
sage: split = Hom(HZ,A_plus_HZ)([A_plus_HZ.generator(1)])
sage: (q*split).is_identity()
True
>>> from sage.all import *
>>> A_plus_HZ = FPModule(A, [Integer(0),Integer(0)], [[Integer(0), Sq(Integer(1))]])
>>> HZ = FPModule(A, [Integer(0)], [[Sq(Integer(1))]])
>>> q = Hom(A_plus_HZ, HZ)([HZ([Integer(1)]), HZ([Integer(1)])])
>>> # We can construct a splitting of `q` manually:
>>> split = Hom(HZ,A_plus_HZ)([A_plus_HZ.generator(Integer(1))])
>>> (q*split).is_identity()
True

Thus, lifting the identity homomorphism over \(q\) should be possible:

sage: one = Hom(HZ,HZ).identity()
sage: j = one.lift(q); j
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 1 relation over mod 2 Steenrod algebra, milnor basis
  Defn: g[0] |--> g[0, 1]
sage: q*j
Module endomorphism of Finitely presented left module on 1 generator and 1 relation over mod 2 Steenrod algebra, milnor basis
  Defn: g[0] |--> g[0]
>>> from sage.all import *
>>> one = Hom(HZ,HZ).identity()
>>> j = one.lift(q); j
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 1 relation over mod 2 Steenrod algebra, milnor basis
  Defn: g[0] |--> g[0, 1]
>>> q*j
Module endomorphism of Finitely presented left module on 1 generator and 1 relation over mod 2 Steenrod algebra, milnor basis
  Defn: g[0] |--> g[0]

Lifting over the inclusion of the image sub module:

sage: A = SteenrodAlgebra(2)
sage: M = FPModule(A, [0], relations=[[Sq(0,1)]])
sage: f = Hom(M,M)([Sq(2)*M.generator(0)])
sage: im = f.image(top_dim=10)
sage: f.lift(im)
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 1 generator and 2 relations over mod 2 Steenrod algebra, milnor basis
  Defn: g[0] |--> g[2]
>>> from sage.all import *
>>> A = SteenrodAlgebra(Integer(2))
>>> M = FPModule(A, [Integer(0)], relations=[[Sq(Integer(0),Integer(1))]])
>>> f = Hom(M,M)([Sq(Integer(2))*M.generator(Integer(0))])
>>> im = f.image(top_dim=Integer(10))
>>> f.lift(im)
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 1 generator and 2 relations over mod 2 Steenrod algebra, milnor basis
  Defn: g[0] |--> g[2]

When a lift cannot be found, the None value is returned. By setting the verbose argument to True, an explanation of why the lifting failed will be displayed:

sage: F2 = FPModule(A, [0,0])
sage: non_surjection = Hom(F2, F2)([F2([1, 0]), F2([0, 0])])
sage: lift = Hom(F2, F2).identity().lift(non_surjection, verbose=True)
The generators of the domain of this homomorphism do not map into
 the image of the homomorphism we are lifting over.
sage: lift is None
True
>>> from sage.all import *
>>> F2 = FPModule(A, [Integer(0),Integer(0)])
>>> non_surjection = Hom(F2, F2)([F2([Integer(1), Integer(0)]), F2([Integer(0), Integer(0)])])
>>> lift = Hom(F2, F2).identity().lift(non_surjection, verbose=True)
The generators of the domain of this homomorphism do not map into
 the image of the homomorphism we are lifting over.
>>> lift is None
True

See also

split()

solve(x)[source]#

Return an element in the inverse image of x.

INPUT:

  • x – an element of the codomain of this morphism

OUTPUT:

An element of the domain which maps to x under this morphism or None if x was not in the image of this morphism.

EXAMPLES:

sage: from sage.modules.fp_graded.module import FPModule
sage: A = SteenrodAlgebra(2)
sage: M = FPModule(A, [0], [[Sq(3)]])
sage: N = FPModule(A, [0], [[Sq(2,2)]])
sage: f = Hom(M, N)( [Sq(2)*N.generator(0)] )
sage: y = Sq(1,1)*N.generator(0); y
Sq(1,1)*g[0]
sage: x = f.solve(y); x
Sq(2)*g[0]
sage: y == f(x)
True
>>> from sage.all import *
>>> from sage.modules.fp_graded.module import FPModule
>>> A = SteenrodAlgebra(Integer(2))
>>> M = FPModule(A, [Integer(0)], [[Sq(Integer(3))]])
>>> N = FPModule(A, [Integer(0)], [[Sq(Integer(2),Integer(2))]])
>>> f = Hom(M, N)( [Sq(Integer(2))*N.generator(Integer(0))] )
>>> y = Sq(Integer(1),Integer(1))*N.generator(Integer(0)); y
Sq(1,1)*g[0]
>>> x = f.solve(y); x
Sq(2)*g[0]
>>> y == f(x)
True

Trying to lift an element which is not in the image results in a None value:

sage: z = f.solve(Sq(1)*N.generator(0))
sage: z is None
True
>>> from sage.all import *
>>> z = f.solve(Sq(Integer(1))*N.generator(Integer(0)))
>>> z is None
True
split(verbose=False)[source]#

Return a split of self.

INPUT:

  • verbose – boolean (default: False); enable progress messages

OUTPUT:

A homomorphism with the property that the composite homomorphism \(S \circ f = id\), where \(S\) is self, is The identity homomorphism If no such split exist, None is returned.

EXAMPLES:

sage: from sage.modules.fp_graded.module import FPModule
sage: A = SteenrodAlgebra(2)
sage: M = FPModule(A, [0,0], [[0, Sq(1)]])
sage: N = FPModule(A, [0], [[Sq(1)]])
sage: p = Hom(M, N)([N.generator(0), N.generator(0)])
sage: s = p.split(); s
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 1 relation over mod 2 Steenrod algebra, milnor basis
  Defn: g[0] |--> g[0, 1]
sage: # Verify that `s` is a splitting:
sage: p*s
Module endomorphism of Finitely presented left module on 1 generator and 1 relation over mod 2 Steenrod algebra, milnor basis
  Defn: g[0] |--> g[0]
>>> from sage.all import *
>>> from sage.modules.fp_graded.module import FPModule
>>> A = SteenrodAlgebra(Integer(2))
>>> M = FPModule(A, [Integer(0),Integer(0)], [[Integer(0), Sq(Integer(1))]])
>>> N = FPModule(A, [Integer(0)], [[Sq(Integer(1))]])
>>> p = Hom(M, N)([N.generator(Integer(0)), N.generator(Integer(0))])
>>> s = p.split(); s
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 1 relation over mod 2 Steenrod algebra, milnor basis
  Defn: g[0] |--> g[0, 1]
>>> # Verify that `s` is a splitting:
>>> p*s
Module endomorphism of Finitely presented left module on 1 generator and 1 relation over mod 2 Steenrod algebra, milnor basis
  Defn: g[0] |--> g[0]

See also

lift()

suspension(t)[source]#

The suspension of this morphism by the given degree t.

INPUT:

  • t – an integer by which the morphism is suspended

OUTPUT:

The morphism which is the suspension of self by the degree t.

EXAMPLES:

sage: from sage.modules.fp_graded.module import FPModule
sage: A = SteenrodAlgebra(2)
sage: F1 = FPModule(A, [4,5])
sage: F2 = FPModule(A, [5])

sage: f = Hom(F1, F2)( ( F2([Sq(4)]), F2([Sq(5)]) ) ); f
Module morphism:
  From: Free graded left module on 2 generators over mod 2 Steenrod algebra, milnor basis
  To:   Free graded left module on 1 generator over mod 2 Steenrod algebra, milnor basis
  Defn: g[4] |--> Sq(4)*g[5]
        g[5] |--> Sq(5)*g[5]

sage: e1 = F1([1, 0])
sage: e2 = F1([0, 1])
sage: f(e1)
Sq(4)*g[5]
sage: f(e2)
Sq(5)*g[5]

sage: sf = f.suspension(4); sf
Module morphism:
  From: Free graded left module on 2 generators over mod 2 Steenrod algebra, milnor basis
  To:   Free graded left module on 1 generator over mod 2 Steenrod algebra, milnor basis
  Defn: g[8] |--> Sq(4)*g[9]
        g[9] |--> Sq(5)*g[9]

sage: sf.domain() is f.domain().suspension(4)
True

sage: sf.codomain() is f.codomain().suspension(4)
True
>>> from sage.all import *
>>> from sage.modules.fp_graded.module import FPModule
>>> A = SteenrodAlgebra(Integer(2))
>>> F1 = FPModule(A, [Integer(4),Integer(5)])
>>> F2 = FPModule(A, [Integer(5)])

>>> f = Hom(F1, F2)( ( F2([Sq(Integer(4))]), F2([Sq(Integer(5))]) ) ); f
Module morphism:
  From: Free graded left module on 2 generators over mod 2 Steenrod algebra, milnor basis
  To:   Free graded left module on 1 generator over mod 2 Steenrod algebra, milnor basis
  Defn: g[4] |--> Sq(4)*g[5]
        g[5] |--> Sq(5)*g[5]

>>> e1 = F1([Integer(1), Integer(0)])
>>> e2 = F1([Integer(0), Integer(1)])
>>> f(e1)
Sq(4)*g[5]
>>> f(e2)
Sq(5)*g[5]

>>> sf = f.suspension(Integer(4)); sf
Module morphism:
  From: Free graded left module on 2 generators over mod 2 Steenrod algebra, milnor basis
  To:   Free graded left module on 1 generator over mod 2 Steenrod algebra, milnor basis
  Defn: g[8] |--> Sq(4)*g[9]
        g[9] |--> Sq(5)*g[9]

>>> sf.domain() is f.domain().suspension(Integer(4))
True

>>> sf.codomain() is f.codomain().suspension(Integer(4))
True
values()[source]#

The values under self of the module generators of the domain module.

OUTPUT:

A sequence of module elements of the codomain.

EXAMPLES:

sage: from sage.modules.fp_graded.module import FPModule
sage: A = SteenrodAlgebra(2)
sage: M = FPModule(A, [0,1], [[Sq(2), Sq(1)]])
sage: N = FPModule(A, [2], [[Sq(4)]])
sage: homspace = Hom(M, N)

sage: values = [Sq(5)*N.generator(0), Sq(3,1)*N.generator(0)]
sage: f = homspace(values)

sage: f.values()
(Sq(5)*g[2], Sq(3,1)*g[2])

sage: homspace.zero().values()
(0, 0)

sage: homspace = Hom(A.free_graded_module((0,1)), A.free_graded_module((2,)))
sage: N = homspace.codomain()
sage: values = [Sq(5)*N.generator(0), Sq(3,1)*N.generator(0)]
sage: f = homspace(values)
sage: f.values()
(Sq(5)*g[2], Sq(3,1)*g[2])
sage: homspace.zero().values()
(0, 0)
>>> from sage.all import *
>>> from sage.modules.fp_graded.module import FPModule
>>> A = SteenrodAlgebra(Integer(2))
>>> M = FPModule(A, [Integer(0),Integer(1)], [[Sq(Integer(2)), Sq(Integer(1))]])
>>> N = FPModule(A, [Integer(2)], [[Sq(Integer(4))]])
>>> homspace = Hom(M, N)

>>> values = [Sq(Integer(5))*N.generator(Integer(0)), Sq(Integer(3),Integer(1))*N.generator(Integer(0))]
>>> f = homspace(values)

>>> f.values()
(Sq(5)*g[2], Sq(3,1)*g[2])

>>> homspace.zero().values()
(0, 0)

>>> homspace = Hom(A.free_graded_module((Integer(0),Integer(1))), A.free_graded_module((Integer(2),)))
>>> N = homspace.codomain()
>>> values = [Sq(Integer(5))*N.generator(Integer(0)), Sq(Integer(3),Integer(1))*N.generator(Integer(0))]
>>> f = homspace(values)
>>> f.values()
(Sq(5)*g[2], Sq(3,1)*g[2])
>>> homspace.zero().values()
(0, 0)
vector_presentation(n)[source]#

Return the restriction of self to the domain module elements of degree n.

The restriction of a non-zero module homomorphism to the free module of module elements of degree \(n\) is a linear function into the free module of elements of degree \(n+d\) belonging to the codomain. Here \(d\) is the degree of this homomorphism.

When this homomorphism is zero, it has no well defined degree so the function cannot be presented since we do not know the degree of its codomain. In this case, an error is raised.

INPUT:

  • n – an integer degree

OUTPUT:

A linear function of finite dimensional free modules over the ground ring of the algebra for this module. The domain is isomorphic to the free module of domain elements of degree n of self via the choice of basis given by basis_elements(). If the morphism is zero, an error is raised.

EXAMPLES:

sage: from sage.modules.fp_graded.module import FPModule
sage: A = SteenrodAlgebra(2)
sage: M = FPModule(A, [0,1], [[Sq(2), Sq(1)]])
sage: N = FPModule(A, [2], [[Sq(4)]])
sage: values = [Sq(5)*N.generator(0), Sq(3,1)*N.generator(0)]
sage: f = Hom(M, N)(values)
sage: f.vector_presentation(0)
Vector space morphism represented by the matrix:
[0]
Domain: Vector space quotient V/W of dimension 1 over Finite Field of size 2 where
V: Vector space of dimension 1 over Finite Field of size 2
W: Vector space of degree 1 and dimension 0 over Finite Field of size 2
Basis matrix:
[]
Codomain: Vector space quotient V/W of dimension 1 over Finite Field of size 2 where
V: Vector space of dimension 2 over Finite Field of size 2
W: Vector space of degree 2 and dimension 1 over Finite Field of size 2
Basis matrix:
[0 1]
sage: f.vector_presentation(1)
Vector space morphism represented by the matrix:
[0 0]
[0 1]
Domain: Vector space quotient V/W of dimension 2 over Finite Field of size 2 where
V: Vector space of dimension 2 over Finite Field of size 2
W: Vector space of degree 2 and dimension 0 over Finite Field of size 2
Basis matrix:
[]
Codomain: Vector space quotient V/W of dimension 2 over Finite Field of size 2 where
V: Vector space of dimension 3 over Finite Field of size 2
W: Vector space of degree 3 and dimension 1 over Finite Field of size 2
Basis matrix:
[0 1 1]
sage: f.vector_presentation(2)
Vector space morphism represented by the matrix:
[0 0]
Domain: Vector space quotient V/W of dimension 1 over Finite Field of size 2 where
V: Vector space of dimension 2 over Finite Field of size 2
W: Vector space of degree 2 and dimension 1 over Finite Field of size 2
Basis matrix:
[1 1]
Codomain: Vector space quotient V/W of dimension 2 over Finite Field of size 2 where
V: Vector space of dimension 4 over Finite Field of size 2
W: Vector space of degree 4 and dimension 2 over Finite Field of size 2
Basis matrix:
[0 0 1 0]
[0 0 0 1]

sage: M = A.free_graded_module((0,1))
sage: N = A.free_graded_module((2,))
sage: v = N.generator(0)
sage: values = [Sq(5)*v, Sq(3,1)*v]
sage: f = Hom(M, N)(values)
sage: f.vector_presentation(0)
Vector space morphism represented by the matrix:
[0 1]
Domain: Vector space of dimension 1 over Finite Field of size 2
Codomain: Vector space of dimension 2 over Finite Field of size 2
sage: f.vector_presentation(1)
Vector space morphism represented by the matrix:
[0 0 0]
[0 1 0]
Domain: Vector space of dimension 2 over Finite Field of size 2
Codomain: Vector space of dimension 3 over Finite Field of size 2
sage: f.vector_presentation(2)
Vector space morphism represented by the matrix:
[0 0 1 1]
[0 0 0 0]
Domain: Vector space of dimension 2 over Finite Field of size 2
Codomain: Vector space of dimension 4 over Finite Field of size 2
>>> from sage.all import *
>>> from sage.modules.fp_graded.module import FPModule
>>> A = SteenrodAlgebra(Integer(2))
>>> M = FPModule(A, [Integer(0),Integer(1)], [[Sq(Integer(2)), Sq(Integer(1))]])
>>> N = FPModule(A, [Integer(2)], [[Sq(Integer(4))]])
>>> values = [Sq(Integer(5))*N.generator(Integer(0)), Sq(Integer(3),Integer(1))*N.generator(Integer(0))]
>>> f = Hom(M, N)(values)
>>> f.vector_presentation(Integer(0))
Vector space morphism represented by the matrix:
[0]
Domain: Vector space quotient V/W of dimension 1 over Finite Field of size 2 where
V: Vector space of dimension 1 over Finite Field of size 2
W: Vector space of degree 1 and dimension 0 over Finite Field of size 2
Basis matrix:
[]
Codomain: Vector space quotient V/W of dimension 1 over Finite Field of size 2 where
V: Vector space of dimension 2 over Finite Field of size 2
W: Vector space of degree 2 and dimension 1 over Finite Field of size 2
Basis matrix:
[0 1]
>>> f.vector_presentation(Integer(1))
Vector space morphism represented by the matrix:
[0 0]
[0 1]
Domain: Vector space quotient V/W of dimension 2 over Finite Field of size 2 where
V: Vector space of dimension 2 over Finite Field of size 2
W: Vector space of degree 2 and dimension 0 over Finite Field of size 2
Basis matrix:
[]
Codomain: Vector space quotient V/W of dimension 2 over Finite Field of size 2 where
V: Vector space of dimension 3 over Finite Field of size 2
W: Vector space of degree 3 and dimension 1 over Finite Field of size 2
Basis matrix:
[0 1 1]
>>> f.vector_presentation(Integer(2))
Vector space morphism represented by the matrix:
[0 0]
Domain: Vector space quotient V/W of dimension 1 over Finite Field of size 2 where
V: Vector space of dimension 2 over Finite Field of size 2
W: Vector space of degree 2 and dimension 1 over Finite Field of size 2
Basis matrix:
[1 1]
Codomain: Vector space quotient V/W of dimension 2 over Finite Field of size 2 where
V: Vector space of dimension 4 over Finite Field of size 2
W: Vector space of degree 4 and dimension 2 over Finite Field of size 2
Basis matrix:
[0 0 1 0]
[0 0 0 1]

>>> M = A.free_graded_module((Integer(0),Integer(1)))
>>> N = A.free_graded_module((Integer(2),))
>>> v = N.generator(Integer(0))
>>> values = [Sq(Integer(5))*v, Sq(Integer(3),Integer(1))*v]
>>> f = Hom(M, N)(values)
>>> f.vector_presentation(Integer(0))
Vector space morphism represented by the matrix:
[0 1]
Domain: Vector space of dimension 1 over Finite Field of size 2
Codomain: Vector space of dimension 2 over Finite Field of size 2
>>> f.vector_presentation(Integer(1))
Vector space morphism represented by the matrix:
[0 0 0]
[0 1 0]
Domain: Vector space of dimension 2 over Finite Field of size 2
Codomain: Vector space of dimension 3 over Finite Field of size 2
>>> f.vector_presentation(Integer(2))
Vector space morphism represented by the matrix:
[0 0 1 1]
[0 0 0 0]
Domain: Vector space of dimension 2 over Finite Field of size 2
Codomain: Vector space of dimension 4 over Finite Field of size 2