Синтез унітарних операцій
Версії пакетів
Код на цій сторінці розроблено з використанням наведених нижче залежностей. Рекомендуємо використовувати ці або новіші версії.
qiskit[all]~=2.4.0
Унітарна операція описує норм-зберігальну зміну квантової системи. Для кубітів ця зміна описується матрицею розміром — комплексною матрицею , спряжена якої дорівнює оберненій, тобто .
Синтез конкретних унітарних операцій у набір квантових вентилів є фундаментальним завданням, що використовується, наприклад, при проектуванні та застосуванні квантових алгоритмів або при компіляції квантових схем.
Хоча ефективний синтез можливий для певних класів унітарних операцій — наприклад, тих, що складаються з вентилів Кліффорда або мають тензорно-добуткову структуру — більшість унітарних операцій не потрапляють до цих категорій. Для загальних унітарних матриць синтез є складним завданням, обчислювальна вартість якого зростає експоненційно з кількістю кубітів. Тому, якщо ти знаєш ефективне розкладення для унітарної операції, яку хочеш реалізувати, воно, скоріш за все, буде кращим за загальний синтез.
Якщо жодного розкладення недоступно, Qiskit SDK надає тобі інструменти для його знаходження. Однак зауваж, що це, як правило, генерує глибокі схеми, які можуть бути непридатними для запуску на шумних квантових комп'ютерах.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
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 0x7f5ec46183d0>
Повторний синтез для оптимізації схеми
Іноді корисно повторно синтезувати довгу послідовність однокубітних і двокубітних вентилів, якщо вдається скоротити її довжину. Наприклад, наступна схема використовує три двокубітні вентилі.
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: 6.2071
┌───────────────┐ ┌────────────────┐
q_0: ─┤ U(π/2,π/2,-π) ├────■────┤ U(π/2,-π,-π/2) ├─
┌┴───────────────┴─┐┌─┴─┐┌─┴────────────────┴┐
q_1: ┤ U(1.7229,π/2,-π) ├┤ X ├┤ U(π/2,0.15207,-π) ├
└──────────────────┘└───┘└───────────────────┘
Функція transpile у Qiskit автоматично виконує цей повторний синтез при достатньо високому рівні оптимізації.
Наступні кроки
- Переглянь приклад розкладення схеми у навчальному посібнику Алгоритм Гровера.
- Для отримання додаткової інформації про транспілятор Qiskit відвідай розділ Транспіляція.