Учебник. Изучение квантовой запутанности с помощью Q#
В этом руководстве вы напишете Q# программу, которая управляет кубитами и измеряет кубиты и демонстрирует эффекты суперпозиции и запутанности. Вы подготавливаете два кубита в определенном квантовом состоянии, узнайте, как работать с кубитами, Q# чтобы изменить их состояние, и продемонстрировать эффекты суперпозиции и запутанности. Вы создаете программу Q# по частям, чтобы представить состояния кубитов, операции и измерения.
Ниже приведены некоторые основные понятия, которые необходимо понять перед началом работы:
- В классическом бите хранится одно двоичное значение (0 или 1), а кубит может находиться в состоянии суперпозиции двух квантовых значений (0 и 1). Каждое возможное квантовое состояние связано с амплитудой вероятности.
- Действие измерения кубита создает двоичный результат с определенной вероятностью и изменяет состояние кубита вне суперпозиции.
- Несколько кубитов могут быть запутаны таким образом, что их нельзя описать независимо друг от друга. Это означает, что любые события с одним из кубитов в паре запутанных влияют и на другой кубит.
Из этого руководства вы узнаете, как выполнять следующие задачи:
- Создайте Q# операции для инициализации кубита в требуемое состояние.
- создание суперпозиции для кубита;
- запутывание пары кубитов;
- Измерение кубита и наблюдение за результатами.
Совет
Если вы хотите ускорить путешествие квантовых вычислений, ознакомьтесь с кодом с помощью Azure Quantum, уникальной функцией веб-сайта Azure Quantum. Здесь можно запустить встроенные Q# примеры или Q# собственные программы, создать новый Q# код из запросов, открыть и запустить код в VS Code для Интернета с помощью одного щелчка мыши и задать Copilot любые вопросы о квантовых вычислениях.
Необходимые компоненты
Чтобы запустить пример кода в Copilot для Azure Quantum, вам потребуется:
- Учетная запись электронной почты Майкрософт (MSA).
Дополнительные сведения о Copilot см. в статье "Обзор Azure Quantum".
Инициализация кубита в известном состоянии
Первым делом мы определим операцию Q#, которая инициализирует кубит в известном состоянии. Эту операцию можно вызвать для задания кубита классическому состоянию, что означает, что при измерении он возвращает Zero
100% времени или возвращает One
100% времени. Измерение кубита возвращает Q# тип Result
, который может иметь только значение Zero
или One
.
Откройте Copilot для Azure Quantum и скопируйте следующий код в окно редактора кода. Не нажимайте кнопку "Выполнить " еще; вы запустите код позже в руководстве.
import Microsoft.Quantum.Intrinsic.*;
import Microsoft.Quantum.Canon.*;
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
Пример кода содержит две стандартны операции, M
и X
, которые преобразуют состояние кубита.
Операция SetQubitState
:
- Принимает два параметра: тип
Result
с именемdesired
, который представляет требуемое состояние для кубита, в который должен находиться кубит (Zero
илиOne
), а также типQubit
. - Выполняет операцию измерения,
M
, которая измеряет состояние кубита (Zero
илиOne
) и сравнивает результат со значением, указанным вdesired
. - Если результат измерения не соответствует сравниваемому значению, выполняется операция
X
, инвертирующая состояние кубита, в котором вероятности возвращаемого измеренияZero
иOne
меняются местами. Таким образом,SetQubitState
всегда устанавливает целевой кубит в нужное состояние.
Создание тестовой операции для проверки состояния Колокола
Далее, чтобы продемонстрировать результат операции SetQubitState
, создайте другую операцию с именем Main
. Эта операция будет выделять два кубита, вызывать SetQubitState
для задания первого кубита известному состоянию, а затем измерять кубиты, чтобы увидеть результаты.
Скопируйте следующий код в окно редактора кода под операцией SetQubitState
.
operation Main() : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
let count = 1000;
let initial = One;
// allocate the qubits
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
// Count the number of 'Ones' returned:
if resultQ1 == One {
set numOnesQ1 += 1;
}
if resultQ2 == One {
set numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Display the times that |0> is returned, and times that |1> is returned
Message($"Q1 - Zeros: {count - numOnesQ1}");
Message($"Q1 - Ones: {numOnesQ1}");
Message($"Q2 - Zeros: {count - numOnesQ2}");
Message($"Q2 - Ones: {numOnesQ2}");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
В коде count
initial
переменные задаются и One
имеют значение 1000
соответственно. Это инициализирует первый кубит в состоянии One
и измеряет каждый кубит 1000 раз.
Операция Main
:
- Задает переменные для счетчика и начального состояния кубита.
- Вызывает инструкцию
use
для инициализации двух кубитов. - Выполняет цикл в течение
count
итераций. Для каждого цикла он- Вызывает
SetQubitState
, чтобы задать указанное значениеinitial
для первого кубита. - Снова вызывает
SetQubitState
, чтобы установить для второго кубита состояниеZero
. - Использует операцию
M
для измерения каждого кубита. - Сохраняет количество измерений для каждого кубита, возвращающего значение
One
.
- Вызывает
- После завершения цикла снова вызывается метод
SetQubitState
, чтобы сбросить кубиты до известного состояния (Zero
) и разрешить другим пользователям выделить кубиты в известном состоянии. Сброс требуется операторомuse
. - Наконец, функция используется
Message
для печати результатов в окнах выходных данных Copilot, прежде чем возвращать результаты.
Запустите код в Copilot для Azure Quantum
Перед переходом к процедурам для суперпозиции и запутания можно проверить код до этой точки, чтобы увидеть инициализацию и измерение кубитов.
Чтобы запустить код как автономную программу, Q# компилятор в Copilot должен знать , где начать программу. Так как пространство имен не указано, компилятор распознает точку входа по умолчанию как Main
операцию. Дополнительные сведения см. в разделе "Проекты" и неявные пространства имен.
Теперь программа Q# должна выглядеть следующим образом:
import Microsoft.Quantum.Intrinsic.*;
import Microsoft.Quantum.Canon.*;
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
operation Main() : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
let count = 1000;
let initial = One;
// allocate the qubits
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
// Count the number of 'Ones' returned:
if resultQ1 == One {
set numOnesQ1 += 1;
}
if resultQ2 == One {
set numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Display the times that |0> is returned, and times that |1> is returned
Message($"Q1 - Zeros: {count - numOnesQ1}");
Message($"Q1 - Ones: {numOnesQ1}");
Message($"Q2 - Zeros: {count - numOnesQ2}");
Message($"Q2 - Ones: {numOnesQ2}");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
Скопируйте и вставьте полный пример кода в окно кода Copilot для Azure Quantum , задайте для слайда количество снимков "1" и нажмите кнопку "Выполнить". Результаты отображаются в гистограмме и в полях результатов .
Q1 - Zeros: 0
Q1 - Ones: 1000
Q2 - Zeros: 1000
Q2 - Ones: 0
Так как манипуляций с кубитом еще не было, они сохраняют начальные значения: первый кубит каждый раз возвращает One
, а второй кубит возвращает Zero
.
Если изменить значение initial
Zero
и снова запустить программу, следует отметить, что первый кубит также возвращается Zero
каждый раз.
Q1 - Zeros: 1000
Q1 - Ones: 0
Q2 - Zeros: 1000
Q2 - Ones: 0
Совет
Нажмите клавиши CTRL-Z или Изменить > отмену и сохраните файл всякий раз, когда вы вводите тестовое изменение кода перед его повтором.
Состояние суперпозиции для кубита
В настоящее время кубиты в нашей программе находятся в классическом состоянии, то есть всегда имеют значение 1 или 0. Это известно, потому что программа инициализирует кубиты в известном состоянии, и вы не добавили процессы для управления ими. Прежде чем запутать кубиты, вы помещаете первый куб в состояние суперпозиции, где измерение кубита возвращает Zero
~50% времени и One
~50% времени. Концептуально кубит можно считать равным вероятностью измерения либо Zero
One
.
Чтобы помещать кубиты в состояние суперпозиции, Q# предоставляет операцию H
(операцию Адамара). X
Вспомните операцию от инициализации кубита к известной процедуре состояния ранее, которая перевернула кубит с 0 до 1 (или наоборот); H
операция перевернута кубита на полпути в состояние равной вероятности Zero
илиOne
. При измерении кубит должен возвращать примерно равное количество результатов Zero
и One
.
Измените код в Main
операции, сбросив начальное значение One
и вставив строку для H
операции:
for test in 1..count {
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
H(q1); // Add the H operation after initialization and before measurement
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
...
Теперь при запуске программы вы увидите результаты первого кубита в суперпозиции.
Q1 - Zeros: 523 // results vary
Q1 - Ones: 477
Q2 - Zeros: 1000
Q2 - Ones: 0
Каждый раз, когда вы запускаете программу, результаты первого кубита немного различаются, но будут близко к 50% и 50%, One
Zero
а результаты для второго кубита остаются все Zero
время.
Q1 - Zeros: 510
Q1 - Ones: 490
Q2 - Zeros: 1000
Q2 - Ones: 0
Инициализация первого кубита в состоянии Zero
дает аналогичные результаты.
Q1 - Zeros: 504
Q1 - Ones: 496
Q2 - Zeros: 1000
Q2 - Ones: 0
Примечание.
Переместив ползунок в Copilot для Azure Quantum и увеличив количество снимков, вы можете увидеть, как результаты суперпозиции немного отличаются по сравнению с распределением выстрелов.
Запутывание двух кубитов
Как упоминалось ранее, запутанные кубиты находятся в такой зависимости, что их невозможно описать независимо друг от друга. Любая операция, которая выполняется с одним из запутанных кубитов, определенным образом влияет на другой. Это позволяет вам выяснить состояние одного из этих кубитов без непосредственного измерения, зная результаты измерения состояние другого кубита. (В нашем примере используется всего два кубита, но вы можете запутать три кубита и даже больше.)
Для работы с состоянием запутанности Q# предоставляет операцию CNOT
, которая расшифровывается как Controlled-NOT (Контролируемое НЕ). В результате выполнения этой операции второй кубит инвертируется, только если первый кубит имеет значение One
.
Добавьте в программу операцию CNOT
, поместив ее сразу после операции H
. Теперь программа должна выглядеть так:
import Microsoft.Quantum.Intrinsic.*;
import Microsoft.Quantum.Canon.*;
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
operation Main() : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
let count = 1000;
let initial = Zero;
// allocate the qubits
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
H(q1);
CNOT(q1, q2); // Add the CNOT operation after the H operation
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
// Count the number of 'Ones' returned:
if resultQ1 == One {
set numOnesQ1 += 1;
}
if resultQ2 == One {
set numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Display the times that |0> is returned, and times that |1> is returned
Message($"Q1 - Zeros: {count - numOnesQ1}");
Message($"Q1 - Ones: {numOnesQ1}");
Message($"Q2 - Zeros: {count - numOnesQ2}");
Message($"Q2 - Ones: {numOnesQ2}");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
Теперь при запуске программы вы увидите примерно следующее:
Q1 - Zeros: 502 // results will vary
Q1 - Ones: 498
Q2 - Zeros: 502
Q2 - Ones: 498
Обратите внимание, что статистика для первого кубита не изменилась (по-прежнему существует ~50/50 вероятность Zero
измерения или One
после измерения), но результаты измерения для второго кубита всегда совпадают с измерением первого кубита, независимо от того, сколько раз вы запускаете программу. Операция CNOT
добавила запутанность кубитов, и любые изменения с одним из них теперь влияют и на другой.
Необходимые компоненты
Чтобы разработать и запустить пример кода в локальной среде разработки:
- Последняя версия Visual Studio Code или откройте VS Code в Интернете.
- Последняя версия расширения Пакета средств разработки Azure Quantum. Дополнительные сведения об установке см. в разделе "Установка QDK" в VS Code.
Создание файла Q#
- Откройте Visual Studio Code и выберите "Создать > текстовый файл ", чтобы создать новый файл.
- Сохраните файл как
CreateBellStates.qs
. Этот файл будет содержать Q# код для программы.
Инициализация кубита в известном состоянии
Первым делом мы определим операцию Q#, которая инициализирует кубит в известном состоянии. Эту операцию можно вызвать, чтобы задать кубит классическому состоянию, что означает, что она возвращает Zero
100% времени или возвращает One
100% времени. Значения Zero
и One
имеют тип Q# и представляют единственные возможные результаты измерения кубита.
Откройте и скопируйте CreateBellStates.qs
следующий код:
import Microsoft.Quantum.Intrinsic.*;
import Microsoft.Quantum.Canon.*;
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
Пример кода содержит две стандартны операции, M
и X
, которые преобразуют состояние кубита.
Операция SetQubitState
:
- Принимает два параметра: тип
Result
с именемdesired
, который представляет требуемое состояние для кубита, в который должен находиться кубит (Zero
илиOne
), а также типQubit
. - Выполняет операцию измерения,
M
, которая измеряет состояние кубита (Zero
илиOne
) и сравнивает результат со значением, указанным вdesired
. - Если результат измерения не соответствует сравниваемому значению, выполняется операция
X
, инвертирующая состояние кубита, в котором вероятности возвращаемого измеренияZero
иOne
меняются местами. Таким образом,SetQubitState
всегда устанавливает целевой кубит в нужное состояние.
Создание тестовой операции для проверки состояния Колокола
Далее, чтобы продемонстрировать результат операции SetQubitState
, создайте другую операцию с именем Main
. Эта операция выделяет два кубита, вызов SetQubitState
для задания первого кубита известному состоянию, а затем измеряет кубиты, чтобы увидеть результаты.
Добавьте следующую операцию в файл CreateBellStates.qs
после операции SetQubitState
.
operation Main() : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
let count = 1000;
let initial = One;
// allocate the qubits
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
// Count the number of 'Ones' returned:
if resultQ1 == One {
set numOnesQ1 += 1;
}
if resultQ2 == One {
set numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Display the times that |0> is returned, and times that |1> is returned
Message($"Q1 - Zeros: {count - numOnesQ1}");
Message($"Q1 - Ones: {numOnesQ1}");
Message($"Q2 - Zeros: {count - numOnesQ2}");
Message($"Q2 - Ones: {numOnesQ2}");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
В коде count
initial
переменные задаются и One
имеют значение 1000
соответственно. Этот шаг инициализирует первый кубит и измеряет каждый кубит One
1000 раз.
Операция Main
:
- Принимает два параметра:
count
— количество запусков измерения,initial
— требуемое состояние для инициализации кубита. - Вызывает инструкцию
use
для инициализации двух кубитов. - Выполняет цикл в течение
count
итераций. Для каждого цикла он- Вызывает
SetQubitState
, чтобы задать указанное значениеinitial
для первого кубита. - Снова вызывает
SetQubitState
, чтобы установить для второго кубита состояниеZero
. - Использует операцию
M
для измерения каждого кубита. - Сохраняет количество измерений для каждого кубита, возвращающего значение
One
.
- Вызывает
- После завершения цикла снова вызывается метод
SetQubitState
, чтобы сбросить кубиты до известного состояния (Zero
) и разрешить другим пользователям выделить кубиты в известном состоянии. Сброс кубита требуется инструкциейuse
. - Наконец, использует функцию
Message
для вывода в консоль сообщения и возвращает полученные результаты.
Выполнение кода
Прежде чем переходить к процедурам для работы с суперпозицией и запутанностью, протестируйте код до этой точки, чтобы увидеть инициализацию и измерение кубита.
Чтобы запустить код как автономную программу, Q# компилятор должен знать , где запустить программу. Так как пространство имен не указано, компилятор распознает точку входа по умолчанию как Main
операцию. Дополнительные сведения см. в разделе "Проекты" и неявные пространства имен.
Файл
CreateBellStates.qs
до этого момента должен выглядеть следующим образом:import Microsoft.Quantum.Intrinsic.*; import Microsoft.Quantum.Canon.*; operation SetQubitState(desired : Result, target : Qubit) : Unit { if desired != M(target) { X(target); } } operation Main() : (Int, Int, Int, Int) { mutable numOnesQ1 = 0; mutable numOnesQ2 = 0; let count = 1000; let initial = One; // allocate the qubits use (q1, q2) = (Qubit(), Qubit()); for test in 1..count { SetQubitState(initial, q1); SetQubitState(Zero, q2); // measure each qubit let resultQ1 = M(q1); let resultQ2 = M(q2); // Count the number of 'Ones' returned: if resultQ1 == One { set numOnesQ1 += 1; } if resultQ2 == One { set numOnesQ2 += 1; } } // reset the qubits SetQubitState(Zero, q1); SetQubitState(Zero, q2); // Display the times that |0> is returned, and times that |1> is returned Message($"Q1 - Zeros: {count - numOnesQ1}"); Message($"Q1 - Ones: {numOnesQ1}"); Message($"Q2 - Zeros: {count - numOnesQ2}"); Message($"Q2 - Ones: {numOnesQ2}"); return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 ); }
Перед запуском программы убедитесь, что целевой профиль имеет значение "Неограниченный". Выберите представление —> палитра команд, найдите QIR, выберите Q#: задайте целевой профиль QIR Azure Quantum, а затем выберите Q#: неограниченный.
Примечание.
Если целевой профиль не задан как Неограниченный, при запуске программы возникает ошибка.
Чтобы запустить программу, щелкните "Запустить файл" в раскрывающемся списке значка воспроизведения в правом верхнем углу, выберите "ВыполнитьQ#" из списка команд, предшествующих
Main
операции, или нажмите клавиши CTRL+F5. Программа выполняетMain
операцию на симуляторе по умолчанию.Выходные данные отображаются в консоли отладки.
Q1 - Zeros: 0 Q1 - Ones: 1000 Q2 - Zeros: 1000 Q2 - Ones: 0
Так как манипуляций с кубитом еще не было, они сохраняют начальные значения: первый кубит каждый раз возвращает
One
, а второй кубит возвращаетZero
.Если изменить значение
initial
Zero
и снова запустить программу, следует отметить, что первый кубит также возвращаетсяZero
каждый раз.Q1 - Zeros: 1000 Q1 - Ones: 0 Q2 - Zeros: 1000 Q2 - Ones: 0
Совет
Нажмите клавиши CTRL-Z или Изменить > отмену и сохраните файл всякий раз, когда вы вводите тестовое изменение кода перед его повтором.
Состояние суперпозиции для кубита
В настоящее время кубиты в нашей программе находятся в классическом состоянии, то есть всегда имеют значение 1 или 0. Это известно, потому что программа инициализирует кубиты в известном состоянии, и вы не добавили процессы для управления ими. Прежде чем запутать кубиты, вы помещаете первый куб в состояние суперпозиции, где измерение кубита возвращает Zero
50% времени и One
50% времени. В теории можно рассматривать состояние кубита как промежуточное между Zero
и One
.
Чтобы помещать кубиты в состояние суперпозиции, Q# предоставляет операцию H
(операцию Адамара). X
Вспомните операцию от инициализации кубита к известной процедуре состояния ранее, которая перевернула кубитов из One
Zero
(или наоборот), H
операция перевернута кубита на полпути в состояние равной вероятности Zero
илиOne
. При измерении кубит должен возвращать примерно равное количество результатов Zero
и One
.
Измените код в операции
Main
, добавив в него операциюH
:for test in 1..count { use (q1, q2) = (Qubit(), Qubit()); for test in 1..count { SetQubitState(initial, q1); SetQubitState(Zero, q2); H(q1); // Add the H operation after initialization and before measurement // measure each qubit let resultQ1 = M(q1); let resultQ2 = M(q2); ...
Теперь при запуске программы вы можете наблюдать результаты применения суперпозиции к первому кубиту:
Q1 - Zeros: 523 // results will vary Q1 - Ones: 477 Q2 - Zeros: 1000 Q2 - Ones: 0
Каждый раз, когда вы запускаете программу, результаты первого кубита немного различаются, но будут близко к 50% и 50%,
One
Zero
а результаты для второго кубита остаются всеZero
время.Q1 - Zeros: 510 Q1 - Ones: 490 Q2 - Zeros: 1000 Q2 - Ones: 0
Инициализация первого кубита в состоянии
Zero
дает аналогичные результаты.Q1 - Zeros: 504 Q1 - Ones: 496 Q2 - Zeros: 1000 Q2 - Ones: 0
Запутывание двух кубитов
Как упоминалось ранее, запутанные кубиты находятся в такой зависимости, что их невозможно описать независимо друг от друга. Любая операция, которая выполняется с одним из запутанных кубитов, определенным образом влияет на другой. Это позволяет вам выяснить состояние одного из этих кубитов без непосредственного измерения, зная результаты измерения состояние другого кубита. (В нашем примере используется всего два кубита, но вы можете запутать три кубита и даже больше.)
Для работы с состоянием запутанности Q# предоставляет операцию CNOT
, которая расшифровывается как Controlled-NOT (Контролируемое НЕ). В результате выполнения этой операции второй кубит инвертируется, только если первый кубит имеет значение One
.
Добавьте в программу операцию
CNOT
, поместив ее сразу после операцииH
. Теперь программа должна выглядеть так:import Microsoft.Quantum.Intrinsic.*; import Microsoft.Quantum.Canon.*; operation SetQubitState(desired : Result, target : Qubit) : Unit { if desired != M(target) { X(target); } } operation Main() : (Int, Int, Int, Int) { mutable numOnesQ1 = 0; mutable numOnesQ2 = 0; let count = 1000; let initial = Zero; // allocate the qubits use (q1, q2) = (Qubit(), Qubit()); for test in 1..count { SetQubitState(initial, q1); SetQubitState(Zero, q2); H(q1); CNOT(q1, q2); // Add the CNOT operation after the H operation // measure each qubit let resultQ1 = M(q1); let resultQ2 = M(q2); // Count the number of 'Ones' returned: if resultQ1 == One { set numOnesQ1 += 1; } if resultQ2 == One { set numOnesQ2 += 1; } } // reset the qubits SetQubitState(Zero, q1); SetQubitState(Zero, q2); // Display the times that |0> is returned, and times that |1> is returned Message($"Q1 - Zeros: {count - numOnesQ1}"); Message($"Q1 - Ones: {numOnesQ1}"); Message($"Q2 - Zeros: {count - numOnesQ2}"); Message($"Q2 - Ones: {numOnesQ2}"); return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 ); }
Q1 - Zeros: 502 Q1 - Ones: 498 // results will vary Q2 - Zeros: 502 Q2 - Ones: 498 Result: "(502, 498, 502, 498)"
Статистика значений для первого кубита не изменилась (соотношение Zero
и One
после измерения составляет 50 на 50), но при измерении второго кубита теперь всегда возвращается такое же состояние, как у первого кубита. Операция CNOT
запутала два кубита, так что все, что происходит с одним из них, происходит с другим.
График гистограммы частоты
Давайте визуализируем распределение результатов, полученных при выполнении квантовой программы несколько раз. Гистограмма частоты помогает визуализировать распределение вероятностей этих результатов.
Выберите представление —> палитра команд или нажмите клавиши CTRL+SHIFT+P и введите гистограмму, которая должна открыть Q#файл : Запустить файл и отобразить параметр гистограммы . Вы также можете выбрать гистограмму из списка команд, описанных выше
Main
. Выберите этот параметр, чтобы открыть Q# окно гистограммы.Введите несколько снимков для выполнения программы, например 100 выстрелов , и нажмите клавишу ВВОД. Гистограмма отображается в Q# окне гистограммы.
Каждая полоса в гистограмме соответствует возможному результату, и его высота представляет количество наблюдаемых результатов. В этом случае существует 50 различных уникальных результатов. Обратите внимание, что для каждого результата результаты измерения для первого и второго кубита всегда одинаковы.
Совет
Вы можете увеличить гистограмму с помощью колесика прокрутки мыши или жеста трекпада. При увеличении масштаба диаграмму можно сдвигать, нажав клавиши ALT во время прокрутки.
Выберите панель, чтобы отобразить процент этого результата.
Щелкните значок параметров вверху слева, чтобы отобразить параметры. Вы можете отобразить первые 10 результатов, 25 лучших результатов или все результаты. Вы также можете отсортировать результаты от высокого до низкого или низкого.
Связанный контент
Ознакомьтесь с другими учебниками по Q#:
- Алгоритм поиска Гровера показывает, как написать Q# программу, использующую алгоритм поиска Гровера.
- Quantum Fourier Transform изучает, как писать программу, которая напрямую Q# обращается к определенным кубитам.
- Квантовые Катас — это самоуправляемые учебники и упражнения по программированию, направленные на обучение элементам квантовых вычислений и Q# программирования одновременно.