Use true versor fixtures in closure tests

This commit is contained in:
Shay 2026-05-13 12:55:20 -07:00
parent fca6216e3f
commit bacf1f4084

View file

@ -4,41 +4,58 @@ It verifies the core algebraic invariant of the entire system.
"""
import numpy as np
import pytest
from hypothesis import given, settings
from hypothesis import strategies as st
from algebra.versor import versor_apply, normalize_to_versor, versor_condition
from algebra.versor import versor_apply, unitize_versor, versor_condition
def _random_versor(seed=None) -> np.ndarray:
def _unit_reflector(seed=None) -> np.ndarray:
"""
Construct a true Cl(4,1) versor: a unit grade-1 vector.
Scaling an arbitrary 32D multivector does not make it a versor. A unit
vector is a valid reflector by construction and satisfies v * ~v = ±1.
"""
rng = np.random.default_rng(seed)
raw = rng.standard_normal(32).astype(np.float32)
return normalize_to_versor(raw)
vec = rng.standard_normal(5).astype(np.float32)
# Avoid accidentally producing an exactly null vector under (+,+,+,+,-).
if abs(float(np.dot(vec[:4], vec[:4]) - vec[4] * vec[4])) < 1e-4:
vec[0] += 1.0
mv = np.zeros(32, dtype=np.float32)
mv[1:6] = vec
return unitize_versor(mv)
@given(st.integers(min_value=0, max_value=99))
@settings(max_examples=100)
def test_versor_apply_preserves_manifold(seed):
"""V*F*reverse(V) must be a versor if V and F are versors."""
V = _random_versor(seed)
F = _random_versor(seed + 1000)
V = _unit_reflector(seed)
F = _unit_reflector(seed + 1000)
result = versor_apply(V, F)
cond = versor_condition(result)
assert cond < 1e-4, f"versor_apply broke the manifold: condition={cond:.2e}"
def test_normalize_produces_versor():
raw = np.random.randn(32).astype(np.float32)
V = normalize_to_versor(raw)
assert versor_condition(V) < 1e-6
def test_unitize_random_multivector_is_not_claimed_to_create_versor():
"""
Unitizing arbitrary 32D garbage is not versor construction.
unitize_versor() scales a construction product; it does not project an
arbitrary multivector onto the versor manifold. This test prevents the
old false fixture from returning.
"""
raw = np.random.default_rng(0).standard_normal(32).astype(np.float32)
V = unitize_versor(raw)
assert versor_condition(V) > 1e-3
def test_composition_closed():
"""Two sequential versor_apply calls stay on the manifold."""
V1 = _random_versor(0)
V2 = _random_versor(1)
F = _random_versor(2)
V1 = _unit_reflector(0)
V2 = _unit_reflector(1)
F = _unit_reflector(2)
F2 = versor_apply(V1, F)
F3 = versor_apply(V2, F2)
assert versor_condition(F3) < 1e-4
@ -48,6 +65,6 @@ def test_identity_versor():
"""Scalar 1 is a valid versor and applies as identity."""
identity = np.zeros(32, dtype=np.float32)
identity[0] = 1.0
F = _random_versor(42)
F = _unit_reflector(42)
result = versor_apply(identity, F)
assert np.allclose(result, F, atol=1e-5)