httk.core.vectors¶
Exact-rational vectors (FracVector/FracScalar/MutableFracVector) and
the Vector backend/view family that lets the same tensor data be viewed as the exact
representation, plain nested sequences, or (optionally) numpy arrays.
The exact-math helpers live in the submodules httk.core.vectors.exactmath (type-preserving
exact transcendentals on Fraction and Decimal) and httk.core.vectors.vectormath (functional
math wrappers).
Submodules¶
- httk.core.vectors.exactmath
- httk.core.vectors.fracvector
- httk.core.vectors.leaf_codecs
- httk.core.vectors.mutablefracvector
- httk.core.vectors.numeric
- httk.core.vectors.surdvector
- httk.core.vectors.vector_api
- httk.core.vectors.vector_backend
- httk.core.vectors.vector_frac
- httk.core.vectors.vector_frac_view
- httk.core.vectors.vector_like
- httk.core.vectors.vector_native
- httk.core.vectors.vector_native_view
- httk.core.vectors.vector_numpy
- httk.core.vectors.vector_numpy_view
- httk.core.vectors.vector_surd
- httk.core.vectors.vector_surd_view
- httk.core.vectors.vector_view
- httk.core.vectors.vectormath
Attributes¶
Classes¶
Represents the fractional number |
|
FracVector is a general immutable N-dimensional vector (tensor) class for performing |
|
A leaf codec: a documented conversion of one exact |
|
Same as |
|
A scalar |
|
An immutable exact tensor over the squarefree-radical field |
|
Abstract base class for the canonical vector interface. |
|
Abstract base class for all backends of vector (tensor) data. |
|
Backend for a vector backed by an actual |
|
A view presenting an underlying vector backend as an exact |
|
Backend for a vector backed by plain nested sequences. |
|
A view presenting an underlying vector backend as nested tuples, with a selectable leaf codec. |
|
Backend for a vector backed by an exact |
|
A view presenting an underlying vector backend as an exact |
|
Abstract base class for all views of vector (tensor) data. |
Functions¶
|
Return the registered leaf-codec names, in registration order. |
|
Register (or replace) a codec under its |
|
Return whether the optional numpy dependency is available for the numeric helpers. |
|
Present |
|
Convert a single scalar value to a plain |
Package Contents¶
- class httk.core.vectors.FracScalar(nom: int, denom: int)[source]¶
Bases:
FracVectorRepresents the fractional number
nom/denom. This is a subclass of FracVector with the purpose of making it clear when a scalar fracvector is needed/used.- noms¶
- denom¶
- classmethod create(noms: Any, denom: int | None = None, simplify: bool = True, chain: bool = False, min_accuracy: fractions.Fraction | None = fractions.Fraction(1, 10000)) Self[source]¶
Create a FracScalar.
FracScalar.create(something)wheresomethingmay be any object that can be used in the constructor of the Python Fraction class (also works with strings!).Note: for signature-compatibility with
FracVector.create(), this acceptschainandmin_accuracy, but (as in the legacy implementation) it ignores them and converts strings exactly via the Fraction constructor.
- class httk.core.vectors.FracVector(noms: Noms, denom: int = 1)[source]¶
FracVector is a general immutable N-dimensional vector (tensor) class for performing linear algebra with fractional numbers.
A FracVector consists of a multidimensional tuple of integer nominators, and a single shared integer denominator.
Since FracVectors are immutable, every operation on a FracVector returns a new FracVector with the result of the operation. A created FracVector never changes. Hence, they are safe to use as keys in dictionaries, to use in sets, etc.
Note: most methods return FracVector results that are not simplified (i.e., the FracVector returned does not have the smallest possible integer denominator). To return a FracVector with the smallest possible denominator, just call
simplify()at the last step.- nested_map: ClassVar[collections.abc.Callable[Ellipsis, Any]]¶
- nested_map_fractions: ClassVar[collections.abc.Callable[Ellipsis, Any]]¶
- classmethod use(old: Any) FracVector[source]¶
Make sure the variable is a FracVector, and if not, convert it.
- classmethod create(noms: Any, denom: int | None = None, simplify: bool = True, chain: bool = False, min_accuracy: fractions.Fraction | None = fractions.Fraction(1, 10000)) Self[source]¶
Create a FracVector from various types of sequences.
Simplest use:
FracVector.create(some_kind_of_sequence)
where ‘some_kind_of_sequence’ can be any nested list or tuple of objects that can be used in the constructor of the Python Fraction class (also works with strings!). If any object found while traveling the items has a
.to_fractions()method, it will be called and is expected to return a fraction or list or tuple of fractions.- Parameters:
noms – any nested sequence of Fraction-constructible objects.
denom – an optional common denominator to divide all nominators with.
simplify – if True, return a FracVector with the smallest possible denominator.
chain – if True, remove the outermost dimension and chain the sub-sequences. I.e., if
input=[[1, 2, 3], [4, 5, 6]]thenFracVector.create(input)gives[1, 2, 3, 4, 5, 6].min_accuracy – the minimum accuracy assumed in string input. The default is
1/10000, i.e.0.33 = 0.3300 = 33/100, whereas0.3333 = 1/3. Set it to None to assume infinite accuracy, i.e. convert exactly whatever string is given (unless a standard deviation is given as a parenthesis after the string).
Note: FracVector itself implements
.to_fractions(), and hence the same constructor allows stacking several FracVector objects like this:vertical_fracvector = FracVector.create([[fracvector1], [fracvector2]]) horizontal_fracvector = FracVector.create([fracvector1, fracvector2], chain=True)
- classmethod create_fast(noms: Any, common_denom: int = 1, max_denom: int | None = None, denom: int | None = None, simplify: bool = True, chain: bool = False) Self[source]¶
Optimized version of
create()that takes advantage of the fact that the type ofnomsis a nested list of ints (of depth 2 or 3) over a singlecommon_denom.
- get_stacked(other: Any) Self[source]¶
Return a new FracVector with
otherstacked afterselfalong a new leading axis.selfandothermust have the same shape; the result gains one extra outermost dimension of size two (numpystack-like). E.g. stacking the row[1, 2, 3]with[4, 5, 6]gives[[1, 2, 3], [4, 5, 6]]. (The legacy version wrappedotherin a redundant extra list, producing a ragged, non-rectangular result.)
- get_prestacked(other: Any) Self[source]¶
Return a new FracVector with
otherstacked beforeselfalong a new leading axis.The mirror of
get_stacked(): stacking[1, 2, 3]in front with[4, 5, 6]gives[[4, 5, 6], [1, 2, 3]].
- classmethod chain_vecs(vecs: Any) Self[source]¶
Optimized chaining of FracVectors.
- Parameters:
vecs – a list (or tuple) of fracvectors that all share the same denominator.
Returns the same thing as
FracVector.create(vecs, chain=True), i.e., removes the outermost dimension and chains the sub-sequences. Ifinput=[[1, 2, 3], [4, 5, 6]]then it gives[1, 2, 3, 4, 5, 6], but this method assumes all vectors share the same denominator (it raises an exception if this is not true).
- classmethod stack_vecs(vecs: Any) Self[source]¶
Optimized stacking of FracVectors.
- Parameters:
vecs – a list (or tuple) of fracvectors that all share the same denominator.
Returns the same thing as
FracVector.create(vecs), but only works if all vectors share the same denominator (raises an exception if this is not true).
- classmethod eye(dims: tuple[int, Ellipsis]) Self[source]¶
Create a diagonal one-matrix with the given dimensions.
- classmethod zeros(dims: tuple[int, Ellipsis]) Self[source]¶
Create a zero matrix with the given dimensions.
- classmethod random(dims: tuple[int, Ellipsis], minnom: int = -100, maxnom: int = 100, denom: int = 100) Self[source]¶
Create a matrix with the given dimensions filled with random rational numbers.
- classmethod from_tuple(t: tuple[int, Noms]) Self[source]¶
Return a FracVector created from the tuple representation
(denom, noms), as returned by theto_tuple()method.from_tuple(v.to_tuple())reconstructsvexactly.
- classmethod from_floats(data: Any, resolution: int = 2**32) Self[source]¶
Create a FracVector from a (nested) list or tuple of floats. You can convert a numpy array with this method if you use
A.tolist().- Parameters:
l – the (nested) list or tuple of floats.
resolution – the resolution used for interpreting the given floating point numbers. Default is
2**32.
- classmethod create_cos(data: Any, degrees: bool = False, limit: bool = False, find_best_rational: bool = True, prec: fractions.Fraction = fractions.Fraction(1, 1000000)) Self[source]¶
Create a FracVector as the cosine of the argument
data. Ifdatais composed of strings, the standard deviation of the numbers is taken into account, and the best possible fractional approximation to the cosines of the data is returned within the standard deviation.This is not the same as
FracVector.create(data).cos(), which creates the best possible fractional approximations ofdataand then takes cos on that.
- classmethod create_sin(data: Any, degrees: bool = False, limit: bool = False, prec: fractions.Fraction = fractions.Fraction(1, 1000000)) Self[source]¶
Create a FracVector as the sine of the argument
data. Ifdatais composed of strings, the standard deviation of the numbers is taken into account, and the best possible fractional approximation to the sines of the data is returned within the standard deviation.This is not the same as
FracVector.create(data).sin(), which creates the best possible fractional approximations ofdataand then takes sin on that.
- classmethod create_exp(data: Any, prec: fractions.Fraction = fractions.Fraction(1, 1000000), limit: bool = False) Self[source]¶
Create a FracVector as the exponent of the argument
data. Ifdatais composed of strings, the standard deviation of the numbers is taken into account, and the best possible fractional approximation to the exponents of the data is returned within the standard deviation.This is not the same as
FracVector.create(data).exp(), which creates the best possible fractional approximations ofdataand then takes exp on that.
- classmethod pi(prec: fractions.Fraction = fractions.Fraction(1, 1000000), limit: bool = False) Self[source]¶
Create a scalar FracVector with a rational approximation of pi to precision
prec.
- property dim: tuple[int, Ellipsis]¶
A tuple with the dimensionality of each dimension of the FracVector (the noms are assumed to be a nested list of rectangular shape).
- to_tuple() tuple[int, Noms][source]¶
Return the FracVector on tuple representation
(denom, ...noms...).
- to_ints() Any[source]¶
Convert the FracVector to a (nested) list of integers, rounded off as best possible.
- to_fraction() fractions.Fraction[source]¶
Convert a scalar FracVector to a fraction.
- classmethod set_common_denom(A: Any, B: Any) tuple[Self, Self, int][source]¶
Used internally to combine two different FracVectors.
Returns a tuple
(A2, B2, denom)where A2 is numerically equal to A, and B2 is numerically equal to B, but A2 and B2 are both set on the same shared denominatordenom, which is the product of the denominators of A and B.
- simplify() Self[source]¶
Return a reduced FracVector. I.e., each element has the same numerical value but the new FracVector represents them using the smallest possible shared denominator.
- simplify_fast(depth: int) Self[source]¶
Return a reduced FracVector, taking advantage of a known nesting
depth. I.e., each element has the same numerical value but the new FracVector represents them using the smallest possible shared denominator.
- set_denominator(set_denom: int = 1000000000) Self[source]¶
Return a FracVector of reduced resolution where every element is the closest numerical approximation using this denominator.
- limit_denominator(max_denom: int = 1000000000) Self[source]¶
Return a FracVector of reduced resolution.
Each element in the returned FracVector is the closest numerical approximation that is allowed by a fraction with maximally this denominator. Note: since all elements must be put on a common denominator, the result may have a larger denominator than
max_denom.
- floor() int[source]¶
Return the integer that is equal to or just below the value stored in a scalar FracVector.
- modf() tuple[FracVector, FracVector][source]¶
Return the fractional and integer parts of each element as the pair
(fractional, integer)of exact FracVectors sharing this vector’s denominator.Both parts carry the sign of the element and the integer part truncates toward zero, matching the conventions of
math.modf()(e.g. the value -5/2 splits into -1/2 and -2).
- ceil() int[source]¶
Return the integer that is equal to or just above the value stored in a scalar FracVector.
- normalize() Self[source]¶
Add/remove an integer +/-N to each element to place it in the range [0, 1).
- normalize_half() Self[source]¶
Add/remove an integer +/-N to each element to place it in the range [-1/2, 1/2).
This is useful to find the shortest vector C between two points A, B in a space with periodic boundary conditions [0, 1):
C = (A - B).normalize_half()
- mul(other: Any) Self[source]¶
Return the result of multiplying the vector with
otherusing matrix multiplication.Note that for two 1D FracVectors,
A.dot(B)is not the same asA.mul(B), but ratherA.mul(B.T()).
- dot(other: FracVector) Self[source]¶
Return the vector dot product of the 1D vector with the 1D vector
other, i.e.,A . B. The same asA * B.T().
- cross(other: FracVector) Self[source]¶
Return the vector cross product of the 3-element 1D vector with the 3-element 1D vector
other, i.e.,A x B.
- reciprocal() Self[source]¶
Return the reciprocal matrix of a 3x3 matrix (the rows are the reciprocal vectors, without the
2*pifactor).
- metric_product(vecA: FracVector, vecB: FracVector) Self[source]¶
Return the result of the metric product using the present square FracVector as the metric matrix. The same as
vecA * self * vecB.T().
- cos(prec: fractions.Fraction | None = None, degrees: bool = False, limit: bool = False) Self[source]¶
Return a FracVector where every element is the cosine of the element in the source FracVector.
- Parameters:
prec – the precision (should be set as a fraction).
degrees – if True, interpret the elements in degrees.
limit – if True, require the denominator to be smaller than or equal to the precision.
- sin(prec: fractions.Fraction | None = None, degrees: bool = False, limit: bool = False) Self[source]¶
Return a FracVector where every element is the sine of the element in the source FracVector.
- Parameters:
prec – the precision (should be set as a fraction).
degrees – if True, interpret the elements in degrees.
limit – if True, require the denominator to be smaller than or equal to the precision.
- acos(prec: fractions.Fraction | None = None, degrees: bool = False, limit: bool = False) Self[source]¶
Return a FracVector where every element is the arccos of the element in the source FracVector.
- Parameters:
prec – the precision (should be set as a fraction).
degrees – if True, return the result in degrees.
limit – if True, require the denominator to be smaller than or equal to the precision.
- asin(prec: fractions.Fraction | None = None, degrees: bool = False, limit: bool = False) Self[source]¶
Return a FracVector where every element is the arcsin of the element in the source FracVector.
- Parameters:
prec – the precision (should be set as a fraction).
degrees – if True, return the result in degrees.
limit – if True, require the denominator to be smaller than or equal to the precision.
- exp(prec: fractions.Fraction | None = None, limit: bool = False) Self[source]¶
Return a FracVector where every element is the exponent of the element in the source FracVector.
- Parameters:
prec – the precision (should be set as a fraction).
limit – if True, require the denominator to be smaller than or equal to the precision.
- sqrt(prec: fractions.Fraction | None = None, limit: bool = False) Self[source]¶
Return a FracVector where every element is the sqrt of the element in the source FracVector.
- Parameters:
prec – the precision (should be set as a fraction).
limit – if True, require the denominator to be smaller than or equal to the precision.
- max() Self[source]¶
Return the maximum element across all dimensions in the FracVector.
max(fracvector)works for a 1D vector.
- nargmax() list[Any][source]¶
Return a list of indices of all maximum elements across all dimensions in the FracVector.
- argmax() Any[source]¶
Return the index of the maximum element across all dimensions in the FracVector.
- min() Self[source]¶
Return the minimum element across all dimensions in the FracVector.
min(fracvector)works for a 1D vector.
- class httk.core.vectors.LeafCodec[source]¶
A leaf codec: a documented conversion of one exact
fractions.Fractionleaf into a presentation leaf.A codec is an orthogonal layer beside the vector backends: given a value already reduced to the canonical Fraction hub, it produces the requested element type. Its
from_fractiondocuments both its exactness contract (when the result is exact) and its default conversion (what it does when an exact result is impossible); on data it never raises.- from_fraction: collections.abc.Callable[Ellipsis, Any]¶
Convert
(value: fractions.Fraction, **options) -> leaffrom the canonical Fraction hub.
- check_options: collections.abc.Callable[[dict[str, Any]], None]¶
Validate an options mapping eagerly, raising
ValueErroron any invalid option.
- httk.core.vectors.known_leaf_codecs() list[str][source]¶
Return the registered leaf-codec names, in registration order.
- httk.core.vectors.register_leaf_codec(codec: LeafCodec) None[source]¶
Register (or replace) a codec under its
name.
- class httk.core.vectors.MutableFracVector(noms: Any, denom: int = 1)[source]¶
Bases:
httk.core.vectors.fracvector.FracVectorSame as
FracVector, only this version allows assignment of elements, e.g.:mfracvec[2, 7] = 5
and, e.g.:
mfracvec[:, 7] = [1, 2, 3, 4]
Other than this, the FracVector methods exist and do the same, i.e., they return copies of the fracvector, rather than modifying it.
However, methods have also been added named with
set_*prefixes which perform mutating operations, e.g.:A.set_T()
replaces A with its own transpose, whereas:
A.T()
just returns a new MutableFracVector that is the transpose of A, leaving A unmodified.
- nested_map: ClassVar[collections.abc.Callable[Ellipsis, Any]]¶
- nested_inmap: ClassVar[collections.abc.Callable[Ellipsis, Any]]¶
- nested_map_fractions: ClassVar[collections.abc.Callable[Ellipsis, Any]]¶
- noms: Any¶
- classmethod use(old: Any) httk.core.vectors.fracvector.FracVector[source]¶
Make sure the variable is a MutableFracVector, and if not, convert it.
- to_FracVector() httk.core.vectors.fracvector.FracVector[source]¶
Return a FracVector with the values of this MutableFracVector.
- classmethod from_FracVector(other: httk.core.vectors.fracvector.FracVector) MutableFracVector[source]¶
Create a MutableFracVector from a FracVector.
- invalidate() None[source]¶
Internal method to call when the MutableFracVector is changed in such a way that cached properties are invalidated (e.g.,
_dim).
- set_negative() None[source]¶
Change the MutableFracVector inline into its own negative:
self -> -self.
- set_simplify() None[source]¶
Change the MutableFracVector; reduces any common factor between the denominator and all nominators.
- set_set_denominator(resolution: int = 1000000000) None[source]¶
Change the MutableFracVector; reduces resolution.
- Parameters:
resolution – the new denominator; each element becomes the closest numerical approximation using this denominator.
- type httk.core.vectors.NumericVector = float | numpy.ndarray[source]¶
- httk.core.vectors.numpy_available() bool[source]¶
Return whether the optional numpy dependency is available for the numeric helpers.
This reads the vectors package’s
_numpy_availableflag freshly on each call (the flag set whenhttk.core.vectorsconditionally imports/registers the numpy backend), so tests may monkeypatchhttk.core.vectors._numpy_availableto exercise the numpy-absent path.
- httk.core.vectors.to_numeric(obj: httk.core.vectors.vector_like.VectorLike) NumericVector[source]¶
Present
objas plain numpy numbers: anumpy.ndarrayfor a tensor, afloatfor a scalar.A tensor becomes a base-class
float64numpy.ndarray(never a view subclass) viaVectorNumpyView; a scalar input (shape()) returns a plainfloatviato_numeric_scalar()(never a 0-d array).The numeric presentation is numpy-backed, so this always requires numpy: it raises
ImportError(naming thehttk-core[numpy]extra) when numpy is not installed, uniformly, so the contract is predictable regardless of the input shape. Useto_numeric_scalar()directly for a single float without a numpy requirement.
- httk.core.vectors.to_numeric_scalar(obj: Any) float[source]¶
Convert a single scalar value to a plain
float, deterministically.A
SurdScalar(or scalarSurdVector) and a scalarFracVectorrender through their own exactto_float(); aFraction,int,float, or numericstrrender viaany_to_fraction(). A non-scalar shape raisesTypeError.Unlike
to_numeric(), this needs no numpy: a plainfloatconversion has no numpy dependency, so it works unconditionally and never raises for a missing numpy.
- class httk.core.vectors.SurdScalar(components: dict[int, httk.core.vectors.fracvector.FracVector], dim: tuple[int, Ellipsis])[source]¶
Bases:
SurdVectorA scalar
SurdVector(shape()): a single field element \(\sum_r q_r\sqrt r\).Adds the scalar-only operations — the field inverse, exact sign and ordering, and Decimal rendering — that need a single value rather than a tensor.
- inverse() SurdScalar[source]¶
The multiplicative inverse
1/self(raisesZeroDivisionErroron zero).
- sign() int[source]¶
Return the exact sign of the value:
-1,0or1.For an irrational value the sign is decided by refining rational lower/upper bounds on each
sqrt(r)(frominteger_sqrt()at increasing precision) and summing the weighted intervals until the total interval excludes zero — which always happens in finitely many steps because a nonzero surd is bounded away from zero.
- classmethod cos_degrees(q: Any) SurdScalar | None[source]¶
Return
cos(q degrees)as an exactSurdScalar, or None when it is not a surd.The value lies in the squarefree-radical field precisely when the angle, reduced modulo 360, is a multiple of 15 or of 36 degrees — e.g. \(\cos 30° = \tfrac{\sqrt3}2\), \(\cos 15° = \tfrac{\sqrt6+\sqrt2}4\), \(\cos 36° = \tfrac{1+\sqrt5}4\).
qmay be an int,Fraction, or numeric string (parsed viaany_to_fraction()).That list is complete: \(\cos(2\pi a/b)\) lies in a field generated by square roots of rationals iff the Galois group \((\mathbb{Z}/b)^\times/\{\pm1\}\) of \(\mathbb{Q}(\cos 2\pi/b)\) has exponent at most 2, which holds exactly for \(b \in \{1,2,3,4,5,6,8,10,12,24\}\) — the rational-degree angles that are multiples of 15° or 36°. (Niven’s theorem is the rational-value special case of this classification.) A
Noneresult is therefore a proof that the exact cosine lies outside \(\mathbb{Q}[\sqrt n]\) — usecos()withdegrees=Truefor a deterministic rational approximation in that case.
- classmethod sin_degrees(q: Any) SurdScalar | None[source]¶
Return
sin(q degrees)as an exactSurdScalar, or None when it is irrational.Computed as
cos(90 - q)degrees, so exactness follows the same classification ascos_degrees()applied to90 - q: exact for all multiples of 15 degrees, otherwise None (a proof that the exact sine is outside the field). Note the asymmetry withcos_degrees()for the 36° family: \(\cos 36°\) is an exact surd but \(\sin 36° = \cos 54°\) is not (54 is a multiple of neither 15 nor 36).
- acos_degrees() fractions.Fraction | None[source]¶
Return the exact
arccosof this value in degrees over \([0, 180]\), or None.This is the reverse table lookup: the result is an exact rational number of degrees precisely when the value equals the cosine of a multiple of 15° or 36° (the complete set of rational-degree angles with surd cosines — see
cos_degrees()), decided by exact surd equality; otherwise None (the exact angle is then irrational in degrees). RaisesValueError— decided exactly viasign()— when the value lies outside \([-1, 1]\).
- to_float(prec: fractions.Fraction = fractions.Fraction(1, 10**30)) float[source]¶
The value as a float (via a high-precision exact rational approximation).
- to_decimal(digits: int | None = None, rounding: str = 'half_even', max_refinements: int | None = None) Any[source]¶
Render the value as a correctly-rounded
decimal.Decimal.Reuses the exact-math module’s Ziv refinement loop (
_to_decimal): a rational value renders exactly (its finite expansion when it fits, else quantized), and an irrational surd — never on a rational rounding boundary — is rendered by refining the rational approximation until the rounding is determined.digits(significant digits; default: the active decimal context precision),rounding("half_even"/"down") andmax_refinementsmatchsqrt()in Decimal mode.
- class httk.core.vectors.SurdVector(components: dict[int, httk.core.vectors.fracvector.FracVector], dim: tuple[int, Ellipsis])[source]¶
An immutable exact tensor over the squarefree-radical field \(\mathbb{Q}[\sqrt n : n\ \text{squarefree}]\).
A SurdVector is a map
{squarefree radicand -> FracVector coefficient}(all coefficients sharing onedim); radicand1is the rational part. It is stored canonically — coefficients simplified, all-zero coefficients dropped — so the representation is unique and equality/zero-detection are exact. LikeFracVectorit is immutable and hashable.See the module docstring for the field facts, the fractional-vs-Cartesian motivation, and the magnitude-vs-linear-structure purpose boundary.
- classmethod create(obj: Any) SurdVector[source]¶
Create a SurdVector from a
FracVector, nested rationals, or another SurdVector.A SurdVector is returned unchanged; anything else is built through
create()and embedded exactly at radicand 1 (so every rational value is representable, and a rational input stays rational).
- classmethod from_radicand_map(mapping: dict[int, Any]) SurdVector[source]¶
Compose a SurdVector from a
{radicand -> coefficient}mapping.Radicands are positive integers and need not be squarefree — each is normalized via
square_part(sqrt(radicand) = s*sqrt(r)) and the coefficients (FracVector-like, all of one shape) folded together canonically.
- classmethod sqrt_of(q: Any) SurdScalar[source]¶
Return the exact square root of a nonnegative rational
qas aSurdScalar.The result is a plain rational when
qis a perfect square (e.g.sqrt_of(4/9) == 2/3) and otherwise a single-radical surd (sqrt_of(8) == 2*sqrt(2)).sqrt(p/q)is normalized assqrt(p*q)/qso the stored radicand is always a positive squarefree integer (sqrt_of(1/2) == sqrt(2)/2). RaisesValueErroron a negative argument — there is no exact square root of a surd (no nested radicals), only of a rational.
- classmethod zero(dim: tuple[int, Ellipsis] = ()) SurdVector[source]¶
The zero SurdVector of shape
dim(aSurdScalarfor the default()).
- classmethod one() SurdScalar[source]¶
The scalar
1.
- property is_rational: bool¶
True iff the value is purely rational (only the radicand-1 term is present).
- property radicands: tuple[int, Ellipsis]¶
The sorted squarefree radicands present in the canonical form.
- coefficient(radicand: int) httk.core.vectors.fracvector.FracVector[source]¶
The FracVector coefficient of
sqrt(radicand)(a zero tensor when absent).
- T() SurdVector[source]¶
Return the transpose, transposing each radicand’s coefficient tensor.
- dot(other: Any) SurdScalar[source]¶
Vector dot product of two 1-D SurdVectors (
sum a_i b_i).
- lengthsqr() SurdScalar[source]¶
Return the squared length
A * A^Tas aSurdScalar.
- length() SurdScalar[source]¶
Return the exact length
sqrt(lengthsqr)as aSurdScalar.Exact precisely when
lengthsqris rational — which canonical arithmetic guarantees for a difference of Cartesian sites under a rational metric (the crystallographic case). Whenlengthsqris itself irrational the length would be a nested radical (sqrt(a + b*sqrt(c))), which is outside the field, so this raisesValueError.
- det() SurdScalar[source]¶
Return the determinant of a 3x3 SurdVector as a
SurdScalar.
- inv() SurdVector[source]¶
Return the inverse of a 3x3 SurdVector via the adjugate and the scalar field inverse.
- to_fractions_approx(prec: fractions.Fraction = fractions.Fraction(1, 10**30)) Any[source]¶
A deterministic nested list of
fractions.Fractionwithinprecof the true value.Exact (not merely within
prec) whenever the value is rational. This is thecompute(prec)-shaped rational approximation reused by the Decimal rendering.
- to_floats(prec: fractions.Fraction = fractions.Fraction(1, 10**30)) Any[source]¶
A nested list of floats (via a high-precision exact rational approximation).
- class httk.core.vectors.VectorAPI[source]¶
Bases:
abc.ABCAbstract base class for the canonical vector interface.
It declares the exactness-preserving
fractionsaccessor (a nested tuple offractions.Fraction, or a bare Fraction for a scalar) that every vector backend produces from its own native representation and every vector view builds its presentation from, together with thedimshape tuple. This is the single interchange format; there is no pairwise conversion between backends.On top of the two abstract accessors it provides the guaranteed float renderings
to_floats()andto_float(), derived from thefractionshub — so whatever object the family hands you,.to_floats()works. (The exact value typesFracVectorandSurdVectorhonor the same contract with their own implementations.)
- class httk.core.vectors.VectorBackend(backend, **hints)[source]¶
Bases:
httk.core.views.Backend[VectorBackend],httk.core.vectors.vector_api.VectorAPIAbstract base class for all backends of vector (tensor) data.
Concrete backends carry a native representation (an exact FracVector, plain nested sequences, or a numpy array) and produce the canonical exactness-preserving
fractionsinterchange declared byVectorAPIfrom it.- backend_classes: ClassVar[list[type[httk.core.views.Backend[Any]]]]¶
- class httk.core.vectors.VectorFrac(obj: httk.core.vectors.fracvector.FracVector, **hints: Any)[source]¶
Bases:
httk.core.vectors.vector_backend.VectorBackendBackend for a vector backed by an actual
FracVector(orFracScalar).Its
fractionsaccessor produces the exact nested tuple of Fraction, andunwrapreturns the wrapped FracVector.- property fractions: httk.core.vectors.vector_api.Fractions¶
- unwrap() Any[source]¶
Return the most raw representation possible of this backend, i.e., if it uses a backend with an internal representaion - or if it can (possibly lossly) convert itself into a more raw representation that still would be recognized as a <Something>Like type, that representation will be returned. If this is not possible, the instance itself is returned.
- class httk.core.vectors.VectorFracView(obj: httk.core.vectors.vector_like.VectorLike, denom: Any = _NO_DENOM, **hints: Any)[source]¶
Bases:
httk.core.vectors.vector_view.VectorView,httk.core.vectors.fracvector.FracVectorA view presenting an underlying vector backend as an exact
FracVector.This view is a genuine FracVector, so it can be passed anywhere a FracVector is accepted, and it exposes the full exact-rational algebra (
det/inv/*/…). It is built eagerly from the backend’s exactfractionsinterchange on construction, so the round-trip is exactness-preserving for the frac and native backends. (numpy values are binary rationals, so a numpy source round-trips to the exact float64 rational, not necessarily the original decimal fraction.)Because inherited FracVector algebra builds its results with the low-level
self.__class__(noms, denom)constructor, this class also accepts that two-argument form; results built that way are plain (backend-less) FracVector values presented through this class.- unwrap() Any[source]¶
Return the most raw representation possible of this view, i.e., if it uses a backend with an internal representaion - or if it can (possibly lossly) convert itself into a more raw representation that still would be recognized as a <Something>Like type, that representation will be returned. If this is not possible, the instance itself is returned.
- type httk.core.vectors.VectorLike = vector_backend.VectorBackend | vector_view.VectorView | fracvector.FracVector | surdvector.SurdVector | tuple[Any, ...] | list[Any] | 'numpy.ndarray'[source]¶
- class httk.core.vectors.VectorNative(obj: Any, **hints: Any)[source]¶
Bases:
httk.core.vectors.vector_backend.VectorBackendBackend for a vector backed by plain nested sequences.
The native representation is a (possibly nested) rectangular list or tuple whose leaves are
int,float,decimal.Decimal,fractions.Fraction, orstr. Conversion into the exactfractionsinterchange goes throughcreate(), so string-uncertainty parsing (e.g."0.33342(10)") works here too.unwrapreturns the original raw object.- property native: Any¶
The original nested list/tuple this backend wraps, leaves untouched.
This is the same object returned by
unwrap(), exposed as a named accessor so the native view can present a natively-held vector’s leaves verbatim (its preserve-original default) without reaching into private state.
- property fractions: httk.core.vectors.vector_api.Fractions¶
- unwrap() Any[source]¶
Return the most raw representation possible of this backend, i.e., if it uses a backend with an internal representaion - or if it can (possibly lossly) convert itself into a more raw representation that still would be recognized as a <Something>Like type, that representation will be returned. If this is not possible, the instance itself is returned.
- class httk.core.vectors.VectorNativeView(obj: httk.core.vectors.vector_like.VectorLike, **hints: Any)[source]¶
Bases:
httk.core.vectors.vector_view.VectorView,tupleA view presenting an underlying vector backend as nested tuples, with a selectable leaf codec.
The leaf codec is the element-domain axis (see
httk.core.vectors.leaf_codecs); it is chosen with theleaf=hint plus any codec options (rounding=,digits=, …). There are three modes:preserve-original (
leaf=None, and the source is natively-held data): the backend’s original nested leaves are presented verbatim — the same objects, only containers tuple-ized (Decimals in, the sameDecimals out). This fixes silent Fraction-ization of natively-held data.exact default (
leaf=None, source crossing from a frac/numpy backend): the"exact"codec —intwhen integral, elsefractions.Fraction, never a float (the historical behavior).explicit codec (
leaf="int"/"float"/"decimal"/"fraction"/…): every element is converted from the backend’s exactfractionsinterchange through that codec.
The codec name and its options are validated eagerly at construction (an unknown codec name or invalid option raises
ValueError); a codec never raises on the data — a value it cannot represent exactly takes the codec’s documented default conversion, because the backend keeps the exact original. A scalar source is presented as a single-element tuple.- unwrap() Any[source]¶
Return the most raw representation possible of this view, i.e., if it uses a backend with an internal representaion - or if it can (possibly lossly) convert itself into a more raw representation that still would be recognized as a <Something>Like type, that representation will be returned. If this is not possible, the instance itself is returned.
- class httk.core.vectors.VectorSurd(obj: httk.core.vectors.surdvector.SurdVector, **hints: Any)[source]¶
Bases:
httk.core.vectors.vector_backend.VectorBackendBackend for a vector backed by an exact
SurdVector(orSurdScalar), kind"surd".unwrapreturns the exact SurdVector. The canonicalfractionshub is exact whenever the value is rational (a surd whose canonical form has only the radicand-1 term), matching the established backend-keeps-the-original principle; when the value is genuinely irrational it is reduced to a deterministic rational approximation at the active decimal context precision plus a small guard (lossy but reproducible), and the exact original remains recoverable viaunwrap.- property fractions: httk.core.vectors.vector_api.Fractions¶
- unwrap() Any[source]¶
Return the most raw representation possible of this backend, i.e., if it uses a backend with an internal representaion - or if it can (possibly lossly) convert itself into a more raw representation that still would be recognized as a <Something>Like type, that representation will be returned. If this is not possible, the instance itself is returned.
- class httk.core.vectors.VectorSurdView(obj: httk.core.vectors.vector_like.VectorLike, **hints: Any)[source]¶
Bases:
httk.core.vectors.vector_view.VectorView,httk.core.vectors.surdvector.SurdVectorA view presenting an underlying vector backend as an exact
SurdVector.This view is a genuine SurdVector, so it exposes the full exact surd algebra (
det/inv/*/length/…). It is built eagerly on construction, following the eager immutable-subclass pattern ofVectorFracView: from a surd backend it adopts the exact SurdVector directly, and from a frac/native/numpy backend it embeds the backend’s exact rationalfractionsat radicand 1 — exactly, since every rational is a surd.(numpy values are binary rationals, so a numpy source embeds the exact float64 rational, not necessarily the original decimal fraction — the same caveat as
VectorFracView.)- unwrap() Any[source]¶
Return the most raw representation possible of this view, i.e., if it uses a backend with an internal representaion - or if it can (possibly lossly) convert itself into a more raw representation that still would be recognized as a <Something>Like type, that representation will be returned. If this is not possible, the instance itself is returned.
- class httk.core.vectors.VectorView[source]¶
Bases:
httk.core.views.View[httk.core.vectors.vector_backend.VectorBackend]Abstract base class for all views of vector (tensor) data.