주 콘텐츠로 건너뛰기

Circuit 라이브러리

패키지 버전

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

qiskit[all]~=2.5.2

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를 참조하세요.

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 문서의 산술을 참조하세요.

다음 단계​

추천