Paggalugad ng kawalan ng katiyakan
Para sa modyul na ito ng Qiskit in Classrooms, kailangang magkaroon ng gumaganang Python environment ang mga estudyante na may mga sumusunod na naka-install na pakete:
qiskitv2.1.0 o mas bagoqiskit-ibm-runtimev0.40.1 o mas bagoqiskit-aerv0.17.0 o mas bagoqiskit.visualizationnumpypylatexenc
Para i-set up at i-install ang mga pakete sa itaas, tingnan ang gabay na I-install ang Qiskit. Para mapatakbo ang mga trabaho sa tunay na quantum computers, kailangang mag-set up ng account sa IBM Quantum® ang mga estudyante sa pamamagitan ng pagsunod sa mga hakbang sa gabay na I-set up ang iyong IBM Cloud account.
Ang modyul na ito ay nasubok at gumamit ng 8 minuto ng QPU time. Tantiya lamang ito. Maaaring mag-iba ang iyong aktwal na paggamit. Dalawang matagal na kalkulasyon ang minarkahan bilang ganoon sa mga komento ng header at maaaring isagawa sa mga simulator kung kulang ang QPU time ng mga estudyante. Kapag inalis ang mga iyon, ang modyul ay nangangailangan lamang ng ~30 segundo ng QPU time.
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-aer 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'
Panoorin ang walkthrough ng modyul ni Dr. Katie McCormick sa ibaba, o i-click dito para manood sa YouTube.
Panimula
Malamang narinig mo na ang prinsipyo ng kawalan ng katiyakan, kahit sa labas ng iyong mga kurso sa pisika. Isang karaniwang pagpapahayag ng kawalan ng katiyakan sa pang-araw-araw na wika ay: "Sa pamamagitan ng pagtingin sa isang bagay, naiimpluwensyahan mo ito." Tiyak na totoo iyon. Ngunit isang mas pisikal na paraan ng paglalarawan ng kawalan ng katiyakan ay ang may ilang mga pisikal na obserbasyon na may hindi pagkakatugma na pumipigil sa kanilang parehong malaman nang sabay-sabay nang may di-tiyak na katumpakan. Maraming estudyante ang unang nakakatagpo ng pares ng mga hindi tugmang variable na at , ibig sabihin, ang posisyon sa isang axis na tinatawag na -axis, at ang linear momentum sa direksyong iyon, ayon sa pagkakasunod. Para sa mga variable na iyon, ang hadlang sa kawalan ng katiyakan ay nakasulat bilang Dito, ang ay tinatawag na "kawalan ng katiyakan sa ", na may parehong kahulugan bilang standard deviation sa istatistika, at maaaring tukuyin bilang Ang ay tinukoy sa parehong paraan.
Dito, hindi namin bibigyan ng patunay ang relasyong ito ng kawalan ng katiyakan; itaturo natin na ito ay naaayon sa ating pag-unawa sa mga klasikal na alon. Ibig sabihin, ang isang alon na may tunay na iisang perpektong dalas at haba ng alon ay magpapatuloy magpakailanman bilang isang perpektong sinusoid. Sa quantum mechanically, naaayon ito sa perpektong pagkaalam ng momentum ayon sa hypothesis ni de Broglie: . Ngunit para malaman ang kung saan matatagpuan ang isang particle na parang alon, ang alon na naglalarawan nito ay dapat maging mas matulis sa espasyo, tulad ng isang napakakitid na Gaussian, halimbawa. Alam natin na maaari nating ipahayag ang anumang patuloy na function, kasama ang mga gayong matulis na wave function, bilang isang Fourier series ng mga sinusoidal na function na may iba't ibang haba ng alon. Ngunit habang nagiging mas matulis ang wave function (at mas mahusay na nalalaman ang posisyon), kakailanganin natin ng mas maraming termino sa Fourier series, ibig sabihin, isang halo ng mas maraming haba ng alon (at sa gayon, sa quantum mechanically, mas maraming halaga ng momentum).
Mas simpleng sabihin: ang isang estado na may malinaw na tinukoy na momentum (isang perpektong sinusoid sa espasyo) ay may napakawalang-katiyakang posisyon. Ang isang estado na may malinaw na tinukoy na posisyon (tulad ng isang Dirac delta distribution) ay may napakawalang-katiyakang momentum.
Mayroon pang ibang mga variable na nagpapakita ng ganitong hindi pagkakatugma. Halimbawa, ang spin ng isang particle ay maaaring magkaroon ng malinaw na tinukoy na proyeksyon sa isang axis, ngunit wala na tayong nalalaman tungkol sa proyeksyon sa isang ortogonal na axis. Halimbawa ang estado (para sa isang Qubit o spin-1/2 na particle) ay may tiyak na proyeksyon sa kahabaan ng axis (ng 1 sa konteksto ng isang Qubit, at ng sa konteksto ng isang spin-1/2 na particle). Ngunit ang estadong ito ay maaaring isulat bilang isang superposisyon ng dalawang estado na ang bawat isa ay may malinaw na tinukoy na proyeksyon sa axis: o katumbas nito Ang ay may malinaw na tinukoy na proyeksyon sa , tulad din ng . Kaya kung tinukoy natin ang proyeksyon ng isang estado sa kahabaan ng axis, hindi natin alam ang proyeksyon sa kahabaan ng axis. At kung tinukoy natin ang proyeksyon sa axis, hindi natin alam ang proyeksyon sa kahabaan ng . May maliliit na pagkakaiba kapag tinalakay ito sa konteksto ng spin at ng mga Qubit. Ngunit sa pangkalahatan, ang mga eigenstate ng mga Pauli matrix ay may kawili-wiling relasyon na maaari nating tuklasin.
Sa buong araling ito, eksperimentasyon nating susuriin ang ating intuisyon para sa kawalan ng katiyakan sa mga hindi tugmang variable na ito, at ibe-verify na ang mga relasyon ng kawalan ng katiyakan ay nananatili sa mga quantum computer ng IBM®.
Simpleng pagsusuri ng intuisyon
Sa unang eksperimentong ito at sa buong modyul, gagamit tayo ng isang balangkas para sa quantum computing na kilala bilang "Qiskit patterns", na nagpapahati ng mga daloy ng trabaho sa mga sumusunod na hakbang:
- Hakbang 1: I-map ang mga klasikal na input sa isang quantum na problema
- Hakbang 2: I-optimize ang problema para sa quantum execution
- Hakbang 3: I-execute gamit ang Qiskit Runtime Primitives
- Hakbang 4: Post-processing at klasikal na pagsusuri
Karaniwan naming susundin ang mga hakbang na ito, kahit hindi namin palaging tahasang ilalabel ang mga ito.
Magsimula tayo sa pag-load ng ilang kinakailangang pakete kasama ang Runtime primitives. Pipili rin tayo ng pinaka-hindi abala na quantum computer na available sa atin.
May code sa ibaba para sa pag-save ng iyong mga kredensyal sa unang paggamit. Siguraduhing burahin ang impormasyong ito mula sa notebook pagkatapos itong i-save sa iyong environment, para hindi aksidenteng maibahagi ang iyong mga kredensyal kapag ibinabahagi mo ang notebook. Tingnan ang I-set up ang iyong IBM Cloud account at I-initialize ang serbisyo sa isang hindi pinagkakatiwalaang environment para sa karagdagang gabay.
from numpy import pi
# 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 (
Batch,
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
)
# Use the least busy backend
backend = service.least_busy(min_num_qubits=127)
print(backend.name)
ibm_sherbrooke
Kung maubusan ng available na quantum computing time ang isang estudyante sa panahon ng aralin, ang mga linya sa ibaba ay maaaring i-uncomment at gamitin para mag-set up ng simulator na bahagyang ginagaya ang gawi ng ingay ng quantum computer na pinili sa itaas.
# Import an estimator, this time from qiskit (we will import from Runtime for real hardware)
from qiskit_aer.primitives import SamplerV2, EstimatorV2
from qiskit_aer.noise import NoiseModel
# Generate the noise model from the backend properties
noise_model = NoiseModel.from_backend(backend)
noisy_sampler = SamplerV2(options={"backend_options": {"noise_model": noise_model}})
noisy_estimator = EstimatorV2(options={"backend_options": {"noise_model": noise_model}})
Maaaring maalala mo na ang isang eigenstate ng isang operator, Z, ay hindi isang eigenstate ng isa pang operator X. Maoobserbahan natin iyon ngayon, eksperimentalmente, sa pamamagitan ng paggawa ng mga sukat sa kahabaan ng at axes. Para sa sukat sa kahabaan ng , ginagamit lang natin ang qc.measure(), dahil ang mga quantum computer ng IBM ay nakaayos upang sumukat sa kahabaan ng . Ngunit para sumukat sa kahabaan ng , kailangan nating i-rotate ang sistema upang epektibong ilipat ang axis pataas sa oryentasyon kung saan tayo sumusukat. Ito ay nagagawa sa pamamagitan ng isang Hadamard Gate. Mayroong katulad na hakbang na kinakailangan para sa mga sukat sa kahabaan ng . Ang mga kinakailangang hakbang ay nakolekta dito para sa kaginhawahan:
- Para sumukat sa kahabaan ng :
qc.measure() - Para sumukat sa kahabaan ng :
qc.h()taposqc.measure() - Para sumukat sa kahabaan ng :
qc.sdg(),qc.h(),qc.staposqc.measure()
Hakbang 1: I-map ang mga klasikal na input sa isang quantum na problema
Sa kasong ito, ang hakbang ng mapping ay simpleng pagpapahayag ng mga sukat at pag-ikot na inilarawan sa itaas sa isang quantum Circuit:
# Step 1: Map
# Import some general packages
from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister
# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(2, "c")
qc = QuantumCircuit(qr, cr)
# Add a first measurement
qc.measure(qr, cr[0])
qc.barrier()
# Change basis so that measurements made on quantum computer which normally tell us about z, now tell us about x.
qc.h(qr)
# Add a second measurement
qc.measure(qr, cr[1])
qc.draw("mpl")
Hakbang 2: I-optimize ang problema para sa quantum execution
Kinukuha ng hakbang na ito ang mga operasyong gusto naming isagawa at inilalahad ang mga ito sa mga termino ng functionality ng isang tiyak na quantum computer. Ino-map din nito ang ating problema sa layout ng quantum computer.
# Step 2: 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(qc)
Hakbang 3: I-execute gamit ang Qiskit Runtime primitives
Maaari nating gamitin ang sampler para mangolekta ng istatistika sa mga sukat. Itatayo natin ang Sampler primitive para tumakbo sa isang tunay na quantum computer gamit ang mode = backend. Mayroon pang ibang mga mode para sa iba pang mga daloy ng trabaho, at gagamitin natin ang isa sa ibaba. Gagamitin ang Sampler sa pamamagitan ng pagtawag sa run() method nito na may listahan ng "pubs" (Primitive Unified Blocs). Ang bawat pub ay naglalaman ng hanggang tatlong halaga na, magkasama, nagtatukoy ng isang yunit ng computation para makumpleto ng estimator: mga Circuit, mga obserbasyon, mga parameter. Maaari ka ring magbigay ng listahan ng mga Circuit, listahan ng mga obserbasyon, at listahan ng mga parameter. Para sa karagdagang impormasyon, basahin ang Pangkalahatang-ideya ng mga PUB.
Gusto nating tumakbo sa isang tunay na quantum computer, para nagsasagawa tayo ng tunay na eksperimento sa quantum physics. Kung maubusan mo ng iyong nakatalagang oras sa mga tunay na quantum computer, maaari mong i-comment out ang code sa ibaba para sa quantum computer, at i-uncomment ang code para sa pagpapatakbo sa isang simulator.
# Step 3: Run the job on a real quantum computer
sampler = Sampler(mode=backend)
pubs = [qc_isa]
job = sampler.run(pubs)
res = job.result()
counts = res[0].data.c.get_counts()
# Run the job on the Aer simulator with noise model from real backend
# job = noisy_sampler.run([qc_isa])
# res=job.result()
# counts=res[0].data.c.get_counts()
Hakbang 4: Post-processing
Ito ay isang espesyal na simpleng kaso ng post-processing, kung saan simpleng ini-visualize natin ang mga bilang.
Pansinin na ang Qiskit ay nag-oorder ng mga Qubit, sukat, at iba pang mga bagay sa pamamagitan ng paglilista ng pinaka-mababang numero na item sa huli / sa kanan, isang kombensiyon na tinutukoy bilang "little-endian". Ibig sabihin, ang column sa ibaba na may label na "10" ay tumutukoy sa mga bilang kung saan ang unang sukat ay nagbunga ng "0", at ang pangalawang sukat ay nagbunga ng "1".
# Step 4: Post-process
from qiskit.visualization import plot_histogram
plot_histogram(counts)
Kung hindi ka naakit sa kombensyong ito, maaari mong gamitin ang marginal_counts para ma-visualize nang hiwalay ang mga resulta ng bawat sukat:
from qiskit.result import marginal_counts
plot_histogram(
marginal_counts(counts, indices=[0]), title="Counts after first measurement"
)
plot_histogram(
marginal_counts(counts, indices=[1]), title="Counts after second measurement"
)
Bilang default, ang mga estado sa Qiskit ay ini-initialize sa estado na . Kaya hindi nakakagulat na halos lahat ng unang sukat ay nagbunga ng . Ngunit pansinin, na halos pantay ang pagbabahagi sa pangalawang sukat (ang nagbibigay ng impormasyon tungkol sa mga proyeksyon ng estado sa ). Tila ang estadong nagbibigay sa atin ng napaka-predictable na resulta ng mga sukat sa kahabaan ng ay nagbibigay sa atin ng napaka-hindi-predictable na hanay ng mga resulta para sa mga sukat sa kahabaan ng . Tuklasin natin ito.
Ano ang mangyayari kung gagawin natin ang mga sukat sa kabaligtarang pagkakasunod? Maaari tayong magsimula sa paggamit ng Hadamard Gate para makakuha ng istatistika sa probabilidad ng na masukat sa . Pagkatapos para sa pangalawang sukat, magbabalik tayo sa basis gamit ang pangalawang Hadamard Gate.
# Step 1:
# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(2, "c")
qc = QuantumCircuit(qr, cr)
# Change basis to measure along x.
qc.h(qr)
qc.measure(qr, cr[0])
qc.barrier()
# Change our basis back to z and make a second measurement
qc.h(qr)
qc.measure(qr, cr[1])
qc.draw("mpl")
# Step 2: Transpile the circuit for running on a quantum computer
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
# Step 3: Run the job on a real quantum computer
sampler = Sampler(mode=backend)
pubs = [qc_isa]
job = sampler.run(pubs)
res = job.result()
counts = res[0].data.c.get_counts()
# Run the job on the Aer simulator with noise model from real backend
# job = noisy_sampler.run([qc_isa])
# res=job.result()
# counts=res[0].data.c.get_counts()
# Step 4: Post-process
from qiskit.visualization import plot_histogram
plot_histogram(counts)
Dito, tila mas kaunti na ang predictability! Dati, alam natin man lang kung ano ang magiging resulta ng unang sukat, ngayon ay mayroon tayong medyo pantay na pamamahagi sa lahat ng posibleng estado. Hindi masyadong mahirap makita kung bakit ito nangyari. Nagsimula tayo sa , na isang 50-50 na halo ng at , ayon sa Kaya malinaw na dapat mayroong pantay na probabilidad ng pagkuha ng estado na + o - (na naka-map sa 0 at 1 sa tsart) para sa unang sukat. Ang sukat sa kahabaan ng ay nagko-collapse ng estado sa alinman sa eigenstate na o sa eigenstate na . Ang bawat isa sa mga estadong iyon ay isang 50-50 na halo ng at , ayon sa Kaya kapag nasa eigenstate na ng ang sistema, malinaw na ang mga sukat sa kahabaan ng ay magbubunga ng parehong at , at gagawin ito nang may halos pantay na probabilidad.
Kaya ang ating unang halimbawa ay nagpakita sa atin na ang ilang estado ay magkakaroon ng napaka-predictable na mga resulta ng ilang sukat, ngunit hindi-predictable na mga resulta para sa iba pang mga sukat. Ang kasalukuyang halimbawa ay nagpapakita sa atin na maaari tayong gumawa nang mas masahol pa. Mayroon mga estado na maaaring magbigay sa atin ng hindi-predictable na mga resulta para sa parehong sukat, kahit na ang ginagawa lang natin ay baguhin ang pagkakasunod ng mga sukat. Suriin natin kung gaano katiyak o hindi-tiyak ang isang dami para sa isang ibinigay na estado.
Pagkalkula ng kawalan ng katiyakan
Maaari nating sukatin ito gamit ang kawalan ng katiyakan, o variance. Ang "kawalan ng katiyakan" ay karaniwang tinukuoy bilang square root ng "variance" ng isang distribusyon. Ibig sabihin, ang kawalan ng katiyakan para sa isang observable na ay tinutukoy ng at ibinibigay ng
Para sa kaso ng mga Pauli matrix, kung saan , nagiging ganito ito:
Ilapat natin ito sa isang kongkretong halimbawa. Magsimula tayo sa estado na at tukuyin natin ang kawalan ng katiyakan ng observable na sa estadong iyon.
Suriin ang iyong pag-unawa
Basahin ang tanong sa ibaba, isipin ang iyong sagot, pagkatapos i-click ang tatsulok para makita ang solusyon.
Kalkulahin ang kawalan ng katiyakan ng sa estado na , gamit ang kamay.
Sagot:
Sa ibinigay na estado, nagbubunga ito ng:
Maaari tayong lumikha ng arbitrary na paunang estado gamit ang qc.initialize(). Tandaan na ang syntax para sa imaginary unit dito ay .
# Step 1: Map the problem into a quantum circuit
from qiskit.quantum_info import SparsePauliOp
import numpy as np
obs = SparsePauliOp("X")
# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)
# Initialize the state
qc.initialize([1, 1j] / np.sqrt(2))
# Step 2: Transpile the circuit
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
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 = noisy_estimator.run([[qc_isa,obs_isa]])
# res=job.result()
# Step 4: Return the result in classical form, and analyze.
print(res[0].data.evs)
-0.02408454165642664
Ayon sa ating equation sa itaas, Manatili tayo sa parehong estado, ngunit hanapin na natin ang expectation value ng ngayon:
# Step 1: Map the problem into a quantum circuit
obs = SparsePauliOp("Z")
# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)
# Initialize the state to |+>_y
qc.initialize([1, 1j] / np.sqrt(2))
# Step 2: Transpile the circuit
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
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(pubs)
res = job.result()
# Run the job on the Aer simulator with noise model from real backend
# job = noisy_estimator.run([[qc_isa,obs_isa]])
# res=job.result()
# Step 4: Return the result in classical form, and analyze.
print(res[0].data.evs)
0.04958271968581247
Magagawa nating gawin ang parehong matematika tulad ng dati, ngunit makikita natin na ang variance ay malapit na rin sa 1.0. Masasabing . Katotohanan, ito ay halos tama para sa estadong pinili natin. Ngunit kaya pa ba nating gumawa ng mas maganda? O mas masahol pa?
Alalahanin na may uncertainty relation sa pagitan ng posisyon sa isang direksyon, at momentum sa parehong direksyon, Para sa mga variable na iyon, ang pinakakilalang anyo ay malamang
Kung ito lang ang natatandaan natin, maaari tayong matukso na isipin na ang at ay maaari ring magkaroon ng ganitong pundamental na limitasyon sa kawalan ng katiyakan. Marahil imposible para sa produkto na maabot ang zero? Subukan natin ang ibang estado at tingnan kung totoo ito. Sa pagkakataong ito, gagamitin natin ang Tingnan natin kung ano ang mangyayari. Tandaan na sa code sa ibaba, ang estimator ay maaaring tumanggap ng dalawang set ng mga circuit at observable sa iisang job submission.
# Step 1: Map the problem into a quantum circuit
obs1 = SparsePauliOp("X")
obs2 = SparsePauliOp("Z")
# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)
# Initialize the state
qc.initialize([1, 1] / np.sqrt(2))
# Step 2: Transpile the circuit
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
obs1_isa = obs1.apply_layout(layout=qc_isa.layout)
obs2_isa = obs2.apply_layout(layout=qc_isa.layout)
# Step 3: Run the circuit on a real quantum computer
with Batch(backend=backend) as batch:
estimator = Estimator(mode=batch)
pubs = [(qc_isa, obs1_isa), (qc_isa, obs2_isa)]
job = estimator.run(pubs)
res = job.result()
batch.close()
# Run the job on the Aer simulator with noise model from real backend
# job = noisy_estimator.run([[qc,obs1],[qc,obs2]])
# res=job.result()
# Step 4: Return the result in classical form, and analyze.
print("The expectation value of the first observable is: ", res[0].data.evs)
print("The expectation value of the second observable is: ", res[1].data.evs)
The expectation value of the first observable is: 1.0011036174126302
The expectation value of the second observable is: 0.0029429797670141016
Ang expectation value ng ay dapat na malapit sa 1.0, ngunit hindi dapat lumampas sa 1.0. Huwag mag-alala kung ito ay lumampas ng kaunti sa 1.0. Ito ay maiuugnay sa mga salik tulad ng noise at/o readout error. Bagaman ito ay napakahalagang paksa, maaari nating balewalain ito sa ngayon.
Nakakuha tayo ng expectation value ng na napakalapit sa 1.0 (na tumutugma sa napakababang variance para sa ). Ginagawa nitong mababa ang produkto ng dalawang variance:
Bagaman hindi eksakto ang zero, ang halagang ito ay nagiging maliit kumpara sa mga eigenvalue ng mga Pauli operator (). Baka naalala mo na ang uncertainty relation sa pagitan ng linear na posisyon at momentum ay maaaring isulat nang iba, gamit nang eksakto ang commutation relation sa pagitan ng mga operator na at :
kung saan
ang commutator ng at .
Ito ang anyo na pinaka-madaling palawigin sa mga Pauli operator. Sa pangkalahatan, para sa dalawang operator na at ,
At sa kaso ng mga Pauli matrix na at , kailangan natin ang para makalkula ang
Ipinakita natin ito dito, at iniiwan ang mga katulad na kalkulasyon sa mambabasa bilang ehersisyo: