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.
- superquantx/__init__.py +321 -0
- superquantx/algorithms/__init__.py +55 -0
- superquantx/algorithms/base_algorithm.py +413 -0
- superquantx/algorithms/hybrid_classifier.py +628 -0
- superquantx/algorithms/qaoa.py +406 -0
- superquantx/algorithms/quantum_agents.py +1006 -0
- superquantx/algorithms/quantum_kmeans.py +575 -0
- superquantx/algorithms/quantum_nn.py +544 -0
- superquantx/algorithms/quantum_pca.py +499 -0
- superquantx/algorithms/quantum_svm.py +346 -0
- superquantx/algorithms/vqe.py +553 -0
- superquantx/algorithms.py +863 -0
- superquantx/backends/__init__.py +265 -0
- superquantx/backends/base_backend.py +321 -0
- superquantx/backends/braket_backend.py +420 -0
- superquantx/backends/cirq_backend.py +466 -0
- superquantx/backends/ocean_backend.py +491 -0
- superquantx/backends/pennylane_backend.py +419 -0
- superquantx/backends/qiskit_backend.py +451 -0
- superquantx/backends/simulator_backend.py +455 -0
- superquantx/backends/tket_backend.py +519 -0
- superquantx/circuits.py +447 -0
- superquantx/cli/__init__.py +28 -0
- superquantx/cli/commands.py +528 -0
- superquantx/cli/main.py +254 -0
- superquantx/client.py +298 -0
- superquantx/config.py +326 -0
- superquantx/exceptions.py +287 -0
- superquantx/gates.py +588 -0
- superquantx/logging_config.py +347 -0
- superquantx/measurements.py +702 -0
- superquantx/ml.py +936 -0
- superquantx/noise.py +760 -0
- superquantx/utils/__init__.py +83 -0
- superquantx/utils/benchmarking.py +523 -0
- superquantx/utils/classical_utils.py +575 -0
- superquantx/utils/feature_mapping.py +467 -0
- superquantx/utils/optimization.py +410 -0
- superquantx/utils/quantum_utils.py +456 -0
- superquantx/utils/visualization.py +654 -0
- superquantx/version.py +33 -0
- superquantx-0.1.0.dist-info/METADATA +365 -0
- superquantx-0.1.0.dist-info/RECORD +46 -0
- superquantx-0.1.0.dist-info/WHEEL +4 -0
- superquantx-0.1.0.dist-info/entry_points.txt +2 -0
- superquantx-0.1.0.dist-info/licenses/LICENSE +21 -0
superquantx/circuits.py
ADDED
@@ -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
|
+
]
|