이 자습서에서는 큐비트를 조작하고 측정하며 중첩 및 얽힘의 효과를 보여 주는 프로그램을 작성 Q# 합니다. 특정 양자 상태에서 두 개의 큐비트를 준비하고, 큐비트 Q# 에서 작동하여 상태를 변경하는 방법을 알아보고, 중첩 및 얽힘의 효과를 보여 줍니다. 큐비트 상태, 연산 및 측정값을 소개하기 위해 프로그램을 단계별로 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
합니다. 큐비트를 측정하면 Q# 형식 Result
이 반환되며, 이 값은 Zero
또는 One
중 하나만 가질 수 있습니다.
Azure Quantum용 Copilot를 열고 다음 코드를 코드 편집기 창에 복사합니다. 아직 실행을 선택하지 마세요. 왜냐하면 자습서의 뒷부분에서 코드를 실행합니다.
import Microsoft.Quantum.Intrinsic.*;
import Microsoft.Quantum.Canon.*;
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
이 코드 예제는 큐비트 상태를 변환하는 두 가지 연산인 M
및 X
를 소개합니다.
SetQubitState
연산:
- 두 개의 매개변수를 사용합니다. 여기에는 큐비트의 원하는 상태(
Zero
또는One
)를 나타내는desired
라는 이름의 형식Result
과 형식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 {
numOnesQ1 += 1;
}
if resultQ2 == One {
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
변수가 각각 1000
와 One
로 설정됩니다. 그러면 첫 번째 큐비트를 One
로 초기화하고 각 큐비트를 1,000번 측정합니다.
Main
연산:
- 카운터 및 초기 큐비트 상태에 대한 변수를 설정합니다.
-
use
문을 호출하여 두 큐비트를 초기화합니다. -
count
번 반복합니다. 각 루프에 대해-
SetQubitState
를 호출하여 첫 번째 큐비트에 지정된initial
값을 설정합니다. -
SetQubitState
를 다시 호출하여 두 번째 큐비트를Zero
상태로 설정합니다. -
M
연산을 사용하여 각 큐비트를 측정합니다. -
One
을 반환하는 각 큐비트의 측정 수를 저장합니다.
-
- 루프가 완료되면
SetQubitState
를 다시 호출하여 큐비를 알려진 상태(Zero
)로 다시 설정합니다. 그러면 다른 사용자가 큐비트를 알려진 상태에서 할당할 수 있습니다.use
문에 의해 재설정이 필요합니다. - 마지막으로, 결과를 반환하기 전에 이 함수를 사용하여
Message
결과를 코필로트 출력 창에 출력합니다.
Azure Quantum에 대한 Copilot에서 코드 실행
중첩 및 얽힘 프로시저로 이동하기 전에 이 시점까지 코드를 테스트하여 큐비트의 초기화 및 측정을 확인할 수 있습니다.
코드를 독립 실행형 프로그램으로 실행하려면 Copilot의 Q# 컴파일러가 프로그램을 시작할 위치를 알고 있어야 합니다. 네임스페이스를 지정하지 않으므로 컴파일러는 기본 진입점을 작업으로 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 {
numOnesQ1 += 1;
}
if resultQ2 == One {
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 );
}
전체 코드 샘플을 복사하여 Azure Quantum 코드 창의
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입니다. 프로그램에서 큐비트를 알려진 상태로 초기화하고 조작할 프로세스를 추가하지 않았기 때문에 이를 알 수 있습니다. 큐비트를 얽기 전에 첫 번째 큐비트를 중첩 상태로 전환합니다. 여기서 큐비트의 측정값은 시간의 ~50%와 Zero
시간의 ~50%를 반환 One
합니다. 개념적으로 큐비트는 측정 Zero
확률이 같거나 One
같은 것으로 간주할 수 있습니다.
큐비트를 중첩에 배치하기 위해 Q#에서는 H
또는 Hadamard 연산을 제공합니다.
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
프로그램을 실행할 때마다 첫 번째 큐비트의 결과는 약간 다르지만, 대체로% One
50과% Zero
50에 가깝습니다. 반면 두 번째 큐비트의 결과는 항상 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
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 {
numOnesQ1 += 1;
}
if resultQ2 == One {
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 확장설정을 참조하세요.
새 Q# 파일 만들기
- Visual Studio Code를 열고 파일>새 텍스트 파일을 선택하여 새 파일을 만듭니다.
- 파일을
CreateBellStates.qs
로 저장합니다. 이 파일에는 프로그램에 대한 코드가 Q# 포함됩니다.
알려진 상태로 큐비트 초기화
첫 번째 단계는 큐비트를 알려진 상태로 초기화하는 Q# 연산을 정의하는 것입니다. 이 작업을 호출하여 큐비트를 클래식 상태로 설정할 수 있습니다. 즉, 100%의 시간을 반환 Zero
하거나 시간의 100%를 반환 One
합니다.
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
라는 형식과Qubit
라는 형식인데, 여기서desired
는 큐비트의 원하는 상태 (Zero
또는One
)를 나타냅니다. - 큐비트(
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 {
numOnesQ1 += 1;
}
if resultQ2 == One {
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
변수가 각각 1000
와 One
로 설정됩니다. 이 단계에서는 첫 번째 큐비트를 초기화하고 각 큐비 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 { numOnesQ1 += 1; } if resultQ2 == One { 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#: Azure Quantum QIR 타겟 프로필 설정을 선택하고, Q#: unrestricted를 선택합니다.
참고
대상 프로필이 무제한으로 설정되지 않은 경우 프로그램을 실행할 때 오류가 발생합니다.
프로그램을 실행하려면 오른쪽 위에 있는 재생 아이콘 드롭다운에서 파일 실행을 선택하거나, 작업 전에 명령 목록에서 실행을 선택하거나, 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 또는 Edit > Undo를 선택하고 파일을 저장하세요.
큐비트를 중첩에 넣기
현재 프로그램의 큐비트는 모두 클래식 상태입니다. 즉, 1 또는 0입니다. 프로그램에서 큐비트를 알려진 상태로 초기화하고 조작할 프로세스를 추가하지 않았기 때문에 이를 알 수 있습니다. 큐비트를 얽기 전에 첫 번째 큐비트를 중첩 상태로 전환합니다. 여기서 큐비트의 측정값은 시간의 50%와 Zero
시간의 50%를 반환 One
합니다. 개념적으로 큐비트는 Zero
와 One
의 중간으로 생각할 수 있습니다.
큐비트를 중첩에 배치하기 위해 Q#에서는 H
또는 Hadamard 연산을 제공합니다.
X
연산을 이전의 큐비트를 알려진 상태로 초기화 절차에서 기억하시나요? 이 연산은 큐비트를 Zero
에서 One
로 (또는 그 반대로) 뒤집습니다. 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%
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
연산을 제공하는데, 이는 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 { numOnesQ1 += 1; } if resultQ2 == One { 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를 누른 후, "histogram"을 입력하여 파일을 실행하고 히스토그램을 표시Q# 옵션을 찾습니다. 앞의 명령 목록에서 히스토그램을 선택할 수도 있습니다
Main
. 이 옵션을 선택하여 Q# 히스토그램 창을 여십시오.프로그램을 실행할 샷 수를 입력하고, 예를 들어 100번 샷 후에, Enter 키를 누릅니다. 히스토그램이 Q# 히스토그램 창에 표시됩니다.
히스토그램의 각 막대는 가능한 결과에 해당하며, 높이가 결과가 관찰되는 횟수를 나타냅니다. 이 경우 50개의 고유한 결과가 있습니다. 각 결과에 대해 첫 번째 큐비트와 두 번째 큐비트의 측정 결과는 항상 동일합니다.
팁
마우스 스크롤 휠 또는 트랙 패드 제스처를 사용하여 히스토그램을 확대/축소할 수 있습니다. 확대하면 스크롤하는 동안 Alt 키를 눌러 차트를 이동하면 됩니다.
막대를 선택하여 해당 결과의 백분율을 표시합니다.
왼쪽 위 설정 아이콘 을 선택하여 옵션을 표시합니다. 상위 10개 결과, 상위 25개 결과 또는 모든 결과를 표시할 수 있습니다. 결과를 높음에서 낮음 또는 낮음에서 높음으로 정렬할 수도 있습니다.
관련 콘텐츠
다른 Q# 자습서 살펴보기:
- Grover의 검색 알고리즘 은 Grover의 검색 알고리즘을 Q# 사용하는 프로그램을 작성하는 방법을 보여줍니다.
- Quantum Fourier Transform 은 특정 큐비트를 Q# 직접 해결하는 프로그램을 작성하는 방법을 살펴봅니다.
- Quantum Katas는 양자 컴퓨팅 및 프로그래밍 요소를 동시에 교육하기 위한 자가 진행 자습서 및 Q# 프로그래밍 연습입니다.