Use newtype idiom to generate Hyperbolic Space-specific matrix and vector types
To help avoid mistakes and make code easier to read and write, we should consider creating types to enforce the various invariants Hyperbolic vectors can have, much like nalgebra's Point vs. Vector vs. UnitVector types.
For example, we could have the following types (names subject to change):
-
HPoint: A vector that can represent a point in hyperbolic space. The invariant isx^2 + y^2 + z^2 < w^2andw > 0. -
HVector: A vector that can represent a direction in hyperbolic space. The invariant isx^2 + y^2 + z^2 > w^2. -
NormalHPoint: A Lorentz-normalizedHPoint. The invariant isx^2 + y^2 + z^2 - w^2 = -1andw > 0. -
NormalHVector: A Lorentz-normalizedHVector. The invariant isx^2 + y^2 + z^2 - w^2 = 1. -
HIsometry: A matrix representing an isometry in Hyperbolic space. All columns are Lorentz-orthogonal to each other. The first three columns areNormalHVectors, and the last column is aNormalHPoint.
Under normal use, it should be pretty easy to enforce these invariants. There can be convenient helper and impl functions for common operations and conversions. For exceptional cases, functions with unchecked in their name can be added to opt out of this extra safety.
Let's continue the nalgebra convention and use HyperPoint and HyperVector rather than overloading "vector" further.
I like that idea. I'll edit the description from HyperWVector to HyperPoint and from HyperXyzVector to HyperVector. If we for some reason need a single type that encompasses both (which I don't expect will happen), which originally would have been called HyperVector, we can just use a term like GeneralHyperVector instead.
Another option is to call it HPoint, HVector, UnitHPoint, UnitHVector, and HIsometry to keep things shorter. There's already an HPoint in math.rs, but it isn't used anywhere, so it would make sense to replace it.
I like that concision. Given the broad scope of these types I think that's justified.
Another thought: for the "unit" types, would it make sense to represent w implicitly, since it's uniquely determined by the other components? Also, to avoid confusion with vectors of unit length, would it make sense to name them differently (perhaps LorentzHPoint)?
My first inclination would be to say that w should not be implicit. It cannot be implicit in UnitHVector because it can be positive or negative, and for UnitHPoint, if we need to find w, it requires a square-root operation, which is expensive enough that one would be tempted to use an HPoint instead, reducing safety.
For the unit type, it might make sense to use NormalizedHPoint. There isn't really any situation where it makes sense to take the Euclidean length of one of these vector types, so I believe using a term like Lorentz would be redundant and wouldn't clarify that it's Lorentz-normalized. I do agree that the term "unit vector" doesn't really make sense here, so I'm down to switch the language to "normalized vector".
SGTM. Maybe "Normal" for concision.
That makes sense to me. "normal" means a lot of things in math, so there is the risk of confusing it with surface normals, but I think the benefits of that concision outweigh this risk. I'll edit the issue description.
If we're careful, we may be able to use the proper mathematical terms for things, which may help for people who want to google things. For instance, we could lean into the "Minkowski" terminology and use something like MVector. Whenever we want to take a transpose, we could take the "Hermitian Adjoint" instead (probably can be shortened to adjoint). I don't know the best term for "orthogonal matrix" that could apply to Minkowski space, but I think "unitary" is the right term (https://en.wikipedia.org/wiki/Unitary_operator).
This could also potentially reopen the "unit" vs "normal" question, since it seems likely that Minkowski space already would have a term for vectors whose Minkowski product with themselves is 1 or -1. Based on https://en.wikipedia.org/wiki/Minkowski_space#Pseudo-Euclidean_metrics, the answer might be that "unit vector" is the right term after all, and we would use the term "space" and "time" to distinguish between the two types of unit vector.
This would give us something like MVector, MSpaceVector, MTimeVector, UnitMSpaceVector, UnitMTimeVector, and MUnitaryTransform (or possibly shortening it to MIsometry, since inner-product-preserving transformations should probably be able to be referred to as isometries).
Fortunately, renaming things is easy, so this can be decided later.