Project, reject, and invert safely¶
For a non-null blade \(A\), use
For vector \(x\), projection gives the component in the subspace represented by \(A\). Supply a decomposable blade: a homogeneous tensor is not necessarily a blade in higher dimensions. The inverse helper uses this formula; it does not solve a general multivector inverse or verify decomposability.
import torch
from clifra import make_algebra
algebra = make_algebra(3, dtype=torch.float64)
vectors = algebra.layout((1,))
bivectors = algebra.layout((2,))
plane = torch.tensor([2., 0., 0.], dtype=torch.float64) # 2 e12
x = torch.tensor([1., 2., 3.], dtype=torch.float64)
project = algebra.plan_strict_blade_project(input=vectors, blade=bivectors)
projection = project(x, plane)
rejection = algebra.strict_blade_reject(x, plane, input=vectors, blade=bivectors)
torch.testing.assert_close(projection, torch.tensor([1., 2., 0.], dtype=x.dtype))
torch.testing.assert_close(projection + rejection, x)
inverse = algebra.strict_blade_inverse(plane, input=bivectors)
identity = algebra.geometric_product(
plane, inverse, left=bivectors, right=bivectors, output=algebra.layout((0,)),
)
torch.testing.assert_close(identity, torch.ones(1, dtype=x.dtype))
try:
algebra.strict_blade_inverse(torch.zeros_like(plane), input=bivectors)
except ValueError as error:
assert "zero denominator" in str(error)
else:
raise AssertionError("a zero blade has no inverse")
The strict_ variants divide by the computed signed square and reject any
exactly zero denominator in the input batch. Non-null does not mean
positive: negative denominators are valid and keep their sign. A nonzero
blade with zero signed square is singular, including null blades in mixed
or degenerate signatures.
The corresponding methods without strict_ clamp the denominator's
magnitude to algebra.eps_sq, preserving negative signs and assigning a
positive sign at zero. They can remain finite at singular inputs, but do
not produce a mathematical inverse there. Near-null inverses can still be
very large. For the zero blade, the regularized inverse and projection are
zero and rejection returns the input. Rejection requires an output layout
matching its input layout.
For a supplied versor \(V\), versor_product(V, x, input=..., versor=...)
computes \(\widehat V x V^{-1}\); strict_versor_product uses the exact
denominator. This twisted convention includes a vector's reflection sign.
For an explicit even rotor, it reduces to the usual sandwich. Arbitrary
mixed-parity tensors are not guaranteed to be versors.