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,420 @@
1
+ """AWS Braket backend implementation for SuperQuantX.
2
+
3
+ This module provides integration with Amazon Braket for quantum computing
4
+ on AWS quantum hardware and simulators.
5
+ """
6
+
7
+ import logging
8
+ from typing import Any, Dict, List, Optional, Tuple, Union
9
+
10
+ import numpy as np
11
+
12
+ from .base_backend import BaseBackend
13
+
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+ # Try to import AWS Braket
18
+ try:
19
+ from braket.circuits import Circuit as BraketCircuit
20
+ from braket.circuits import Gate, Instruction
21
+ from braket.circuits.gates import *
22
+ from braket.devices import LocalSimulator
23
+ try:
24
+ from braket.aws import AwsDevice
25
+ AWS_AVAILABLE = True
26
+ except:
27
+ AWS_AVAILABLE = False
28
+ BRAKET_AVAILABLE = True
29
+ except ImportError:
30
+ BRAKET_AVAILABLE = False
31
+ AWS_AVAILABLE = False
32
+ BraketCircuit = None
33
+ LocalSimulator = None
34
+
35
+ class BraketBackend(BaseBackend):
36
+ """AWS Braket backend for quantum computing operations.
37
+
38
+ This backend provides access to AWS Braket's quantum devices including
39
+ local simulators, managed simulators, and QPU hardware from IonQ, Rigetti,
40
+ and other providers available on AWS.
41
+
42
+ Args:
43
+ device: Device name or ARN (e.g., 'local:braket/braket_sv', 'arn:aws:braket::device/qpu/ionq/ionQdevice')
44
+ shots: Number of measurement shots
45
+ aws_session: Optional AWS session for authentication
46
+ s3_folder: S3 bucket folder for results (required for hardware)
47
+ **kwargs: Additional device configuration
48
+
49
+ Example:
50
+ >>> # Local simulator
51
+ >>> backend = BraketBackend(device='local:braket/braket_sv')
52
+ >>>
53
+ >>> # AWS hardware (requires authentication)
54
+ >>> backend = BraketBackend(
55
+ ... device='arn:aws:braket::device/qpu/ionq/ionQdevice',
56
+ ... s3_folder=('my-bucket', 'quantum-results')
57
+ ... )
58
+
59
+ """
60
+
61
+ def __init__(
62
+ self,
63
+ device: str = 'local:braket/braket_sv',
64
+ shots: int = 1024,
65
+ aws_session = None,
66
+ s3_folder: Optional[Tuple[str, str]] = None,
67
+ **kwargs
68
+ ) -> None:
69
+ if not BRAKET_AVAILABLE:
70
+ raise ImportError(
71
+ "AWS Braket not available. Install with: pip install amazon-braket-sdk"
72
+ )
73
+
74
+ self.device_name = device
75
+ self.aws_session = aws_session
76
+ self.s3_folder = s3_folder
77
+ self._device = None
78
+
79
+ super().__init__(device=device, shots=shots, **kwargs)
80
+
81
+ def _initialize_backend(self) -> None:
82
+ """Initialize AWS Braket backend and device."""
83
+ try:
84
+ if self.device_name.startswith('local:'):
85
+ # Local simulator
86
+ simulator_name = self.device_name.split('local:')[1]
87
+ self._device = LocalSimulator(simulator_name)
88
+ logger.info(f"Initialized Braket local simulator: {simulator_name}")
89
+
90
+ elif self.device_name.startswith('arn:aws:braket'):
91
+ # AWS hardware/managed simulators
92
+ if not AWS_AVAILABLE:
93
+ raise ImportError("AWS Braket cloud access not available")
94
+
95
+ self._device = AwsDevice(
96
+ arn=self.device_name,
97
+ aws_session=self.aws_session
98
+ )
99
+ logger.info(f"Initialized AWS Braket device: {self.device_name}")
100
+
101
+ # Verify S3 folder for hardware
102
+ if 'qpu' in self.device_name.lower() and not self.s3_folder:
103
+ logger.warning("QPU devices typically require S3 folder for results")
104
+
105
+ else:
106
+ raise ValueError(f"Invalid device name: {self.device_name}")
107
+
108
+ self.capabilities = {
109
+ 'supports_measurements': True,
110
+ 'supports_parameterized_circuits': True,
111
+ 'supports_classical_control': False, # Limited support
112
+ 'max_qubits': self._get_max_qubits(),
113
+ 'native_gates': self._get_native_gates(),
114
+ }
115
+
116
+ except Exception as e:
117
+ logger.error(f"Failed to initialize Braket backend: {e}")
118
+ raise
119
+
120
+ def _get_max_qubits(self) -> int:
121
+ """Get maximum number of qubits for the device."""
122
+ if hasattr(self._device, 'properties'):
123
+ try:
124
+ return self._device.properties.paradigm.qubit_count
125
+ except:
126
+ pass
127
+ # Default estimates
128
+ if 'sv' in self.device_name:
129
+ return 34 # SV1 simulator
130
+ elif 'tn1' in self.device_name:
131
+ return 50 # TN1 tensor network
132
+ elif 'dm1' in self.device_name:
133
+ return 17 # DM1 density matrix
134
+ else:
135
+ return 30 # Conservative estimate for hardware
136
+
137
+ def _get_native_gates(self) -> List[str]:
138
+ """Get native gates supported by the device."""
139
+ # Common Braket gates
140
+ return [
141
+ 'i', 'x', 'y', 'z', 'h', 's', 'si', 't', 'ti',
142
+ 'rx', 'ry', 'rz', 'cnot', 'cz', 'cy', 'swap',
143
+ 'iswap', 'pswap', 'phaseshift', 'cphaseshift',
144
+ 'ccnot', 'cswap'
145
+ ]
146
+
147
+ # ========================================================================
148
+ # Core Circuit Operations
149
+ # ========================================================================
150
+
151
+ def create_circuit(self, n_qubits: int) -> BraketCircuit:
152
+ """Create a Braket quantum circuit."""
153
+ if n_qubits > self._get_max_qubits():
154
+ logger.warning(f"Requested {n_qubits} qubits exceeds device limit")
155
+
156
+ return BraketCircuit()
157
+
158
+ def add_gate(self, circuit: BraketCircuit, gate: str, qubits: Union[int, List[int]],
159
+ params: Optional[List[float]] = None) -> BraketCircuit:
160
+ """Add a quantum gate to the circuit."""
161
+ if isinstance(qubits, int):
162
+ qubits = [qubits]
163
+
164
+ params = params or []
165
+
166
+ # Map gate names to Braket gates
167
+ gate_mapping = {
168
+ 'i': I, 'x': X, 'y': Y, 'z': Z, 'h': H,
169
+ 's': S, 'sdg': Si, 't': T, 'tdg': Ti,
170
+ 'rx': RX, 'ry': RY, 'rz': RZ,
171
+ 'cnot': CNot, 'cx': CNot, 'cz': CZ, 'cy': CY,
172
+ 'swap': Swap, 'iswap': ISwap,
173
+ 'ccnot': CCNot, 'toffoli': CCNot,
174
+ 'cswap': CSwap, 'fredkin': CSwap
175
+ }
176
+
177
+ gate_lower = gate.lower()
178
+ if gate_lower not in gate_mapping:
179
+ raise ValueError(f"Gate '{gate}' not supported in Braket backend")
180
+
181
+ gate_class = gate_mapping[gate_lower]
182
+
183
+ try:
184
+ if len(params) == 0:
185
+ # Parameter-less gates
186
+ if len(qubits) == 1:
187
+ circuit.add_instruction(Instruction(gate_class(), qubits[0]))
188
+ elif len(qubits) == 2:
189
+ circuit.add_instruction(Instruction(gate_class(), qubits))
190
+ elif len(qubits) == 3:
191
+ circuit.add_instruction(Instruction(gate_class(), qubits))
192
+ else:
193
+ raise ValueError(f"Too many qubits for gate {gate}")
194
+
195
+ else:
196
+ # Parameterized gates
197
+ if gate_lower in ['rx', 'ry', 'rz']:
198
+ circuit.add_instruction(Instruction(gate_class(params[0]), qubits[0]))
199
+ elif gate_lower == 'phaseshift':
200
+ circuit.add_instruction(Instruction(PhaseShift(params[0]), qubits[0]))
201
+ elif gate_lower == 'cphaseshift':
202
+ circuit.add_instruction(Instruction(CPhaseShift(params[0]), qubits))
203
+ else:
204
+ raise ValueError(f"Parameters not supported for gate {gate}")
205
+
206
+ except Exception as e:
207
+ logger.error(f"Failed to add gate {gate} to circuit: {e}")
208
+ raise
209
+
210
+ return circuit
211
+
212
+ def add_measurement(self, circuit: BraketCircuit, qubits: Union[int, List[int]]) -> BraketCircuit:
213
+ """Add measurement instructions to specified qubits."""
214
+ if isinstance(qubits, int):
215
+ qubits = [qubits]
216
+
217
+ # Braket doesn't use explicit measurement instructions in circuits
218
+ # Measurements are handled during task submission
219
+ # Store measurement info for later use
220
+ if not hasattr(circuit, '_measurement_qubits'):
221
+ circuit._measurement_qubits = set()
222
+ circuit._measurement_qubits.update(qubits)
223
+
224
+ return circuit
225
+
226
+ def execute_circuit(self, circuit: BraketCircuit, shots: Optional[int] = None) -> Dict[str, Any]:
227
+ """Execute quantum circuit and return results."""
228
+ shots = shots or self.shots
229
+
230
+ try:
231
+ # Get measurement qubits (all qubits if not specified)
232
+ if hasattr(circuit, '_measurement_qubits'):
233
+ measure_qubits = sorted(circuit._measurement_qubits)
234
+ else:
235
+ # Measure all qubits that have gates applied
236
+ measure_qubits = list(range(circuit.qubit_count))
237
+
238
+ # Add measurement to circuit copy
239
+ measured_circuit = circuit.copy()
240
+ for qubit in measure_qubits:
241
+ measured_circuit.add_instruction(Instruction(Measure(), qubit))
242
+
243
+ # Execute task
244
+ if self.s3_folder and hasattr(self._device, 'run'):
245
+ # AWS device with S3 storage
246
+ task = self._device.run(measured_circuit, shots=shots, s3_destination_folder=self.s3_folder)
247
+ result = task.result()
248
+ else:
249
+ # Local simulator
250
+ task = self._device.run(measured_circuit, shots=shots)
251
+ result = task.result()
252
+
253
+ # Process measurement results
254
+ measurement_counts = result.measurement_counts
255
+
256
+ # Convert to standard format
257
+ counts = {}
258
+ for bitstring, count in measurement_counts.items():
259
+ counts[bitstring] = count
260
+
261
+ return {
262
+ 'counts': counts,
263
+ 'shots': shots,
264
+ 'success': True,
265
+ 'measurement_qubits': measure_qubits,
266
+ 'task_arn': getattr(task, 'id', 'local'),
267
+ 'device': self.device_name,
268
+ }
269
+
270
+ except Exception as e:
271
+ logger.error(f"Circuit execution failed: {e}")
272
+ return {
273
+ 'counts': {},
274
+ 'shots': shots,
275
+ 'success': False,
276
+ 'error': str(e),
277
+ 'device': self.device_name,
278
+ }
279
+
280
+ # ========================================================================
281
+ # Algorithm-Specific Operations
282
+ # ========================================================================
283
+
284
+ def create_parameterized_circuit(self, n_qubits: int, n_params: int) -> Tuple[BraketCircuit, List[str]]:
285
+ """Create a parameterized quantum circuit for variational algorithms."""
286
+ circuit = self.create_circuit(n_qubits)
287
+
288
+ # Create parameter names
289
+ param_names = [f"theta_{i}" for i in range(n_params)]
290
+
291
+ # Store parameter info
292
+ circuit._param_names = param_names
293
+ circuit._n_params = n_params
294
+
295
+ return circuit, param_names
296
+
297
+ def bind_parameters(self, circuit: BraketCircuit, param_values: Dict[str, float]) -> BraketCircuit:
298
+ """Bind parameter values to parameterized circuit."""
299
+ # Braket handles parameterization differently - would need custom implementation
300
+ # For now, create a new circuit with bound parameters
301
+ bound_circuit = circuit.copy()
302
+
303
+ # This is a simplified implementation
304
+ # In practice, you'd need to track parameterized gates and substitute values
305
+ logger.warning("Parameter binding in Braket backend is simplified")
306
+
307
+ return bound_circuit
308
+
309
+ def expectation_value(self, circuit: BraketCircuit, observable: Union[str, np.ndarray],
310
+ shots: Optional[int] = None) -> float:
311
+ """Calculate expectation value of observable."""
312
+ shots = shots or self.shots
313
+
314
+ try:
315
+ # Simple implementation for Pauli observables
316
+ if isinstance(observable, str):
317
+ if observable.upper() == 'Z':
318
+ # Measure in Z basis
319
+ result = self.execute_circuit(circuit, shots)
320
+ counts = result['counts']
321
+
322
+ # Calculate <Z> expectation
323
+ expectation = 0.0
324
+ total_counts = sum(counts.values())
325
+
326
+ for bitstring, count in counts.items():
327
+ # Z expectation: +1 for |0>, -1 for |1>
328
+ prob = count / total_counts
329
+ if bitstring == '0' or (len(bitstring) > 0 and bitstring[0] == '0'):
330
+ expectation += prob
331
+ else:
332
+ expectation -= prob
333
+
334
+ return expectation
335
+ else:
336
+ logger.warning(f"Observable {observable} not fully implemented")
337
+ return 0.0
338
+ else:
339
+ logger.warning("Matrix observables not implemented")
340
+ return 0.0
341
+
342
+ except Exception as e:
343
+ logger.error(f"Expectation value calculation failed: {e}")
344
+ return 0.0
345
+
346
+ # ========================================================================
347
+ # Backend Information
348
+ # ========================================================================
349
+
350
+ def get_backend_info(self) -> Dict[str, Any]:
351
+ """Get information about the Braket backend."""
352
+ info = {
353
+ 'backend_name': 'braket',
354
+ 'device': self.device_name,
355
+ 'provider': 'AWS Braket',
356
+ 'shots': self.shots,
357
+ 'capabilities': self.capabilities,
358
+ 'local_simulator': self.device_name.startswith('local:'),
359
+ }
360
+
361
+ if hasattr(self._device, 'properties'):
362
+ try:
363
+ props = self._device.properties
364
+ info.update({
365
+ 'device_type': getattr(props, 'deviceType', 'unknown'),
366
+ 'provider_name': getattr(props, 'providerName', 'AWS'),
367
+ 'max_qubits': getattr(props.paradigm, 'qubit_count', 'unknown') if hasattr(props, 'paradigm') else 'unknown',
368
+ })
369
+ except:
370
+ pass
371
+
372
+ return info
373
+
374
+ def get_version_info(self) -> Dict[str, str]:
375
+ """Get version information for Braket dependencies."""
376
+ import braket
377
+ return {
378
+ 'braket_sdk': getattr(braket, '__version__', 'unknown'),
379
+ 'backend_version': '1.0.0',
380
+ }
381
+
382
+ def is_available(self) -> bool:
383
+ """Check if the backend is available and properly configured."""
384
+ return BRAKET_AVAILABLE and self._device is not None
385
+
386
+ def get_circuit_info(self) -> Dict[str, Any]:
387
+ """Get information about circuit execution capabilities."""
388
+ return {
389
+ 'max_qubits': self._get_max_qubits(),
390
+ 'native_gates': self._get_native_gates(),
391
+ 'supports_mid_circuit_measurement': False,
392
+ 'supports_reset': False,
393
+ 'supports_conditional': False,
394
+ }
395
+
396
+ def _get_n_qubits(self, circuit: BraketCircuit) -> int:
397
+ """Get number of qubits in Braket circuit."""
398
+ return circuit.qubit_count
399
+
400
+ def get_statevector(self, circuit: BraketCircuit) -> np.ndarray:
401
+ """Get statevector from Braket circuit."""
402
+ try:
403
+ # Use local simulator for statevector
404
+ from braket.devices import LocalSimulator
405
+ sv_device = LocalSimulator("braket_sv")
406
+
407
+ # Execute without measurements for statevector
408
+ task = sv_device.run(circuit, shots=0)
409
+ result = task.result()
410
+
411
+ if hasattr(result, 'get_value_by_result_type'):
412
+ from braket.circuits.result_types import StateVector
413
+ return result.get_value_by_result_type(StateVector())
414
+ else:
415
+ logger.warning("Statevector not available")
416
+ return np.zeros(2**circuit.qubit_count, dtype=complex)
417
+
418
+ except Exception as e:
419
+ logger.error(f"Failed to get statevector: {e}")
420
+ return np.zeros(2**circuit.qubit_count, dtype=complex)