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)