0
# Circuit Construction
1
2
Qiskit's circuit construction framework provides the foundation for building quantum algorithms through quantum circuits, registers, and instructions. The framework supports parameterized circuits, control flow, and extensive gate libraries.
3
4
## Capabilities
5
6
### Quantum Circuit Creation
7
8
The `QuantumCircuit` class is the central object for building quantum algorithms, supporting gate operations, measurements, and circuit composition.
9
10
```python { .api }
11
class QuantumCircuit:
12
def __init__(self, *args, name: str = None, global_phase: float = 0):
13
"""
14
Create a quantum circuit.
15
16
Parameters:
17
- *args: QuantumRegister, ClassicalRegister, or int (number of qubits)
18
- name: Circuit name
19
- global_phase: Global phase of the circuit
20
"""
21
22
def add_register(self, register):
23
"""Add a quantum or classical register to the circuit."""
24
25
def compose(self, other, qubits=None, clbits=None, front=False):
26
"""Compose this circuit with another circuit or instruction."""
27
28
def copy(self, name=None):
29
"""Create a copy of the circuit."""
30
31
def reverse_ops(self):
32
"""Reverse the order of circuit operations."""
33
34
def inverse(self):
35
"""Return the inverse of the circuit."""
36
37
@property
38
def num_qubits(self) -> int:
39
"""Number of qubits in the circuit."""
40
41
@property
42
def num_clbits(self) -> int:
43
"""Number of classical bits in the circuit."""
44
45
@property
46
def depth(self) -> int:
47
"""Circuit depth (number of layers)."""
48
49
@property
50
def width(self) -> int:
51
"""Total circuit width (qubits + clbits)."""
52
```
53
54
### Register Management
55
56
Quantum and classical registers organize qubits and classical bits for circuit construction and measurement.
57
58
```python { .api }
59
class QuantumRegister:
60
def __init__(self, size: int, name: str = None):
61
"""
62
Create a quantum register.
63
64
Parameters:
65
- size: Number of qubits in the register
66
- name: Register name
67
"""
68
69
@property
70
def size(self) -> int:
71
"""Number of qubits in the register."""
72
73
def __getitem__(self, key) -> 'Qubit':
74
"""Access individual qubits by index."""
75
76
class ClassicalRegister:
77
def __init__(self, size: int, name: str = None):
78
"""
79
Create a classical register.
80
81
Parameters:
82
- size: Number of classical bits in the register
83
- name: Register name
84
"""
85
86
@property
87
def size(self) -> int:
88
"""Number of classical bits in the register."""
89
90
def __getitem__(self, key) -> 'Clbit':
91
"""Access individual classical bits by index."""
92
93
class AncillaRegister(QuantumRegister):
94
def __init__(self, size: int, name: str = None):
95
"""
96
Create an ancilla register for auxiliary qubits.
97
98
Parameters:
99
- size: Number of ancilla qubits
100
- name: Register name
101
"""
102
```
103
104
### Basic Quantum Operations
105
106
Fundamental quantum operations including gates, measurements, and control operations.
107
108
```python { .api }
109
# Gate operations (methods of QuantumCircuit)
110
def h(self, qubit):
111
"""Apply Hadamard gate to qubit."""
112
113
def x(self, qubit):
114
"""Apply Pauli-X gate to qubit."""
115
116
def y(self, qubit):
117
"""Apply Pauli-Y gate to qubit."""
118
119
def z(self, qubit):
120
"""Apply Pauli-Z gate to qubit."""
121
122
def s(self, qubit):
123
"""Apply S gate to qubit."""
124
125
def t(self, qubit):
126
"""Apply T gate to qubit."""
127
128
def rx(self, theta, qubit):
129
"""Apply rotation about X-axis."""
130
131
def ry(self, theta, qubit):
132
"""Apply rotation about Y-axis."""
133
134
def rz(self, phi, qubit):
135
"""Apply rotation about Z-axis."""
136
137
def cx(self, control_qubit, target_qubit):
138
"""Apply controlled-X (CNOT) gate."""
139
140
def cz(self, control_qubit, target_qubit):
141
"""Apply controlled-Z gate."""
142
143
def swap(self, qubit1, qubit2):
144
"""Apply SWAP gate between two qubits."""
145
146
def measure(self, qubit, clbit):
147
"""Measure qubit and store result in classical bit."""
148
149
def measure_all(self, add_bits=True):
150
"""Measure all qubits."""
151
152
def reset(self, qubit):
153
"""Reset qubit to |0⟩ state."""
154
155
def barrier(self, *qubits):
156
"""Add synchronization barrier."""
157
```
158
159
### Parameterized Circuits
160
161
Support for parameterized quantum circuits enabling variational algorithms and circuit families.
162
163
```python { .api }
164
class Parameter:
165
def __init__(self, name: str):
166
"""
167
Create a circuit parameter.
168
169
Parameters:
170
- name: Parameter name
171
"""
172
173
@property
174
def name(self) -> str:
175
"""Parameter name."""
176
177
class ParameterVector:
178
def __init__(self, name: str, length: int):
179
"""
180
Create a vector of parameters.
181
182
Parameters:
183
- name: Base name for parameters
184
- length: Number of parameters
185
"""
186
187
def __getitem__(self, key) -> Parameter:
188
"""Access individual parameters by index."""
189
190
@property
191
def params(self) -> List[Parameter]:
192
"""List of all parameters in vector."""
193
194
class ParameterExpression:
195
"""Mathematical expression involving parameters."""
196
197
def bind(self, parameter_values: Dict) -> float:
198
"""Bind parameter values to get numeric result."""
199
200
@property
201
def parameters(self) -> Set[Parameter]:
202
"""Set of parameters in the expression."""
203
204
# Circuit parameter methods
205
def assign_parameters(self, parameter_values: Dict, inplace=False):
206
"""Assign values to circuit parameters."""
207
208
def bind_parameters(self, parameter_values: Dict):
209
"""Bind parameter values (alias for assign_parameters)."""
210
211
@property
212
def parameters(self) -> Set[Parameter]:
213
"""Set of all parameters in the circuit."""
214
```
215
216
### Control Flow Operations
217
218
Quantum control flow including conditional operations, loops, and control transfer operations.
219
220
```python { .api }
221
from qiskit.circuit.controlflow import IfElseOp, WhileLoopOp, ForLoopOp, SwitchCaseOp, BreakLoopOp, ContinueLoopOp
222
223
class IfElseOp(ControlFlowOp):
224
def __init__(self, condition, true_body, false_body=None, label=None):
225
"""
226
Conditional operation: if-else statement.
227
228
Parameters:
229
- condition: Classical condition to test
230
- true_body: Circuit executed if condition is true
231
- false_body: Circuit executed if condition is false (optional)
232
- label: Optional operation label
233
"""
234
235
class WhileLoopOp(ControlFlowOp):
236
def __init__(self, condition, body, label=None):
237
"""
238
While loop operation.
239
240
Parameters:
241
- condition: Loop continuation condition
242
- body: Circuit executed in each loop iteration
243
- label: Optional operation label
244
"""
245
246
class ForLoopOp(ControlFlowOp):
247
def __init__(self, indexset, loop_parameter, body, label=None):
248
"""
249
For loop operation.
250
251
Parameters:
252
- indexset: Iterable of values to loop over
253
- loop_parameter: Loop variable parameter
254
- body: Circuit executed in each loop iteration
255
- label: Optional operation label
256
"""
257
258
class SwitchCaseOp(ControlFlowOp):
259
def __init__(self, target, cases, label=None):
260
"""
261
Switch-case operation.
262
263
Parameters:
264
- target: Value to switch on
265
- cases: Iterable of (case_value, circuit) pairs
266
- label: Optional operation label
267
"""
268
269
class BreakLoopOp(Instruction):
270
def __init__(self, num_qubits: int, num_clbits: int, label=None):
271
"""
272
Break out of the nearest containing loop.
273
274
Parameters:
275
- num_qubits: Number of qubits affected
276
- num_clbits: Number of classical bits affected
277
- label: Optional operation label
278
"""
279
280
class ContinueLoopOp(Instruction):
281
def __init__(self, num_qubits: int, num_clbits: int, label=None):
282
"""
283
Continue to next iteration of nearest containing loop.
284
285
Parameters:
286
- num_qubits: Number of qubits affected
287
- num_clbits: Number of classical bits affected
288
- label: Optional operation label
289
"""
290
291
# QuantumCircuit convenience methods
292
def if_test(self, condition, true_body, qubits=None, clbits=None, label=None):
293
"""Add if-else conditional operation to circuit."""
294
295
def while_loop(self, condition, body, qubits=None, clbits=None, label=None):
296
"""Add while loop operation to circuit."""
297
298
def for_loop(self, indexset, loop_parameter, body, qubits=None, clbits=None, label=None):
299
"""Add for loop operation to circuit."""
300
301
def switch(self, target, cases, qubits=None, clbits=None, label=None):
302
"""Add switch-case operation to circuit."""
303
```
304
305
### Real-time Classical Computation
306
307
Support for real-time classical expressions and variables that are evaluated during quantum circuit execution.
308
309
```python { .api }
310
from qiskit.circuit.classical import expr
311
from qiskit.circuit import Store
312
313
class Store(Instruction):
314
def __init__(self, lvalue, rvalue):
315
"""
316
Store classical expression result in a storage location.
317
318
Parameters:
319
- lvalue: Classical storage location (Var)
320
- rvalue: Classical expression to evaluate and store
321
"""
322
323
# Classical expression types
324
class expr.Var:
325
def __init__(self, name: str, type: 'Type'):
326
"""
327
Classical variable for real-time computation.
328
329
Parameters:
330
- name: Variable name
331
- type: Variable type (Bool, Uint8, etc.)
332
"""
333
334
class expr.Expr:
335
"""Base class for classical expressions."""
336
337
@property
338
def type(self) -> 'Type':
339
"""Type of the expression result."""
340
341
# Expression operations
342
def expr.bit_and(left: expr.Expr, right: expr.Expr) -> expr.Expr:
343
"""Bitwise AND of two expressions."""
344
345
def expr.bit_or(left: expr.Expr, right: expr.Expr) -> expr.Expr:
346
"""Bitwise OR of two expressions."""
347
348
def expr.bit_xor(left: expr.Expr, right: expr.Expr) -> expr.Expr:
349
"""Bitwise XOR of two expressions."""
350
351
def expr.bit_not(operand: expr.Expr) -> expr.Expr:
352
"""Bitwise NOT of expression."""
353
354
def expr.logic_and(left: expr.Expr, right: expr.Expr) -> expr.Expr:
355
"""Logical AND of two expressions."""
356
357
def expr.logic_or(left: expr.Expr, right: expr.Expr) -> expr.Expr:
358
"""Logical OR of two expressions."""
359
360
def expr.logic_not(operand: expr.Expr) -> expr.Expr:
361
"""Logical NOT of expression."""
362
363
def expr.equal(left: expr.Expr, right: expr.Expr) -> expr.Expr:
364
"""Equality comparison of two expressions."""
365
366
def expr.not_equal(left: expr.Expr, right: expr.Expr) -> expr.Expr:
367
"""Inequality comparison of two expressions."""
368
369
def expr.less(left: expr.Expr, right: expr.Expr) -> expr.Expr:
370
"""Less-than comparison of two expressions."""
371
372
# Classical types
373
class expr.Type:
374
"""Base class for classical types."""
375
376
class expr.Bool(expr.Type):
377
"""Boolean type for classical expressions."""
378
379
class expr.Uint8(expr.Type):
380
"""8-bit unsigned integer type."""
381
```
382
383
### Instruction Framework
384
385
Base classes for quantum instructions and gates enabling custom operation development.
386
387
```python { .api }
388
class Instruction:
389
def __init__(self, name: str, num_qubits: int, num_clbits: int, params: List):
390
"""
391
Base quantum instruction.
392
393
Parameters:
394
- name: Instruction name
395
- num_qubits: Number of qubits instruction acts on
396
- num_clbits: Number of classical bits instruction acts on
397
- params: Instruction parameters
398
"""
399
400
@property
401
def name(self) -> str:
402
"""Instruction name."""
403
404
@property
405
def num_qubits(self) -> int:
406
"""Number of qubits."""
407
408
@property
409
def num_clbits(self) -> int:
410
"""Number of classical bits."""
411
412
def copy(self):
413
"""Create a copy of the instruction."""
414
415
class Gate(Instruction):
416
def __init__(self, name: str, num_qubits: int, params: List):
417
"""
418
Base unitary gate.
419
420
Parameters:
421
- name: Gate name
422
- num_qubits: Number of qubits gate acts on
423
- params: Gate parameters
424
"""
425
426
def control(self, num_ctrl_qubits=1, label=None):
427
"""Create controlled version of gate."""
428
429
def inverse(self):
430
"""Return inverse of gate."""
431
432
def power(self, exponent):
433
"""Return gate raised to a power."""
434
435
class ControlledGate(Gate):
436
def __init__(self, name: str, num_qubits: int, params: List, num_ctrl_qubits: int):
437
"""
438
Controlled gate with multiple control qubits.
439
440
Parameters:
441
- name: Gate name
442
- num_qubits: Total number of qubits (including controls)
443
- params: Gate parameters
444
- num_ctrl_qubits: Number of control qubits
445
"""
446
447
@property
448
def num_ctrl_qubits(self) -> int:
449
"""Number of control qubits."""
450
```
451
452
### Circuit Analysis and Utilities
453
454
Tools for analyzing and manipulating quantum circuits.
455
456
```python { .api }
457
def count_ops(self) -> Dict[str, int]:
458
"""Count occurrences of each operation type."""
459
460
def decompose(self, gate=None):
461
"""Decompose circuit into more elementary operations."""
462
463
def qasm(self, formatted=False, filename=None):
464
"""Generate OpenQASM representation of circuit."""
465
466
def draw(self, output=None, **kwargs):
467
"""Draw the circuit."""
468
469
@property
470
def size(self) -> int:
471
"""Total number of operations in circuit."""
472
473
@property
474
def data(self) -> List:
475
"""List of circuit instructions."""
476
477
def remove_final_measurements(self, inplace=True):
478
"""Remove final measurement operations."""
479
480
def reverse_bits(self):
481
"""Reverse bit ordering in circuit."""
482
483
def tensor(self, other):
484
"""Tensor product with another circuit."""
485
```
486
487
### Usage Examples
488
489
```python
490
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, Parameter
491
import numpy as np
492
493
# Basic circuit construction
494
qreg = QuantumRegister(3, 'q')
495
creg = ClassicalRegister(3, 'c')
496
circuit = QuantumCircuit(qreg, creg)
497
498
# Add gates
499
circuit.h(qreg[0]) # Hadamard on first qubit
500
circuit.cx(qreg[0], qreg[1]) # CNOT gate
501
circuit.cx(qreg[1], qreg[2]) # Another CNOT
502
circuit.measure(qreg, creg) # Measure all qubits
503
504
# Parameterized circuit
505
theta = Parameter('θ')
506
param_circuit = QuantumCircuit(1)
507
param_circuit.ry(theta, 0)
508
509
# Bind parameter value
510
bound_circuit = param_circuit.assign_parameters({theta: np.pi/4})
511
512
# Circuit composition
513
bell_pair = QuantumCircuit(2)
514
bell_pair.h(0)
515
bell_pair.cx(0, 1)
516
517
larger_circuit = QuantumCircuit(4)
518
larger_circuit.compose(bell_pair, qubits=[0, 1])
519
larger_circuit.compose(bell_pair, qubits=[2, 3])
520
521
# Control flow example
522
condition_circuit = QuantumCircuit(2, 1)
523
condition_circuit.h(0)
524
condition_circuit.measure(0, 0)
525
526
# Apply X gate conditionally
527
with condition_circuit.if_test((0, 1)): # If measurement result is 1
528
condition_circuit.x(1)
529
```