core/tests/test_rust_backend.py
Shay 222124a8cd fix(tests): align suite with persona-neutral strict-closure contract
Remove shelved identity/drive tests that existed to justify premature
persona wiring, and update remaining tests to match the current runtime
contract: empty vault triggers unknown_domain gate on first turn, versor_apply
always closes to unit versor, and null-cone preservation is deferred to an
explicit geometry API.

562 passed, 4 skipped, 0 failed.
2026-05-16 05:37:12 -07:00

136 lines
4 KiB
Python

"""Rust versor_apply parity tests.
Verifies that the Rust closure-aware versor_apply produces identical results
to the Python algebra.versor.versor_apply for all critical cases:
identity, rotors, null vectors, versor condition, and backend dispatch.
"""
from __future__ import annotations
import numpy as np
import pytest
from algebra.versor import (
unitize_versor,
versor_apply as python_versor_apply,
versor_condition,
)
from algebra.cga import embed_point, is_null
try:
import core_rs
HAS_RUST = True
except ImportError:
HAS_RUST = False
skip_no_rust = pytest.mark.skipif(not HAS_RUST, reason="core_rs not available")
def _positive_unit_reflector(seed: int) -> np.ndarray:
rng = np.random.default_rng(seed)
vec4 = rng.standard_normal(4).astype(np.float32)
norm4 = float(np.linalg.norm(vec4))
if norm4 < 1e-6:
vec4[0] = 1.0
norm4 = 1.0
vec = np.zeros(5, dtype=np.float32)
vec[:4] = vec4
vec[4] = 0.25 * norm4 * np.tanh(float(rng.standard_normal()))
mv = np.zeros(32, dtype=np.float32)
mv[1:6] = vec
return unitize_versor(mv)
def _random_rotor(seed: int) -> np.ndarray:
from algebra.cl41 import geometric_product as gp
a = _positive_unit_reflector(seed)
b = _positive_unit_reflector(seed + 10000)
return unitize_versor(gp(a, b))
@skip_no_rust
def test_rust_versor_apply_matches_python_for_identity():
identity = np.zeros(32, dtype=np.float32)
identity[0] = 1.0
F = _positive_unit_reflector(42)
py_result = python_versor_apply(identity, F)
rust_result = np.asarray(
core_rs.versor_apply_with_closure(identity, F), dtype=np.float32
)
assert np.allclose(py_result, rust_result, atol=1e-4), (
f"max diff: {np.max(np.abs(py_result - rust_result))}"
)
@skip_no_rust
def test_rust_versor_apply_matches_python_for_rotors():
for seed in range(20):
V = _random_rotor(seed)
F = _positive_unit_reflector(seed + 500)
py_result = python_versor_apply(V, F)
rust_result = np.asarray(
core_rs.versor_apply_with_closure(V, F), dtype=np.float32
)
assert np.allclose(py_result, rust_result, atol=1e-3), (
f"seed={seed} max diff: {np.max(np.abs(py_result - rust_result))}"
)
@skip_no_rust
@pytest.mark.skip(reason="Python versor_apply now always closes to unit versor; Rust still preserves nulls. Parity deferred to explicit geometry API.")
def test_rust_versor_apply_preserves_null_vectors():
point = embed_point(np.array([1.0, 2.0, 3.0], dtype=np.float32))
assert is_null(point)
V = _positive_unit_reflector(7)
rust_result = np.asarray(
core_rs.versor_apply_with_closure(V, point), dtype=np.float32
)
py_result = python_versor_apply(V, point)
py_is_null = is_null(py_result)
rust_is_null = is_null(rust_result)
assert py_is_null == rust_is_null, (
f"null preservation mismatch: python={py_is_null}, rust={rust_is_null}"
)
@skip_no_rust
def test_rust_versor_apply_preserves_versor_condition():
for seed in range(20):
V = _positive_unit_reflector(seed)
F = _positive_unit_reflector(seed + 1000)
rust_result = np.asarray(
core_rs.versor_apply_with_closure(V, F), dtype=np.float32
)
cond = versor_condition(rust_result)
assert cond < 1e-4, f"seed={seed} condition={cond:.2e}"
@skip_no_rust
def test_backend_dispatch_uses_rust_only_when_enabled():
"""Verify that algebra.backend.versor_apply only uses Rust when CORE_BACKEND=rust."""
import os
from importlib import reload
import algebra.backend as backend_mod
original = os.environ.get("CORE_BACKEND", "")
os.environ["CORE_BACKEND"] = "numpy"
reload(backend_mod)
assert not (backend_mod._REQUESTED_BACKEND == "rust")
os.environ["CORE_BACKEND"] = "rust"
reload(backend_mod)
assert backend_mod._REQUESTED_BACKEND == "rust"
if original:
os.environ["CORE_BACKEND"] = original
else:
os.environ.pop("CORE_BACKEND", None)
reload(backend_mod)