주 콘텐츠로 건너뛰기

Qiskit 구현

이전 레슨에서는 Qiskit의 StatevectorOperator 클래스를 처음으로 살펴보았고, 이를 사용하여 단일 Qubit에 대한 연산과 측정을 시뮬레이션했습니다. 이 섹션에서는 이 클래스들을 사용하여 여러 Qubit의 동작을 탐구하겠습니다.

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
from qiskit import __version__

print(__version__)
2.1.1

먼저 StatevectorOperator 클래스와 NumPy의 제곱근 함수를 가져오는 것으로 시작하겠습니다. 앞으로는 일반적으로 각 레슨 내에서 필요한 모든 import를 먼저 처리하도록 하겠습니다.

from qiskit.quantum_info import Statevector, Operator
from numpy import sqrt

텐서곱

Statevector 클래스에는 tensor 메서드가 있으며, 이는 인자로 주어진 다른 Statevector와의 텐서곱을 반환합니다. 인자는 오른쪽의 텐서 인수로 해석됩니다.

예를 들어, 아래에서는 0\vert 0\rangle1\vert 1\rangle을 나타내는 두 개의 상태 벡터를 생성하고, tensor 메서드를 사용하여 새로운 벡터 ψ=01\vert \psi\rangle = \vert 0\rangle \otimes \vert 1\rangle을 만듭니다. 여기서는 0\vert 0\rangle1\vert 1\rangle 상태를 직접 정의하는 대신 from_label 메서드를 사용하여 정의하고 있다는 점에 유의해 주세요.

zero = Statevector.from_label("0")
one = Statevector.from_label("1")
psi = zero.tensor(one)
display(psi.draw("latex"))

01 |01\rangle

허용되는 다른 레이블에는 플러스 및 마이너스 상태를 위한 "+"와 "-"가 있으며, 다음 상태들을 위한 "r"과 "l"("right" 및 "left"의 약어)이 있습니다.

+i=120+i21andi=120i21.\vert {+i} \rangle = \frac{1}{\sqrt{2}} \vert 0 \rangle + \frac{i}{\sqrt{2}} \vert 1 \rangle \qquad\text{and}\qquad \vert {-i} \rangle = \frac{1}{\sqrt{2}} \vert 0 \rangle - \frac{i}{\sqrt{2}} \vert 1 \rangle.

여기서 "+", "-" 또는 "right"와 "left"는 양자역학적 스핀의 맥락에서 유래한 것으로, 실험에서 스핀의 성분이 왼쪽이나 오른쪽을 가리킬 수 있음을 의미합니다. 이는 다중 Qubit 시스템에서 가장 오른쪽이나 가장 왼쪽 Qubit을 가리키는 것이 아닙니다. 다음은 +\vert {+} \ranglei\vert {-i} \rangle의 텐서곱의 예입니다.

plus = Statevector.from_label("+")
minus_i = Statevector.from_label("l")
phi = plus.tensor(minus_i)
display(phi.draw("latex"))

1200i201+1210i211\frac{1}{2} |00\rangle- \frac{i}{2} |01\rangle+\frac{1}{2} |10\rangle- \frac{i}{2} |11\rangle

다른 방법은 텐서곱을 위한 ^ 연산을 사용하는 것이며, 당연히 동일한 결과를 제공합니다.

display((plus ^ minus_i).draw("latex"))

1200i201+1210i211\frac{1}{2} |00\rangle- \frac{i}{2} |01\rangle+\frac{1}{2} |10\rangle- \frac{i}{2} |11\rangle

Operator 클래스에도 tensor 메서드(그리고 from_label 메서드)가 있으며, 다음 예제들에서 확인할 수 있습니다.

H = Operator.from_label("H")
Id = Operator.from_label("I")
X = Operator.from_label("X")
display(H.tensor(Id).draw("latex"))
display(H.tensor(Id).tensor(X).draw("latex"))
[220220022022220220022022] \begin{bmatrix} \frac{\sqrt{2}}{2} & 0 & \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & \frac{\sqrt{2}}{2} \\ \frac{\sqrt{2}}{2} & 0 & - \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & - \frac{\sqrt{2}}{2} \\ \end{bmatrix} [02200022002200022000000220002200220002200220002200220002200000022000220022000220] \begin{bmatrix} 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 \\ \end{bmatrix}

다시, 벡터의 경우와 마찬가지로 ^ 연산은 동등합니다.

display((H ^ Id ^ X).draw("latex"))
[02200022002200022000000220002200220002200220002200220002200000022000220022000220] \begin{bmatrix} 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 \\ \end{bmatrix}

복합 상태는 이전 레슨에서 단일 시스템에 대해 살펴본 것과 마찬가지로, 예상대로 복합 연산을 사용하여 시간 발전시킬 수 있습니다. 예를 들어, 다음 코드는 ϕ=+i\vert\phi\rangle = \vert + \rangle \otimes \vert {-i}\rangle(위에서 이미 정의됨)에 대한 상태 (HI)ϕ(H\otimes I)\vert\phi\rangle를 계산합니다.

display(phi.evolve(H ^ Id).draw("latex"))

22002i201\frac{\sqrt{2}}{2} |00\rangle- \frac{\sqrt{2} i}{2} |01\rangle

다음은 CXCX 연산을 정의하고 ψ=+0\vert\psi\rangle = \vert + \rangle \otimes \vert 0 \rangle에 대해 CXψCX \vert\psi\rangle를 계산하는 코드입니다. 명확히 말씀드리면, 이것은 왼쪽 Qubit이 제어이고 오른쪽 Qubit이 대상인 CXCX 연산입니다. 결과는 Bell 상태 ϕ+\vert\phi^{+}\rangle입니다.

CX = Operator([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])
psi = plus.tensor(zero)
display(psi.evolve(CX).draw("latex"))

2200+2211\frac{\sqrt{2}}{2} |00\rangle+\frac{\sqrt{2}}{2} |11\rangle

부분 측정

이전 레슨에서는 measure 메서드를 사용하여 양자 상태 벡터의 측정을 시뮬레이션했습니다. 이 메서드는 시뮬레이션된 측정 결과와 이 측정 이후의 새로운 Statevector라는 두 가지 항목을 반환합니다.

기본적으로 measure는 상태 벡터의 모든 Qubit을 측정합니다. 대안으로, 정수 리스트를 인자로 제공하여 해당 Qubit 인덱스만 측정되도록 할 수 있습니다. 이를 보여드리기 위해, 아래 코드는 다음 상태를 생성합니다.

w=001+010+1003\vert w\rangle = \frac{\vert 001\rangle + \vert 010\rangle + \vert 100\rangle}{\sqrt{3}}

그리고 가장 오른쪽 Qubit인 0번 Qubit을 측정합니다. (Qiskit은 Qubit을 오른쪽에서 왼쪽으로, 0부터 시작하여 번호를 매깁니다. 이 번호 매기기 규약은 다음 레슨에서 다시 다루겠습니다.)

w = Statevector([0, 1, 1, 0, 1, 0, 0, 0] / sqrt(3))
display(w.draw("latex"))

result, state = w.measure([0])
print(f"Measured: {result}\nState after measurement:")
display(state.draw("latex"))

result, state = w.measure([0, 1])
print(f"Measured: {result}\nState after measurement:")
display(state.draw("latex"))

33001+33010+33100\frac{\sqrt{3}}{3} |001\rangle+\frac{\sqrt{3}}{3} |010\rangle+\frac{\sqrt{3}}{3} |100\rangle

Measured: 0
State after measurement:

22010+22100\frac{\sqrt{2}}{2} |010\rangle+\frac{\sqrt{2}}{2} |100\rangle

Measured: 00
State after measurement:

100 |100\rangle