Реалізація в Qiskit
У попередньому уроці ми вперше ознайомились з класами Statevector та Operator у Qiskit і використали їх для симуляції операцій та вимірювань на одиночних кубітах.
У цьому розділі ми використаємо ці класи для вивчення поведінки множинних кубітів.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
from qiskit import __version__
print(__version__)
2.1.1
Почнемо з імпорту класів Statevector та Operator, а також функції квадратного кореня з NumPy.
Надалі, як правило, ми будемо робити всі необхідні імпорти на початку кожного уроку.
from qiskit.quantum_info import Statevector, Operator
from numpy import sqrt
Тензорні добутки
Клас Statevector має метод tensor, що повертає тензорний добуток цього Statevector з іншим, переданим як аргумент.
Аргумент інтерпретується як правий тензорний множник.
Наприклад, нижче ми створюємо два вектори стану, що представляють та і використовуємо метод tensor для створення нового вектора
Зверни увагу, що ми використовуємо метод from_label для визначення станів та а не визначаємо їх самостійно.
zero = Statevector.from_label("0")
one = Statevector.from_label("1")
psi = zero.tensor(one)
display(psi.draw("latex"))
Інші допустимі мітки включають "+" та "-" для станів плюс і мінус, а також "r" та "l" (скорочення від "right" та "left" — "правий" та "лівий") для станів
Тут "+", "-" або "right" та "left" походять із контексту квантово-механічного спіну, в якому компонент спіну може вказувати вліво або вправо в експерименті; це не стосується крайнього правого або крайнього лівого кубіта в системах із множинними кубітами. Ось приклад тензорного добутку та
plus = Statevector.from_label("+")
minus_i = Statevector.from_label("l")
phi = plus.tensor(minus_i)
display(phi.draw("latex"))
Альтернативою є використання операції ^ для тензорних добутків, що природно дає ті самі результати.
display((plus ^ minus_i).draw("latex"))
Клас Operator також має метод tensor (а також метод from_label), як ми бачимо в наступних прикладах.
H = Operator.from_label("H")
Id = Operator.from_label("I")
X = Operator.from_label("X")
display(H.tensor(Id).draw("latex"))
display(H.tensor(Id).tensor(X).draw("latex"))
Знову ж таки, як і у випадку з векторами, операція ^ є еквівалентною.
display((H ^ Id ^ X).draw("latex"))
Складені стани можна еволюціонувати за допомогою складених операцій, як і очікується, — так само, як ми бачили для одиночних систем у попередньому уроці. Наприклад, наступний код обчислює стан для (вже визначеного вище).
display(phi.evolve(H ^ Id).draw("latex"))
Ось код, що визначає операцію та обчислює для Для ясності: це операція , в якій лівий кубіт є керуючим, а правий — цільовим. Результатом є стан Белла
CX = Operator([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])
psi = plus.tensor(zero)
display(psi.evolve(CX).draw("latex"))
Часткові вимірювання
У попередньому уроці ми використовували метод measure для симуляції вимірювання вектора квантового стану.
Цей метод повертає два елементи: симульований результат вимірювання та новий Statevector з урахуванням цього вимірювання.
За замовчуванням measure вимірює всі кубіти у векторі стану.
Натомість ми можемо передати список цілих чисел як аргумент, що призведе до вимірювання лише кубітів з відповідними індексами.
Щоб продемонструвати це, наведений нижче код створює стан
і вимірює кубіт з номером 0, який є крайнім правим кубітом. (Qiskit нумерує кубіти починаючи з 0, справа наліво. До цієї конвенції нумерації ми повернемося в наступному уроці.)
w = Statevector([0, 1, 1, 0, 1, 0, 0, 0] / sqrt(3))
display(w.draw("latex"))
result, state = w.measure([0])
print(f"Measured: {result}\nState after measurement:")
display(state.draw("latex"))
result, state = w.measure([0, 1])
print(f"Measured: {result}\nState after measurement:")
display(state.draw("latex"))
Measured: 0
State after measurement:
Measured: 00
State after measurement: