주 콘텐츠로 건너뛰기

Circuit 라이브러리

패키지 버전

이 페이지의 코드는 다음 요구 사항을 사용하여 개발되었습니다. 이 버전 이상을 사용하는 것을 권장합니다.

qiskit[all]~=2.3.0

Qiskit SDK에는 자신의 프로그램에서 빌딩 블록으로 사용할 수 있는 인기 있는 Circuit 라이브러리가 포함되어 있습니다. 미리 정의된 Circuit을 사용하면 연구, 코드 작성, 디버깅에 드는 시간을 절약할 수 있습니다. 이 라이브러리에는 양자 컴퓨팅에서 인기 있는 Circuit, 고전적으로 시뮬레이션하기 어려운 Circuit, 그리고 양자 하드웨어 벤치마킹에 유용한 Circuit이 포함되어 있습니다.

이 페이지에서는 라이브러리가 제공하는 다양한 Circuit 카테고리를 나열합니다. Circuit의 전체 목록은 Circuit 라이브러리 API 문서를 참조하세요.

표준 Gate

Circuit 라이브러리에는 표준 양자 Gate도 포함되어 있습니다. 일부는 더 기본적인 Gate(예: UGate)이고, 다른 일부는 일반적으로 단일 및 이중 Qubit Gate로 구성해야 하는 다중 Qubit Gate입니다. 가져온 Gate를 Circuit에 추가하려면 append 메서드를 사용하세요. 첫 번째 인자는 Gate이고, 다음 인자는 Gate를 적용할 Qubit 목록입니다.

예를 들어, 다음 코드 셀은 Hadamard Gate와 다중 제어 X Gate가 있는 Circuit을 생성합니다.

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit
from qiskit import QuantumCircuit
from qiskit.circuit.library import HGate, MCXGate

mcx_gate = MCXGate(3)
hadamard_gate = HGate()

qc = QuantumCircuit(4)
qc.append(hadamard_gate, [0])
qc.append(mcx_gate, [0, 1, 2, 3])
qc.draw("mpl")

Output of the previous code cell

Circuit 라이브러리 API 문서의 표준 Gate를 참조하세요.

Gate 이름이 헷갈리시나요? Qiskit Code Assistant에 물어보세요.

N-local Circuit

이 Circuit들은 단일 Qubit 회전 Gate 레이어와 다중 Qubit 얽힘 Gate 레이어를 번갈아 가며 구성합니다.

이 Circuit 계열은 다양한 양자 상태를 생성할 수 있기 때문에 변분 양자 알고리즘에서 인기가 많습니다. 변분 알고리즘은 Gate 파라미터를 조정하여 특정 속성(예: 최적화 문제에 대한 좋은 해를 나타내는 상태)을 가진 상태를 찾습니다. 이를 위해 라이브러리의 많은 Circuit은 파라미터화되어 있으며, 이는 고정된 값 없이 정의할 수 있음을 의미합니다.

다음 코드 셀은 얽힘 Gate가 이중 Qubit Gate인 n_local Circuit을 가져옵니다. 이 Circuit은 파라미터화된 단일 Qubit Gate 블록과 이중 Qubit Gate의 얽힘 블록을 교대로 배치합니다. 다음 코드는 단일 Qubit RX Gate와 이중 Qubit CZ Gate를 사용하여 세 개의 Qubit Circuit을 생성합니다.

from qiskit.circuit.library import n_local

two_local = n_local(3, "rx", "cz")
two_local.draw("mpl")

Output of the previous code cell

parameters 속성을 통해 Circuit 파라미터의 리스트 형식 객체를 가져올 수 있습니다.

two_local.parameters
ParameterView([ParameterVectorElement(θ[0]), ParameterVectorElement(θ[1]), ParameterVectorElement(θ[2]), ParameterVectorElement(θ[3]), ParameterVectorElement(θ[4]), ParameterVectorElement(θ[5]), ParameterVectorElement(θ[6]), ParameterVectorElement(θ[7]), ParameterVectorElement(θ[8]), ParameterVectorElement(θ[9]), ParameterVectorElement(θ[10]), ParameterVectorElement(θ[11])])

{ Parameter: number } 형식의 딕셔너리를 사용하여 이 파라미터들을 실제 값에 할당할 수도 있습니다. 예시로, 다음 코드 셀은 Circuit의 각 파라미터를 0으로 할당합니다.

bound_circuit = two_local.assign_parameters(
{p: 0 for p in two_local.parameters}
)
bound_circuit.decompose().draw("mpl")

Output of the previous code cell

자세한 내용은 Circuit 라이브러리 API 문서의 N-local Gate를 참조하거나 IBM Quantum Learning의 변분 알고리즘 설계 과정을 수강하세요.

데이터 인코딩 Circuit

이 파라미터화된 Circuit들은 양자 머신러닝 알고리즘이 처리할 수 있도록 데이터를 양자 상태에 인코딩합니다. Qiskit이 지원하는 일부 Circuit은 다음과 같습니다:

  • 진폭 인코딩(Amplitude encoding): 각 숫자를 기저 상태의 진폭으로 인코딩합니다. 단일 상태에 2n2^n개의 숫자를 저장할 수 있지만, 구현 비용이 높을 수 있습니다.
  • 기저 인코딩(Basis encoding): 정수 kk를 해당 기저 상태 k|k\rangle로 준비하여 인코딩합니다.
  • 각도 인코딩(Angle encoding): 데이터의 각 숫자를 파라미터화된 Circuit의 회전 각도로 설정합니다.

최적의 방법은 애플리케이션의 구체적인 특성에 따라 다릅니다. 그러나 현재 양자 컴퓨터에서는 zz_feature_map과 같은 각도 인코딩 Circuit을 자주 사용합니다.

from qiskit.circuit.library import zz_feature_map

features = [0.2, 0.4, 0.8]
feature_map = zz_feature_map(feature_dimension=len(features))

encoded = feature_map.assign_parameters(features)
encoded.draw("mpl")

Output of the previous code cell

Circuit 라이브러리 API 문서의 데이터 인코딩 Circuit을 참조하세요.

시간 진화 Circuit

이 Circuit들은 시간에 따라 진화하는 양자 상태를 시뮬레이션합니다. 시간 진화 Circuit을 사용하여 시스템에서의 열 전달이나 상 전이와 같은 물리적 효과를 조사하세요. 시간 진화 Circuit은 화학 파동 함수(예: 유니터리 결합 클러스터 시험 상태)와 최적화 문제에 사용하는 QAOA 알고리즘의 기본 빌딩 블록이기도 합니다.

from qiskit.circuit.library import PauliEvolutionGate
from qiskit.circuit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp

# Prepare an initial state with a Hadamard on the middle qubit
state = QuantumCircuit(3)
state.h(1)

hamiltonian = SparsePauliOp(["ZZI", "IZZ"])
evolution = PauliEvolutionGate(hamiltonian, time=1)

# Evolve state by appending the evolution gate
state.compose(evolution, inplace=True)

state.draw("mpl")

Output of the previous code cell

PauliEvolutionGate API 문서를 읽어보세요.

벤치마킹 및 복잡도 이론 Circuit

벤치마킹 Circuit은 하드웨어가 실제로 얼마나 잘 작동하는지 파악하는 데 도움을 주며, 복잡도 이론 Circuit은 우리가 해결하려는 문제가 얼마나 어려운지 이해하는 데 도움을 줍니다.

예를 들어, "양자 볼륨(quantum volume)" 벤치마크는 양자 컴퓨터가 특정 유형의 무작위 양자 Circuit을 얼마나 정확하게 실행하는지 측정합니다. 양자 컴퓨터의 점수는 안정적으로 실행할 수 있는 Circuit의 크기에 따라 증가합니다. 이는 Qubit 수, 명령 충실도, Qubit 연결성, 결과를 Transpile하고 후처리하는 소프트웨어 스택 등 컴퓨터의 모든 측면을 고려합니다. 양자 볼륨에 대한 자세한 내용은 원래 양자 볼륨 논문을 참조하세요.

다음 코드는 네 개의 Qubit에서 실행되는 Qiskit으로 구축된 양자 볼륨 Circuit 예시를 보여줍니다(unitary 블록은 무작위 이중 Qubit Gate입니다).

from qiskit.circuit.library import quantum_volume

quantum_volume(4).draw("mpl")

Output of the previous code cell

Circuit 라이브러리에는 순간 양자 다항식(iqp) Circuit과 같이 고전적으로 시뮬레이션하기 어렵다고 여겨지는 Circuit도 포함되어 있습니다. 이 Circuit들은 Hadamard Gate 블록 사이에 특정 대각 Gate(계산 기저에서)를 끼워 넣습니다.

그 외 Circuit으로는 Grover 알고리즘에서 사용하는 grover_operator와 푸리에 검사 문제를 위한 fourier_checking Circuit이 있습니다. Circuit 라이브러리 API 문서의 특정 양자 Circuit에서 이 Circuit들을 확인하세요.

산술 Circuit

산술 연산은 정수 덧셈, 비트 연산 등의 고전적 함수입니다. 이러한 연산은 금융 응용을 위한 진폭 추정과 같은 알고리즘과, 선형 방정식 시스템을 푸는 HHL 알고리즘과 같은 알고리즘에 유용할 수 있습니다.

예시로, "ripple-carry" Circuit을 사용하여 제자리 덧셈(FullAdderGate)을 수행하는 방식으로 두 개의 세 자리 이진수를 더해보겠습니다. 이 덧셈기는 두 수(각각 "A"와 "B"라고 부릅니다)를 더하고 결과를 B를 보유하던 레지스터에 씁니다. 다음 예시에서는 A=2이고 B=3입니다.

from qiskit.circuit.library import FullAdderGate
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister

adder = FullAdderGate(3) # Adder of 3-bit numbers

# Create the number A=2
reg_a = QuantumRegister(3, "a")
number_a = QuantumCircuit(reg_a)
number_a.initialize(2) # Number 2; |010>

# Create the number B=3
reg_b = QuantumRegister(3, "b")
number_b = QuantumCircuit(reg_b)
number_b.initialize(3) # Number 3; |011>

# Create a circuit to hold everything, including a classical register for
# the result
qregs = [
QuantumRegister(1, "cin"),
QuantumRegister(3, "a"),
QuantumRegister(3, "b"),
QuantumRegister(1, "cout"),
]
reg_result = ClassicalRegister(3)
circuit = QuantumCircuit(*qregs, reg_result)

# Compose number initializers with the adder. Adder stores the result to
# register B, so we'll measure those qubits.
circuit = (
circuit.compose(number_a, qubits=reg_a)
.compose(number_b, qubits=reg_b)
.compose(adder)
)
circuit.measure(reg_b, reg_result)
circuit.draw("mpl")

Output of the previous code cell

Circuit을 시뮬레이션하면 모든 1024번의 샷에서 5를 출력하는 것을 확인할 수 있습니다(즉, 확률 1.0으로 측정됩니다).

from qiskit.primitives import StatevectorSampler

result = StatevectorSampler().run([circuit]).result()

print(f"Count data:\n {result[0].data.c0.get_int_counts()}")
Count data:
{5: 1024}

Circuit 라이브러리 API 문서의 산술을 참조하세요.

다음 단계

추천