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,346 @@
1
+ """Quantum Support Vector Machine (QSVM) implementation.
2
+
3
+ This module provides a quantum support vector machine algorithm that can be used
4
+ for binary and multiclass classification tasks using quantum kernels.
5
+ """
6
+
7
+ import logging
8
+ from typing import Any, Callable, Dict, Optional, Union
9
+
10
+ import numpy as np
11
+ from sklearn.metrics import accuracy_score
12
+ from sklearn.preprocessing import StandardScaler
13
+ from sklearn.svm import SVC
14
+
15
+ from .base_algorithm import SupervisedQuantumAlgorithm
16
+
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+ class QuantumSVM(SupervisedQuantumAlgorithm):
21
+ """Quantum Support Vector Machine for classification.
22
+
23
+ This implementation uses quantum feature maps to transform data into
24
+ a high-dimensional Hilbert space where linear separation is possible.
25
+ The quantum kernel is computed using quantum circuits.
26
+
27
+ The algorithm works by:
28
+ 1. Encoding classical data into quantum states using feature maps
29
+ 2. Computing quantum kernels between data points
30
+ 3. Training a classical SVM using the quantum kernel matrix
31
+
32
+ Args:
33
+ backend: Quantum backend for circuit execution
34
+ feature_map: Type of quantum feature map ('ZZFeatureMap', 'PauliFeatureMap', etc.)
35
+ feature_map_reps: Number of repetitions in the feature map
36
+ C: Regularization parameter for SVM
37
+ gamma: Kernel coefficient (for RBF-like quantum kernels)
38
+ quantum_kernel: Custom quantum kernel function
39
+ shots: Number of measurement shots
40
+ **kwargs: Additional parameters
41
+
42
+ Example:
43
+ >>> qsvm = QuantumSVM(backend='pennylane', feature_map='ZZFeatureMap')
44
+ >>> qsvm.fit(X_train, y_train)
45
+ >>> predictions = qsvm.predict(X_test)
46
+ >>> accuracy = qsvm.score(X_test, y_test)
47
+
48
+ """
49
+
50
+ def __init__(
51
+ self,
52
+ backend: Union[str, Any],
53
+ feature_map: str = 'ZZFeatureMap',
54
+ feature_map_reps: int = 2,
55
+ C: float = 1.0,
56
+ gamma: Optional[float] = None,
57
+ quantum_kernel: Optional[Callable] = None,
58
+ shots: int = 1024,
59
+ normalize_data: bool = True,
60
+ **kwargs
61
+ ) -> None:
62
+ super().__init__(backend=backend, shots=shots, **kwargs)
63
+
64
+ self.feature_map = feature_map
65
+ self.feature_map_reps = feature_map_reps
66
+ self.C = C
67
+ self.gamma = gamma
68
+ self.quantum_kernel = quantum_kernel
69
+ self.normalize_data = normalize_data
70
+
71
+ # Classical components
72
+ self.svm = None
73
+ self.scaler = StandardScaler() if normalize_data else None
74
+
75
+ # Quantum components
76
+ self.kernel_matrix_ = None
77
+ self.feature_map_circuit_ = None
78
+
79
+ # Training data storage (needed for kernel computation)
80
+ self.X_train_ = None
81
+
82
+ logger.info(f"Initialized QuantumSVM with feature_map={feature_map}, reps={feature_map_reps}")
83
+
84
+ def _create_feature_map(self, n_features: int) -> Any:
85
+ """Create quantum feature map circuit."""
86
+ try:
87
+ if hasattr(self.backend, 'create_feature_map'):
88
+ return self.backend.create_feature_map(
89
+ n_features=n_features,
90
+ feature_map=self.feature_map,
91
+ reps=self.feature_map_reps
92
+ )
93
+ else:
94
+ # Fallback implementation
95
+ return self._default_feature_map(n_features)
96
+ except Exception as e:
97
+ logger.error(f"Failed to create feature map: {e}")
98
+ return self._default_feature_map(n_features)
99
+
100
+ def _default_feature_map(self, n_features: int) -> Any:
101
+ """Create default feature map when backend doesn't provide one."""
102
+ # This would be implemented based on the backend
103
+ logger.warning("Using default feature map - results may vary")
104
+ return None
105
+
106
+ def _compute_quantum_kernel(self, X1: np.ndarray, X2: Optional[np.ndarray] = None) -> np.ndarray:
107
+ """Compute quantum kernel matrix between data points.
108
+
109
+ Args:
110
+ X1: First set of data points
111
+ X2: Second set of data points (if None, use X1)
112
+
113
+ Returns:
114
+ Quantum kernel matrix
115
+
116
+ """
117
+ if X2 is None:
118
+ X2 = X1
119
+
120
+ n1, n2 = len(X1), len(X2)
121
+ kernel_matrix = np.zeros((n1, n2))
122
+
123
+ if self.quantum_kernel:
124
+ # Use custom quantum kernel
125
+ for i in range(n1):
126
+ for j in range(n2):
127
+ kernel_matrix[i, j] = self.quantum_kernel(X1[i], X2[j])
128
+ else:
129
+ # Use backend's kernel computation
130
+ try:
131
+ kernel_matrix = self.backend.compute_kernel_matrix(
132
+ X1, X2,
133
+ feature_map=self.feature_map_circuit_,
134
+ shots=self.shots
135
+ )
136
+ except Exception as e:
137
+ logger.error(f"Quantum kernel computation failed: {e}")
138
+ # Fallback to classical RBF kernel
139
+ from sklearn.metrics.pairwise import rbf_kernel
140
+ gamma = self.gamma if self.gamma else 1.0 / X1.shape[1]
141
+ kernel_matrix = rbf_kernel(X1, X2, gamma=gamma)
142
+ logger.warning("Using classical RBF kernel as fallback")
143
+
144
+ return kernel_matrix
145
+
146
+ def fit(self, X: np.ndarray, y: np.ndarray, **kwargs) -> 'QuantumSVM':
147
+ """Train the quantum SVM.
148
+
149
+ Args:
150
+ X: Training data features
151
+ y: Training data labels
152
+ **kwargs: Additional training parameters
153
+
154
+ Returns:
155
+ Self for method chaining
156
+
157
+ """
158
+ logger.info(f"Training QuantumSVM on {X.shape[0]} samples with {X.shape[1]} features")
159
+
160
+ # Validate and preprocess data
161
+ super().fit(X, y, **kwargs)
162
+
163
+ if self.normalize_data:
164
+ X = self.scaler.fit_transform(X)
165
+
166
+ self.X_train_ = X.copy()
167
+
168
+ # Create quantum feature map
169
+ self.feature_map_circuit_ = self._create_feature_map(X.shape[1])
170
+
171
+ # Compute quantum kernel matrix
172
+ logger.info("Computing quantum kernel matrix...")
173
+ self.kernel_matrix_ = self._compute_quantum_kernel(X)
174
+
175
+ # Train classical SVM with quantum kernel
176
+ self.svm = SVC(
177
+ kernel='precomputed',
178
+ C=self.C,
179
+ )
180
+
181
+ self.svm.fit(self.kernel_matrix_, y)
182
+ self.is_fitted = True
183
+
184
+ # Compute training accuracy
185
+ train_predictions = self.predict(X)
186
+ train_accuracy = accuracy_score(y, train_predictions)
187
+
188
+ self.training_history.append({
189
+ 'train_accuracy': train_accuracy,
190
+ 'n_support_vectors': self.svm.n_support_,
191
+ 'kernel_matrix_shape': self.kernel_matrix_.shape,
192
+ })
193
+
194
+ logger.info(f"Training completed. Accuracy: {train_accuracy:.3f}, "
195
+ f"Support vectors: {sum(self.svm.n_support_)}")
196
+
197
+ return self
198
+
199
+ def predict(self, X: np.ndarray, **kwargs) -> np.ndarray:
200
+ """Make predictions using the trained quantum SVM.
201
+
202
+ Args:
203
+ X: Input data for prediction
204
+ **kwargs: Additional prediction parameters
205
+
206
+ Returns:
207
+ Predicted labels
208
+
209
+ """
210
+ if not self.is_fitted:
211
+ raise ValueError("Model must be fitted before making predictions")
212
+
213
+ if self.normalize_data:
214
+ X = self.scaler.transform(X)
215
+
216
+ # Compute kernel matrix between test data and training data
217
+ test_kernel = self._compute_quantum_kernel(X, self.X_train_)
218
+
219
+ # Make predictions using the trained SVM
220
+ predictions = self.svm.predict(test_kernel)
221
+
222
+ return predictions
223
+
224
+ def predict_proba(self, X: np.ndarray, **kwargs) -> np.ndarray:
225
+ """Predict class probabilities.
226
+
227
+ Args:
228
+ X: Input data for prediction
229
+ **kwargs: Additional parameters
230
+
231
+ Returns:
232
+ Predicted class probabilities
233
+
234
+ """
235
+ if not self.is_fitted:
236
+ raise ValueError("Model must be fitted before making predictions")
237
+
238
+ if self.normalize_data:
239
+ X = self.scaler.transform(X)
240
+
241
+ test_kernel = self._compute_quantum_kernel(X, self.X_train_)
242
+
243
+ # Need to recreate SVM with probability=True for probabilities
244
+ if not hasattr(self.svm, 'predict_proba'):
245
+ logger.warning("Probability prediction not available, returning decision scores")
246
+ return self.decision_function(X)
247
+
248
+ return self.svm.predict_proba(test_kernel)
249
+
250
+ def decision_function(self, X: np.ndarray) -> np.ndarray:
251
+ """Compute decision function values.
252
+
253
+ Args:
254
+ X: Input data
255
+
256
+ Returns:
257
+ Decision function values
258
+
259
+ """
260
+ if not self.is_fitted:
261
+ raise ValueError("Model must be fitted before computing decision function")
262
+
263
+ if self.normalize_data:
264
+ X = self.scaler.transform(X)
265
+
266
+ test_kernel = self._compute_quantum_kernel(X, self.X_train_)
267
+ return self.svm.decision_function(test_kernel)
268
+
269
+ def get_support_vectors(self) -> np.ndarray:
270
+ """Get support vectors from the trained model."""
271
+ if not self.is_fitted:
272
+ raise ValueError("Model must be fitted to get support vectors")
273
+
274
+ return self.X_train_[self.svm.support_]
275
+
276
+ def get_quantum_kernel_matrix(self, X: Optional[np.ndarray] = None) -> np.ndarray:
277
+ """Get the quantum kernel matrix.
278
+
279
+ Args:
280
+ X: Data to compute kernel matrix for (default: training data)
281
+
282
+ Returns:
283
+ Quantum kernel matrix
284
+
285
+ """
286
+ if X is None:
287
+ if self.kernel_matrix_ is None:
288
+ raise ValueError("No kernel matrix available")
289
+ return self.kernel_matrix_
290
+ else:
291
+ if self.normalize_data:
292
+ X = self.scaler.transform(X)
293
+ return self._compute_quantum_kernel(X)
294
+
295
+ def analyze_kernel(self) -> Dict[str, Any]:
296
+ """Analyze properties of the quantum kernel.
297
+
298
+ Returns:
299
+ Dictionary with kernel analysis results
300
+
301
+ """
302
+ if self.kernel_matrix_ is None:
303
+ raise ValueError("Model must be fitted to analyze kernel")
304
+
305
+ K = self.kernel_matrix_
306
+
307
+ # Compute kernel properties
308
+ eigenvalues = np.linalg.eigvals(K)
309
+
310
+ analysis = {
311
+ 'kernel_shape': K.shape,
312
+ 'kernel_rank': np.linalg.matrix_rank(K),
313
+ 'condition_number': np.linalg.cond(K),
314
+ 'trace': np.trace(K),
315
+ 'frobenius_norm': np.linalg.norm(K, 'fro'),
316
+ 'eigenvalue_stats': {
317
+ 'mean': np.mean(eigenvalues),
318
+ 'std': np.std(eigenvalues),
319
+ 'min': np.min(eigenvalues),
320
+ 'max': np.max(eigenvalues),
321
+ },
322
+ 'is_positive_definite': np.all(eigenvalues > 0),
323
+ }
324
+
325
+ return analysis
326
+
327
+ def get_params(self, deep: bool = True) -> Dict[str, Any]:
328
+ """Get algorithm parameters."""
329
+ params = super().get_params(deep)
330
+ params.update({
331
+ 'feature_map': self.feature_map,
332
+ 'feature_map_reps': self.feature_map_reps,
333
+ 'C': self.C,
334
+ 'gamma': self.gamma,
335
+ 'normalize_data': self.normalize_data,
336
+ })
337
+ return params
338
+
339
+ def set_params(self, **params) -> 'QuantumSVM':
340
+ """Set algorithm parameters."""
341
+ if self.is_fitted and any(key in params for key in
342
+ ['feature_map', 'feature_map_reps', 'C', 'gamma']):
343
+ logger.warning("Changing core parameters requires refitting the model")
344
+ self.is_fitted = False
345
+
346
+ return super().set_params(**params)