자습서: Q#으로 양자 얽힘 살펴보기
이 자습서에서는 큐비트를 조작 및 측정하고 중첩과 얽힘의 효과를 시연하는 Q# 프로그램을 작성하는 방법을 보여 줍니다.
- 클래식 비트는 0 또는 1 같은 단일 이진 값을 보유하는 반면, 큐비트 상태는 두 양자 상태 0과 1의 중첩에 있을 수 있습니다. 가능한 각 양자 상태에는 연결된 확률 진폭이 있습니다.
- 큐비트를 측정하는 행위는 특정 확률로 0 또는 1의 이진 결과를 생성하고 큐비트의 상태를 중첩에서 변경합니다.
- 여러 큐비트는 서로 독립적으로 설명할 수 없도록, 얽히게 할 수 있습니다. 즉, 얽힌 쌍의 한 큐비트에 어떤 일이 발생하든 다른 큐비트에도 발생합니다.
이 자습서에서는 특정 양자 상태에 있는 두 큐비트를 준비하고, Q#에서 두 큐비트의 상태를 변경하는 작업을 수행하며, 중첩 및 얽힘의 효과를 알아봅니다. 큐비트 상태, 연산 및 측정을 소개하는 Q# 프로그램을 하나씩 작성하게 됩니다.
필수 구성 요소
이 자습서를 완료하려면 다음이 필요합니다.
- 활성 구독이 있는 Azure 계정. Azure 계정이 없는 경우 무료로 등록하고 종량제 구독에 등록합니다.
- Azure Quantum 작업 영역 자세한 내용은 Azure Quantum 작업 영역 만들기를 참조하세요.
이 자습서에서는 다음 방법에 대해 알아봅니다.
- 큐비트를 측정하고 원하는 상태로 초기화하는 Q# 연산을 만듭니다.
- 큐비트를 만들고 프로그램을 테스트합니다.
- 큐비트를 중첩에 넣습니다.
- 큐비트 쌍을 얽습니다.
작업 영역에 새 Notebook 만들기
- Azure Portal에 로그인하고 이전 단계에서 만든 작업 영역을 선택합니다.
- 왼쪽 블레이드에서 Notebooks를 선택합니다.
- 내 Notebooks를 클릭하고 새로 추가를 클릭합니다.
- 커널 형식에서 IQ#를 선택합니다.
- 파일 이름(예: Entanglement.ipynb)을 입력하고 파일 만들기를 클릭합니다.
새 Notebook이 열리면 구독 및 작업 영역 정보를 기반으로 첫 번째 셀에 대한 코드가 자동으로 만들어집니다.
%azure.connect "/subscriptions/\<subscription ID>/\<resource group>/providers/Microsoft.Quantum/Workspaces/\<workspace>" \<location>
참고
%azure.connect는 Jupyter Notebook에서 작업을 간소화하는 데 도움이 되는 명령 집합인 IQ# Magic 명령입니다.
이 셀을 실행하는 경우 구독에 대해 인증하고 사용 가능한 공급자 및 대상 목록을 표시해야 합니다.
측정을 사용하여 큐비트 초기화
첫 번째 단계는 큐비트를 알려진 상태로 초기화하는 Q# 연산을 정의하는 것입니다. 큐비트를 클래식 상태로 설정하려면 이를 호출합니다. 즉, 시간의 Zero
100%를 반환하거나 시간의 One
100%를 반환합니다. Zero
및 One
은 큐비트 측정에서 가능한 두 가지 결과를 나타내는 Q# 값입니다.
+ 코드를 클릭하여 새 셀을 추가하고 다음 코드를 추가합니다.
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
참고
이 코드의 연산에서 사용되는 Microsoft.Quantum.Intrinsic
및 Microsoft.Quantum.Canon
네임스페이스는 Azure Quantum Notebook의 모든 셀에서 자동으로 열립니다.
이 코드 예제는 큐비트 상태를 변환하는 두 가지 연산인 M
및 X
를 소개합니다.
SetQubitState
연산:
- 두 개의 매개 변수를 사용합니다. 하나는 필요한 상태가 큐비트(0 또는 1)임을 나타내는
desired
라는Result
형식이고 다른 하나는Qubit
형식입니다. - 큐비트(
Zero
또는One
)의 상태를 측정하고 결과를desired
에 지정된 값과 비교하는 측정 연산M
을 수행합니다. - 측정값이 비교된 값과 일치하지 않는 경우
X
연산을 실행합니다. 이 연산은 측정이Zero
및One
을 반환할 확률이 역전되도록 큐비트의 상태를 플리핑합니다. 이러한 방식으로SetQubitState
는 항상 대상 큐비트를 원하는 상태로 설정합니다.
측정 테스트
이제 SetQubitState
연산의 효과를 보여 주기 위해 이름이 TestBellState
인 다른 연산을 만듭니다.
새 셀을 또 하나 추가하고 다음 코드를 추가합니다.
operation TestBellState(count : Int, initial : Result) : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
// 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':
if resultQ1 == One {
set numOnesQ1 += 1;
}
if resultQ2 == One {
set numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Return number of |0> states, number of |1> states
Message("q1:Zero, One q2:Zero, One");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
TestBellState
연산:
- 두 매개 변수를 사용합니다. 하나는 측정을 실행할 횟수인
count
이고 다른 하나는 큐비트를 초기화할 필요한 상태인initial
입니다. use
문을 호출하여 두 큐비트를 초기화합니다.count
반복을 반복합니다. 각 루프에 대해SetQubitState
를 호출하여 첫 번째 큐비트에 지정된initial
값을 설정합니다.SetQubitState
를 다시 호출하여 두 번째 큐비트를Zero
상태로 설정합니다.M
연산을 사용하여 각 큐비트를 측정합니다.One
을 반환하는 각 큐비트의 측정 수를 저장합니다.
- 루프가 완료되면
SetQubitState
를 다시 호출하여 큐비를 알려진 상태(Zero
)로 다시 설정합니다. 그러면 다른 사용자가 큐비트를 알려진 상태에서 할당할 수 있습니다. 이는use
문에 필요합니다. - 마지막으로, 결과를 반환하기 전에
Message
함수를 사용하여 콘솔에 메시지를 표시합니다.
코드 테스트
중첩 및 얽힘 프로시저로 이동하기 전에 이 지점까지 코드를 테스트하여 큐비트의 초기화 및 측정을 확인합니다.
TestBellState
연산을 실행하려면 %simulate
매직 명령을 사용하여 Azure Quantum 전체 상태 시뮬레이터를 호출합니다. count
및 initial
인수를 지정해야 향 합니다(예: count=1000
및 initial=1
). 그러면 첫 번째 큐비트를 One
로 초기화하고 각 큐비트를 1,000번 측정합니다. 다음 명령을 사용하여 새 셀을 추가하고 모두 실행을 클릭합니다.
%simulate TestBellState count=1000 initial=1
그러면 다음과 같이 출력됩니다.
q1:Zero, One q2:Zero, One
(0, 1000, 1000, 0)
큐비트는 아직 조작되지 않았기 때문에 초기 값을 유지했습니다. 첫 번째 큐비트는 매번 One
을 반환하고 두 번째 큐비트는 Zero
을 반환합니다.
셀을 initial=0
으로 다시 실행하면 첫 번째 큐비트도 매번 Zero
를 반환하는 것을 알 수 있습니다.
%simulate TestBellState count=1000 initial=0
q1:Zero, One q2:Zero, One
(1000, 0, 1000, 0)
큐비트를 중첩에 넣기
현재 프로그램의 큐비트는 모두 클래식 상태입니다. 즉, 1 또는 0입니다. 프로그램에서 큐비트를 알려진 상태로 초기화하고 조작할 프로세스를 추가하지 않았기 때문에 이를 알 수 있습니다. 큐비트를 얽기 전에 첫 번째 큐비트를 중첩 상태로 전환합니다. 이 상태에서는 큐비트의 측정이 50%의 시간에서 Zero
를 반환하고 50%의 시간에서 One
을 반환합니다. 개념적으로 큐비트는 Zero
와 One
사이에서 모든 상태의 선형 조합으로 간주될 수 있습니다.
큐비트를 중첩에 배치하기 위해 Q#에서는 H
또는 Hadamard 연산을 제공합니다. 큐비트를 0에서 1로(또는 그 반대로) 플립한 이전의 측정값을 사용한 큐비트 초기화 프로시저에서의 X
연산을 다시 떠올려 보겠습니다. H
연산은 0 또는 1의 동일한 확률 상태로 큐비트를 중간으로 대칭 이동합니다. 측정할 때 중첩의 큐비트는 대략 동일한 수의 Zero
및 One
결과를 반환해야 합니다.
TestBellState
를 사용한 이전 셀에서 for
루프 내부에 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);
%simulate
명령에서 큐비트를 다시 1로 초기화하고 모두 실행을 클릭하면 중첩 상태의 첫 번째 큐비트의 결과를 볼 수 있습니다.
%simulate TestBellState count=1000 initial=1
q1:Zero, One q2:Zero, One
(523, 477, 1000, 0) // results will vary
프로그램을 실행할 때마다 첫 번째 큐비트의 결과는 약간씩 달라지지만 50% One
과 50% Zero
에 가깝고 두 번째 큐비트의 결과는 항상 Zero
를 유지합니다.
Q1:Zero/One Q2:Zero/One
(510, 490, 1000, 0)
첫 번째 큐비트를 Zero
로 초기화하면 유사한 결과를 반환합니다.
%simulate TestBellState count=1000 initial=0
Q1:Zero/One Q2:Zero/One
(504, 496, 1000, 0)
두 큐비트 얽기
앞에서 설명한 것처럼 얽힌 큐비트는 서로 독립적으로 설명할 수 없도록 연결됩니다. 즉, 얽힌 쌍의 한 큐비트에 어떤 연산이 발생하든 다른 큐비트에도 발생합니다. 이렇게 하면 다른 큐비트의 상태를 측정하여 측정하지 않고 한 큐비트의 결과 상태를 알 수 있습니다. 이 예제에서는 두 큐비트를 사용하지만 셋 이상의 큐비트를 얽을 수도 있습니다.
얽힘을 사용하도록 설정하기 위해 Q#에서는 CNOT
Controled-NOT을 나타내는 연산을 제공합니다. 두 큐비트에 대해 이 연산을 실행하면 그 결과로 첫 번째 큐비트가 One
인 경우 두 번째 큐비트가 대칭 이동됩니다.
H
연산 직후의 for
루프에 CNOT
연산을 추가합니다. 이제 TestBellState
연산이 다음과 같이 표시됩니다.
operation TestBellState(count : Int, initial : Result) : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
// allocate the qubits
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
H(q1);
CNOT(q1, q2); // added CNOT operation
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
// Count the number of 'Ones':
if resultQ1 == One {
set numOnesQ1 += 1;
}
if resultQ2 == One {
set numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Return number of |0> states, number of |1> states
Message("q1:Zero, One q2:Zero, One");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
모두 실행을 클릭하여 업데이트된 연산을 실행하면 다음이 출력됩니다.
Q1:Zero/One Q2:Zero/One
(502, 498, 502, 498) // actual results will vary
첫 번째 큐비트에 대한 통계는 변경되지 않았지만(측정 후 Zero
또는 One
의 50/50 확률) 두 번째 큐비트의 측정 결과는 큐비트가 무엇으로 초기화되든 항상 첫 번째 큐비트의 측정값과 동일합니다. CNOT
연산은 두 큐비트를 얽어서 두 큐비트 중 한 큐비트에서 발생하는 모든 것이 다른 큐비트에서 발생하도록 했습니다.
필수 조건
- 기본 설정 언어와 개발 환경을 사용하여 QDK(Quantum 개발 키트)를 설치합니다.
- QDK가 이미 설치되어 있는 경우 최신 버전으로 업데이트해야 합니다.
- Q# 애플리케이션 또는 C# 호스트 프로그램에 대해 이름이 Bell인 Q# 프로젝트를 만듭니다. 또는 Juptyer Notebook 또는 Python 호스트 프로그램에서 직접 Q# 코드를 실행할 수 있습니다.
이 자습서에서는 다음 방법에 대해 알아봅니다.
- 큐비트를 측정하고 원하는 상태로 초기화하는 Q# 연산을 만듭니다.
- 큐비트를 만들고 프로그램을 테스트합니다.
- 큐비트를 중첩에 넣습니다.
- 큐비트 쌍을 얽습니다.
측정을 사용하여 큐비트 초기화
첫 번째 단계는 큐비트를 알려진 상태로 초기화하는 Q# 연산을 정의하는 것입니다. 이를 호출하여 큐비트를 클래식 상태로 설정할 수 있습니다. 즉, 시간의 Zero
100%를 반환하거나 시간의 One
100%를 반환합니다. Zero
및 One
은 큐비트 측정에서 가능한 두 가지 결과를 나타내는 Q# 값입니다.
프로젝트에서 Program.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
연산:
- 두 개의 매개 변수를 사용합니다. 하나는 필요한 상태가 큐비트(0 또는 1)임을 나타내는
desired
라는Result
형식이고 다른 하나는Qubit
형식입니다. - 큐비트(
Zero
또는One
)의 상태를 측정하고 결과를desired
에 지정된 값과 비교하는 측정 연산M
을 수행합니다. - 측정값이 비교된 값과 일치하지 않는 경우
X
연산을 실행합니다. 이 연산은 측정이Zero
및One
을 반환할 확률이 역전되도록 큐비트의 상태를 플리핑합니다. 이러한 방식으로SetQubitState
는 항상 대상 큐비트를 원하는 상태로 설정합니다.
측정 테스트
이제 SetQubitState
연산의 효과를 보여 주기 위해 이름이 TestBellState
인 다른 연산을 만듭니다.
Program.qs
파일에서 SetQubitState
연산 이후에 다음 연산을 추가합니다.
operation TestBellState(count : Int, initial : Result) : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
// 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' we saw:
if resultQ1 == One {
set numOnesQ1 += 1;
}
if resultQ2 == One {
set numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Return times we saw |0>, times we saw |1>
Message("q1:Zero, One q2:Zero, One");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
TestBellState
연산:
- 두 매개 변수를 사용합니다. 하나는 측정을 실행할 횟수인
count
이고 다른 하나는 큐비트를 초기화할 필요한 상태인initial
입니다. use
문을 호출하여 두 큐비트를 초기화합니다.count
반복을 반복합니다. 각 루프에 대해SetQubitState
를 호출하여 첫 번째 큐비트에 지정된initial
값을 설정합니다.SetQubitState
를 다시 호출하여 두 번째 큐비트를Zero
상태로 설정합니다.M
연산을 사용하여 각 큐비트를 측정합니다.One
을 반환하는 각 큐비트의 측정 수를 저장합니다.
- 루프가 완료되면
SetQubitState
를 다시 호출하여 큐비를 알려진 상태(Zero
)로 다시 설정합니다. 그러면 다른 사용자가 큐비트를 알려진 상태에서 할당할 수 있습니다. 이는use
문에 필요합니다. - 마지막으로, 결과를 반환하기 전에
Message
함수를 사용하여 콘솔에 메시지를 출력합니다.
명령 프롬프트에서 코드를 실행합니다.
중첩 및 얽힘 프로시저로 이동하기 전에 이 시점까지 코드를 테스트하여 큐비트의 초기화 및 측정을 확인합니다.
코드를 독립 실행형 프로그램으로 실행하려면 Q# 컴파일러가 dotnet run
명령을 실행할 때 프로그램을 시작할 위치를 알아야 합니다. 이를 위해 Q# 파일에서 실행하려는 연산의 바로 앞에 @EntryPoint()
를 추가합니다. 이 경우에는 TestBellState
연산입니다.
참고
@EntryPoint()
는 독립 실행형 Q# 프로그램에만 필요합니다. Jupyter Notebook에서 Q# 프로그램을 실행하거나 Python 또는 .NET 호스트 파일에서 Q# 프로그램을 호출하는 경우에는 필요하지 않으며, 포함되면 오류가 발생합니다.
이제 program.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(count : Int, initial : Result) : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
// 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' we saw:
if resultQ1 == One {
set numOnesQ1 += 1;
}
if resultQ2 == One {
set numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Return times we saw |0>, times we saw |1>
Message("q1:Zero, One q2:Zero, One");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
}
프로그램을 실행하려면 명령 프롬프트에서 count
및 initial
인수를 지정해야 합니다. 예를 들어 --count 1000
및 --initial One
은 첫 번째 큐비트를 One
으로 초기화하고 각 큐비트를 1000번 측정합니다. 다음 명령을 실행합니다.
dotnet run --count 1000 --initial One
그러면 다음과 같이 출력됩니다.
Q1:Zero/One Q2:Zero/One
(0, 1000, 1000, 0)
큐비트는 아직 조작되지 않았기 때문에 초기 값을 유지했습니다. 첫 번째 큐비트는 매번 One
을 반환하고 두 번째 큐비트는 Zero
를 반환합니다.
셀을 --initial Zero
로 다시 실행하면 첫 번째 큐비트도 매번 Zero
를 반환하는 것을 알 수 있습니다.
dotnet run --count 1000 --initial Zero
Q1:Zero/One Q2:Zero/One
(1000, 0, 1000, 0)
큐비트를 중첩에 넣기
현재 프로그램의 큐비트는 모두 클래식 상태입니다. 즉, 1 또는 0입니다. 프로그램에서 큐비트를 알려진 상태로 초기화하고 조작할 프로세스를 추가하지 않았기 때문에 이를 알 수 있습니다. 큐비트를 얽기 전에 첫 번째 큐비트를 중첩 상태로 전환합니다. 여기서 큐비트의 측정값은 Zero
(시간의 50%) 및 One
(시간의 50%)을 반환합니다. 개념적으로 큐비트는 Zero
와 One
의 중간으로 생각할 수 있습니다.
큐비트를 중첩에 배치하기 위해 Q#에서는 H
또는 Hadamard 연산을 제공합니다. 큐비트를 0에서 1로(또는 그 반대로) 플립한 이전의 측정값을 사용한 큐비트 초기화 프로시저에서의 X
연산을 다시 떠올려 보겠습니다. H
연산은 0 또는 1의 동일한 확률 상태로 큐비트를 중간으로 대칭 이동합니다. 측정할 때 중첩의 큐비트는 대략 동일한 수의 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);
이제 프로그램을 실행할 때 중첩에서 첫 번째 큐비트의 결과를 볼 수 있습니다.
dotnet run --count 1000 --initial One
Q1:Zero/One Q2:Zero/One
(523, 477, 1000, 0) // results will vary
프로그램을 실행할 때마다 첫 번째 큐비트의 결과는 약간 다르지만 50% One
및 50% Zero
에 가까우며 두 번째 큐비트의 결과는 항상 Zero
로 유지됩니다.
dotnet run --count 1000 --initial One
Q1:Zero/One Q2:Zero/One
(510, 490, 1000, 0)
첫 번째 큐비트를 Zero
로 초기화하면 유사한 결과를 반환합니다.
dotnet run --count 1000 --initial Zero
Q1:Zero/One Q2:Zero/One
(504, 496, 1000, 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(count : Int, initial : Result) : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
// 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' we saw:
if resultQ1 == One {
set numOnesQ1 += 1;
}
if resultQ2 == One {
set numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Return times we saw |0>, times we saw |1>
Message("q1:Zero, One q2:Zero, One");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
}
이제 프로그램을 실행합니다.
dotnet run --count 1000 --initial One
Q1:Zero/One Q2:Zero/One
(502, 498, 502, 498)
첫 번째 큐비트에 대한 통계는 변경되지 않았지만(측정 후 Zero
또는 One
의 확률 50/50) 두 번째 큐비트의 측정 결과는 항상 첫 번째 큐비트의 측정과 동일합니다. CNOT
연산은 두 큐비트를 얽어서 둘 중 하나에서 발생하는 모든 것이 다른 큐비트에서도 발생하도록 했습니다.
다음 단계
다른 양자 알고리즘 및 기술을 계속 탐색합니다.
- Grover의 검색 알고리즘 구현 자습서에서는 Grover의 검색 알고리즘을 사용하여 그래프 색 지정 문제를 해결하는 Q# 프로그램을 작성하는 방법을 보여 줍니다.
- Q#으로 큐비트 수준 프로그램 작성 및 시뮬레이션에서는 직접 특정 큐비트의 주소를 지정하는 Q# 프로그램 작성 방법을 살펴봅니다.
- Quantum Kata는 양자 컴퓨팅과 Q# 프로그래밍의 요소를 동시에 가르치기 위한 Jupyter Notebook 기반의 자기 주도적 자습서 및 프로그래밍 연습입니다.