Синтез унітарних операцій
Версії пакетів
Код на цій сторінці розроблено з використанням наведених нижче залежностей. Рекомендуємо використовувати ці або новіші версії.
qiskit[all]~=2.5.2
Унітарна операція описує зміну квантової системи, що зберігає норму. Для кубітів ця зміна описується матрицею розміром — комплексною матрицею , ермітово спряжена матриця якої дорівнює оберненій, тобто .
Синтез конкретних унітарних операцій у набір квантових вентилів є фундаментальним завданням, що використовується, наприклад, при проектуванні та застосуванні квантових алгоритмів або при компіляції квантових схем.
Хоча ефективний синтез можливий для певних класів унітарних операцій — наприклад, тих, що складаються з вентилів Кліффорда або мають тензорно-добуткову структуру — більшість унітарних операцій не потрапляють до цих категорій. Для загальних унітарних матриць синтез є складним завданням, обчислювальна вартість якого зростає експоненційно з кількістю кубітів. Тому, якщо ти знаєш ефективне розкладення для унітарної операції, яку хочеш реалізувати, воно, скоріш за все, буде кращим за загальний синтез.
Якщо розкладення невідоме, Qiskit SDK надає тобі інструменти для його знаходження. Однак зауваж, що це, як правило, генерує глибокі схеми, які можуть бути непридатними для запуску на шумних квантових комп'ютерах.
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"numpy": "numpy", "qiskit": "qiskit"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
import numpy as np
from qiskit import QuantumCircuit
U = 0.5 * np.array(
[[1, 1, 1, 1], [-1, 1, -1, 1], [-1, -1, 1, 1], [-1, 1, 1, -1]]
)
circuit = QuantumCircuit(2)
circuit.unitary(U, circuit.qubits)
<qiskit.circuit.instructionset.InstructionSet at 0x7fe21013b1f0>
Повторний синтез для оптимізації схеми
Іноді корисно повторно синтезувати довгу послідовність однокубітних і двокубітних вентилів, якщо вдається скоротити її довжину. Наприклад, наступна схема використовує три двокубітні вентилі.
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
qreg_q = QuantumRegister(2, "q")
creg_c = ClassicalRegister(4, "c")
circuit = QuantumCircuit(qreg_q, creg_c)
circuit.h(qreg_q[0])
circuit.cx(qreg_q[0], qreg_q[1])
circuit.sx(qreg_q[1])
circuit.cz(qreg_q[0], qreg_q[1])
circuit.x(qreg_q[1])
circuit.x(qreg_q[0])
circuit.cx(qreg_q[0], qreg_q[1])
circuit.h(qreg_q[0])
circuit.draw("mpl")
Однак після повторного синтезу за допомогою наступного коду знадобиться лише один вентиль CX. (Тут ми використовуємо метод QuantumCircuit.decompose() для кращої візуалізації вентилів, що використовуються при повторному синтезі унітарної операції.)
from qiskit.quantum_info import Operator
# compute unitary matrix of circuit
U = Operator(circuit)
# re-synthesize
better_circuit = QuantumCircuit(2)
better_circuit.unitary(U, range(2))
better_circuit.decompose().draw()
global phase: 15π/8
┌───────────────┐ ┌────────────────┐
q_0: ┤ U(π/2,π/2,-π) ├───■──┤ U(π/2,-π,-π/2) ├
├───────────────┴┐┌─┴─┐├───────────────┬┘
q_1: ┤ U(3π/4,π/2,-π) ├┤ X ├┤ U(π/2,π/4,-π) ├─
└────────────────┘└───┘└───────────────┘
Функція transpile у Qiskit автоматично виконує цей повторний синтез при достатньо високому рівні оптимізації.
Наступні кроки
- Переглянь приклад розкладення схеми у навчальному посібнику Алгоритм Гровера.
- Для отримання додаткової інформації про транспілятор Qiskit відвідай розділ Транспіляція.