Скажу сразу: как бы мне этого ни хотелось, квантовая телепортация не позволит перенести мою бабушку из деревни в мою квартиру. Бабуля знает, что мне нравятся всякие квантовые штуки, и решила вместо денег и носков отправить мне на день рождения квантовое состояние. Здесь мы поговорим о другом — передаче квантовой информации.
Это вторая статья из серии о квантовом программировании. Предполагается, что читатель уже знаком с первой частью.
![](https://habrastorage.org/r/w780q1/webt/k_/0n/u4/k_0nu4o_wb5qjn-zoc3d9xavqv0.jpeg)
К сожалению, отправить кубит ни по электронной почте, ни посылкой нельзя. Они передаются по специальным квантовым каналам, а в деревне и Интернет-то появился совсем недавно.
Но, может быть, бабушке удастся передать квантовую информацию по классическому каналу связи (например, через Интернет или телефонную линию)? Проблема заключается в том, что диапазон возможных значений квантового состояния непрерывен, поэтому для его точного описания потребуется бесконечное количество классических бит. Моя бабушка — весьма занятой человек, и у нее нет времени набирать столько бит.
Она уже начала терять всякую надежду, и тут я говорю: «Бабуль, все в порядке». Помнишь, мы в прошлую среду за чаем смастерили состояние Белла? Передать квантовое состояние можно через него! Такая передача квантового состояния с использованием классических каналов связи и называется квантовой телепортацией. Мы постараемся разобраться, как она работает — в теории и в коде.
Чтобы все описанное ниже сработало, мы с бабушкой должны подготовить состояние Белла: перевести ее кубит |G⟩ и мой кубит |F⟩ в состояние запутанности. Я расстаюсь с бабушкой, но свой кубит (половину состояния Белла) беру с собой. Наши кубиты будут находиться в состоянии запутанности вне зависимости от того, какое расстояние их разделяет — несколько километров или несколько миллиардов световых лет.
Помните, мы обсуждали замечательное свойство запутанных состояний — связанность результатов измерений соответствующих кубитов? Если бабушка измерит состояние своего кубита, это скажется на моем кубите (вне зависимости от расстояния). Ниже мы будем активно использовать это свойство.
![](https://habrastorage.org/r/w1560/webt/f5/92/xt/f592xt9olphpusouyag8i5qe47e.png)
Исходное состояние будем описывать с помощью приведенной выше диаграммы. В верхнем левом углу находится предмет всех наших стараний — кубит, который бабушка хочет мне отправить. Он находится в неизвестном состоянии, которое можно представить следующим образом:
![](https://habrastorage.org/r/w1560/webt/9t/n2/mr/9tn2mrk_qvsnxo2xgnqvwzogv9e.png)
Кроме того, в ее распоряжении находится кубит |G⟩, который, как мы только что обсуждали, запутан с моим кубитом, |F⟩ (эта их связь показана волнистой линией). Теперь два кубита находятся в состоянии Белла, которое описывается формулой
![](https://habrastorage.org/r/w1560/webt/xk/9h/qu/xk9hquewk0hlpo8mbm2sf93ep6c.png)
Вначале мы запутаем бабушкин кубит |G⟩ с состоянием |ψ⟩. Скоро поймете зачем. В предыдущей статье мы узнали, что два кубита можно запутать с помощью схемы, состоящей из вентиля CNOT и вентиля Адамара. Давайте посмотрим, как этот процесс представляется с помощью квантовой цепи.
[Чтобы лучше понимать эти обозначения на диаграммах квантовых цепей, рекомендую вкратце ознакомиться со статьей Квантовые цепи и вентили — вводный курс.]
![](https://habrastorage.org/r/w1560/webt/ur/qv/or/urqvorrxksyc5ylc1z0onmhtuva.png)
Если добавить вентиль CNOT, схема принимает следующий вид. Состояние, которое подается на вход CNOT, можно записать как |ψ⟩|G⟩, где первый вход соответствует верхнему проводу, второй — среднему. Если подставить определения |ψ⟩ и |G⟩, получим:
![](https://habrastorage.org/r/w1560/webt/be/re/b4/bereb4jbqtlpzmhawpjoj6k220c.png)
Раскроем скобки:
![](https://habrastorage.org/r/w1560/webt/we/fx/cg/wefxcgi36e17ucapf_30kpjdouc.png)
Таким образом, на вход подается
. Каждое из этих слагаемых проходит через вентиль CNOT. В первой статье мы видели, как действует вентиль CNOT и как он обрабатывает два кубита. Самые внимательные читатели уже заметили, что все наши слагаемые — |000〉, |011〉, |100〉 и |111〉 — состоят из трех кубитов. В этом случае в роли управляющего кубита используется первый, а управляемым является второй (см. ниже).
![](https://habrastorage.org/r/w1560/webt/a6/fc/up/a6fcupyzo4kkijegfdpos3tbnhw.png)
Когда управляющий кубит равен |1〉, значение управляемого кубита меняется на противоположное. Таким образом, CNOT превращает набор кубитов |100〉 в |110〉, а |111〉 — в |101〉. Все другие состояния остаются прежними.
![](https://habrastorage.org/r/w1560/webt/kh/n5/z2/khn5z2_mlswhswzplwqlrls9gfk.png)
Это значит, что состояние трех кубитов после вентиля CNOT будет описываться следующим выражением:
.
Второй этап запутывания кубита |G⟩ с состоянием |ψ⟩ — применение вентиля Адамара к первому кубиту. Вот как это выглядит на диаграмме квантовой цепи:
![](https://habrastorage.org/r/w1560/webt/ne/z4/gs/nez4gsn85tsbo_tbagbw710xi8q.png)
Напомню, что вентиль Адамара преобразует |0〉 и |1〉 в состояния
![](https://habrastorage.org/r/w1560/webt/rg/xp/nv/rgxpnv5h13982tewsnzfgs_xjoq.png)
После вентиля CNOT кубиты находились в состоянии
. Применим вентиль Адамара к первому кубиту каждого слагаемого. Результат выглядит довольно неаккуратно:
![](https://habrastorage.org/r/w1560/webt/lb/xu/rd/lbxurd3ourgyof4z6wga6us4c0q.png)
Итак, мы получили
![](https://habrastorage.org/r/w1560/webt/bs/an/nj/bsannjuidvlatehsv0rhyg_nqh8.png)
Давайте немного причешем нашу формулу. Как можно заметить, в первом слагаемом
есть две дроби со знаменателем √2. Перемножим их:
![](https://habrastorage.org/r/w1560/webt/lg/uy/za/lguyzaask0mansqwscrdzb-imus.png)
Если применить аналогичную операцию к другим слагаемым, получим
,
и
. Как можно заметить, у каждой дроби есть множитель 1/2. Если вынести его за скобки, получим:
![](https://habrastorage.org/r/w1560/webt/f6/d8/l6/f6d8l6y8guuoeh4kwd793wgyffs.png)
Выглядит уже лучше. Теперь раскроем скобки (это упростит нам работу на следующем этапе). В качестве примера я приведу выкладки для слагаемого
.
![](https://habrastorage.org/r/w1560/webt/kh/qr/4p/khqr4piktpjstq2rsecg4p1jyhq.png)
Остальные «читателю предлагается сделать в качестве упражнения». Если честно, я такие заманчивые предложения обычно игнорирую. Вот как будут выглядеть оставшиеся слагаемые, если раскрыть скобки:
![](https://habrastorage.org/r/w1560/webt/o3/g7/bf/o3g7bf5xpskc5qzygdmlxr-fbhk.png)
Их сумма равна
![](https://habrastorage.org/r/w1560/webt/2q/_i/k2/2q_ik2yfclfcxndjioecdbha1i0.png)
Итак, мы запутали бабушкин кубит |G⟩ с кубитом |ψ⟩. Теперь измерим их. Но перед этим результаты нужно привести к виду, более удобному для понимания.
Это последний раз, честное слово. Вот все возможные результаты измерения первого и второго кубита: 00, 01, 10, 11. Пока мы не знаем, каким в каждом из этих случаев будет наш третий кубит. Сгруппируем слагаемые так, чтобы понять, в каком состоянии будет находиться третий кубит, а именно мой кубит |F⟩.
Пока наш результат выглядит так:
![](https://habrastorage.org/r/w1560/webt/zl/t2/-u/zlt2-ub0l47fknadufp0isa5u4o.png)
Выделим первый и второй кубит каждого слагаемого:
![](https://habrastorage.org/r/w1560/webt/yx/oj/pr/yxojpr3abserpkisoggbvxmkbim.png)
Рассмотрим случаи, в которых первый и второй кубит равны |00〉. Им соответствуют слагаемые
. Их можно преобразовать так:
![](https://habrastorage.org/r/w1560/webt/xf/44/g7/xf44g7rtwrbomluqo0mqiyg-nbg.png)
То же самое можно сделать для случаев |01〉, |10〉 и |11〉.
![](https://habrastorage.org/r/w1560/webt/fj/cy/hf/fjcyhfzzj5h3jjcxa7z3o5id6v8.png)
После преобразования выражение принимает следующий вид:
![](https://habrastorage.org/r/w1560/webt/th/ex/uw/thexuwgnwof5xipum2uqlikqw08.png)
Отлично.
Так выглядит наша цепь с добавленными символами измерения. Обратите внимание на двойные черты после символов измерения. Они соответствуют переносу классических битов, которые и являются результатами измерений.
![](https://habrastorage.org/r/w1560/webt/l4/ud/ty/l4udtyikervtl8ibehpu2u2jv8k.png)
Моя бабушка также измеряет свои два кубита, |G⟩ и |ψ⟩. Как мы уже говорили, всего возможно четыре результата измерения: 00, 01, 10 или 11. При измерении кубита суперпозиция его состояний коллапсирует. Предположим, мы измерили состояние первого кубита |ψ⟩ и получили 0. Суперпозиция коллапсирует, и у нас остаются только те слагаемые, которые согласуются с таким результатом измерения (0), то есть следующие:
![](https://habrastorage.org/r/w1560/webt/eu/wx/tt/euwxttlm8pifu1f-el2nwon0gbw.png)
Предположим теперь, что мы измерили состояние второго кубита, |G⟩, и получили 0. Суперпозиция коллапсирует. Остается единственное слагаемое, которое согласуется с обоими результатами измерения (0 и 0), то есть следующее:
![](https://habrastorage.org/r/w1560/webt/o1/4z/oz/o14zoz86mktxxprbtlg7-b5twd8.png)
Теперь мы знаем, в каком состоянии находится третий кубит (то есть мой кубит |F⟩): в состоянии
.
Что, если бы в результате измерения мы получили 01? Вернемся к нашему приведенному результату:
![](https://habrastorage.org/r/w1560/webt/9t/jp/u7/9tjpu75gd8e409ok31j_ig0ptkc.png)
Рассуждая по аналогии, мы поймем, что единственное слагаемое, которое соответствует результату измерения 01 —
, а значит, мой кубит должен находиться в состоянии
. Если после измерений бабушка получила результат 10, то я знаю, что третий кубит в состоянии
, а если она получила 11, то третий кубит равен
.
Этот результат можно представить в виде таблицы:
Мы остановились на том, что бабушка измерила состояние своих двух кубитов, позвонила мне и рассказала о результате, так что я знаю состояние моего кубита. Помните, что неизвестное состояние, с которого мы начали, |ψ⟩, было равно
. Нам нужно применить к моему кубиту определенные операции, чтобы привести его в это состояние — в состояние, которое мне хотела отправить бабушка (в противном случае я получу нечто совсем иное).
Сейчас сделать это будет просто. Взгляните на таблицу выше. Если результат измерений 00, а мой кубит находится в состоянии
, то выполнять какие-либо операции над ним не нужно — он уже в состоянии |ψ⟩. Это самый простой случай.
Если результат измерений 01, то мой кубит находится в состоянии
. Если сравнить его с состоянием |ψ⟩, станет понятно, что нам нужно поменять местами коэффициенты при |0〉 и |1〉. Для этого просто пропустим мой кубит через вентиль NOT, то есть вентиль X, и получим нужный результат
.
При результате измерений 10 мой кубит находится в состоянии
. Сравним его с |ψ⟩. У нас есть
, а нужно
. Чтобы сделать желаемое действительным, применим вентиль Z, который меняет знак.
И последний вариант — 11. В этом случае мой кубит находится в состоянии
. Здесь нужно поменять местами коэффициенты при |0〉 и 1〉, а также знак при
. Таким образом, мой кубит нужно пропустить через вентиль X, а потом через Z. Тогда мы получим нужный результат,
. Внесем эти операции в таблицу.
![](https://habrastorage.org/r/w1560/webt/z0/5f/fd/z05ffddqi6o9emspwiubae-d_ti.png)
Обратите внимание: если первый бит результата измерения равен 1, то мы применяем вентиль Z, а если второй бит равен 1, то применяем вентиль X. Окончательный вариант цепи показан ниже. Мы добавили вентиль Z, используя верхний провод в качестве управляющего, и вентиль X, для которого управляющим будет второй провод. Управляемым при этом будет мой кубит (потому что именно его нужно обработать с помощью вентилей).
![](https://habrastorage.org/r/w1560/webt/9h/5s/a3/9h5sa31hvg9n6-wt6kbmf1o2j3w.png)
Итак, мы показали, что бабушке достаточно передать всего два классических бита (а именно результаты измерения состояний кубитов |G⟩ и |ψ⟩), чтобы мы могли узнать неизвестное до этого состояние кубита. Благодаря явлению квантового запутывания информация от бабушки помогает узнать значения коэффициентов α и β. При этом нам удалось обойтись без канала квантовой связи. Поэтому такой метод называется квантовой телепортацией.
Итак, мы немного разобрались в теории квантовой телепортации. Пора переходить к коду!
Если на каком-либо шаге вам понадобится помощь, готовый код доступен здесь (просто клонируйте или скачайте репозиторий, откройте файл QuantumTeleportation.sln в Visual Studio и переходите к этапу 5).
Создайте в Visual Studio новый проект типа «Приложение Q#» и присвойте ему какое-нибудь простое и понятное название — например, QuantumTeleportation.
Загрузите копию кода с примерами квантовых вычислений на свой компьютер. Для этого клонируйте или скачайте репозиторий.
Теперь нужно заменить весь код в файле Operation.qs на код из файла TeleportationSample.qs, который находится в разделе Quantum > Samples > Teleportation здесь.
Замените весь код в файле Driver.cs на содержимое файла Program.cs.
Нажмите на кнопку «start», чтобы запустить код. На экран будут выведены результаты для итераций 0–8. Они должны выглядеть примерно так:
![](https://habrastorage.org/r/w1560/webt/qm/h-/bi/qmh-bi7ehx9tfft55nr6q6qku_8.png)
На самом деле вы сможете в нем разобраться и без моей помощи — код замечательно прокомментирован. Мы просто сопоставим его с теорией, разобранной выше, — это будет несложно.
В первой части статьи мы говорили о трех кубитах: кубит в неизвестном состоянии |ψ⟩ и два кубита в состоянии Белла (один у бабушки, второй у меня). Этим трем кубитам в операции Teleport (Телепортация) соответствуют кубиты msg (неизвестное состояние, которое мне отправляет бабушка), here (кубит у бабушки) и there (мой кубит F, где |ψ⟩ — пересылаемое состояние).
Как уже обсуждалось, мы с бабушкой заранее подготовили пару кубитов в состоянии Белла. Один из них находится у бабушки, второй — у меня. Поэтому в самом начале нам нужно запутать ее кубит, который называется here, с моим, there. В коде для этого используются вентиль Адамара и вентиль CNOT:
![](https://habrastorage.org/r/w1560/webt/ln/qb/bl/lnqbbl3qygs1ysdlvyjcxyveuky.png)
Воспользуемся нашей диаграммой цепи. Я буду добавлять на нее обозначения по мере их появления в коде.
![](https://habrastorage.org/r/w1560/webt/3b/vj/0v/3bvj0vucyk311_4j3rjqta7vuce.png)
Повторяя операции, описанные в начале статьи, мы запутываем кубит бабушки here с неизвестным квантовым состоянием msg. Вентиль CNOT и вентиль Адамара на диаграмме соответствуют следующим строкам кода:
![](https://habrastorage.org/r/w1560/webt/dj/l_/l3/djl_l3qwak5klbreev41llug6b8.png)
Затем мы измерили первый и второй кубиты, msg и here. О результатах именно этих измерений бабушка сообщила мне по телефону. Этим событиям соответствуют условия оператора if:
![](https://habrastorage.org/r/w1560/webt/_b/kh/xt/_bkhxtodqa8j-p_z3gehpugdzse.png)
Как мы обсуждали в конце первой части этой публикации, после получения результатов измерения нужно изменить состояние моего кубита так, чтобы оно соответствовало кубиту |ψ⟩, то есть msg. Как мы говорили, если результат измерения первого кубита равен 1, то мой кубит (there) нужно пропустить через вентиль Z. Эта операция показана выше. Если результат измерения второго кубита равен 1, то мой кубит нужно пропустить через вентиль X.
Готово! Теперь мой кубит находится именно в том состоянии, которое мне хотела передать бабушка.
Давайте подумаем, как с помощью только что рассмотренной операции Teleport можно передать сообщение. Бабушка уже вполне освоилась с квантовой телепортацией и теперь посылает мне не неизвестное квантовое состояние, а известное — сообщение длиной в один бит. Предположим, я спросила бабушку, включила ли она чайник. Ответом будет одно из двух возможных сообщений — да или нет.
Вначале выделим регистр на два кубита, булево сообщение, которое мы будем пересылать (msg), и мой кубит, (there), с помощью которого бабушка будет передавать сообщение. Помните, что нумерация элементов регистра начинается с 0 (так же, как в массивах). Результат выглядит так:
![](https://habrastorage.org/r/w1560/webt/j5/sg/jr/j5sgjrxm9835m99v_jhxcgd3p_o.png)
Кубит msg, который мы выделили, изначально находится в состоянии |0〉 (это состояние по умолчанию для всех выделяемых кубитов). Сообщение бабушки о том, включен ли чайник, может принимать одно из двух значений — да или нет. Если ответ — нет, то ничего дополнительно делать не надо — такое сообщение соответствует состоянию |0〉, в котором кубит msg находится изначально. Если ответ — да, то есть |1〉, то нам нужно пропустить кубит msg через квантовый вентиль NOT, чтобы перевести его в показанное ниже состояние.
![](https://habrastorage.org/r/w1560/webt/bw/hk/8b/bwhk8bximmvyypnxmzok_mkizjy.png)
Далее бабушка передает состояние мне с помощью операции Teleport.
![](https://habrastorage.org/r/w1560/webt/dz/rd/ij/dzrdij0j432haiufs-mk8_axeke.png)
Затем мы измеряем состояние моего кубита, there.
![](https://habrastorage.org/r/w1560/webt/_h/cs/6a/_hcs6ahuh3zl6qmmrimv81xym7o.png)
В результате я получаю сообщение объемом 1 бит и узнаю, могу ли я рассчитывать на горячий чай. Так десятки лет исследований в сферах квантовой механики и вычислений нашли очень важное применение.
Если вы запустите код, на экран будут выводиться результаты передачи различных булевых состояний, которые содержатся в файле Driver.cs.
![](https://habrastorage.org/r/w1560/webt/dz/8_/bn/dz8_bn3ndsw0cfuojzan4rmvybo.png)
На этом мы закончим.
![](https://habrastorage.org/r/w1560/webt/hk/f5/bf/hkf5bf8jr5p6lezhprm-7enlno8.png)
Это вторая статья из серии о квантовом программировании. Предполагается, что читатель уже знаком с первой частью.
![](https://habrastorage.org/webt/k_/0n/u4/k_0nu4o_wb5qjn-zoc3d9xavqv0.jpeg)
Статьи из цикла:
К сожалению, отправить кубит ни по электронной почте, ни посылкой нельзя. Они передаются по специальным квантовым каналам, а в деревне и Интернет-то появился совсем недавно.
Но, может быть, бабушке удастся передать квантовую информацию по классическому каналу связи (например, через Интернет или телефонную линию)? Проблема заключается в том, что диапазон возможных значений квантового состояния непрерывен, поэтому для его точного описания потребуется бесконечное количество классических бит. Моя бабушка — весьма занятой человек, и у нее нет времени набирать столько бит.
Она уже начала терять всякую надежду, и тут я говорю: «Бабуль, все в порядке». Помнишь, мы в прошлую среду за чаем смастерили состояние Белла? Передать квантовое состояние можно через него! Такая передача квантового состояния с использованием классических каналов связи и называется квантовой телепортацией. Мы постараемся разобраться, как она работает — в теории и в коде.
Отправляем бабушке квантовую почту
Этап 0, подготовительный
Чтобы все описанное ниже сработало, мы с бабушкой должны подготовить состояние Белла: перевести ее кубит |G⟩ и мой кубит |F⟩ в состояние запутанности. Я расстаюсь с бабушкой, но свой кубит (половину состояния Белла) беру с собой. Наши кубиты будут находиться в состоянии запутанности вне зависимости от того, какое расстояние их разделяет — несколько километров или несколько миллиардов световых лет.
Помните, мы обсуждали замечательное свойство запутанных состояний — связанность результатов измерений соответствующих кубитов? Если бабушка измерит состояние своего кубита, это скажется на моем кубите (вне зависимости от расстояния). Ниже мы будем активно использовать это свойство.
Этап 1. Запутывание бабушкиного кубита с |ψ⟩
![](https://habrastorage.org/webt/f5/92/xt/f592xt9olphpusouyag8i5qe47e.png)
Исходное состояние будем описывать с помощью приведенной выше диаграммы. В верхнем левом углу находится предмет всех наших стараний — кубит, который бабушка хочет мне отправить. Он находится в неизвестном состоянии, которое можно представить следующим образом:
![](https://habrastorage.org/webt/9t/n2/mr/9tn2mrk_qvsnxo2xgnqvwzogv9e.png)
Кроме того, в ее распоряжении находится кубит |G⟩, который, как мы только что обсуждали, запутан с моим кубитом, |F⟩ (эта их связь показана волнистой линией). Теперь два кубита находятся в состоянии Белла, которое описывается формулой
![](https://habrastorage.org/webt/xk/9h/qu/xk9hquewk0hlpo8mbm2sf93ep6c.png)
Вначале мы запутаем бабушкин кубит |G⟩ с состоянием |ψ⟩. Скоро поймете зачем. В предыдущей статье мы узнали, что два кубита можно запутать с помощью схемы, состоящей из вентиля CNOT и вентиля Адамара. Давайте посмотрим, как этот процесс представляется с помощью квантовой цепи.
[Чтобы лучше понимать эти обозначения на диаграммах квантовых цепей, рекомендую вкратце ознакомиться со статьей Квантовые цепи и вентили — вводный курс.]
Применение вентиля CNOT
![](https://habrastorage.org/webt/ur/qv/or/urqvorrxksyc5ylc1z0onmhtuva.png)
Если добавить вентиль CNOT, схема принимает следующий вид. Состояние, которое подается на вход CNOT, можно записать как |ψ⟩|G⟩, где первый вход соответствует верхнему проводу, второй — среднему. Если подставить определения |ψ⟩ и |G⟩, получим:
![](https://habrastorage.org/webt/be/re/b4/bereb4jbqtlpzmhawpjoj6k220c.png)
Раскроем скобки:
![](https://habrastorage.org/webt/we/fx/cg/wefxcgi36e17ucapf_30kpjdouc.png)
Таким образом, на вход подается
![](https://habrastorage.org/webt/hj/tn/lp/hjtnlpzzbgryt96nq9lzkhpj_h8.png)
![](https://habrastorage.org/webt/a6/fc/up/a6fcupyzo4kkijegfdpos3tbnhw.png)
Когда управляющий кубит равен |1〉, значение управляемого кубита меняется на противоположное. Таким образом, CNOT превращает набор кубитов |100〉 в |110〉, а |111〉 — в |101〉. Все другие состояния остаются прежними.
![](https://habrastorage.org/webt/kh/n5/z2/khn5z2_mlswhswzplwqlrls9gfk.png)
Это значит, что состояние трех кубитов после вентиля CNOT будет описываться следующим выражением:
![](https://habrastorage.org/webt/mo/xu/ri/moxuri3tcy25vukr9pf5jtjbtfs.png)
Применение вентиля Адамара
Второй этап запутывания кубита |G⟩ с состоянием |ψ⟩ — применение вентиля Адамара к первому кубиту. Вот как это выглядит на диаграмме квантовой цепи:
![](https://habrastorage.org/webt/ne/z4/gs/nez4gsn85tsbo_tbagbw710xi8q.png)
Напомню, что вентиль Адамара преобразует |0〉 и |1〉 в состояния
![](https://habrastorage.org/webt/rg/xp/nv/rgxpnv5h13982tewsnzfgs_xjoq.png)
После вентиля CNOT кубиты находились в состоянии
![](https://habrastorage.org/webt/mo/xu/ri/moxuri3tcy25vukr9pf5jtjbtfs.png)
![](https://habrastorage.org/webt/lb/xu/rd/lbxurd3ourgyof4z6wga6us4c0q.png)
Итак, мы получили
![](https://habrastorage.org/webt/bs/an/nj/bsannjuidvlatehsv0rhyg_nqh8.png)
Уберем лишнее
Давайте немного причешем нашу формулу. Как можно заметить, в первом слагаемом
![](https://habrastorage.org/webt/nz/cd/eo/nzcdeochkpbt3hyc-fm5vcqthbm.png)
![](https://habrastorage.org/webt/lg/uy/za/lguyzaask0mansqwscrdzb-imus.png)
Если применить аналогичную операцию к другим слагаемым, получим
![](https://habrastorage.org/webt/uh/lk/ds/uhlkdsdhcpe5wpswshhbhvmqucw.png)
![](https://habrastorage.org/webt/55/wp/jx/55wpjxqjr9os5jo2ji9fpkwaf-m.png)
![](https://habrastorage.org/webt/h_/z8/63/h_z8631qjypnxxny1zvu9zzqy2u.png)
![](https://habrastorage.org/webt/f6/d8/l6/f6d8l6y8guuoeh4kwd793wgyffs.png)
Выглядит уже лучше. Теперь раскроем скобки (это упростит нам работу на следующем этапе). В качестве примера я приведу выкладки для слагаемого
![](https://habrastorage.org/webt/3r/l3/1u/3rl31uct_dlgrw2nxe419sbzwzg.png)
![](https://habrastorage.org/webt/kh/qr/4p/khqr4piktpjstq2rsecg4p1jyhq.png)
Остальные «читателю предлагается сделать в качестве упражнения». Если честно, я такие заманчивые предложения обычно игнорирую. Вот как будут выглядеть оставшиеся слагаемые, если раскрыть скобки:
![](https://habrastorage.org/webt/o3/g7/bf/o3g7bf5xpskc5qzygdmlxr-fbhk.png)
Их сумма равна
![](https://habrastorage.org/webt/2q/_i/k2/2q_ik2yfclfcxndjioecdbha1i0.png)
Этап 2. Измерение
Итак, мы запутали бабушкин кубит |G⟩ с кубитом |ψ⟩. Теперь измерим их. Но перед этим результаты нужно привести к виду, более удобному для понимания.
Снова подчищаем результаты
Это последний раз, честное слово. Вот все возможные результаты измерения первого и второго кубита: 00, 01, 10, 11. Пока мы не знаем, каким в каждом из этих случаев будет наш третий кубит. Сгруппируем слагаемые так, чтобы понять, в каком состоянии будет находиться третий кубит, а именно мой кубит |F⟩.
Пока наш результат выглядит так:
![](https://habrastorage.org/webt/zl/t2/-u/zlt2-ub0l47fknadufp0isa5u4o.png)
Выделим первый и второй кубит каждого слагаемого:
![](https://habrastorage.org/webt/yx/oj/pr/yxojpr3abserpkisoggbvxmkbim.png)
Рассмотрим случаи, в которых первый и второй кубит равны |00〉. Им соответствуют слагаемые
![](https://habrastorage.org/webt/5v/fg/m2/5vfgm2rhqsyiqonwsjgunpxv6m0.png)
![](https://habrastorage.org/webt/xf/44/g7/xf44g7rtwrbomluqo0mqiyg-nbg.png)
То же самое можно сделать для случаев |01〉, |10〉 и |11〉.
![](https://habrastorage.org/webt/fj/cy/hf/fjcyhfzzj5h3jjcxa7z3o5id6v8.png)
После преобразования выражение принимает следующий вид:
![](https://habrastorage.org/webt/th/ex/uw/thexuwgnwof5xipum2uqlikqw08.png)
Отлично.
Измерение
Так выглядит наша цепь с добавленными символами измерения. Обратите внимание на двойные черты после символов измерения. Они соответствуют переносу классических битов, которые и являются результатами измерений.
![](https://habrastorage.org/webt/l4/ud/ty/l4udtyikervtl8ibehpu2u2jv8k.png)
Моя бабушка также измеряет свои два кубита, |G⟩ и |ψ⟩. Как мы уже говорили, всего возможно четыре результата измерения: 00, 01, 10 или 11. При измерении кубита суперпозиция его состояний коллапсирует. Предположим, мы измерили состояние первого кубита |ψ⟩ и получили 0. Суперпозиция коллапсирует, и у нас остаются только те слагаемые, которые согласуются с таким результатом измерения (0), то есть следующие:
![](https://habrastorage.org/webt/eu/wx/tt/euwxttlm8pifu1f-el2nwon0gbw.png)
Предположим теперь, что мы измерили состояние второго кубита, |G⟩, и получили 0. Суперпозиция коллапсирует. Остается единственное слагаемое, которое согласуется с обоими результатами измерения (0 и 0), то есть следующее:
![](https://habrastorage.org/webt/o1/4z/oz/o14zoz86mktxxprbtlg7-b5twd8.png)
Теперь мы знаем, в каком состоянии находится третий кубит (то есть мой кубит |F⟩): в состоянии
![](https://habrastorage.org/webt/m7/iz/_9/m7iz_9sjzp2oxpgqnrfkmzj0ft8.png)
Что, если бы в результате измерения мы получили 01? Вернемся к нашему приведенному результату:
![](https://habrastorage.org/webt/9t/jp/u7/9tjpu75gd8e409ok31j_ig0ptkc.png)
Рассуждая по аналогии, мы поймем, что единственное слагаемое, которое соответствует результату измерения 01 —
![](https://habrastorage.org/webt/9y/s3/xa/9ys3xa2jaliduoagjizl0qsgbt0.png)
![](https://habrastorage.org/webt/mc/me/5d/mcme5dvhqfgxyrbmmfbituuddu4.png)
![](https://habrastorage.org/webt/69/u7/5_/69u75_n61rl8csjgzb6ushvj3ky.png)
![](https://habrastorage.org/webt/a9/uj/fy/a9ujfyz2ej4-kee3gjjy7vjr0ky.png)
Этот результат можно представить в виде таблицы:
![](https://habrastorage.org/webt/t5/e7/cc/t5e7ccebcnphz13z4jxjpn7tapw.png)
Этап 3. Перевод моего кубита (F) в состояние |ψ⟩
Мы остановились на том, что бабушка измерила состояние своих двух кубитов, позвонила мне и рассказала о результате, так что я знаю состояние моего кубита. Помните, что неизвестное состояние, с которого мы начали, |ψ⟩, было равно
![](https://habrastorage.org/webt/6c/xc/cz/6cxcczxjwhtwrqh4yspjmzg0otg.png)
Сейчас сделать это будет просто. Взгляните на таблицу выше. Если результат измерений 00, а мой кубит находится в состоянии
![](https://habrastorage.org/webt/bv/pm/x_/bvpmx_glbkkmzjjqn42msjnbona.png)
Если результат измерений 01, то мой кубит находится в состоянии
![](https://habrastorage.org/webt/ug/s_/wc/ugs_wco11ysl7qb0zq9h2ugxt18.png)
![](https://habrastorage.org/webt/yi/n7/p2/yin7p2f6bbtl8kwo00qprynqvk8.png)
При результате измерений 10 мой кубит находится в состоянии
![](https://habrastorage.org/webt/my/td/vj/mytdvjadvjt4eob1y4c29r8rg_m.png)
![](https://habrastorage.org/webt/s6/el/bl/s6elbl8p_suhhki-filcqz9ds0y.png)
![](https://habrastorage.org/webt/be/6b/mb/be6bmb0tpew8zwvxwvqwsydzpxu.png)
И последний вариант — 11. В этом случае мой кубит находится в состоянии
![](https://habrastorage.org/webt/9f/wa/yv/9fwayvb1urzmdzj_x4edkcp9xuu.png)
![](https://habrastorage.org/webt/yz/6z/jn/yz6zjn2qhzunaiq5wdzb5qduavq.png)
![](https://habrastorage.org/webt/b0/hv/kk/b0hvkkdzc9hhf8bjruvpop_6h54.png)
![](https://habrastorage.org/webt/z0/5f/fd/z05ffddqi6o9emspwiubae-d_ti.png)
Обратите внимание: если первый бит результата измерения равен 1, то мы применяем вентиль Z, а если второй бит равен 1, то применяем вентиль X. Окончательный вариант цепи показан ниже. Мы добавили вентиль Z, используя верхний провод в качестве управляющего, и вентиль X, для которого управляющим будет второй провод. Управляемым при этом будет мой кубит (потому что именно его нужно обработать с помощью вентилей).
![](https://habrastorage.org/webt/9h/5s/a3/9h5sa31hvg9n6-wt6kbmf1o2j3w.png)
Итак, мы показали, что бабушке достаточно передать всего два классических бита (а именно результаты измерения состояний кубитов |G⟩ и |ψ⟩), чтобы мы могли узнать неизвестное до этого состояние кубита. Благодаря явлению квантового запутывания информация от бабушки помогает узнать значения коэффициентов α и β. При этом нам удалось обойтись без канала квантовой связи. Поэтому такой метод называется квантовой телепортацией.
Подготавливаем и запускаем код
Итак, мы немного разобрались в теории квантовой телепортации. Пора переходить к коду!
Если на каком-либо шаге вам понадобится помощь, готовый код доступен здесь (просто клонируйте или скачайте репозиторий, откройте файл QuantumTeleportation.sln в Visual Studio и переходите к этапу 5).
Этап 1. Создайте проект
Создайте в Visual Studio новый проект типа «Приложение Q#» и присвойте ему какое-нибудь простое и понятное название — например, QuantumTeleportation.
Этап 2. Загрузите копию кода
Загрузите копию кода с примерами квантовых вычислений на свой компьютер. Для этого клонируйте или скачайте репозиторий.
Этап 3. Измените файл Operation.qs
Теперь нужно заменить весь код в файле Operation.qs на код из файла TeleportationSample.qs, который находится в разделе Quantum > Samples > Teleportation здесь.
Этап 4. Измените файл Driver.cs
Замените весь код в файле Driver.cs на содержимое файла Program.cs.
Этап 5. Сохраните и запустите проект
Нажмите на кнопку «start», чтобы запустить код. На экран будут выведены результаты для итераций 0–8. Они должны выглядеть примерно так:
![](https://habrastorage.org/webt/qm/h-/bi/qmh-bi7ehx9tfft55nr6q6qku_8.png)
Разбираемся, как этот код работает
На самом деле вы сможете в нем разобраться и без моей помощи — код замечательно прокомментирован. Мы просто сопоставим его с теорией, разобранной выше, — это будет несложно.
Этап 1. Телепортация
В первой части статьи мы говорили о трех кубитах: кубит в неизвестном состоянии |ψ⟩ и два кубита в состоянии Белла (один у бабушки, второй у меня). Этим трем кубитам в операции Teleport (Телепортация) соответствуют кубиты msg (неизвестное состояние, которое мне отправляет бабушка), here (кубит у бабушки) и there (мой кубит F, где |ψ⟩ — пересылаемое состояние).
Как уже обсуждалось, мы с бабушкой заранее подготовили пару кубитов в состоянии Белла. Один из них находится у бабушки, второй — у меня. Поэтому в самом начале нам нужно запутать ее кубит, который называется here, с моим, there. В коде для этого используются вентиль Адамара и вентиль CNOT:
![](https://habrastorage.org/webt/ln/qb/bl/lnqbbl3qygs1ysdlvyjcxyveuky.png)
Воспользуемся нашей диаграммой цепи. Я буду добавлять на нее обозначения по мере их появления в коде.
![](https://habrastorage.org/webt/3b/vj/0v/3bvj0vucyk311_4j3rjqta7vuce.png)
Повторяя операции, описанные в начале статьи, мы запутываем кубит бабушки here с неизвестным квантовым состоянием msg. Вентиль CNOT и вентиль Адамара на диаграмме соответствуют следующим строкам кода:
![](https://habrastorage.org/webt/dj/l_/l3/djl_l3qwak5klbreev41llug6b8.png)
Затем мы измерили первый и второй кубиты, msg и here. О результатах именно этих измерений бабушка сообщила мне по телефону. Этим событиям соответствуют условия оператора if:
![](https://habrastorage.org/webt/_b/kh/xt/_bkhxtodqa8j-p_z3gehpugdzse.png)
Как мы обсуждали в конце первой части этой публикации, после получения результатов измерения нужно изменить состояние моего кубита так, чтобы оно соответствовало кубиту |ψ⟩, то есть msg. Как мы говорили, если результат измерения первого кубита равен 1, то мой кубит (there) нужно пропустить через вентиль Z. Эта операция показана выше. Если результат измерения второго кубита равен 1, то мой кубит нужно пропустить через вентиль X.
Готово! Теперь мой кубит находится именно в том состоянии, которое мне хотела передать бабушка.
Этап 2. TeleportClassicalMessage
Давайте подумаем, как с помощью только что рассмотренной операции Teleport можно передать сообщение. Бабушка уже вполне освоилась с квантовой телепортацией и теперь посылает мне не неизвестное квантовое состояние, а известное — сообщение длиной в один бит. Предположим, я спросила бабушку, включила ли она чайник. Ответом будет одно из двух возможных сообщений — да или нет.
Вначале выделим регистр на два кубита, булево сообщение, которое мы будем пересылать (msg), и мой кубит, (there), с помощью которого бабушка будет передавать сообщение. Помните, что нумерация элементов регистра начинается с 0 (так же, как в массивах). Результат выглядит так:
![](https://habrastorage.org/webt/j5/sg/jr/j5sgjrxm9835m99v_jhxcgd3p_o.png)
Кубит msg, который мы выделили, изначально находится в состоянии |0〉 (это состояние по умолчанию для всех выделяемых кубитов). Сообщение бабушки о том, включен ли чайник, может принимать одно из двух значений — да или нет. Если ответ — нет, то ничего дополнительно делать не надо — такое сообщение соответствует состоянию |0〉, в котором кубит msg находится изначально. Если ответ — да, то есть |1〉, то нам нужно пропустить кубит msg через квантовый вентиль NOT, чтобы перевести его в показанное ниже состояние.
![](https://habrastorage.org/webt/bw/hk/8b/bwhk8bximmvyypnxmzok_mkizjy.png)
Далее бабушка передает состояние мне с помощью операции Teleport.
![](https://habrastorage.org/webt/dz/rd/ij/dzrdij0j432haiufs-mk8_axeke.png)
Затем мы измеряем состояние моего кубита, there.
![](https://habrastorage.org/webt/_h/cs/6a/_hcs6ahuh3zl6qmmrimv81xym7o.png)
В результате я получаю сообщение объемом 1 бит и узнаю, могу ли я рассчитывать на горячий чай. Так десятки лет исследований в сферах квантовой механики и вычислений нашли очень важное применение.
Если вы запустите код, на экран будут выводиться результаты передачи различных булевых состояний, которые содержатся в файле Driver.cs.
![](https://habrastorage.org/webt/dz/8_/bn/dz8_bn3ndsw0cfuojzan4rmvybo.png)
На этом мы закончим.
![](https://habrastorage.org/webt/hk/f5/bf/hkf5bf8jr5p6lezhprm-7enlno8.png)
Ресурсы
- Более подробная информация доступна на веб-сайте Microsoft Quantum
- Загрузите Quantum Development Kit
- Подпишитесь на информационный бюллетень Microsoft Quantum
- Узнавайте о новейших разработках из блога Microsoft Quantum