ข้ามไปยังเนื้อหาหลัก

สร้าง Circuit

เวอร์ชันแพ็กเกจ

โค้ดในหน้านี้ถูกพัฒนาโดยใช้ข้อกำหนดต่อไปนี้ แนะนำให้ใช้เวอร์ชันเหล่านี้หรือใหม่กว่า

qiskit[all]~=2.3.0

หน้านี้จะศึกษาคลาส QuantumCircuit ใน Qiskit SDK อย่างละเอียดมากขึ้น รวมถึงเมธอดขั้นสูงบางอย่างที่ใช้สร้าง quantum circuits ได้

Quantum circuit คืออะไร?

Quantum circuit อย่างง่ายคือชุดของ Qubits และรายการ instructions ที่กระทำต่อ Qubits เหล่านั้น เพื่อแสดงให้เห็น เซลล์ต่อไปนี้สร้าง circuit ใหม่พร้อม Qubit ใหม่สองตัว แล้วแสดง attribute qubits ของ circuit ซึ่งเป็นรายการ Qubits เรียงลำดับจาก bit ที่มีนัยสำคัญน้อยที่สุด q0q_0 ไปยัง bit ที่มีนัยสำคัญมากที่สุด qnq_n

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit
from qiskit import QuantumCircuit

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

ออบเจกต์ QuantumRegister และ ClassicalRegister หลายตัวสามารถรวมกันเพื่อสร้าง circuit ได้ 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.qubits
[<Qubit register=(2, "qreg1"), index=0>,
<Qubit register=(2, "qreg1"), index=1>,
<Qubit register=(1, "qreg2"), index=0>]

สามารถหา index และ register ของ Qubit ได้โดยใช้เมธอด find_bit ของ circuit และ attributes ของมัน

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)
Index: 2
Register: [(QuantumRegister(1, 'qreg2'), 0)]

การเพิ่ม instruction ลงใน circuit จะต่อท้าย instruction ไปยัง attribute data ของ circuit ผลลัพธ์ของเซลล์ต่อไปนี้แสดงว่า data คือรายการของออบเจกต์ CircuitInstruction ซึ่งแต่ละตัวมี attribute operation และ attribute qubits

qc.x(0)  # Add X-gate to qubit 0
qc.data
[CircuitInstruction(operation=Instruction(name='x', num_qubits=1, num_clbits=0, params=[]), qubits=(<Qubit register=(2, "q"), index=0>,), clbits=())]

วิธีที่ง่ายที่สุดในการดูข้อมูลนี้คือผ่านเมธอด draw ซึ่งส่งคืนภาพ visualization ของ circuit ดู แสดงผล circuits สำหรับวิธีต่าง ๆ ในการแสดง quantum circuits

qc.draw("mpl")

Output of the previous code cell

ออบเจกต์ Circuit instruction สามารถมี "definition" circuits ที่อธิบาย instruction นั้นในแง่ของ instructions ที่พื้นฐานกว่า ตัวอย่างเช่น X-gate ถูกกำหนดเป็นกรณีเฉพาะของ U3-gate ซึ่งเป็น Gate สำหรับ Qubit เดียวที่ทั่วไปกว่า

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

Output of the previous code cell

Instructions และ circuits มีความคล้ายกันในแง่ที่ทั้งสองอธิบายการดำเนินการบน bits และ Qubits แต่มีวัตถุประสงค์ที่แตกต่างกัน:

  • Instructions ถูกถือว่าคงที่ และเมธอดของพวกเขามักจะส่งคืน instructions ใหม่ (โดยไม่ mutate ออบเจกต์ต้นฉบับ)
  • Circuits ถูกออกแบบให้สร้างในหลายบรรทัดของโค้ด และเมธอด QuantumCircuit มักจะ mutate ออบเจกต์ที่มีอยู่

Circuit depth คืออะไร?

depth() ของ quantum circuit คือการวัดจำนวน "ชั้น" ของ quantum gates ที่รันแบบขนานเพื่อทำการคำนวณที่กำหนดโดย circuit ให้สมบูรณ์ เนื่องจาก quantum gates ใช้เวลาในการ implement depth ของ circuit จึงสอดคล้องกับเวลาที่คอมพิวเตอร์ควอนตัมใช้ในการรัน circuit นั้น ๆ ดังนั้น depth ของ circuit จึงเป็นปริมาณสำคัญหนึ่งที่ใช้วัดว่า quantum circuit สามารถรันบนอุปกรณ์ได้หรือไม่

ส่วนที่เหลือของหน้านี้จะแสดงวิธีจัดการ quantum circuits

สร้าง circuits

เมธอดอย่าง QuantumCircuit.h และ QuantumCircuit.cx เพิ่ม instructions เฉพาะลงใน circuits ในการเพิ่ม instructions ลงใน circuit อย่างทั่วไปมากขึ้น ให้ใช้เมธอด append ซึ่งรับ instruction และรายการ Qubits ที่จะใช้ instruction นั้น ดูเอกสาร Circuit Library API สำหรับรายการ instructions ที่รองรับ

from qiskit.circuit.library import HGate

qc = QuantumCircuit(1)
qc.append(
HGate(), # New HGate instruction
[0], # Apply to qubit 0
)
qc.draw("mpl")

Output of the previous code cell

ในการรวมสอง circuits เข้าด้วยกัน ให้ใช้เมธอด compose ซึ่งรับ QuantumCircuit อื่นและรายการ qubit mappings ที่เป็นตัวเลือก

หมายเหตุ

เมธอด compose ส่งคืน circuit ใหม่และไม่ mutate circuit ใด ๆ ที่มันกระทำ ในการ mutate circuit ที่กำลังเรียกเมธอด compose ให้ใช้ argument 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)

# compose qubits (0, 1) of qc_a to qubits (1, 3) of qc_b respectively
combined = qc_a.compose(qc_b, qubits=[1, 3])
combined.draw("mpl")

Output of the previous code cell

นอกจากนี้ยังอาจต้องการ compile circuits เป็น instructions เพื่อจัดระเบียบ circuits ให้ดีขึ้น สามารถแปลง circuit เป็น instruction ได้โดยใช้เมธอด to_instruction จากนั้น append ไปยัง circuit อื่นเหมือน instruction ทั่วไป circuit ที่วาดในเซลล์ต่อไปนี้มีฟังก์ชันเทียบเท่ากับ circuit ที่วาดในเซลล์ก่อนหน้า

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

Output of the previous code cell

ถ้า circuit เป็น unitary สามารถแปลงเป็น Gate ได้โดยใช้เมธอด to_gate ออบเจกต์ Gate เป็นประเภทเฉพาะของ instructions ที่มีฟีเจอร์พิเศษบางอย่าง เช่นเมธอด control ซึ่งเพิ่ม quantum control

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

Output of the previous code cell

เพื่อดูสิ่งที่เกิดขึ้น สามารถใช้เมธอด decompose เพื่อขยาย instruction แต่ละตัวเป็นคำนิยามของมัน

หมายเหตุ

เมธอด decompose ส่งคืน circuit ใหม่และไม่ mutate circuit ที่มันกระทำ

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

Output of the previous code cell

วัด Qubits

การวัดใช้เพื่อสุ่มตัวอย่างสถานะของ Qubits แต่ละตัวและถ่ายโอนผลลัพธ์ไปยัง classical register สังเกตว่าถ้าส่ง circuits ไปยัง primitive Sampler จำเป็นต้องมีการวัด อย่างไรก็ตาม circuits ที่ส่งไปยัง primitive Estimator ต้องไม่มีการวัด

Qubits สามารถวัดได้โดยใช้สามเมธอด: measure, measure_all และ measure_active ดูวิธีแสดงผลที่ แสดงผลลัพธ์

  1. QuantumCircuit.measure : วัด Qubit แต่ละตัวใน argument แรกไปยัง classical bit ที่ให้เป็น argument ที่สอง เมธอดนี้ให้ควบคุมอย่างเต็มที่ว่าผลการวัดถูกเก็บที่ไหน

  2. QuantumCircuit.measure_all : ไม่รับ argument และสามารถใช้กับ quantum circuits ที่ไม่มี classical bits ที่กำหนดไว้ล่วงหน้า มันสร้าง classical wires และเก็บผลการวัดตามลำดับ ตัวอย่างเช่น การวัด Qubit qiq_i จะถูกเก็บใน cbit measimeas_i) นอกจากนี้ยังเพิ่ม barrier ก่อนการวัด

  3. QuantumCircuit.measure_active : คล้ายกับ measure_all แต่วัดเฉพาะ Qubits ที่มีการดำเนินการ

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

Output of the previous code cell

qc2 = QuantumCircuit(2)
qc2.measure_all()
qc2.draw("mpl", cregbundle=False)

Output of the previous code cell

qc3 = QuantumCircuit(2)
qc3.x(1)
qc3.measure_active()
qc3.draw("mpl", cregbundle=False)

Output of the previous code cell

Parameterized circuits

อัลกอริทึมควอนตัมระยะสั้นจำนวนมากเกี่ยวข้องกับการรัน variations ของ quantum circuit จำนวนมาก เนื่องจากการสร้างและ optimize circuits ขนาดใหญ่อาจใช้ทรัพยากรการคำนวณมาก Qiskit รองรับ circuits แบบ parameterized circuits เหล่านี้มีพารามิเตอร์ที่ยังไม่ได้กำหนด และไม่จำเป็นต้องกำหนดค่าจนกว่าจะก่อนรัน circuit ซึ่งช่วยให้ย้ายการสร้างและการ optimize circuit ออกจาก main program loop ได้ เซลล์ต่อไปนี้สร้างและแสดง parameterized circuit

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 of the previous code cell

เซลล์ต่อไปนี้สร้าง variations จำนวนมากของ circuit นี้และแสดง variation หนึ่งในนั้น

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

circuits[0].draw("mpl")

Output of the previous code cell

สามารถหารายการพารามิเตอร์ที่ยังไม่ได้กำหนดของ circuit ได้ใน attribute parameters ของมัน

qc.parameters
ParameterView([Parameter(angle)])

เปลี่ยนชื่อพารามิเตอร์

โดยค่าเริ่มต้น ชื่อพารามิเตอร์สำหรับ parameterized circuit จะ prefix ด้วย 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)
Forgotten the method name? Try asking Qiskit Code Assistant.

ขั้นตอนถัดไป

คำแนะนำ
Source: IBM Quantum docs — updated 27 เม.ย. 2569
English version on doQumentation — updated 7 พ.ค. 2569
This translation based on the English version of 11 มี.ค. 2569