자습서: Q#으로 양자 얽힘 살펴보기
이 자습서에서는 큐비트를 조작 및 측정하고 중첩과 얽힘의 효과를 시연하는 Q# 프로그램을 작성하는 방법을 보여 줍니다. 특정 양자 상태에서 두 개의 큐비트를 준비하고, 를 사용하여 큐비트 Q# 에서 작동하여 상태를 변경하는 방법을 알아보고, 중첩 및 얽힘의 영향을 보여 줍니다. 큐비트 상태, 작업 및 측정값을 소개하는 프로그램을 하나씩 빌드 Q# 합니다.
참고
Microsoft Quantum Development Kit(클래식 QDK)는 2024년 6월 30일 이후에 더 이상 지원되지 않습니다. 기존 QDK 개발자인 경우 새로운 Azure Quantum Development Kit(최신 QDK) 로 전환하여 양자 솔루션을 계속 개발하는 것이 좋습니다. 자세한 내용은 최신 QDK로 코드 마이그레이션을 참조하세요Q#.
시작하기 전에 이해해야 할 몇 가지 주요 개념은 다음과 같습니다.
- 클래식 비트는 0 또는 1 같은 단일 이진 값을 보유하는 반면, 큐비트 상태는 두 양자 상태 0과 1의 중첩에 있을 수 있습니다. 가능한 각 양자 상태에는 연결된 확률 진폭이 있습니다.
- 큐비트를 측정하는 행위는 특정 확률로 이진 결과를 생성하고 큐비트의 상태를 중첩에서 바꿉니다.
- 서로 독립적으로 설명할 수 없도록 여러 큐비트를 얽을 수 있습니다. 즉, 얽힌 쌍의 한 큐비트에 어떤 일이 발생하든 다른 큐비트에도 발생합니다.
이 자습서에서 학습할 방법은 다음과 같습니다.
- 큐비트를 원하는 상태로 초기화하는 작업을 만듭니 Q# 다.
- 큐비트를 중첩에 넣습니다.
- 큐비트 쌍을 얽습니다.
- 큐비트를 측정하고 결과를 관찰합니다.
팁
양자 컴퓨팅 과정을 가속화하려면 Azure Quantum 웹 사이트의 고유한 기능인 Azure Quantum을 사용하여 코드를 검사. 여기서는 기본 제공 샘플 또는 사용자 고유 Q# 의 Q# 프로그램을 실행하고, 프롬프트에서 새 Q# 코드를 생성하고, 한 번의 클릭으로 웹용 VS Code에서 코드를 열고 실행하고, Copilot에게 양자 컴퓨팅에 대한 질문을 할 수 있습니다.
사전 요구 사항
Azure Quantum용 Copilot에서 코드 샘플을 실행하려면 다음이 필요합니다.
- MICROSOFT(MSA) 전자 메일 계정.
Copilot에 대한 자세한 내용은 Azure Quantum 탐색을 참조하세요.
알려진 상태로 큐비트 초기화
첫 번째 단계는 큐비트를 알려진 상태로 초기화하는 Q# 연산을 정의하는 것입니다. 이는 큐비트를 클래식 상태로 설정하기 위해 호출할 수 있습니다. 즉, 측정될 때 시간의 100%를 반환 Zero
하거나 시간의 100%를 반환 One
합니다. 큐비트 측정은 또는 One
값 Zero
만 가질 수 있는 형식Result
을 반환 Q# 합니다.
Azure Quantum용 Copilot를 열고 다음 코드를 코드 편집기 창에 복사합니다. 아직 실행을 클릭하지 마세요 . 자습서의 뒷부분에서 코드를 실행합니다.
namespace Bell {
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Canon;
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
}
이 코드 예제는 큐비트 상태를 변환하는 두 가지 연산인 M
및 X
를 소개합니다.
SetQubitState
연산:
- 두 개의 매개 변수를 사용합니다. 즉
Result
, 큐비트가 (Zero
또는One
)에 있을 때 원하는 상태를 나타내는 라는desired
형식과 형식Qubit
을 사용합니다. - 큐비트(
Zero
또는One
)의 상태를 측정하고 결과를desired
에 지정된 값과 비교하는 측정 연산M
을 수행합니다. - 측정값이 비교된 값과 일치하지 않는 경우
X
연산을 실행합니다. 이 연산은 측정이Zero
및One
을 반환할 확률이 역전되도록 큐비트의 상태를 플리핑합니다. 이러한 방식으로SetQubitState
는 항상 대상 큐비트를 원하는 상태로 설정합니다.
Bell 상태를 테스트하는 테스트 작업 작성
이제 SetQubitState
연산의 효과를 보여 주기 위해 이름이 TestBellState
인 다른 연산을 만듭니다. 이 작업은 두 개의 큐비트를 할당하고, 를 호출 SetQubitState
하여 첫 번째 큐비트를 알려진 상태로 설정한 다음, 큐비트를 측정하여 결과를 확인합니다.
다음 코드를 작업 아래의 코드 편집기 창에 복사합니다 SetQubitState
.
operation TestBellState() : (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
로 초기화하고 각 큐비트를 1,000번 측정합니다.
TestBellState
연산:
- 카운터 및 초기 큐비트 상태에 대한 변수를 설정합니다.
use
문을 호출하여 두 큐비트를 초기화합니다.count
반복을 반복합니다. 각 루프에 대해SetQubitState
를 호출하여 첫 번째 큐비트에 지정된initial
값을 설정합니다.SetQubitState
를 다시 호출하여 두 번째 큐비트를Zero
상태로 설정합니다.M
연산을 사용하여 각 큐비트를 측정합니다.One
을 반환하는 각 큐비트의 측정 수를 저장합니다.
- 루프가 완료되면
SetQubitState
를 다시 호출하여 큐비를 알려진 상태(Zero
)로 다시 설정합니다. 그러면 다른 사용자가 큐비트를 알려진 상태에서 할당할 수 있습니다. 이는use
문에 필요합니다. - 마지막으로 함수를
Message
사용하여 결과를 반환하기 전에 Copilot 출력 창에 결과를 출력합니다.
Azure Quantum용 Copilot에서 코드 실행
중첩 및 얽힘 프로시저로 이동하기 전에 이 시점까지 코드를 테스트하여 큐비트의 초기화 및 측정을 확인할 수 있습니다.
코드를 독립 실행형 프로그램으로 실행하려면 Copilot의 Q# 컴파일러에서 프로그램을 시작할 위치를 알아야 합니다. 이 작업은 먼저 실행하려는 작업 바로 앞에 를 추가하여 @EntryPoint()
파일에서 Q# 수행됩니다. 예를 들어 이 경우 작업은 입니다 TestBellState
.
참고
@EntryPoint()
는 독립 실행형 Q# 프로그램에만 필요합니다. Jupyter Notebooks에서 프로그램을 실행 Q# 하거나 Python 호스트 파일에서 프로그램을 호출 Q# 하는 경우 필요하지 않으며 포함된 경우 오류가 발생합니다.
@EntryPoint()
작업 직전에 TestBellState
를 추가하면 Q# 이제 이 시점까지 프로그램이 다음과 같이 표시됩니다.
namespace Bell {
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Canon;
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
@EntryPoint()
operation TestBellState() : (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 for 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
큐비트를 중첩에 넣기
현재 프로그램의 큐비트는 모두 클래식 상태입니다. 즉, 1 또는 0입니다. 프로그램에서 큐비트를 알려진 상태로 초기화하고 조작할 프로세스를 추가하지 않았기 때문에 이를 알 수 있습니다. 큐비트를 얽기 전에 첫 번째 큐비트를 중첩 상태로 전환합니다. 여기서 큐비트의 측정값은 시간의 ~50%와 One
시간의 ~50%를 반환 Zero
합니다. 개념적으로 큐비트는 또는 One
를 측정 Zero
할 확률이 같다고 생각할 수 있습니다.
큐비트를 중첩에 배치하기 위해 Q#에서는 H
또는 Hadamard 연산을 제공합니다. X
큐비트를 0에서 1(또는 그 반대로 H
대칭 이동)한 이전에 알려진 상태 프로시저로 큐비트 초기화 작업을 기억합니다. 이 연산은 큐비트를 중간에 또는 One
의 Zero
동일한 확률 상태로 대칭 이동합니다. 측정할 때 중첩의 큐비트는 대략 동일한 수의 Zero
및 One
결과를 반환해야 합니다.
초기 값을 One
로 재설정하고 작업에 대한 줄을 삽입하여 작업의 코드를 TestBellState
수정합니다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% One
과 50% 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
참고
Azure Quantum용 Copilot에서 슬라이더를 이동하고 샷 수를 늘리면 중첩 결과가 샷 분포에 따라 약간 달라지는 방식을 확인할 수 있습니다.
두 큐비트 얽기
앞에서 설명한 것처럼 얽힌 큐비트는 서로 독립적으로 설명할 수 없도록 연결됩니다. 즉, 하나의 큐비트에 어떤 연산이 일어나든 얽힌 큐비트에도 발생합니다. 이렇게 하면 다른 큐비트의 상태를 측정하여 측정하지 않고 한 큐비트의 결과 상태를 알 수 있습니다. 이 예제에서는 두 큐비트를 사용하지만 셋 이상의 큐비트를 얽을 수도 있습니다.
얽힘을 사용하도록 설정하기 위해 Q#에서는 CNOT
Controled-NOT을 나타내는 연산을 제공합니다. 두 큐비트에 대해 이 연산을 실행하면 그 결과로 첫 번째 큐비트가 One
인 경우 두 번째 큐비트가 대칭 이동됩니다.
프로그램에서 H
연산 바로 다음에 CNOT
연산을 추가합니다. 전체 프로그램은 다음과 같습니다.
namespace Bell {
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Canon;
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
@EntryPoint()
operation TestBellState() : (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 Development Kit 확장의 최신 버전입니다. 설치 세부 정보는 VS Code에 최신 QDK 설치를 참조하세요.
새 Q# 파일 만들기
- Visual Studio Code 열고 파일 > 새 텍스트 파일을 선택하여 새 파일을 만듭니다.
- 파일을
CreateBellStates.qs
로 저장합니다. 이 파일에는 프로그램의 코드가 Q# 포함됩니다.
알려진 상태로 큐비트 초기화
첫 번째 단계는 큐비트를 알려진 상태로 초기화하는 Q# 연산을 정의하는 것입니다. 이를 호출하여 큐비트를 클래식 상태로 설정할 수 있습니다. 즉, 시간의 Zero
100%를 반환하거나 시간의 One
100%를 반환합니다. Zero
및 One
은 큐비트 측정에서 가능한 두 가지 결과를 나타내는 Q# 값입니다.
CreateBellStates.qs
다음 코드를 열고 복사합니다.
namespace Bell {
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Canon;
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
}
이 코드 예제는 큐비트 상태를 변환하는 두 가지 연산인 M
및 X
를 소개합니다.
SetQubitState
연산:
- 두 개의 매개 변수를 사용합니다. 즉
Result
,desired
큐비트가 (Zero
또는One
)에 있을 원하는 상태를 나타내는 라는 형식과 형식Qubit
을 사용합니다. - 큐비트(
Zero
또는One
)의 상태를 측정하고 결과를desired
에 지정된 값과 비교하는 측정 연산M
을 수행합니다. - 측정값이 비교된 값과 일치하지 않는 경우
X
연산을 실행합니다. 이 연산은 측정이Zero
및One
을 반환할 확률이 역전되도록 큐비트의 상태를 플리핑합니다. 이러한 방식으로SetQubitState
는 항상 대상 큐비트를 원하는 상태로 설정합니다.
Bell 상태를 테스트하는 테스트 작업 작성
이제 SetQubitState
연산의 효과를 보여 주기 위해 이름이 TestBellState
인 다른 연산을 만듭니다. 이 작업은 두 개의 큐비트를 할당하고, 를 호출 SetQubitState
하여 첫 번째 큐비트를 알려진 상태로 설정한 다음, 큐비트를 측정하여 결과를 확인합니다.
CreateBellStates.qs
파일에서 SetQubitState
연산 이후에 다음 연산을 추가합니다.
operation TestBellState() : (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
로 초기화하고 각 큐비트를 1,000번 측정합니다.
TestBellState
연산:
- 두 매개 변수를 사용합니다. 하나는 측정을 실행할 횟수인
count
이고 다른 하나는 큐비트를 초기화할 필요한 상태인initial
입니다. use
문을 호출하여 두 큐비트를 초기화합니다.count
반복을 반복합니다. 각 루프에 대해SetQubitState
를 호출하여 첫 번째 큐비트에 지정된initial
값을 설정합니다.SetQubitState
를 다시 호출하여 두 번째 큐비트를Zero
상태로 설정합니다.M
연산을 사용하여 각 큐비트를 측정합니다.One
을 반환하는 각 큐비트의 측정 수를 저장합니다.
- 루프가 완료되면
SetQubitState
를 다시 호출하여 큐비를 알려진 상태(Zero
)로 다시 설정합니다. 그러면 다른 사용자가 큐비트를 알려진 상태에서 할당할 수 있습니다. 이는use
문에 필요합니다. - 마지막으로, 결과를 반환하기 전에
Message
함수를 사용하여 콘솔에 메시지를 출력합니다.
코드 실행
중첩 및 얽힘 프로시저로 이동하기 전에 이 지점까지 코드를 테스트하여 큐비트의 초기화 및 측정을 확인합니다.
이 작업은 실행하려는 작업 바로 앞에 를 추가하여 @EntryPoint()
파일에서 Q# 수행됩니다. 예를 들어 이 경우 작업은 입니다 TestBellState
.
참고
@EntryPoint()
는 독립 실행형 Q# 프로그램에만 필요합니다. Jupyter Notebook에서 프로그램을 실행 Q# 하거나 Python 호스트 파일에서 프로그램을 호출 Q# 하는 경우 필요하지 않으며 포함된 경우 오류가 발생합니다.
이제 CreateBellStates.qs
파일이 다음과 비슷할 것입니다.
namespace Bell {
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Canon;
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
@EntryPoint()
operation TestBellState() : (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을 검색하고, : Azure Quantum QIR 대상 프로필을 설정한 다음, : 무제한을 선택합니다Q#.Q#
프로그램을 실행하려면 오른쪽 위에 있는 재생 아이콘 드롭다운에서 파일 실행을 Q# 선택하거나 Ctrl+F5를 누릅니다. 프로그램은 기본 시뮬레이터에서 특성으로 @EntryPoint()
표시된 작업 또는 함수를 실행합니다.
참고
대상 프로필이 무제한으로 설정되지 않은 경우 프로그램을 실행할 때 오류가 발생합니다.
출력이 디버그 콘솔에 표시됩니다.
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
팁
코드를 다시 실행하기 전에 변경 내용을 적용할 때마다 파일을 저장해야 합니다.
큐비트를 중첩에 넣기
현재 프로그램의 큐비트는 모두 클래식 상태입니다. 즉, 1 또는 0입니다. 프로그램에서 큐비트를 알려진 상태로 초기화하고 조작할 프로세스를 추가하지 않았기 때문에 이를 알 수 있습니다. 큐비트를 얽기 전에 첫 번째 큐비트를 중첩 상태로 전환합니다. 여기서 큐비트의 측정값은 Zero
(시간의 50%) 및 One
(시간의 50%)을 반환합니다. 개념적으로 큐비트는 Zero
와 One
의 중간으로 생각할 수 있습니다.
큐비트를 중첩에 배치하기 위해 Q#에서는 H
또는 Hadamard 연산을 제공합니다. X
큐비트를 이전의 알려진 상태 프로시저로 초기화하여 큐비트를 에서 Zero
One
(또는 그 반대로H
) 대칭 이동한 작업을 회수합니다. 이 작업은 큐비트를 중간에 또는 의 Zero
One
동일한 확률 상태로 대칭 이동합니다. 측정할 때 중첩의 큐비트는 대략 동일한 수의 Zero
및 One
결과를 반환해야 합니다.
H
연산을 포함하도록 TestBellState
연산의 코드를 수정합니다.
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% One
및 50% 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
Controled-NOT을 나타내는 연산을 제공합니다. 두 큐비트에 대해 이 연산을 실행하면 그 결과로 첫 번째 큐비트가 One
인 경우 두 번째 큐비트가 대칭 이동됩니다.
프로그램에서 H
연산 바로 다음에 CNOT
연산을 추가합니다. 전체 프로그램은 다음과 같습니다.
namespace Bell {
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Canon;
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
@EntryPoint()
operation TestBellState() : (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);
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
첫 번째 큐비트에 대한 통계는 변경되지 않았지만(측정 후 Zero
또는 One
의 확률 50/50) 두 번째 큐비트의 측정 결과는 항상 첫 번째 큐비트의 측정과 동일합니다. CNOT
연산은 두 큐비트를 얽어서 둘 중 하나에서 발생하는 모든 것이 다른 큐비트에서도 발생하도록 했습니다.
빈도 히스토그램 그리기
양자 프로그램을 여러 번 실행하여 얻은 결과의 분포를 시각화해 보겠습니다. 빈도 히스토그램은 이러한 결과의 확률 분포를 시각화하는 데 도움이 됩니다.
보기 -> 명령 팔레트를 선택하거나 Ctrl+Shift+P를 누르고 " 히스토그램"Q#을 입력합니다. 그러면 : 파일 실행 및 히스토그램 표시 옵션이 표시됩니다. 히스토그램 창을 열려 Q# 면 이 옵션을 선택합니다.
프로그램을 실행할 수 있는 여러 샷 (예: 100발)을 입력하고 Enter 키를 누릅니 다. 히스토그램이 히스토그램 창에 Q# 표시됩니다.
히스토그램의 각 막대는 가능한 결과에 해당하며, 그 높이는 결과가 관찰되는 횟수를 나타냅니다. 이 경우 50개의 고유한 결과가 있습니다. 각 결과에 대해 첫 번째 및 두 번째 큐비트의 측정 결과는 항상 동일합니다.
팁
마우스 스크롤 휠 또는 트랙 패드 제스처를 사용하여 히스토그램을 확대/축소할 수 있습니다. 확대하면 스크롤하는 동안 'Alt'를 눌러 차트를 이동하면 됩니다.
막대를 클릭하여 해당 결과의 백분율 을 표시합니다.
왼쪽 위 설정 아이콘 을 클릭하여 옵션을 표시합니다. 상위 10개 결과, 상위 25개 결과 또는 모든 결과를 표시할 수 있습니다. 결과를 높음에서 낮음 또는 낮음에서 높음으로 정렬할 수도 있습니다.
다음 단계
다른 Q# 자습서 살펴보기:
- 양자 난수 생성기는 중첩의 큐비트에서 난수를 생성하는 프로그램을 작성하는 Q# 방법을 보여 줍니다.
- Grover의 검색 알고리즘 은 Grover의 검색 알고리즘을 Q# 사용하는 프로그램을 작성하는 방법을 보여줍니다.
- Quantum 푸리에 변환 은 특정 큐비트를 직접 해결하는 프로그램을 작성하는 Q# 방법을 살펴봅니다.
- Quantum Katas는 양자 컴퓨팅 및 프로그래밍 요소를 동시에 교육하기 위한 자기 주도적인 자습서 및 Q# 프로그래밍 연습입니다.
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기