Source code for mathematicskit.abstract_algebra.systems.homomorphisms

r"""Group homomorphisms: the homomorphism property, kernel, and image.

No numpy/scipy equivalent. See Dummit & Foote, *Abstract Algebra*, 3rd
ed., Sec. 1.6 and 3.3 (the isomorphism theorems), and E. Noether,
"Abstrakter Aufbau der Idealtheorie in algebraischen Zahl- und
Funktionenkörpern," Mathematische Annalen 96 (1927), 26-61.
"""

from __future__ import annotations

from typing import Callable

from mathematicskit.abstract_algebra.core.base import FiniteGroup, HomomorphismResult

__all__ = ["is_homomorphism", "homomorphism_kernel", "homomorphism_image", "analyze_homomorphism"]


[docs] def is_homomorphism(source: FiniteGroup, target: FiniteGroup, phi: Callable) -> bool: r"""Whether :math:`\varphi(ab) = \varphi(a)\varphi(b)` for every pair :math:`a, b \in G`. Parameters ---------- source : FiniteGroup target : FiniteGroup phi : callable Maps elements of `source` to elements of `target`. Returns ------- bool Examples -------- >>> from mathematicskit.abstract_algebra.systems.groups import CyclicGroup >>> is_homomorphism(CyclicGroup(12), CyclicGroup(4), lambda a: a % 4) True >>> is_homomorphism(CyclicGroup(12), CyclicGroup(5), lambda a: a % 5) False """ return all(phi(source.operate(a, b)) == target.operate(phi(a), phi(b)) for a in source.elements for b in source.elements)
[docs] def homomorphism_kernel(source: FiniteGroup, target: FiniteGroup, phi: Callable) -> list: r"""The kernel :math:`\ker\varphi = \{g \in G : \varphi(g) = e_H\}`, always a normal subgroup. Parameters ---------- source : FiniteGroup target : FiniteGroup phi : callable Returns ------- list Examples -------- >>> from mathematicskit.abstract_algebra.systems.groups import CyclicGroup >>> homomorphism_kernel(CyclicGroup(12), CyclicGroup(4), lambda a: a % 4) [0, 4, 8] """ e = target.identity() return [g for g in source.elements if phi(g) == e]
[docs] def homomorphism_image(source: FiniteGroup, target: FiniteGroup, phi: Callable) -> list: r"""The image :math:`\varphi(G) \le H`, in the target group's element order. Parameters ---------- source : FiniteGroup target : FiniteGroup phi : callable Returns ------- list Examples -------- >>> from mathematicskit.abstract_algebra.systems.groups import CyclicGroup >>> homomorphism_image(CyclicGroup(6), CyclicGroup(6), lambda a: (2 * a) % 6) [0, 2, 4] """ values = {phi(g) for g in source.elements} return [h for h in target.elements if h in values]
[docs] def analyze_homomorphism(source: FiniteGroup, target: FiniteGroup, phi: Callable) -> HomomorphismResult: r"""Kernel, image, and homomorphism check together. The first isomorphism theorem, stated in its modern abstract form by Emmy Noether in 1927, gives :math:`G/\ker\varphi \cong \varphi(G)`, so :math:`|G| = |\ker\varphi| \cdot |\varphi(G)|`. Parameters ---------- source : FiniteGroup target : FiniteGroup phi : callable Returns ------- HomomorphismResult Examples -------- >>> from mathematicskit.abstract_algebra.systems.groups import CyclicGroup >>> result = analyze_homomorphism(CyclicGroup(12), CyclicGroup(4), lambda a: a % 4) >>> len(result.kernel) * len(result.image) # = |Z_12| 12 """ return HomomorphismResult( kernel=homomorphism_kernel(source, target, phi), image=homomorphism_image(source, target, phi), is_homomorphism=is_homomorphism(source, target, phi), )