מטבעות קוונטיים — מודול על סופרפוזיציה והתאבכות
במודול Qiskit in Classrooms הזה, התלמידים צריכים סביבת Python פועלת עם החבילות הבאות מותקנות:
qiskitv2.1.0 או חדש יותרqiskit-ibm-runtimev0.40.1 או חדש יותרqiskit-aerv0.17.0 או חדש יותרqiskit.visualizationnumpypylatexenc
להגדרת הסביבה והתקנת החבילות שלמעלה, ראו את המדריך התקנת Qiskit. כדי להריץ עבודות על מחשבים קוונטיים אמיתיים, התלמידים יצטרכו להגדיר חשבון ב-IBM Quantum® לפי השלבים במדריך הגדרת חשבון IBM Cloud שלך.
המודול הזה נבדק והשתמש ב-47 שניות של זמן QPU. זו הערכה בלבד. השימוש בפועל שלך עשוי להשתנות.
# 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'
צפו בהדרכת המודול של ד"ר קייטי מקורמיק למטה, או לחצו כאן לצפייה ב-YouTube.
מבוא
במודול הזה, נחקור אחד מהעקרונות המרכזיים שבלב התיאוריה הקוונטית: סופרפוזיציה. בחוויה היומיומית שלנו, לאובייקטים תמיד יש תכונות מוגדרות. מיקומם, גודלם, צורתם, צבעם — הכל בנ וגע אליהם — קבוע וודאי, גם אם אנחנו המתבוננים עדיין לא מדדנו אותם. בעולם הקוונטי, זה לא בהכרח המצב. אובייקט קוונטי יכול להיות במשהו שנקרא "סופרפוזיציה" של מספר מצבים קלאסיים מותרים. כשמודדים את הסופרפוזיציה, היא "תתמוטט" באקראיות לאחד מאותם מצבים.
במובנים מסוימים, מדידת מצב סופרפוזיציה דומה להטלת מטבע: אין שום דרך לדעת מראש לאיזה כיוון הוא ינחת. אי-הוודאות הבסיסית הזו היא היבט מטריד של מכניקת הקוונטים שאפילו לאיינשטיין היה קשה איתו. הוא אמר בפירוש, "אלוהים לא משחק בקוביות" על האקראיות הזו. אבל, כפי שנראה, אלוהים אכן משחק בקוביות — ומטיל מטבעות.
אנחנו הולכים לחשוב על הטלת מטבע קלאסית כאנלוגיה למדידת מצב סופרפוזיציה. ו — על ידי משחק עם "מטבע קוונטי" באמצעות Qiskit וQubit על מעבד קוונטי של IBM® — נגלה במהירה את מגבלות האנלוגיה הזו.
מטבע קלאסי
בואו נתחיל עם מטבע קלאסי. זורקים מטבע, והוא ינחת בין עץ-למעלה לעץ-למטה, עם סיכוי של 50% לכל אחד. בעוד שעקרונית, ניתן לחשב לאיזה צד ינחת המטבע אם מישהו ידע את התנאים ההתחלתיים המדויקים של המטבע ואת הכוח/המומנט של הזריקה, בפועל, אין שום דרך לדעת מראש לאיזה צד ינחת המטבע. לכן אנחנו משתמשים בהטלת המטבע כדוגמה קנונית של מצב הסתברותי קלאסי, שבו התוצאה היא בעצם אקראית. אנחנו יכולים לכתוב את מצב המטבע לפני שינחת כדי לשקף את ההסתברות הזו של 50/50:
כאן, שני האיברים מייצגים את שתי התוצאות האפשריות של הזריקה, והמקדמים שלהם מייצגים את ההסתברויות של כל אחת מהתוצאות. שימו לב שבדרך כלל, ה-"" (המכונה "קט") משמש לייצוג מצב קוונטי, אבל כאן, אנחנו מדברים על מצב קלאסי הסתברותי. ראו את שיעור 1: מערכות בודדות בקורס יסודות מידע קוונטי כדי ללמוד עוד על האופן שבו אנחנו מייצגים מידע קלאסי וקוונטי.
אם היינו מטילים מטבע 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 וה-Primitives, ואז בוחרים Backend שעליו להריץ את ה-Circuit.
יש קוד למטה לשמירת האישורים שלך בשימוש הראשון. הקפידו למחוק את המידע הזה מהמחברת לאחר שמירתו לסביבה שלכם, כדי שהאישורים שלכם לא יישתפו בטעות כשתשתפו את המחברת. ראו הגדרת חשבון 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
אם נגמר לך הזמן הזמין בחשבון שלך, תוכל גם לבחור להריץ זאת על סימולטור במקום. פשוט בטל את ה-comment על הקוד והרץ את התא למטה:
## 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 שלמעלה, יש לנו משהו שנראה בעצם זהה להיסטוגרם של המטבע הקלאסי, למעט תנודות סטטיסטיות מסוימות.
בנוסף לדגימת הסטטיסטיקה של המטבע הקוונטי, אנחנו יכולים גם להשתמש ב-Qiskit Primitive אחר שנקרא Estimator כדי למדוד את מה שנקרא ערך הציפייה של אובזרבל של המצב. כדי להמחיש מה הוא ערך הציפייה הזה, בואו נשתמש במטבע הקלאסי כדוגמה. נניח שאתה משתמש במטבע כדי להמר: בכל פעם שאתה מטיל את המטבע והוא נוחת "עץ-למעלה," אתה מרוויח דולר אחד. אבל בכל פעם שהוא נוחת "עץ-למטה," אתה מפסיד דולר אחד. אם אתה רוצה לדעת כמה כסף אתה מצפה לקבל בכל הטלה (ערך הציפייה של האובזרבל "כסף"), אז תחשב:
מכיוון שיש לך סיכוי שווה לזכות בדולר כמו להפסיד דולר, ערך הציפייה הוא $0.
באופן דומה, עם מצב קוונטי, אנחנו יכולים לחשב את ערך הציפייה של האובזרבל "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
אנחנו מקבלים ערך ציפייה של 0, כצפוי (היפה). זוהי דרך נוספת לאשר שאכן יש הסתברות שווה למדידת 0 או 1, ונראה שהתנהגות זו דומה להטלת מטבע.
בשלב זה, ה"מטבע הקוונטי" נראה בדיוק כמו המטבע הקלאסי. אבל בחלק הבא, נעשה כמה ניסויים שיחשפו את ההבדלים הבסיסיים בין השניים.
הקוונטי מתגלה: ניסוי בשלושה ממדים
בואו נעשה ניסוי מחשבתי: נניח שאתה זורק מטבע באוויר, ובמקום לתת לו ליפול לקרקע, יש לך את התיאום לכף ידיים כשהוא עובר ביניהן ולמחוץ את המטבע בין כפות ידיך. עכשיו, במקום שהמטבע יהיה עם הפנים למעלה או למטה, הוא עם הפנים שמאלה או ימינה.
בדוק את הבנתך
קרא את השאלה/ות למטה, חשוב על תשובתך, ואז לחץ על המשולש כדי לגלות את הפתרון.
מה ההסתברות לכל אחד מהתוצאות האלה, פנים שמאלה או פנים ימינה?
תשובה:
ההסתברות עדיין תהיה 50-50. לא אמורה להיות חשיבות לאיזה ממד אנחנו בוחרים למדוד את תוצאת הטלת המטבע.
בתקווה, ענית שההסתברות למצוא פנים שמאלה או ימינה עדיין היא 50-50. הממד שלאורכו מודדים את הטלת המטבע לא אמור להשפיע על ההסתברות של התוצאות.
אבל איך הדברים ייראו שונה עבור המטבע הקוונטי שלנו? בואו נבדוק.
אנחנו יכולים ליצור את הסופרפוזיציה הקוונטית שלנו באותו אופן שעשינו בפעם הקודמת, עם Hadamard Gate. כדי למדוד "פנים שמאלה או ימינה" על המטבע הקוונטי שלנו, אנחנו יכולים לעשות מה שעשינו עם המטבע הקלאסי: למדוד לאורך ציר שונה. המדידות הסטנדרטיות שלנו על המחשב הקוונטי הן לאורך הציר האנכי, ממש כמו מדידת "פנים למעלה או למטה" הרגילה של המטבע הקלאסי. אבל אנחנו גם יכולים לשאול את המטבע הקוונטי שלנו אם הוא פנים שמאלה או ימינה, או בשקילות, אם הוא נמצא במצבים או , שמצביעים לאורך ציר ה-. Sampler רק דוגם בבסיס המדידה Z, אבל אנחנו יכולים להשתמש ב-Estimator כדי לקבל את ערך ההצפייה של X. הערכים של X הם +1 ו-1- עבור המצבים או , בהתאמה.
בדוק את הבנתך
קרא את השאלה למטה, חשוב על תשובתך, ואז לחץ על המשולש כדי לגלות את הפתרון.
אם המטבע הקוונטי היה מתנהג כמו המטבע הקלאסי במקרה זה, היינו מקבלים הסתברות 50-50 למדידת המצב ב- ו-. איזה ערך הצפייה של X היינו מצפים ש-Estimator יחזיר, אם זה היה המצב?
Estimator יחזיר, אם זה היה המצב?תשובה:
כשאנחנו מפעילים X על המצב