본 튜토리얼은 Qiskit 기반 실습을 통해 양자 회로 설계, 측정, 시뮬레이션의 전체 흐름을 학습하는 예제입니다.
Qiskit은 IBM에서 개발한 언어로, 클라우드 시스템을 통해 양자 컴퓨터에 접근하고 회로를 설계하기 위해 만들어진 오픈소스 퀀텀 컴퓨팅 프레임워크입니다.
양자컴퓨터의 연구는 개인이 회로를 설계하여 IBM의 서버로 보내면 IBM은 그를 본인들이 가지고 있는 양자컴퓨터에서 실험을 해주고 결과를 다시 개인에게 보내는 방식으로 진행되고 있으며, 이러한 과정을 컨트롤 하기 위한 언어가 바로 Qiskit 이라고 합니다.
Qiskit에서는 한글로 된 매뉴얼을 제공하고 있으니 참고하길 바랍니다.
pip install qiskit
pip install qiskit-ibm-runtime
pip install qiskit[visualization]
pip install jupyter
pip install pylatexenc
pip install qiskit-ibm-provider
pip install qiskit_aer
import qiskit as qk
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
# Qiskit Backend -> Quantum Circuit Simulator
from qiskit_aer import Aer
실습 목표는 GHZ 상태를 만드는 것입니다.
GHZ (Greenberger-Home-Zeilinger) 상태는 얽힘 (Entanglement)의 한 형태로 N개의 큐비트가 얽혀있는 양자 상태입니다. GHZ 상태 정의는 아래 그림과 같이 나타납니다.
N개의 큐비트에 대해 GHZ 상태는 위와 같이 일반화 되며, 즉, 모든 큐비트가 0 또는 1 상태로 동시에 얽혀있는 상태입니다. GHZ 상태가 N 큐비트로 확장되면, 한 큐비트만 측정해도 전체 상태가 즉시 확정되는 성질을 유지합니다.
3개의 큐비트를 예로 들어, 하나라도 측정되면 나머지 2개의 상태가 즉시 결정됩니다. 첫 번째 큐비트를 측정해서 |0>가 나오면, 나머지 2개도 자동으로 |00>가 되며, 반면에 |1>로 나오면 나머지 2개도 자동으로 |11> 상태가 됩니다.
생성 방법
# 1. 3개의 큐비트를 가지는 양자 회로를 생성합니다.
circuit = qk.QuantumCircuit(3)
circuit.draw('mpl')
# 2. 첫 번째 큐비트에 Hadmard 게이트를 적용합니다.
circuit.h(0)
circuit.draw('mpl')
# 3. 두 번째/세 번째 큐비트에 CNOT 게이트를 적용합니다.
circuit.cx(0, 1)
circuit.cx(0, 2)
circuit.draw('mpl')
코드실행 결과
복소수 진폭 (Complex numeber amplitude)을 가지는 벡터로, n개의 큐비트를 가지는 시스템의 상태는 2ⁿ 차원의 벡터로 표현됩니다.
특징
이를 바탕으로 Aer 시뮬레이터를 통한 회로를 실행시켜 보았습니다. 아래는 시뮬레이터를 실행 후 측정 결과를 추출하고 이를 시각화 하는 코드입니다.
# Simulator
statevector_simulator = Aer.get_backend('statevector_simulator')
# Create a quantum program for execution
# Qiskit 1.0 doesn't support execute method, use transplie instead
new_circuit = qk.transpile(circuit, statevector_simulator)
job = statevector_simulator.run(new_circuit)
# Check the job status
job.status()
result = job.result()
output_state = result.get_statevector(decimals=3)
print(f'OUPTUT:\n{output_state}')
# Visualization
from qiskit.visualization import plot_histogram
plot_histogram(result.get_counts())
측정 결과 시각화
양자 상태는 복소수 벡터 공간에서 Norm 이 1인 벡터, 즉 유니타리 벡터 (Unitary Vector) 로 표현됩니다.
Unitary Vector는 양자 상태를 나타내는 벡터로, 항상 정규화된 상태를 유지해야 하며
양자 게이트(유니타리 행렬)를 곱하면 상태 벡터가 변하지만, 전체 확률은 보존되는 특성을 가지고있습니다.
아래 코드는 Qiskit에서 Unitary Simulator를 사용하여 회로의 유니터리 행렬을 얻은 것입니다. 이를 통해 해당 양자 회로가 전체 상태공간에 대해 어떤 선형 변환을 수행하는지를 정확하게 알 수 있습니다.
# Run the quantum circuit on an unitary simulator backend
unitary_simulator = Aer.get_backend('unitary_simulator')
unitary_circuit = qk.transpile(circuit, unitary_simulator)
unitary_job = unitary_simulator.run(unitary_circuit)
unitary_result = unitary_job.result()
print(f'UNITARY RESULT:\n{unitary_result.get_unitary(decimals=3)}')
실행결과
OpenQASM Simulator는 코드를 실행하는 Qiskit 기반의 시뮬레이터입니다.
OpenQASM은 양자 회로를 기술하는 언어로, 이를 클래식 컴퓨터에서 실행할 수 있게 변환하는 역할을 합니다.
OpenQASM Simulator는 OpenQASM 언어로 작성된 양자 회로를 시뮬레이션하기 위한 특화된 도구로, 양자 회로의 연산 및 측정을 포함한 전체 시뮬레이션을 지원합니다.
시간복잡도는 아래 특성을 가집니다.
아래 코드는 Qiskit을 사용하여 3큐비트 양자 회로의 측정(measurement) 과 시뮬레이션 결과 분석을 수행하는 전체 흐름을 보여줍니다.
1️⃣ 측정회로(meas) 생성
meas = qk.QuantumCircuit(3, 3)
meas.barrier(range(3))
meas.measure(range(3), range(3))
meas.draw('mpl')
2️⃣ 측정 회로와 본 회로 결합
qc = circuit & meas
qc.draw('mpl')
3️⃣ QASM 시뮬레이터 실행
# Use Aer's qasm_simulator
qsam_simulator = Aer.get_backend('qasm_simulator')
# Execute the circuit on the qasm simulator
qsam_job = qk.transpile(qc, qsam_simulator)
qsam_result = qsam_simulator.run(qsam_job).result()
# Result
qsam_counts = qsam_result.get_counts(qc)
print(f'QSAM COUNTS:\n{qsam_counts}')
실행결과
QSAM COUNTS:
{'000': 522, '111': 502}
4️⃣ 측정 결과 확인
plot_histogram(qsam_counts)
아래와 같이 블로흐 구를 통해 상태를 기하학적으로 시각화가 가능합니다.
상태벡터는 그림과 같이 블로흐 구 위의 벡터로 시각화하여 나타내지며,
∣+⟩ 상태는 X축 방향 (θ = π/2, φ = 0) 벡터로 표시됩니다.
from qiskit.visualization import plot_bloch_multivector
plot_bloch_multivector(bloch_result.get_statevector())
실행결과