superquantx 0.1.0__py3-none-any.whl

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.
Files changed (46) hide show
  1. superquantx/__init__.py +321 -0
  2. superquantx/algorithms/__init__.py +55 -0
  3. superquantx/algorithms/base_algorithm.py +413 -0
  4. superquantx/algorithms/hybrid_classifier.py +628 -0
  5. superquantx/algorithms/qaoa.py +406 -0
  6. superquantx/algorithms/quantum_agents.py +1006 -0
  7. superquantx/algorithms/quantum_kmeans.py +575 -0
  8. superquantx/algorithms/quantum_nn.py +544 -0
  9. superquantx/algorithms/quantum_pca.py +499 -0
  10. superquantx/algorithms/quantum_svm.py +346 -0
  11. superquantx/algorithms/vqe.py +553 -0
  12. superquantx/algorithms.py +863 -0
  13. superquantx/backends/__init__.py +265 -0
  14. superquantx/backends/base_backend.py +321 -0
  15. superquantx/backends/braket_backend.py +420 -0
  16. superquantx/backends/cirq_backend.py +466 -0
  17. superquantx/backends/ocean_backend.py +491 -0
  18. superquantx/backends/pennylane_backend.py +419 -0
  19. superquantx/backends/qiskit_backend.py +451 -0
  20. superquantx/backends/simulator_backend.py +455 -0
  21. superquantx/backends/tket_backend.py +519 -0
  22. superquantx/circuits.py +447 -0
  23. superquantx/cli/__init__.py +28 -0
  24. superquantx/cli/commands.py +528 -0
  25. superquantx/cli/main.py +254 -0
  26. superquantx/client.py +298 -0
  27. superquantx/config.py +326 -0
  28. superquantx/exceptions.py +287 -0
  29. superquantx/gates.py +588 -0
  30. superquantx/logging_config.py +347 -0
  31. superquantx/measurements.py +702 -0
  32. superquantx/ml.py +936 -0
  33. superquantx/noise.py +760 -0
  34. superquantx/utils/__init__.py +83 -0
  35. superquantx/utils/benchmarking.py +523 -0
  36. superquantx/utils/classical_utils.py +575 -0
  37. superquantx/utils/feature_mapping.py +467 -0
  38. superquantx/utils/optimization.py +410 -0
  39. superquantx/utils/quantum_utils.py +456 -0
  40. superquantx/utils/visualization.py +654 -0
  41. superquantx/version.py +33 -0
  42. superquantx-0.1.0.dist-info/METADATA +365 -0
  43. superquantx-0.1.0.dist-info/RECORD +46 -0
  44. superquantx-0.1.0.dist-info/WHEEL +4 -0
  45. superquantx-0.1.0.dist-info/entry_points.txt +2 -0
  46. superquantx-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,456 @@
1
+ """Quantum-specific utility functions.
2
+
3
+ This module provides utility functions for quantum information processing,
4
+ including fidelity calculations, quantum distances, and entanglement measures.
5
+ """
6
+
7
+ import warnings
8
+ from typing import Tuple
9
+
10
+ import numpy as np
11
+ from scipy.linalg import sqrtm
12
+
13
+
14
+ def fidelity(
15
+ state1: np.ndarray,
16
+ state2: np.ndarray,
17
+ validate: bool = True
18
+ ) -> float:
19
+ """Calculate quantum fidelity between two quantum states.
20
+
21
+ For pure states |ψ₁⟩ and |ψ₂⟩:
22
+ F(ψ₁, ψ₂) = |⟨ψ₁|ψ₂⟩|²
23
+
24
+ For mixed states ρ₁ and ρ₂:
25
+ F(ρ₁, ρ₂) = Tr(√(√ρ₁ ρ₂ √ρ₁))²
26
+
27
+ Args:
28
+ state1: First quantum state (vector or density matrix)
29
+ state2: Second quantum state (vector or density matrix)
30
+ validate: Whether to validate inputs
31
+
32
+ Returns:
33
+ Fidelity value between 0 and 1
34
+
35
+ """
36
+ if validate:
37
+ _validate_quantum_state(state1)
38
+ _validate_quantum_state(state2)
39
+
40
+ # Check if states are vectors (pure states) or matrices (mixed states)
41
+ is_pure1 = len(state1.shape) == 1
42
+ is_pure2 = len(state2.shape) == 1
43
+
44
+ if is_pure1 and is_pure2:
45
+ # Both pure states
46
+ overlap = np.vdot(state1, state2)
47
+ return abs(overlap) ** 2
48
+
49
+ elif is_pure1 and not is_pure2:
50
+ # state1 pure, state2 mixed
51
+ rho2 = state2
52
+ psi1 = state1.reshape(-1, 1)
53
+ return np.real(np.conj(psi1).T @ rho2 @ psi1)[0, 0]
54
+
55
+ elif not is_pure1 and is_pure2:
56
+ # state1 mixed, state2 pure
57
+ rho1 = state1
58
+ psi2 = state2.reshape(-1, 1)
59
+ return np.real(np.conj(psi2).T @ rho1 @ psi2)[0, 0]
60
+
61
+ else:
62
+ # Both mixed states
63
+ rho1, rho2 = state1, state2
64
+
65
+ # F = Tr(√(√ρ₁ ρ₂ √ρ₁))²
66
+ sqrt_rho1 = sqrtm(rho1)
67
+ M = sqrt_rho1 @ rho2 @ sqrt_rho1
68
+ sqrt_M = sqrtm(M)
69
+
70
+ fid = np.real(np.trace(sqrt_M)) ** 2
71
+
72
+ # Ensure fidelity is in [0, 1] (numerical errors can cause small violations)
73
+ return np.clip(fid, 0, 1)
74
+
75
+
76
+ def trace_distance(
77
+ state1: np.ndarray,
78
+ state2: np.ndarray,
79
+ validate: bool = True
80
+ ) -> float:
81
+ """Calculate trace distance between two quantum states.
82
+
83
+ For quantum states ρ₁ and ρ₂:
84
+ D(ρ₁, ρ₂) = (1/2) * Tr(|ρ₁ - ρ₂|)
85
+
86
+ Args:
87
+ state1: First quantum state
88
+ state2: Second quantum state
89
+ validate: Whether to validate inputs
90
+
91
+ Returns:
92
+ Trace distance between 0 and 1
93
+
94
+ """
95
+ if validate:
96
+ _validate_quantum_state(state1)
97
+ _validate_quantum_state(state2)
98
+
99
+ # Convert to density matrices if needed
100
+ rho1 = _to_density_matrix(state1)
101
+ rho2 = _to_density_matrix(state2)
102
+
103
+ # Compute difference
104
+ diff = rho1 - rho2
105
+
106
+ # Compute eigenvalues and take absolute values
107
+ eigenvals = np.linalg.eigvals(diff)
108
+ abs_eigenvals = np.abs(eigenvals)
109
+
110
+ # Trace distance is half the sum of absolute eigenvalues
111
+ return 0.5 * np.sum(abs_eigenvals)
112
+
113
+
114
+ def quantum_mutual_information(
115
+ joint_state: np.ndarray,
116
+ subsystem_dims: Tuple[int, int],
117
+ validate: bool = True
118
+ ) -> float:
119
+ """Calculate quantum mutual information between two subsystems.
120
+
121
+ I(A:B) = S(ρₐ) + S(ρᵦ) - S(ρₐᵦ)
122
+
123
+ where S(ρ) is the von Neumann entropy.
124
+
125
+ Args:
126
+ joint_state: Joint quantum state of both subsystems
127
+ subsystem_dims: Dimensions of subsystems (dim_A, dim_B)
128
+ validate: Whether to validate inputs
129
+
130
+ Returns:
131
+ Quantum mutual information
132
+
133
+ """
134
+ if validate:
135
+ _validate_quantum_state(joint_state)
136
+
137
+ rho_AB = _to_density_matrix(joint_state)
138
+ dim_A, dim_B = subsystem_dims
139
+
140
+ if rho_AB.shape[0] != dim_A * dim_B:
141
+ raise ValueError(f"State dimension {rho_AB.shape[0]} doesn't match subsystem dims {dim_A * dim_B}")
142
+
143
+ # Partial traces
144
+ rho_A = partial_trace(rho_AB, (dim_A, dim_B), trace_out=1)
145
+ rho_B = partial_trace(rho_AB, (dim_A, dim_B), trace_out=0)
146
+
147
+ # Von Neumann entropies
148
+ S_A = von_neumann_entropy(rho_A)
149
+ S_B = von_neumann_entropy(rho_B)
150
+ S_AB = von_neumann_entropy(rho_AB)
151
+
152
+ return S_A + S_B - S_AB
153
+
154
+
155
+ def entanglement_measure(
156
+ state: np.ndarray,
157
+ subsystem_dims: Tuple[int, int],
158
+ measure: str = 'negativity',
159
+ validate: bool = True
160
+ ) -> float:
161
+ """Calculate entanglement measure for a bipartite quantum state.
162
+
163
+ Args:
164
+ state: Quantum state (pure or mixed)
165
+ subsystem_dims: Dimensions of subsystems (dim_A, dim_B)
166
+ measure: Type of measure ('negativity', 'concurrence', 'entropy')
167
+ validate: Whether to validate inputs
168
+
169
+ Returns:
170
+ Entanglement measure value
171
+
172
+ """
173
+ if validate:
174
+ _validate_quantum_state(state)
175
+
176
+ if measure == 'negativity':
177
+ return negativity(state, subsystem_dims)
178
+ elif measure == 'concurrence':
179
+ return concurrence(state, subsystem_dims)
180
+ elif measure == 'entropy':
181
+ return entanglement_entropy(state, subsystem_dims)
182
+ else:
183
+ raise ValueError(f"Unknown entanglement measure: {measure}")
184
+
185
+
186
+ def negativity(
187
+ state: np.ndarray,
188
+ subsystem_dims: Tuple[int, int]
189
+ ) -> float:
190
+ """Calculate negativity entanglement measure.
191
+
192
+ Negativity is defined as:
193
+ N(ρ) = (||ρᵀᴬ||₁ - 1) / 2
194
+
195
+ where ρᵀᴬ is the partial transpose with respect to subsystem A.
196
+
197
+ Args:
198
+ state: Quantum state
199
+ subsystem_dims: Dimensions of subsystems
200
+
201
+ Returns:
202
+ Negativity value
203
+
204
+ """
205
+ rho = _to_density_matrix(state)
206
+
207
+ # Partial transpose
208
+ rho_TA = partial_transpose(rho, subsystem_dims, transpose_subsystem=0)
209
+
210
+ # Calculate trace norm (sum of absolute eigenvalues)
211
+ eigenvals = np.linalg.eigvals(rho_TA)
212
+ trace_norm = np.sum(np.abs(eigenvals))
213
+
214
+ return (trace_norm - 1) / 2
215
+
216
+
217
+ def concurrence(
218
+ state: np.ndarray,
219
+ subsystem_dims: Tuple[int, int]
220
+ ) -> float:
221
+ """Calculate concurrence for two-qubit systems.
222
+
223
+ Note: This implementation is only valid for 2×2 systems.
224
+
225
+ Args:
226
+ state: Two-qubit quantum state
227
+ subsystem_dims: Should be (2, 2) for two qubits
228
+
229
+ Returns:
230
+ Concurrence value
231
+
232
+ """
233
+ if subsystem_dims != (2, 2):
234
+ raise ValueError("Concurrence is only implemented for two-qubit systems")
235
+
236
+ rho = _to_density_matrix(state)
237
+
238
+ # Pauli Y matrix
239
+ sigma_y = np.array([[0, -1j], [1j, 0]])
240
+
241
+ # Two-qubit Y tensor product
242
+ Y_tensor = np.kron(sigma_y, sigma_y)
243
+
244
+ # Spin-flipped state
245
+ rho_tilde = Y_tensor @ np.conj(rho) @ Y_tensor
246
+
247
+ # R matrix
248
+ R = rho @ rho_tilde
249
+
250
+ # Eigenvalues in descending order
251
+ eigenvals = np.sqrt(np.real(np.linalg.eigvals(R)))
252
+ eigenvals = np.sort(eigenvals)[::-1]
253
+
254
+ # Concurrence
255
+ C = max(0, eigenvals[0] - eigenvals[1] - eigenvals[2] - eigenvals[3])
256
+
257
+ return C
258
+
259
+
260
+ def entanglement_entropy(
261
+ state: np.ndarray,
262
+ subsystem_dims: Tuple[int, int]
263
+ ) -> float:
264
+ """Calculate entanglement entropy (von Neumann entropy of reduced state).
265
+
266
+ Args:
267
+ state: Quantum state
268
+ subsystem_dims: Dimensions of subsystems
269
+
270
+ Returns:
271
+ Entanglement entropy
272
+
273
+ """
274
+ rho = _to_density_matrix(state)
275
+
276
+ # Reduced state of first subsystem
277
+ rho_A = partial_trace(rho, subsystem_dims, trace_out=1)
278
+
279
+ return von_neumann_entropy(rho_A)
280
+
281
+
282
+ def von_neumann_entropy(rho: np.ndarray) -> float:
283
+ """Calculate von Neumann entropy of a quantum state.
284
+
285
+ S(ρ) = -Tr(ρ log ρ)
286
+
287
+ Args:
288
+ rho: Density matrix
289
+
290
+ Returns:
291
+ von Neumann entropy
292
+
293
+ """
294
+ eigenvals = np.linalg.eigvals(rho)
295
+
296
+ # Remove zero eigenvalues to avoid log(0)
297
+ eigenvals = eigenvals[eigenvals > 1e-12]
298
+
299
+ if len(eigenvals) == 0:
300
+ return 0.0
301
+
302
+ return -np.sum(eigenvals * np.log2(eigenvals))
303
+
304
+
305
+ def partial_trace(
306
+ rho: np.ndarray,
307
+ subsystem_dims: Tuple[int, int],
308
+ trace_out: int
309
+ ) -> np.ndarray:
310
+ """Compute partial trace of a density matrix.
311
+
312
+ Args:
313
+ rho: Density matrix
314
+ subsystem_dims: Dimensions of subsystems (dim_A, dim_B)
315
+ trace_out: Which subsystem to trace out (0 for A, 1 for B)
316
+
317
+ Returns:
318
+ Reduced density matrix
319
+
320
+ """
321
+ dim_A, dim_B = subsystem_dims
322
+
323
+ if rho.shape != (dim_A * dim_B, dim_A * dim_B):
324
+ raise ValueError("Density matrix dimensions don't match subsystem dimensions")
325
+
326
+ if trace_out == 0:
327
+ # Trace out subsystem A, keep B
328
+ rho_B = np.zeros((dim_B, dim_B), dtype=complex)
329
+ for i in range(dim_A):
330
+ rho_B += rho[i*dim_B:(i+1)*dim_B, i*dim_B:(i+1)*dim_B]
331
+ return rho_B
332
+
333
+ elif trace_out == 1:
334
+ # Trace out subsystem B, keep A
335
+ rho_A = np.zeros((dim_A, dim_A), dtype=complex)
336
+ for i in range(dim_A):
337
+ for j in range(dim_A):
338
+ for k in range(dim_B):
339
+ rho_A[i, j] += rho[i*dim_B + k, j*dim_B + k]
340
+ return rho_A
341
+
342
+ else:
343
+ raise ValueError("trace_out must be 0 or 1")
344
+
345
+
346
+ def partial_transpose(
347
+ rho: np.ndarray,
348
+ subsystem_dims: Tuple[int, int],
349
+ transpose_subsystem: int
350
+ ) -> np.ndarray:
351
+ """Compute partial transpose of a density matrix.
352
+
353
+ Args:
354
+ rho: Density matrix
355
+ subsystem_dims: Dimensions of subsystems
356
+ transpose_subsystem: Which subsystem to transpose (0 for A, 1 for B)
357
+
358
+ Returns:
359
+ Partially transposed density matrix
360
+
361
+ """
362
+ dim_A, dim_B = subsystem_dims
363
+
364
+ if transpose_subsystem == 0:
365
+ # Transpose subsystem A
366
+ rho_TA = np.zeros_like(rho)
367
+ for i in range(dim_A):
368
+ for j in range(dim_A):
369
+ for k in range(dim_B):
370
+ for l in range(dim_B):
371
+ # Transpose indices for subsystem A
372
+ rho_TA[i*dim_B + k, j*dim_B + l] = rho[j*dim_B + k, i*dim_B + l]
373
+ return rho_TA
374
+
375
+ elif transpose_subsystem == 1:
376
+ # Transpose subsystem B
377
+ rho_TB = np.zeros_like(rho)
378
+ for i in range(dim_A):
379
+ for j in range(dim_A):
380
+ for k in range(dim_B):
381
+ for l in range(dim_B):
382
+ # Transpose indices for subsystem B
383
+ rho_TB[i*dim_B + k, j*dim_B + l] = rho[i*dim_B + l, j*dim_B + k]
384
+ return rho_TB
385
+
386
+ else:
387
+ raise ValueError("transpose_subsystem must be 0 or 1")
388
+
389
+
390
+ def _validate_quantum_state(state: np.ndarray) -> None:
391
+ """Validate that input represents a valid quantum state."""
392
+ if len(state.shape) == 1:
393
+ # Pure state vector
394
+ if not np.isclose(np.linalg.norm(state), 1.0, atol=1e-10):
395
+ warnings.warn("State vector is not normalized")
396
+
397
+ elif len(state.shape) == 2:
398
+ # Density matrix
399
+ if state.shape[0] != state.shape[1]:
400
+ raise ValueError("Density matrix must be square")
401
+
402
+ # Check if Hermitian
403
+ if not np.allclose(state, np.conj(state.T), atol=1e-10):
404
+ warnings.warn("Density matrix is not Hermitian")
405
+
406
+ # Check if positive semidefinite
407
+ eigenvals = np.linalg.eigvals(state)
408
+ if np.any(eigenvals < -1e-10):
409
+ warnings.warn("Density matrix is not positive semidefinite")
410
+
411
+ # Check trace
412
+ if not np.isclose(np.trace(state), 1.0, atol=1e-10):
413
+ warnings.warn("Density matrix trace is not 1")
414
+
415
+ else:
416
+ raise ValueError("Invalid quantum state format")
417
+
418
+
419
+ def _to_density_matrix(state: np.ndarray) -> np.ndarray:
420
+ """Convert state vector to density matrix if needed."""
421
+ if len(state.shape) == 1:
422
+ # Pure state vector -> density matrix
423
+ psi = state.reshape(-1, 1)
424
+ return psi @ np.conj(psi.T)
425
+ else:
426
+ # Already a density matrix
427
+ return state
428
+
429
+
430
+ def quantum_state_distance(
431
+ state1: np.ndarray,
432
+ state2: np.ndarray,
433
+ metric: str = 'fidelity'
434
+ ) -> float:
435
+ """Calculate distance between quantum states using various metrics.
436
+
437
+ Args:
438
+ state1: First quantum state
439
+ state2: Second quantum state
440
+ metric: Distance metric ('fidelity', 'trace_distance', 'hilbert_schmidt')
441
+
442
+ Returns:
443
+ Distance value
444
+
445
+ """
446
+ if metric == 'fidelity':
447
+ return 1 - fidelity(state1, state2)
448
+ elif metric == 'trace_distance':
449
+ return trace_distance(state1, state2)
450
+ elif metric == 'hilbert_schmidt':
451
+ rho1 = _to_density_matrix(state1)
452
+ rho2 = _to_density_matrix(state2)
453
+ diff = rho1 - rho2
454
+ return np.sqrt(np.real(np.trace(np.conj(diff.T) @ diff)))
455
+ else:
456
+ raise ValueError(f"Unknown metric: {metric}")