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
superquantx/noise.py CHANGED
@@ -2,7 +2,7 @@
2
2
  """
3
3
 
4
4
  from abc import ABC, abstractmethod
5
- from typing import Any, Dict, List, Optional
5
+ from typing import Any
6
6
 
7
7
  import numpy as np
8
8
  from pydantic import BaseModel, Field
@@ -17,7 +17,7 @@ class NoiseChannel(ABC):
17
17
 
18
18
  def __init__(self, probability: float):
19
19
  """Initialize noise channel
20
-
20
+
21
21
  Args:
22
22
  probability: Noise probability (0 <= p <= 1)
23
23
 
@@ -27,7 +27,7 @@ class NoiseChannel(ABC):
27
27
  self.probability = probability
28
28
 
29
29
  @abstractmethod
30
- def kraus_operators(self) -> List[np.ndarray]:
30
+ def kraus_operators(self) -> list[np.ndarray]:
31
31
  """Return Kraus operators for the noise channel"""
32
32
  pass
33
33
 
@@ -47,7 +47,7 @@ class BitFlipChannel(NoiseChannel):
47
47
  """Bit flip (X) noise channel
48
48
  """
49
49
 
50
- def kraus_operators(self) -> List[np.ndarray]:
50
+ def kraus_operators(self) -> list[np.ndarray]:
51
51
  """Kraus operators for bit flip channel"""
52
52
  sqrt_p = np.sqrt(self.probability)
53
53
  sqrt_1_p = np.sqrt(1 - self.probability)
@@ -72,7 +72,7 @@ class PhaseFlipChannel(NoiseChannel):
72
72
  """Phase flip (Z) noise channel
73
73
  """
74
74
 
75
- def kraus_operators(self) -> List[np.ndarray]:
75
+ def kraus_operators(self) -> list[np.ndarray]:
76
76
  """Kraus operators for phase flip channel"""
77
77
  sqrt_p = np.sqrt(self.probability)
78
78
  sqrt_1_p = np.sqrt(1 - self.probability)
@@ -97,7 +97,7 @@ class BitPhaseFlipChannel(NoiseChannel):
97
97
  """Bit-phase flip (Y) noise channel
98
98
  """
99
99
 
100
- def kraus_operators(self) -> List[np.ndarray]:
100
+ def kraus_operators(self) -> list[np.ndarray]:
101
101
  """Kraus operators for bit-phase flip channel"""
102
102
  sqrt_p = np.sqrt(self.probability)
103
103
  sqrt_1_p = np.sqrt(1 - self.probability)
@@ -122,7 +122,7 @@ class DepolarizingChannel(NoiseChannel):
122
122
  """Depolarizing noise channel
123
123
  """
124
124
 
125
- def kraus_operators(self) -> List[np.ndarray]:
125
+ def kraus_operators(self) -> list[np.ndarray]:
126
126
  """Kraus operators for depolarizing channel"""
127
127
  p = self.probability
128
128
 
@@ -146,7 +146,7 @@ class AmplitudeDampingChannel(NoiseChannel):
146
146
  """Amplitude damping noise channel (T1 decay)
147
147
  """
148
148
 
149
- def kraus_operators(self) -> List[np.ndarray]:
149
+ def kraus_operators(self) -> list[np.ndarray]:
150
150
  """Kraus operators for amplitude damping channel"""
151
151
  gamma = self.probability
152
152
 
@@ -177,7 +177,7 @@ class PhaseDampingChannel(NoiseChannel):
177
177
  """Phase damping noise channel (T2 dephasing)
178
178
  """
179
179
 
180
- def kraus_operators(self) -> List[np.ndarray]:
180
+ def kraus_operators(self) -> list[np.ndarray]:
181
181
  """Kraus operators for phase damping channel"""
182
182
  gamma = self.probability
183
183
 
@@ -208,7 +208,7 @@ class TwoQubitDepolarizingChannel(NoiseChannel):
208
208
  """Two-qubit depolarizing noise channel
209
209
  """
210
210
 
211
- def kraus_operators(self) -> List[np.ndarray]:
211
+ def kraus_operators(self) -> list[np.ndarray]:
212
212
  """Kraus operators for two-qubit depolarizing channel"""
213
213
  p = self.probability
214
214
 
@@ -249,27 +249,27 @@ class NoiseModel(BaseModel):
249
249
 
250
250
  model_config = {"arbitrary_types_allowed": True}
251
251
 
252
- single_qubit_error_rates: Dict[str, float] = Field(
252
+ single_qubit_error_rates: dict[str, float] = Field(
253
253
  default_factory=dict,
254
254
  description="Error rates for single-qubit gates"
255
255
  )
256
256
 
257
- two_qubit_error_rates: Dict[str, float] = Field(
257
+ two_qubit_error_rates: dict[str, float] = Field(
258
258
  default_factory=dict,
259
259
  description="Error rates for two-qubit gates"
260
260
  )
261
261
 
262
- readout_error_rates: Dict[int, float] = Field(
262
+ readout_error_rates: dict[int, float] = Field(
263
263
  default_factory=dict,
264
264
  description="Readout error rates per qubit"
265
265
  )
266
266
 
267
- coherence_times: Dict[str, Dict[int, float]] = Field(
267
+ coherence_times: dict[str, dict[int, float]] = Field(
268
268
  default_factory=dict,
269
269
  description="T1 and T2 times per qubit"
270
270
  )
271
271
 
272
- crosstalk_matrix: Optional[np.ndarray] = Field(
272
+ crosstalk_matrix: np.ndarray | None = Field(
273
273
  default=None,
274
274
  description="Crosstalk coupling matrix"
275
275
  )
@@ -298,10 +298,10 @@ class NoiseModel(BaseModel):
298
298
 
299
299
  def apply_to_circuit(self, circuit: QuantumCircuit) -> QuantumCircuit:
300
300
  """Apply noise model to quantum circuit
301
-
301
+
302
302
  Args:
303
303
  circuit: Original circuit
304
-
304
+
305
305
  Returns:
306
306
  Noisy circuit with error channels
307
307
 
@@ -357,13 +357,13 @@ class NoiseModel(BaseModel):
357
357
  @classmethod
358
358
  def from_device_properties(
359
359
  cls,
360
- device_props: Dict[str, Any]
360
+ device_props: dict[str, Any]
361
361
  ) -> "NoiseModel":
362
362
  """Create noise model from device properties
363
-
363
+
364
364
  Args:
365
365
  device_props: Device property dictionary
366
-
366
+
367
367
  Returns:
368
368
  Noise model based on device properties
369
369
 
@@ -392,7 +392,7 @@ class NoiseModel(BaseModel):
392
392
  t1_times = device_props["coherence_times"].get("T1", [])
393
393
  t2_times = device_props["coherence_times"].get("T2", [])
394
394
 
395
- for qubit, (t1, t2) in enumerate(zip(t1_times, t2_times)):
395
+ for qubit, (t1, t2) in enumerate(zip(t1_times, t2_times, strict=False)):
396
396
  noise_model.set_coherence_time(qubit, t1, t2)
397
397
 
398
398
  return noise_model
@@ -410,12 +410,12 @@ class NoiseModel(BaseModel):
410
410
  readout_error: float = 1e-2
411
411
  ) -> "NoiseModel":
412
412
  """Create basic device noise model
413
-
413
+
414
414
  Args:
415
415
  single_qubit_error: Single-qubit gate error rate
416
416
  two_qubit_error: Two-qubit gate error rate
417
417
  readout_error: Readout error rate
418
-
418
+
419
419
  Returns:
420
420
  Basic noise model
421
421
 
@@ -438,9 +438,9 @@ class QuantumErrorCorrection:
438
438
  """
439
439
 
440
440
  @staticmethod
441
- def three_qubit_bit_flip_code() -> Dict[str, Any]:
441
+ def three_qubit_bit_flip_code() -> dict[str, Any]:
442
442
  """Three-qubit repetition code for bit flip errors
443
-
443
+
444
444
  Returns:
445
445
  Code properties and circuits
446
446
 
@@ -477,9 +477,9 @@ class QuantumErrorCorrection:
477
477
  }
478
478
 
479
479
  @staticmethod
480
- def three_qubit_phase_flip_code() -> Dict[str, Any]:
480
+ def three_qubit_phase_flip_code() -> dict[str, Any]:
481
481
  """Three-qubit code for phase flip errors
482
-
482
+
483
483
  Returns:
484
484
  Code properties and circuits
485
485
 
@@ -525,9 +525,9 @@ class QuantumErrorCorrection:
525
525
  }
526
526
 
527
527
  @staticmethod
528
- def nine_qubit_shor_code() -> Dict[str, Any]:
528
+ def nine_qubit_shor_code() -> dict[str, Any]:
529
529
  """Nine-qubit Shor code (corrects arbitrary single-qubit errors)
530
-
530
+
531
531
  Returns:
532
532
  Code properties and circuits
533
533
 
@@ -566,9 +566,9 @@ class QuantumErrorCorrection:
566
566
  }
567
567
 
568
568
  @staticmethod
569
- def steane_code() -> Dict[str, Any]:
569
+ def steane_code() -> dict[str, Any]:
570
570
  """7-qubit Steane code
571
-
571
+
572
572
  Returns:
573
573
  Code properties
574
574
 
@@ -598,13 +598,13 @@ class QuantumErrorCorrection:
598
598
  }
599
599
 
600
600
  @staticmethod
601
- def decode_syndrome(syndrome: str, correction_table: Dict[str, str]) -> Optional[str]:
601
+ def decode_syndrome(syndrome: str, correction_table: dict[str, str]) -> str | None:
602
602
  """Decode error syndrome to determine correction
603
-
603
+
604
604
  Args:
605
605
  syndrome: Measured syndrome bitstring
606
606
  correction_table: Syndrome to correction mapping
607
-
607
+
608
608
  Returns:
609
609
  Correction operation or None if no error
610
610
 
@@ -617,11 +617,11 @@ class QuantumErrorCorrection:
617
617
  correction: str
618
618
  ) -> QuantumCircuit:
619
619
  """Apply error correction to circuit
620
-
620
+
621
621
  Args:
622
622
  circuit: Circuit to correct
623
623
  correction: Correction operation (e.g., "X0", "Z2")
624
-
624
+
625
625
  Returns:
626
626
  Corrected circuit
627
627
 
@@ -653,15 +653,15 @@ class ErrorMitigation:
653
653
  def randomized_compiling(
654
654
  circuit: QuantumCircuit,
655
655
  num_random_circuits: int = 10,
656
- random_seed: Optional[int] = None
657
- ) -> List[QuantumCircuit]:
656
+ random_seed: int | None = None
657
+ ) -> list[QuantumCircuit]:
658
658
  """Generate randomly compiled circuits for error mitigation
659
-
659
+
660
660
  Args:
661
661
  circuit: Original circuit
662
662
  num_random_circuits: Number of random compilations
663
663
  random_seed: Random seed for reproducibility
664
-
664
+
665
665
  Returns:
666
666
  List of randomly compiled circuits
667
667
 
@@ -679,7 +679,7 @@ class ErrorMitigation:
679
679
  for gate in random_circuit.gates:
680
680
  if len(gate.qubits) == 1:
681
681
  # Add random Pauli before and after
682
- qubit = gate.qubits[0]
682
+ gate.qubits[0]
683
683
 
684
684
  # Random Pauli group element
685
685
  pauli_choice = np.random.choice(['I', 'X', 'Y', 'Z'])
@@ -698,15 +698,15 @@ class ErrorMitigation:
698
698
 
699
699
  @staticmethod
700
700
  def clifford_data_regression(
701
- noisy_results: List[float],
702
- clifford_expectation_values: List[float]
701
+ noisy_results: list[float],
702
+ clifford_expectation_values: list[float]
703
703
  ) -> float:
704
704
  """Perform Clifford data regression for error mitigation
705
-
705
+
706
706
  Args:
707
707
  noisy_results: Noisy measurement results
708
708
  clifford_expectation_values: Expected values from Clifford simulation
709
-
709
+
710
710
  Returns:
711
711
  Error-mitigated expectation value
712
712
 
@@ -734,14 +734,14 @@ class ErrorMitigation:
734
734
  @staticmethod
735
735
  def symmetry_verification(
736
736
  circuit: QuantumCircuit,
737
- symmetry_generators: List[PauliString]
738
- ) -> Dict[str, Any]:
737
+ symmetry_generators: list[PauliString]
738
+ ) -> dict[str, Any]:
739
739
  """Verify circuit preserves expected symmetries
740
-
740
+
741
741
  Args:
742
742
  circuit: Quantum circuit
743
743
  symmetry_generators: List of Pauli symmetries to check
744
-
744
+
745
745
  Returns:
746
746
  Symmetry verification results
747
747
 
@@ -6,9 +6,10 @@ compare performance, and generate comprehensive performance reports.
6
6
 
7
7
  import json
8
8
  import time
9
+ from collections.abc import Callable
9
10
  from dataclasses import dataclass
10
11
  from pathlib import Path
11
- from typing import Any, Callable, Dict, List, Optional, Tuple
12
+ from typing import Any
12
13
 
13
14
  import numpy as np
14
15
 
@@ -28,33 +29,33 @@ class BenchmarkResult:
28
29
  backend_name: str
29
30
  dataset_name: str
30
31
  execution_time: float
31
- memory_usage: Optional[float]
32
- accuracy: Optional[float]
33
- loss: Optional[float]
34
- n_parameters: Optional[int]
35
- n_qubits: Optional[int]
36
- n_iterations: Optional[int]
32
+ memory_usage: float | None
33
+ accuracy: float | None
34
+ loss: float | None
35
+ n_parameters: int | None
36
+ n_qubits: int | None
37
+ n_iterations: int | None
37
38
  success: bool
38
- error_message: Optional[str]
39
- metadata: Dict[str, Any]
39
+ error_message: str | None
40
+ metadata: dict[str, Any]
40
41
 
41
42
 
42
43
  def benchmark_algorithm(
43
44
  algorithm: Any,
44
- datasets: List[Tuple[str, Any]],
45
- metrics: Optional[List[str]] = None,
45
+ datasets: list[tuple[str, Any]],
46
+ metrics: list[str] | None = None,
46
47
  n_runs: int = 1,
47
48
  verbose: bool = True
48
- ) -> List[BenchmarkResult]:
49
+ ) -> list[BenchmarkResult]:
49
50
  """Benchmark quantum algorithm performance across multiple datasets.
50
-
51
+
51
52
  Args:
52
53
  algorithm: Quantum algorithm instance
53
54
  datasets: List of (name, dataset) tuples
54
55
  metrics: List of metrics to compute
55
56
  n_runs: Number of runs for averaging
56
57
  verbose: Whether to print progress
57
-
58
+
58
59
  Returns:
59
60
  List of benchmark results
60
61
 
@@ -90,25 +91,27 @@ def benchmark_algorithm(
90
91
 
91
92
 
92
93
  def benchmark_backend(
93
- backends: List[Any],
94
+ backends: list[Any],
94
95
  test_circuit: Callable,
95
- n_qubits_range: List[int] = [2, 4, 6, 8],
96
+ n_qubits_range: list[int] = None,
96
97
  n_shots: int = 1024,
97
98
  verbose: bool = True
98
- ) -> Dict[str, List[BenchmarkResult]]:
99
+ ) -> dict[str, list[BenchmarkResult]]:
99
100
  """Benchmark different quantum backends.
100
-
101
+
101
102
  Args:
102
103
  backends: List of backend instances
103
104
  test_circuit: Function that creates test circuit
104
105
  n_qubits_range: Range of qubit numbers to test
105
106
  n_shots: Number of shots for each measurement
106
107
  verbose: Whether to print progress
107
-
108
+
108
109
  Returns:
109
110
  Dictionary mapping backend names to benchmark results
110
111
 
111
112
  """
113
+ if n_qubits_range is None:
114
+ n_qubits_range = [2, 4, 6, 8]
112
115
  results = {}
113
116
 
114
117
  for backend in backends:
@@ -180,14 +183,14 @@ def performance_metrics(
180
183
  y_true: np.ndarray,
181
184
  y_pred: np.ndarray,
182
185
  task_type: str = 'classification'
183
- ) -> Dict[str, float]:
186
+ ) -> dict[str, float]:
184
187
  """Compute performance metrics for predictions.
185
-
188
+
186
189
  Args:
187
190
  y_true: True labels/values
188
191
  y_pred: Predicted labels/values
189
192
  task_type: Type of task ('classification' or 'regression')
190
-
193
+
191
194
  Returns:
192
195
  Dictionary of computed metrics
193
196
 
@@ -244,25 +247,27 @@ def performance_metrics(
244
247
 
245
248
 
246
249
  def compare_algorithms(
247
- algorithms: List[Any],
250
+ algorithms: list[Any],
248
251
  dataset: Any,
249
- metrics: List[str] = ['accuracy', 'execution_time'],
252
+ metrics: list[str] = None,
250
253
  n_runs: int = 3,
251
254
  verbose: bool = True
252
- ) -> Dict[str, Any]:
255
+ ) -> dict[str, Any]:
253
256
  """Compare multiple algorithms on the same dataset.
254
-
257
+
255
258
  Args:
256
259
  algorithms: List of algorithm instances
257
260
  dataset: Dataset to use for comparison
258
261
  metrics: Metrics to compare
259
262
  n_runs: Number of runs for averaging
260
263
  verbose: Whether to print progress
261
-
264
+
262
265
  Returns:
263
266
  Comparison results dictionary
264
267
 
265
268
  """
269
+ if metrics is None:
270
+ metrics = ['accuracy', 'execution_time']
266
271
  comparison_results = {
267
272
  'algorithms': [],
268
273
  'metrics': metrics,
@@ -322,15 +327,15 @@ def compare_algorithms(
322
327
 
323
328
 
324
329
  def generate_benchmark_report(
325
- results: List[BenchmarkResult],
326
- output_path: Optional[str] = None
327
- ) -> Dict[str, Any]:
330
+ results: list[BenchmarkResult],
331
+ output_path: str | None = None
332
+ ) -> dict[str, Any]:
328
333
  """Generate comprehensive benchmark report.
329
-
334
+
330
335
  Args:
331
336
  results: List of benchmark results
332
337
  output_path: Optional path to save report
333
-
338
+
334
339
  Returns:
335
340
  Report dictionary
336
341
 
@@ -409,7 +414,7 @@ def _run_single_benchmark(
409
414
  algorithm: Any,
410
415
  dataset_name: str,
411
416
  dataset: Any,
412
- metrics: List[str]
417
+ metrics: list[str]
413
418
  ) -> BenchmarkResult:
414
419
  """Run single benchmark iteration."""
415
420
  try:
@@ -483,7 +488,7 @@ def _run_single_benchmark(
483
488
  return result
484
489
 
485
490
 
486
- def _average_benchmark_results(results: List[BenchmarkResult]) -> BenchmarkResult:
491
+ def _average_benchmark_results(results: list[BenchmarkResult]) -> BenchmarkResult:
487
492
  """Average multiple benchmark results."""
488
493
  # Take the first result as template
489
494
  template = results[0]
@@ -511,7 +516,7 @@ def _average_benchmark_results(results: List[BenchmarkResult]) -> BenchmarkResul
511
516
  )
512
517
 
513
518
 
514
- def _get_memory_usage() -> Optional[float]:
519
+ def _get_memory_usage() -> float | None:
515
520
  """Get current memory usage in MB."""
516
521
  if not HAS_PSUTIL:
517
522
  return None
@@ -519,5 +524,5 @@ def _get_memory_usage() -> Optional[float]:
519
524
  try:
520
525
  process = psutil.Process()
521
526
  return process.memory_info().rss / 1024 / 1024 # Convert to MB
522
- except:
527
+ except (ImportError, AttributeError, Exception):
523
528
  return None