การจำลองแบบแม่นยำและแบบมีสัญญาณรบกวนด้วย Qiskit Aer primitives
เวอร์ชันของแพ็กเกจ
โค้ดในหน้านี้พัฒนาด้วยข้อกำหนดต่อไปนี้ แนะนำให้ใช้เวอร์ชันเหล่านี้หรือใหม่กว่า
qiskit[all]~=2.5.2
qiskit-aer~=0.17
การจำลองแบบแม่นยำด้วย Qiskit SDK primitives แสดงวิธีใช้ reference primitives ที่มาพร้อมกับ Qiskit เพื่อทำการจำลองวงจรควอนตัมแบบแม่นยำ โปรเซสเซอร์ควอนตัมที่มีอยู่ในปัจจุบันมีความผิดพลาด หรือสัญญาณรบกวน ดังนั้นผลลัพธ์ของการจำลองแบบแม่นยำจึงไม่จำเป็นต้องสะท้อนผลลัพธ์ที่คุณคาดว่าจะได้เมื่อรันวงจรบนฮาร์ดแวร์จริง แม้ว่า reference primitives ใน Qiskit จะไม่รองรับการจำลองสัญญาณรบกวน แต่ Qiskit Aer มีการใช้งาน primitives ที่รองรับการจำลองสัญญาณรบกวน Qiskit Aer เป็นตัวจำลองวงจรควอนตัมประสิทธิภาพสูงที่คุณสามารถใช้แทน reference primitives เพื่อประสิทธิภาพที่ดีกว่าและฟีเจอร์ที่มากกว่า มันเป็นส่วนหนึ่งของ Qiskit Ecosystem ในบทความนี้ เราจะสาธิตการใช้ Qiskit Aer primitives สำหรับการจำลองแบบแม่นยำและแบบมีสัญญาณรบกวน
- ต้องใช้
qiskit-aerv0.14 หรือใหม่กว่า - แม้ Qiskit Aer primitives จะใช้อินเทอร์เฟซของ primitive แต่ไม่ได้ให้ options เหมือนกับ IBM Quantum primitives ยกตัวอย่างเช่น Resilience level ไม่มีให้ใช้กับ Qiskit Aer primitives
- ดู เอกสาร AerSimulator สำหรับรายละเอียดเกี่ยวกับตัวเลือกวิธีการจำลองที่ Aer รองรับ
หากต้องการสำรวจการจำลองแบบ exact และแบบมี noise ให้สร้าง circuit ตัวอย่างบนแปด qubits:
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-aer
from qiskit.circuit.library import efficient_su2
n_qubits = 8
circuit = efficient_su2(n_qubits)
circuit.draw("mpl")
วงจรนี้มีพารามิเตอร์ที่แทนมุมการหมุนสำหรับเกต และ เมื่อจำลองวงจรนี้ เราจำเป็นต้องระบุค่าที่ชัดเจนสำหรับพารามิเตอร์เหล่านี้ ในเซลล์ถัดไป เราจะระบุค่าสำหรับพารามิเตอร์เหล่านี้และใช้ primitive Estimator จาก Qiskit Aer เพื่อคำนวณค่าคาดหวังที่แม่นยำของ observable
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_aer import AerSimulator
from qiskit_aer.primitives import EstimatorV2 as Estimator
observable = SparsePauliOp("Z" * n_qubits)
params = [0.1] * circuit.num_parameters
exact_estimator = Estimator()
# The circuit needs to be transpiled to the AerSimulator target
pass_manager = generate_preset_pass_manager(3, AerSimulator())
isa_circuit = pass_manager.run(circuit)
pub = (isa_circuit, observable, params)
job = exact_estimator.run([pub])
result = job.result()
pub_result = result[0]
exact_value = float(pub_result.data.evs)
exact_value
0.8870140234256602
ตอนนี้ มาเริ่มต้นโมเดลสัญญาณรบกวนที่รวมความผิดพลาดแบบ depolarizing 2% บนทุกเกต CX ในทางปฏิบัติ ความผิดพลาดที่เกิดจากเกตสองคิวบิต ซึ่งในที่นี้คือเกต CX เป็นแหล่งความผิดพลาดหลักเมื่อรันวงจร ดู สร้างโมเดลสัญญาณรบกวน สำหรับภาพรวมของการสร้างโมเดลสัญญาณรบกวนใน Qiskit Aer
ในเซลล์ถัดไป เราจะสร้าง Estimator ที่รวมโมเดลสัญญาณรบกวนนี้และใช้เพื่อคำนวณค่าคาดหวังของ observable
from qiskit_aer.noise import NoiseModel, depolarizing_error
noise_model = NoiseModel()
cx_depolarizing_prob = 0.02
noise_model.add_all_qubit_quantum_error(
depolarizing_error(cx_depolarizing_prob, 2), ["cx"]
)
noisy_estimator = Estimator(
options=dict(backend_options=dict(noise_model=noise_model))
)
job = noisy_estimator.run([pub])
result = job.result()
pub_result = result[0]
noisy_value = float(pub_result.data.evs)
noisy_value
0.7247404214143528
ดังที่คุณเห็น ค่าคาดหวังเมื่อมีสัญญาณรบกวนนั้นค่อนข้างห่างไกลจากค่าที่ถูกต้อง ในทางปฏิบัติ คุณสามารถใช้เทคนิคการลดผลกระทบจากความผิดพลาดหลายรูปแบบเพื่อรับมือกับผลของสัญญาณรบกวนได้ แต่การกล่าวถึงรายละเอียดของเทคนิคเหล่านี้อยู่นอกขอบเขตของบทความนี้
เพื่อให้เข้าใจคร่าวๆ ว่าสัญญาณรบกวนส่งผลต่อผลลัพธ์สุดท้ายอย่างไร ลองพิจารณาโมเดลสัญญาณรบกวนของเรา ซึ่งเพิ่มความผิดพลาดแบบ depolarizing 2% ให้กับแต่ละเกต CX ความผิดพลาดแบบ depolarizing ที่มีความน่าจะเป็น ถูกกำหนดให้เป็นช่องสัญญาณควอนตัม ที่มีการกระทำต่อไปนี้บนเมทริกซ์ความหนาแน่น :
โดยที่ คือจำนวนคิวบิต ในกรณีนี้คือ 2 นั่นคือ ด้วยความน่าจะเป็น สถานะจะถูกแทนที่ด้วยสถานะผสมอย่างสมบูรณ์ และสถานะจะคงอยู่ด้วยความน่าจะเป็น หลังจากการใช้ช่องสัญญาณ depolarizing ครั้ง ความน่าจะเป็นที่สถานะจะคงอยู่จะเป็น ดังนั้น เราคาดว่าความน่าจะเป็นในการรักษาสถานะที่ถูกต้องเมื่อสิ้นสุดการจำลองจะลดลงแบบเอ็กซ์โพเนนเชียลตามจำนวนเกต CX ในวงจรของเรา
ลองนับจำนวนเกต CX ในวงจรของเราและคำนวณ เราจะเรียก count_ops เพื่อรับพจนานุกรมที่แมปชื่อเกตไปยังจำนวน และดึงรายการสำหรับเกต CX
cx_count = circuit.count_ops()["cx"]
(1 - cx_depolarizing_prob) ** cx_count
0.6542558123199923
ค่านี้ 65% ให้การประมาณคร่าวๆ ของความน่าจะเป็นที่สถานะสุดท้ายของเราถูกต้อง เป็นการประมาณแบบระมัดระวังเนื่องจากไม่ได้คำนึงถึงสถานะเริ่มต้นของการจำลอง
เซลล์โค้ดต่อไปนี้แสดงวิธีใช้ primitive Sampler จาก Qiskit Aer เพื่อสุ่มตัวอย่างจากวงจรที่มีสัญญาณรบกวน เราจำเป็นต้องเพิ่ม measurements ให้กับวงจรก่อนรันด้วย primitive Sampler
from qiskit_aer.primitives import SamplerV2 as Sampler
measured_circuit = circuit.copy()
measured_circuit.measure_all()
noisy_sampler = Sampler(
options=dict(backend_options=dict(noise_model=noise_model))
)
# The circuit needs to be transpiled to the AerSimulator target
pass_manager = generate_preset_pass_manager(3, AerSimulator())
isa_circuit = pass_manager.run(measured_circuit)
pub = (isa_circuit, params, 100)
job = noisy_sampler.run([pub])
result = job.result()
pub_result = result[0]
pub_result.data.meas.get_counts()
{'00000110': 1,
'11100000': 1,
'00000000': 59,
'11000000': 3,
'11110000': 1,
'00010100': 1,
'00100000': 2,
'00000011': 3,
'00110010': 1,
'00110101': 1,
'00000101': 1,
'11000010': 1,
'10000000': 4,
'00110000': 1,
'01000000': 2,
'00010000': 2,
'00000100': 2,
'01010000': 1,
'00001000': 2,
'00011110': 1,
'00001010': 1,
'01111000': 1,
'10100000': 1,
'01100000': 1,
'00001100': 2,
'00010110': 1,
'01001000': 1,
'00101000': 1,
'00000010': 1}
ขั้นตอนถัดไป
- สำหรับการจำลอง circuit ขนาดเล็กและเรียบง่าย ดูที่ การจำลองแบบแม่นยำด้วย Qiskit primitives
- อ่านเอกสาร Qiskit Aer