Побудова схем
Package versions
Код на цій сторінці був розроблений з використанням наступних вимог. Ми рекомендуємо використовувати ці версії або новіші.
qiskit[all]~=2.4.0
Ця сторінка детальніше розглядає клас QuantumCircuit у Qiskit SDK, включаючи деякі більш просунуті методи, які ви можете використовувати для створення квантових схем.
Що таке квантова схема?
Проста квантова схема — це колекція кубітів та список інструкцій, які діють на ці кубіти. Для демонстрації наступна комірка створює нову схему з двома новими кубітами, а потім відображає атрибут qubits схеми, який є списком Qubits у порядку від найменш значущого біта до найбільш значущого біта .
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit
from qiskit import QuantumCircuit
qc = QuantumCircuit(2)
qc.qubits
[<Qubit register=(2, "q"), index=0>, <Qubit register=(2, "q"), index=1>]
Кілька об'єктів QuantumRegister та ClassicalRegister можна об'єднати для створення схеми. Кожен QuantumRegister та ClassicalRegister також може мати ім'я.
from qiskit.circuit import QuantumRegister, ClassicalRegister
qr1 = QuantumRegister(2, "qreg1") # Create a QuantumRegister with 2 qubits
qr2 = QuantumRegister(1, "qreg2") # Create a QuantumRegister with 1 qubit
cr1 = ClassicalRegister(3, "creg1") # Create a ClassicalRegister with 3 cbits
combined_circ = QuantumCircuit(
qr1, qr2, cr1
) # Create a quantum circuit with 2 QuantumRegisters and 1 ClassicalRegister
combined_circ.qubits
[<Qubit register=(2, "qreg1"), index=0>,
<Qubit register=(2, "qreg1"), index=1>,
<Qubit register=(1, "qreg2"), index=0>]
Ви можете знайти індекс та регістр кубіта, використовуючи метод find_bit схеми та його атрибути.
desired_qubit = qr2[0] # Qubit 0 of register 'qreg2'
print("Index:", combined_circ.find_bit(desired_qubit).index)
print("Register:", combined_circ.find_bit(desired_qubit).registers)
Index: 2
Register: [(QuantumRegister(1, 'qreg2'), 0)]
Додавання інструкції до схеми додає інструкцію до атрибуту data схеми. Наступний вивід комірки показує, що data є списком об'єктів CircuitInstruction, кожен з яких має атрибут operation та атрибут qubits.
qc.x(0) # Add X-gate to qubit 0
qc.data
[CircuitInstruction(operation=Instruction(name='x', num_qubits=1, num_clbits=0, params=[]), qubits=(<Qubit register=(2, "q"), index=0>,), clbits=())]
Найлегший спосіб переглянути цю інформацію — через метод draw, який повертає візуалізацію схеми. Дивіться Візуалізація схем для різних способів відображення квантових схем.
qc.draw("mpl")
Об'єкти інструкцій схеми можуть містити схеми "визначення", які описують інструкцію в термінах більш фундаментальних інструкцій. Наприклад, X-вентіль визначається як конкретний випадок U3-вентиля, більш загального однокубітного вентиля.
# Draw definition circuit of 0th instruction in `qc`
qc.data[0].operation.definition.draw("mpl")
Інструкції та схеми схожі тим, що обидва описують операції над бітами та кубітами, але вони мають різне призначення:
- Інструкції розглядаються як фіксовані, і їхні методи зазвичай повертатимуть нові інструкції (без зміни оригінального об'єкта).
- Схеми призначені для побудови впродовж багатьох рядків коду, і методи
QuantumCircuitчасто змінюють існуючий об'єкт.
Що таке глибина схеми?
Глибина() квантової схеми є мірою кількості "шарів" квантових вентилів, виконаних паралельно, які потрібні для завершення обчислення, визначеного схемою. Оскільки квантові вентилі потребують часу для реалізації, глибина схеми приблизно відповідає кількості часу, який потрібен квантовому комп'ютеру для виконання схеми. Таким чином, глибина схеми є однією важливою величиною, яка використовується для вимірювання того, чи можна запустити квантову схему на пристрої.
Решта цієї сторінки ілюструє, як маніпулювати квантовими схемами.
Побудова схем
Методи, такі як QuantumCircuit.h та QuantumCircuit.cx, додають конкретні інструкції до схем. Щоб додавати інструкції до схеми більш загально, використовуйте метод append. Це приймає інструкцію та список кубітів, до яких слід застосувати інструкцію. Дивіться документацію API бібліотеки схем для списку підтримуваних інструкцій.
from qiskit.circuit.library import HGate
qc = QuantumCircuit(1)
qc.append(
HGate(), # New HGate instruction
[0], # Apply to qubit 0
)
qc.draw("mpl")
Щоб об'єднати дві схеми, використовуйте метод compose. Це приймає інший QuantumCircuit та необов'язковий список відображень кубітів.
qc_a = QuantumCircuit(4)
qc_a.x(0)
qc_b = QuantumCircuit(2, name="qc_b")
qc_b.y(0)
qc_b.z(1)
# compose qubits (0, 1) of qc_a to qubits (1, 3) of qc_b respectively
combined = qc_a.compose(qc_b, qubits=[1, 3])
combined.draw("mpl")
Ви також можете захотіти скомпілювати схеми в інструкції, щоб тримати свої схеми організованими. Ви можете перетворити схему на інструкцію, використовуючи метод to_instruction, а потім додати це до іншої схеми, як і будь-яку іншу інструкцію. Схема, намальована в наступній комірці, функціонально еквівалентна схемі, намальованій у попередній комірці.
inst = qc_b.to_instruction()
qc_a.append(inst, [1, 3])
qc_a.draw("mpl")
Якщо ваша схема є унітарною, ви можете перетворити її на Gate, використовуючи метод to_gate. Об'єкти Gate є конкретними типами інструкцій, які мають деякі додаткові функції, такі як метод control, який додає квантове керування.
gate = qc_b.to_gate().control()
qc_a.append(gate, [0, 1, 3])
qc_a.draw("mpl")
Щоб побачити, що відбувається, ви можете використовувати метод decompose, щоб розгорнути кожну інструкцію в її визначення.
Метод decompose повертає нову схему та не змінює схему, на яку він діє.
qc_a.decompose().draw("mpl")
Вимірювання кубітів
Вимірювання використовуються для вибірки станів окремих кубітів та передачі результатів у класичний регістр. Зверніть увагу, що якщо ти подаєш схеми до примітиву Sampler, вимірювання є обов'язковими. Однак схеми, подані до примітиву Estimator, не повинні містити вимірювань.
Кубіти можна виміряти за допомогою трьох мет одів: measure, measure_all та measure_active. Щоб дізнатися, як візуалізувати виміряні результати, дивіться сторінку Візуалізація результатів.
-
QuantumCircuit.measure: вимірює кожен кубіт у першому аргументі на класичний біт, заданий другим аргументом. Цей метод дозволяє повний контроль над тим, де зберігається результат вимірювання. -
QuantumCircuit.measure_all: не приймає аргументів і може використовуватися для квантових схем без попередньо визначених класичних бітів. Він створює класичні проводи та зберігає результати вимірювань у порядку. Наприклад, вимірювання кубіта зберігається в cbit ). Він також додає бар'єр перед вимірюванням. -
QuantumCircuit.measure_active: подібний доmeasure_all, але вимірює лише кубіти, які мають операції.
qc1 = QuantumCircuit(2, 2)
qc1.measure(0, 1)
qc1.draw("mpl", cregbundle=False)
qc2 = QuantumCircuit(2)
qc2.measure_all()
qc2.draw("mpl", cregbundle=False)
qc3 = QuantumCircuit(2)
qc3.x(1)
qc3.measure_active()
qc3.draw("mpl", cregbundle=False)
Параметризовані схеми
Багато близькочасових квантових алгоритмів включають виконання багатьох варіацій квантової схеми. Оскільки побудова та оптимізація великих схем може бути обчислювально дорогою, Qiskit підтримує параметризовані схеми. Ці схеми мають невизначені параметри, і їхні значення не потрібно визначати до моменту безпосередньо перед виконанням схеми. Це дозволяє вам винести побудову та оптимізацію схеми з основного циклу програми. Наступна комірка створює та відображає параметризовану схему.
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.circuit import Parameter
angle = Parameter("angle") # undefined number
# Create and optimize circuit once
qc = QuantumCircuit(1)
qc.rx(angle, 0)
qc = generate_preset_pass_manager(
optimization_level=3, basis_gates=["u", "cx"]
).run(qc)
qc.draw("mpl")
Наступна комірка створює багато варіацій цієї схеми та відображає одну з варіацій.
circuits = []
for value in range(100):
circuits.append(qc.assign_parameters({angle: value}))
circuits[0].draw("mpl")
Ви можете знайти список невизначених параметрів схеми в її атрибуті parameters.
qc.parameters
ParameterView([Parameter(angle)])
Зміна імені параметра
За замовчуванням імена параметрів для параметризованої схеми мають префікс x — наприклад, x[0]. Ви можете змінити імена після їх визначення, як показано в наступному прикладі.
from qiskit.circuit.library import z_feature_map
from qiskit.circuit import ParameterVector
# Define a parameterized circuit with default names
# For example, x[0]
circuit = z_feature_map(2)
# Set new parameter names
# They will now be prefixed by `hi` instead
# For example, hi[0]
training_params = ParameterVector("hi", 2)
# Assign parameter names to the quantum circuit
circuit = circuit.assign_parameters(parameters=training_params)
Наступні кроки
- Щоб дізнатися про близькочасові квантові алгоритми, пройдіть курс Проектування варіаційних алгоритмів.
- Подивіться приклад використання схем у підручнику Алгоритм Гровера.
- Працюйте з простими схемами, використовуючи IBM Quantum Composer.