การลดความลึกของ Circuit ด้วย AQC-Tensor Qiskit addon
ใน notebook นี้ เราจะทำตามขั้นตอนของ Qiskit pattern โดยใช้ การคอมไพล์ควอนตัมเชิงประมาณด้วย tensor networks (AQC-Tensor) เ พื่อให้ได้ความลึกของ Circuit ที่ต่ำกว่าที่จำเป็นต้องใช้ตามปกติสำหรับการทำ Trotter evolution
ขั้นตอนที่เราจะดำเนินการมีดังนี้:
- ขั้นตอนที่ 1: แมปสู่ปัญหาควอนตัม
- กำหนด Hamiltonian และ observable(s) ของปัญหา
- สร้าง target tensor-network state สำหรับส่วนเริ่มต้นของ Circuit
- สร้าง Circuit ที่มีความลึกต่ำเพื่อประมาณส่วนที่กำลังถูกบีบอัด
- สร้าง ansatz ทั่วไปจาก Circuit นั้น
- ปรับพารามิเตอร์ให้ ansatz ใกล้เคียงกับ target มากที่สุดเท่าที่จะทำได้
- เพิ่ม Trotter steps ถัดมาต่อท้าย ansatz ที่ปรับแล้ว
- ขั้นตอนที่ 2: ปรับแต่งสำหรับฮาร์ดแวร์เป้าหมาย
- Transpile Circuit สำหรับฮาร์ดแวร์
- ขั้นตอนที่ 3: รันการทดลอง
- ใช้ fake backend เพื่อความสะดวก
- ขั้นตอนที่ 4: สร้างผลลัพธ์คืน
- ไม่จำ เป็น แต่เราแค่แสดงค่า observable ที่วัดได้
ขั้นตอนที่ 1: แมปสู่ quantum circuit และ operator
ตั้งค่า Hamiltonian ของโมเดลและ observable
ใน notebook นี้ เราใช้ Ising model บนวงกลมที่มี 10 ตำแหน่ง:
โดยที่เงื่อนไขขอบเขตแบบวนรอบหมายความว่า สำหรับ จะได้ , คือความแข็งแกร่งของการจับคู่ระหว่างสองตำแหน่ง และ คือสนามแม่เหล็กภายนอก
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-addon-aqc-tensor qiskit-addon-utils qiskit-ibm-runtime quimb scipy
from qiskit.transpiler import CouplingMap
from qiskit_addon_utils.problem_generators import generate_xyz_hamiltonian
# Generate some coupling map to use for this example
coupling_map = CouplingMap.from_heavy_hex(3, bidirectional=False)
# Choose a 10-qubit circle on this coupling map
reduced_coupling_map = coupling_map.reduce([0, 13, 1, 14, 10, 16, 4, 15, 3, 9])
# Get a qubit operator describing the Ising field model
hamiltonian = generate_xyz_hamiltonian(
reduced_coupling_map,
coupling_constants=(0.0, 0.0, 1.0),
ext_magnetic_field=(0.4, 0.0, 0.0),
)
observable ที่เราจะวัดคือค่าแม่เหล็กรวม (total magnetization)
from qiskit.quantum_info import SparsePauliOp
L = reduced_coupling_map.size()
observable = SparsePauliOp.from_sparse_list([("Z", [i], 1 / L / 2) for i in range(L)], num_qubits=L)
กำหนดขอบเขตที่จะจำลองแบบคลาสสิก
เป้าหมายหลักของเราคือการจำลอง time evolution ของ Hamiltonian โมเดลข้างต้น โดยใช้ Trotter evolution ซึ่งเราแบ่งออกเป็นสองส่วน:
- ส่วนเริ่มต้นที่สามารถจำลองได้ด้วย matrix product states (MPS) เราจะ "คอมไพล์" ส่วนนี้โดยใช้ AQC ตามที่นำเสนอใน https://arxiv.org/abs/2301.08609
- ส่วนถัดไปของ Circuit ที่จะรันบนฮาร์ดแวร์ เราวางแผนจะใช้ AQC-Tensor บีบอัด Circuit ของ time evolution จนถึงเวลา จากนั้นจึง evolve ต่อโดยใช้ Trotter steps ปกติจนถึง
สร้าง Circuit ก่อนและหลังจุดแบ่ง
เมื่อเลือกที่จะแบ่งที่ แล้ว เราจะสร้าง Circuit สองตัว:
- Circuit แบบ "target" สำหรับส่วน AQC ของ evolution ตั้งแต่ ถึง เนื่องจากส่วนนี้ถูกจำลองด้วย tensor-network simulator จำนวน layer จึงมีผลต่อเวลาการรันเพียงปัจจัยคงที่เท่านั้น ดังนั้นเราอาจใช้จำนวน layer มากๆ เพื่อลด Trotter error
from qiskit.synthesis import SuzukiTrotter
from qiskit_addon_utils.problem_generators import generate_time_evolution_circuit
aqc_evolution_time = 4.0
aqc_target_num_trotter_steps = 45
aqc_target_circuit = generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(reps=aqc_target_num_trotter_steps),
time=aqc_evolution_time,
)
- Circuit ของ evolution ถัดมา ซึ่ง evolve จาก ถึง เนื่องจากส่วนนี้รันบนฮาร์ดแวร์ควอนตัม จึงควรใช้จำนวน Trotter layer น้อยที่สุดเท่าที่จะทำได้
subsequent_evolution_time = 1.0
subsequent_num_trotter_steps = 5
subsequent_circuit = generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(reps=subsequent_num_trotter_steps),
time=subsequent_evolution_time,
)
เพื่อการเปรียบเทียบในภายหลัง ลองสร้าง Circuit ที่สามตัวด้วย นั่นคือ Circuit ที่ evolve ด้วย aqc_evolution_time แต่มี evolution time ต่อ Trotter step เท่ากับ Circuit ถัดมา นี่คือ Circuit ที่เราจะต้องทำงานด้วยหากไม่ได้ใช้จำนวน Trotter steps มากๆ สำหรับ target circuit เราจะเรียกมันว่า comparison circuit
aqc_comparison_num_trotter_steps = int(
subsequent_num_trotter_steps / subsequent_evolution_time * aqc_evolution_time
)
aqc_comparison_num_trotter_steps
20
comparison_circuit = generate_time_evolution_circuit(
hamiltonian,
synthesis=SuzukiTrotter(reps=aqc_comparison_num_trotter_steps),
time=aqc_evolution_time,
)