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

Дослідження невизначеності

Для цього модуля Qiskit у навчальних закладах студенти повинні мати налаштоване середовище Python із такими встановленими пакетами:

  • qiskit v2.1.0 або новіше
  • qiskit-ibm-runtime v0.40.1 або новіше
  • qiskit-aer v0.17.0 або новіше
  • qiskit.visualization
  • numpy
  • pylatexenc

Щоб налаштувати та встановити пакети вище, дивись посібник Встановлення Qiskit. Для запуску задач на реальних квантових комп'ютерах студентам потрібно зареєструватися на IBM Quantum®, дотримуючись кроків у посібнику Налаштування облікового запису IBM Cloud.

Цей модуль було протестовано і він використав 8 хвилин часу QPU. Це лише орієнтовна оцінка. Твоє фактичне використання може відрізнятися. Два тривалих обчислення позначені відповідним чином у заголовних коментарях і можуть виконуватись на симуляторах, якщо студентам бракує часу QPU. Без них модуль потребує лише ~30 секунд часу QPU.

# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-aer qiskit-ibm-runtime
# Uncomment and modify this line as needed to install dependencies
#!pip install 'qiskit>=2.1.0' 'qiskit-ibm-runtime>=0.40.1' 'qiskit-aer>=0.17.0' 'numpy' 'pylatexenc'

Перегляньте огляд модуля від Dr. Katie McCormick нижче або натисни тут, щоб переглянути на YouTube.


Вступ

Ти, напевно, чув про принцип невизначеності, навіть поза межами курсів з фізики. Поширене просторічне формулювання невизначеності звучить так: «Спостерігаючи за чимось, ти на нього впливаєш.» Це безумовно правда. Але більш фізичне описання невизначеності полягає в тому, що існують певні фізичні спостережувані величини, між якими є несумісність, що не дозволяє одночасно знати обидві з довільною точністю. Багато студентів уперше стикаються з парою несумісних змінних xx і pxp_x — координатою вздовж осі xx та лінійним імпульсом у тому самому напрямку відповідно. Для цих змінних обмеження на невизначеність записується як ΔxΔpx2.\Delta x \Delta p_x \geq \frac{\hbar}{2}. Тут Δx\Delta x називається «невизначеністю xx» і має те саме визначення, що й стандартне відхилення в статистиці, а саме: Δx=x2x2.\Delta x = \sqrt{\langle x^2 \rangle - \langle x \rangle^2}. Δpx\Delta p_x визначається аналогічно. Тут ми не будемо виводити це співвідношення невизначеності — лише вкажемо, що воно узгоджується з нашим розумінням класичних хвиль. Тобто хвиля з єдиною ідеальною частотою ff і довжиною хвилі λ\lambda тягнулася б нескінченно як ідеальний синусоїд. У квантовій механіці це відповідає точному знанню імпульсу згідно з гіпотезою де Бройля: λ=h/p\lambda = h/p. Але щоб знати, деде знаходиться хвилеподібна частинка, хвиля, що її описує, повинна стати більш різко зосередженою в просторі — наприклад, як дуже вузький гаусіан. Ми знаємо, що будь-яку неперервну функцію, включно з такими різко зосередженими хвильовими функціями, можна виразити у вигляді ряду Фур'є синусоїдів із різними довжинами хвиль. Але чим різкішою стає хвильова функція (і чим точніше відоме положення), тим більше доданків потрібно у ряді Фур'є, тобто суміш більшої кількості довжин хвиль (а отже, квантово-механічно — більшої кількості значень імпульсу).

Якщо спростити: стан із добре визначеним імпульсом (ідеальний синусоїд у просторі) має дуже невизначене положення. Стан із добре визначеним положенням (як розподіл Дірака-дельта) має дуже невизначений імпульс.

Є й інші змінні, між якими спостерігається така несумісність. Наприклад, проєкція спіну частинки може бути добре визначена вздовж однієї осі, але тоді ми нічого не знаємо про проєкцію на перпендикулярну вісь. Наприклад, стан 0|0\rangle \sim |\uparrow\rangle (для кубіта або частинки зі спіном 1/2) має визначену проєкцію вздовж осі zz (рівну 1 у контексті кубіта і /2\hbar/2 у контексті частинки зі спіном 1/2). Але цей стан можна записати як суперпозицію двох станів, кожен із яких має добре визначену проєкцію на вісь xx: 0=12(+x+x)|0\rangle = \frac{1}{\sqrt{2}}(|+\rangle_x+|-\rangle_x) або еквівалентно (10)=12[12(11)+12(11)].\begin{pmatrix} 1 \\ 0\end{pmatrix} = \frac{1}{\sqrt{2}}\left[\frac{1}{\sqrt{2}}\begin{pmatrix} 1 \\ 1\end{pmatrix}+\frac{1}{\sqrt{2}}\begin{pmatrix} 1 \\ -1\end{pmatrix}\right]. +x|+\rangle_x має добре визначену проєкцію на xx, як і x|-\rangle_x. Тож якщо ми задаємо проєкцію стану вздовж осі xx, ми не знаємо проєкцію вздовж осі zz. І якщо ми задаємо проєкцію на вісь zz, ми не знаємо проєкцію вздовж xx. Є невеликі відмінності у трактуванні цього в контексті спіну та кубітів. Але загалом власні стани матриць Паулі мають цікаві взаємозв'язки, які ми можемо дослідити. Протягом цього уроку ми будемо експериментально перевіряти нашу інтуїцію щодо невизначеності цих несумісних змінних і верифікувати, що співвідношення невизначеності виконуються на квантових комп'ютерах IBM®.

Простий тест інтуїції

У цьому першому експерименті й протягом усього модуля ми будемо використовувати фреймворк для квантових обчислень під назвою «Qiskit патерни», який розбиває робочі процеси на такі кроки:

  • Крок 1: Відображення класичних вхідних даних на квантову задачу
  • Крок 2: Оптимізація задачі для квантового виконання
  • Крок 3: Виконання за допомогою Qiskit Runtime Primitives
  • Крок 4: Постобробка та класичний аналіз

Зазвичай ми дотримуємося цих кроків, хоча не завжди явно їх позначаємо.

Розпочнімо з завантаження необхідних пакетів, зокрема Runtime примітивів. Також виберемо найменш завантажений доступний квантовий комп'ютер.

Нижче наведено код для збереження твоїх облікових даних під час першого використання. Обов'язково видали цю інформацію з ноутбука після збереження в середовище, щоб облікові дані випадково не потрапили до інших, коли ти ділишся ноутбуком. Докладніше дивись у Налаштування облікового запису IBM Cloud та Ініціалізація сервісу в ненадійному середовищі.

from numpy import pi

# Load the Qiskit Runtime service
from qiskit_ibm_runtime import QiskitRuntimeService

# Syntax for first saving your token. Delete these lines after saving your credentials.
# QiskitRuntimeService.save_account(channel='ibm_quantum_platform', instance = '<YOUR_IBM_INSTANCE_CRN>', token='<YOUR-API_KEY>', overwrite=True, set_as_default=True)
# service = QiskitRuntimeService(channel='ibm_quantum_platform')

# Load saved credentials
service = QiskitRuntimeService()
# Load the Runtime primitive and session
from qiskit_ibm_runtime import (
Batch,
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
)

# Use the least busy backend
backend = service.least_busy(min_num_qubits=127)
print(backend.name)
ibm_sherbrooke

Якщо студент вичерпає доступний час квантових обчислень під час уроку, рядки нижче можна розкоментувати й використати для налаштування симулятора, який частково імітує шумову поведінку обраного вище квантового комп'ютера.

# Import an estimator, this time from qiskit (we will import from Runtime for real hardware)
from qiskit_aer.primitives import SamplerV2, EstimatorV2
from qiskit_aer.noise import NoiseModel

# Generate the noise model from the backend properties
noise_model = NoiseModel.from_backend(backend)

noisy_sampler = SamplerV2(options={"backend_options": {"noise_model": noise_model}})
noisy_estimator = EstimatorV2(options={"backend_options": {"noise_model": noise_model}})

Ти, напевно, пам'ятаєш, що власний стан одного оператора, Z, не є власним станом іншого оператора X. Ми спостерігатимемо це зараз експериментально, виконуючи вимірювання вздовж осей xx і zz. Для вимірювання вздовж zz ми просто використовуємо qc.measure(), оскільки квантові комп'ютери IBM побудовані так, що вимірюють вздовж zz. Але для вимірювання вздовж xx нам потрібно повернути систему, щоб фактично перемістити вісь xx до орієнтації, вздовж якої виконується вимірювання. Це досягається за допомогою Gate Адамара. Для вимірювань вздовж yy потрібен аналогічний крок. Необхідні кроки зібрані тут для зручності:

  • Для вимірювання вздовж zz: qc.measure()
  • Для вимірювання вздовж xx: qc.h(), потім qc.measure()
  • Для вимірювання вздовж yy: qc.sdg(), qc.h(), qc.s, потім qc.measure()

Крок 1: Відображення класичних вхідних даних на квантову задачу

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

# Step 1: Map

# Import some general packages
from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister

# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(2, "c")
qc = QuantumCircuit(qr, cr)

# Add a first measurement
qc.measure(qr, cr[0])
qc.barrier()

# Change basis so that measurements made on quantum computer which normally tell us about z, now tell us about x.
qc.h(qr)

# Add a second measurement
qc.measure(qr, cr[1])

qc.draw("mpl")

Output of the previous code cell

Крок 2: Оптимізація задачі для квантового виконання

Цей крок бере операції, які ми хочемо виконати, і виражає їх у термінах функціональності конкретного квантового комп'ютера. Також він відображає нашу задачу на топологію квантового комп'ютера.

# Step 2: Transpile
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)

qc_isa = pm.run(qc)

Крок 3: Виконання за допомогою Qiskit Runtime Primitives

Ми можемо використати Sampler для збору статистики вимірювань. Побудуємо примітив Sampler для запуску на реальному квантовому комп'ютері за допомогою mode = backend. Існують інші режими для інших робочих процесів, і один із них ми використаємо нижче. Sampler викликається методом run() зі списком «публів» (Primitive Unified Blocs). Кожен публ містить до трьох значень, які разом визначають обчислювальну одиницю роботи для estimator: схеми Circuit, спостережувані observables, параметри. Можна також надати список схем Circuit, список спостережуваних observables і список параметрів. Докладніше читай у Огляді PUBs.

Ми хочемо запускати на реальному квантовому комп'ютері, щоб проводити справжній квантово-фізичний експеримент. Якщо ти вичерпаєш виділений час на реальних квантових комп'ютерах, можеш закоментувати наведений нижче код для квантового комп'ютера і розкоментувати код для запуску на симуляторі.

# Step 3: Run the job on a real quantum computer

sampler = Sampler(mode=backend)
pubs = [qc_isa]
job = sampler.run(pubs)
res = job.result()

counts = res[0].data.c.get_counts()

# Run the job on the Aer simulator with noise model from real backend

# job = noisy_sampler.run([qc_isa])
# res=job.result()
# counts=res[0].data.c.get_counts()

Крок 4: Постобробка

Це особливо простий випадок постобробки, де ми просто візуалізуємо підрахунки.

Зверни увагу, що Qiskit впорядковує кубіти, вимірювання та інші елементи, розміщуючи елемент із найменшим номером останнім (праворуч) — ця угода називається «little-endian». Це означає, що стовпець нижче з позначкою «10» відповідає підрахункам, де перше вимірювання дало «0», а друге вимірювання дало «1».

# Step 4: Post-process

from qiskit.visualization import plot_histogram

plot_histogram(counts)

Output of the previous code cell

Якщо ця угода тебе не влаштовує, можеш скористатися marginal_counts, щоб окремо візуалізувати результати кожного вимірювання:

from qiskit.result import marginal_counts

plot_histogram(
marginal_counts(counts, indices=[0]), title="Counts after first measurement"
)

Output of the previous code cell

plot_histogram(
marginal_counts(counts, indices=[1]), title="Counts after second measurement"
)

Output of the previous code cell

За замовчуванням стани в Qiskit ініціалізуються у стан 0|0\rangle. Тому цілком не дивно, що майже всі перші вимірювання дали 0|0\rangle. Однак зверни увагу, що у другому вимірюванні (яке дає інформацію про проєкції стану на xx) спостерігається майже рівний розподіл. Здається, що стан, який дає дуже передбачуваний результат вимірювань вздовж zz, дає нам дуже непередбачуваний набір результатів для вимірювань вздовж xx. Давай дослідимо це детальніше.

Що станеться, якщо зробити вимірювання у зворотному порядку? Ми могли б розпочати з використання Gate Адамара, щоб отримати статистику ймовірності вимірювання 0|0\rangle у стані ±x|\pm\rangle_x. Потім для другого вимірювання ми повернемося до базису zz за допомогою другого Gate Адамара.

# Step 1:

# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(2, "c")
qc = QuantumCircuit(qr, cr)

# Change basis to measure along x.
qc.h(qr)
qc.measure(qr, cr[0])
qc.barrier()

# Change our basis back to z and make a second measurement
qc.h(qr)
qc.measure(qr, cr[1])

qc.draw("mpl")

Output of the previous code cell

# Step 2: Transpile the circuit for running on a quantum computer

pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
# Step 3: Run the job on a real quantum computer

sampler = Sampler(mode=backend)
pubs = [qc_isa]
job = sampler.run(pubs)
res = job.result()
counts = res[0].data.c.get_counts()

# Run the job on the Aer simulator with noise model from real backend
# job = noisy_sampler.run([qc_isa])
# res=job.result()
# counts=res[0].data.c.get_counts()
# Step 4: Post-process
from qiskit.visualization import plot_histogram

plot_histogram(counts)

Output of the previous code cell

Тут передбачуваності ще менше! Раніше ми принаймні знали результат першого вимірювання, тепер же маємо досить рівномірний розподіл по всіх можливих станах. Нескладно зрозуміти, чому так сталося. Ми почали у стані 0|0\rangle, який є сумішшю 50 на 50 +x|+\rangle_x і x|-\rangle_x згідно з 0=12(+x+x)|0\rangle=\frac{1}{\sqrt{2}}(|+\rangle_x+|-\rangle_x) Тому очевидно, що для першого вимірювання ймовірність отримати стан + або − (відображені як 0 і 1 на графіку) однакова. Вимірювання вздовж xx колапсує стан або у власний стан +x|+\rangle_x, або у власний стан x|-\rangle_x. Кожен із цих станів є сумішшю 50 на 50 0|0\rangle і 1|1\rangle згідно з +x=12(0+1)|+\rangle_x = \frac{1}{\sqrt{2}}(|0\rangle+|1\rangle) x=12(01)|-\rangle_x = \frac{1}{\sqrt{2}}(|0\rangle-|1\rangle) Тож коли система перебуває у власному стані xx, вимірювання вздовж zz даватимуть і 0|0\rangle, і 1|1\rangle з приблизно рівною ймовірністю. Отже, перший приклад показав нам, що деякі стани матимуть дуже передбачувані результати одних вимірювань, але непередбачувані результати інших. Поточний приклад показує, що все може бути ще гіршим. Існують стани, які можуть давати непередбачувані результати для обох вимірювань — навіть якщо ми просто міняємо порядок вимірювань. Давай дослідимо, наскільки певна або невизначена деяка величина для заданого стану.

Обчислення невизначеності

Ми можемо кількісно оцінити це за допомогою невизначеності або дисперсії. «Невизначеність» часто визначається як квадратний корінь із «дисперсії» розподілу. Тобто невизначеність деякої спостережуваної SS позначається ΔS\Delta S і визначається як

(ΔS)2(SS)2(ΔS)2=S22SS+S2(ΔS)2=S2S2\begin{aligned} (\Delta S)^2 & \equiv \langle (S - \langle S \rangle)^2 \rangle\\ (\Delta S)^2 & = \langle S^2 - 2 S \langle S \rangle +\langle S \rangle^2 \rangle\\ (\Delta S)^2 & = \langle S^2 \rangle - \langle S \rangle^2 \end{aligned}

Для матриць Паулі, де S2=IS^2 = I, це спрощується до

(ΔS)2=1S2(\Delta S)^2 = 1 - \langle S \rangle^2

Застосуємо це до конкретного прикладу. Почнімо зі стану ψ=+y=12(1i),|\psi\rangle = |+\rangle_y = \frac{1}{\sqrt{2}}\begin{pmatrix} 1 \\ i \end{pmatrix}, і визначимо невизначеність спостережуваної XX у цьому стані.

Перевір своє розуміння

Прочитай питання нижче, подумай над відповіддю, а потім натисни на трикутник, щоб побачити розв'язання.

Обчисли невизначеність XX у стані +y=+i|+\rangle_y = |+i\rangle вручну.

Відповідь:

ΔX=+iX2+i+iX+i2\Delta X =\sqrt{\langle+i| X^2 |+i\rangle - \langle+i| X |+i\rangle^2}

У заданому стані це дає:

ΔX=12(1i)(0110)(0110)12(1i)(12(1i)(0110)12(1i))2ΔX=12(1i)(1001)(1i)(12(1i)(i1))2ΔX=12(1i)(1i)(12(0)))2ΔX=12(2)=1\begin{aligned} \Delta X & =\sqrt{\frac{1}{\sqrt{2}}\begin{pmatrix}1 & -i\end{pmatrix} \begin{pmatrix}0 & 1 \\ 1 & 0\end{pmatrix} \begin{pmatrix}0 & 1 \\ 1 & 0\end{pmatrix} \frac{1}{\sqrt{2}}\begin{pmatrix}1 \\ i\end{pmatrix} - \left(\frac{1}{\sqrt{2}}\begin{pmatrix}1 & -i\end{pmatrix} \begin{pmatrix}0 & 1 \\ 1 & 0\end{pmatrix} \frac{1}{\sqrt{2}}\begin{pmatrix}1 \\ i\end{pmatrix}\right)^2}\\ \Delta X & =\sqrt{\frac{1}{2}\begin{pmatrix}1 & -i\end{pmatrix} \begin{pmatrix}1 & 0 \\ 0 & 1\end{pmatrix} \begin{pmatrix}1 \\ i\end{pmatrix} - \left(\frac{1}{2}\begin{pmatrix}1 & -i\end{pmatrix} \begin{pmatrix}i \\ 1\end{pmatrix}\right)^2}\\ \Delta X & =\sqrt{\frac{1}{2}\begin{pmatrix}1 & -i\end{pmatrix} \begin{pmatrix}1 \\ i\end{pmatrix} - \left(\frac{1}{2}(0))\right)^2}\\ \Delta X & =\sqrt{\frac{1}{2}(2)} = 1 \end{aligned}

Ми можемо створити довільний початковий стан за допомогою qc.initialize(). Зверни увагу, що синтаксис для уявної одиниці тут — 1j1j.

# Step 1: Map the problem into a quantum circuit

from qiskit.quantum_info import SparsePauliOp
import numpy as np

obs = SparsePauliOp("X")

# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)

# Initialize the state
qc.initialize([1, 1j] / np.sqrt(2))

# Step 2: Transpile the circuit

pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
obs_isa = obs.apply_layout(layout=qc_isa.layout)

# Step 3: Run the circuit on a real quantum computer

estimator = Estimator(mode=backend)
pubs = [(qc_isa, obs_isa)]
job = estimator.run([[qc_isa, obs_isa]])
res = job.result()

# Run the job on the Aer simulator with noise model from real backend
# job = noisy_estimator.run([[qc_isa,obs_isa]])
# res=job.result()

# Step 4: Return the result in classical form, and analyze.

print(res[0].data.evs)
-0.02408454165642664

Згідно з нашим рівнянням вище, (ΔX)2=1X2=1(0.0015...)2ΔX=0.999...(\Delta X)^2 = 1 - \langle X \rangle^2 = 1-(0.0015...)^2 \rightarrow \Delta X = 0.999... Залишимося з тим самим станом, але тепер знайдемо математичне очікування ZZ:

# Step 1: Map the problem into a quantum circuit

obs = SparsePauliOp("Z")

# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)

# Initialize the state to |+>_y
qc.initialize([1, 1j] / np.sqrt(2))

# Step 2: Transpile the circuit

pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
obs_isa = obs.apply_layout(layout=qc_isa.layout)

# Step 3: Run the circuit on a real quantum computer

estimator = Estimator(mode=backend)
pubs = [(qc_isa, obs_isa)]
job = estimator.run(pubs)
res = job.result()

# Run the job on the Aer simulator with noise model from real backend
# job = noisy_estimator.run([[qc_isa,obs_isa]])
# res=job.result()

# Step 4: Return the result in classical form, and analyze.

print(res[0].data.evs)
0.04958271968581247

Ми могли б провести ті ж самі обчислення, що й раніше, і побачили б, що дисперсія знову дуже близька до 1.0. Можна зробити висновок, що ΔXΔZ1.0\Delta X \Delta Z \approx 1.0. Дійсно, це приблизно правильно для обраного нами стану. Але чи можна зробити краще? Або гірше?

Пригадай, що між координатою вздовж одного напрямку, xx, та імпульсом у тому ж напрямку, pxp_x, існує співвідношення невизначеності. Для цих змінних найвідоміша форма, мабуть, така: ΔxΔpx/2\Delta x \Delta p_x \geq \hbar/2 Якщо це все, що ми пам'ятаємо, у нас може виникнути спокуса думати, що ΔX\Delta X і ΔZ\Delta Z також можуть мати таке фундаментальне обмеження на невизначеність. Можливо, добуток ΔXΔZ\Delta X \Delta Z не може досягти нуля? Спробуємо інший стан і подивимося, чи це так. На цей раз використаємо ψ=12(11).|\psi\rangle = \frac{1}{\sqrt{2}}\begin{pmatrix} 1 \\ 1 \end{pmatrix}. Подивимося, що станеться. Зверни увагу, що у наведеному нижче коді estimator може приймати два набори схем Circuit і спостережуваних observables в одному поданні задачі.

# Step 1: Map the problem into a quantum circuit

obs1 = SparsePauliOp("X")
obs2 = SparsePauliOp("Z")

# Define registers

qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)

# Initialize the state
qc.initialize([1, 1] / np.sqrt(2))

# Step 2: Transpile the circuit

pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
obs1_isa = obs1.apply_layout(layout=qc_isa.layout)
obs2_isa = obs2.apply_layout(layout=qc_isa.layout)

# Step 3: Run the circuit on a real quantum computer

with Batch(backend=backend) as batch:
estimator = Estimator(mode=batch)
pubs = [(qc_isa, obs1_isa), (qc_isa, obs2_isa)]
job = estimator.run(pubs)
res = job.result()
batch.close()

# Run the job on the Aer simulator with noise model from real backend

# job = noisy_estimator.run([[qc,obs1],[qc,obs2]])
# res=job.result()

# Step 4: Return the result in classical form, and analyze.

print("The expectation value of the first observable is: ", res[0].data.evs)
print("The expectation value of the second observable is: ", res[1].data.evs)
The expectation value of the first observable is:  1.0011036174126302
The expectation value of the second observable is: 0.0029429797670141016

Математичне очікування XX має бути близьким до 1.0, але не повинно перевищувати 1.0. Не хвилюйся, якщо воно незначно перевищує 1.0. Це можна пояснити такими факторами, як шум і/або похибка зчитування. Хоча це дуже важлива тема, зараз ми можемо її ігнорувати.

Ми отримали математичне очікування XX, дуже близьке до 1.0 (що відповідає дуже малій дисперсії для XX). Це робить добуток двох дисперсій досить малим:

ΔXΔZ=1(0.9853)2×1(0.00195)2=0.171.\Delta X \Delta Z = \sqrt{1-(0.9853)^2} \times \sqrt{1-(-0.00195)^2} = 0.171.

Хоча це не рівно нулю, значення стає малим порівняно з власними значеннями операторів Паулі (±1\pm 1). Можливо, ти пам'ятаєш, що співвідношення невизначеності між лінійним положенням та імпульсом можна записати по-іншому — явно використовуючи комутаційне співвідношення між операторами xx і pxp_x:

ΔxΔpx12[x,px]\Delta x \Delta p_x \geq \frac{1}{2}|\langle [x,p_x] \rangle|

де

[x,px]=xpxpxx[x,p_x] = xp_x-p_xx

є комутатором xx і pxp_x.

Це форма, яку найлегше узагальнити на оператори Паулі. Загалом, для двох операторів AA і BB,

ΔAΔB12[A,B].\Delta A \Delta B \geq \frac{1}{2}|\langle [A,B] \rangle|.

І у випадку матриць Паулі XX і ZZ нам потрібен [X,Z][X,Z], щоб обчислити

ΔXΔZ12[X,Z].\Delta X \Delta Z \geq \frac{1}{2}|\langle [X,Z] \rangle|.

Покажемо це тут, а аналогічні обчислення залишимо читачеві як вправу:

[X,Z]=XZZX=(0110)(1001)(1001)(0110)[X,Z] = XZ-ZX = \begin{pmatrix}0 & 1 \\ 1 & 0\end{pmatrix}\begin{pmatrix}1 & 0 \\ 0 & -1\end{pmatrix}-\begin{pmatrix}1 & 0 \\ 0 & -1\end{pmatrix}\begin{pmatrix}0 & 1 \\ 1 & 0\end{pmatrix} [X,Z]=(0110)(0110)=2(0110)[X,Z] = \begin{pmatrix}0 & -1 \\ 1 & 0\end{pmatrix}-\begin{pmatrix}0 & 1 \\ -1 & 0\end{pmatrix} = 2\begin{pmatrix}0 & -1 \\ 1 & 0\end{pmatrix}

Це цілком прийнятна відповідь, але ще один крок дає нам

[X,Z]=2i(0ii0)=2iY[X,Z] = -2i\begin{pmatrix}0 & -i \\ i & 0\end{pmatrix}=-2iY

Тому наше співвідношення невизначеності набуває вигляду

ΔXΔZY.\Delta X \Delta Z \geq |\langle Y \rangle|.

Перевір своє розуміння

Прочитай запитання нижче, подумай над відповіддю, а потім натисни на трикутник, щоб побачити розв'язок.

Визнач [X,Y][X,Y] і [Y,Z][Y,Z]. Використай це, щоб записати співвідношення невизначеностей між XX і YY, а також між YY і ZZ.

Відповідь:

[X,Y]=XYYX=(0110)(0ii0)(0ii0)(0110)=2(i00i)=2iZ[X,Y] = XY-YX = \begin{pmatrix}0 & 1 \\ 1 & 0\end{pmatrix}\begin{pmatrix}0 & -i \\ i & 0\end{pmatrix}-\begin{pmatrix}0 & -i \\ i & 0\end{pmatrix}\begin{pmatrix}0 & 1 \\ 1 & 0\end{pmatrix} = 2 \begin{pmatrix}i & 0 \\ 0 & -i\end{pmatrix}=2iZ[Y,Z]=YZZY=(0ii0)(1001)(1001)(0ii0)=2(0ii0)=2iX[Y,Z] = YZ-ZY = \begin{pmatrix}0 & -i \\ i & 0\end{pmatrix}\begin{pmatrix}1 & 0 \\ 0 & -1\end{pmatrix}-\begin{pmatrix}1 & 0 \\ 0 & -1\end{pmatrix}\begin{pmatrix}0 & -i \\ i & 0\end{pmatrix} = 2 \begin{pmatrix}0 & i \\ i & 0\end{pmatrix}=2iX

Поєднуючи із загальним співвідношенням невизначеностей, отримуємо:

ΔXΔYZ,\Delta X \Delta Y \geq |\langle Z \rangle|,ΔYΔZX.\Delta Y \Delta Z \geq |\langle X \rangle|.

Перевір узгодженість

Перш ніж рухатися далі, переконаймося, що це узгоджується з нашим попереднім результатом. Ми використовували стан ψ=12(11).|\psi\rangle = \frac{1}{\sqrt{2}}\begin{pmatrix} 1 \\ 1 \end{pmatrix}. І знайшли, що ΔXΔZ=0.171.\Delta X \Delta Z = 0.171. Тепер ми знаємо, що цей добуток має бути більшим або рівним

Y=12(11)(0ii0)12(11)|\langle Y \rangle|=\frac{1}{\sqrt{2}}\begin{pmatrix} 1 & 1 \end{pmatrix}\begin{pmatrix}0 & -i \\ i & 0\end{pmatrix}\frac{1}{\sqrt{2}}\begin{pmatrix} 1 \\ 1 \end{pmatrix} Y=12(11)(ii)=12(i+i)=0.|\langle Y \rangle| = \frac{1}{2}\begin{pmatrix} 1 & 1 \end{pmatrix}\begin{pmatrix} -i \\ i \end{pmatrix} = \frac{1}{2}(-i+i) = 0.

Отже, справді ΔXΔZ=0.171Y=0\Delta X \Delta Z = 0.171 \geq |\langle Y \rangle|=0. Використай наведені нижче запитання, щоб краще відчути ці результати:

Перевір своє розуміння

Прочитай запитання нижче, подумай над своїми відповідями, а потім натисни на трикутники, щоб побачити розв'язки.

Дай відповідь на всі пункти разом як єдиний набір:

(a) Для яких станів ти очікуєш нульову невизначеність у XX?

(b) Для яких станів ти очікуєш нульову невизначеність у ZZ?

(c) У яких станах ти отримаєш нульове середнє значення Y\langle Y \rangle?

(d) Чи узгоджуються відповіді на наведені вище запитання з випадком ΔXΔZY\Delta X \Delta Z \geq |\langle Y \rangle|?

(e) Напиши код для явної перевірки цього за допомогою estimator.

Відповіді:

(a) Можна очікувати, що власні стани оператора XX дадуть нульову невизначеність у XX. Справді, використовуючи ψ=+x,|\psi\rangle = |+\rangle_x, маємо: ΔX=1X2=112=0.\Delta X = \sqrt{1-\langle X \rangle^2} = \sqrt{1-1^2} = 0.

(b) Можна очікувати, що власні стани оператора ZZ дадуть нульову невизначеність у ZZ. Справді, використовуючи ψ=1,|\psi\rangle = |1\rangle, маємо: ΔZ=1Z2=1(1)2=0.\Delta Z = \sqrt{1-\langle Z \rangle^2} = \sqrt{1-(-1)^2} = 0.

(c) Ми очікуємо Y=0\langle Y \rangle=0 для будь-яких станів, які при вимірюванні дають позитивну проєкцію на вісь yy так само часто, як і негативну. До них належать власні стани XX і ZZ.

(d) Так. Для власних станів XX або ZZ можна очікувати дуже малого значення добутку невизначеностей ΔXΔZ\Delta X \Delta Z: ΔXΔZ0.\Delta X \Delta Z \approx 0. Це можливо, оскільки для тих самих станів ми також очікуємо Y=0\langle Y \rangle=0. Таким чином, співвідношення невизначеностей може виконуватися.

(e) Для перевірки підійде такий код:

obs1 = SparsePauliOp.from_list(
[("X", 1.000)]
)
obs2 = SparsePauliOp.from_list(
[("Y", 1.000)]
)
obs3 = SparsePauliOp.from_list(
[("Z", 1.000)]
)
qc = QuantumCircuit(1,1)
qc.ry(pi/2,0)

job = estimator.run([(qc, [[obs1], [obs2], [obs3]])], precision=0.001)
res=job.result()

Де результат повертає всі середні значення. Щоб отримати всі середні значення та обчислити невизначеності, можна скористатися:

xs=res[0].data.evs[0]
ys=abs(res[0].data.evs[1])
zs=res[0].data.evs[2]

import math
prodxz=((1-xs[i]*xs[i])**0.5)*(1-zs[i]*zs[i])**0.5

Дай відповідь на всі пункти разом як єдиний набір:

(a) Чи можеш ти придумати стан, у якому середнє значення Y\langle Y \rangle буде великим?

(b) Чи очікуєш ти, що для того самого стану невизначеність у XX буде великою чи малою?

(c) Чи очікуєш ти, що для того самого стану невизначеність у ZZ буде великою чи малою?

(d) Чи узгоджуються відповіді на наведені вище запитання з випадком ΔXΔZY\Delta X \Delta Z \geq |\langle Y \rangle|?

(e) Напиши код для явної перевірки цього за допомогою estimator.

Відповіді:

(a) Ми очікуємо Y1\langle Y \rangle\approx 1 для власного стану оператора YY: +y|+\rangle_y.

(b) Можна очікувати, що XX матиме велику невизначеність у стані +y|+\rangle_y, оскільки вимірювання XX у цьому стані давало б позитивний і негативний результат з однаковою частотою/ймовірністю.

(c) Можна очікувати, що ZZ матиме велику невизначеність у стані +y|+\rangle_y, оскільки вимірювання ZZ у цьому стані давало б позитивний і негативний результат з однаковою частотою/ймовірністю.

(d) Так. Для власних станів YY, зокрема для +y|+\rangle_y, можна очікувати великого значення добутку невизначеностей ΔXΔZ\Delta X \Delta Z. Ми також очікуємо Y1\langle Y \rangle\approx 1 для того самого стану. Таким чином, і Y\langle Y \rangle, і ΔXΔZ\Delta X \Delta Z є досить великими в цьому стані, і цілком правдоподібно, що співвідношення невизначеностей знову виконається.

(e) Для перевірки підійде такий код:

obs1 = SparsePauliOp.from_list(
[("X", 1.000)]
)
obs2 = SparsePauliOp.from_list(
[("Y", 1.000)]
)
obs3 = SparsePauliOp.from_list(
[("Z", 1.000)]
)
qc = QuantumCircuit(1,1)
qc.rx(-pi/2,0)

job = estimator.run([(qc, [[obs1], [obs2], [obs3]])], precision=0.001)
res=job.result()

Де результат повертає всі середні значення. Щоб отримати всі середні значення та обчислити невизначеності, можна скористатися:

xs=res[0].data.evs[0]
ys=abs(res[0].data.evs[1])
zs=res[0].data.evs[2]

import math
prodxz=((1-xs[i]*xs[i])**0.5)*(1-zs[i]*zs[i])**0.5

Тестування співвідношень невизначеностей

Наведений вище тест продемонстрував справедливість співвідношення невизначеностей лише для одного конкретного вектора стану ψ=+x|\psi\rangle = |+\rangle_x. Щоб переконатися, що це загалом узгоджується з експериментом, слід провести аналогічні обчислення за допомогою estimator для багатьох векторів стану. Почнімо з того, що відхиляємо вектор стану від осі zz, використовуючи Gate RY, щоб отримати різні початкові стани за допомогою параметра θ\theta.

# The calculation below uses approximately 3-4 minutes of QPU time.
# Step 1: Map the problem into a quantum circuit

from qiskit.circuit import Parameter
import numpy as np

# Specify observables
obs1 = SparsePauliOp("X")
obs2 = SparsePauliOp("Y")
obs3 = SparsePauliOp("Z")

# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)

# Rotate away from |0>
theta = Parameter("θ")
qc.ry(theta, 0)

params = np.linspace(0, 2, num=21)

# Step 2: Transpile the circuit

pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
obs1_isa = obs1.apply_layout(layout=qc_isa.layout)
obs2_isa = obs2.apply_layout(layout=qc_isa.layout)
obs3_isa = obs3.apply_layout(layout=qc_isa.layout)

# Step 3: Run the circuit on a real quantum computer

with Batch(backend=backend) as batch:
estimator = Estimator(mode=batch)
pubs = [(qc_isa, [[obs1_isa], [obs2_isa], [obs3_isa]], [params])]
job = estimator.run(pubs, precision=0.01)
res = job.result()

batch.close()

# Run the job on the Aer simulator with noise model from real backend

# job = noisy_estimator.run([(qc, [[obs1], [obs2], [obs3]], [params])])
# res=job.result()
# Step 4: Post-processing and classical analysis.
xs = res[0].data.evs[0]
ys = abs(res[0].data.evs[1])
zs = res[0].data.evs[2]

# Calculate uncertainties

delx = []
delz = []
prodxz = []
for i in range(len(xs)):
delx.append(abs((1 - xs[i] * xs[i])) ** 0.5)
delz.append(abs((1 - zs[i] * zs[i])) ** 0.5)
prodxz.append(delx[i] * delz[i])
# Here we can plot the results from this simulation.
import matplotlib.pyplot as plt

plt.plot(params, delx, label=r"$\Delta$ X")
plt.plot(params, ys, label=r"$\langle$ Y $\rangle$")
plt.plot(params, delz, label=r"$\Delta$ Z")
plt.plot(params, prodxz, label=r"$\Delta$X $\Delta$Z")
plt.xlabel(r"$\theta$")
plt.ylabel("Expectation/Uncertainty Values")
plt.legend()
plt.show()

Output of the previous code cell

Зверни увагу, що червона крива (ΔXΔZ)(\Delta X \Delta Z) завжди більша за помаранчеву криву Y.\langle Y \rangle. Іноді добуток невизначеностей опускається і наближається до межі, а іноді зростає і відходить від неї, але він завжди підпорядковується співвідношенню невизначеностей.

Звісно, це може бути не найкращим тестом співвідношення невизначеностей, оскільки наша межа Y\langle Y \rangle завжди дуже близька до нуля. Використаймо квантовий стан, що має більшу проєкцію на власні стани YY. Зокрема, ми як і раніше будемо відхиляти 0|0\rangle від осі zz на різні кути, але тепер ще й обертатимемо отриманий стан навколо zz на деякий кут, наприклад π/4\pi/4, і подивимося, що відбудеться.

# The calculation below uses approximately 3-4 minutes of QPU time.
from qiskit.circuit import Parameter
import numpy as np

# Step 1: Map the problem to a quantum circuit

# Specify observables
obs1 = SparsePauliOp("X")
obs2 = SparsePauliOp("Y")
obs3 = SparsePauliOp("Z")

# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)

# Rotate away from |0> along one plane, and then along a transverse direction.
theta = Parameter("θ")
qc.ry(theta, 0)
qc.rz(pi / 4, 0)

params = np.linspace(0, 2, num=21)

# Step 2: Transpile the circuit

pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)

obs1_isa = obs1.apply_layout(layout=qc_isa.layout)
obs2_isa = obs2.apply_layout(layout=qc_isa.layout)
obs3_isa = obs3.apply_layout(layout=qc_isa.layout)

# Step 3: Run the circuit on a real quantum computer

with Batch(backend=backend) as batch:
estimator = Estimator(mode=batch)
pubs = [(qc_isa, [[obs1_isa], [obs2_isa], [obs3_isa]], [params])]
job = estimator.run(pubs, precision=0.01)
res = job.result()

batch.close()

# Run the job on the Aer simulator with noise model from real backend

# job = noisy_estimator.run([(qc, [[obs1], [obs2], [obs3]], [params])])
# res=job.result()
# Step 4: Post-processing and classical analysis.
xs = res[0].data.evs[0]
ys = abs(res[0].data.evs[1])
zs = res[0].data.evs[2]

# Calculate uncertainties

delx = []
delz = []
prodxz = []
for i in range(len(xs)):
delx.append(abs((1 - xs[i] * xs[i])) ** 0.5)
delz.append(abs((1 - zs[i] * zs[i])) ** 0.5)
prodxz.append(delx[i] * delz[i])
# Here we can plot the results from this simulation.
import matplotlib.pyplot as plt

plt.plot(params, delx, label=r"$\Delta$ X")
plt.plot(params, ys, label=r"$\langle$ Y $\rangle$")
plt.plot(params, delz, label=r"$\Delta$ Z")
plt.plot(params, prodxz, label=r"$\Delta$X $\Delta$Z")
plt.xlabel(r"$\theta$")
plt.ylabel("Expectation/Uncertainty Values")
plt.legend()
plt.show()

Output of the previous code cell

Тепер ми бачимо, що межа невизначеності (ΔXΔZ)(\Delta X \Delta Z) зазнає справжнього випробування! Червона крива підходить значно ближче до помаранчевої, ніж раніше. Насправді, за відсутності шуму співвідношення невизначеностей було б точно насичено ((ΔXΔZ)=Y(\Delta X \Delta Z) = \langle Y \rangle) в одній точці. За наявності шуму та помилок зчитування не дивно, якщо запуск іноді дає (ΔXΔZ)(\Delta X \Delta Z), дещо більший за Y.\langle Y \rangle. Це не справжнє порушення невизначеності — це лише артефакт ненульової похибки.

Перевір своє розуміння

Прочитай запитання нижче, подумай над своїми відповідями, а потім натисни на трикутники, щоб побачити розв'язки.

Поясни, як ти міг би довести це до абсолютної межі, зробивши Y\langle Y \rangle якомога більшим?

Відповідь:

У коді є рядки, які відхиляють типовий початковий стан 0|0\rangle від осі zz на параметризований кут θ\theta, а потім обертають його навколо осі zz на кут π/4\pi/4, переміщуючи вектор стану частково в бік осі yy.

qc.ry(theta,0)

qc.rz(pi/4,0)

Ми могли б змінити обертання навколо zz з π/4\pi/4 на π/2\pi/2, повністю довернувши до власного стану YY:

qc.ry(theta,0)

qc.rz(pi/2,0)

Жодних інших змін не знадобиться.

Зміни код або скопіюй його і реалізуй ту перевірку співвідношення невизначеностей із максимізованим середнім значенням YY. Чи виконується співвідношення невизначеностей?

Відповідь:

Ми б використали саме код із прикладу вище, підставивши

qc.rz(pi/2,0)

замість

qc.rz(pi/4,0).

Отриманий графік повинен виглядати так, як показано нижче, і так, принцип невизначеностей має залишатися в силі.

A plot comparing uncertainty to the maximum expectation value of the Y operator.

Зміни наведений вище код, щоб отримати аналогічний графік, який демонструє, що за результатами вимірювань на квантовому комп'ютері добуток ΔXΔY\Delta X \Delta Y поводиться так, як і слід очікувати. Обери будь-який набір станів.

Відповідь:

Ми б використали саме код із прикладу вище — фактично можна використати ті самі результати зі змінами лише у обчисленні невизначеностей. Наприклад, можна скористатися:

xs=res[0].data.evs[0]
ys=res[0].data.evs[1]
zs=abs(res[0].data.evs[2])
import math
delx = []
dely = []
prodxy=[]
for i in range(len(xs)):
delx.append((1-xs[i]*xs[i])**0.5)
dely.append((1-ys[i]*ys[i])**0.5)
prodxy.append(((1-xs[i]*xs[i])**0.5)*(1-ys[i]*ys[i])**0.5)

і побудувати графік:

import matplotlib.pyplot as plt
plt.plot(params, delx, label=r'$\Delta$ X')
plt.plot(params, dely, label=r'$\langle$ Y $\rangle$')
plt.plot(params, zs, label=r'$\Delta$ Z')
plt.plot(params, prodxy, label=r'$\Delta$X $\Delta$Z')
plt.xlabel(r'$\theta$')
plt.ylabel('Expectation/Uncertainty Values')
plt.legend()
plt.show()

Завдання: Напиши код для перебору багатьох значень ϕ\phi, так само як ми перебирали багато значень θ\theta, і побудуй тривимірний графік, що демонструє, що співвідношення невизначеностей ніколи не порушується. Обери будь-які спостережувані.

Запитання

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

Ключові концепції:

  • Між багатьма парами фізичних спостережуваних існують співвідношення невизначеності, зокрема між положенням і лінійним імпульсом, а також між компонентами спіну.
  • Матриці Паулі не комутують. Це математичне відображення того факту, що не всі компоненти спіну можуть бути одночасно відомі/визначені.
  • У квантових обчисленнях активно використовуються оператори/матриці Паулі, тому корисно знати співвідношення невизначеності для операторів Паулі, а також тісно пов'язаних із ними операторів спіну.
  • Загальна формула для невизначеності двох операторів AA та BB має вигляд ΔAΔB12[A,B].\Delta A \Delta B \geq \frac{1}{2}|\langle [A,B] \rangle|.
  • Власний стан a|a\rangle деякого оператора AA дає нульову невизначеність фізичної спостережуваної, пов'язаної з цим оператором. Навіть експериментально aAa0.\langle a|A|a\rangle \approx 0.
  • Власний стан a|a\rangle деякого оператора AA даватиме більшу невизначеність для оператора BB, який не комутує з AA.
  • Експериментальні результати, отримані на реальному квантовому комп'ютері, підтверджують інтуїцію, яку ми набуваємо з матричних представлень фізичних операторів.

Запитання «Правда/хибність»:

  1. П/Х Можна одночасно виміряти XX та YY, але не ZZ.
  2. П/Х Можна одночасно виміряти XX та ZZ, але не YY.
  3. П/Х Оператори лінійного положення і лінійного імпульсу не комутують.
  4. П/Х Квантові комп'ютери IBM за замовчуванням вимірюють вздовж ZZ, тому для вимірювання вздовж будь-якого іншого напряму необхідно виконати поворот.
  5. П/Х Наведена нижче схема Circuit фактично вимірює спочатку ZZ, а потім XX.

A circuit diagram showing a measurement, a Hadamard gate, and then another measurement.

Запитання з вибором відповіді:

  1. Яке з наведених нижче співвідношень невизначеності ілюструє діаграма нижче?

    • а. ΔXΔYZ\Delta X \Delta Y \geq |\langle Z \rangle|
    • б. ΔYΔZX\Delta Y \Delta Z \geq |\langle X \rangle|
    • в. ΔZΔXY\Delta Z \Delta X \geq |\langle Y \rangle|
    • г. Жодне з наведених

A plot comparing uncertainty to the maximum expectation value of the Y operator.

  1. Яка з наведених послідовностей є стандартною для виконання вимірювання вздовж xx?

    • а. Лише qc.measure()
    • б. qc.h(), потім qc.measure()
    • в. qc.h(), qc.h(), потім qc.measure()
    • г. qc.h(), qc.s, qc.h(), потім qc.measure()
    • д. qc.sdg(), qc.h(), qc.s, потім qc.measure()
    • е. qc.sdg(), qc.h(), qc.s, qc.h(), потім qc.measure()
  2. Який із наведених станів дає найбільше значення математичного очікування X\langle X \rangle?

    • а. +x|+\rangle_x
    • б. x|-\rangle_x
    • в. +y|+\rangle_y, також відомий як +i|+i\rangle
    • г. y|-\rangle_y, також відомий як i|-i\rangle
    • д. 0|0\rangle, також відомий як |\uparrow\rangle
    • е. 1|1\rangle, також відомий як |\downarrow\rangle
  3. Який із наведених станів дає найбільшу невизначеність ΔX\Delta X?

    • а. +x|+\rangle_x
    • б. +y|+\rangle_y, також відомий як +i|+i\rangle
    • в. 0|0\rangle, також відомий як |\uparrow\rangle
    • г. а і б однакові
    • д. б і в однакові
    • е. а, б і в однакові

Запитання для обговорення:

  1. Чи суперечить це поняття невизначеності уявленню про спін як про векторну стрілку в декартовому просторі? А як щодо сфери Блоха?

  2. Припустимо, ти орієнтуєш вимірювальний пристрій у напрямку, що знаходиться рівно між осями xx та yy. Що відбувається? Чи можна виконати вимірювання в цьому напрямку? Як це пов'язано з невизначеністю в XX та YY?