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.
- superquantx/__init__.py +24 -12
- superquantx/algorithms/__init__.py +1 -1
- superquantx/algorithms/base_algorithm.py +36 -36
- superquantx/algorithms/hybrid_classifier.py +22 -22
- superquantx/algorithms/qaoa.py +29 -28
- superquantx/algorithms/quantum_agents.py +57 -56
- superquantx/algorithms/quantum_kmeans.py +17 -17
- superquantx/algorithms/quantum_nn.py +18 -18
- superquantx/algorithms/quantum_pca.py +26 -26
- superquantx/algorithms/quantum_svm.py +26 -25
- superquantx/algorithms/vqe.py +40 -39
- superquantx/algorithms.py +56 -55
- superquantx/backends/__init__.py +12 -12
- superquantx/backends/base_backend.py +25 -24
- superquantx/backends/braket_backend.py +21 -21
- superquantx/backends/cirq_backend.py +26 -26
- superquantx/backends/ocean_backend.py +38 -38
- superquantx/backends/pennylane_backend.py +12 -11
- superquantx/backends/qiskit_backend.py +12 -12
- superquantx/backends/simulator_backend.py +31 -17
- superquantx/backends/tket_backend.py +23 -23
- superquantx/circuits.py +25 -25
- superquantx/cli/commands.py +6 -7
- superquantx/cli/main.py +5 -6
- superquantx/client.py +42 -42
- superquantx/config.py +14 -14
- superquantx/datasets/__init__.py +58 -0
- superquantx/datasets/molecular.py +307 -0
- superquantx/datasets/preprocessing.py +279 -0
- superquantx/datasets/quantum_datasets.py +277 -0
- superquantx/datasets/synthetic.py +300 -0
- superquantx/exceptions.py +29 -29
- superquantx/gates.py +26 -26
- superquantx/logging_config.py +29 -29
- superquantx/measurements.py +53 -54
- superquantx/ml.py +51 -52
- superquantx/noise.py +49 -49
- superquantx/utils/benchmarking.py +41 -36
- superquantx/utils/classical_utils.py +32 -32
- superquantx/utils/feature_mapping.py +40 -35
- superquantx/utils/optimization.py +28 -26
- superquantx/utils/quantum_utils.py +47 -48
- superquantx/utils/visualization.py +49 -49
- superquantx/version.py +3 -3
- {superquantx-0.1.0.dist-info → superquantx-0.1.1.dist-info}/METADATA +18 -16
- superquantx-0.1.1.dist-info/RECORD +51 -0
- superquantx-0.1.1.dist-info/licenses/LICENSE +180 -0
- superquantx-0.1.0.dist-info/RECORD +0 -46
- superquantx-0.1.0.dist-info/licenses/LICENSE +0 -21
- {superquantx-0.1.0.dist-info → superquantx-0.1.1.dist-info}/WHEEL +0 -0
- {superquantx-0.1.0.dist-info → superquantx-0.1.1.dist-info}/entry_points.txt +0 -0
superquantx/__init__.py
CHANGED
@@ -1,38 +1,49 @@
|
|
1
1
|
"""SuperQuantX: Experimental Quantum AI Research Platform.
|
2
2
|
|
3
|
-
⚠️ RESEARCH SOFTWARE WARNING: This is experimental research software developed by
|
4
|
-
SuperXLab (Superagentic AI Research Division). NOT intended for production use.
|
3
|
+
⚠️ RESEARCH SOFTWARE WARNING: This is experimental research software developed by
|
4
|
+
SuperXLab (Superagentic AI Research Division). NOT intended for production use.
|
5
5
|
For research and educational purposes only.
|
6
6
|
|
7
|
-
Part of SuperXLab's comprehensive quantum research program - the practical implementation
|
7
|
+
Part of SuperXLab's comprehensive quantum research program - the practical implementation
|
8
8
|
platform for validating theoretical research in:
|
9
9
|
🔬 Quantum-Inspired Agentic Systems: Superposition, interference, entanglement in agents
|
10
|
-
🔬 Quantum Neural Networks (QNNs): Hardware-validated quantum neural architectures
|
10
|
+
🔬 Quantum Neural Networks (QNNs): Hardware-validated quantum neural architectures
|
11
11
|
🔬 QuantumML for AI Training: Quantum-accelerated machine learning techniques
|
12
12
|
🔬 Quantinuum Integration: Real hardware validation on H-Series quantum computers
|
13
13
|
|
14
14
|
Research Examples:
|
15
15
|
Experimental quantum agent research:
|
16
16
|
>>> import superquantx as sqx # EXPERIMENTAL
|
17
|
-
>>> agent = sqx.QuantumTradingAgent(strategy="quantum_portfolio", backend="simulator")
|
17
|
+
>>> agent = sqx.QuantumTradingAgent(strategy="quantum_portfolio", backend="simulator")
|
18
18
|
>>> results = agent.solve(research_data) # Research use only
|
19
19
|
>>> print(f"Research findings: {results.metadata}")
|
20
|
-
|
20
|
+
|
21
21
|
Quantum neural network experiments:
|
22
22
|
>>> qnn = sqx.QuantumNN(architecture='hybrid', backend='pennylane') # EXPERIMENTAL
|
23
23
|
>>> qnn.fit(X_research, y_research) # Research data only
|
24
24
|
>>> analysis = qnn.analyze_expressivity() # Research analysis
|
25
|
-
|
25
|
+
|
26
26
|
Quantum algorithm benchmarking:
|
27
|
-
>>> qsvm = sqx.QuantumSVM(backend='simulator') # EXPERIMENTAL
|
27
|
+
>>> qsvm = sqx.QuantumSVM(backend='simulator') # EXPERIMENTAL
|
28
28
|
>>> benchmark = sqx.benchmark_algorithm(qsvm, classical_baseline)
|
29
29
|
"""
|
30
30
|
|
31
31
|
import logging
|
32
|
-
from typing import Any
|
32
|
+
from typing import Any
|
33
33
|
|
34
34
|
# Core imports - make available at top level
|
35
|
-
from . import algorithms, backends, cli,
|
35
|
+
from . import algorithms, backends, cli, utils
|
36
|
+
|
37
|
+
|
38
|
+
# Import datasets lazily to avoid circular imports
|
39
|
+
try:
|
40
|
+
from . import datasets
|
41
|
+
except ImportError:
|
42
|
+
# If datasets import fails, create a placeholder
|
43
|
+
import sys
|
44
|
+
import types
|
45
|
+
datasets = types.ModuleType('datasets')
|
46
|
+
sys.modules[f'{__name__}.datasets'] = datasets
|
36
47
|
from .config import config, configure
|
37
48
|
from .version import __version__
|
38
49
|
|
@@ -164,7 +175,7 @@ __title__ = "SuperQuantX"
|
|
164
175
|
__description__ = "Experimental Quantum AI Research Platform - NOT for production use"
|
165
176
|
__author__ = "SuperXLab - Superagentic AI Research Division"
|
166
177
|
__author_email__ = "research@superagentic.ai"
|
167
|
-
__license__ = "
|
178
|
+
__license__ = "Apache-2.0"
|
168
179
|
__url__ = "https://github.com/superagentic/superquantx"
|
169
180
|
|
170
181
|
# Version information
|
@@ -172,7 +183,7 @@ def get_version() -> str:
|
|
172
183
|
"""Get SuperQuantX version."""
|
173
184
|
return __version__
|
174
185
|
|
175
|
-
def get_backend_info() ->
|
186
|
+
def get_backend_info() -> dict[str, Any]:
|
176
187
|
"""Get information about available backends."""
|
177
188
|
info = {}
|
178
189
|
|
@@ -288,6 +299,7 @@ __all__ = [
|
|
288
299
|
"HybridClassifier",
|
289
300
|
|
290
301
|
# Common backends
|
302
|
+
"BaseBackend",
|
291
303
|
"AutoBackend",
|
292
304
|
"QiskitBackend",
|
293
305
|
"PennyLaneBackend",
|
@@ -6,7 +6,7 @@ make decisions and optimize complex problems independently.
|
|
6
6
|
|
7
7
|
The module is organized in layers:
|
8
8
|
- Quantum ML Algorithms: QSVM, VQE, QAOA, Quantum NN
|
9
|
-
- Quantum AI Models: Advanced neural networks and transformers
|
9
|
+
- Quantum AI Models: Advanced neural networks and transformers
|
10
10
|
- Quantum Agents: Autonomous systems for trading, research, optimization
|
11
11
|
- Hybrid Intelligence: Quantum-classical integrated systems
|
12
12
|
"""
|
@@ -8,7 +8,7 @@ import logging
|
|
8
8
|
import time
|
9
9
|
from abc import ABC, abstractmethod
|
10
10
|
from dataclasses import dataclass
|
11
|
-
from typing import Any
|
11
|
+
from typing import Any
|
12
12
|
|
13
13
|
import numpy as np
|
14
14
|
|
@@ -18,10 +18,10 @@ logger = logging.getLogger(__name__)
|
|
18
18
|
@dataclass
|
19
19
|
class QuantumResult:
|
20
20
|
"""Container for quantum algorithm results.
|
21
|
-
|
21
|
+
|
22
22
|
This class provides a standardized way to return results from quantum
|
23
23
|
algorithms, including the main result, metadata, and performance metrics.
|
24
|
-
|
24
|
+
|
25
25
|
Attributes:
|
26
26
|
result: The main algorithm result
|
27
27
|
metadata: Additional information about the computation
|
@@ -33,11 +33,11 @@ class QuantumResult:
|
|
33
33
|
"""
|
34
34
|
|
35
35
|
result: Any
|
36
|
-
metadata:
|
36
|
+
metadata: dict[str, Any]
|
37
37
|
execution_time: float
|
38
|
-
backend_info:
|
39
|
-
error:
|
40
|
-
intermediate_results:
|
38
|
+
backend_info: dict[str, Any]
|
39
|
+
error: str | None = None
|
40
|
+
intermediate_results: dict[str, Any] | None = None
|
41
41
|
|
42
42
|
def __post_init__(self):
|
43
43
|
"""Validate and process result after initialization."""
|
@@ -48,10 +48,10 @@ class QuantumResult:
|
|
48
48
|
|
49
49
|
class BaseQuantumAlgorithm(ABC):
|
50
50
|
"""Abstract base class for all quantum machine learning algorithms.
|
51
|
-
|
51
|
+
|
52
52
|
This class defines the common interface that all quantum algorithms must
|
53
53
|
implement, providing consistency across different algorithm types and backends.
|
54
|
-
|
54
|
+
|
55
55
|
Args:
|
56
56
|
backend: Quantum backend to use for computation
|
57
57
|
shots: Number of measurement shots (default: 1024)
|
@@ -63,9 +63,9 @@ class BaseQuantumAlgorithm(ABC):
|
|
63
63
|
|
64
64
|
def __init__(
|
65
65
|
self,
|
66
|
-
backend:
|
66
|
+
backend: str | Any,
|
67
67
|
shots: int = 1024,
|
68
|
-
seed:
|
68
|
+
seed: int | None = None,
|
69
69
|
optimization_level: int = 1,
|
70
70
|
**kwargs
|
71
71
|
) -> None:
|
@@ -90,7 +90,7 @@ class BaseQuantumAlgorithm(ABC):
|
|
90
90
|
|
91
91
|
logger.info(f"Initialized {self.__class__.__name__} with backend {type(self.backend).__name__}")
|
92
92
|
|
93
|
-
def _initialize_backend(self, backend:
|
93
|
+
def _initialize_backend(self, backend: str | Any) -> Any:
|
94
94
|
"""Initialize the quantum backend."""
|
95
95
|
if isinstance(backend, str):
|
96
96
|
# Import here to avoid circular imports
|
@@ -99,14 +99,14 @@ class BaseQuantumAlgorithm(ABC):
|
|
99
99
|
return backend
|
100
100
|
|
101
101
|
@abstractmethod
|
102
|
-
def fit(self, X: np.ndarray, y:
|
102
|
+
def fit(self, X: np.ndarray, y: np.ndarray | None = None, **kwargs) -> 'BaseQuantumAlgorithm':
|
103
103
|
"""Train the quantum algorithm.
|
104
|
-
|
104
|
+
|
105
105
|
Args:
|
106
106
|
X: Training data features
|
107
107
|
y: Training data labels (for supervised learning)
|
108
108
|
**kwargs: Additional training parameters
|
109
|
-
|
109
|
+
|
110
110
|
Returns:
|
111
111
|
Self for method chaining
|
112
112
|
|
@@ -116,11 +116,11 @@ class BaseQuantumAlgorithm(ABC):
|
|
116
116
|
@abstractmethod
|
117
117
|
def predict(self, X: np.ndarray, **kwargs) -> np.ndarray:
|
118
118
|
"""Make predictions using the trained algorithm.
|
119
|
-
|
119
|
+
|
120
120
|
Args:
|
121
121
|
X: Input data for prediction
|
122
122
|
**kwargs: Additional prediction parameters
|
123
|
-
|
123
|
+
|
124
124
|
Returns:
|
125
125
|
Predictions array
|
126
126
|
|
@@ -129,12 +129,12 @@ class BaseQuantumAlgorithm(ABC):
|
|
129
129
|
|
130
130
|
def score(self, X: np.ndarray, y: np.ndarray, **kwargs) -> float:
|
131
131
|
"""Compute the algorithm's score on the given test data.
|
132
|
-
|
132
|
+
|
133
133
|
Args:
|
134
134
|
X: Test data features
|
135
135
|
y: True test data labels
|
136
136
|
**kwargs: Additional scoring parameters
|
137
|
-
|
137
|
+
|
138
138
|
Returns:
|
139
139
|
Algorithm score (higher is better)
|
140
140
|
|
@@ -147,12 +147,12 @@ class BaseQuantumAlgorithm(ABC):
|
|
147
147
|
from sklearn.metrics import accuracy_score
|
148
148
|
return accuracy_score(y_true, predictions)
|
149
149
|
|
150
|
-
def get_params(self, deep: bool = True) ->
|
150
|
+
def get_params(self, deep: bool = True) -> dict[str, Any]:
|
151
151
|
"""Get algorithm parameters.
|
152
|
-
|
152
|
+
|
153
153
|
Args:
|
154
154
|
deep: Whether to return deep copy of parameters
|
155
|
-
|
155
|
+
|
156
156
|
Returns:
|
157
157
|
Parameter dictionary
|
158
158
|
|
@@ -168,10 +168,10 @@ class BaseQuantumAlgorithm(ABC):
|
|
168
168
|
|
169
169
|
def set_params(self, **params) -> 'BaseQuantumAlgorithm':
|
170
170
|
"""Set algorithm parameters.
|
171
|
-
|
171
|
+
|
172
172
|
Args:
|
173
173
|
**params: Parameters to set
|
174
|
-
|
174
|
+
|
175
175
|
Returns:
|
176
176
|
Self for method chaining
|
177
177
|
|
@@ -185,7 +185,7 @@ class BaseQuantumAlgorithm(ABC):
|
|
185
185
|
|
186
186
|
def save_model(self, filepath: str) -> None:
|
187
187
|
"""Save the trained model to disk.
|
188
|
-
|
188
|
+
|
189
189
|
Args:
|
190
190
|
filepath: Path where to save the model
|
191
191
|
|
@@ -212,10 +212,10 @@ class BaseQuantumAlgorithm(ABC):
|
|
212
212
|
@classmethod
|
213
213
|
def load_model(cls, filepath: str) -> 'BaseQuantumAlgorithm':
|
214
214
|
"""Load a trained model from disk.
|
215
|
-
|
215
|
+
|
216
216
|
Args:
|
217
217
|
filepath: Path to the saved model
|
218
|
-
|
218
|
+
|
219
219
|
Returns:
|
220
220
|
Loaded algorithm instance
|
221
221
|
|
@@ -235,14 +235,14 @@ class BaseQuantumAlgorithm(ABC):
|
|
235
235
|
logger.info(f"Model loaded from {filepath}")
|
236
236
|
return instance
|
237
237
|
|
238
|
-
def benchmark(self, X: np.ndarray, y:
|
238
|
+
def benchmark(self, X: np.ndarray, y: np.ndarray | None = None, runs: int = 5) -> dict[str, Any]:
|
239
239
|
"""Benchmark algorithm performance.
|
240
|
-
|
240
|
+
|
241
241
|
Args:
|
242
242
|
X: Test data
|
243
243
|
y: Test labels (optional)
|
244
244
|
runs: Number of benchmark runs
|
245
|
-
|
245
|
+
|
246
246
|
Returns:
|
247
247
|
Benchmark results dictionary
|
248
248
|
|
@@ -281,9 +281,9 @@ class BaseQuantumAlgorithm(ABC):
|
|
281
281
|
|
282
282
|
return results
|
283
283
|
|
284
|
-
def get_circuit_info(self) ->
|
284
|
+
def get_circuit_info(self) -> dict[str, Any]:
|
285
285
|
"""Get information about the quantum circuit.
|
286
|
-
|
286
|
+
|
287
287
|
Returns:
|
288
288
|
Circuit information dictionary
|
289
289
|
|
@@ -348,7 +348,7 @@ class UnsupervisedQuantumAlgorithm(BaseQuantumAlgorithm):
|
|
348
348
|
self.n_features_ = None
|
349
349
|
self.n_samples_ = None
|
350
350
|
|
351
|
-
def fit(self, X: np.ndarray, y:
|
351
|
+
def fit(self, X: np.ndarray, y: np.ndarray | None = None, **kwargs) -> 'UnsupervisedQuantumAlgorithm':
|
352
352
|
"""Fit unsupervised algorithm."""
|
353
353
|
self._validate_data(X)
|
354
354
|
self.n_features_ = X.shape[1]
|
@@ -369,14 +369,14 @@ class OptimizationQuantumAlgorithm(BaseQuantumAlgorithm):
|
|
369
369
|
self.optimal_value_ = None
|
370
370
|
self.optimization_history_ = []
|
371
371
|
|
372
|
-
def optimize(self, objective_function, initial_params:
|
372
|
+
def optimize(self, objective_function, initial_params: np.ndarray | None = None, **kwargs) -> QuantumResult:
|
373
373
|
"""Optimize objective function.
|
374
|
-
|
374
|
+
|
375
375
|
Args:
|
376
376
|
objective_function: Function to optimize
|
377
377
|
initial_params: Initial parameter values
|
378
378
|
**kwargs: Additional optimization parameters
|
379
|
-
|
379
|
+
|
380
380
|
Returns:
|
381
381
|
Optimization result
|
382
382
|
|
@@ -5,7 +5,7 @@ machine learning components for enhanced performance and flexibility.
|
|
5
5
|
"""
|
6
6
|
|
7
7
|
import logging
|
8
|
-
from typing import Any
|
8
|
+
from typing import Any
|
9
9
|
|
10
10
|
import numpy as np
|
11
11
|
from sklearn.ensemble import GradientBoostingClassifier, RandomForestClassifier
|
@@ -24,14 +24,14 @@ logger = logging.getLogger(__name__)
|
|
24
24
|
|
25
25
|
class HybridClassifier(SupervisedQuantumAlgorithm):
|
26
26
|
"""Hybrid Classical-Quantum Classifier.
|
27
|
-
|
27
|
+
|
28
28
|
This classifier combines classical and quantum machine learning algorithms
|
29
29
|
to leverage the strengths of both approaches. It can operate in different modes:
|
30
30
|
- Ensemble: Combines predictions from multiple quantum and classical models
|
31
31
|
- Sequential: Uses quantum features as input to classical models
|
32
|
-
- Voting: Majority voting among quantum and classical predictions
|
32
|
+
- Voting: Majority voting among quantum and classical predictions
|
33
33
|
- Stacking: Uses meta-learner to combine quantum and classical predictions
|
34
|
-
|
34
|
+
|
35
35
|
Args:
|
36
36
|
backend: Quantum backend for quantum components
|
37
37
|
hybrid_mode: Mode of operation ('ensemble', 'sequential', 'voting', 'stacking')
|
@@ -42,7 +42,7 @@ class HybridClassifier(SupervisedQuantumAlgorithm):
|
|
42
42
|
meta_learner: Meta-learning algorithm for stacking mode
|
43
43
|
shots: Number of measurement shots
|
44
44
|
**kwargs: Additional parameters
|
45
|
-
|
45
|
+
|
46
46
|
Example:
|
47
47
|
>>> hybrid = HybridClassifier(
|
48
48
|
... backend='pennylane',
|
@@ -57,10 +57,10 @@ class HybridClassifier(SupervisedQuantumAlgorithm):
|
|
57
57
|
|
58
58
|
def __init__(
|
59
59
|
self,
|
60
|
-
backend:
|
60
|
+
backend: str | Any,
|
61
61
|
hybrid_mode: str = 'ensemble',
|
62
|
-
quantum_algorithms:
|
63
|
-
classical_algorithms:
|
62
|
+
quantum_algorithms: list[str] | None = None,
|
63
|
+
classical_algorithms: list[str] | None = None,
|
64
64
|
quantum_weight: float = 0.5,
|
65
65
|
feature_selection: bool = False,
|
66
66
|
meta_learner: str = 'logistic_regression',
|
@@ -153,7 +153,7 @@ class HybridClassifier(SupervisedQuantumAlgorithm):
|
|
153
153
|
from sklearn.feature_selection import SelectKBest, f_classif
|
154
154
|
self.feature_selector = SelectKBest(score_func=f_classif, k='all')
|
155
155
|
|
156
|
-
def _apply_feature_selection(self, X: np.ndarray, y:
|
156
|
+
def _apply_feature_selection(self, X: np.ndarray, y: np.ndarray | None = None) -> np.ndarray:
|
157
157
|
"""Apply quantum-inspired feature selection."""
|
158
158
|
if not self.feature_selection or self.feature_selector is None:
|
159
159
|
return X
|
@@ -172,7 +172,7 @@ class HybridClassifier(SupervisedQuantumAlgorithm):
|
|
172
172
|
logger.info(f"Feature selection: {X.shape[1]} -> {X_selected.shape[1]} features")
|
173
173
|
return X_selected
|
174
174
|
|
175
|
-
def _train_quantum_models(self, X: np.ndarray, y: np.ndarray) ->
|
175
|
+
def _train_quantum_models(self, X: np.ndarray, y: np.ndarray) -> dict[str, float]:
|
176
176
|
"""Train quantum models and return their scores."""
|
177
177
|
scores = {}
|
178
178
|
|
@@ -194,7 +194,7 @@ class HybridClassifier(SupervisedQuantumAlgorithm):
|
|
194
194
|
|
195
195
|
return scores
|
196
196
|
|
197
|
-
def _train_classical_models(self, X: np.ndarray, y: np.ndarray) ->
|
197
|
+
def _train_classical_models(self, X: np.ndarray, y: np.ndarray) -> dict[str, float]:
|
198
198
|
"""Train classical models and return their scores."""
|
199
199
|
scores = {}
|
200
200
|
|
@@ -216,7 +216,7 @@ class HybridClassifier(SupervisedQuantumAlgorithm):
|
|
216
216
|
|
217
217
|
return scores
|
218
218
|
|
219
|
-
def _get_base_predictions(self, X: np.ndarray) ->
|
219
|
+
def _get_base_predictions(self, X: np.ndarray) -> tuple[np.ndarray, np.ndarray]:
|
220
220
|
"""Get predictions from all base models."""
|
221
221
|
quantum_preds = []
|
222
222
|
classical_preds = []
|
@@ -367,12 +367,12 @@ class HybridClassifier(SupervisedQuantumAlgorithm):
|
|
367
367
|
|
368
368
|
def fit(self, X: np.ndarray, y: np.ndarray, **kwargs) -> 'HybridClassifier':
|
369
369
|
"""Train the hybrid classifier.
|
370
|
-
|
370
|
+
|
371
371
|
Args:
|
372
372
|
X: Training data features
|
373
373
|
y: Training data labels
|
374
374
|
**kwargs: Additional training parameters
|
375
|
-
|
375
|
+
|
376
376
|
Returns:
|
377
377
|
Self for method chaining
|
378
378
|
|
@@ -460,11 +460,11 @@ class HybridClassifier(SupervisedQuantumAlgorithm):
|
|
460
460
|
|
461
461
|
def predict(self, X: np.ndarray, **kwargs) -> np.ndarray:
|
462
462
|
"""Make predictions using the hybrid classifier.
|
463
|
-
|
463
|
+
|
464
464
|
Args:
|
465
465
|
X: Input data for prediction
|
466
466
|
**kwargs: Additional prediction parameters
|
467
|
-
|
467
|
+
|
468
468
|
Returns:
|
469
469
|
Predicted labels
|
470
470
|
|
@@ -496,11 +496,11 @@ class HybridClassifier(SupervisedQuantumAlgorithm):
|
|
496
496
|
|
497
497
|
def predict_proba(self, X: np.ndarray, **kwargs) -> np.ndarray:
|
498
498
|
"""Predict class probabilities.
|
499
|
-
|
499
|
+
|
500
500
|
Args:
|
501
501
|
X: Input data for prediction
|
502
502
|
**kwargs: Additional parameters
|
503
|
-
|
503
|
+
|
504
504
|
Returns:
|
505
505
|
Predicted class probabilities
|
506
506
|
|
@@ -556,7 +556,7 @@ class HybridClassifier(SupervisedQuantumAlgorithm):
|
|
556
556
|
|
557
557
|
return prob_matrix
|
558
558
|
|
559
|
-
def get_model_performance(self) ->
|
559
|
+
def get_model_performance(self) -> dict[str, Any]:
|
560
560
|
"""Get detailed performance metrics for all models."""
|
561
561
|
performance = {
|
562
562
|
'quantum_scores': self.quantum_scores.copy(),
|
@@ -580,11 +580,11 @@ class HybridClassifier(SupervisedQuantumAlgorithm):
|
|
580
580
|
|
581
581
|
return performance
|
582
582
|
|
583
|
-
def get_feature_importance(self) ->
|
583
|
+
def get_feature_importance(self) -> np.ndarray | None:
|
584
584
|
"""Get feature importance from feature selection."""
|
585
585
|
return self.feature_importance_
|
586
586
|
|
587
|
-
def cross_validate(self, X: np.ndarray, y: np.ndarray, cv: int = 5) ->
|
587
|
+
def cross_validate(self, X: np.ndarray, y: np.ndarray, cv: int = 5) -> dict[str, Any]:
|
588
588
|
"""Perform cross-validation on the hybrid classifier."""
|
589
589
|
if not self.is_fitted:
|
590
590
|
raise ValueError("Model must be fitted before cross-validation")
|
@@ -604,7 +604,7 @@ class HybridClassifier(SupervisedQuantumAlgorithm):
|
|
604
604
|
logger.error(f"Cross-validation failed: {e}")
|
605
605
|
return {'error': str(e)}
|
606
606
|
|
607
|
-
def get_params(self, deep: bool = True) ->
|
607
|
+
def get_params(self, deep: bool = True) -> dict[str, Any]:
|
608
608
|
"""Get hybrid classifier parameters."""
|
609
609
|
params = super().get_params(deep)
|
610
610
|
params.update({
|
superquantx/algorithms/qaoa.py
CHANGED
@@ -5,7 +5,8 @@ problems using quantum circuits with parameterized gates.
|
|
5
5
|
"""
|
6
6
|
|
7
7
|
import logging
|
8
|
-
from
|
8
|
+
from collections.abc import Callable
|
9
|
+
from typing import Any
|
9
10
|
|
10
11
|
import numpy as np
|
11
12
|
from scipy.optimize import minimize
|
@@ -17,28 +18,28 @@ logger = logging.getLogger(__name__)
|
|
17
18
|
|
18
19
|
class QAOA(OptimizationQuantumAlgorithm):
|
19
20
|
"""Quantum Approximate Optimization Algorithm for combinatorial optimization.
|
20
|
-
|
21
|
+
|
21
22
|
QAOA is a hybrid quantum-classical algorithm that alternates between
|
22
23
|
quantum evolution and classical parameter optimization to find approximate
|
23
24
|
solutions to combinatorial optimization problems.
|
24
|
-
|
25
|
+
|
25
26
|
The algorithm works by:
|
26
27
|
1. Preparing an initial superposition state
|
27
28
|
2. Applying alternating problem and mixer Hamiltonians
|
28
29
|
3. Measuring the quantum state
|
29
30
|
4. Classically optimizing the parameters
|
30
|
-
|
31
|
+
|
31
32
|
Args:
|
32
33
|
backend: Quantum backend for circuit execution
|
33
34
|
p: Number of QAOA layers (depth)
|
34
35
|
problem_hamiltonian: Problem Hamiltonian function
|
35
|
-
mixer_hamiltonian: Mixer Hamiltonian function
|
36
|
+
mixer_hamiltonian: Mixer Hamiltonian function
|
36
37
|
initial_state: Initial quantum state preparation
|
37
38
|
optimizer: Classical optimizer ('COBYLA', 'L-BFGS-B', etc.)
|
38
39
|
shots: Number of measurement shots
|
39
40
|
maxiter: Maximum optimization iterations
|
40
41
|
**kwargs: Additional parameters
|
41
|
-
|
42
|
+
|
42
43
|
Example:
|
43
44
|
>>> # Define Max-Cut problem
|
44
45
|
>>> def problem_ham(gamma, graph):
|
@@ -50,10 +51,10 @@ class QAOA(OptimizationQuantumAlgorithm):
|
|
50
51
|
|
51
52
|
def __init__(
|
52
53
|
self,
|
53
|
-
backend:
|
54
|
+
backend: str | Any,
|
54
55
|
p: int = 1,
|
55
|
-
problem_hamiltonian:
|
56
|
-
mixer_hamiltonian:
|
56
|
+
problem_hamiltonian: Callable | None = None,
|
57
|
+
mixer_hamiltonian: Callable | None = None,
|
57
58
|
initial_state: str = 'uniform_superposition',
|
58
59
|
optimizer: str = 'COBYLA',
|
59
60
|
shots: int = 1024,
|
@@ -109,10 +110,10 @@ class QAOA(OptimizationQuantumAlgorithm):
|
|
109
110
|
|
110
111
|
def _create_qaoa_circuit(self, params: np.ndarray) -> Any:
|
111
112
|
"""Create QAOA circuit with given parameters.
|
112
|
-
|
113
|
+
|
113
114
|
Args:
|
114
115
|
params: Array of [gamma_1, beta_1, ..., gamma_p, beta_p]
|
115
|
-
|
116
|
+
|
116
117
|
Returns:
|
117
118
|
Quantum circuit
|
118
119
|
|
@@ -147,10 +148,10 @@ class QAOA(OptimizationQuantumAlgorithm):
|
|
147
148
|
|
148
149
|
def _objective_function(self, params: np.ndarray) -> float:
|
149
150
|
"""QAOA objective function to minimize.
|
150
|
-
|
151
|
+
|
151
152
|
Args:
|
152
153
|
params: Circuit parameters
|
153
|
-
|
154
|
+
|
154
155
|
Returns:
|
155
156
|
Negative expectation value (for minimization)
|
156
157
|
|
@@ -188,14 +189,14 @@ class QAOA(OptimizationQuantumAlgorithm):
|
|
188
189
|
logger.warning("Using fallback circuit execution")
|
189
190
|
return np.random.random() # Placeholder
|
190
191
|
|
191
|
-
def fit(self, X: np.ndarray, y:
|
192
|
+
def fit(self, X: np.ndarray, y: np.ndarray | None = None, **kwargs) -> 'QAOA':
|
192
193
|
"""Fit QAOA to problem instance.
|
193
|
-
|
194
|
+
|
194
195
|
Args:
|
195
196
|
X: Problem instance data (e.g., adjacency matrix for Max-Cut)
|
196
197
|
y: Not used in QAOA
|
197
198
|
**kwargs: Additional parameters
|
198
|
-
|
199
|
+
|
199
200
|
Returns:
|
200
201
|
Self for method chaining
|
201
202
|
|
@@ -222,11 +223,11 @@ class QAOA(OptimizationQuantumAlgorithm):
|
|
222
223
|
|
223
224
|
def predict(self, X: np.ndarray, **kwargs) -> np.ndarray:
|
224
225
|
"""Get optimal solution from QAOA results.
|
225
|
-
|
226
|
+
|
226
227
|
Args:
|
227
228
|
X: Problem instance (not used if same as training)
|
228
229
|
**kwargs: Additional parameters
|
229
|
-
|
230
|
+
|
230
231
|
Returns:
|
231
232
|
Optimal bit string solution
|
232
233
|
|
@@ -249,14 +250,14 @@ class QAOA(OptimizationQuantumAlgorithm):
|
|
249
250
|
|
250
251
|
return best_solution
|
251
252
|
|
252
|
-
def _run_optimization(self, objective_function, initial_params:
|
253
|
+
def _run_optimization(self, objective_function, initial_params: np.ndarray | None = None, **kwargs):
|
253
254
|
"""Run QAOA optimization.
|
254
|
-
|
255
|
+
|
255
256
|
Args:
|
256
257
|
objective_function: Function to optimize (ignored, uses internal)
|
257
258
|
initial_params: Initial parameter guess
|
258
259
|
**kwargs: Additional optimization parameters
|
259
|
-
|
260
|
+
|
260
261
|
Returns:
|
261
262
|
Optimization result
|
262
263
|
|
@@ -313,13 +314,13 @@ class QAOA(OptimizationQuantumAlgorithm):
|
|
313
314
|
betas = np.random.uniform(*self.beta_bounds, self.p)
|
314
315
|
return np.concatenate([gammas, betas])
|
315
316
|
|
316
|
-
def get_optimization_landscape(self, param_range:
|
317
|
+
def get_optimization_landscape(self, param_range: tuple[float, float], resolution: int = 50) -> dict[str, Any]:
|
317
318
|
"""Compute optimization landscape for visualization.
|
318
|
-
|
319
|
+
|
319
320
|
Args:
|
320
321
|
param_range: Range of parameters to explore
|
321
322
|
resolution: Number of points per dimension
|
322
|
-
|
323
|
+
|
323
324
|
Returns:
|
324
325
|
Dictionary with landscape data
|
325
326
|
|
@@ -345,12 +346,12 @@ class QAOA(OptimizationQuantumAlgorithm):
|
|
345
346
|
'optimal_params': self.optimal_params_ if hasattr(self, 'optimal_params_') else None
|
346
347
|
}
|
347
348
|
|
348
|
-
def analyze_solution_quality(self, true_optimum:
|
349
|
+
def analyze_solution_quality(self, true_optimum: float | None = None) -> dict[str, Any]:
|
349
350
|
"""Analyze quality of QAOA solution.
|
350
|
-
|
351
|
+
|
351
352
|
Args:
|
352
353
|
true_optimum: Known optimal value for comparison
|
353
|
-
|
354
|
+
|
354
355
|
Returns:
|
355
356
|
Analysis results
|
356
357
|
|
@@ -384,7 +385,7 @@ class QAOA(OptimizationQuantumAlgorithm):
|
|
384
385
|
|
385
386
|
return analysis
|
386
387
|
|
387
|
-
def get_params(self, deep: bool = True) ->
|
388
|
+
def get_params(self, deep: bool = True) -> dict[str, Any]:
|
388
389
|
"""Get QAOA parameters."""
|
389
390
|
params = super().get_params(deep)
|
390
391
|
params.update({
|