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,447 @@
1
+ """Quantum Circuit representation and manipulation for SuperQuantX
2
+ """
3
+
4
+ import json
5
+ from copy import deepcopy
6
+ from typing import Any, Dict, List, Optional, Tuple, Union
7
+
8
+ from pydantic import BaseModel, Field
9
+
10
+
11
+ class QuantumGate(BaseModel):
12
+ """Represents a quantum gate operation
13
+ """
14
+
15
+ name: str = Field(..., description="Gate name (e.g., 'H', 'CNOT', 'RZ')")
16
+ qubits: List[int] = Field(..., description="Target qubit indices")
17
+ parameters: List[float] = Field(default_factory=list, description="Gate parameters")
18
+ classical_condition: Optional[Tuple[str, int]] = Field(
19
+ default=None,
20
+ description="Classical register condition (register_name, value)"
21
+ )
22
+
23
+ def to_dict(self) -> Dict[str, Any]:
24
+ """Convert gate to dictionary representation"""
25
+ return {
26
+ "name": self.name,
27
+ "qubits": self.qubits,
28
+ "parameters": self.parameters,
29
+ "classical_condition": self.classical_condition
30
+ }
31
+
32
+ @classmethod
33
+ def from_dict(cls, data: Dict[str, Any]) -> "QuantumGate":
34
+ """Create gate from dictionary representation"""
35
+ return cls(**data)
36
+
37
+ def __repr__(self) -> str:
38
+ params_str = f"({', '.join(map(str, self.parameters))})" if self.parameters else ""
39
+ qubits_str = f"q{', q'.join(map(str, self.qubits))}"
40
+ return f"{self.name}{params_str} {qubits_str}"
41
+
42
+
43
+ class ClassicalRegister(BaseModel):
44
+ """Represents a classical register for measurements"""
45
+
46
+ name: str = Field(..., description="Register name")
47
+ size: int = Field(..., description="Number of classical bits")
48
+
49
+ def __repr__(self) -> str:
50
+ return f"ClassicalRegister('{self.name}', {self.size})"
51
+
52
+
53
+ class QuantumRegister(BaseModel):
54
+ """Represents a quantum register"""
55
+
56
+ name: str = Field(..., description="Register name")
57
+ size: int = Field(..., description="Number of qubits")
58
+
59
+ def __repr__(self) -> str:
60
+ return f"QuantumRegister('{self.name}', {self.size})"
61
+
62
+
63
+ class QuantumCircuit:
64
+ """Quantum circuit representation with gate operations and measurements
65
+
66
+ This class provides a high-level interface for building and manipulating
67
+ quantum circuits compatible with multiple quantum computing frameworks.
68
+ """
69
+
70
+ def __init__(
71
+ self,
72
+ num_qubits: int,
73
+ num_classical_bits: Optional[int] = None,
74
+ name: Optional[str] = None
75
+ ):
76
+ """Initialize a quantum circuit
77
+
78
+ Args:
79
+ num_qubits: Number of qubits in the circuit
80
+ num_classical_bits: Number of classical bits (defaults to num_qubits)
81
+ name: Optional circuit name
82
+
83
+ """
84
+ self.num_qubits = num_qubits
85
+ self.num_classical_bits = num_classical_bits or num_qubits
86
+ self.name = name or f"circuit_{id(self)}"
87
+
88
+ self.quantum_registers: List[QuantumRegister] = [
89
+ QuantumRegister(name="q", size=num_qubits)
90
+ ]
91
+ self.classical_registers: List[ClassicalRegister] = [
92
+ ClassicalRegister(name="c", size=self.num_classical_bits)
93
+ ]
94
+
95
+ self.gates: List[QuantumGate] = []
96
+ self.measurements: List[Tuple[int, int]] = [] # (qubit_index, classical_bit_index)
97
+ self.barriers: List[List[int]] = [] # Barrier positions
98
+
99
+ def __len__(self) -> int:
100
+ """Return the number of gates in the circuit"""
101
+ return len(self.gates)
102
+
103
+ def __repr__(self) -> str:
104
+ return f"QuantumCircuit({self.num_qubits} qubits, {len(self.gates)} gates)"
105
+
106
+ def copy(self) -> "QuantumCircuit":
107
+ """Create a deep copy of the circuit"""
108
+ return deepcopy(self)
109
+
110
+ def add_register(self, register: Union[QuantumRegister, ClassicalRegister]) -> None:
111
+ """Add a quantum or classical register to the circuit"""
112
+ if isinstance(register, QuantumRegister):
113
+ self.quantum_registers.append(register)
114
+ self.num_qubits += register.size
115
+ elif isinstance(register, ClassicalRegister):
116
+ self.classical_registers.append(register)
117
+ self.num_classical_bits += register.size
118
+
119
+ # Single-qubit gates
120
+ def h(self, qubit: int) -> "QuantumCircuit":
121
+ """Apply Hadamard gate"""
122
+ self.gates.append(QuantumGate(name="H", qubits=[qubit]))
123
+ return self
124
+
125
+ def x(self, qubit: int) -> "QuantumCircuit":
126
+ """Apply Pauli-X gate"""
127
+ self.gates.append(QuantumGate(name="X", qubits=[qubit]))
128
+ return self
129
+
130
+ def y(self, qubit: int) -> "QuantumCircuit":
131
+ """Apply Pauli-Y gate"""
132
+ self.gates.append(QuantumGate(name="Y", qubits=[qubit]))
133
+ return self
134
+
135
+ def z(self, qubit: int) -> "QuantumCircuit":
136
+ """Apply Pauli-Z gate"""
137
+ self.gates.append(QuantumGate(name="Z", qubits=[qubit]))
138
+ return self
139
+
140
+ def s(self, qubit: int) -> "QuantumCircuit":
141
+ """Apply S gate (phase gate)"""
142
+ self.gates.append(QuantumGate(name="S", qubits=[qubit]))
143
+ return self
144
+
145
+ def sdg(self, qubit: int) -> "QuantumCircuit":
146
+ """Apply S† gate (inverse phase gate)"""
147
+ self.gates.append(QuantumGate(name="SDG", qubits=[qubit]))
148
+ return self
149
+
150
+ def t(self, qubit: int) -> "QuantumCircuit":
151
+ """Apply T gate"""
152
+ self.gates.append(QuantumGate(name="T", qubits=[qubit]))
153
+ return self
154
+
155
+ def tdg(self, qubit: int) -> "QuantumCircuit":
156
+ """Apply T† gate"""
157
+ self.gates.append(QuantumGate(name="TDG", qubits=[qubit]))
158
+ return self
159
+
160
+ def rx(self, theta: float, qubit: int) -> "QuantumCircuit":
161
+ """Apply rotation around X-axis"""
162
+ self.gates.append(QuantumGate(name="RX", qubits=[qubit], parameters=[theta]))
163
+ return self
164
+
165
+ def ry(self, theta: float, qubit: int) -> "QuantumCircuit":
166
+ """Apply rotation around Y-axis"""
167
+ self.gates.append(QuantumGate(name="RY", qubits=[qubit], parameters=[theta]))
168
+ return self
169
+
170
+ def rz(self, theta: float, qubit: int) -> "QuantumCircuit":
171
+ """Apply rotation around Z-axis"""
172
+ self.gates.append(QuantumGate(name="RZ", qubits=[qubit], parameters=[theta]))
173
+ return self
174
+
175
+ def u(self, theta: float, phi: float, lam: float, qubit: int) -> "QuantumCircuit":
176
+ """Apply general unitary gate U(θ,φ,λ)"""
177
+ self.gates.append(
178
+ QuantumGate(name="U", qubits=[qubit], parameters=[theta, phi, lam])
179
+ )
180
+ return self
181
+
182
+ # Two-qubit gates
183
+ def cx(self, control: int, target: int) -> "QuantumCircuit":
184
+ """Apply CNOT gate"""
185
+ self.gates.append(QuantumGate(name="CNOT", qubits=[control, target]))
186
+ return self
187
+
188
+ def cnot(self, control: int, target: int) -> "QuantumCircuit":
189
+ """Apply CNOT gate (alias for cx)"""
190
+ return self.cx(control, target)
191
+
192
+ def cy(self, control: int, target: int) -> "QuantumCircuit":
193
+ """Apply controlled-Y gate"""
194
+ self.gates.append(QuantumGate(name="CY", qubits=[control, target]))
195
+ return self
196
+
197
+ def cz(self, control: int, target: int) -> "QuantumCircuit":
198
+ """Apply controlled-Z gate"""
199
+ self.gates.append(QuantumGate(name="CZ", qubits=[control, target]))
200
+ return self
201
+
202
+ def swap(self, qubit1: int, qubit2: int) -> "QuantumCircuit":
203
+ """Apply SWAP gate"""
204
+ self.gates.append(QuantumGate(name="SWAP", qubits=[qubit1, qubit2]))
205
+ return self
206
+
207
+ def crx(self, theta: float, control: int, target: int) -> "QuantumCircuit":
208
+ """Apply controlled rotation around X-axis"""
209
+ self.gates.append(
210
+ QuantumGate(name="CRX", qubits=[control, target], parameters=[theta])
211
+ )
212
+ return self
213
+
214
+ def cry(self, theta: float, control: int, target: int) -> "QuantumCircuit":
215
+ """Apply controlled rotation around Y-axis"""
216
+ self.gates.append(
217
+ QuantumGate(name="CRY", qubits=[control, target], parameters=[theta])
218
+ )
219
+ return self
220
+
221
+ def crz(self, theta: float, control: int, target: int) -> "QuantumCircuit":
222
+ """Apply controlled rotation around Z-axis"""
223
+ self.gates.append(
224
+ QuantumGate(name="CRZ", qubits=[control, target], parameters=[theta])
225
+ )
226
+ return self
227
+
228
+ # Three-qubit gates
229
+ def ccx(self, control1: int, control2: int, target: int) -> "QuantumCircuit":
230
+ """Apply Toffoli (CCNOT) gate"""
231
+ self.gates.append(
232
+ QuantumGate(name="TOFFOLI", qubits=[control1, control2, target])
233
+ )
234
+ return self
235
+
236
+ def toffoli(self, control1: int, control2: int, target: int) -> "QuantumCircuit":
237
+ """Apply Toffoli gate (alias for ccx)"""
238
+ return self.ccx(control1, control2, target)
239
+
240
+ def cswap(self, control: int, target1: int, target2: int) -> "QuantumCircuit":
241
+ """Apply controlled SWAP (Fredkin) gate"""
242
+ self.gates.append(
243
+ QuantumGate(name="FREDKIN", qubits=[control, target1, target2])
244
+ )
245
+ return self
246
+
247
+ def fredkin(self, control: int, target1: int, target2: int) -> "QuantumCircuit":
248
+ """Apply Fredkin gate (alias for cswap)"""
249
+ return self.cswap(control, target1, target2)
250
+
251
+ # Measurement operations
252
+ def measure(self, qubit: int, classical_bit: int) -> "QuantumCircuit":
253
+ """Measure a qubit into a classical bit"""
254
+ self.measurements.append((qubit, classical_bit))
255
+ return self
256
+
257
+ def measure_all(self) -> "QuantumCircuit":
258
+ """Measure all qubits into classical bits"""
259
+ for i in range(min(self.num_qubits, self.num_classical_bits)):
260
+ self.measure(i, i)
261
+ return self
262
+
263
+ def barrier(self, qubits: Optional[List[int]] = None) -> "QuantumCircuit":
264
+ """Add a barrier (prevents gate reordering across barrier)"""
265
+ if qubits is None:
266
+ qubits = list(range(self.num_qubits))
267
+ self.barriers.append(qubits)
268
+ return self
269
+
270
+ # Circuit composition
271
+ def compose(self, other: "QuantumCircuit", qubits: Optional[List[int]] = None) -> "QuantumCircuit":
272
+ """Compose this circuit with another circuit
273
+
274
+ Args:
275
+ other: Circuit to compose with
276
+ qubits: Qubit mapping for the other circuit
277
+
278
+ Returns:
279
+ New composed circuit
280
+
281
+ """
282
+ if qubits is None:
283
+ qubits = list(range(other.num_qubits))
284
+
285
+ if len(qubits) != other.num_qubits:
286
+ raise ValueError("Qubit mapping must match other circuit size")
287
+
288
+ new_circuit = self.copy()
289
+
290
+ # Map gates from other circuit
291
+ for gate in other.gates:
292
+ mapped_qubits = [qubits[q] for q in gate.qubits]
293
+ new_gate = QuantumGate(
294
+ name=gate.name,
295
+ qubits=mapped_qubits,
296
+ parameters=gate.parameters,
297
+ classical_condition=gate.classical_condition
298
+ )
299
+ new_circuit.gates.append(new_gate)
300
+
301
+ # Map measurements
302
+ for qubit, cbit in other.measurements:
303
+ new_circuit.measurements.append((qubits[qubit], cbit))
304
+
305
+ return new_circuit
306
+
307
+ def inverse(self) -> "QuantumCircuit":
308
+ """Return the inverse (adjoint) of the circuit"""
309
+ inv_circuit = QuantumCircuit(self.num_qubits, self.num_classical_bits)
310
+
311
+ # Reverse gates and apply inverse
312
+ for gate in reversed(self.gates):
313
+ inv_gate = self._inverse_gate(gate)
314
+ inv_circuit.gates.append(inv_gate)
315
+
316
+ return inv_circuit
317
+
318
+ def _inverse_gate(self, gate: QuantumGate) -> QuantumGate:
319
+ """Get the inverse of a gate"""
320
+ inverse_map = {
321
+ "H": "H", "X": "X", "Y": "Y", "Z": "Z",
322
+ "S": "SDG", "SDG": "S", "T": "TDG", "TDG": "T",
323
+ "CNOT": "CNOT", "CZ": "CZ", "SWAP": "SWAP"
324
+ }
325
+
326
+ if gate.name in inverse_map:
327
+ return QuantumGate(
328
+ name=inverse_map[gate.name],
329
+ qubits=gate.qubits,
330
+ parameters=gate.parameters,
331
+ classical_condition=gate.classical_condition
332
+ )
333
+ elif gate.name in ["RX", "RY", "RZ", "CRX", "CRY", "CRZ"]:
334
+ # Rotation gates: negate the angle
335
+ inv_params = [-p for p in gate.parameters]
336
+ return QuantumGate(
337
+ name=gate.name,
338
+ qubits=gate.qubits,
339
+ parameters=inv_params,
340
+ classical_condition=gate.classical_condition
341
+ )
342
+ elif gate.name == "U":
343
+ # U(θ,φ,λ)† = U(-θ,-λ,-φ)
344
+ theta, phi, lam = gate.parameters
345
+ inv_params = [-theta, -lam, -phi]
346
+ return QuantumGate(
347
+ name=gate.name,
348
+ qubits=gate.qubits,
349
+ parameters=inv_params,
350
+ classical_condition=gate.classical_condition
351
+ )
352
+ else:
353
+ # For unknown gates, assume self-inverse
354
+ return gate
355
+
356
+ # Export functions
357
+ def to_dict(self) -> Dict[str, Any]:
358
+ """Convert circuit to dictionary representation"""
359
+ return {
360
+ "name": self.name,
361
+ "num_qubits": self.num_qubits,
362
+ "num_classical_bits": self.num_classical_bits,
363
+ "quantum_registers": [reg.dict() for reg in self.quantum_registers],
364
+ "classical_registers": [reg.dict() for reg in self.classical_registers],
365
+ "gates": [gate.to_dict() for gate in self.gates],
366
+ "measurements": self.measurements,
367
+ "barriers": self.barriers
368
+ }
369
+
370
+ def to_json(self, indent: int = 2) -> str:
371
+ """Convert circuit to JSON string"""
372
+ return json.dumps(self.to_dict(), indent=indent)
373
+
374
+ @classmethod
375
+ def from_dict(cls, data: Dict[str, Any]) -> "QuantumCircuit":
376
+ """Create circuit from dictionary representation"""
377
+ circuit = cls(
378
+ num_qubits=data["num_qubits"],
379
+ num_classical_bits=data["num_classical_bits"],
380
+ name=data.get("name")
381
+ )
382
+
383
+ circuit.quantum_registers = [
384
+ QuantumRegister(**reg) for reg in data.get("quantum_registers", [])
385
+ ]
386
+ circuit.classical_registers = [
387
+ ClassicalRegister(**reg) for reg in data.get("classical_registers", [])
388
+ ]
389
+ circuit.gates = [QuantumGate.from_dict(gate) for gate in data.get("gates", [])]
390
+ circuit.measurements = data.get("measurements", [])
391
+ circuit.barriers = data.get("barriers", [])
392
+
393
+ return circuit
394
+
395
+ @classmethod
396
+ def from_json(cls, json_str: str) -> "QuantumCircuit":
397
+ """Create circuit from JSON string"""
398
+ data = json.loads(json_str)
399
+ return cls.from_dict(data)
400
+
401
+ def draw(self, output: str = "text") -> str:
402
+ """Draw the circuit in text format
403
+
404
+ Args:
405
+ output: Output format ("text" only for now)
406
+
407
+ Returns:
408
+ String representation of the circuit
409
+
410
+ """
411
+ if output != "text":
412
+ raise NotImplementedError("Only text output is currently supported")
413
+
414
+ lines = []
415
+ for i in range(self.num_qubits):
416
+ line = f"q{i} |0⟩─"
417
+ lines.append(line)
418
+
419
+ for gate in self.gates:
420
+ max_qubit = max(gate.qubits)
421
+ gate_repr = gate.name
422
+
423
+ if len(gate.qubits) == 1:
424
+ # Single-qubit gate
425
+ qubit = gate.qubits[0]
426
+ lines[qubit] += f"─{gate_repr}─"
427
+ for i in range(self.num_qubits):
428
+ if i != qubit:
429
+ lines[i] += "─" * (len(gate_repr) + 2)
430
+ elif len(gate.qubits) == 2:
431
+ # Two-qubit gate
432
+ control, target = gate.qubits
433
+ for i in range(self.num_qubits):
434
+ if i == control:
435
+ lines[i] += "─●─"
436
+ elif i == target:
437
+ lines[i] += "─⊕─"
438
+ elif min(control, target) < i < max(control, target):
439
+ lines[i] += "─│─"
440
+ else:
441
+ lines[i] += "───"
442
+
443
+ # Add measurements
444
+ for qubit, cbit in self.measurements:
445
+ lines[qubit] += f"─M{cbit}"
446
+
447
+ return "\n".join(lines)
@@ -0,0 +1,28 @@
1
+ """SuperQuantX Command Line Interface.
2
+
3
+ This module provides a comprehensive CLI for SuperQuantX, enabling users
4
+ to run quantum machine learning algorithms, manage configurations,
5
+ and perform various quantum computing tasks from the command line.
6
+ """
7
+
8
+ from .commands import (
9
+ benchmark,
10
+ configure,
11
+ info,
12
+ list_algorithms,
13
+ list_backends,
14
+ run_algorithm,
15
+ )
16
+ from .main import create_app, main
17
+
18
+
19
+ __all__ = [
20
+ 'main',
21
+ 'create_app',
22
+ 'run_algorithm',
23
+ 'list_algorithms',
24
+ 'list_backends',
25
+ 'benchmark',
26
+ 'configure',
27
+ 'info'
28
+ ]