เหรียญควอนตัม — โมดูลเกี่ยวกับซูเปอร์โพซิชันและการอินเตอร์เฟียร์
สำหรับโมดูล Qiskit in Classrooms นี้ นักเรียนต้องมีสภาพแวดล้อม Python ที่ใช้งานได้พร้อมติดตั้งแพ็คเกจต่อไปนี้:
qiskitv2.1.0 หรือใหม่กว่าqiskit-ibm-runtimev0.40.1 หรือใหม่กว่าqiskit-aerv0.17.0 หรือใหม่กว่าqiskit.visualizationnumpypylatexenc
เพื่อตั้งค่าและติดตั้งแพ็คเกจข้างต้น ดูคู่มือ ติดตั้ง Qiskit เพื่อรัน job บนคอมพิวเตอร์ควอนตัมจริง นักเรียนจะต้องสร้างบัญชีกับ IBM Quantum® โดยทำตามขั้นตอนในคู่มือ ตั้งค่าบัญชี IBM Cloud ของคุณ
โมดูลนี้ถูกทดสอบและใช้เวลา QPU 47 วินาที นี่เป็นการประมาณเท่านั้น การใช้งานจริงของคุณอาจแตกต่างกัน
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-ibm-runtime
# Uncomment and modify this line as needed to install dependencies
#!pip install 'qiskit>=2.1.0' 'qiskit-ibm-runtime>=0.40.1' 'qiskit-aer>=0.17.0' 'numpy' 'pylatexenc'
ดูการนำเสนอโมดูลโดย Dr. Katie McCormick ด้านล่าง หรือคลิก ที่นี่ เพื่อดูบน YouTube
บทนำ
ในโมดูลนี้ เราจะสำรวจหลักการหนึ่งที่เป็นแก่นของทฤษฎีควอนตัม: ซูเปอร์โพซิชัน ในประสบการณ์ประจำวันของเรา วัตถุมักมีลักษณะที่แน่นอนเสมอ ตำแหน่ง ขนาด รูปร่าง สี — ทุกอย่างเกี่ยวกับพวกมัน — ถ ูกกำหนดและแน่นอน แม้ว่าเราผู้สังเกตยังไม่ได้วัดมัน ในโลกควอนตัม สิ่งนี้ไม่จำเป็นต้องเป็นเช่นนั้น วัตถุควอนตัมสามารถอยู่ในสิ่งที่เรียกว่า "ซูเปอร์โพซิชัน" ของสถานะที่อนุญาตแบบคลาสสิกหลายสถานะ เมื่อซูเปอร์โพซิชันถูกวัด มันจะ "collapse" แบบสุ่มไปยังหนึ่งในสถานะเหล่านั้น
ในบางแง่ การวัดสถานะซูเปอร์โพซิชันเหมือนกับการโยนเหรียญ: ไม่มีทางรู้ล่วงหน้าว่ามันจะลงด้านใด ความไม่แน่นอนพื้นฐานนี้เป็นแง่มุมที่น่าอึดอัดของกลศาสตร์ควอนตัมที่แม้แต่ Einstein ก็มีปัญหากับมัน เขาพูดอย่างโด่งดังว่า "พระเจ้าไม่ทอยลูกเต๋า" เกี่ยวกับความสุ่มนี้ แต่อย่างที่เราจะเห็น พระเจ้าที่แท้จริงทอยลูกเต๋า — และโยนเหรียญด้วย
เราจะคิดเกี่ยวกับการโยนเหรียญคลาสสิกเป็นการเปรียบเทียบกับการวัดสถานะซูเปอร์โพซิชัน และ — โดยเล่นกับ "เหรียญควอนตัม" โดยใช้ Qiskit และ Qubit บนโปรเซสเซอร์ควอนตัม IBM® — เราจะพบข้อจำกัดของการเปรียบเทียบนั้นอย่างรวดเร็ว
เหรียญคลาสสิก
มาเริ่มต้นกับเหรียญคลาสสิก โยนเหรียญ มันจะลงหัวขึ้นหรือหัวลงด้วยโอกาส 50% ของแต่ละด้าน แม้ว่า ในหลักการ คุณสามารถคำนวณว่าเหรียญจะลงด้านใดถ้าคุณรู้เงื่อนไขเริ่มต้นที่แม่นยำของเหรียญและแรง/แรงบิดของการโยน แต่ ในทางปฏิบัติ ไม่มีทางรู้ล่วงหน้าว่าเหรียญจะลงด้านใด นั่นคือเหตุผลที่เราใช้การโยนเหรียญเป็นตัวอย่างมาตรฐานของ สถานะความน่าจะเป็นแบบคลา สสิก ซึ่งผลลัพธ์นั้นโดยพื้นฐานแล้วสุ่ม เราสามารถเขียนสถานะของเหรียญก่อนที่มันจะลงเพื่อสะท้อนความน่าจะเป็น 50/50 นี้:
ที่นี่ สองพจน์แทนผลลัพธ์ที่เป็นไปได้สองอย่างของการโยน และสัมประสิทธิ์ของพวกมันแทนความน่ าจะเป็นของผลลัพธ์แต่ละอย่าง โปรดสังเกตว่าโดยทั่วไป "" (เรียกว่า "ket") ใช้แทนสถานะควอนตัม แต่ที่นี่ เรากำลังพูดถึง สถานะความน่าจะเป็นแบบคลาสสิก ดู บทเรียนที่ 1: ระบบเดี่ยว ในคอร์ส Basics of Quantum Information เพื่อเรียนรู้เพิ่มเติมเกี่ยวกับวิธีที่เราแสดงข้อมูลแบบคลาสสิกและควอนตัม
หากเราโยนเหรียญ 1000 ครั้งและบันทึกจำนวนหัวขึ้นและหัวลง เราจะได้บางอย่างแบบนี้:
# import necessary packages:
import numpy as np
import matplotlib.pyplot as plt
import random
nflips = 1000
fliplist = [random.randint(0, 1) for f in range(nflips)]
# bar plots using get_gaussian_probs function
plt.hist(fliplist)
plt.show()
เหรียญควอนตัม
เราสามารถสร้างสถานะความน่าจะเป็นที่คล้ายกันโดยใช้ Qubit บนคอมพิวเตอร์ควอนตัมของเรา เช่นเดียวกับการโยนเหรียญ Qubit ก็สามารถวัดได้ในสองสถานะที่เป็นไปได้: และ เราสร้างสถานะความน่าจะเป็น "ซูเปอร์โพซิชัน" โดยเริ่มในสถานะ แล้วใช้สิ่งที่เรียกว่า Hadamard gate กับ Qubit ซึ่งทำให้มันอยู่ในซูเปอร์โพซิชันที่เท่ากันของ และ โปรดสังเกตว่าแม้สถานะซูเปอร์โพซิชันนี้อาจดูและทำงานเหมือนเหรียญในตอนแรก แต่เราจะเห็นในไม่ช้าว่ามีมากกว่านั้น จุดประสงค ์ของโมดูลนี้คือแสดงให้คุณเห็นว่าซูเปอร์โพซิชันไม่เหมือนกับการโยนเหรียญคลาสสิก
ดังนั้น เนื่องจาก Qubit อยู่ในซูเปอร์โพซิชันที่เท่ากันของ 0 และ 1 เมื่อเราวัด Qubit จะมีโอกาส 50% ที่เราวัดได้ โอกาส 50% ที่เราวัดได้ เราเขียนสถานะนี้แตกต่างจากกรณีความน่าจะเป็นแบบคลาสสิกเล็กน้อย ด้วยเหตุผลที่จะชัดเจนในภายหลัง:
ที่นี่ ความน่าจะเป็นของการวัดสถานะทั้งสอง ไม่ใช่ เท่ากับสัมประสิทธิ์อีกต่อไป เช่นเดียวกับกรณีสถานะความน่าจะเป็นแบบคลาสสิกข้างต้น แต่เป็น กำลังสอง ของสัมประสิทธิ์ที่ให้ความน่าจะเป็นของเรา และสัมประสิทธิ์เหล่านี้แต่ละตัวตอนนี้สามารถซับซ้อนได้ หมายควา มว่าพวกมันสามารถมีทั้งส่วนจริงและส่วนจินตภาพ
แม้จะมีความแตกต่างเหล่านี้ ผลลัพธ์ของการวัดสถานะนี้โดยพื้นฐานแล้วเหมือนกับการโยนเหรียญ
from qiskit import QuantumCircuit
qcoin = QuantumCircuit(1)
qcoin.h(0)
qcoin.measure_all()
qcoin.draw("mpl")
ดังนั้น ในผล การใช้ Hadamard gate เป็นอนาล็อกของการโยนเหรียญ และเช่นเดียวกับที่เราโยนเหรียญ 1000 ครั้งเพื่อดูสถิติของเหรียญที่ลงหัวขึ้นหรือลง เราสามารถทำสิ่งที่คล้ายกันบน Qiskit กับ "เหรียญควอนตัม" ของเรา เราสามารถใช้ Qiskit primitive ที่เรียกว่า Sampler ซึ่งจะทำซ้ำ Circuit หลายครั้งเพื่อสุ่มตัวอย่างสถิติของสถานะที่ได้
ขั้นแรก เราโหลด Qiskit Runtime service และ primitives จากนั้นเราเลือก Backend ที่จะรัน Circuit
มีโค้ดด้านล่างสำหรับบันทึก credentials ของคุณในการใช้งานครั้งแรก อย่าลืมลบข้อมูลนี้ออกจาก notebook หลังจากบันทึกลงในสภาพแวดล้อมของคุณ เพื่อไม่ให้ credentials ของคุณถูกแบ่งปันโดยไม่ตั้งใจเมื่อคุณแบ่งปัน notebook ดู ตั้งค่าบัญชี IBM Cloud ของคุณ และ เริ่มต้นใช้งานบริการในสภาพแวดล้อมที่ไม่น่าเชื่อถือ สำหรับคำแนะนำเพิ่มเติม
# Load the Qiskit Runtime service
from qiskit_ibm_runtime import QiskitRuntimeService
# Syntax for first saving your token. Delete these lines after saving your credentials.
# QiskitRuntimeService.save_account(channel='ibm_quantum_platform', instance = '<YOUR_IBM_INSTANCE_CRN>', token='<YOUR-API_KEY>', overwrite=True, set_as_default=True)
# service = QiskitRuntimeService(channel='ibm_quantum_platform')
# Load saved credentials
service = QiskitRuntimeService()
# Load the Runtime primitive and session
from qiskit_ibm_runtime import (
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
)
# Use the least busy backend
backend = service.least_busy()
print(backend.name)
ibm_kingston
หากคุณไม่มีเว ลาเหลือในบัญชีของคุณ คุณยังสามารถเลือกรันบน simulator แทน เพียง uncomment โค้ดแล้วรัน cell ด้านล่างเพื่อทำเช่นนั้น:
## Use a local simulator
# from qiskit_aer import AerSimulator
## Generate a simulator that mimics the real quantum system
# backend_sim = AerSimulator.from_backend(backend)
## Import an estimator, this time from qiskit (we will import from Runtime for real hardware)
# from qiskit.primitives import BackendSamplerV2
# sampler_sim = BackendSamplerV2(backend = backend_sim)
# from qiskit.primitives import BackendEstimatorV2
# estimator_sim = BackendEstimatorV2(backend = backend_sim)
## Transpile
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qcoin)
## Execute
# On real hardware:
sampler = Sampler(mode=backend)
pubs = [qc_isa]
job = sampler.run(pubs, shots=1000)
res = job.result()
counts = res[0].data.meas.get_counts()
# or with Aer simulator with noise model from real backend
# job = sampler_sim.run([qc_isa])
# counts=job.result()[0].data.meas.get_counts()
## Analysis
from qiskit.visualization import plot_histogram
plot_histogram(counts)
ด้วย 1000 ตัวอย่างของ Circuit ข้างต้น เรามีบางอย่างที่ดูเหมือนกับ histogram เหรียญคลาสสิกอย่างสมบูรณ์ โดยมีความผันแปรทางสถิติบ้าง
นอกจากการสุ่มตัวอย่างสถิติของเหรียญควอนตัม เรายังสามารถใช้ Qiskit primitive อีกตัวที่เรียกว่า Estimator เพื่อวัดสิ่งที่เรียกว่า expectation value ของ observable ของสถานะ เพื่อแสดงให้เห็นว่า expectation value นี้คืออะไร มาใช้เหรียญคลาสสิกเป็นตัวอย่าง สมมติว่าคุณใช้เหรียญเล่นการพนัน: ทุกครั้งที่คุณโยนเหรียญและมันลงหัวขึ้น คุณได้หนึ่งดอลลาร์ แต่ทุกครั้งที่มันลงหัวลง คุณเสียหนึ่งดอลลาร์ ถ้าคุณต้องการรู้ว่าคาดว่าจะได้เงินเท่าไรต่อการโยนแต่ละครั้ง (expectation value ของ observable "เงิน") คุณจะคำนวณ:
เนื่องจากคุณมีโอกาสเท่ากันที่จะได้ดอลลาร์หรือเสียดอลลาร์ expectation value จึงเป็น $0
ในทำนองเดียวกัน กับสถานะควอนตัม เราสามารถคำนวณ expectation value ของ observable "Z" ซึ่ง Z คือเมทริกซ์ Pauli ที่มีค่า +1 และ -1 เชื่อมโยงกับสถานะ และ ตามลำดับ
from qiskit.quantum_info import Pauli
qcoin = QuantumCircuit(1)
qcoin.h(0)
# for Estimator, we do not apply the measurement to the circuit
<qiskit.circuit.instructionset.InstructionSet at 0x136df1ba0>
## Transpile
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
obs = Pauli("Z")
qc_isa = pm.run(qcoin)
obs_isa = obs.apply_layout(layout=qc_isa.layout)
## Execute
# On real hardware:
estimator = Estimator(mode=backend)
pubs = [(qc_isa, obs_isa)]
job = estimator.run([[qc_isa, obs_isa]])
res = job.result()
# On a simulator:
# job = estimator_sim.run([[qc_isa, obs_isa]])
# res=job.result()
print(res[0].data.evs)
-0.014799284701239441
เราได้ expectation value เป็น 0 ตามที่คาดไว้ นี่เป็นอีกวิธีหนึ่งในการยืนยันว่ามีความน่าจะเป็นเท่ากันในการวัด 0 และ 1 และดูเหมือนจะทำงานเหมือนการโยนเหรียญ
ณ จุดนี้ "เหรียญควอนตัม" ดูเหมือนกับเหรียญคลาสสิกทุกประการ แต่ในส่วนถัดไป เราจะทำการทดลองที่จะเผยให้เห็นความแตกต่างพื้นฐานระหว่างทั้งสอง
ควอนตัมที่เปิดเผยออกมา: การทดลองในสามมิติ
มาทำการทดลองทางความคิด: สมมติว่าคุณ โยนเหรียญขึ้นไปในอากาศ และแทนที่จะให้มันตกลงพื้น คุณมีความคล่องพอที่จะปรบมือขณะที่มันผ่านระหว่างมือและหนีบเหรียญระหว่างฝ่ามือ ตอนนี้ แทนที่เหรียญจะหัวขึ้นหรือลง มันหัวซ้ายหรือขวา
ตรวจสอบความเข้าใจของคุณ
อ่านคำถามด้านล่าง คิดคำตอบของคุณ จากนั้นคลิกสามเหลี่ยมเพื่อดูคำตอบ
ความน่าจะเป็นของแต่ละผลลัพธ์เหล่านี้คือเท่าใด หัวซ้ายหรือหัวขวา?
คำตอบ:
ความน่าจะเป็นยังคงเป็น 50-50 ไม่ควรสำคัญว่าเราเลือกมิติใดในการวัดผลลัพธ์ของการโยนเหรียญ
หวังว่าคุณตอบว่าความน่าจะเป็นของการพบหัวซ้ายหรือขวายังคงเป็น 50-50 มิติที่เลือกวัดการโยนเหรียญไม่ควรส่งผลต่อความน่าจะเป็นของผลลัพธ์
แต่สิ่งต่างๆ จะดูแตกต่างอย่างไรสำหรับเหรียญควอนตัมของเรา? มาตรวจสอบ
เราสามารถสร้างซูเปอร์โพซิชันควอนตัมในแบบเดียวกับที่เราทำครั้งที่แล้ว ด้วย Hadamard gate เพื่อวัด "หัวซ้ายหรือขวา" บนเหรียญควอนตัมของเรา เราสามารถทำสิ่งที่เราทำกับเหรียญคลาสสิก: วัดตามแกนที่แตกต่าง การวัดมาตรฐานของเราบนคอมพิวเตอร์ควอนตัมเป็นตามแกนแนวตั้ง เช่นเดียวกับการวัด "หัวขึ้นหรือลง" ปกติของเหรียญคลาสสิก แต่เราสามารถถามเหรียญควอนตัมด้วยว่ามันหัวซ้ายหรือขวา หรือเทียบเท่า ถ้ามันอยู่ในสถานะ หรือ ซึ่งชี้ตามแกน Sampler สุ่มตัวอย่างเฉพาะใน measurement basis Z แต่เราสามารถใช้ Estimator เพื่อให้ expectation value ของ X ค่าของ X คือ +1 และ -1 สำหรับสถานะ หรือ ตามลำดับ
ตรวจสอบความเข้าใจของคุณ
อ่านคำถามด้านล่าง คิดคำตอบของคุณ จากนั้นคลิกสามเหลี่ยมเพื่อดูคำตอบ
ถ้าเหรียญควอนตัมทำงานเหมือนเหรียญคลาสสิกในกรณีนี้ เราจะมีความน่าจะเป็น 50-50 ของการวัดสถานะ และ Estimator จะส่งคืน expectation value ของ X เท่าใด ถ้าเป็นเช่นนั้น?
Estimator จะส่งคืน expectation value ของ X เท่าใด ถ้าเป็นเช่นนั้น?คำตอบ:
เมื่อเรานำ X ไปใช้กับสถานะ เราได้ค่า +1 และกับสถานะ เราได้ -1 ดังนั้นถ้าเราได้การกระจาย 50-50 เราจะได้ expectation value เป็น 0
# Step 1: map problem
qcoin_lr = QuantumCircuit(1)
qcoin_lr.h(0)
obs = Pauli("X")
# Step 2: Transpile the circuit
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qcoin_lr)
obs_isa = obs.apply_layout(layout=qc_isa.layout)
# Step 3: Run the circuit on a real quantum computer
estimator = Estimator(mode=backend)
pubs = [(qc_isa, obs_isa)]
job = estimator.run([[qc_isa, obs_isa]])
res = job.result()
# Run the job on the Aer simulator with noise model from real backend
# job = estimator_sim.run([[qc_isa,obs_isa]])
# res=job.result()
# Step 4: Return the result in classical form, and analyze.
print(res[0].data.evs)
0.9985207100591716
expectation value ของ X สำหรับสถานะนี้คือ 1 ดังนั้น จึงไม่ใช่ความน่าจะเป็น 50-50 ของการวัด และ