Source code for httk.core.vectors.vector_frac

"""
Backend wrapping a FracVector/FracScalar in the exact-rational representation.
"""

import fractions
from typing import Any

from .fracvector import FracVector
from .vector_api import Fractions
from .vector_backend import VectorBackend


def _fracvector_to_fractions(fv: FracVector) -> Fractions:
    denom = fv.denom

    def rec(noms: Any) -> Fractions:
        if isinstance(noms, tuple):
            return tuple(rec(n) for n in noms)
        return fractions.Fraction(noms, denom)

    return rec(fv.noms)


[docs] class VectorFrac(VectorBackend): """ Backend for a vector backed by an actual :class:`~httk.core.vectors.fracvector.FracVector` (or :class:`~httk.core.vectors.fracvector.FracScalar`). Its ``fractions`` accessor produces the exact nested tuple of Fraction, and ``unwrap`` returns the wrapped FracVector. """ _fracvector: FracVector # Cannot type annotate __new__ as `Self | None` for some reason def __new__(cls, obj: Any, **hints: Any) -> Any: if not isinstance(obj, FracVector): return None if hints and hints.get("kind", "frac") != "frac": return None return super().__new__(cls) def __init__(self, obj: FracVector, **hints: Any) -> None: self._fracvector = obj @property
[docs] def fractions(self) -> Fractions: return _fracvector_to_fractions(self._fracvector)
@property
[docs] def dim(self) -> tuple[int, ...]: return self._fracvector.dim
[docs] def unwrap(self) -> Any: return self._fracvector