회로 구성
이 페이지의 코드는 다음 요구 사항을 사용하여 개발되었습니다. 다음 버전 이상을 사용하는 것이 좋습니다.
qiskit[all]~=2.5.2
이 페이지에서는 키스킷 SDK의 QuantumCircuit 클래스를 자세히 살펴보고, 양자 회로를 만드는 데 사용할 수 있는 몇 가지 고급 메서드를 포함합니다.
양자 회로란 무엇인가?
간단한 양자 회로는 큐비트와 그 큐비트에 작용하는 명령어 목록의 모음입니다. 이를 보여주기 위해 다음 셀은 두 개의 새로운 큐비트로 새 회로를 생성한 다음, 해당 회로의 qubits 속성을 표시합니다 Qubits 최하위 비트 부터 최상위 비트 까지 순서대로 표시합니다.
from qiskit import QuantumCircuit
qc = QuantumCircuit(2)
qc.qubitsOutput:
[<Qubit register=(2, "q"), index=0>, <Qubit register=(2, "q"), index=1>]
여러 개의 QuantumRegister 및 ClassicalRegister 개체를 결합하여 회로를 만들 수 있습니다. 모든 QuantumRegister 및 ClassicalRegister 도 이름을 지정할 수 있습니다.
from qiskit.circuit import QuantumRegister, ClassicalRegister
qr1 = QuantumRegister(2, "qreg1") # Create a QuantumRegister with 2 qubits
qr2 = QuantumRegister(1, "qreg2") # Create a QuantumRegister with 1 qubit
cr1 = ClassicalRegister(3, "creg1") # Create a ClassicalRegister with 3 cbits
combined_circ = QuantumCircuit(
qr1, qr2, cr1
) # Create a quantum circuit with 2 QuantumRegisters and 1 ClassicalRegister
combined_circ.qubitsOutput:
[<Qubit register=(2, "qreg1"), index=0>,
<Qubit register=(2, "qreg1"), index=1>,
<Qubit register=(1, "qreg2"), index=0>]
큐비트의 인덱스를 찾고 등록하려면 회로의 find_bit 메서드와 그 어트리뷰트를 사용하면 됩니다.
desired_qubit = qr2[0] # Qubit 0 of register 'qreg2'
print("Index:", combined_circ.find_bit(desired_qubit).index)
print("Register:", combined_circ.find_bit(desired_qubit).registers)Output:
Index: 2
Register: [(QuantumRegister(1, 'qreg2'), 0)]
회로에 인스트럭션을 추가하면 해당 인스트럭션이 회로의 data 어트리뷰트에 인스트럭션을 추가합니다. 다음 셀 출력은 data 의 목록입니다 CircuitInstruction 객체의 목록이며, 각 객체에는 operation 어트리뷰트와 qubits 어트리뷰트가 있습니다.
qc.x(0) # Add X-gate to qubit 0
qc.dataOutput:
[CircuitInstruction(operation=Instruction(name='x', num_qubits=1, num_clbits=0, params=[]), qubits=(<Qubit register=(2, "q"), index=0>,), clbits=())]
이 정보를 확인하는 가장 쉬운 방법은 회로 시각화 결과를 반환하는 draw 메서드를 이용하는 것입니다. 양자 회로를 표시하는 다양한 방법에 대해서는 ‘회로 시각화’를 참조하십시오.
qc.draw("mpl")Output:
회로 명령어 객체에는 보다 기본적인 명령어 측면에서 명령어를 설명하는 '정의' 회로가 포함될 수 있습니다. 예를 들어, X-게이트는 특정 경우의 U3-gate 보다 일반적인 단일 큐비트 게이트로 정의됩니다.
# Draw definition circuit of 0th instruction in `qc`
qc.data[0].operation.definition.draw("mpl")Output:
명령어와 회로는 모두 비트와 큐비트에 대한 연산을 설명한다는 점에서 비슷하지만 목적이 다릅니다:
- 인스트럭션은 고정된 것으로 취급되며, 해당 메서드는 일반적으로 (원래 객체를 변경하지 않고) 새 인스트럭션을 반환합니다.
- 회로는 여러 줄의 코드에 걸쳐 구축되도록 설계되며
QuantumCircuit메서드는 종종 기존 객체를 변경합니다.
회로 깊이란 무엇인가?
양자 회로의 깊이() 는 병렬로 실행되는 양자 게이트의 '레이어' 수를 측정한 값으로, 회로에 정의된 연산을 완료하는 데 걸리는 시간을 의미합니다. 양자 게이트는 구현하는 데 시간이 걸리기 때문에 회로의 깊이는 양자 컴퓨터가 회로를 실행하는 데 걸리는 시간과 대략적으로 일치합니다. 따라서 회로의 깊이는 양자 회로가 장치에서 실행될 수 있는지 여부를 측정하는 데 사용되는 중요한 수량 중 하나입니다.
이 페이지의 나머지 부분에서는 양자 회로를 조작하는 방법을 설명합니다.
회로를 구축하다
다음과 같은 메서드 QuantumCircuit.h 및 QuantumCircuit.cx 회로에 특정 지침을 추가합니다. 보다 일반적으로 회로에 인스트럭션을 추가하려면 append 메서드를 사용합니다. 여기에는 인스트럭션과 인스트럭션을 적용할 큐비트 목록이 필요합니다. 지원되는 지침 목록은 서킷 라이브러리 API 설명서를 참조하세요.
from qiskit.circuit.library import HGate
qc = QuantumCircuit(1)
qc.append(
HGate(), # New HGate instruction
[0], # Apply to qubit 0
)
qc.draw("mpl")Output:
두 회로를 결합하려면 compose 메서드를 사용합니다. 이것은 다른 QuantumCircuit 와 선택적 큐비트 매핑 목록을 받습니다.
qc_a = QuantumCircuit(4)
qc_a.x(0)
qc_b = QuantumCircuit(2, name="qc_b")
qc_b.y(0)
qc_b.z(1)
# keep qubits (0, 1) of qc_a with same index.
# compose qubits (0,1) of qc_b to qubits (1, 3), respectively, of new composite circuit
combined = qc_a.compose(qc_b, qubits=[1, 3])
combined.draw("mpl")Output:
회로를 정리하기 위해 회로를 지침으로 컴파일할 수도 있습니다. 메서드를 사용하여 회로를 인스트럭션으로 변환할 수 있습니다 to_instruction 메서드를 사용하여 회로를 인스트럭션으로 변환한 다음 다른 인스트럭션과 마찬가지로 다른 회로에 추가할 수 있습니다. 다음 셀에 그려진 회로는 이전 셀에 그려진 회로와 기능적으로 동일합니다.
inst = qc_b.to_instruction()
qc_a.append(inst, [1, 3])
qc_a.draw("mpl")Output:
회로가 단일 회로인 경우 다음을 사용하여 Gate 로 변환할 수 있습니다 to_gate 메서드를 사용하여 변환할 수 있습니다. Gate 객체는 특정 유형의 명령어로, 양자 제어를 추가하는 control 메서드처럼 양자 제어를 추가합니다.
gate = qc_b.to_gate().control()
qc_a.append(gate, [0, 1, 3])
qc_a.draw("mpl")Output:
무슨 일이 일어나고 있는지 확인하려면 decompose 메서드를 사용하여 각 명령어를 해당 정의로 확장할 수 있습니다.
메서드는 decompose 메서드는 새 회로를 반환하고 작동하는 회로를 변경하지 않습니다.
qc_a.decompose().draw("mpl")Output:
큐비트 측정
측정 과정은 개별 큐비트의 상태를 샘플링하고 그 결과를 고전적 레지스터로 전송하는 데 사용됩니다. 샘플러 프리미티브에 회로를 제출할 경우, 측정값을 반드시 포함해야 합니다. 단, Estimator 프리미티브에 전달되는 회로에는 측정값이 포함되어서는 안 됩니다.
큐비트는 다음 세 가지 방법으로 측정할 수 있습니다: measure, measure_all 및 measure_active. 측정 결과를 시각화하는 방법은 ‘결과 시각화’ 페이지를 참조하십시오.
-
QuantumCircuit.measure는 첫 번째 인수의 각 큐비트를 두 번째 인자로 주어진 클래식 비트에 측정합니다. 이 방법을 사용하면 측정 결과가 저장되는 위치를 완벽하게 제어할 수 있습니다. -
QuantumCircuit.measure_all는 인수를 받지 않으며 사전 정의된 클래식 비트 없이 양자 회로에 사용할 수 있습니다. 클래식 와이어를 생성하고 측정 결과를 순서대로 저장합니다. 예를 들어, 큐비트 의 측정값은 cbit )에 저장됩니다. 또한 측정 전에 배리어를 추가합니다. -
QuantumCircuit.measure_activemeasure_all와 유사하지만 연산이 있는 큐비트만 측정합니다.
qc1 = QuantumCircuit(2, 2)
qc1.measure(0, 1)
qc1.draw("mpl", cregbundle=False)Output:
qc2 = QuantumCircuit(2)
qc2.measure_all()
qc2.draw("mpl", cregbundle=False)Output:
qc3 = QuantumCircuit(2)
qc3.x(1)
qc3.measure_active()
qc3.draw("mpl", cregbundle=False)Output:
매개변수화된 회로
많은 단기 양자 알고리즘은 양자 회로의 다양한 변형을 실행하는 것을 포함합니다. 대규모 회로를 구성하고 최적화하는 것은 계산 비용이 많이 들 수 있으므로, 키스킷은 매개변수화된 회로를 지원합니다. 이러한 회로에는 정의되지 않은 매개변수가 있으며, 회로를 실행하기 직전까지 해당 값을 정의할 필요가 없습니다. 이를 통해 회로 구성 및 최적화를 메인 프로그램 루프 밖으로 옮길 수 있습니다. 다음 셀은 매개변수화된 회로를 생성하고 표시합니다.
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.circuit import Parameter
angle = Parameter("angle") # undefined number
# Create and optimize circuit once
qc = QuantumCircuit(1)
qc.rx(angle, 0)
qc = generate_preset_pass_manager(
optimization_level=3, basis_gates=["u", "cx"]
).run(qc)
qc.draw("mpl")Output:
다음 셀은 이 회로의 다양한 변형을 생성하고 그 중 하나를 표시합니다.
circuits = []
for value in range(100):
circuits.append(qc.assign_parameters({angle: value}))
circuits[0].draw("mpl")Output:
회로의 정의되지 않은 매개변수 목록은 parameters 속성에서 찾을 수 있습니다.
qc.parametersOutput:
ParameterView([Parameter(angle)])
매개변수 이름 변경
기본적으로 매개변수화된 회로의 매개변수 이름은 -로 시작합니다 x. 예를 들어, x[0]. 정의된 후에도 이름을 변경할 수 있습니다. 다음 예시에서 확인할 수 있듯이.
from qiskit.circuit.library import z_feature_map
from qiskit.circuit import ParameterVector
# Define a parameterized circuit with default names
# For example, x[0]
circuit = z_feature_map(2)
# Set new parameter names
# They will now be prefixed by `hi` instead
# For example, hi[0]
training_params = ParameterVector("hi", 2)
# Assign parameter names to the quantum circuit
circuit = circuit.assign_parameters(parameters=training_params)다음 단계
- 단기 양자 알고리즘에 대해 알아보려면 변형 알고리즘 설계 과정을 수강하세요.
- 그로버 알고리즘 튜토리얼에서 회로의 사용 예시를 참조하세요.
- IBM 퀀텀 컴포저를 사용하여 간단한 회로로 작업하세요.