การเรียงลำดับบิตใน Qiskit SDK
เวอร์ชันของแ พ็กเกจ
โค้ดในหน้านี้พัฒนาโดยใช้ requirements ต่อไปนี้ แนะนำให้ใช้เวอร์ชันเหล่านี้หรือใหม่กว่า
qiskit[all]~=2.3.0
ถ้ามีบิต (หรือ Qubit) จำนวน ตัว โดยปกติแต่ละบิตจะถูกกำกับหมายเลข ซอฟต์แวร์และทรัพยากรต่างๆ ต้องเลือกวิธีการเรียงลำดับบิตเหล่านี้ทั้งในหน่วยความจำคอมพิวเตอร์และการแสดงผลบนหน้าจอ
ข้อตกลงของ Qiskit
นี่คือวิธีที่ Qiskit SDK เรียงลำดับบิตในสถานการณ์ต่างๆ
Quantum Circuit
คลาส QuantumCircuit เก็บ Qubit ในรายการ
(QuantumCircuit.qubits) ดัชนีของ Qubit ในรายการนี้คือ label ของ Qubit นั้น
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit import Qubit
qc = QuantumCircuit(2)
qc.qubits[0] # qubit "0"
Qubit(QuantumRegister(2, "q"), 0)
<Qubit register=(2, "q"), index=0>
แผนภาพ Circuit
ในแผนภาพ Circuit Qubit จะอยู่บนสุด และ Qubit จะอยู่ล่างสุด สามารถเปลี่ยนสิ่งนี้ได้ด้วยอาร์กิวเมนต์ reverse_bits ของ QuantumCircuit.draw (ดู การเปลี่ยนลำดับใน Qiskit)
qc.x(1)
qc.draw()
q_0: ─────
┌───┐
q_1: ┤ X ├
└───┘
จำนวนเต็ม
เมื่อตีความบิตเป็นตัวเลข บิต คือบิตที่มีนัยสำคัญน้อยที่สุด (least significant bit) และบิต คือบิตที่มีนัยสำคัญมากที่สุด (most significant bit) ซึ่งเป็นประโยชน์ในการเขียนโค้ดเพราะแต่ละบิตมีค่า (label คือดัชนีของ Qubit ใน QuantumCircuit.qubits) ตัวอย่างเช่น Circuit ต่อไปนี้เมื่อ execute เสร็จแล้ว บิต จะเป็น 0 และบิต จะเป็น 1 ซึ่งตีความเป็นจำนวนเต็มทศนิยม 2 (วัดได้ด้วยความน่าจะเป็น 1.0)
from qiskit.primitives import StatevectorSampler as Sampler
qc.measure_all()
job = Sampler().run([qc])
result = job.result()
print(f" > Counts: {result[0].data.meas.get_counts()}")
> Counts: {'10': 1024}
สตริง
เมื่อแสดงหรือตีความรายการบิต (หรือ Qubit) เป็นสตริง บิต จะอยู่ซ้ายสุด และบิต จะอยู่ขวาสุด เพราะโดยปกติเราเขียนตัวเลขโดยให้หลักที่มีนัยสำคัญมากที่สุดอยู่ทางซ้าย และใน Qiskit บิต ถูกตีความว่าเป็น most significant bit
ตัวอย่างเช่น เซลล์ต่อไปนี้กำหนด Statevector จากสตริงของสถานะ single-qubit ในกรณีนี้ Qubit อยู่ในสถานะ และ Qubit อยู่ในสถานะ
from qiskit.quantum_info import Statevector
sv = Statevector.from_label("0+")
sv.probabilities_dict()
{np.str_('00'): np.float64(0.4999999999999999),
np.str_('01'): np.float64(0.4999999999999999)}
บางครั้งอาจเกิดความสับสนเมื่อตีความสตริงของบิต เพราะอาจคาดว่าบิตซ้ายสุดคือบิต ในขณะที่จริงๆ แล้วแทนบิต
เมทริกซ์ Statevector
เมื่อแทน statevector เป็นรายการของจำนวนเชิงซ้อน (amplitudes) Qiskit จัดเรียง amplitude เหล่านี้โดยให้ amplitude ที่ดัชนี แทน computational basis state
print(sv[1]) # amplitude of state |01>
print(sv[2]) # amplitude of state |10>
(0.7071067811865475+0j)
0j
Gate
แต่ละ Gate ใน Qiskit สามารถตีความรายการ Qubit ในแบบของตัวเอง แต่ controlled gate มักจะใช้ข้อตกลง (control, target)
ตัวอย่างเช่น เซลล์ต่อไปนี้เพิ่ม controlled-X gate โดยที่ Qubit เป็น control และ Qubit เป็น target
from qiskit import QuantumCircuit
qc = QuantumCircuit(2)
qc.cx(0, 1)
qc.draw()
q_0: ──■──
┌─┴─┐
q_1: ┤ X ├
└───┘
เมื่อนำข้อตกลงที่กล่าวมา ทั้งหมดใน Qiskit มาใช้ CX-gate นี้ทำการแปลง จึงมีเมทริกซ์ดังต่อไปนี้
การเปลี่ยนลำดับใน Qiskit
ในการวาด Circuit ด้วย Qubit ในลำดับย้อนกลับ (นั่นคือ Qubit อยู่ล่างสุด) ให้ใช้อาร์กิวเมนต์ reverse_bits ซึ่งจะมีผลเฉพาะกับแผนภาพที่สร้างขึ้นเท่านั้น และไม่ส่งผลต่อ Circuit เอง โดย X-gate ยังคงกระท ำบน Qubit
from qiskit import QuantumCircuit
qc = QuantumCircuit(2)
qc.x(0)
qc.draw(reverse_bits=True)
q_1: ─────
┌───┐
q_0: ┤ X ├
└───┘
สามารถใช้เมธอด reverse_bits เพื่อส่งคืน Circuit ใหม่ที่มี label ของ Qubit ย้อนกลับ (โดยไม่เปลี่ยนแปลง Circuit เดิม)
qc.reverse_bits().draw()
q_0: ─────
┌───┐
q_1: ┤ X ├
└───┘
โปรด ทราบว่าใน Circuit ใหม่นี้ X-gate กระทำบน Qubit
ขั้นตอนถัดไป
- ดูตัวอย่างการใช้ Circuit ในบทเรียน Grover's Algorithm
- สำรวจเอกสาร API ของ QuantumCircuit