Линкоры с квантовыми измерениями

Не зря в названии этой статьи есть «Часть 2». Была часть 1, в которой мы рассмотрели основы написания и выполнения квантовых программ.



Я предполагаю, что вы прочитали хотя бы первую половину этого перед тем, как приехать сюда.

Большая часть фактических знаний о кодировании, необходимых для этого урока, была рассмотрена в прошлый раз. В этой статье основное внимание будет уделено тому, что мы можем делать с помощью этих команд.

Как смотреть на кубиты

В программах у нас есть переменные. В какой-то момент нам нужно будет их посмотреть.

Это может быть в конце программы, когда мы получим результат. Это также может быть во время программы, когда мы используем переменную как часть условного оператора. В любом случае, это случается часто. А при программировании неквантовых переменных это довольно ничем не примечательный процесс.

Это потому, что неквантовые переменные имеют определенные значения. Взгляд на них просто говорит нам или другим частям программы, в чем ценность. В самой переменной ничего не изменится.

Это не относится к квантовым переменным, которые могут иметь неопределенные значения. Они могут находиться в так называемой квантовой суперпозиции, что позволяет им одновременно удерживать несколько противоречивых значений.

Когда мы смотрим на них, они должны отказаться от всей этой странности. Они вынуждены принимать определенную ценность, а затем сообщать нам, что это за ценность. Поскольку это не просто пассивный процесс, он требует внимательного рассмотрения. И ему нужно имя. Мы называем это измерением.

В этой статье мы исследуем некоторые свойства измерения. Мы также будем использовать его в качестве основы игровой механики и посмотрим, как именно запрограммировать его на квантовом компьютере. В конце концов у нас будет новая версия линкоров.

Отображение мира кубита

Прежде чем мы действительно приступим к измерению кубитов, мы должны попытаться немного больше понять их мир. Лучший способ визуализировать кубит - использовать сферу. Любое возможное состояние кубита соответствует точке на поверхности этой сферы.

Состояния 0 и 1 совершенно разные, совершенно не пересекаются. Они противоположны друг другу. Следовательно, они будут жить по разные стороны сферы. Обычно мы выбираем 0 на северном полюсе и 1 на юге.

Давайте выберем точку, которая находится на равном расстоянии между ними, где-нибудь на экваторе. Это может быть где угодно. Назовем это +. Почему +? Почему нет?

Состояние + также имеет противоположность, столь же отличную от него, как 0 от 1. Он живет на противоположной стороне, которая также будет точкой на экваторе. Мы назовем это состояние -.

Теперь, когда определены точки 0, 1, + и -, еще пара точек требует нашего внимания. Это те, которые равноудалены между 0 и 1, а также равноудалены между + и -. Мы назовем их и . Почему? Потому что однажды я увидел парня, который этого не писал, Код да Винчи, и мне это понравилось.

Теперь мы нанесли на карту мир кубита с шестью точками. Это ни в коем случае не единственные, которые мы когда-либо будем использовать. Это просто ориентиры, по которым мы будем ориентироваться.

Измерение кубита

Любое измерение - это просто просьба кубита выбрать между двумя противоположными точками на сфере.

Классический пример - для нашей любимой пары противоположных состояний: 0 и 1. Мы просим кубит выбрать между ними. Если он уже был в состоянии 0, он перейдет в состояние 0. Кубит в состоянии 1 аналогичным образом даст результат 1. Для любого другого состояния результат будет случайным, причем наиболее вероятным будет ближайший вариант.

На экваторе в любом случае шанс 50/50. Итак, если наше состояние было + или -, а затем мы спрашиваем, 0 или 1, ему придется выбрать одно или другое с равной вероятностью.

Измерение, основанное на 0 и 1, имеет несколько названий. По понятным причинам мы можем назвать это измерением 33_. Это также называется базисным измерением Z из-за особой связи состояний 0 и 1 с операцией z. Подробнее об этой истории в другой раз.

Следующим по популярности видом измерения является измерение + и -. Я назову это +/- измерением, но вы также можете увидеть его как измерение на основе X. Он работает так же, как и раньше, но только для + и - вместо 0 и 1. Итак, если вы начнете с кубита в состоянии + и выполните это измерение, вы получите результат +. Но если вы начнете с 0 и зададите тот же вопрос, он будет выбран случайным образом.

У нас также есть измерение для странных стрелок. Это называется базисным измерением Y. Никому не нравятся измерения на основе Y.

Немного - это всего лишь немного, даже если оно квантовое

Измерение неквантовых объектов - пассивный процесс. Он сообщает вам, что делает объект, но никоим образом не меняет его. Измерение квантовых вещей - это совсем другое дело. Квантовые измерения не просто меняют наши знания о переменных. Они сами меняют переменные.

Предположим, у вас есть кубит в состоянии +, а затем спросите его, 0 или 1. Когда он дает случайный результат, он не просто обманывает вас. Это не говорит вам чушь из-за того, что вы задали неправильный вопрос. Как только он даст вам результат, он останется с ним. Значение изменится, чтобы отразить ответ. Если он сообщает вам 0, он будет 0 навсегда (или, по крайней мере, до тех пор, пока вы снова не начнете с ним связываться). Он забудет, что когда-либо было +.

Это означает, что кубит может быть уверен в своем результате только после однократного измерения. Если он точно знает, 0 или 1, он совершенно не уверен, + или , а также совершенно не уверен, или . У кубита есть лишь ограниченная степень уверенности, которую можно обойти, ограниченная принципом неопределенности Гейзенберга.

Это означает, что у нас есть только один шанс получить информацию с кубита. Как только мы извлекаем единственный двоичный результат, все, что кубит когда-либо знал до измерения, забывается. Он запоминает только результат, который нам дал. Итак, несмотря на бесконечное количество возможных состояний кубита, мы можем извлечь только один бит информации. Вот почему мы думаем о нем как о квантовой версии бита, а не о квантовом поплавке или квантовом 3-векторе и т. Д.

Игровая механика

Мы собираемся сделать вариант линкоров, в котором будет два типа атаки: бомбы и торпеды. Чтобы потопить корабль, потребуется всего одна успешная атака, но добиться успешной атаки не всегда так просто. Некоторые корабли обладают такой хорошей защитой от самолетов, что никакая бомба никогда не подлетит к ним. Другие отлично отражают торпеды.

Чтобы реализовать это на обычном компьютере, мы могли бы определить две логические переменные для каждого корабля. Один скажет нам, невосприимчив ли корабль к бомбам, а другой - к торпедам. Затем их можно проверить во время атак, чтобы узнать, тонет корабль или нет.

Если бы это была та реализация, которую мы используем, было бы теоретически возможно, чтобы корабль был невосприимчивым к обоим типам атак. Это было бы плохим дизайном игры, поскольку в нем невозможно выиграть одному игроку. Хорошая реализация должна предотвратить появление неразрушимых кораблей.

Один из способов избежать создания таких кораблей - это несколько простых строк кода. Но это не совсем наш стиль. Вместо этого мы исправим это с помощью квантовой механики!

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

Мы реализуем это, связав взрыв бомбы с 0/1 измерением. Если мы получаем результат 1, мы говорим, что корабль затонул. Для 0 мы делаем вывод, что корабль невосприимчив к бомбовым атакам. Для торпед мы вместо этого делаем измерение +/-, где - подразумевает разрушение, а + подразумевает невосприимчивость.

Этот метод делает невозможным для корабля определенную невосприимчивость к обоим типам атак. Если мы узнаем, что вражеский корабль невосприимчив к бомбам (т.е. его состояние 0), мы знаем, что у него должна быть полная неуверенность в отношении торпед (результат измерения +/-). Поскольку бомбовая атака наверняка не удастся, мы должны атаковать торпедами.

Тогда может оказаться, что торпедная атака не удалась (состояние становится + после +/- измерения). Корабль решит, что он определенно невосприимчив к ним, и любая дальнейшая торпедная атака не удастся. Но надежда еще не потеряна. Уверенный в торпедах, он стал неуверен в отношении бомб. Следующая атака с их помощью (измерение 0/1) может привести к победе.

Если бомбовая атака не удалась, мы возвращаемся к торпедам и так далее. Лучшая тактика - продолжать переключаться между ними, пока корабль не затонет.

Мы запустим корабли, так как не уверены в их невосприимчивости к обеим атакам. Это можно сделать, инициализировав кубит в одном из базовых состояний Y. Пойдем за . На самом деле это состояние, с которым мы познакомились в Части 1, а именно u3(0.5*pi,0,0) 0, поэтому мы уже знаем, как это сделать.

Работа с недолговечными кубитами

Реализовать игру на квантовом процессоре будет не так просто, как мы могли бы надеяться. Мы рассмотрим все проблемы, которые встанут у нас на пути, и посмотрим, как их решить.

Предположим, на корабль взорвалась бомба и он выжил. Затем в следующем раунде в него попадает торпеда.

Если бы игра запускалась на обычном компьютере и моделировалась с использованием обычных битов, реализовать это было бы довольно просто. Корабль будет инициализирован, когда начнется игра, а затем будет ждать в памяти, пока игрок не решит, что с ним делать. После того, как игрок отправит бомбу, будут применены соответствующие операции, чтобы увидеть, уничтожена ли она. Если он выживает, он снова ждет следующей атаки.

У нас это не сработает. Кубиты не могут сидеть сложа руки, ожидая человеческих временных рамок. Несколько секунд - более чем достаточно времени, чтобы они рухнули и сгорели, по крайней мере, с учетом современных технологий.

Альтернатива - запускать новый квантовый процесс каждый раз при атаке. Первое задание будет инициализировано с состоянием , так что результаты будут случайными как для измерения 0/1 (бомбовая атака), так и для измерения +/- (торпедная атака). Затем результат измерения записывается и сохраняется в памяти обычного компьютера. Когда происходит следующая атака, создается другое задание, чтобы посмотреть, что произойдет. Он будет инициализирован результатом последнего измерения и продолжится.

Выполнение измерения +/-

Пока что я написал целую кучу слов, но ни одной строчки кода. Начнем с того, что вспомним, как 0/1 измерение реализовано в коде QASM.

measure q[0] -> c[0];

Роль c[0] здесь важно пересмотреть. Это результат процесса измерения. Это обычный бит, в котором сохраняется результат измерения. Для 0/1 измерения результат 0 или 1.

Все это довольно просто для измерения 0/1. Но сейчас мы смотрим на +/- измерение. Как мы можем получить информацию от одного из них?

Мы по-прежнему хотим сохранить результат в обычном бите c[0]. Поскольку это нормальный бит, он ничего не знает о странных состояниях + и -. Он знает только обычный двоичный код. Поэтому мы решили сообщать результат + как c[0]=0, а - как c[0]=1. Тот факт, что они будут выглядеть так же, как результаты 0/1 измерения, не будет проблемой. Как и в любой компьютерной программе, мы должны знать, что мы запрограммировали, и поэтому мы должны знать, как интерпретировать результаты.

Теперь мы знаем, как получить результаты измерения +/-. Но мы еще не выяснили, как это сделать на самом деле сделать. Это потому, что нам нужно скрывать это. Нам нужно взломать процесс, который выполняет 0/1 измерения, и вместо этого сделать +/- измерение.

Ключом к нашему взлому является операция под названием Адамара. Применение этого к кубиту q[0] в коде QASM выглядит так.

h q[0];

Команда, которую мы используем в Python для добавления этой строки в файл QASM с именем gridScript, выглядит следующим образом:

gridScript.h(q[0])

Эффект Адамара заключается в замене базисных состояний Z на базисные состояния X и наоборот. Это вращение Сферы, которое перемещает состояние кубита 0 в + и + в 0. Точно так же 1 поворачивается на - и наоборот.

Это означает, что историю, которую мы можем рассказать о кубите в терминах 0 и 1 до Адамара, мы должны рассказать с + и - после него. И любая история о + и - становится одной из 0 и 1.

Это именно то, что нам нужно. Это означает, что измерение +/- кубита q[0] может быть выполнено с помощью следующего кода QASM.

h q[0];
measure q[0] -> c[0];
h q[0];

Чтобы понять, почему это работает, давайте рассмотрим несколько примеров. Кубит q[0] будет начинаться заново, объявленный в каждом, и поэтому будет иметь начальное значение по умолчанию 0.

Пример нуля:

measure q[0] -> c[0];

Кубит запускается в состоянии 0. Спрашивают, 0 или 1, и дают c[0] ответ. Результат всегда будет c[0]=0.

Пример первый:

x q[0];
measure q[0] -> c[0];

Кубит запускается в состоянии 0, а затем вращается в 1. Затем его спрашивают, 0 или 1. Всегда отвечает 1.

Пример +:

h q[0];
measure q[0] -> c[0];

Кубит запускается в состоянии 0 и сразу же становится +. Затем его спрашивают, является ли его состояние 0 или 1. Он случайным образом выбирает один или другой, и его состояние обновляется с ответом.

Мы сделали несколько тривиальных примеров, давайте займемся чем-нибудь посложнее.

Пример ++:

h q[0];
h q[0];
measure q[0] -> c[0];
h q[0];

Кубит запускается в состоянии 0, а затем вращается в +. После этого есть два равноценных способа продолжить рассказ.

Один из них - сказать, что три последние строки вместе составляют +/- измерение. Они спрашивают кубит, + или -. Для + они возвращают результат c[0]=0, а для - они возвращают c[0]=1. Поскольку кубит переходит в измерение с состоянием + в этом примере, он всегда измеряется как +. Поэтому он выходит из измерения еще в этом состоянии.

Для другой истории мы смотрим на эффекты линий одну за другой. Второй Адамар отменяет действие первого и, таким образом, возвращает кубит в состояние 0. Затем его спрашивают, является ли его состояние 0 или 1, и он всегда отвечает 0. Следующий Адамар снова поворачивает его на 141_.

Обе истории согласны в наблюдаемых эффектах. Они соглашаются, что результат c[0] всегда будет 0, и они соглашаются, что состояние кубита в конце будет +. Они просто не согласны с тем, как это произошло. Обе интерпретации одинаково верны.

Если вам нужен жаргон, чтобы найти что-то в Википедии, это примеры изображений квантовой механики Шредингера и Гейзенберга.

Пример +1:

x q[0];
h q[0];
measure q[0] -> c[0];
h q[0];

Вот еще один пример, для которого у нас есть две эквивалентные истории. Можно сказать, что q[0] начинается как 0, а затем меняется на 1. Затем он поворачивается на t0 - перед выполнением 0/1 измерения. Он случайным образом выбирает одно или другое, выдает результат c[0]=0 или c[0]=1 и соответствующим образом обновляет свое состояние. Если решено 0, последний Адамар поворачивает его на 153_. В противном случае получится -.

В качестве альтернативы мы могли бы сказать, что после поворота на 1 кубит проходит +/- измерение. Он случайным образом выбирает между этими двумя вариантами, давая результат c[0]=0 для + и c[0]=0 для -. Состояние обновляется соответствующим образом, переходя в состояние + или -.

Опять же, эти две истории одинаково достоверны и согласуются со всеми наблюдаемыми эффектами. Если мы хотим думать о трех строках

h q[0];
measure q[0] -> c[0];
h q[0];

в качестве +/- измерения мы можем это сделать. Если мы хотим думать об этом как об измерении Адамара, за которым следует 0/1 измерение, за которым следует измерение Адамара, это тоже хорошо.

Прежде чем мы продолжим, следует отметить одну важную вещь. API IBM в настоящее время не позволяет нам делать что-либо с кубитом после того, как мы его измерили. Это не общее правило для квантовых компьютеров. Обычно мы ожидаем, что сможем измерять кубиты и манипулировать ими столько, сколько захотим. Но в данный момент мы не можем этого сделать.

Это не представляет для нас никаких проблем. Поскольку кубиты в любом случае не могут сидеть сложа руки, пока игроки делают выбор, мы уже должны полностью воссоздавать состояние после каждого раунда измерений. Второй Адамар эффективно появится на следующей работе, действуя на реинкарнированную версию государства.

Все остальные возможные измерения могут быть достигнуты аналогичными хитростями. Нам просто нужно заранее выполнить некоторые операции, чтобы активировать наше альтернативное измерение, а затем (если API позволяет) сразу после этого выполнить противоположные операции.

Работа с ошибками

Современная квантовая технология несовершенна. Кубиты не всегда делают то, что должны. Если ваш кубит 0, и вы выполняете 0/1 измерение, результат всегда должен быть 0. Всегда. Но с нынешними квантовыми устройствами есть шанс 1. Это могло быть потому, что x операция подкралась, пока мы не смотрели. Это может быть потому, что измерения нам лгут. Подобные события редки, но они случаются.

Есть два способа исправить ошибки. Один из них - игнорировать их. Мы можем вписать их в повествование игры. На море сильные штормы. Иногда они приводят к уничтожению корабля атакой, даже если он невосприимчив. Или пережить атаку, которая должна была его уничтожить.

Второй способ справиться с ошибками - попытаться устранить их последствия. Если бы было доступно много кубитов, мы могли бы сделать это с помощью квантовой коррекции ошибок. К сожалению, до этого еще несколько лет.

Вместо этого мы сделаем некоторую статистику. Для этого нам нужны вероятности, которые мы получаем, выполняя каждое задание много раз и наблюдая, как часто появляется каждый возможный результат.

В бесшумном случае все вероятности будут 0%, 100% или 50%. Результат либо невозможен (например, получение 1, если состояние 0), наверняка (например, получение +, если состояние +), или полностью случайный (например, получение 0 при состоянии +).

Шум немного испортит их. Когда мы делаем 0/1 измерение 0, мы можем обнаружить, что результат 0 встречается только в 98% случаев, а 2% приходится на 1. Чтобы исправить это, мы сделаем что-нибудь довольно произвольное. Мы решим, что ничего с вероятностью менее 5% никогда не должно было произойти. Все, что с вероятностью более 95%, должно было быть достоверным.

Собираем все вместе

В этой статье были рассмотрены основные моменты игровой механики этой версии боевых кораблей и способы ее реализации с помощью квантового компьютера. Вместо того, чтобы вдаваться в подробности здесь, я оставлю это для комментариев в исходном коде.



Если есть что-то, что, по вашему мнению, требует дополнительных объяснений, дайте мне знать.