tools/tests.py
class Space
Linear-algebra helpers for vector spaces and bipartite decompositions.
gramSchmidt
Gram-Schmidt orthonormalization.
Given vectors
py
def gramSchmidt(vectors: np.ndarray) -> np.ndarray [static]Implementation
python
def gramSchmidt(vectors: np.ndarray) -> np.ndarray:
ortho = []
for v in vectors:
w = v - sum((np.dot(v, np.conj(u)) * u for u in ortho))
if LA.norm(w) > 1e-08:
ortho.append(w / LA.norm(w))
return np.array(ortho)schmidtDecompose
Schmidt decomposition via SVD.
Treats state as a bipartite coefficient matrix
py
def schmidtDecompose(state: np.ndarray) -> list [static]Implementation
python
def schmidtDecompose(state: np.ndarray) -> list:
U, D, V = LA.svd(state)
dims = int(np.min(state.shape))
return sorted([(D[k], U[:, k], V.T[:, k]) for k in range(dims)], key=lambda dec: dec[0], reverse=True)schmidtRank
Schmidt rank (matrix rank) of a bipartite coefficient matrix.
py
def schmidtRank(mat: np.ndarray) -> int [static]Implementation
python
def schmidtRank(mat: np.ndarray) -> int:
return int(LA.matrix_rank(mat))PPT
Peres–Horodecki (PPT) separability test for a bipartite density matrix.
Performs a blockwise partial transpose on subsystem blocks of size sub and checks positivity:
Note: current implementation overrides sub to 3.
py
def PPT(rho: np.ndarray, sub: int) -> boolImplementation
python
def PPT(rho: np.ndarray, sub: int) -> bool:
side = rho.shape[0]
sub = 3
if side % sub != 0:
raise ValueError(f'Matrix side ({side}) not divisible by sub ({sub})')
mat0 = rho.copy()
for i in range(0, mat0.shape[0], sub):
for j in range(0, mat0.shape[1], sub):
mat0[i:i + sub, j:j + sub] = mat0[i:i + sub, j:j + sub].T
return bool(np.all(np.linalg.eigvals(mat0) >= 0))