Привет, Хабр! Сегодня, в первый день нового учебного года мы будем решать интересную задачку про Винтика и Шпунтика, которую не так давно запостил vvvphoenix. Да решать не на бумажке, не на калькуляторе, и даже не на питоне, а на новейшем облачном фотонном квантовом компьютере!



Credit: Bernard Marr


Задача


В оригинальном посте все началось с олимпиадной задачки для 7-8 классов:


Незнайка записывает 10-значное десятичное число, оставляя пропуск вместо одной из цифр. Он предлагает Винтику заполнить пропуск любой цифрой, а затем показать полученное 10-значное число Шпунтику. Как могут Винтик и Шпунтик договориться, чтобы Шпунтик угадал, на каком именно месте стоял пропуск?

Если вы не видели задачу раньше, подумайте немного над ее решением, оно не очень сложное.


Ответ

Ключ к решению — чексумма: Винтик заполняет пропуск такой цифрой, чтобы чексумма 10-значного числа совпадала с номером пропущенного разряда.


Чексумму можно выбрать любую, например, посчитать сумму всех цифр и взять ее последнюю цифру. Скажем, если Незнайка загадал 12345_7890, то Винтик заполняет его цифрой 7. Шпунтик считает сумму всех цифр: 1+2+3+4+5+7+7+8+9 = 46. Последняя цифра суммы — 6, значит пропуск стоял в шестом разряде.


Очевидно, что Винтик и Шпунтик могут договориться и использовать любую чексумму — а значит, у задачи есть больше одного решения. И тут vvvphoenix задается по-настоящему интересным вопросом: а сколько же всего существует решений? Иными словами, сколько существует взаимооднозначных соответствий между 10^10 строками с пропуском, которые придумывает Незнайка, и 10^10 десятизначными числами, которые записывает Винтик?


Вообще 10^10 — это немножко дофига. К счастью, смысл задачи не меняется для N-значных чисел в N-значной системе счисления: например, для N=2 Незнайка придумывает двухначное число, в котором один из разрядов — 0 или 1, а на месте второго стоит пропуск. Теперь Винтику и Шпунтику нужно найти отображение множества {0..., 1..., ...0, ...1} на {00, 01, 10, 11}. Нюанс в том, что не все варианты доступны: "0_" не может соответствовать "11", потому что первые разряды не совпадают. Давайте нарисуем возможные варианты в виде таблицы, где 1 — разрешенные соответствия, а 0 — запрещенные:



Несложно заметить, что у этой задачи ровно два решения:



Для N=3 таблица вырастает до N^N x N^N = 27x27 и выглядит так:



Картинка из телеграма автора задачи


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


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



На этом сходства заканчиваются. В отличие от детерминанта, вычисление перманента имеет экспоненциальную сложность, и быстрого алгоритма для него не существует. Возвращаясь к задаче про Винтика и Шпунтика, для случая N=2 (матрица 4х4) перманент считается на бумажке и равен 2, расчеты для N=3 (матрица 27х27) на питоне занимают около часа и дают 10 752, а дальше вычисления становятся неприлично долгими. Случай N=10 так и вообще остается в области фантастики.


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


Boson sampling


Задача о бозонном сэмплинге появилась почти пятнадцать лет назад, но прогремела заметно позже. Именно на ее разновидностях сначала Google, а потом и группа профессора Пэна в Китае продемонстрировали превосходство квантового компьютера над классическим. Бозонный сэмплинг — задача довольно синтетическая: для нее не существует эффективных классических алгоритмов, при этом она идеально подходит для реализации на квантовых компьютерах. А теперь пристегните ремни, потому что звучит она еще более необычно:


У нас есть n волноводов для света (например, оптических волокон). Некоторые из волноводов попарно пересекаются на сплиттерах: на каждом сплиттере свет из каждого волновода делится на две части, половина остается в том же волноводе, половина уходит в другой. Расположение сплиттеров известно. Мы выбираем m из n волноводов и запускаем на вход каждого из них ровно по одному фотону. Какова вероятность того, что на выходе каждого из этих m волноводов все еще останется по одному фотону?


Волноводы на фотонном чипе. Credit: PhotonQ


Вопрос из зала: эээ… и это все еще имеет отношение к квантовому превосходству?


И еще какое! Секрет в том, что одиночные фотоны — это квантовые объекты: проходя через сплиттер, фотон не выбирает один выход, а остается в обоих, прямо как полуживой-полумертвый кот сами-знаете кого. А еще фотоны интерферируют между собой, добавляя щепотку квантовой запутанности в эту и без того запутанную задачу.


Вопрос из зала: Так мы же знаем расположение сплиттеров? Вычисление должно быть элементарным, разве нет?


Давайте разбираться. Вот, например, мы послали на первые два волновода по фотону и хотим увидеть на выходе один фотон во втором волноводе, а один — в третьем. Какова вероятность такого события?



Отсюда


Ну понятно, тут два (на самом деле 2!) варианта: либо первый фотон пойдет во второй волновод, а второй — в третий, либо наоборот. Можно записать это как произведение вероятностей, сумма которых подозрительно напоминает перманент матрицы 2х2:



А если фотонов три? Тогда у нас 3! = 6 вариантов:



и идеальное совпадение с перманентом матрицы 3х3. Именно этот перманент и делает бозонный сэмплинг экспоненциально сложным для классических алгоритмов.


Linear optics quantum computing


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


Впрочем, в 2019 году Google демонстрировала квантовое превосходство на сверхпроводниковых кубитах. На тот момент это была единственная масштабируемая платформа для квантовых компьютеров. Зато уже через год научная группа Цзянвей Пэна в Китае запустила бозонный сэмплинг на фотонном компьютере, да каком — вместо фотонного чипа там была настоящая стеклянная оптика, занимавшая целый стол!



Фотонный компьютер Jiuzhang собственной персоной. Credit: University of Science and Technology of China


Вскоре после этого фотонные квантовые компьютеры уверенно ворвались на рынок. Сейчас в мире даже есть два сервера облачных фотонных вычислений, и если канадская Xanadu ориентирована только на корпоративных клиентов, то французская Quandela дает всем желающим возможность бесплатно прикоснуться к фотонным вычислениям. Черт, вы только представьте: 2010-й год, Ааронсон и Архипов — авторы идеи бозонного сэмплинга — выглядят буквально как персонаж мема:



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


Дорога в облака


После регистрации на cloud.quandela.com мы попадаем на главную страницу, которая встречает нас статусом доступных платформ. Среди них несколько симуляторов и квантовый процессор (QPU) под названием Altair:



Сердце Altair — это универсальный программируемый фотонный чип (universal interferometer). Специальный источник (SPS) генерирует поток одиночных фотонов, который разводится демультиплексором на заданные входы в чипе. На выходе чипа стоят сверхпроводящие однофотонные детекторы (SNSPD), которые измеряют распределение фотонов после прохождения чипа.



Отсюда. Картинке больше года, с тех пор чип немного вырос.


В 20-модовый чип Altair (это значит, что в нем 20 волноводов) можно запустить до 10 фотонов. Это очень условно соответствует 10+ кубитам; условно — потому что фотонные компьютеры кодируют информацию более эффективно, и 10 кубитов — это оценка снизу. На странице QPU можно найти полную схему чипа, она выглядит примерно так:



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


Теперь давайте разберемся с тем, как все это запустить.


Квантовый Hello, world!


Для работы с облаком нужно сгенерировать токен и установить фреймворк под названием Perceval (pip install perceval-quandela). В Perceval нас интересует несколько сущностей.


Processor


Первым делом мы инициализируем квантовый процессор или его симулятор. Если нас интересует процессор в облаке, то мы инициализируем класс RemoteProcessor именем процессора с Quandela Cloud и токеном:


import perceval as pcvl

proc = pcvl.RemoteProcessor("qpu:altair", token)    # QPU Altair
proc = pcvl.RemoteProcessor("sim:altair", token)    # симулятор Altair на GPU

Если же мы не хотим в облако, то можно запустить симулятор на локальной машине, указав архитектуру процессора:


proc = pcvl.Processor("CliffordClifford2017")

На симуляторе можно запускать любое число задач, а для работы на настоящем QPU понадобятся кредиты. Юзеру дается 200 бесплатных кредитов каждый месяц.


Circuit


Следующим шагом мы создаем схему, которую хотим запрограммировать в фотонный чип. Она инициализируется количеством мод, которые мы хотим использовать:


c = pcvl.Circuit(2)
pcvl.pdisplay(c)

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



Давайте добавим в схему два сплиттера с фазовращателем — это называется интерферометр Маха-Цендера:


phase = 0.5*np.pi
c.add(0, pcvl.BS())
c.add(0, pcvl.PS(phi=phase))
c.add(0, pcvl.BS())
pcvl.pdisplay(c)


Осталось записать эту схему в чип:


proc.set_circuit(c)

Source


Теперь мы должны прописать входы чипа, на которые мы подаем одиночные фотоны. Это делается при помощи класса BasicState. Мы подадим один фотон в первую моду, а вторую оставим пустой:


input_state = pcvl.BasicState([1,0])
proc.with_input(input_state)

Sampler


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



открыть коробку, записать результат, а потом повторить эксперимент еще пару тысяч раз. Если в половине случаев кот остался живым, то наш рецепт готовил идеального полуживого-полумертвого кота Шредингера. Если живыми остались 90% котов, то и кот из рецепта был скорее жив, чем мертв. Именно так и никак иначе мы и набираем итоговую статистику. В любых квантовых вычислениях мы измеряем вероятность тех или иных исходов, запуская один и тот же алгоритм много раз и считая количество результатов. Собственно, это и называется сэмплингом.


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


Для запуска сэмплинга в Perceval используется класс Sampler, который инициализируется процессором с прописанной схемой и максимальным количеством шотов (shots):


sampler = Sampler(proc, max_shots_per_call=1000)

Здесь max_shots_per_call — это количество повторений, в которых на выходе чипа был задетектирован хотя бы один фотон. Дело в том, что реальный чип — он большой и сложный, и какой-то процент фотонов в нем теряется, поэтому в ряде попыток до детекторов не долетит ничего. Чтобы получить 1000 шотов, компьютер сделает больше, чем 1000 повторений. Впрочем, наш локальный симулятор работает без потерь.


Нам осталось поставить задачу в очередь задач:


job = sampler.sample_count.execute_async()

и время от времени проверять ее статус:


print(f"Job status = {job.status()}")

Job status = SUCCESS

Results


Когда задача будет готова, мы можем забрать ее результаты:


results = job.get_results()

Можно забрать и результат более старой задачи

Для этого нужно скопитьвать ее ID из списка задач на облаке:



и обратиться к ней таким образом:


proc = pcvl.RemoteProcessor(proc_name, token)
job_id = 'e2692e28-9ccd-4f9d-b2fe-8c64ded10d66'
job = proc.resume_job(job_id)
results = job.get_results()

Результат квантового вычисления показывает, сколько раз алгоритм дал ту или иную комбинацию фотонов (outcomes) на выхоже из чипа. В нашем случае он выглядит так:


outcomes = results['results']
print(outcomes)

{
  |0,1>: 497
  |1,0>: 503
}

Симулятор произвел 1000 шотов, в 503 из них фотон оказался в первой моде, в 497 — во второй. Почти идеальное соотношение 50:50. А что будет, если мы поменяем фазу интерферометра Маха-Цендера?


phase = 0*np.pi

{
  |0,1>: 1000
}

phase = 1*np.pi

{
  |1,0>: 1000
}

Ого, поведение интерферометра меняется в зависимости от приложенной фазы! В принципе, это именно то, чего мы от него ожидаем: интерферометр Маха-Цендера часто используется именно для перераспределения света между двумя выводами. (Если присмотреться к схеме чипа Altair, то можно заметить, что он буквально набит такими интерферометрами.) Это не квантовый эффект, а классическая интерференция, но для Hello, world! нам её хватит.


Теперь повторим те же вычисления не на симуляторе, а на QPU. При этом с вашего счета в Quandela Cloud списываются кредиты: один кредит соответствует миллиону шотов. Нам хватит всего тысячи шотов:


phase = 0*np.pi

{
  |0,1>: 930
  |1,0>: 70
}

phase = 0.5*np.pi

{
  |0,1>: 480
  |1,0>: 520
}

phase = 1*np.pi

{
  |0,1>: 141
  |1,0>: 859
}

Не так идеально, но работает! Ничего удивительного: оптика QPU сложная, поэтому к выходу из чипа набегает какая-то ошибка — впрочем, она не сильно мешает реальным квантовым вычисленям.


Матрицы


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



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


Квантовый перманент


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



где U — это матрица, описывающая чип. А значит, перманент матрицы U можно вычислить как



Здесь N_shots — общее число шотов, а N_events — количество интересующих нас событий на выходе, где в каждой моде оказалось по фотону.


На удивление простая формула, не так ли? Давайте проверим её на каком-нибудь примере. Возьмем, например, вот такую матрицу:



перманент которой несложно посчитать: 0.6 + (-0.4) = 0.2. А теперь попробуем вычислить его на симуляторе. В Perceval матрица записывается в фотонный чип вот таким образом:


U = np.array([
    [np.sqrt(0.6), np.sqrt(0.4)],
    [-np.sqrt(0.4), np.sqrt(0.6)],
 ])
unitary_component = comp.Unitary(pcvl.Matrix(U))
pcvl.pdisplay(unitary_component)

и отображается не как набор сплиттеров-фазовращателей, а как один большой блок:



Посылаем по фотону в каждую моду и запускаем вычисления:


input_state = pcvl.BasicState([1,1])
shots = 10_000

proc = pcvl.Processor("CliffordClifford2017")
proc.set_circuit(unitary_component)
proc.with_input(input_state)
proc.min_detected_photons_filter(1)

sampler = Sampler(proc, max_shots_per_call=shots)
remote_job = sampler.sample_count
remote_job.execute_async()

и смотрим на результаты:


results = remote_job.get_results()
outcomes = results['results']
print(outcomes)

{
  |2,0>: 4759
  |0,2>: 4829
  |1,1>: 412
}

412 событий из 10 000 шотов соответствуют перманенту:


perm = np.sqrt(412/10_000)
print(f'Calculated permanent: {perm:.2f}')

Calculated permanent: 0.20

Идеальное совпадение с ожидаемым результатом!


Унитарность


С матрицами связан один нюанс. Матрица U должна быть унитарной, другую физически не получится прописать в чип. Но это не проблема: если мы хотим посчитать перманент произвольной матрицы A размером N x N, то мы всегда можем дополнить ее до унитарной матрицы U размером 2N x 2N:



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


Алгоритм дополнения до унитарной матрицы

хорошо описан в этой работе:



Если в двух словах, то мы:


  • генерируем матрицу A_s, нормируя A на ее спектральную норму s
  • составляем матрицу U с подматрицей A_s как в уравнении (6)
  • после вычисления перманента A_s не забываем скорректировать его на спектральную норму:


где n — число строк (или столбцов) матрицы.


А код для этого выглядит вот так:
import numpy as np
from numpy import linalg
from scipy.linalg import sqrtm

def prepare_unitary(A):
    n = len(A)
    _, D, _ = linalg.svd(A)
    s = np.max(D)
    As = A/s

    Q = sqrtm(np.identity(n) - np.dot(As, As.conj().T))
    R = sqrtm(np.identity(n) - np.dot(As.conj().T, As))

    Ubmat = np.bmat([
        [As, Q], 
        [R, -As.conj().T]
    ])
    Ubmat = Ubmat.real
    return np.copy(Ubmat), s

Заметьте, что кроме матрицы U функция возвращает ещё и спектральную норму s, на которое нужно будет отнормировать результат (n — это размер матрицы A):



В задаче про Винтика и Шпунтика для N=2 мы считаем перманент матрицы 4х4, которую мы впишем в унитарную матрицу размером 8x8 и легко запишем в чип Altair. К сожалению, уже для N=3 нам потребуется матрица 54х54 — это заметно больше нынешних возможностей. Ну что ж, не все сразу, начнем с простого.


Считаем!


Задаем матрицу из задачки про Винтика и Шпутника для N=2:


A = np.array([
    [1, 0, 1, 0],
    [0, 1, 0, 1],
    [1, 1, 0, 0],
    [0, 0, 1, 1],
 ])

Дополняем ее до унитарной матрицы U и готовимся послать по одиночному фотону в первые четыре моды:


import perceval.components as comp

U, s = prepare_unitary(A)
print(f'Spectral norm = {s}')
unitary_component = comp.Unitary(pcvl.Matrix(U))
input_state = pcvl.BasicState([1,1,1,1,0,0,0,0])

Spectral norm = 2.0

Локальный симулятор


Для начала запускаем вычисления на нашем компьютере:


proc = pcvl.Processor("CliffordClifford2017")
proc.set_circuit(unitary_component)
proc.with_input(input_state)
proc.min_detected_photons_filter(1)

shots = 10_000
sampler = Sampler(proc, max_shots_per_call=shots)
sampler.default_job_name = 'Permanent'
remote_job = sampler.sample_count
remote_job.execute_async()

и получаем результат:


results = remote_job.get_results()
outcomes = results['results']
print(outcomes)

{
  |0,0,0,0,1,0,1,2>: 66
  |0,0,0,2,1,1,0,0>: 249
  |0,0,0,0,0,2,2,0>: 63
  |0,0,0,0,0,1,2,1>: 80
  ...
  |1,0,0,0,0,0,3,0>: 1
}

Нас интересует только события, когда выходное состояние совпало с входным. Переменная outcomes — это объект класса BSCount, который наследует от dict, поэтому к нему можно обратиться просто как


events = outcomes[input_state]
print(f'Detected events: {events}')

Detected events: 153

Восстанавливаем перманент по формуле выше, не забывая про нормировку на спектральную норму s:


n = 4 # размер матрицы
perm = (s**n) * np.sqrt(events/shots)
print(f'Calculated permanent: {perm:.2f}')

1.98

Вау, идеальное совпадение с ожидаемой двойкой!


Симулятор Altair


Теперь запустим то же самое на облачном симуляторе, предварительно увеличив число шотов до 100 миллионов:


shots = 100_000_000
proc = pcvl.RemoteProcessor('sim:altair', token)

После окончания посмотрим, сколько же совпадений мы увидели:


events = outcomes[input_state]
print(f'Detected events: {events}')

Detected events: 83

Всего 83 из 100 миллионов?! Минуту назад мы видели в два раза больше совпадений на 10 тысяч шотов, что произошло?


Секрет в том, что QPU очень большой и сложный, и фотону легко в нем потеряться. Суммарное пропускание (transmittance) QPU Altair составляет всего несколько процентов. По дефолту симулятор запускает расчет именно пропусканием в 6 % — то есть только 6 % фотонов оказываются задетектированы на выходе из чипа. Но это же симулятор, поэтому пропускание можно выставить обратно на 100 %:


proc = pcvl.RemoteProcessor('sim:altair', token)
proc.set_parameters({
    "transmittance": 1.00,
})

и запустить вычисления еще раз:


events = outcomes[input_state]
print(f'Detected events: {events}')

n = 4 # размер матрицы
perm = (s**n) * np.sqrt(events/shots)
print(f'Calculated permanent: {perm:.2f}')

Detected events:  1444826
Calculated permanent: 1.98

Совсем другое дело! Но что же делать с симуляцией рельного QPU, у которого пропускание t гораздо ниже? В принципе, эти потери несложно учесть:


  • Один фотон, запущенный в QPU, будет задетектирован с вероятностью t, а потерян — с веротяностью 1-t.
  • Для двух фотонов вероятность задетектировать оба равна t^2, а вероятность потерять оба — (1-t)^2.
  • И так далее. Для четырех картинка выглядит как-то так:


Когда мы вычисляем перманент, мы делим число интересующих нас событий |1,1,1,1,0,0,0,0> на число всех событий. Из-за потерь события |1,1,1,1,0,0,0,0> приходят в t^4 раз реже, а шоты надо скорректировать на 1 — (1-t)^4 чтобы не забыть случаи со всеми нулями на выходе. В итоге получаем красивую формулу:



И немедленно подставляем в нее наш результат с 83 событиями из 100 000 000 и t = 6 %:


events = outcomes[input_state]
print(f'Detected events: {events}')

n = 4 # размер матрицы
t = 0.06 # пропускание
perm = (s**n) * np.sqrt(events/shots * (1-(1-t)**n)/t**n)
print(f'Calculated permanent: {perm:.2f}')

Detected samples: 83
Calculated permanent: 1.90 

Бинго! Вот таким нехитрым способом можно учесть неидеальность квантового процессора.


QPU Altair


Осталось запустить то же самое на настоящем QPU. Его пропускание еще меньше, поэтому увеличим число шотов до 1 миллиарда:


shots = 1_000_000_000
proc = pcvl.RemoteProcessor('qpu:altair', token)

и заберем результаты:


events = outcomes[input_state]
print(f'Detected events: {events}')

Detected events: 69

Пропускание в тот день составило 2.3 %, поэтому после коррекции я получил


n = 4 # размер матрицы
t = 0.023 # пропускание
perm = (s**n) * np.sqrt(events/shots * (1-(1-t)**n)/t**n)
print(f'Calculated permanent: {perm:.2f}')

Calculated permanent: 2.22

И вновь перманент равен двум, как мы и ожидали. Напомню, что мы не ждем высокой точности от квантовых вычислений, ошибка всего в 10 % — это более, чем замечательно.


Ну что же, принимайте поздравления, мы решили задачу про Винтика и Шпунтика на квантовом компьютере!


Вместо заключения


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


А теперь хорошие новости: фотонные квантовые компьютеры способны далеко не только на бозонный сэмплинг. Фотонные платформы принципиально отличаются от привычных сверхпроводниковых чипов IBM или Google и позволяет нативно реализовывать новые интересные алгоритмы. При этом на фотонные чипы на удивление хорошо портируются примитивы сверхпроводниковых платформ, поэтому на них можно будет успешно запускать и знаменитые алгоритмы Шора или Гровера. Разумеется, десятифотонного компьютера от Quandela пока еще недостаточно для факторизации простых чисел; впрочем, он уже успешно используется в простых юз-кейсах и учебных программах. Плюс ко всему все нынешние фотонные платформы показывают уверенный рост и на удивление хорошие перспективы для масштабирования. Так что все самое интересное только начинается.

Комментарии (10)


  1. sonytruelove
    02.09.2024 12:58
    +3

    Статья расставила все точки над и в тайне квантовых вычислений для меня. Природу фотона я знал, но о фотонных чипах услышал впервые. Будут ли еще статьи с схожей тематикой?


  1. rencom66
    02.09.2024 12:58
    +2

    Спасибо за статью.

    Не всё понятно , но интересно очень )


  1. Tihron
    02.09.2024 12:58
    +3

    Ткнул, думая что необычным названием автор пытался компенсировать скудность статьи, а тут такой алмаз


  1. janatem
    02.09.2024 12:58
    +2

    Насчет учета потерь фотонов. Насколько я понял, отбрасываются все результаты, в которых хотя бы один фотон потерян. Но, кажется, для экономии шотов (или, эквивалентно, для повышения точности) можно учитывать и «бракованные» результаты. Например, если пришло три фотона из четырех, то есть два варианта: (1) как ни добавляй потерянный фотон в результат, нельзя добиться добиться того, чтобы выход совпадал с входом; (2) наоборот. Тогда вроде можно посчитать количество случаев (2), скорректировать их на некоторый множитель и добавить к «хорошим» результатам.


    1. qbertych Автор
      02.09.2024 12:58

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


  1. vvvphoenix
    02.09.2024 12:58
    +3

    Wow. Я в восторге. Приз, который я анонсировал однозначно ваш :). Cкоро все официально, опубликую. Я к тому же придумал новое решение тернарного случая (через теорию групп), так что есть повод. К тому же мы в Неймарке активно интересуемся темой квантовых вычислений, так что будем рады посотрудничать.

    Ну и напоследок еще соображение, скорее обращенное к Хабру. Мне сейчас по долгу службы часто приходится общаться с редакторами (реферируемых) научных журналов. Это такие издания, которые читают 1.5 человека из соответствующей секты. И все они жалуются на отсутствие денег и тяжелую жизнь. И это неудивительно. И вот недавно мне пришла в голову мысль, что Хабр мог бы заменить многие из них. И охват аудитории в разы больше и ресурс гораздо живее. И аудитория тут вполне квалифицированная, чему настоящая статья - доказательство. Возьметесь? :)


    1. rukhi7
      02.09.2024 12:58
      +1

      я конечно дико извиняюсь что лезу не в свое дело, но мне кажется аудитории тоже будет интересно в чем же суть вашего предложения (автору статьи я так понимаю), за что вы предлагаете взяться?

      Из абзатца который заканчивается этим

      Возьметесь? :)

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

      Но может быть в этом тексте что-то закодировано, конечно, то что все кроме меня поняли, тогда еще раз извините.


    1. qbertych Автор
      02.09.2024 12:58

      Спасибо, очень рад услышать!
      Новое аналитическое решение - это очень любоптыно, буду ждать с нетерпением.


  1. rukhi7
    02.09.2024 12:58

    Статья действительно замечательная и выше всяких похвал, только на вопрос:

    Вопрос из зала: эээ… и это все еще имеет отношение к квантовому превосходству?

    надо добавить уточнение: квантовое превосходство для кого?!

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

    Я уверен те кто придумал задачу про фотоны очень давно и небезуспешно занимаются проектированием и производством реальных процессоров на транзисторах, а не фотонных и/или квантовых. И пока у нас не будет этой базы мы так и будем наблюдать за чужими успехами в области запрещенной (фактически) у нас практической кибернетики, разрабатывая фантастические- оторванные от практики теории далекого будущего.


  1. qw1
    02.09.2024 12:58

    Но первоначальная постановка подразумевает точный ответ. Ошибка в любой цифре - это уже неверное решение. А тут задачу подменили на "приблизительно оценить"?