Source code for pocketpartition.core.kunz._coords
"""
Kunz coordinate computation.
This module provides the low-level helper that builds the Kunz coordinate
tuple from a NumericalSemigroup, and the public ``kunz_tuple`` wrapper.
"""
__all__ = ['kunz_tuple']
from ..numerical_semigroup import NumericalSemigroup
def _compute_kunz_coords(S: NumericalSemigroup) -> tuple:
"""
Return the raw Kunz coordinate tuple for semigroup S.
For each residue class ``r = 1, ..., m-1`` (where ``m`` is the
multiplicity of S) this finds the unique element of the Apéry set
``Ap(S, m)`` that is congruent to ``r`` mod ``m``, then divides by ``m``.
Parameters
----------
S : NumericalSemigroup
Returns
-------
tuple of int
Length ``m - 1``, entries ``w_1, ..., w_{m-1}`` in residue order.
"""
m = S.multiplicity()
A = S.apery_set(m)
# Build a residue->coord map in one pass over the Apéry set (|A| = m, so O(m)).
residue_to_coord = {n % m: n // m for n in A}
return tuple(residue_to_coord[res] for res in range(1, m))
[docs]
def kunz_tuple(S: NumericalSemigroup) -> tuple:
"""
Return the Kunz coordinate tuple of a numerical semigroup.
For a semigroup S with multiplicity m, the Kunz tuple is the vector
``(w_1, ..., w_{m-1})`` where ``w_i = min{ n in S : n ≡ i (mod m) } / m``.
Parameters
----------
S : NumericalSemigroup
Returns
-------
tuple of int
Length ``m - 1``, all entries positive.
Examples
--------
>>> from pocketpartition import NumericalSemigroup
>>> from pocketpartition.core.kunz import kunz_tuple
>>> S = NumericalSemigroup(generators=[3, 4, 5])
>>> kunz_tuple(S)
(1, 1)
"""
return _compute_kunz_coords(S)