Spaces:
Sleeping
Sleeping
Download app/surface_code.py from Rohith9059/quantum-qec: direct link, hf CLI and curl.
- Browser
- Download file 4.78 kB
-
https://huggingface.co/spaces/Rohith9059/quantum-qec/resolve/main/app/surface_code.py
- Command line
-
hf download hf://spaces/Rohith9059/quantum-qec/app/surface_code.py
-
curl -L -o surface_code.py https://huggingface.co/spaces/Rohith9059/quantum-qec/resolve/main/app/surface_code.py
4.78 kB
| from __future__ import annotations | |
| import math | |
| from collections import deque | |
| from typing import Dict, List, Tuple | |
| import numpy as np | |
| class SurfaceCode: | |
| """ | |
| Lightweight stabilizer-style simulator. | |
| Uses binary error frames (X/Z) plus parity-check matrices to expose a | |
| syndrome-based control problem while staying within small CPU/RAM limits. | |
| """ | |
| def __init__(self, distance: int): | |
| self.distance = int(distance) | |
| self.n_qubits = 2 * (self.distance ** 2) - 2 * self.distance + 1 | |
| self.grid_cols = math.ceil(math.sqrt(self.n_qubits)) | |
| self.grid_rows = math.ceil(self.n_qubits / self.grid_cols) | |
| self.x_err = np.zeros(self.n_qubits, dtype=np.uint8) | |
| self.z_err = np.zeros(self.n_qubits, dtype=np.uint8) | |
| self.hx, self.hz = self._build_parity_checks() | |
| def _neighbors(self, idx: int) -> List[int]: | |
| r = idx // self.grid_cols | |
| c = idx % self.grid_cols | |
| out: List[int] = [idx] | |
| cand = [ | |
| (r - 1, c), | |
| (r + 1, c), | |
| (r, c - 1), | |
| (r, c + 1), | |
| ] | |
| for rr, cc in cand: | |
| if 0 <= rr < self.grid_rows and 0 <= cc < self.grid_cols: | |
| j = rr * self.grid_cols + cc | |
| if j < self.n_qubits: | |
| out.append(j) | |
| return out | |
| def _build_parity_checks(self) -> Tuple[np.ndarray, np.ndarray]: | |
| x_rows: List[np.ndarray] = [] | |
| z_rows: List[np.ndarray] = [] | |
| for i in range(self.n_qubits - 1): | |
| row_x = np.zeros(self.n_qubits, dtype=np.uint8) | |
| row_z = np.zeros(self.n_qubits, dtype=np.uint8) | |
| for j in self._neighbors(i): | |
| row_x[j] = 1 | |
| for j in self._neighbors((i + self.distance) % self.n_qubits): | |
| row_z[j] = 1 | |
| x_rows.append(row_x) | |
| z_rows.append(row_z) | |
| return np.vstack(x_rows), np.vstack(z_rows) | |
| def apply_error(self, qubit_idx: int, error_type: str) -> None: | |
| if qubit_idx < 0 or qubit_idx >= self.n_qubits: | |
| return | |
| if error_type == "X": | |
| self.x_err[qubit_idx] ^= 1 | |
| elif error_type == "Z": | |
| self.z_err[qubit_idx] ^= 1 | |
| elif error_type == "Y": | |
| self.x_err[qubit_idx] ^= 1 | |
| self.z_err[qubit_idx] ^= 1 | |
| def measure_syndromes(self) -> List[int]: | |
| x_syn = (self.hx @ self.z_err) % 2 | |
| z_syn = (self.hz @ self.x_err) % 2 | |
| return np.concatenate([x_syn, z_syn]).astype(int).tolist() | |
| def apply_correction(self, corrections: Dict[int, str]) -> None: | |
| for q, op in corrections.items(): | |
| self.apply_error(int(q), op) | |
| def _spans_vertical(self, active: np.ndarray) -> bool: | |
| top = [i for i in range(min(self.grid_cols, self.n_qubits)) if active[i] == 1] | |
| if not top: | |
| return False | |
| last_row_start = (self.grid_rows - 1) * self.grid_cols | |
| bottom = { | |
| i | |
| for i in range(last_row_start, min(last_row_start + self.grid_cols, self.n_qubits)) | |
| if active[i] == 1 | |
| } | |
| if not bottom: | |
| return False | |
| seen = set(top) | |
| queue = deque(top) | |
| while queue: | |
| cur = queue.popleft() | |
| if cur in bottom: | |
| return True | |
| for nxt in self._neighbors(cur): | |
| if active[nxt] == 1 and nxt not in seen: | |
| seen.add(nxt) | |
| queue.append(nxt) | |
| return False | |
| def _spans_horizontal(self, active: np.ndarray) -> bool: | |
| left = [i for i in range(0, self.n_qubits, self.grid_cols) if active[i] == 1] | |
| if not left: | |
| return False | |
| right = { | |
| i | |
| for i in range(self.grid_cols - 1, self.n_qubits, self.grid_cols) | |
| if active[i] == 1 | |
| } | |
| if not right: | |
| return False | |
| seen = set(left) | |
| queue = deque(left) | |
| while queue: | |
| cur = queue.popleft() | |
| if cur in right: | |
| return True | |
| for nxt in self._neighbors(cur): | |
| if active[nxt] == 1 and nxt not in seen: | |
| seen.add(nxt) | |
| queue.append(nxt) | |
| return False | |
| def check_logical_failure(self) -> bool: | |
| return self._spans_vertical(self.z_err) or self._spans_horizontal(self.x_err) | |
| def get_fidelity_estimate(self) -> float: | |
| weight = int(self.x_err.sum() + self.z_err.sum()) | |
| ratio = weight / max(1, 2 * self.n_qubits) | |
| return max(0.0, 1.0 - ratio) | |
| def error_frame(self) -> Dict[str, List[int]]: | |
| return { | |
| "x": self.x_err.astype(int).tolist(), | |
| "z": self.z_err.astype(int).tolist(), | |
| } | |