Spaces:
Running on Zero
Running on Zero
Download src/ulens/_math.py from loose-bits/u-space: direct link, hf CLI and curl.
- Browser
- Download file 790 Bytes
-
https://huggingface.co/spaces/loose-bits/u-space/resolve/main/src/ulens/_math.py
- Command line
-
hf download hf://spaces/loose-bits/u-space/src/ulens/_math.py
-
curl -L -o _math.py https://huggingface.co/spaces/loose-bits/u-space/resolve/main/src/ulens/_math.py
790 Bytes
| """Vector normalisation and symmetric orthogonalisation.""" | |
| from __future__ import annotations | |
| import numpy as np | |
| EPS = 1e-9 | |
| def unit(a: np.ndarray) -> np.ndarray: | |
| """Rows of `a` scaled to unit L2 norm, in float32.""" | |
| a = np.asarray(a, np.float32) | |
| return a / (np.linalg.norm(a, axis=-1, keepdims=True) + EPS) | |
| def lowdin(M: np.ndarray) -> np.ndarray: | |
| """Symmetric (Loewdin) orthonormalisation U = M (M^T M)^{-1/2}. | |
| Each output column is sign-aligned with the prototype column it came from, so axis k of | |
| the result still points the same way as column k of `M`. | |
| """ | |
| M = np.asarray(M, np.float32) | |
| w, V = np.linalg.eigh(M.T @ M) | |
| U = M @ (V @ np.diag(np.maximum(w, 1e-12) ** -0.5) @ V.T) | |
| return U * np.sign(np.einsum("hc,hc->c", U, M))[None, :] | |