이번 포스팅에서는 양자 컴퓨팅에서 가장 기본적인 게이트 중 하나인 파울리 게이트 (Pauli Gates)에 대해 알아보겠습니다.
양자 컴퓨터란 무엇인가?
양자 컴퓨터는 "큐비트(Qubit)"라는 단위를 정보의 기본 단위로 사용합니다. 고전 컴퓨터의 비트(Bit)는 0 또는 1의 값을 가지지만, 큐비트는 "양자 중첩(Superposition)"을 통해 0과 1의 상태를 동시에 가질 수 있습니다. 이러한 특성으로 인해 양자 컴퓨팅은 복잡한 문제에 대해서 빠른 계산을 수행할 수 있습니다.
Qiskit 설치
양자 컴퓨팅에 대한 알고리즘을 개발하기 위해 다양한 프레임워크가 존재합니다. 그 중에서도 Qiskit은 IBM 에서 개발한 오픈소스 양자 컴퓨팅 프레임워크로, 양자 알고리즘을 설계하고, 시뮬레이션하며, 실제 양자 하드웨어에서 실행할 수 있도록 지원합니다. Python을 기반으로 하며, 양자 컴퓨팅의 학습, 연구, 실험에 널리 사용됩니다. Python을 기반으로 하기 때문에 Qiskit은 아래와 같이 간단하게 pip install을 통해 설치할 수 있습니다:
pip install qiskit
양자 컴퓨팅을 시뮬레이션하기 위해 Qiskit Aer도 아래와 같이 설치해 줍니다:
pip install qiskit-aer
출력한 결과들은 시각화하기 위한 도구로 pylatexenc도 설치해 줍니다:
pip install pylatexenc
자, 그럼 파울리 게이트에 대한 설명과 함께 예제를 실행해 보겠습니다:
파울리 게이트
양자 컴퓨터에서 큐비트의 상태를 조작하기 위해 양자 게이트를 사용합니다. 이 중 파울리 게이트는 가장 기본적인 단일 큐비트 게이트로, 큐비트의 상태를 반전하거나 회전하는 연산을 수행합니다. 파울리 게이트는 아래와 같이 Pauli-X, Pauli-Y, Pauli-Z 등 세 가지 종류로 나뉩니다:
Pauli-X 게이트 (양자 NOT 게이트)
Pauli-X 게이트 연산자는 아래와 같이 행렬로 표현이 가능합니다.
\begin{eqnarray} {\pmb X} = \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}\end{eqnarray}
그럼 일반적으로 $|0\rangle$과 $|1\rangle$ 상태가 아래와 같은 행렬로 표현이 가능하므로,
\begin{eqnarray} |0\rangle = \begin{pmatrix} 1 \\ 0 \end{pmatrix}, \ \ \ |1\rangle = \begin{pmatrix} 0 \\ 1 \end{pmatrix} \end{eqnarray}
X 연산자는 아래와 같은 결과를 줍니다:
$$ {\pmb X} | 0 \rangle = \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix} \begin{pmatrix} 1 \\ 0 \end{pmatrix} = \begin{pmatrix} 0 \\ 1 \end{pmatrix} = | 1\rangle.$$
혹은
$$ {\pmb X} | 1 \rangle = \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix} \begin{pmatrix} 0 \\ 1 \end{pmatrix} = \begin{pmatrix} 1 \\ 0 \end{pmatrix} = | 0 \rangle.$$
즉, X-게이트는 주어진 큐비트의 상태를 뒤집는 역할을 합니다.
이것을 Qiskit을 통해 구현해 보겠습니다.
from qiskit import QuantumCircuit
# 1. 양자 회로 생성
qc = QuantumCircuit(1) # 1개의 큐비트 생성
# 2. Pauli-X 게이트 적용
qc.x(0)
print(qc)
"QuantumCircuit" 함수는 큐비트를 생성하는 함수입니다. "QuantumCircuit(1)"은 1개의 큐비트를 생성하겠다는 것을 의미하며, 이는 $|0\rangle$ 상태를 만들어 줍니다. 생성된 큐비트는 0번, 1번, 2번 등의 번호를 갖습니다. 따라서, 우리는 0번이라는 번호를 갖는 큐비트 하나를 생성한 것입니다.
그럼 "qc.x(0)"라는 명령어를 통해 우리가 만들어낸 "qc"의 0번 큐비트에 X-게이트를 적용할 수 있습니다. 위의 코드를 조금 더 구체화 해보겠습니다.
from qiskit import QuantumCircuit, transpile
from qiskit_aer import AerSimulator
# 1. 양자 회로 생성
qc = QuantumCircuit(1) # 1개의 큐비트 생성
# 2. Pauli-X 게이트 적용
qc.x(0) # 첫 번째 큐비트를 |1⟩ 상태로 변환
# 3. 상태 벡터 저장
qc.save_statevector()
# 3. 시뮬레이터 초기화
simulator = AerSimulator()
# 4. 회로 컴파일 및 실행
compiled_circuit = transpile(qc, simulator)
result = simulator.run(compiled_circuit).result()
# 5. 상태 벡터 확인
statevector = result.get_statevector()
print("Statevector:", statevector)
이 코드는 "큐비트 1개 생성 -> X-게이트 적용 -> 이에 대한 상태 벡터 저장 -> 시뮬레이터 초기화 -> 컴파일 및 회로 실행 -> 상태 벡터 확인" 등의 과정을 거칩니다. 이 코드에 대한 결과값은 아래와 같이 주어집니다:
Statevector: Statevector([0.+0.j, 1.+0.j],
dims=(2,))
예상한 것처럼 $|0\rangle$의 상태가 X-게이트로 인해 $|1\rangle$ 상태로 변화한 것을 볼 수 있습니다.
그럼 이번에는 X 게이트를 두 번 적용해 보겠습니다.
from qiskit import QuantumCircuit, transpile
from qiskit_aer import AerSimulator
# 1. 양자 회로 생성
qc = QuantumCircuit(1) # 1개의 큐비트 생성
# 2. Pauli-X 게이트 2번 적용
qc.x(0) # 첫 번째 큐비트를 |1⟩ 상태로 변환
qc.x(0) # 변환된 큐비트에 X 연산자를 한 번 더 적용
# 3. 상태 벡터 저장
qc.save_statevector()
# 3. 시뮬레이터 초기화
simulator = AerSimulator()
# 4. 회로 컴파일 및 실행
compiled_circuit = transpile(qc, simulator)
result = simulator.run(compiled_circuit).result()
# 5. 상태 벡터 확인
statevector = result.get_statevector()
print("Statevector:", statevector)
이 코드에 대한 실행값은 아래와 같이 $|1\rangle$ 상태를 줍니다:
Statevector: Statevector([1.+0.j, 0.+0.j],
dims=(2,))
Pauli-Y 게이트
Pauli-Y 게이트는 아래와 같이 행렬로 표현됩니다:
\begin{eqnarray} {\pmb Y} = \begin{pmatrix} 0 & -i \\ i & 0 \end{pmatrix} \end{eqnarray}
이러한 Y 게이트는 주어진 큐비트를 아래와 같이 변화한합니다:
\begin{eqnarray} {\pmb Y} |0\rangle = \begin{pmatrix} 0 & -i \\ i & 0 \end{pmatrix} \begin{pmatrix} 1 \\ 0 \end{pmatrix} = i \begin{pmatrix} 0 \\ 1 \end{pmatrix} = i |1 \rangle \end{eqnarray}
또는
\begin{eqnarray} {\pmb Y} |1\rangle = \begin{pmatrix} 0 & -i \\ i & 0 \end{pmatrix} \begin{pmatrix} 0 \\ 1 \end{pmatrix} = -i \begin{pmatrix} 1 \\ 0 \end{pmatrix} = -i |0 \rangle \end{eqnarray}
즉, Y 게이트는 큐비트를 x-y 평면에서 180도 회전하며, 회전을 통해 위상을 변화시키는 역할을 합니다.
Y 게이트를 입력하는 명령어는 "큐빗변수.y(큐빗 넘버)"입니다. 따라서, 위에 코드에서 "qc.x(0)"를 "qc.y(0)"로 바꿔주면, Y 연산자를 생성된 큐비트에 적용할 수 있습니다. 출력 결과는 아래와 같습니다:
Statevector: Statevector([0.-0.j, 0.+1.j],
dims=(2,))
$|0\rangle$ 상태가 $i|1\rangle$ 상태로 변환한 것을 알 수 있습니다.
Pauli-Z 게이트
파울리 Z 연산자는 아래와 같이 행렬로 표현됩니다:
\begin{eqnarray} {\pmb Z} = \begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix} \end{eqnarray}
이러한 연산자는 주어진 상태에 대해서 아래와 같은 결과를 줍니다:
\begin{eqnarray} {\pmb Z} |0 \rangle = \begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix} \begin{pmatrix} 1 \\ 0\end{pmatrix} = \begin{pmatrix} 1 \\ 0 \end{pmatrix} = | 0 \rangle \end{eqnarray}
\begin{eqnarray} {\pmb Z} |1 \rangle = \begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix} \begin{pmatrix} 0 \\ 1 \end{pmatrix} = - \begin{pmatrix} 1 \\ 0 \end{pmatrix} = - | 1 \rangle \end{eqnarray}
즉, $|0\rangle$ 상태는 변환하지 않는 반면, $| 1 \rangle$ 상태는 위상을 -1 만큼 변화시킵니다.
Z 게이트는 위에 주어진 코드에서 "큐빗변수.z(큐빗 넘버)" 명령어를 통해 적용해볼 수 있습니다. ("qc.z(0)" 명령어를 이용해 위 코드에서 그 결과값을 확인해보시기 바랍니다.)
결국 이러한 게이트 들은 양자 회로를 구성하는 데 기본 블럭같은 역할을 합니다. 이러한 게이트들을 조합해 풀고 싶은 문제에 대한 복잡한 회로들을 구성할 수 있습니다.
'Quantum Computing' 카테고리의 다른 글
Qiskit을 이용한 양자 컴퓨팅 예제 (6) - 양자 상태의 측정 (Measurement) (0) | 2024.12.16 |
---|---|
Qiskit을 이용한 양자 컴퓨팅 예제 (5) - 이진 연산자: CNOT, CZ 게이트 (0) | 2024.12.15 |
Qiskit을 이용한 양자 컴퓨팅 예제 (4) - 이진 연산자: SWAP 게이트 (0) | 2024.12.15 |
Qiskit을 이용한 양자 컴퓨팅 예제 (3) - 아다마르 게이트 (Hadamard Gate) (0) | 2024.12.02 |
Qiskit을 이용한 양자 컴퓨팅 예제 (2) - 양자회로와 블로흐 구(Bloch Sphere)의 시각화 (0) | 2024.11.27 |