연습 - Q#을 사용하여 다른 중첩 만들기
이전 단원에서는 중첩과 디랙 표기법에 대해 알아보았습니다. 지금 당장은 충분한 이론입니다! 몇 가지 코드를 작성하여 Q#에서 중첩을 살펴보겠습니다.
이 단원에서는 DumpMachine
함수를 사용하여 양자 중첩을 만들고 Q#로 확률을 심도 있게 탐구해 보겠습니다. DumpMachine
함수는 대상 머신이 호출되는 지점에서 양자 시스템의 현재 상태에 대한 정보를 덤프합니다.
새 Q# 파일 만들기
- Visual Studio Code를 엽니다.
- Visual Studio Code에서 파일 > 새 텍스트 파일을 선택하고 파일을 Main.qs라는 이름으로 저장합니다.
- 보기 -> 명령 팔레트를 선택하고 Q#을 입력합니다. Azure Quantum QIR 대상 프로필을 설정합니다. Enter 키를 누릅니다.
- Q#: 제한 없음을 선택합니다.
중첩 시작
중첩에서 큐비트를 사용하여 임의 비트를 생성하는 간단한 프로그램으로 시작해 보겠습니다. DumpMachine
함수를 사용하여 프로그램의 여러 지점에서 큐비트의 상태를 확인합니다.
Main.qs 파일에 다음 코드를 추가합니다.
import Microsoft.Quantum.Diagnostics.*; operation Main() : Result { use q = Qubit(); Message("Initialized qubit:"); DumpMachine(); // First dump Message(" "); H(q); Message("Qubit after applying H:"); DumpMachine(); // Second dump Message(" "); let randomBit = M(q); Message("Qubit after the measurement:"); DumpMachine(); // Third dump Message(" "); Reset(q); Message("Qubit after resetting:"); DumpMachine(); // Fourth dump Message(" "); return randomBit; }
여기서는
DumpMachine
을 네 번 호출합니다.- 큐비트가 할당된 후
- 큐비트를 중첩에 배치한 후.
- 큐비트의 상태를 측정한 후.
- 큐비트를 초기화한 후.
연산
MResetZ
를 두 개의 연산M
및Reset
으로 분할했습니다. 이는 측정 후 상태를 검사하기 위함입니다.기본 제공 시뮬레이터에서 프로그램을 실행하려면
Main
작업 위에 있는 실행을 클릭하거나 Ctrl+F5를 누릅니다. 디버그 콘솔에 출력이 표시됩니다.DumpMachine
함수는 큐비트 레지스터의 상태를 설명하는 정보 표를 작성합니다. 구체적으로 각 기저 상태의 확률 진폭, 확률 및 위상을 라디안으로 제공합니다.프로그램의 끝에 결과
Zero
또는One
이 표시됩니다. 각 단계를 살펴보겠습니다.초기화된 큐비트:
use
문을 통해 할당된 모든 큐비트는 $|0\rangle$ 상태로 시작합니다. 따라서DumpMachine
은 $|0\rangle$ 상태의 단일 큐비트 레지스터에 해당하는 정보를 생성합니다.Initialized qubit: DumpMachine: Basis | Amplitude | Probability | Phase ----------------------------------------------- |0⟩ | 1.0000+0.0000𝑖 | 100.0000% | 0.0000
H를 적용한 후 큐비트:
H
를 적용한 후 큐비트를 중첩 상태 $|\psi\rangle=\frac1{\sqrt2} |0\rangle + \frac1{\sqrt2} |1\rangle$로 준비합니다.Qubit after applying H: DumpMachine: Basis | Amplitude | Probability | Phase ----------------------------------------------- |0⟩ | 0.7071+0.0000𝑖 | 50.0000% | 0.0000 |1⟩ | 0.7071+0.0000𝑖 | 50.0000% | 0.0000
측정 후 큐비트: 결과를 측정하고 저장한 후(
Zero
또는One
일 수 있음). 예를 들어 결과 상태가One
인 경우 레지스터의 상태가 $|1\rangle$로 축소되고 더 이상 중첩되지 않습니다.Qubit after the measurement: DumpMachine: Basis | Amplitude | Probability | Phase ----------------------------------------------- |1⟩ | 1.0000+0.0000𝑖 | 100.0000% | 0.0000
재설정 후 큐비트:
Reset
연산은 큐비트를 $|0\rangle$ 상태로 다시 설정합니다. 모든 Q# 연산에서는 사용하는 큐비트를 항상 $|0\rangle$ 상태로 유지하여 다른 연산에서 사용할 수 있도록 해야 합니다.Qubit after resetting: DumpMachine: Basis | Amplitude | Probability | Phase ----------------------------------------------- |0⟩ | 1.0000+0.0000𝑖 | 100.0000% | 0.0000
참고 항목
난수 생성기는 확률적이므로 출력이 다를 수 있습니다. 결과의 확률은 결정적이지 않습니다.
다른 유형의 중첩 상태 살펴보기
레지스터의 상태를 검사하는 방법을 배웠으므로, 큐비트의 상태를 수정하고 중첩시키는 많은 연산을 살펴볼 수 있습니다.
현재 난수 생성기는 50% 확률로 Zero
또는 One
을 생성합니다. 다른 확률을 사용하여 난수를 생성하는 두 번째 예제를 살펴보겠습니다.
기울어진 임의 비트 생성기
기울어진 임의 비트 생성기를 만들려는 경우, 즉 Zero
을(를) 얻을 확률이 One
을(를) 얻을 확률과 다르다고 가정합니다.
예를 들어 $P$ 확률의 Zero
결과와 $1-P$ 확률의 One
결과를 표시하려고 합니다. 이러한 임의 비트 생성기를 생성하는 유효한 큐비트 상태는 다음과 같습니다.
$$|\psi\rangle=\sqrt{P}|0\rangle+\sqrt{1-P}|1\rangle$$
여기서 $\alpha=\sqrt{P}$ 및 $\beta=\sqrt{1-P}$는 각각 기본 상태 $|0\rangle$ 및 $|1\rangle$의 진폭입니다.
이 상태는 $|0\rangle$ 상태의 큐비트에$R_y(2\arccos\sqrt{P})$ 연산자를 순차적으로 적용하여 얻을 수 있습니다. 이 결과는 Q#에서 표준 라이브러리의 Ry 연산을 사용하여 얻을 수 있습니다.
팁
단일 큐비트 연산 뒤의 수학을 자세히 알아보려면 Quantum Katas의 단일 큐비트 게이트 자습서를 확인하세요.
다음 예와 같이 Main.qs를 수정한 후 파일을 저장합니다. 이 예제에서는 $\alpha$를 대략 $\frac13$으로 선택합니다.
import Microsoft.Quantum.Diagnostics.*; import Microsoft.Quantum.Math.*; operation Main() : Result { use q = Qubit(); let P = 0.333333; // P is 1/3 Ry(2.0 * ArcCos(Sqrt(P)), q); Message("The qubit is in the desired state."); Message(""); DumpMachine(); // Dump the state of the qubit Message(""); Message("Your skewed random bit is:"); let skewedrandomBit = M(q); Reset(q); return skewedrandomBit; }
기본 제공 시뮬레이터에서 프로그램을 실행하려면
Main
작업 위에 있는 실행을 클릭하거나 Ctrl+F5를 누릅니다. 디버그 콘솔에 출력이 표시됩니다.DumpMachine
이 연산을 적용한 후 예상 상태를 표시하고 관련 확률을 표시하는 방식을 확인할 수 있습니다.Zero
을(를) 얻을 확률은 약 33.33%이고One
을(를) 얻을 확률은 약 66.67%입니다. 따라서 임의 비트 생성기가 기울어집니다.The qubit is in the desired state. DumpMachine: Basis | Amplitude | Probability | Phase ----------------------------------------------- |0⟩ | 0.5773+0.0000𝑖 | 33.3333% | 0.0000 |1⟩ | 0.8165+0.0000𝑖 | 66.6667% | 0.0000 Your skewed random bit is: Result: "One"
참고 항목
난수 생성기는 확률적이므로 출력이 다를 수 있습니다. 결과의 확률은 결정적이지 않습니다.
다중 큐비트 중첩
이제 여러 큐비트가 있는 레지스터의 중첩을 살펴보겠습니다. 예를 들어 레지스터에 3개의 큐비트가 있는 경우 기저 상태는 다음 8개입니다.
$$|000\rangle,|001\rangle,|010\rangle,|011\rangle,|100\rangle,|101\rangle, |110\rangle,|111\rangle $$
따라서 다음과 같은 임의의 세 가지 큐비트 상태를 표현할 수 있습니다.
$$|\psi\rangle=\alpha_0|000\rangle+\alpha_1|001\rangle+\alpha_2|010\rangle+\alpha_3|011\rangle+\alpha_4|100\rangle+\alpha_5|101\rangle+\alpha_6 |110\rangle+\alpha_7|111\rangle$$
여기서 $\alpha_i$는 $\sum|\alpha_i|^2=1$을 만족하는 복소수입니다.
예를 들어 각 큐비트에 H
을(를) 적용하여 균일한 중첩에 큐비트를 배치할 수 있습니다. 이 균일한 중첩을 사용하여 한 큐비트를 세 번 측정하는 대신 중첩에서 세 개의 큐비트를 측정하여 3비트 숫자를 생성하는 다른 버전의 양자 난수 생성기를 만들 수 있습니다.
기준 | 숫자 |
---|---|
$\ket{000}$ | 0 |
$\ket{001}$ | 1 |
$\ket{010}$ | 2 |
$\ket{011}$ | 3 |
$\ket{100}$ | 4 |
$\ket{101}$ | 5 |
$\ket{110}$ | 6 |
$\ket{111}$ | 7 |
다음 예와 같이 Main.qs를 수정한 후 파일을 저장합니다.
import Microsoft.Quantum.Diagnostics.*; import Microsoft.Quantum.Math.*; import Microsoft.Quantum.Convert.*; import Microsoft.Quantum.Arrays.*; operation Main() : Int { use qubits = Qubit[3]; ApplyToEach(H, qubits); Message("The qubit register in a uniform superposition: "); DumpMachine(); let result = ForEach(M, qubits); Message("Measuring the qubits collapses the superposition to a basis state."); DumpMachine(); ResetAll(qubits); return BoolArrayAsInt(ResultArrayAsBoolArray(result)); }
여기서는 다음 세 가지 개념을 볼 수 있습니다.
qubits
변수는 이제 길이가 3인Qubit
배열을 나타냅니다.ApplyToEach
및ForEach
연산은 여러 큐비트를 측정하고 작업하는 데 유용하며 코드를 적게 사용합니다. Q# 라이브러리는 양자 프로그램을 보다 효율적으로 작성할 수 있도록 하는 다양한 연산 및 함수를 제공합니다.Microsoft.Quantum.Convert
라이브러리의BoolArrayAsInt
및ResultArrayAsBoolArray
함수는ForEach(M, qubits)
에서 반환한 이진Result
배열을 정수로 변환합니다.
프로그램을 실행하려면
Main
작업 위에 있는 실행을 클릭하거나 Ctrl+F5를 누릅니다. 디버그 콘솔에 출력이 표시됩니다.세 큐비트를 측정하는 행위가 어떻게 레지스터의 상태를 8개의 가능한 기저 상태 중 하나로 축소하는지
DumpMachine
을 사용하여 확인할 수 있습니다. 예를 들어3
결과를 가져오는 경우 레지스터의 상태가 $|110\rangle$로 축소되었음을 의미합니다.The qubit register in a uniform superposition: DumpMachine: Basis | Amplitude | Probability | Phase ----------------------------------------------- |000⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000 |001⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000 |010⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000 |011⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000 |100⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000 |101⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000 |110⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000 |111⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000 Measuring the qubits collapses the superposition to a basis state. DumpMachine: Basis | Amplitude | Probability | Phase ----------------------------------------------- |110⟩ | 1.0000+0.0000𝑖 | 100.0000% | 0.0000 Result: "3"
참고 항목
난수 생성기는 확률적이므로 출력이 다를 수 있습니다. 결과의 확률은 결정적이지 않습니다.
ForEach(M, qubit)
연산은 각 큐비트를 차례로 측정하여 상태를 점차 축소합니다. 각 측정 후에 중간 상태를 덤프할 수도 있습니다. 그렇게 하려면 다음 예와 같이 Main.qs를 수정한 다음 파일을 저장합니다.import Microsoft.Quantum.Diagnostics.*; import Microsoft.Quantum.Measurement.*; import Microsoft.Quantum.Math.*; import Microsoft.Quantum.Convert.*; operation Main() : Int { use qubits = Qubit[3]; ApplyToEach(H, qubits); Message("The qubit register in a uniform superposition: "); DumpMachine(); mutable results = []; for q in qubits { Message(" "); set results += [M(q)]; DumpMachine(); } Message(" "); Message("Your random number is: "); ResetAll(qubits); return BoolArrayAsInt(ResultArrayAsBoolArray(results)); }
여기서는
for
루프를 사용하여 각 큐비트를 순차적으로 처리합니다. Q#에는 프로그램의 흐름을 제어하는 데 사용할 수 있는for
루프 및if
문과 같은 클래식 흐름 제어 기능이 있습니다.프로그램을 실행하려면
Main
작업 위의 명령 목록에서 실행을 클릭하거나 Ctrl+F5를 누릅니다.각 연속 측정이 양자 상태, 따라서 각 결과를 얻을 확률을 변화시키는 방식을 확인할 수 있습니다. 예를 들어 결과가 숫자 5이면 다음 출력이 표시됩니다. 각 단계를 간단히 살펴보겠습니다.
상태 준비: 레지스터의 각 큐비트에
H
를 적용하여 균일한 중첩을 얻습니다.The qubit register in a uniform superposition: DumpMachine: Basis | Amplitude | Probability | Phase ----------------------------------------------- |000⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000 |001⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000 |010⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000 |011⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000 |100⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000 |101⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000 |110⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000 |111⟩ | 0.3536+0.0000𝑖 | 12.5000% | 0.0000
첫 번째 측정: 첫 번째 측정의 결과는
One
이었습니다. 따라서 맨 오른쪽 큐비트가Zero
인 상태의 모든 진폭은 더 이상 존재하지 않습니다. 이 진폭은 $|0\rangle=|000\rangle, |2\rangle=|010\rangle, |4\rangle=|100\rangle$ 및 $|6\rangle= |110\rangle$입니다. 나머지 진폭은 정규화 조건을 충족하기 위해 증가합니다.DumpMachine: Basis | Amplitude | Probability | Phase ----------------------------------------------- |001⟩ | 0.5000+0.0000𝑖 | 25.0000% | 0.0000 |011⟩ | 0.5000+0.0000𝑖 | 25.0000% | 0.0000 |101⟩ | 0.5000+0.0000𝑖 | 25.0000% | 0.0000 |111⟩ | 0.5000+0.0000𝑖 | 25.0000% | 0.0000
두 번째 측정: 두 번째 측정의 결과는
Zero
였습니다. 따라서 맨 오른쪽에서 두 번째 큐비트가One
인 상태의 모든 진폭이 사라집니다. 진폭은 $|3\rangle=|011\rangle$ 및 $|7\rangle=|111\rangle$입니다. 나머지 진폭은 정규화 조건을 충족하기 위해 증가합니다.DumpMachine: Basis | Amplitude | Probability | Phase ----------------------------------------------- |001⟩ | 0.7071+0.0000𝑖 | 50.0000% | 0.0000 |101⟩ | 0.7071+0.0000𝑖 | 50.0000% | 0.0000
세 번째 측정: 세 번째 측정의 결과는
One
이었습니다. 따라서 맨 왼쪽 큐비트가Zero
인 상태의 모든 진폭이 사라집니다. 유일하게 호환되는 상태는 $|5\rangle=|101\rangle$입니다. 이 상태의 진폭 확률은 $1$입니다.DumpMachine: Basis | Amplitude | Probability | Phase ----------------------------------------------- |101⟩ | 1.0000+0.0000𝑖 | 100.0000% | 0.0000 Your random number is: Result: "5"
참고 항목
난수 생성기는 확률적이므로 출력이 다를 수 있습니다. 결과의 확률은 결정적이지 않습니다.