70 lines
2.2 KiB
Python
70 lines
2.2 KiB
Python
"""
|
|
Conformal Geometric Algebra geometry on Cl(4,1).
|
|
|
|
Key identity: for null vectors X, Y on the horosphere,
|
|
cga_inner(X, Y) = -d(X, Y)^2 / 2
|
|
where d is Euclidean distance.
|
|
|
|
This is the ONLY distance metric in CORE-AI.
|
|
No cosine similarity. No L2 norm. No approximate indexing.
|
|
"""
|
|
|
|
import numpy as np
|
|
from .cl41 import geometric_product, reverse, scalar_part, basis_vector, N_COMPONENTS
|
|
|
|
|
|
def cga_inner(X: np.ndarray, Y: np.ndarray) -> float:
|
|
"""
|
|
Symmetric inner product: 0.5 * scalar_part(X*Y + Y*X).
|
|
For null vectors representing conformal points: equals -d^2 / 2.
|
|
"""
|
|
XY = geometric_product(X, Y)
|
|
YX = geometric_product(Y, X)
|
|
return 0.5 * scalar_part(XY + YX)
|
|
|
|
|
|
def outer_product(X: np.ndarray, Y: np.ndarray) -> np.ndarray:
|
|
"""
|
|
Outer (wedge) product: X ^ Y.
|
|
For a prompt versor X_p and response versor X_r,
|
|
X_p ^ X_r is a grade-2 object encoding their geometric relationship.
|
|
A real (non-imaginary) result means the dialogue is coherent.
|
|
"""
|
|
XY = geometric_product(X, Y)
|
|
YX = geometric_product(Y, X)
|
|
return 0.5 * (XY - YX)
|
|
|
|
|
|
def is_null(X: np.ndarray, tol: float = 1e-6) -> bool:
|
|
"""Check if X lies on the null cone: X*X = 0."""
|
|
return abs(cga_inner(X, X)) < tol
|
|
|
|
|
|
def null_project(X: np.ndarray) -> np.ndarray:
|
|
"""
|
|
Re-project X onto the null cone.
|
|
Call on vault entries periodically to correct floating-point null-cone drift.
|
|
This is numerical maintenance, not a heat shield.
|
|
Method: extract Euclidean part, re-embed via standard CGA point map.
|
|
"""
|
|
euclidean = X[1:4].copy().astype(np.float32)
|
|
x_sq = float(np.dot(euclidean, euclidean))
|
|
result = np.zeros(N_COMPONENTS, dtype=np.float32)
|
|
result[1:4] = euclidean
|
|
result[4] = 0.5 * x_sq # e+ coefficient
|
|
result[5] = 1.0 # e- coefficient
|
|
return result
|
|
|
|
|
|
def embed_point(x: np.ndarray) -> np.ndarray:
|
|
"""
|
|
Embed a Euclidean point x in R^3 into the CGA null cone.
|
|
Standard map: X = x + (1/2)|x|^2 * e+ + e-
|
|
"""
|
|
x = np.asarray(x, dtype=np.float32)
|
|
assert len(x) == 3, "embed_point expects a 3D vector"
|
|
result = np.zeros(N_COMPONENTS, dtype=np.float32)
|
|
result[1:4] = x
|
|
result[4] = 0.5 * float(np.dot(x, x))
|
|
result[5] = 1.0
|
|
return result
|