Source code for klotho.topos.types

"""
Base class for typed musical units with NumPy integration.
"""

import numbers
import numpy as np
from fractions import Fraction

__all__ = ['Unit', '_to_fraction_array']


def _to_fraction_array(value):
    """
    Convert a value to Fraction(s), preserving shape. Accepts int, Fraction, str,
    or array-like of those. Returns ndarray with dtype=object (0-d for scalar).
    """
    if isinstance(value, (list, tuple, np.ndarray)):
        arr = np.asarray(value)
        out = np.array([Fraction(x) for x in arr.flat], dtype=object)
        return out.reshape(arr.shape)
    return np.array(Fraction(value), dtype=object)


[docs] class Unit: """ Base class for typed musical units with NumPy integration. Wraps a numeric magnitude with unit metadata, supporting transparent NumPy array operations via ``__array__`` and ``__array_ufunc__``. Parameters ---------- magnitude : scalar or array-like The numeric value(s) of the unit. unit_type : str Identifier for the unit type (e.g., 'frequency', 'amplitude'). unit_symbol : str, optional Display symbol for the unit (default is ``""``). """
[docs] def __init__(self, magnitude, unit_type, unit_symbol=""): self.magnitude = np.asarray(magnitude) self.unit_type = unit_type self.unit_symbol = unit_symbol
def __array__(self): return self.magnitude def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): magnitudes = [] for input_ in inputs: if hasattr(input_, 'magnitude'): magnitudes.append(input_.magnitude) else: magnitudes.append(input_) result_magnitude = ufunc(*magnitudes, **kwargs) return type(self)(result_magnitude) def __float__(self): return float(self.magnitude) def __int__(self): return int(self.magnitude) def __repr__(self): return self.__str__() def __str__(self): return f"{self.magnitude} {self.unit_symbol}" def __getitem__(self, key): return type(self)(self.magnitude[key])