Tutorial: Factoring homomorphisms¶
This is an interactive tutorial written with real code. We start by
importing the LCA
class, the HomLCA
class and setting up
\(\LaTeX\) printing.
In [1]:
from abelian import LCA, HomLCA
from IPython.display import display, Math
def show(arg):
return display(Math(arg.to_latex()))
Initialization and source/target projections¶
We create a HomLCA
instance, which may represent a homomorphism
between FGAs. In this tutorial we will only consider homomorphisms
between FGAs.
In [2]:
phi = HomLCA([[5, 10, 15],
[10, 20, 30],
[10, 5, 30]],
target = [50, 20, 30])
show(phi)
Projecting to source¶
The source (or domain) is assumed to be free (infinite order).
Calculating the orders is done with the project_to_source
method,
after which the orders of the columns are shown in the source group.
In [3]:
# Project to source, i.e. orders of generator columns
phi = phi.project_to_source()
show(phi)
Projecting to target¶
Projecting the columns onto the target group will make the morphism more
readable. The project_to_target()
method will project every column
to the target group.
In [4]:
# Project the generator columns to the target group
phi = phi.project_to_target()
show(phi)
The kernel monomorphism¶
The kernel morphism is a monomorphism such that \(\phi \circ \operatorname{ker} (\phi) = 0\). The kernel of \(\phi\) is:
In [5]:
# Calculate the kernel
show(phi.kernel())
The kernel monomorphism is not projected to source by default, but doing so is simple.
In [6]:
show(phi.kernel().project_to_source())
Verify that \(\phi \circ \operatorname{ker} (\phi) = 0\).
In [7]:
show(phi * phi.kernel())
To clearly see that this is the zero morphism, use the
project_to_target()
method as such.
In [8]:
zero = phi * phi.kernel()
zero = zero.project_to_target()
show(zero)
The cokernel epimorphism¶
The kernel morphism is an epimorphism such that \(\operatorname{coker}(\phi) \circ \phi = 0\). The cokernel of \(\phi\) is:
In [9]:
show(phi.cokernel())
We verify the factorization.
In [10]:
show((phi.cokernel() * phi))
Again it is not immediately clear that this is the zero morphism. To
verify this, we again use the project_to_target()
method as such.
In [11]:
zero = phi.cokernel() * phi
zero = zero.project_to_target()
show(zero)
The image/coimage factorization¶
The image/coimage factorization is \(\phi = \operatorname{im}(\phi) \circ \operatorname{coim}(\phi)\), where the image is a monomorphism and the coimage is an epimorphism.
The image monomorphism¶
Finding the image is easy, just call the image()
method.
In [12]:
im = phi.image()
show(im)
A trivial group \(\mathbb{Z}_1\) is in the source. It can be removed
using remove_trivial_subgroups()
.
In [13]:
im = im.remove_trivial_groups()
show(im)
The coimage epimorphism¶
Finding the coimage is done by calling the coimage()
method.
In [14]:
coim = phi.coimage().remove_trivial_groups()
show(coim)
Verify the image/coimage factorization¶
We now verify that \(\phi = \operatorname{im}(\phi) \circ \operatorname{coim}(\phi)\).
In [15]:
show(phi)
show((im * coim).project_to_target())
In [16]:
(im * coim).project_to_target() == phi
Out[16]:
True