superquantx 0.1.0__py3-none-any.whl → 0.1.1__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 (51) hide show
  1. superquantx/__init__.py +24 -12
  2. superquantx/algorithms/__init__.py +1 -1
  3. superquantx/algorithms/base_algorithm.py +36 -36
  4. superquantx/algorithms/hybrid_classifier.py +22 -22
  5. superquantx/algorithms/qaoa.py +29 -28
  6. superquantx/algorithms/quantum_agents.py +57 -56
  7. superquantx/algorithms/quantum_kmeans.py +17 -17
  8. superquantx/algorithms/quantum_nn.py +18 -18
  9. superquantx/algorithms/quantum_pca.py +26 -26
  10. superquantx/algorithms/quantum_svm.py +26 -25
  11. superquantx/algorithms/vqe.py +40 -39
  12. superquantx/algorithms.py +56 -55
  13. superquantx/backends/__init__.py +12 -12
  14. superquantx/backends/base_backend.py +25 -24
  15. superquantx/backends/braket_backend.py +21 -21
  16. superquantx/backends/cirq_backend.py +26 -26
  17. superquantx/backends/ocean_backend.py +38 -38
  18. superquantx/backends/pennylane_backend.py +12 -11
  19. superquantx/backends/qiskit_backend.py +12 -12
  20. superquantx/backends/simulator_backend.py +31 -17
  21. superquantx/backends/tket_backend.py +23 -23
  22. superquantx/circuits.py +25 -25
  23. superquantx/cli/commands.py +6 -7
  24. superquantx/cli/main.py +5 -6
  25. superquantx/client.py +42 -42
  26. superquantx/config.py +14 -14
  27. superquantx/datasets/__init__.py +58 -0
  28. superquantx/datasets/molecular.py +307 -0
  29. superquantx/datasets/preprocessing.py +279 -0
  30. superquantx/datasets/quantum_datasets.py +277 -0
  31. superquantx/datasets/synthetic.py +300 -0
  32. superquantx/exceptions.py +29 -29
  33. superquantx/gates.py +26 -26
  34. superquantx/logging_config.py +29 -29
  35. superquantx/measurements.py +53 -54
  36. superquantx/ml.py +51 -52
  37. superquantx/noise.py +49 -49
  38. superquantx/utils/benchmarking.py +41 -36
  39. superquantx/utils/classical_utils.py +32 -32
  40. superquantx/utils/feature_mapping.py +40 -35
  41. superquantx/utils/optimization.py +28 -26
  42. superquantx/utils/quantum_utils.py +47 -48
  43. superquantx/utils/visualization.py +49 -49
  44. superquantx/version.py +3 -3
  45. {superquantx-0.1.0.dist-info → superquantx-0.1.1.dist-info}/METADATA +18 -16
  46. superquantx-0.1.1.dist-info/RECORD +51 -0
  47. superquantx-0.1.1.dist-info/licenses/LICENSE +180 -0
  48. superquantx-0.1.0.dist-info/RECORD +0 -46
  49. superquantx-0.1.0.dist-info/licenses/LICENSE +0 -21
  50. {superquantx-0.1.0.dist-info → superquantx-0.1.1.dist-info}/WHEEL +0 -0
  51. {superquantx-0.1.0.dist-info → superquantx-0.1.1.dist-info}/entry_points.txt +0 -0
@@ -3,7 +3,7 @@
3
3
 
4
4
  import json
5
5
  from collections import Counter, defaultdict
6
- from typing import Any, Dict, List, Optional, Tuple
6
+ from typing import Any
7
7
 
8
8
  import matplotlib.pyplot as plt
9
9
  import numpy as np
@@ -14,10 +14,10 @@ class MeasurementResult(BaseModel):
14
14
  """Represents the result of quantum measurements
15
15
  """
16
16
 
17
- counts: Dict[str, int] = Field(..., description="Measurement outcome counts")
17
+ counts: dict[str, int] = Field(..., description="Measurement outcome counts")
18
18
  shots: int = Field(..., description="Total number of shots")
19
- memory: Optional[List[str]] = Field(default=None, description="Individual shot outcomes")
20
- metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
19
+ memory: list[str] | None = Field(default=None, description="Individual shot outcomes")
20
+ metadata: dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
21
21
 
22
22
  def model_post_init(self, __context):
23
23
  """Validate measurement result"""
@@ -25,21 +25,21 @@ class MeasurementResult(BaseModel):
25
25
  raise ValueError("Sum of counts must equal total shots")
26
26
 
27
27
  @property
28
- def probabilities(self) -> Dict[str, float]:
28
+ def probabilities(self) -> dict[str, float]:
29
29
  """Get measurement probabilities"""
30
30
  return {outcome: count / self.shots for outcome, count in self.counts.items()}
31
31
 
32
32
  @property
33
- def most_frequent(self) -> Tuple[str, int]:
33
+ def most_frequent(self) -> tuple[str, int]:
34
34
  """Get most frequent measurement outcome"""
35
35
  return max(self.counts.items(), key=lambda x: x[1])
36
36
 
37
- def marginal_counts(self, qubits: List[int]) -> Dict[str, int]:
37
+ def marginal_counts(self, qubits: list[int]) -> dict[str, int]:
38
38
  """Get marginal counts for specific qubits
39
-
39
+
40
40
  Args:
41
41
  qubits: List of qubit indices to marginalize over
42
-
42
+
43
43
  Returns:
44
44
  Marginal counts dictionary
45
45
 
@@ -55,10 +55,10 @@ class MeasurementResult(BaseModel):
55
55
 
56
56
  def expectation_value(self, observable: str) -> float:
57
57
  """Calculate expectation value for Pauli observable
58
-
58
+
59
59
  Args:
60
60
  observable: Pauli string (e.g., "ZZI")
61
-
61
+
62
62
  Returns:
63
63
  Expectation value
64
64
 
@@ -94,16 +94,16 @@ class MeasurementResult(BaseModel):
94
94
  def plot_histogram(
95
95
  self,
96
96
  title: str = "Measurement Results",
97
- figsize: Tuple[int, int] = (10, 6),
97
+ figsize: tuple[int, int] = (10, 6),
98
98
  max_outcomes: int = 20
99
99
  ) -> plt.Figure:
100
100
  """Plot measurement histogram
101
-
101
+
102
102
  Args:
103
103
  title: Plot title
104
104
  figsize: Figure size
105
105
  max_outcomes: Maximum number of outcomes to show
106
-
106
+
107
107
  Returns:
108
108
  Matplotlib figure
109
109
 
@@ -117,7 +117,7 @@ class MeasurementResult(BaseModel):
117
117
  if len(sorted_outcomes) > max_outcomes:
118
118
  sorted_outcomes = sorted_outcomes[:max_outcomes]
119
119
 
120
- outcomes, counts = zip(*sorted_outcomes) if sorted_outcomes else ([], [])
120
+ outcomes, counts = zip(*sorted_outcomes, strict=False) if sorted_outcomes else ([], [])
121
121
 
122
122
  ax.bar(range(len(outcomes)), counts)
123
123
  ax.set_xlabel('Measurement Outcome')
@@ -129,7 +129,7 @@ class MeasurementResult(BaseModel):
129
129
  plt.tight_layout()
130
130
  return fig
131
131
 
132
- def to_dict(self) -> Dict[str, Any]:
132
+ def to_dict(self) -> dict[str, Any]:
133
133
  """Convert to dictionary"""
134
134
  return {
135
135
  "counts": self.counts,
@@ -143,7 +143,7 @@ class MeasurementResult(BaseModel):
143
143
  return json.dumps(self.to_dict(), indent=indent)
144
144
 
145
145
  @classmethod
146
- def from_dict(cls, data: Dict[str, Any]) -> "MeasurementResult":
146
+ def from_dict(cls, data: dict[str, Any]) -> "MeasurementResult":
147
147
  """Create from dictionary"""
148
148
  return cls(**data)
149
149
 
@@ -176,15 +176,15 @@ class QuantumMeasurement:
176
176
  """Quantum measurement operations and analysis
177
177
  """
178
178
 
179
- def __init__(self, backend: Optional[str] = "simulator"):
179
+ def __init__(self, backend: str | None = "simulator"):
180
180
  """Initialize measurement system
181
-
181
+
182
182
  Args:
183
183
  backend: Quantum backend for measurements
184
184
 
185
185
  """
186
186
  self.backend = backend
187
- self.measurement_history: List[MeasurementResult] = []
187
+ self.measurement_history: list[MeasurementResult] = []
188
188
 
189
189
  def measure_circuit(
190
190
  self,
@@ -193,12 +193,12 @@ class QuantumMeasurement:
193
193
  memory: bool = False
194
194
  ) -> MeasurementResult:
195
195
  """Measure quantum circuit
196
-
196
+
197
197
  Args:
198
198
  circuit: Quantum circuit to measure
199
199
  shots: Number of measurement shots
200
200
  memory: Whether to store individual shot outcomes
201
-
201
+
202
202
  Returns:
203
203
  Measurement result
204
204
 
@@ -206,7 +206,6 @@ class QuantumMeasurement:
206
206
  # This would interface with actual quantum hardware/simulator
207
207
  # For now, create simulated results
208
208
 
209
- num_classical_bits = circuit.num_classical_bits
210
209
 
211
210
  # Simulate measurement outcomes
212
211
  if self.backend == "simulator":
@@ -232,7 +231,7 @@ class QuantumMeasurement:
232
231
  self.measurement_history.append(result)
233
232
  return result
234
233
 
235
- def _simulate_measurements(self, circuit: "QuantumCircuit", shots: int) -> Dict[str, int]:
234
+ def _simulate_measurements(self, circuit: "QuantumCircuit", shots: int) -> dict[str, int]:
236
235
  """Simulate measurement outcomes"""
237
236
  num_bits = circuit.num_classical_bits
238
237
 
@@ -245,7 +244,7 @@ class QuantumMeasurement:
245
244
 
246
245
  return dict(Counter(outcomes))
247
246
 
248
- def _execute_measurements(self, circuit: "QuantumCircuit", shots: int) -> Dict[str, int]:
247
+ def _execute_measurements(self, circuit: "QuantumCircuit", shots: int) -> dict[str, int]:
249
248
  """Execute measurements on quantum hardware"""
250
249
  # This would interface with quantum hardware via client
251
250
  # Placeholder for now
@@ -258,12 +257,12 @@ class QuantumMeasurement:
258
257
  shots: int = 1024
259
258
  ) -> float:
260
259
  """Measure expectation value of Pauli observable
261
-
260
+
262
261
  Args:
263
262
  circuit: Quantum circuit (without measurements)
264
263
  observable: Pauli string observable
265
264
  shots: Number of shots
266
-
265
+
267
266
  Returns:
268
267
  Expectation value
269
268
 
@@ -306,16 +305,16 @@ class QuantumMeasurement:
306
305
  def tomography_measurements(
307
306
  self,
308
307
  circuit: "QuantumCircuit",
309
- qubits: Optional[List[int]] = None,
308
+ qubits: list[int] | None = None,
310
309
  shots_per_measurement: int = 1024
311
- ) -> Dict[str, MeasurementResult]:
310
+ ) -> dict[str, MeasurementResult]:
312
311
  """Perform quantum state tomography measurements
313
-
312
+
314
313
  Args:
315
314
  circuit: Quantum circuit to tomographically reconstruct
316
315
  qubits: Qubits to perform tomography on (default: all)
317
316
  shots_per_measurement: Shots per Pauli measurement
318
-
317
+
319
318
  Returns:
320
319
  Dictionary of measurement results for each Pauli basis
321
320
 
@@ -354,7 +353,7 @@ class QuantumMeasurement:
354
353
  self,
355
354
  circuit: "QuantumCircuit",
356
355
  pauli_string: str,
357
- qubits: List[int]
356
+ qubits: list[int]
358
357
  ) -> "QuantumCircuit":
359
358
  """Prepare circuit for tomography measurement"""
360
359
  measurement_circuit = circuit.copy()
@@ -379,13 +378,13 @@ class QuantumMeasurement:
379
378
 
380
379
  def reconstruct_state(
381
380
  self,
382
- tomography_results: Dict[str, MeasurementResult]
381
+ tomography_results: dict[str, MeasurementResult]
383
382
  ) -> np.ndarray:
384
383
  """Reconstruct quantum state from tomography measurements
385
-
384
+
386
385
  Args:
387
386
  tomography_results: Results from tomography_measurements
388
-
387
+
389
388
  Returns:
390
389
  Reconstructed density matrix
391
390
 
@@ -410,11 +409,11 @@ class QuantumMeasurement:
410
409
  state2: np.ndarray
411
410
  ) -> float:
412
411
  """Calculate quantum state fidelity
413
-
412
+
414
413
  Args:
415
414
  state1: First quantum state (vector or density matrix)
416
415
  state2: Second quantum state (vector or density matrix)
417
-
416
+
418
417
  Returns:
419
418
  Fidelity between states
420
419
 
@@ -447,11 +446,11 @@ class QuantumMeasurement:
447
446
  state2: np.ndarray
448
447
  ) -> float:
449
448
  """Calculate trace distance between quantum states
450
-
449
+
451
450
  Args:
452
451
  state1: First quantum state
453
452
  state2: Second quantum state
454
-
453
+
455
454
  Returns:
456
455
  Trace distance
457
456
 
@@ -478,15 +477,15 @@ class QuantumMeasurement:
478
477
  depth: int,
479
478
  trials: int = 100,
480
479
  shots_per_trial: int = 1024
481
- ) -> Dict[str, Any]:
480
+ ) -> dict[str, Any]:
482
481
  """Perform quantum volume benchmark
483
-
482
+
484
483
  Args:
485
484
  num_qubits: Number of qubits
486
485
  depth: Circuit depth
487
486
  trials: Number of random circuits to test
488
487
  shots_per_trial: Shots per circuit
489
-
488
+
490
489
  Returns:
491
490
  Quantum volume benchmark results
492
491
 
@@ -557,13 +556,13 @@ class ResultAnalyzer:
557
556
  def compare_results(
558
557
  results1: MeasurementResult,
559
558
  results2: MeasurementResult
560
- ) -> Dict[str, float]:
559
+ ) -> dict[str, float]:
561
560
  """Compare two measurement results
562
-
561
+
563
562
  Args:
564
563
  results1: First measurement result
565
564
  results2: Second measurement result
566
-
565
+
567
566
  Returns:
568
567
  Comparison metrics
569
568
 
@@ -603,17 +602,17 @@ class ResultAnalyzer:
603
602
 
604
603
  @staticmethod
605
604
  def error_mitigation_zero_noise_extrapolation(
606
- noise_levels: List[float],
607
- measurement_results: List[MeasurementResult],
605
+ noise_levels: list[float],
606
+ measurement_results: list[MeasurementResult],
608
607
  observable: str = "Z"
609
- ) -> Tuple[float, Dict[str, Any]]:
608
+ ) -> tuple[float, dict[str, Any]]:
610
609
  """Perform zero-noise extrapolation error mitigation
611
-
610
+
612
611
  Args:
613
612
  noise_levels: List of noise levels (e.g., [1, 2, 3])
614
613
  measurement_results: Results for each noise level
615
614
  observable: Observable to extrapolate
616
-
615
+
617
616
  Returns:
618
617
  Zero-noise extrapolated value and fitting info
619
618
 
@@ -670,21 +669,21 @@ class ResultAnalyzer:
670
669
 
671
670
  @staticmethod
672
671
  def readout_error_mitigation(
673
- calibration_results: Dict[str, MeasurementResult],
672
+ calibration_results: dict[str, MeasurementResult],
674
673
  measurement_result: MeasurementResult
675
674
  ) -> MeasurementResult:
676
675
  """Apply readout error mitigation
677
-
676
+
678
677
  Args:
679
678
  calibration_results: Results from measuring |0⟩ and |1⟩ states
680
679
  measurement_result: Result to correct
681
-
680
+
682
681
  Returns:
683
682
  Error-mitigated result
684
683
 
685
684
  """
686
685
  # Build calibration matrix
687
- num_qubits = len(next(iter(calibration_results.keys())))
686
+ len(next(iter(calibration_results.keys())))
688
687
 
689
688
  # This is a simplified implementation
690
689
  # Full readout error mitigation would build complete confusion matrix
superquantx/ml.py CHANGED
@@ -2,7 +2,6 @@
2
2
  """
3
3
 
4
4
  from abc import ABC, abstractmethod
5
- from typing import Dict, List, Optional
6
5
 
7
6
  import numpy as np
8
7
  from scipy.optimize import minimize
@@ -20,7 +19,7 @@ class QuantumFeatureMap(ABC):
20
19
 
21
20
  def __init__(self, num_qubits: int, num_features: int):
22
21
  """Initialize feature map
23
-
22
+
24
23
  Args:
25
24
  num_qubits: Number of qubits
26
25
  num_features: Number of input features
@@ -32,10 +31,10 @@ class QuantumFeatureMap(ABC):
32
31
  @abstractmethod
33
32
  def map_features(self, x: np.ndarray) -> QuantumCircuit:
34
33
  """Map classical features to quantum state
35
-
34
+
36
35
  Args:
37
36
  x: Feature vector
38
-
37
+
39
38
  Returns:
40
39
  Quantum circuit encoding the features
41
40
 
@@ -51,10 +50,10 @@ class AngleEmbeddingFeatureMap(QuantumFeatureMap):
51
50
  self,
52
51
  num_qubits: int,
53
52
  num_features: int,
54
- rotation_gates: List[str] = None
53
+ rotation_gates: list[str] = None
55
54
  ):
56
55
  """Initialize angle embedding
57
-
56
+
58
57
  Args:
59
58
  num_qubits: Number of qubits
60
59
  num_features: Number of features
@@ -117,7 +116,7 @@ class IQPFeatureMap(QuantumFeatureMap):
117
116
 
118
117
  def __init__(self, num_qubits: int, num_features: int, degree: int = 2):
119
118
  """Initialize IQP feature map
120
-
119
+
121
120
  Args:
122
121
  num_qubits: Number of qubits
123
122
  num_features: Number of features
@@ -158,10 +157,10 @@ class QuantumKernel:
158
157
  def __init__(
159
158
  self,
160
159
  feature_map: QuantumFeatureMap,
161
- client: Optional[SuperQuantXClient] = None
160
+ client: SuperQuantXClient | None = None
162
161
  ):
163
162
  """Initialize quantum kernel
164
-
163
+
165
164
  Args:
166
165
  feature_map: Quantum feature map
167
166
  client: SuperQuantX client for execution
@@ -172,11 +171,11 @@ class QuantumKernel:
172
171
 
173
172
  def kernel_matrix(self, X1: np.ndarray, X2: np.ndarray = None) -> np.ndarray:
174
173
  """Compute quantum kernel matrix
175
-
174
+
176
175
  Args:
177
176
  X1: First set of data points
178
177
  X2: Second set of data points (default: same as X1)
179
-
178
+
180
179
  Returns:
181
180
  Kernel matrix K[i,j] = ⟨φ(x_i)|φ(x_j)⟩
182
181
 
@@ -194,11 +193,11 @@ class QuantumKernel:
194
193
 
195
194
  def _kernel_value(self, x1: np.ndarray, x2: np.ndarray) -> float:
196
195
  """Compute kernel value between two data points
197
-
196
+
198
197
  Args:
199
198
  x1: First data point
200
199
  x2: Second data point
201
-
200
+
202
201
  Returns:
203
202
  Kernel value ⟨φ(x1)|φ(x2)⟩
204
203
 
@@ -260,7 +259,7 @@ class QuantumKernel:
260
259
 
261
260
  return kernel_circuit
262
261
 
263
- def _inverse_gate(self, gate: QuantumGate, mapped_qubits: List[int]) -> QuantumGate:
262
+ def _inverse_gate(self, gate: QuantumGate, mapped_qubits: list[int]) -> QuantumGate:
264
263
  """Create inverse gate with mapped qubits"""
265
264
  # Simplified inverse gate creation
266
265
  inverse_params = [-p for p in gate.parameters] if gate.parameters else []
@@ -305,7 +304,7 @@ class QuantumSVM(BaseEstimator, ClassifierMixin):
305
304
  C: float = 1.0
306
305
  ):
307
306
  """Initialize Quantum SVM
308
-
307
+
309
308
  Args:
310
309
  quantum_kernel: Quantum kernel for classification
311
310
  C: Regularization parameter
@@ -316,19 +315,19 @@ class QuantumSVM(BaseEstimator, ClassifierMixin):
316
315
  self.is_fitted_ = False
317
316
 
318
317
  # Will be set during training
319
- self.support_vectors_: Optional[np.ndarray] = None
320
- self.support_: Optional[np.ndarray] = None
321
- self.alpha_: Optional[np.ndarray] = None
322
- self.intercept_: Optional[float] = None
323
- self.classes_: Optional[np.ndarray] = None
318
+ self.support_vectors_: np.ndarray | None = None
319
+ self.support_: np.ndarray | None = None
320
+ self.alpha_: np.ndarray | None = None
321
+ self.intercept_: float | None = None
322
+ self.classes_: np.ndarray | None = None
324
323
 
325
324
  def fit(self, X: np.ndarray, y: np.ndarray) -> "QuantumSVM":
326
325
  """Fit Quantum SVM
327
-
326
+
328
327
  Args:
329
328
  X: Training data
330
329
  y: Training labels
331
-
330
+
332
331
  Returns:
333
332
  Fitted model
334
333
 
@@ -411,10 +410,10 @@ class QuantumSVM(BaseEstimator, ClassifierMixin):
411
410
 
412
411
  def decision_function(self, X: np.ndarray) -> np.ndarray:
413
412
  """Compute decision function
414
-
413
+
415
414
  Args:
416
415
  X: Input data
417
-
416
+
418
417
  Returns:
419
418
  Decision function values
420
419
 
@@ -444,10 +443,10 @@ class QuantumSVM(BaseEstimator, ClassifierMixin):
444
443
 
445
444
  def predict(self, X: np.ndarray) -> np.ndarray:
446
445
  """Make predictions
447
-
446
+
448
447
  Args:
449
448
  X: Input data
450
-
449
+
451
450
  Returns:
452
451
  Predicted labels
453
452
 
@@ -467,12 +466,12 @@ class QuantumClassifier(BaseEstimator, ClassifierMixin):
467
466
  self,
468
467
  feature_map: QuantumFeatureMap,
469
468
  ansatz_layers: int = 2,
470
- client: Optional[SuperQuantXClient] = None,
469
+ client: SuperQuantXClient | None = None,
471
470
  optimizer: str = "SLSQP",
472
471
  max_iter: int = 1000
473
472
  ):
474
473
  """Initialize quantum classifier
475
-
474
+
476
475
  Args:
477
476
  feature_map: Quantum feature map
478
477
  ansatz_layers: Number of variational layers
@@ -488,8 +487,8 @@ class QuantumClassifier(BaseEstimator, ClassifierMixin):
488
487
  self.max_iter = max_iter
489
488
 
490
489
  self.is_fitted_ = False
491
- self.parameters_: Optional[np.ndarray] = None
492
- self.classes_: Optional[np.ndarray] = None
490
+ self.parameters_: np.ndarray | None = None
491
+ self.classes_: np.ndarray | None = None
493
492
  self.label_encoder_ = LabelEncoder()
494
493
 
495
494
  def _create_circuit(self, x: np.ndarray, parameters: np.ndarray) -> QuantumCircuit:
@@ -581,11 +580,11 @@ class QuantumClassifier(BaseEstimator, ClassifierMixin):
581
580
 
582
581
  def fit(self, X: np.ndarray, y: np.ndarray) -> "QuantumClassifier":
583
582
  """Fit quantum classifier
584
-
583
+
585
584
  Args:
586
585
  X: Training data
587
586
  y: Training labels
588
-
587
+
589
588
  Returns:
590
589
  Fitted model
591
590
 
@@ -613,10 +612,10 @@ class QuantumClassifier(BaseEstimator, ClassifierMixin):
613
612
 
614
613
  def predict_proba(self, X: np.ndarray) -> np.ndarray:
615
614
  """Predict class probabilities
616
-
615
+
617
616
  Args:
618
617
  X: Input data
619
-
618
+
620
619
  Returns:
621
620
  Class probabilities
622
621
 
@@ -628,10 +627,10 @@ class QuantumClassifier(BaseEstimator, ClassifierMixin):
628
627
 
629
628
  def predict(self, X: np.ndarray) -> np.ndarray:
630
629
  """Make predictions
631
-
630
+
632
631
  Args:
633
632
  X: Input data
634
-
633
+
635
634
  Returns:
636
635
  Predicted labels
637
636
 
@@ -649,11 +648,11 @@ class QuantumRegressor(BaseEstimator, RegressorMixin):
649
648
  self,
650
649
  feature_map: QuantumFeatureMap,
651
650
  ansatz_layers: int = 2,
652
- client: Optional[SuperQuantXClient] = None,
651
+ client: SuperQuantXClient | None = None,
653
652
  optimizer: str = "SLSQP"
654
653
  ):
655
654
  """Initialize quantum regressor
656
-
655
+
657
656
  Args:
658
657
  feature_map: Quantum feature map
659
658
  ansatz_layers: Number of variational layers
@@ -667,7 +666,7 @@ class QuantumRegressor(BaseEstimator, RegressorMixin):
667
666
  self.optimizer = optimizer
668
667
 
669
668
  self.is_fitted_ = False
670
- self.parameters_: Optional[np.ndarray] = None
669
+ self.parameters_: np.ndarray | None = None
671
670
  self.scaler_ = StandardScaler()
672
671
 
673
672
  def _create_circuit(self, x: np.ndarray, parameters: np.ndarray) -> QuantumCircuit:
@@ -720,11 +719,11 @@ class QuantumRegressor(BaseEstimator, RegressorMixin):
720
719
 
721
720
  def fit(self, X: np.ndarray, y: np.ndarray) -> "QuantumRegressor":
722
721
  """Fit quantum regressor
723
-
722
+
724
723
  Args:
725
724
  X: Training data
726
725
  y: Training targets
727
-
726
+
728
727
  Returns:
729
728
  Fitted model
730
729
 
@@ -755,10 +754,10 @@ class QuantumRegressor(BaseEstimator, RegressorMixin):
755
754
 
756
755
  def predict(self, X: np.ndarray) -> np.ndarray:
757
756
  """Make predictions
758
-
757
+
759
758
  Args:
760
759
  X: Input data
761
-
760
+
762
761
  Returns:
763
762
  Predicted values
764
763
 
@@ -783,10 +782,10 @@ class QuantumGAN:
783
782
  num_qubits: int,
784
783
  generator_layers: int = 3,
785
784
  discriminator_layers: int = 2,
786
- client: Optional[SuperQuantXClient] = None
785
+ client: SuperQuantXClient | None = None
787
786
  ):
788
787
  """Initialize Quantum GAN
789
-
788
+
790
789
  Args:
791
790
  num_qubits: Number of qubits
792
791
  generator_layers: Generator circuit depth
@@ -800,8 +799,8 @@ class QuantumGAN:
800
799
  self.client = client
801
800
 
802
801
  # Parameters will be set during training
803
- self.generator_params: Optional[np.ndarray] = None
804
- self.discriminator_params: Optional[np.ndarray] = None
802
+ self.generator_params: np.ndarray | None = None
803
+ self.discriminator_params: np.ndarray | None = None
805
804
 
806
805
  def create_generator(self, noise: np.ndarray, params: np.ndarray) -> QuantumCircuit:
807
806
  """Create generator circuit"""
@@ -858,14 +857,14 @@ class QuantumGAN:
858
857
  training_data: np.ndarray,
859
858
  num_epochs: int = 100,
860
859
  learning_rate: float = 0.01
861
- ) -> Dict[str, List[float]]:
860
+ ) -> dict[str, list[float]]:
862
861
  """Train Quantum GAN
863
-
862
+
864
863
  Args:
865
864
  training_data: Real training data
866
865
  num_epochs: Number of training epochs
867
866
  learning_rate: Learning rate
868
-
867
+
869
868
  Returns:
870
869
  Training history
871
870
 
@@ -918,7 +917,7 @@ class QuantumGAN:
918
917
 
919
918
  return circuit
920
919
 
921
- def generate_samples(self, num_samples: int) -> List[np.ndarray]:
920
+ def generate_samples(self, num_samples: int) -> list[np.ndarray]:
922
921
  """Generate samples using trained generator"""
923
922
  if self.generator_params is None:
924
923
  raise ValueError("GAN must be trained before generating samples")
@@ -926,7 +925,7 @@ class QuantumGAN:
926
925
  samples = []
927
926
  for _ in range(num_samples):
928
927
  noise = np.random.uniform(0, 2*np.pi, self.num_qubits)
929
- generator_circuit = self.create_generator(noise, self.generator_params)
928
+ self.create_generator(noise, self.generator_params)
930
929
 
931
930
  # Extract generated sample (simplified)
932
931
  # Would measure and extract amplitudes in practice