Skip to main content
IBM Quantum Platform

회로 구성

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

    qiskit[all]~=2.5.2
    

이 페이지에서는 키스킷 SDK의 QuantumCircuit 클래스를 자세히 살펴보고, 양자 회로를 만드는 데 사용할 수 있는 몇 가지 고급 메서드를 포함합니다.


양자 회로란 무엇인가?

간단한 양자 회로는 큐비트와 그 큐비트에 작용하는 명령어 목록의 모음입니다. 이를 보여주기 위해 다음 셀은 두 개의 새로운 큐비트로 새 회로를 생성한 다음, 해당 회로의 qubits 속성을 표시합니다 Qubits 최하위 비트 q0q_0 부터 최상위 비트 qnq_n 까지 순서대로 표시합니다.

from qiskit import QuantumCircuit

qc = QuantumCircuit(2)
qc.qubits

Output:

[<Qubit register=(2, "q"), index=0>, <Qubit register=(2, "q"), index=1>]

여러 개의 QuantumRegisterClassicalRegister 개체를 결합하여 회로를 만들 수 있습니다. 모든 QuantumRegisterClassicalRegister 도 이름을 지정할 수 있습니다.

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.qubits

Output:

[<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.data

Output:

[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:

Output of the previous code cell

회로 명령어 객체에는 보다 기본적인 명령어 측면에서 명령어를 설명하는 '정의' 회로가 포함될 수 있습니다. 예를 들어, X-게이트는 특정 경우의 U3-gate 보다 일반적인 단일 큐비트 게이트로 정의됩니다.

# Draw definition circuit of 0th instruction in `qc`
qc.data[0].operation.definition.draw("mpl")

Output:

Output of the previous code cell

명령어와 회로는 모두 비트와 큐비트에 대한 연산을 설명한다는 점에서 비슷하지만 목적이 다릅니다:

  • 인스트럭션은 고정된 것으로 취급되며, 해당 메서드는 일반적으로 (원래 객체를 변경하지 않고) 새 인스트럭션을 반환합니다.
  • 회로는 여러 줄의 코드에 걸쳐 구축되도록 설계되며 QuantumCircuit 메서드는 종종 기존 객체를 변경합니다.

회로 깊이란 무엇인가?

양자 회로의 깊이() 는 병렬로 실행되는 양자 게이트의 '레이어' 수를 측정한 값으로, 회로에 정의된 연산을 완료하는 데 걸리는 시간을 의미합니다. 양자 게이트는 구현하는 데 시간이 걸리기 때문에 회로의 깊이는 양자 컴퓨터가 회로를 실행하는 데 걸리는 시간과 대략적으로 일치합니다. 따라서 회로의 깊이는 양자 회로가 장치에서 실행될 수 있는지 여부를 측정하는 데 사용되는 중요한 수량 중 하나입니다.

이 페이지의 나머지 부분에서는 양자 회로를 조작하는 방법을 설명합니다.


회로를 구축하다

다음과 같은 메서드 QuantumCircuit.hQuantumCircuit.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:

Output of the previous code cell

두 회로를 결합하려면 compose 메서드를 사용합니다. 이것은 다른 QuantumCircuit 와 선택적 큐비트 매핑 목록을 받습니다.

Note

메서드는 compose 메서드는 새 회로를 반환하며 작동하는 회로를 변경하지 않습니다. 메서드를 호출하는 회로를 변경하려면 compose 메서드를 호출하는 회로를 변경하려면 inplace=True 인수를 사용합니다.

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:

Output of the previous code cell

회로를 정리하기 위해 회로를 지침으로 컴파일할 수도 있습니다. 메서드를 사용하여 회로를 인스트럭션으로 변환할 수 있습니다 to_instruction 메서드를 사용하여 회로를 인스트럭션으로 변환한 다음 다른 인스트럭션과 마찬가지로 다른 회로에 추가할 수 있습니다. 다음 셀에 그려진 회로는 이전 셀에 그려진 회로와 기능적으로 동일합니다.

inst = qc_b.to_instruction()
qc_a.append(inst, [1, 3])
qc_a.draw("mpl")

Output:

Output of the previous code cell

회로가 단일 회로인 경우 다음을 사용하여 Gate 로 변환할 수 있습니다 to_gate 메서드를 사용하여 변환할 수 있습니다. Gate 객체는 특정 유형의 명령어로, 양자 제어를 추가하는 control 메서드처럼 양자 제어를 추가합니다.

gate = qc_b.to_gate().control()
qc_a.append(gate, [0, 1, 3])
qc_a.draw("mpl")

Output:

Output of the previous code cell

무슨 일이 일어나고 있는지 확인하려면 decompose 메서드를 사용하여 각 명령어를 해당 정의로 확장할 수 있습니다.

Note

메서드는 decompose 메서드는 새 회로를 반환하고 작동하는 회로를 변경하지 않습니다.

qc_a.decompose().draw("mpl")

Output:

Output of the previous code cell

큐비트 측정

측정 과정은 개별 큐비트의 상태를 샘플링하고 그 결과를 고전적 레지스터로 전송하는 데 사용됩니다. 샘플러 프리미티브에 회로를 제출할 경우, 측정값을 반드시 포함해야 합니다. 단, Estimator 프리미티브에 전달되는 회로에는 측정값이 포함되어서는 안 됩니다.

큐비트는 다음 세 가지 방법으로 측정할 수 있습니다: measure, measure_allmeasure_active. 측정 결과를 시각화하는 방법은 ‘결과 시각화’ 페이지를 참조하십시오.

  1. QuantumCircuit.measure 는 첫 번째 인수의 각 큐비트를 두 번째 인자로 주어진 클래식 비트에 측정합니다. 이 방법을 사용하면 측정 결과가 저장되는 위치를 완벽하게 제어할 수 있습니다.

  2. QuantumCircuit.measure_all 는 인수를 받지 않으며 사전 정의된 클래식 비트 없이 양자 회로에 사용할 수 있습니다. 클래식 와이어를 생성하고 측정 결과를 순서대로 저장합니다. 예를 들어, 큐비트 qiq_i 의 측정값은 cbit measimeas_i )에 저장됩니다. 또한 측정 전에 배리어를 추가합니다.

  3. QuantumCircuit.measure_active measure_all 와 유사하지만 연산이 있는 큐비트만 측정합니다.

qc1 = QuantumCircuit(2, 2)
qc1.measure(0, 1)
qc1.draw("mpl", cregbundle=False)

Output:

Output of the previous code cell
qc2 = QuantumCircuit(2)
qc2.measure_all()
qc2.draw("mpl", cregbundle=False)

Output:

Output of the previous code cell
qc3 = QuantumCircuit(2)
qc3.x(1)
qc3.measure_active()
qc3.draw("mpl", cregbundle=False)

Output:

Output of the previous code cell

매개변수화된 회로

많은 단기 양자 알고리즘은 양자 회로의 다양한 변형을 실행하는 것을 포함합니다. 대규모 회로를 구성하고 최적화하는 것은 계산 비용이 많이 들 수 있으므로, 키스킷은 매개변수화된 회로를 지원합니다. 이러한 회로에는 정의되지 않은 매개변수가 있으며, 회로를 실행하기 직전까지 해당 값을 정의할 필요가 없습니다. 이를 통해 회로 구성 및 최적화를 메인 프로그램 루프 밖으로 옮길 수 있습니다. 다음 셀은 매개변수화된 회로를 생성하고 표시합니다.

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:

Output of the previous code cell

다음 셀은 이 회로의 다양한 변형을 생성하고 그 중 하나를 표시합니다.

circuits = []
for value in range(100):
    circuits.append(qc.assign_parameters({angle: value}))

circuits[0].draw("mpl")

Output:

Output of the previous code cell

회로의 정의되지 않은 매개변수 목록은 parameters 속성에서 찾을 수 있습니다.

qc.parameters

Output:

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)

다음 단계

권장사항
이 페이지가 도움이 되었습니까?
GitHub에서 버그, 오타를 보고하거나 컨텐츠를 요청하십시오.