quantum-shadow-maps_v2/scripts/cluster.py

51 lines
1.9 KiB
Python
Raw Permalink Normal View History

2026-07-26 14:09:49 +02:00
"""cluster.py -- the full 15x15 bigraduated cluster shadow map M_S for a 2-qubit source
cluster S (within 4 qubits), and helpers for building the Pauli tensor of a general
(possibly mixed) density matrix."""
import numpy as np
I2 = np.eye(2, dtype=complex)
X = np.array([[0, 1], [1, 0]], dtype=complex)
Y = np.array([[0, -1j], [1j, 0]], dtype=complex)
Z = np.array([[1, 0], [0, -1]], dtype=complex)
_PAULI = [I2, X, Y, Z]
def cluster_map(C, s0, s1):
"""C: (4,4,4,4) Pauli correlation tensor. S = {s0,s1} (source cluster), complement =
the other two qubits. Returns the normalized 15x15 matrix M_S(rho), normalization
1/sqrt((d_S-1)(d_Sc-1)) = 1/sqrt(3*3) = 1/3 for two-qubit clusters in 4 qubits."""
others = [k for k in range(4) if k not in (s0, s1)]
c0, c1 = others
rows = [(i, j) for i in range(4) for j in range(4) if (i, j) != (0, 0)]
cols = [(i, j) for i in range(4) for j in range(4) if (i, j) != (0, 0)]
M = np.zeros((15, 15))
for ri, (ia, ib) in enumerate(rows):
for ci, (ic, idd) in enumerate(cols):
idx = [0, 0, 0, 0]
idx[s0] = ia
idx[s1] = ib
idx[c0] = ic
idx[c1] = idd
M[ri, ci] = C[tuple(idx)]
return M / 3.0
def nuc(M):
return np.linalg.svd(M, compute_uv=False).sum()
def full_tensor_mixed(rho):
"""Pauli-tensor extraction for a general (possibly mixed) 16x16 density matrix rho,
via direct trace. Slower than core2.full_tensor (which needs a pure-state vector)
but works for explicit mixtures (e.g. the Smolin state)."""
def kron4(a, b, c, d):
return np.kron(np.kron(a, b), np.kron(c, d))
C = np.zeros((4, 4, 4, 4))
for i0 in range(4):
for i1 in range(4):
for i2 in range(4):
for i3 in range(4):
op = kron4(_PAULI[i0], _PAULI[i1], _PAULI[i2], _PAULI[i3])
C[i0, i1, i2, i3] = np.real(np.trace(rho @ op))
return C