Hello world
Package versions
โค้ดในหน้านี้พัฒนาโดยใช้ requirement ต่อไปนี้ แนะนำให้ใช้เวอร์ชันเหล่านี้หรือใหม่กว่า
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
ตัวอย่างนี้แบ่งเป็นสองส่วน ส่วนแรกจะสร้างโปรแกรมควอนตัมง่าย ๆ แล้วรันบนหน่วยประมวลผลควอนตัม (QPU) เนื่องจากงานวิจัยควอนตัมจริงต้องการโปรแกรมที่แข็งแกร่งกว่านี้มาก ในส่วนที่สอง (ขยายไปยังจำนวน Qubit ขนาดใหญ่) จะนำโปรแกรมง่าย ๆ นั้นขยายขึ้นไปสู่ระดับ utility
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib qiskit qiskit-ibm-runtime
ติดตั้งและยืนยันตัวตน
-
ถ้ายังไม่ได้ติดตั้ง Qiskit ดูคำแนะนำได้ที่คู่มือ Quickstart
-
ติดตั้ง Qiskit Runtime เพื่อรัน job บนฮาร์ดแวร์ควอนตัม:
pip install qiskit-ibm-runtime -
ตั้งค่า environment เพื่อรัน Jupyter notebook บนเครื่องของตัวเอง:
pip install jupyter
-
-
ตั้งค่าการยืนยันตัวตนเพื่อเข้าถึงฮาร์ดแวร์ควอนตัมผ่าน Open Plan ฟรี
(ถ้าได้รับอีเมลเชิญเข้าร่วมบัญชี ให้ทำตาม ขั้นตอนสำหรับผู้ใช้ที่ได้รับเชิญ แทน)
-
ไปที่ IBM Quantum Platform เพื่อเข้าสู่ระบบหรือสร้างบัญชีใหม่
สำคัญถ้าเชื่อมต่อผ่าน proxy server ต้องใช้ Qiskit Runtime v0.44.0 ขึ้นไป
-
สร้าง API key (เรียกอีกชื่อว่า API token) บน dashboard แล้วคัดลอกไปเก็บไว้ในที่ปลอดภัย
-
ไปที่หน้า Instances แล้วหา instance ที่ต้องการใช้ เลื่อนเมาส์ไปที่ CRN แล้วคลิกเพื่อคัดลอก
-
บันทึก credential ไว้บนเครื่องด้วยโค้ดนี้:
from qiskit_ibm_runtime import QiskitRuntimeService
QiskitRuntimeService.save_account(
token="<your-api-key>", # Use the 44-character API_KEY you created and saved from the IBM Quantum Platform Home dashboard
instance="<CRN>", # Optional
)
-
-
ตอนนี้ใช้โค้ด Python นี้ได้ทุกครั้งที่ต้องการยืนยันตัวตนกับ Qiskit Runtime Service:
from qiskit_ibm_runtime import QiskitRuntimeService
# Run every time you need the service
service = QiskitRuntimeService()
ถ้าใช้คอมพิวเตอร์สาธารณะหรือ environment ที่ไม่ปลอดภัย ให้ทำตาม คำแนะนำการยืนยันตัวตนแบบ manual แทน เพื่อให้ credential ปลอดภัย
สร้างและรันโปรแกรมควอนตั มง่าย ๆ
ขั้นตอนสี่ขั้นในการเขียนโปรแกรมควอนตัมด้วย Qiskit patterns คือ:
-
แมปปัญหาให้อยู่ในรูปแบบที่เป็น native ของควอนตัม
-
ปรับ Circuit และ operator ให้เหมาะสม
-
รันโดยใช้ฟังก์ชัน quantum primitive
-
วิเคราะห์ผลลัพธ์
ขั้นตอนที่ 1 แมปปัญหาให้อยู่ในรูปแบบที่เป็น native ของควอนตัม
ในโปรแกรมควอนตัม quantum Circuit คือรูปแบบ native สำหรับแทนคำสั่งควอนตัม และ operator แทน observable ที่ต้อง การวัด เมื่อสร้าง Circuit มักจะสร้าง object QuantumCircuit ใหม่ แล้วเพิ่มคำสั่งลงไปตามลำดับ
โค้ดต่อไปนี้สร้าง Circuit ที่ผลิต Bell state ซึ่งเป็นสถานะที่ Qubit สอง Qubit พันกัน (entangled) กันอย่างสมบูรณ์
Qiskit SDK ใช้การนับบิตแบบ LSb 0 โดยที่หลักที่ มีค่า หรือ สำหรับรายละเอียดเพิ่มเติม ดูที่หัวข้อ Bit-ordering in the Qiskit SDK
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorOptions
from qiskit_ibm_runtime import EstimatorV2 as Estimator
from matplotlib import pyplot as plt
# Uncomment the next line if you want to use a simulator:
# from qiskit_ibm_runtime.fake_provider import FakeBelemV2
# Create a new circuit with two qubits
qc = QuantumCircuit(2)
# Add a Hadamard gate to qubit 0
qc.h(0)
# Perform a controlled-X gate on qubit 1, controlled by qubit 0
qc.cx(0, 1)
# Return a drawing of the circuit using MatPlotLib ("mpl").
# These guides are written by using Jupyter notebooks, which
# display the output of the last line of each cell.
# If you're running this in a script, use `print(qc.draw())` to
# print a text drawing.
qc.draw("mpl")
ดู QuantumCircuit ในเอกสารสำหรับ operation ที่มีทั้งหมด
เมื่อสร้าง quantum Circuit ต้องพิจารณาด้วยว่าต้องการข้อมูลประเภทใดหลังการรัน Qiskit มีสองวิธีในการคืนค่าข้อมูล: รับ probability distribution ของชุด Qubit ที่เลือกวัด หรือรับค่าความคาดหวัง (expectation value) ของ observable เตรียม workload ให้วัด Circuit ด้วยวิธีใดวิธีหนึ่งใน Qiskit primitives (อธิบายรายละเอียดใน ขั้นตอนที่ 3)
ตัวอย่างนี้วัด expectation value โดยใช้ submodule qiskit.quantum_info ซึ่งระบุโดยใช้ operator (วัตถุทางคณิตศาสตร์ที่ใช้แทนการกระทำหรือกระบวนการที่เปลี่ยนสถานะควอนตัม) โค้ดต่อไปนี้สร้าง Pauli operator สองตัว Qubit จำนวนหก ตัว ได้แก่ IZ, IX, ZI, XI, ZZ และ XX
# Set up six different observables.
observables_labels = ["IZ", "IX", "ZI", "XI", "ZZ", "XX"]
observables = [SparsePauliOp(label) for label in observables_labels]
ที่นี่ operator อย่าง ZZ เป็นชื่อย่อสำหรับ tensor product ซึ่งหมายถึงการวัด Z บน Qubit 1 และ Z บน Qubit 0 พร้อมกัน และได้ข้อมูลเกี่ยวกับความสัมพันธ์ระหว่าง Qubit 1 และ Qubit 0 expectation value แบบนี้มักเขียนเป็น
ถ้าสถานะ entangled การวัด ควรแตกต่างจากการวัด สำหรับสถานะ entangled เฉพาะที่สร้างโดย Circuit ที่อธิบายไว้ข้างต้น การวัด ควรได้ 1 และการวัด ควรได้ศูนย์
ขั้นตอนที่ 2 ปรับ Circuit และ operator ให้เหมาะสม
เมื่อรัน Circuit บนอุปกรณ์ สิ่งสำคัญคือต้องปรับชุดคำสั่งที่ Circuit ประกอบด้วยให้เหมาะสม และลด depth โดยรวม (คร่าว ๆ คือจำนวนคำสั่ง) ของ Circuit ให้น้อยที่สุด เพื่อให้ได้ผลลัพธ์ที่ดีที่สุดโดยการลดผลกระทบจากข้อผิดพลาดและสัญญาณรบกวน นอกจากนี้ คำสั่งของ Circuit ต้องสอดคล้องกับ Instruction Set Architecture (ISA) ของ Backend และต้องพิจารณา basis Gate และการเชื่อมต่อ Qubit ของอุปกรณ์
โค้ดต่อไปนี้ instantiate อุปกรณ์จริงเพื่อส่ง job ไป และแปลง Circuit กับ observable ให้ตรงกับ ISA ของ Backend นั้น โดยต้องการให้ บันทึก credential ไว้แล้ว
service = QiskitRuntimeService()
backend = service.least_busy(simulator=False, operational=True)
# Convert to an ISA circuit and layout-mapped observables.
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)
isa_circuit.draw("mpl", idle_wires=False)
ขั้นตอนที่ 3 รันโดยใช้ quantum primitive
คอมพิวเตอร์ควอนตัมสามารถให้ผลลัพธ์แบบสุ่ม ดังนั้นมักจะเก็บตัวอย่าง output โดยการรัน Circuit หลายครั้ง สามารถประมาณค่าของ observable ได้โดยใช้คลาส Estimator Estimator เป็นหนึ่งในสอง primitive อีกตัวคือ Sampler ซึ่งใช้รับข้อมูลจากคอมพิวเตอร์ควอนตัม object เหล่านี้มีเมธอด run() ที่รันชุด Circuit, observable และ parameter (ถ้ามี) โดยใช้ primitive unified bloc (PUB)
# Construct the Estimator instance.
estimator = Estimator(mode=backend)
estimator.options.resilience_level = 1
estimator.options.default_shots = 5000
mapped_observables = [
observable.apply_layout(isa_circuit.layout) for observable in observables
]
# One pub, with one circuit to run against five different observables.
job = estimator.run([(isa_circuit, mapped_observables)])
# Use the job ID to retrieve your job data later
print(f">>> Job ID: {job.job_id()}")
>>> Job ID: d5k96q4jt3vs73ds5tgg
หลังจาก submit job แล้ว รอได้จนกว่า job จะเสร็จสมบูรณ์ใน Python instance ปัจจุบัน หรือใช้ job_id เพื่อดึงข้อมูลในภายหลัง (ดู ส่วนเกี่ยวกับการดึง job สำหรับรายละเอียด)
เมื่อ job เสร็จแล้ว ตรวจดู output ผ่าน attribute result() ของ job
# This is the result of the entire submission. You submitted one Pub,
# so this contains one inner result (and some metadata of its own).
job_result = job.result()
# This is the result from our single pub, which had six observables,
# so contains information on all six.
pub_result = job.result()[0]
# Check there are six observables.
# If not, edit the comments in the previous cell and update this test.
assert len(pub_result.data.evs) == 6
เมื่อรันโปรแกรมควอนตัมบนอุปกรณ์จริง workload ต้องรอในคิวก่อน เพื่อประหยัดเวลา ใช้โค้ดต่อไปนี้แทนเพื่อรัน workload ขนาดเล็กนี้บน fake_provider ด้วย Qiskit Runtime local testing mode โปรดทราบว่าทำได้เฉพาะ Circuit ขนาดเล็กเท่านั้น เมื่อขยายขนาดในส่วนถัดไป ต้องใช้อุปกรณ์จริง
# Use the following code instead if you want to run on a simulator:
from qiskit_ibm_runtime.fake_provider import FakeBelemV2
backend = FakeBelemV2()
estimator = Estimator(backend)
# Convert to an ISA circuit and layout-mapped observables.
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)
mapped_observables = [
observable.apply_layout(isa_circuit.layout) for observable in observables
]
job = estimator.run([(isa_circuit, mapped_observables)])
result = job.result()
# This is the result of the entire submission. You submitted one Pub,
# so this contains one inner result (and some metadata of its own).
job_result = job.result()
# This is the result from our single pub, which had five observables,
# so contains information on all five.
pub_result = job.result()[0]
ขั้นตอนที่ 4 วิเคราะห์ผลลัพธ์
ขั้นตอนการวิเคราะห์มักเป็นขั้นตอนที่อาจทำการ post-process ผลลัพธ์ เช่น การบรรเทาข้อผิดพลาดจากการวัด (measurement error mitigation) หรือ zero noise extrapolation (ZNE) อาจนำ ผลลัพธ์เหล่านี้ป้อนเข้า workflow อื่นเพื่อการวิเคราะห์เพิ่มเติม หรือเตรียมกราฟของค่าและข้อมูลสำคัญ โดยทั่วไปขั้นตอนนี้เฉพาะเจาะจงกับปัญหาของตัวเอง สำหรับตัวอย่างนี้ ให้พล็อต expectation value แต่ละค่าที่วัดได้สำหรับ Circuit
expectation value และ standard deviation สำหรับ observable ที่ระบุให้ Estimator เข้าถึงได้ผ่าน attribute PubResult.data.evs และ PubResult.data.stds ของผลลัพธ์ job หากต้องการผลลัพธ์จาก Sampler ให้ใช้ฟังก์ชัน PubResult.data.meas.get_counts() ซึ่งจะคืน dict ของการวัดในรูปแบบ bitstring เป็น key และจำนวนนับเป็นค่าที่สอดคล้องกัน สำหรับข้อมูลเพิ่มเติม ดู เริ่มต้นใช้งาน Sampler
# Plot the result
values = pub_result.data.evs
errors = pub_result.data.stds
# plotting graph
plt.plot(observables_labels, values, "-o")
plt.xlabel("Observables")
plt.ylabel("Values")
plt.show()
สังเกตว่าสำหรับ Qubit 0 และ 1 expectation value อิสระของทั้ง X และ Z เป็น 0 ในขณะที่ความสัมพันธ์ (XX และ ZZ) เป็น 1 นี่คือลักษณะเด่นของการพันกันควอนตัม (quantum entanglement)
# Make sure the results follow the claim from the previous markdown cell.
# This can happen when the device occasionally behaves strangely. If this cell
# fails, you may just need to run the notebook again.
_results = {obs: val for obs, val in zip(observables_labels, values)}
for _label in ["IZ", "IX", "ZI", "XI"]:
assert abs(_results[_label]) < 0.2
for _label in ["XX", "ZZ"]:
assert _results[_label] > 0.8
ขยายขนาดไปสู่ Qubit จำนวนมาก
ในการคำนวณเชิงควอนตัม งานในระดับ utility-scale เป็นสิ่งสำคัญมากสำหรับความก้าวหน้าในสาขานี้ งา นดังกล่าวต้องทำการคำนวณในขนาดที่ใหญ่กว่ามาก โดยทำงานกับ Circuit ที่อาจใช้ Qubit มากกว่า 100 ตัวและ Gate มากกว่า 1000 ตัว ตัวอย่างนี้แสดงให้เห็นว่าเราสามารถทำงานในระดับ utility-scale บน IBM® QPU ได้อย่างไร โดยการสร้างและวิเคราะห์ GHZ state ขนาด 100 Qubit ตัวอย่างนี้ใช้ workflow แบบ Qiskit patterns และจบด้วยการวัดค่า expectation value สำหรับแต่ละ Qubit
ขั้นตอนที่ 1 กำหนดปัญหา
เขียนฟังก์ชันที่คืนค่า QuantumCircuit ซึ่งเตรียม GHZ state แบบ -Qubit (โดยพื้นฐานคือ Bell state ที่ขยายออกไป) จากนั้นใช้ฟังก์ชันนั้นเพื่อเตรียม GHZ state แบบ 100 Qubit และรวบรวม observable ที่ต้องการวัด
def get_qc_for_n_qubit_GHZ_state(n: int) -> QuantumCircuit:
"""This function will create a qiskit.QuantumCircuit (qc) for an n-qubit GHZ state.
Args:
n (int): Number of qubits in the n-qubit GHZ state
Returns:
QuantumCircuit: Quantum circuit that generate the n-qubit GHZ state, assuming all qubits start in the 0 state
"""
if isinstance(n, int) and n >= 2:
qc = QuantumCircuit(n)
qc.h(0)
for i in range(n - 1):
qc.cx(i, i + 1)
else:
raise Exception("n is not a valid input")
return qc
# Create a new circuit with two qubits (first argument) and two classical
# bits (second argument)
n = 100
qc = get_qc_for_n_qubit_GHZ_state(n)
ต่อไป ทำการ map ไปยัง operator ที่ต้องการ ตัวอย่างนี้ใช้ ZZ operators ระหว่าง Qubit เพื่อตรวจสอบพฤติกรรมเมื่อ Qubit อยู่ห่างออกไปเรื่อยๆ ค่า expectation value ที่ไม่แม่นยำมากขึ้น (บิดเบือน) ระหว่าง Qubit ที่อยู่ห่างไกลจะเผยให้เห็นระดับของ noise ที่มีอยู่
# ZZII...II, ZIZI...II, ... , ZIII...IZ
operator_strings = [
"Z" + "I" * i + "Z" + "I" * (n - 2 - i) for i in range(n - 1)
]
print(operator_strings)
print(len(operator_strings))
operators = [SparsePauliOp(operator) for operator in operator_strings]
['ZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZI', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZ']
99
ขั้นตอนที่ 2 ปรับปัญหาให้เหมาะสมสำหรับการรันบน hardware ควอนตัม
โค้ดต่อไปนี้แปลง Circuit และ observable ให้ตรงกับ ISA ของ Backend โดยต้องการให้คุณบันทึก credentials ไว้แล้ว
service = QiskitRuntimeService()
backend = service.least_busy(
simulator=False, operational=True, min_num_qubits=100
)
pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
isa_circuit = pm.run(qc)
isa_operators_list = [op.apply_layout(isa_circuit.layout) for op in operators]
ขั้นตอนที่ 3 รันบน hardware
ส่ง job และเปิดใช้ error suppression โดยใช้เทคนิคเพื่อลด error ที่เรียกว่า dynamical decoupling ระดับ resilience ระบุว่าจะสร้างความทนทานต่อ error มากแค่ไหน ระดับที่สูงขึ้นจะให้ผลลัพธ์ที่แม่นยำมากขึ้น แต่แลกกับเวลาประมวลผลที่นานขึ้น สำหรับคำอธิบายเพิ่มเติมของ options ที่ตั้งค่าในโค้ดต่อไปนี้ ดูที่ Configure error mitigation for Qiskit Runtime
options = EstimatorOptions()
options.resilience_level = 1
options.dynamical_decoupling.enable = True
options.dynamical_decoupling.sequence_type = "XY4"
# Create an Estimator object
estimator = Estimator(backend, options=options)
# Submit the circuit to Estimator
job = estimator.run([(isa_circuit, isa_operators_list)])
job_id = job.job_id()
print(job_id)
d5k9mmqvcahs73a1ni3g
ขั้นตอนที่ 4 ประมวลผลผลลัพธ์
หลังจาก job เสร็จสิ้น ให้ plot ผลลัพธ์และสังเกตว่า ลดลงเมื่อ เพิ่มขึ้น แม้ว่าในการจำลองแบบ ideal ค่า ทั้งหมดควรเป็น 1
# data
data = list(range(1, len(operators) + 1)) # Distance between the Z operators
result = job.result()[0]
values = result.data.evs # Expectation value at each Z operator.
values = [
v / values[0] for v in values
] # Normalize the expectation values to evaluate how they decay with distance.
# plotting graph
plt.plot(data, values, marker="o", label="100-qubit GHZ state")
plt.xlabel("Distance between qubits $i$")
plt.ylabel(r"$\langle Z_i Z_0 \rangle / \langle Z_1 Z_0 \rangle $")
plt.legend()
plt.show()
กราฟก่อนหน้านี้แสดงให้เห็นว่าเมื่อระยะห่างระหว่าง Qubit เพิ่มขึ้น สัญญาณจะลดทอนลงเนื่องจากการมีอยู่ของ noise
ขั้นตอนถัดไป
- ลองทำหนึ่งใน tutorial เหล่านี้:
- การประมาณพลังงาน ground state ของ Heisenberg chain ด้วย VQE
- แก้ปัญหา optimization โดยใช้ QAOA
- ฝึก quantum kernel models สำหรับงาน machine learning
- ดูคำแนะนำการติดตั้งแบบละเอียดได้ที่คู่มือ Install Qiskit
- ถ้าไม่ต้องการติดตั้ง Qiskit ในเครื่อง ดูข้อมูลเกี่ยวกับตัวเลือกการใช้ Qiskit ใน online development environment
- ถ้าต้องการบันทึก credentials หลายบัญชีหรือระบุ options บัญชีอื่น ดูคำแนะนำแบบละเอียดได้ที่คู่มือ Save your login credentials