Перейти до основного вмісту

Побудова схем

Версії пакетів

Код на цій сторінці був розроблений з використанням наступних вимог. Ми рекомендуємо використовувати ці версії або новіші.

qiskit[all]~=2.3.0

Ця сторінка детальніше розглядає клас QuantumCircuit у Qiskit SDK, включаючи деякі більш просунуті методи, які ви можете використовувати для створення квантових схем.

Що таке квантова схема?

Проста квантова схема — це колекція кубітів та список інструкцій, які діють на ці кубіти. Для демонстрації наступна комірка створює нову схему з двома новими кубітами, а потім відображає атрибут qubits схеми, який є списком Qubits у порядку від найменш значущого біта q0q_0 до найбільш значущого біта qnq_n.

# 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")

Output of the previous code cell

Об'єкти інструкцій схеми можуть містити схеми "визначення", які описують інструкцію в термінах більш фундаментальних інструкцій. Наприклад, X-вентіль визначається як конкретний випадок U3-вентиля, більш загального однокубітного вентиля.

# Draw definition circuit of 0th instruction in `qc`
qc.data[0].operation.definition.draw("mpl")

Output of the previous code cell

Інструкції та схеми схожі тим, що обидва описують операції над бітами та кубітами, але вони мають різне призначення:

  • Інструкції розглядаються як фіксовані, і їхні методи зазвичай повертатимуть нові інструкції (без зміни оригінального об'єкта).
  • Схеми призначені для побудови впродовж багатьох рядків коду, і методи 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")

Output of the previous code cell

Щоб об'єднати дві схеми, використовуйте метод compose. Це приймає інший QuantumCircuit та необов'язковий список відображень кубітів.

примітка

Метод compose повертає нову схему та не змінює жодну схему, на яку він діє. Щоб змінити схему, на якій ви викликаєте метод compose, використовуйте аргумент inplace=True.

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")

Output of the previous code cell

Ви також можете захотіти скомпілювати схеми в інструкції, щоб тримати свої схеми організованими. Ви можете перетворити схему на інструкцію, використовуючи метод to_instruction, а потім додати це до іншої схеми, як і будь-яку іншу інструкцію. Схема, намальована в наступній комірці, функціонально еквівалентна схемі, намальованій у попередній комірці.

inst = qc_b.to_instruction()
qc_a.append(inst, [1, 3])
qc_a.draw("mpl")

Output of the previous code cell

Якщо ваша схема є унітарною, ви можете перетворити її на Gate, використовуючи метод to_gate. Об'єкти Gate є конкретними типами інструкцій, які мають деякі додаткові функції, такі як метод control, який додає квантове керування.

gate = qc_b.to_gate().control()
qc_a.append(gate, [0, 1, 3])
qc_a.draw("mpl")

Output of the previous code cell

Щоб побачити, що відбувається, ви можете використовувати метод decompose, щоб розгорнути кожну інструкцію в її визначення.

примітка

Метод decompose повертає нову схему та не змінює схему, на яку він діє.

qc_a.decompose().draw("mpl")

Output of the previous code cell

Вимірювання кубітів

Вимірювання використовуються для вибірки станів окремих кубітів та передачі результатів у класичний регістр. Зверніть увагу, що якщо ви подаєте схеми до примітиву Sampler, вимірювання є обов'язковими. Однак схеми, подані до примітиву Estimator, не повинні містити вимірювань.

Кубіти можна виміряти за допомогою трьох методів: measure, measure_all та measure_active. Щоб дізнатися, як візуалізувати виміряні результати, дивіться сторінку Візуалізація результатів.

  1. QuantumCircuit.measure : вимірює кожен кубіт у першому аргументі на класичний біт, заданий другим аргументом. Цей метод дозволяє повний контроль над тим, де зберігається результат вимірювання.

  2. QuantumCircuit.measure_all : не приймає аргументів і може використовуватися для квантових схем без попередньо визначених класичних бітів. Він створює класичні проводи та зберігає результати вимірювань у порядку. Наприклад, вимірювання кубіта qiq_i зберігається в cbit measimeas_i). Він також додає бар'єр перед вимірюванням.

  3. QuantumCircuit.measure_active : подібний до measure_all, але вимірює лише кубіти, які мають операції.

qc1 = QuantumCircuit(2, 2)
qc1.measure(0, 1)
qc1.draw("mpl", cregbundle=False)

Output of the previous code cell

qc2 = QuantumCircuit(2)
qc2.measure_all()
qc2.draw("mpl", cregbundle=False)

Output of the previous code cell

qc3 = QuantumCircuit(2)
qc3.x(1)
qc3.measure_active()
qc3.draw("mpl", cregbundle=False)

Output of the previous code cell

Параметризовані схеми

Багато близькочасових квантових алгоритмів включають виконання багатьох варіацій квантової схеми. Оскільки побудова та оптимізація великих схем може бути обчислювально дорогою, 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")

Output of the previous code cell

Наступна комірка створює багато варіацій цієї схеми та відображає одну з варіацій.

circuits = []
for value in range(100):
circuits.append(qc.assign_parameters({angle: value}))

circuits[0].draw("mpl")

Output of the previous code cell

Ви можете знайти список невизначених параметрів схеми в її атрибуті 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)
Забули назву методу? Спробуйте запитати Qiskit Code Assistant.

Наступні кроки

Рекомендації