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

Починаємо роботу з Qiskit у класі

Для цього модуля «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®.

Цей модуль було протестовано та використано 2 секунди QPU-часу на процесорі Heron v2. Це лише приблизна оцінка. Твоє фактичне використання може відрізнятися.

# Added by doQumentation — required packages for this notebook
!pip install -q 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'

Вступ

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

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

Класичні комп'ютери

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

Основні одиниці інформації: біти

Класичні комп'ютери обробляють класичну інформацію, а фундаментальною одиницею класичної інформації є біт. Один біт може зберігати відповідь на одне питання «так/ні». Зазвичай два бінарних стани біта позначають як «0» і «1».

Повторення двійкових чисел

Комбінування бітів дає змогу зберігати більше інформації. Наприклад, якщо потрібно зберегти число від 0 до 15, це можна зробити за допомогою чотирьох бітів таким чином:

0 = 00004 = 01008 = 100012 = 1100
1 = 00015 = 01019 = 100113 = 1101
2 = 00106 = 011010 = 101014 = 1110
3 = 00117 = 011111 = 101115 = 1111

Загалом, щоб перетворити двійкове число з NN бітів на знайоме число в десятковій системі числення, ти множиш молодший (крайній правий) біт на 20=12^0 = 1, наступний біт ліворуч на 21=22^1 = 2, потім наступний на 22=42^2 = 4 і так далі, аж до старшого (крайнього лівого) біта, який множиш на 2N12^{N-1}.

Отже, NN бітів можуть перебувати в одному з 2N2^N різних можливих станів.

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

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

Скільки бітів потрібно, щоб представити число 86? Запиши рядок бітів, що кодує це число в двійковому вигляді.

Відповідь:

Пам'ятай, що NN бітів дають змогу представляти числа від 00 до 2N12^N - 1, тому шість бітів дають нам до 261=632^6 - 1 = 63. Цього недостатньо. Додаємо ще один біт, щоб отримати до 271=1272^7 - 1 = 127. Тепер розкладемо 86 на степені двійки:

86=64+16+4+2=26×1+25×0+24×1+23×0+22×1+21×1+20×0=1010110\begin{aligned} 86 &= 64 + 16 + 4 + 2 \\ &= 2^6 \times 1 + 2^5 \times 0 + 2^4 \times 1 + 2^3 \times 0 + 2^2 \times 1 + 2^1 \times 1 + 2^0 \times 0 \\ &= 1010110 \end{aligned}

Фундаментальні операції: Gate

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

Однобітовий Gate:

NOT

Коли є лише один біт, є лише один спосіб перетворити його стан: переключити стан з 0 на 1 або з 1 на 0. Це називається Gate «NOT». Дія цього Gate — і решти Gate, які ми обговоримо нижче — може бути представлена у так званій «таблиці істинності», зі стовпцями для вхідних і вихідних станів кубітів. Таблиця істинності для Gate NOT:

ВхідВихід
01
10

Багатобітові Gate:

AND

AND — це двобітовий Gate, що приймає два вхідних біти і виводить один біт. Виводить 1, якщо обидва вхідних біти дорівнюють 1, і 0 в іншому випадку:

ВхідВихід
000
010
100
111

OR

OR — ще один двобітовий Gate з одним вихідним бітом. Виводить 1, якщо будь-який з бітів дорівнює 1:

ВхідВихід
000
011
101
111

XOR

XOR означає «виключне АБО» і схожий на Gate OR, але виводить 1, лише якщо тільки один із вхідних бітів дорівнює 1. Виводить 0, якщо обидва рівні 1 або обидва рівні 0:

ВхідВихід
000
011
101
110

Вимірювання:

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

Circuit:

Комбінуючи наведені вище Gate, ти можеш виконувати будь-які операції на комп'ютері. Розглянемо простий приклад: використовуючи Gate AND та XOR, можна побудувати схему напівсуматора, яка обчислює суму двох бітів. Це представлено у логічній схемі Circuit, де дроти представляють біти, а Gate, що діють на біти, показані у вигляді символів на відповідних дротах:

Діаграма класичної Circuit для схеми напівсуматора. Gate XOR генерує вихідний біт суми, а Gate AND генерує вихідний біт перенесення.

Отже, два біти копіюються та подаються через Gate AND і Gate XOR одночасно. Результат Gate XOR — це «біт суми» (S), який залишається в одиничному розряді двійкового числа, а результат Gate AND — це «біт перенесення» (C), що є значенням наступного за значущістю розряду двійкового числа. Ось таблиця істинності:

AABBСума (ABA \oplus B)Перенесення (ABA \wedge B)
0000
0110
1010
1101

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

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

Перевір, що наведена вище таблиця істинності дає правильне рішення для схеми суматора. Тобто для кожного з чотирьох варіантів A і B перевір, що A+B=S+2×CA+B=S+2 \times C.

Відповідь:

0+0=0+0=0 0+1=1+0=1 1+0=1+0=1 1+1=0+2=2 \begin{aligned} 0+0 &= 0+0 = 0 ~\checkmark \\ 0+1 &= 1+0 = 1 ~\checkmark \\ 1+0 &= 1+0 = 1 ~\checkmark \\ 1+1 &= 0+2 = 2 ~\checkmark \\ \end{aligned}

Квантові комп'ютери

Біти \rightarrow Qubit

Так само як біти є фундаментальними одиницями класичної інформації, квантові біти, або «Qubit», є фундаментальними одиницями квантової інформації. Як і класичний біт, стан Qubit може бути або 0, або 1, що зазвичай позначають як 0\vert 0\rangle та 1\vert 1\rangle. Але, на відміну від класичного біта, квантовий біт також може перебувати в суперпозиції обох станів 0\vert 0\rangle і 1\vert 1\rangle одночасно. Загалом, Qubit може перебувати в будь-якому стані ψ\vert \psi\rangle вигляду:

ψ=c00+c11\vert \psi\rangle = c_0 \vert 0\rangle + c_1 \vert 1\rangle

де c0c_0 та c1c_1 — комплексні амплітуди з c02+c12=1\vert c_0 \vert ^2+\vert c_1\vert ^2=1.

Квантова фаза

Оскільки c0c_0 і c1c_1 є комплексними числами, кожне з них можна записати як ci=cieiϕic_i = \vert c_i\vert e^{i\phi_i}, де ϕi\phi_i називається фазою. Якщо помножити весь стан на однаковий спільний фазовий множник, фізично нічого не зміниться — це називається глобальною фазою, і вона не має спостережуваних наслідків.

З цієї причини прийнято «виносити за дужку» eiϕ0e^{i\phi_0}, що дає:

ψ=c00+c1eiϕ1\vert \psi\rangle = \vert c_0\vert \vert 0\rangle + \vert c_1\vert e^{i\phi}\vert 1\rangle

де ϕ=ϕ1ϕ0\phi = \phi_1-\phi_0відносна фаза квантового стану, яка має спостережувані наслідки.

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

Декілька Qubit

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

Пригадаємо, що NN бітів могли перебувати в одному з 2N2^N можливих станів — від двійкових чисел 000...000 до 111...111. Але тепер, завдяки принципу суперпозиції, NN Qubit можуть одночасно перебувати в суперпозиції всіх цих станів!

Це можна виразити як

ψN=i=02N1cii\psi_N = \sum_{i=0}^{2^N-1} c_i \vert i\rangle

де, як і в класичному випадку, стан i\vert i\rangle відповідає стану, в якому кожен Qubit перебуває в правильній комбінації нулів і одиниць, щоб отримати двійкове число ii. Ці стани відомі як «обчислювальні базисні стани» квантової системи. Наприклад, тривкубітний стан можна записати як суперпозицію восьми обчислювальних базисних станів:

ψ3=c0000+c1001+c2010+c3011+c4100+c5101+c6110+c7111\psi_3 = c_0 \vert 000\rangle + c_1 \vert 001\rangle + c_2 \vert 010\rangle + c_3 \vert 011\rangle + c_4 \vert 100\rangle + c_5 \vert 101\rangle + c_6 \vert 110\rangle + c_7 \vert 111\rangle

Кожен Qubit у системі позначається індексом від 00 до N1N-1. Прийнято читати стани Qubit справа наліво, так що стан Qubit 00 є крайнім правим, а стан Qubit N1N-1 — крайнім лівим. Це відомо як «little-endian» нотація, і спочатку вона може здатися неінтуїтивною, оскільки ми звикли читати зліва направо.

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

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

На перший погляд, порядок Qubit справа наліво за little-endian нотацією може здатися неінтуїтивним, але насправді це дуже логічно! Поясни чому. (Пригадай наше обговорення вище щодо перетворення двійкових чисел у десяткові.)

Відповідь:

Якщо впорядковувати Qubit справа наліво, так що Qubit 0 знаходиться крайнім правим, а Qubit N-1 — крайнім лівим, логічно асоціювати Qubit 00 з молодшим бітом, який множиться на 202^0, а Qubit N1N-1 — зі старшим бітом, який множиться на 2N12^{N-1}.

Заплутаність

Як ми вже згадували раніше, ще однією ключовою особливістю Qubit є те, що вони можуть бути заплутані один з одним. Розглянемо приклад двокубітного стану, де c0=c3=12c_0 = c_3 = \frac{1}{\sqrt{2}} та c1=c2=0c_1 = c_2 = 0:

ψ=12(00+11)\vert \psi\rangle = \frac{1}{\sqrt{2}}(\vert 00\rangle + \vert 11\rangle)

Отже, стан Qubit 0 може бути або 0\vert 0\rangle, або 1\vert 1\rangle з рівною імовірністю, і те ж саме стосується стану Qubit 1. Але ці імовірності більше не є незалежними одна від одної. Якщо ми виявимо, що стан Qubit 0 дорівнює 0\vert 0\rangle, то знаємо, що Qubit 1 також буде в стані 0\vert 0\rangle. Це справджується незалежно від того, наскільки далеко вони розташовані один від одного, саме тому акт вимірювання заплутаного стану іноді називають «моторошною дією на відстані».

Заплутаність може також приймати інші форми. Наприклад, стан

ψ=12(01+10)\vert \psi\rangle = \frac{1}{\sqrt{2}}(\vert 01\rangle + \vert 10\rangle)

щоразу дає протилежні результати: якщо один Qubit виміряно в стані 0\vert 0\rangle, то інший гарантовано буде виявлений у стані 1\vert 1\rangle.

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

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

Чи є стан ψ=11\vert \psi\rangle = \vert 11\rangle заплутаним? Чому?

Відповідь:

Він не є заплутаним. Хоча результати завжди однакові при вимірюванні обох Qubit, це лише тому, що кожен Qubit завжди зафіксований у стані 1\vert 1\rangle. Результат вимірювання одного Qubit насправді не залежить від іншого — обидва просто завжди перебувають у стані 1\vert 1\rangle.

Загалом, якщо ти можеш описати стан кожного Qubit окремо і потім перемножити їх ось так:

ψ=ψ1ψ0\vert \psi\rangle = \vert \psi_1\rangle \vert \psi_0\rangle

Тоді це називається «добутковим станом» і він не є заплутаним.

Векторна нотація

Часто корисно використовувати вектори та матриці, щоб побачити, як квантовий стан перетворюється під різними операціями. У цьому представленні наші квантові стани будуть векторами, а наші квантові Gate (розглянуті в наступному розділі) — матрицями, що перетворюють вектори.

Для одного Qubit векторна форма станів обрана такою: 0=(10)\vert 0\rangle = \begin{pmatrix}1 \\ 0\end{pmatrix} 1=(01)\vert 1\rangle = \begin{pmatrix}0 \\ 1\end{pmatrix} Таким чином, довільний стан ψ=a0+b1\vert \psi\rangle = a\vert 0\rangle+b\vert 1\rangle можна записати як ψ=(ab)\vert \psi\rangle =\begin{pmatrix}a \\ b\end{pmatrix}

Для загального nn-кубітного стану нам знадобиться 2n2^n-вимірний вектор, із базисними станами, впорядкованими, як можна очікувати, у порядку зростання двійкового значення:

0000=(1000),0001=1110=(0010),1111=(0001)\vert 0 \dots 000\rangle = \begin{pmatrix}1 \\ 0 \\ 0 \\ \vdots \\ 0\end{pmatrix}, \vert 0 \dots 001 \rangle = \vert 1 \dots 110\rangle = \begin{pmatrix}0 \\ \vdots \\ 0 \\ 1 \\ 0\end{pmatrix}, \vert 1 \dots 111 \rangle = \begin{pmatrix}0 \\ \vdots \\ 0 \\ 0\\ 1\end{pmatrix}

Маючи на увазі цей вибір векторної нотації, ми можемо ввести необхідні нам квантові Gate, їхні дії на квантові стани та їхні матричні форми.

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

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

Для двокубітної системи існує чотири обчислювальних базисних стани. Запиши кожен з них у нотації «кет» та у векторній нотації.

Відповідь:

00=(1000),01=(0100),,10=(0010),11=(0001)\vert 00\rangle = \begin{pmatrix}1 \\ 0 \\ 0 \\ 0\end{pmatrix}, \vert 01 \rangle = \begin{pmatrix}0 \\ 1 \\ 0 \\ 0\end{pmatrix}, \dots, \vert 10\rangle = \begin{pmatrix}0 \\ 0 \\ 1 \\ 0\end{pmatrix}, \vert 11 \rangle = \begin{pmatrix}0 \\ 0 \\ 0\\ 1\end{pmatrix}

Gate \rightarrow квантові Gate

Так само як класичні Gate — NOT, AND, OR і XOR — можна комбінувати для побудови довільних класичних Circuit, квантові Gate відіграють ту ж роль у квантових обчисленнях. Оскільки Qubit мають додаткові квантово-механічні особливості, квантові Gate відповідно багатші. Хоча ми все ще можемо описати їхню дію на базисні стани 0|0\rangle та 1|1\rangle за допомогою таблиці істинності, це не дає повної картини. Для квантових Gate часто природніше використовувати матричне представлення, оскільки вони також діють на суперпозиції базисних станів.

Нижче ми представимо найпоширеніші квантові Gate та те, як вони перетворюють Qubit, з якими взаємодіють. Де це доречно, ми пов'яжемо їх зі знайомими класичними Gate.

Однокубітні Gate

Gate XX: Це квантовий еквівалент операції NOT. Його таблиця істинності виглядає точно так само, як у класичного Gate NOT:

ВхідВихід
0\vert 0\rangle1\vert 1\rangle
1\vert 1\rangle0\vert 0\rangle

І матричне представлення:

X=(0110)X=\begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}

У Qiskit створення Circuit з Gate XX виглядає так:

from qiskit import QuantumCircuit

qc = QuantumCircuit(1)
qc.x(0)
qc.draw("mpl")

Вивід попередньої комірки коду

У цій дуже простій діаграмі Circuit Qubit представлений дротом — чорною горизонтальною лінією, а Gate відображається як прямокутник на цьому дроті.

Gate Адамара: Створює стан суперпозиції. Таблиця істинності:

ВхідВихід
0\vert 0\rangle12(0+1)\frac{1}{\sqrt{2}}\left(\vert 0\rangle+\vert 1\rangle\right)
1\vert 1\rangle12(01)\frac{1}{\sqrt{2}}\left(\vert 0\rangle-\vert 1\rangle\right)

Матричне представлення: H=12(1111)H=\frac{1}{\sqrt{2}}\begin{pmatrix} 1 & 1 \\ 1 & -1 \end{pmatrix}

Circuit з Gate Адамара будується так:

from qiskit import QuantumCircuit

qc = QuantumCircuit(1)
qc.h(0)
qc.draw("mpl")

Вивід попередньої комірки коду

Gate ZZ: Додає фазовий зсув Δϕ=π\Delta \phi = \pi до стану 1|1\rangle:

ВхідВихід
0\vert 0\rangle0\vert 0\rangle
1\vert 1\rangle1-\vert 1\rangle

Z=(1001)Z=\begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix}

У Qiskit створення Circuit з Gate ZZ виглядає так:

qc = QuantumCircuit(1)
qc.z(0)
qc.draw("mpl")

Вивід попередньої комірки коду

Gate TT: Додає фазовий зсув Δϕ=π/4\Delta \phi = \pi/4 до стану 1|1\rangle:

ВхідВихід
0\vert 0\rangle0\vert 0\rangle
1\vert 1\rangleeiπ/41e^{i\pi/4}\vert 1\rangle

T=(100eiπ/4)T=\begin{pmatrix} 1 & 0 \\ 0 & e^{i\pi/4} \end{pmatrix}

У Qiskit створення Circuit з Gate TT виглядає так:

qc = QuantumCircuit(1)
qc.t(0)
qc.draw("mpl")

Вивід попередньої комірки коду

Багатокубітні вентилі

Двокубітні вентилі можуть нагадувати класичні двобітові вентилі, але з одним важливим застереженням: усі квантові вентилі мають бути оборотними. У термінах лінійної алгебри це означає, що вони представлені унітарними матрицями. Отже, два вхідні кубіти завжди відображаються на два вихідних, і операцію можна, в принципі, скасувати. Це контрастує з класичними вентилями, які ми розглядали вище, — такими як AND або OR, — котрі втрачають інформацію та є незворотними: знаючи вихід, неможливо однозначно визначити вхід.

Вентиль CNOT (керований NOT): Два вхідних кубіти називаються «керуючим» (control) і «цільовим» (target) кубітами. Керуючий кубіт залишається незміненим, але його стан визначає, що відбувається з цільовим кубітом. Якщо керуючий кубіт перебуває в стані 1\vert 1\rangle, то до цільового застосовується вентиль XX; якщо стан керуючого кубіта — 0\vert 0\rangle, жодних змін не відбувається. У наведеному нижче записі припустимо, що кубіт AA (крайній правий) є керуючим, а кубіт BB (крайній лівий) — цільовим. Нижче використовується позначення CNOT(qcontrol,qtarget)BA.CNOT(q_{control},q_{target})\vert BA\rangle.

CNOT(A,B)BAinput=BAoutputCNOT(A,B)\vert BA\rangle_{input} = \vert BA\rangle_{output}

ВхідВихід
00\vert 00\rangle00\vert 00\rangle
01\vert 01\rangle11\vert 11\rangle
10\vert 10\rangle10\vert 10\rangle
11\vert 11\rangle01\vert 01\rangle

Отже, матриця, що представляє цю дію:

CNOT=(1000000100100100)CNOT=\begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0\end{pmatrix}

qc = QuantumCircuit(2)
qc.cx(0, 1)
qc.draw("mpl")

Output of the previous code cell

Це перша діаграма Circuit, яку ми бачимо з двома кубітами, що представлені двома лініями. Вентиль CNOT застосовано між двома кубітами: q0q_0 є керуючим, а q1q_1 — цільовим.

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

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

Більшість вентилів мають однакову матричну форму в Qiskit і скрізь в іншому місці. Але вентиль CNOT діє на два кубіти, і тому порядок кубітів раптом стає проблемою. Тексти, що впорядковують кубіти як q0,q1,...\vert q_0,q_1,...\rangle, покажуть іншу матричну форму для своїх вентилів CNOT. Перевір за допомогою явного матричного множення, що наведена вище матриця CNOT має правильну дію на стан 01.\vert 01\rangle.

Відповідь:

CNOT01=(1000000100100100)(0100)=(0001)=11CNOT\vert 01\rangle =\begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0\end{pmatrix}\begin{pmatrix}0 \\ 1 \\ 0 \\0\end{pmatrix} = \begin{pmatrix}0 \\ 0 \\ 0 \\1\end{pmatrix} = \vert 11\rangle

Вентиль SWAP: Цей вентиль обмінює стани двох кубітів. Таблиця істинності:

ВхідВихід
00\vert 00\rangle00\vert 00\rangle
01\vert 01\rangle10\vert 10\rangle
10\vert 10\rangle01\vert 01\rangle
11\vert 11\rangle11\vert 11\rangle

Отже, матриця, що представляє цю дію:

SWAP=(1000001001000001)SWAP=\begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1\end{pmatrix}

qc = QuantumCircuit(2)
qc.swap(0, 1)
qc.draw("mpl")

Output of the previous code cell

Вентиль SWAP насправді можна побудувати з трьох CNOTів. Щоб побачити як, ми можемо розкласти (decompose()) вентиль за допомогою Qiskit:

qc = QuantumCircuit(2)
qc.swap(0, 1)
qc.decompose().draw("mpl")

Output of the previous code cell

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

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

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

Перевір, що комбінація CNOTів вище дійсно дає вентиль SWAP. Це можна зробити за допомогою матричного множення або будь-якого іншого методу.

Відповідь:

За допомогою матричного множення:

(1000000100100100)(1000010000010010)(1000000100100100)=(1000001001000001)=SWAP \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0\end{pmatrix} \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0\end{pmatrix} \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0\end{pmatrix} = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1\end{pmatrix} = SWAP ~\checkmark

За допомогою таблиці істинності, що показує зміну станів після кожного CNOT. В останньому стовпці стани мають відповідати стовпцю «вихід» таблиці істинності SWAP:

ВхідCNOT(A,B)CNOT(B,A)CNOT(A,B)
00\vert 00\rangle00\vert 00\rangle00\vert 00\rangle00\vert 00\rangle \checkmark
01\vert 01\rangle11\vert 11\rangle10\vert 10\rangle10\vert 10\rangle \checkmark
10\vert 10\rangle10\vert 10\rangle11\vert 11\rangle01\vert 01\rangle \checkmark
11\vert 11\rangle01\vert 01\rangle01\vert 01\rangle11\vert 11\rangle \checkmark

Вентиль Тофолі (або «керований-керований NOT» (CCNOT)): Це трикубітний вентиль. Назва «керований-керований NOT» вже підказує, як він працює: є два керуючих кубіти й один цільовий, і стан цільового кубіта перевертається лише тоді, коли обидва керуючих кубіти перебувають у стані 1\vert 1\rangle. Ми дотримуємося тієї самої угоди про порядок, що й у CNOT:

CCNOT(ControlA,ControlB,TargetC)CBACCNOT(Control A, Control B, Target C)\vert CBA\rangle

Отже, таблиця істинності:

ВхідВихід
000\vert 000\rangle000\vert 000\rangle
001\vert 001\rangle001\vert 001\rangle
010\vert 010\rangle010\vert 010\rangle
011\vert 011\rangle111\vert 111\rangle
100\vert 100\rangle100\vert 100\rangle
101\vert 101\rangle101\vert 101\rangle
110\vert 110\rangle110\vert 110\rangle
111\vert 111\rangle011\vert 011\rangle

І матриця, що представляє цю дію:

CCNOT=(1000000001000000001000000000000100001000000001000000001000010000)CCNOT=\begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\end{pmatrix}
qc = QuantumCircuit(3)
qc.ccx(0, 1, 2)
qc.draw("mpl")

Output of the previous code cell

Вентиль Тофолі також можна розкласти в CNOTи разом із деякими іншими вентилями. Однак це значно складніше, ніж розкладання SWAP, тому перевірку цього розкладання залишено як необов'язкове завдання наприкінці модуля.

Вимірювання

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

Зокрема, для NN-кубітного квантового стану ψ=i=02N1cii\vert \psi\rangle = \sum_{i=0}^{2^N-1} c_i \vert i\rangle вимірювання колапсує стан до одного з базисних векторів i\vert i\rangle з імовірністю, рівною ci2\vert c_i\vert ^2.

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

У Qiskit результат вимірювання надсилається в класичний регістр, де зберігається як класичний біт. Створення Circuit з вимірюванням виглядає так:

qc = QuantumCircuit(
1, 1
) # the second number is the number of classical bits in the circuit
qc.measure(0, 0)
qc.draw("mpl")

Output of the previous code cell

Схеми

Тепер, коли ми знаємо, як працюють кубіти, вентилі та вимірювання, давай створимо і виконаємо власну квантову Circuit! Для цього нам потрібно познайомитись із корисним робочим процесом під назвою «патерни Qiskit».

Фреймворк патернів Qiskit

Фреймворк патернів Qiskit — це загальна процедура підходу до розв'язання задач за допомогою квантового комп'ютера та їх розв'язання. Він складається з чотирьох кроків:

  1. Відображення нашої задачі на квантові схеми й оператори
  2. Оптимізація схеми під цільове обладнання
  3. Виконання на цільовому обладнанні
  4. Постобробка результатів

Щоб проілюструвати ці кроки, ми реалізуємо квантову версію схеми напівсуматора, розглянутої вище.

1. Відображення

Класична схема суматора використовує вентилі XOR і AND для обчислення бітів суми та переносу відповідно. Ми можемо адаптувати ці вентилі до квантового контексту, щоб створити квантовий напівсуматор. Пам'ятаймо, що квантові вентилі є оборотними, тому ми не можемо просто перезаписати вхідні дані. Натомість ми вводимо два допоміжних кубіти, ініціалізованих у 0\vert 0\rangle, для зберігання результатів суми та переносу. Отже, наш повний квантовий стан складатиметься з кубітів AA і BB, а також кубітів суми й переносу, які ми позначимо SS і CC:

ψ=CSBA\vert \psi\rangle = \vert C S B A\rangle

Тепер нам потрібні квантові вентилі, що виконують те саме, що вентилі XOR і AND у класичній схемі.

Сума:

Для XOR ми застосовуємо два CNOTи, обидва з керуючими кубітами AA і BB та цільовим кубітом SS. Якщо AA і BB різні, то один із вентилів CNOT перекине SS у стан 1\vert 1\rangle. Якщо обидва AA і BB у стані 0\vert 0\rangle, то SS залишиться незмінним у стані 0\vert 0\rangle. Якщо обидва AA і BB у стані 1\vert 1\rangle, то стан SS перекинеться двічі і повернеться до стану 0\vert 0\rangle.

Перенос:

Для біта переносу нам потрібно щось, що працює як класичний вентиль AND.

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

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

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

Відповідь:

Це вентиль Тофолі! Пам'ятай, що вентиль Тофолі, або керований-керований NOT, перекидає цільовий стан тоді й тільки тоді, коли керуючий кубіт 0 І керуючий кубіт 1 обидва перебувають у стані 1\vert 1\rangle. Отже, якщо цільовий кубіт починає у стані 0\vert 0\rangle, то вентиль має ту саму дію, що й AND.

Отже, тепер у нас є всі інгредієнти для створення квантової схеми:

# qubits: a, b, sum, carry
qc = QuantumCircuit(4)

# Choose values for A and B:
a = 0
b = 0

# Prepare A and B qubits according to selected values:
if a:
qc.x(0)
if b:
qc.x(1)

# XOR (sum) into qubit 2
qc.cx(0, 2)
qc.cx(1, 2)

# AND (carry) into qubit 3
qc.ccx(0, 1, 3) # a AND b

# measure
qc.measure_all()

qc.draw("mpl")

Output of the previous code cell

Вище наведено діаграму Circuit для квантового напівсуматора. Як зазначалося раніше, лінії представляють кубіти від 00 до 33 у порядку зверху вниз, а класичний бітовий регістр — це нижня лінія з подвійним контуром. Читаючи зліва направо, ми бачимо, які вентилі застосовуються до кожного кубіта за розташуванням блоків на відповідних лініях. Нарешті, вимірювання показані в кінці. Вимірювання колапсують стани кубітів до визначених значень 00 або 11, і результати надсилаються до класичного регістра.

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

CCNOT(q0,q1,q3)CNOT(q1,q2)CNOT(q0,q2)q3q2q1q0CCNOT(q_0,q_1,q_3)CNOT(q_1, q_2)CNOT(q_0,q_2)\vert q_3 q_2 q_1 q_0\rangle

2. Оптимізація

Далі нам потрібно оптимізувати схему для запуску на квантовому обладнанні. Ця оптимізація виконується за допомогою Transpiler, який перетворює абстрактну схему, показану вище, на інструкції, зрозумілі квантовому комп'ютеру. Він призначає логічні кубіти реальним фізичним кубітам на процесорі та переписує вентилі через власний набір нативних вентилів, оптимізованих для запуску на квантовому комп'ютері. Нарешті, Transpiler також реалізує так зване «придушення та пом'якшення помилок» (error suppression and mitigation), щоб мінімізувати вплив помилок на результат. Для нашої дуже простої схеми це не так важливо, але якщо ти продовжиш свій шлях у квантових обчисленнях і захочеш запускати складніші схеми, то незабаром побачиш цінність придушення та пом'якшення помилок. Щоб дізнатися більше, перегляньте курс Олівії Лейн «Квантові обчислення на практиці».

Спочатку ми завантажимо пакети, необхідні для зв'язку з квантовими комп'ютерами IBM®, і виберемо Backend для запуску. Ми можемо вибрати найменш завантажений Backend або конкретний Backend, властивості якого нам відомі.

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

# Load the Qiskit Runtime service
from qiskit_ibm_runtime import QiskitRuntimeService

# Load the Qiskit Runtime service

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

# Use the least busy backend, or uncomment the loading of a specific backend like "ibm_brisbane".
backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127)
# backend = service.backend("ibm_brisbane")
print(backend.name)
ibm_fez

Тепер ми використаємо Transpiler для оптимізації схеми. Можна вибрати рівень оптимізації від 0 (без оптимізації) до 3 (максимальна оптимізація). Щоб дізнатися, що означає кожен рівень, перегляньте посібник «Встановлення рівня оптимізації Transpiler». Отримана схема буде суттєво відрізнятися від логічної схеми, яку ми створили на кроці відображення.

# Transpile the circuit and optimize for running on the quantum computer selected
# 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)

qc_isa.draw("mpl")

Output of the previous code cell

«Sampler» — це примітив, призначений для вибірки можливих станів, що виникають у результаті виконання квантової схеми, та збирання статистики про те, які стани можуть бути виміряні і з якою імовірністю. Тут ми імпортуємо Qiskit Runtime Sampler:

# Load the Runtime primitive and session
from qiskit_ibm_runtime import SamplerV2 as Sampler

sampler = Sampler(mode=backend)

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

# Load the backend sampler
from qiskit.primitives import BackendSamplerV2

# Load the Aer simulator and generate a noise model based on the currently-selected backend.
from qiskit_aer import AerSimulator
from qiskit_aer.noise import NoiseModel

noise_model = NoiseModel.from_backend(backend)

# Define a simulator using Aer, and use it in Sampler.
backend_sim = AerSimulator(noise_model=noise_model)
sampler_sim = BackendSamplerV2(backend=backend_sim)

# Alternatively, load a fake backend with generic properties and define a simulator.
# backend_gen = GenericBackendV2(num_qubits=18)
# sampler_gen = BackendSamplerV2(backend=backend_gen)

3. Виконання

Після підготовки схеми ми можемо запустити її на квантовому комп'ютері!

job = sampler.run([qc_isa], shots=100)
# job = sampler_sim.run([qc_isa]) # uncomment if you want to run on a simulator
res = job.result()
counts = res[0].data.meas.get_counts()

4. Постобробка

Тепер ми готові переглянути результати! Виведемо гістограму 100 вибірок схеми.

from qiskit.visualization import plot_histogram

print("counts = ", counts)
plot_histogram(counts)
counts =  {'0000': 90, '0100': 4, '1100': 3, '0010': 3}

Output of the previous code cell

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

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

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

Використовуючи бітовий рядок з найбільшою кількістю відліків як значення для AA, BB, SS та CC, перевір, що квантова схема суматора спрацювала.

Відповідь:

Нам потрібно перевірити, що A+B=S+2×CA+B = S+2 \times C. Пам'ятай, що порядок бітового рядка відповідає запису з молодшим бітом першим (little-endian), тому він читається як CSBA.

З гістограми вище видно, що домінуючим є бітовий рядок 0000.

0+0=0+0×2=0 0 + 0 = 0 + 0 \times 2 = 0 ~\checkmark

Поверніться й змініть значення AA і BB на A=1A=1 та B=1B=1, після чого пройдіть кроки патернів Qiskit знову, щоб перезапустити схему. Перевір, що схема суматора знову спрацювала.

Відповідь:

Ти маєш отримати гістограму, де домінуючим бітовим рядком є 1011:

1+1=0+1×2=2 1 + 1 = 0 + 1 \times 2 = 2 ~\checkmark

Одна з переваг квантового напівсуматора над класичним полягає в тому, що він може працювати з квантовими вхідними даними. Тобто він може «додавати» кубіти AA і BB, навіть якщо вони перебувають у станах суперпозиції. У розділі «Завдання підвищеної складності» нижче тебе попросять підготувати кубіти в суперпозиціях і подивитися, що відбудеться!

Висновок

Цей модуль був розроблений, щоб дати тобі міцне базове розуміння основних принципів квантових обчислень шляхом порівняння їх із класичними. Ми розглянули класичну схему напівсуматора, а потім показали, як адаптувати її для запуску з кубітами на квантовому комп'ютері. Тепер ти готовий досліджувати інші модулі Qiskit in the Classroom!

Ключові поняття:

  • На відміну від класичних бітів, які можуть мати лише значення 0 і 1, кубіти також можуть перебувати в станах суперпозиції обох значень 0 і 1.
  • Декілька кубітів можуть перебувати в суперпозиції над класично допустимими бітовими рядками, що називаються обчислювальними базисними станами.
  • Кілька кубітів можуть бути заплутаними так, що стан одного залежить від стану іншого.
  • Конвенція Qiskit передбачає використання запису з молодшим бітом першим (little-endian notation), де найменш значущий кубіт q0q_0 розташований крайнім праворуч, а найбільш значущий кубіт qNq_N — крайнім ліворуч.
  • Квантові вентилі — це оборотні операції, представлені унітарними матрицями, що діють на вектори квантового стану. У такому записі матриця, найближча до вектора (крайня права), діє першою.
  • Вимірювання колапсує квантовий стан суперпозиції до одного з класично допустимих станів з імовірністю, рівною квадрату амплітуди відповідного обчислювального базисного стану в суперпозиції.
  • Квантові схеми часто зображаються у вигляді діаграм квантових Circuit, де кубіти зображені горизонтальними лініями, а квантові вентилі розташовані вздовж цих ліній зліва направо.
  • Для запуску квантової схеми ми використовуємо чотири кроки робочого процесу патернів Qiskit: Відображення, Оптимізація, Виконання, Постобробка.

Запитання

Запитання «Так/Ні»

  1. Один біт у класичному комп'ютері може зберігати лише значення 0 або 1.

  2. Заплутаність означає, що стан одного кубіта не залежить від стану іншого.

  3. Квантові вентилі, як правило, є незворотними операціями.

  4. Конвенція Qiskit розміщує найменш значущий кубіт q0q_0 на крайній лівій позиції.

  5. Вимірювання квантового стану завжди дає однаковий результат при багаторазовому повторенні.

  6. Вентиль Адамара створює суперпозицію в одному кубіті.

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

  8. Кількість можливих класичних станів для NN бітів дорівнює 2N2N.

  9. Імовірності результатів квантових вимірювань визначаються квадратами амплітуд класично вимірюваних базисних станів.

Запитання з короткою відповіддю

  1. Які основні відмінності між бітом і кубітом?

  2. Що відбувається з квантовим станом під час вимірювання?

  3. Чому в Qiskit використовується запис з молодшим бітом першим (little-endian notation)?

  4. Які чотири кроки входять до робочого процесу патернів Qiskit?

Завдання підвищеної складності:

  1. У модулі ми використовували суматор лише для додавання класично допустимих станів AA і BB. Але ми також можемо підготувати AA і BB у суперпозиціях! Зміни код так, щоб підготувати кожен кубіт в рівній суперпозиції 0 і 1, запусти нову схему та отримай нову гістограму. Що ти бачиш? Поясни, що відбувається.