stabtab 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stabtab
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.14
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "stabtab"
3
- version = "0.2.0"
3
+ version = "0.3.0"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.14"
@@ -112,6 +112,60 @@ class Tableau:
112
112
  if not 0 <= a < self.n_qubits:
113
113
  raise ValueError(f"Qubit idx {a} out of range [0..{self.n_qubits}]")
114
114
 
115
+ def to_statevector(self) -> np.ndarray:
116
+ n = self.n_qubits
117
+ if n > 16:
118
+ raise ValueError("Statevector display is limited to 16 qubits")
119
+ indices = np.arange(1 << n)
120
+
121
+ def apply_pauli(row, vector):
122
+ x, z = row[:n], row[n : 2 * n]
123
+ flips = sum(int(x[q]) << (n - q - 1) for q in range(n))
124
+ phases = np.full(
125
+ indices.size,
126
+ (-1 if row[-1] else 1) * 1j ** int(np.count_nonzero(x & z)),
127
+ dtype=complex,
128
+ )
129
+ for q in np.flatnonzero(z):
130
+ phases *= 1 - 2 * ((indices >> (n - int(q) - 1)) & 1)
131
+ result = np.empty_like(vector)
132
+ result[indices ^ flips] = phases * vector
133
+ return result
134
+
135
+ vector = np.zeros(indices.size, dtype=complex)
136
+ vector[0] = 1
137
+ for i in range(n):
138
+ projected = vector + apply_pauli(self.tableau[n + i], vector)
139
+ norm = np.linalg.norm(projected)
140
+ if norm < 1e-12:
141
+ vector = apply_pauli(self.tableau[i], vector)
142
+ else:
143
+ vector = projected / norm
144
+ first = vector[np.flatnonzero(np.abs(vector) > 1e-12)[0]]
145
+ return vector * (first.conjugate() / abs(first))
146
+
147
+ def print_state(self):
148
+ terms: list[str] = []
149
+ for basis, amplitude in enumerate(self.to_statevector()):
150
+ if abs(amplitude) < 1e-12:
151
+ continue
152
+ imaginary = abs(amplitude.real) < 1e-12
153
+ value = amplitude.imag if imaginary else amplitude.real
154
+ coefficient = "i" if imaginary else ""
155
+ sign = (
156
+ (" - " if value < 0 else " + ") if terms else ("-" if value < 0 else "")
157
+ )
158
+ terms.append(f"{sign}{coefficient}|{basis:0{self.n_qubits}b}⟩")
159
+ ket = "".join(terms)
160
+ exponent = len(terms).bit_length() - 1
161
+ factor = 1 << (exponent // 2)
162
+ if exponent % 2:
163
+ denominator = "√2" if factor == 1 else f"({factor}√2)"
164
+ else:
165
+ denominator = str(factor)
166
+ expression = ket if len(terms) == 1 else f"({ket}) / {denominator}"
167
+ print(f"|ψ⟩ = {expression}")
168
+
115
169
  def __str__(self):
116
170
  n = self.n_qubits
117
171
  index_width = len(str(n - 1))
@@ -119,7 +173,7 @@ class Tableau:
119
173
  header = " │ ".join([" " * (n + index_width + 4), *columns, "r"]) + " │"
120
174
  separator = "".join("┼" if char == "│" else "─" for char in header)
121
175
  lines = [header, separator]
122
- for i, row in enumerate(self.tableau[:2 * n].view(np.uint8)):
176
+ for i, row in enumerate(self.tableau[: 2 * n].view(np.uint8)):
123
177
  if i == n:
124
178
  lines.append(separator)
125
179
  row_type = "D" if i < n else "S"
@@ -135,7 +189,9 @@ class Tableau:
135
189
  sign = "-" if row[-1] else "+"
136
190
  return sign + "".join(
137
191
  "IXZY"[int(x) + 2 * int(z)]
138
- for x, z in zip(row[:self.n_qubits], row[self.n_qubits:2 * self.n_qubits])
192
+ for x, z in zip(
193
+ row[: self.n_qubits], row[self.n_qubits : 2 * self.n_qubits]
194
+ )
139
195
  )
140
196
 
141
197
  def __repr__(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stabtab
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.14
6
6
  Description-Content-Type: text/markdown
File without changes
File without changes
File without changes