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