Introducere Practică în Criteriile DiVincenzo cu Qiskit 2
Introducere
Fizicianul David DiVincenzo a conturat cinci cerințe esențiale pentru orice implementare fizică a unui calculator cuantic, plus două criterii suplimentare pentru comunicații cuantice. În acest notebook, vom experimenta fiecare criteriu DiVincenzo prin demonstrații practice în Qiskit. În loc să intrăm adânc în teorie, fiecare secțiune explică pe scurt un criteriu și oferă apoi exerciții de cod folosind Qiskit 2. Vei putea rula Circuit-uri pe simulatoare și dispozitive reale IBM Quantum pentru a explora fiecare principiu în mod practic.
Cele Cinci Criterii DiVincenzo pentru Calculul Cuantic:
- Un sistem fizic scalabil cu Qubiți bine caracterizați.
- Capacitatea de a inițializa Qubiții la o stare fiducială simplă (de ex. |00…0〉).
- Timpi lungi de decoerență (coerența Qubitului mult mai lungă decât timpul de operare al Gate-ului).
- Un set universal de Gate-uri cuantice (capabil să efectueze operații unitare arbitrare).
- Capacitate de măsurare specifică Qubitului (citirea stării fiecărui Qubit).
(DiVincenzo a descris și două criterii pentru comunicații cuantice: capacitatea de a interconverta Qubiții staționari cu cei „zburători" și de a transmite Qubiții zburători în mod fidel între locații. Le includem într-o activitate recomandată la sfârșitul acestui notebook.)
Fiecare dintre secțiunile următoare corespunde unui criteriu. Vom folosi Qiskit pentru a ilustra conceptul cu cod și experimente interactive pe care le poți încerca. De exemplu, vom vedea cum scalarea numărului de Qubiți și a adâncimii Circuit-ului afectează rezultatele (Criteriul 1), cum să resetezi și să pregătești stările Qubiților (Criteriul 2), cum să măsori Qubiții pe simulatoare vs dispozitive reale (Criteriul 4), cum compune Qiskit Gate-uri universale (Criteriul 3) și cum coerența finită (T₁, T₂) influențează calculele (Criteriul 5). La final, vei dobândi o intuiție mai profundă despre ce înseamnă în practică fiecare criteriu DiVincenzo și cum Qiskit permite experimentarea cu acestea.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy
# Install necessary packages
!pip install qiskit[visualization] qiskit-ibm-runtime qiskit-aer qiskit_ibm_runtime
1. Criteriul 1 – Qubiți Scalabili și Bine Caracterizați
Criteriul 1: „Un sistem fizic scalabil cu Qubiți bine caracterizați." Aceasta înseamnă că avem nevoie de o platformă hardware cuantică unde putem crește numărul de Qubiți și să-i controlăm în continuare cu fiabilitate. Proprietățile fiecărui Qubit (niveluri de energie, rate de erori, conectivitate etc.) trebuie să fie bine înțelese. În esență, vrem să construim Circuit-uri mai mari fără ca sistemul să se degradeze. În practică, pe măsură ce creștem numărul de Qubiți sau adâncimea Circuit-ului, erorile și decoerența se acumulează, deci demonstrarea scalabilității înseamnă și înțelegerea modului în care creșterea dimensiunii afectează performanța.
Scopul demonstrației: Utilizează Qiskit pentru a arăta efectul scalării unui Circuit (ca număr de Qubiți sau adâncime de Gate) asupra fidelității rezultatelor. Vom simula un scenariu ideal versus cu zgomot pentru a vedea cum un sistem mai mare sau un Circuit mai adânc cedează în fața decoherenței și a erorilor.
Mai întâi, să construim o stare mică entangled (starea GHZ) pe 3 Qubiți, apoi una mai mare pe 5 Qubiți, ca un test simplu de scalare. O stare GHZ de n Qubiți este . Într-o simulare ideală, măsurarea unui GHZ de n Qubiți produce doar două rezultate (toți 0 sau toți 1) cu probabilitate egală. Vom compara rezultatul ideal cu rezultatul cu zgomot pe măsură ce creștem n sau adâncimea Circuit-ului.
from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator
from qiskit.visualization import plot_histogram
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime import SamplerV2 as Sampler
# 3-qubit GHZ circuit
qc3 = QuantumCircuit(3, 3)
qc3.h(0)
qc3.cx(0, 1)
qc3.cx(1, 2)
qc3.measure([0, 1, 2], [0, 1, 2])
# 5-qubit GHZ circuit (scaling up the number of qubits)
qc5 = QuantumCircuit(5, 5)
qc5.h(0)
qc5.cx(0, range(1, 5)) # entangle qubit 0 with all others
qc5.measure(range(5), range(5))
# Transpile for a simulator backend
sim_backend = AerSimulator()
pm = generate_preset_pass_manager(backend=sim_backend, optimization_level=1)
isa_qc3 = pm.run(qc3)
isa_qc5 = pm.run(qc5)
# Run ideal simulations (no noise)
sampler = Sampler(mode=sim_backend)
job3 = sampler.run([isa_qc3], shots=1024)
result3 = job3.result()
counts3 = result3[0].data.c.get_counts()
job5 = sampler.run([isa_qc5], shots=1024)
result5 = job5.result()
counts5 = result5[0].data.c.get_counts()
print("3-qubit GHZ counts (ideal):", counts3)
plot_histogram(counts3, legend=['3-qubit ideal'], figsize=(6,4))
3-qubit GHZ counts (ideal): {'000': 531, '111': 493}

print("5-qubit GHZ counts (ideal):", counts5)
plot_histogram(counts5, legend=['5-qubit ideal'], figsize=(6,4))
5-qubit GHZ counts (ideal): {'11111': 535, '00000': 489}

Rezultat așteptat (cazul ideal): GHZ de 3 Qubiți produce în mod ideal aproximativ 50% 000 și 50% 111 în numărătoare. GHZ de 5 Qubiți produce ~50% 00000 și 50% 11111. Nu apare niciun alt șir de biți deoarece starea este ideal complet coerentă și entangled. Ar trebui să vezi două bare înalte pe histogramă pentru fiecare Circuit, corespunzând rezultatelor cu toți zero și toți unu.
În continuare, să vedem ce se întâmplă într-un mediu cu zgomot. Vom folosi capacitățile de modelare a zgomotului din Qiskit Aer pentru a imita erorile unui dispozitiv real. De exemplu, putem prelua proprietățile unui Backend IBM pentru a crea un model de zgomot care include erori de Gate, timpi finiți de Gate, relaxare a Qubitului (T₁), defazare (T₂) și erori de citire. Aici, vom folosi un Backend fals care reprezintă dispozitivul IBM Quantum Brisbane pentru a genera un model de zgomot și vom rula din nou Circuit-urile GHZ prin acesta.
Exercițiul 1a: Simulează cu Zgomot
Completează codul de mai jos pentru a simula Circuit-urile GHZ pe un simulator cu zgomot bazat pe Backend-ul FakeBrisbane. Aceasta va arăta cum degradează performanța pe măsură ce sistemul se scalează într-un mediu realist de zgomot.
from qiskit_ibm_runtime.fake_provider import FakeBrisbane
# We will reuse the ideal circuits qc3 and qc5 and their results from the previous cell.
# --- YOUR CODE HERE ---
# 1. Create a fake backend for IBM Quantum Brisbane
###brisbane_backend = ...
# 2. Create a noisy AerSimulator from the fake backend's properties
###noisy_sim = ...
# 3. Transpile the circuits for the noisy simulator (this adapts them to the device's specific gates and connectivity)
###pm = ...
###isa_qc3_noisy = ...
###isa_qc5_noisy = ...
# 4. Run the noisy simulations using the Sampler and get the counts
###sampler = ...
###job3 = ...
###result3_noisy = ...
###counts3_noisy = ...
###job5 = ...
###result5_noisy = ...
###counts5_noisy = ...
# --- END YOUR CODE ---
# This part is done for you to print and plot the results:
print("3-qubit GHZ counts (noisy):", counts3_noisy)
plot_histogram(counts3_noisy, legend=['3-qubit noisy'], figsize=(6,4))
print("5-qubit GHZ counts (noisy):", counts5_noisy)
plot_histogram(counts5_noisy, legend=['5-qubit noisy'], figsize=(6,4))
Exercițiul 1b: Rulează pe un calculator IBM Quantum real
Codul de mai jos rulează Circuit-urile GHZ pe un calculator IBM Quantum real. Aceasta va arăta cum degradează performanța pe un dispozitiv real.
# your_api_key = "deleteThisAndPasteYourAPIKeyHere"
# your_crn = "deleteThisAndPasteYourCRNHere"
# QiskitRuntimeService.save_account(
# channel="ibm_quantum_platform",
# token=your_api_key,
# instance=your_crn,
# name="fallfest-2025",
# )
# Check that the account has been saved properly
# service = QiskitRuntimeService(name="fallfest-2025")
# print(service.saved_accounts())
# We will reuse the ideal circuits qc3 and qc5 and their results from the previous cell.
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService(name="fallfest-2025")
real_backend = service.least_busy(operational=True, simulator=False)
print("Running on " + real_backend.name)
pm = generate_preset_pass_manager(backend=real_backend, optimization_level=1)
isa_qc3r = pm.run(qc3)
isa_qc5r = pm.run(qc5)
sampler = Sampler(mode=real_backend)
job3r = sampler.run([isa_qc3r], shots=1024)
result3r = job3r.result()
counts3r = result3r[0].data.c.get_counts()
job5r = sampler.run([isa_qc5r], shots=1024)
result5r = job5r.result()
counts5r = result5r[0].data.c.get_counts()
print("3-qubit GHZ counts (real):", counts3r)
plot_histogram(counts3r, legend=['3-qubit real'], figsize=(6,4))
print("5-qubit GHZ counts (real):", counts5r)
plot_histogram(counts5r, legend=['5-qubit real'], figsize=(6,4))
Rezultat așteptat (cu zgomot vs ideal): Cu zgomot, fie simulat, fie pe un dispozitiv real, starea GHZ este mai puțin perfectă. Vei vedea rezultate suplimentare în afara valorilor toți-0 și toți-1. Pentru 3 Qubiți, în loc de 100% în 000/111, o parte din probabilitate se scurge în alte șiruri de biți (de ex. 001, 010 etc.) din cauza erorilor de Gate sau a decoherenței care inversează unii Qubiți. Pentru 5 Qubiți, efectul este și mai pronunțat; Circuit-ul mai mare (mai mulți Qubiți și Gate-uri CNOT) acumulează mai multe erori, astfel încât vârfurile cu toți-0 și toți-1 sunt mai mici, iar multe alte rezultate apar. Această tendință ilustrează provocarea scalabilității: pe măsură ce scalăm, menținerea unei fidelități ridicate devine mai dificilă fără corectarea erorilor.
Concluzie: Un calculator cuantic scalabil trebuie să păstreze corelațiile cuantice pe măsură ce sistemul crește. Exemplele noastre arată cum creșterea numărului de Qubiți/adâncimii Gate-ului determină scăderea fidelității rezultatelor atunci când zgomotul este prezent. Criteriile rămase se vor ocupa de menținerea Qubiților în stare bună (erori mici, inițializabili etc.) pe măsură ce scalăm.
2. Criteriul 2 – Inițializarea Qubitului
Criteriul 2: „Capacitatea de a inițializa starea Qubiților la o stare fiducială simplă, cum ar fi |000…〉." Toți Qubiții trebuie să înceapă în mod fiabil într-o stare de referință cunoscută (de obicei starea de bază |0〉 pentru fiecare Qubit). Inițializarea este esențială pentru ca algoritmii să înceapă pe o tablă curată. În practică, pe dispozitivele IBM Quantum, fiecare Qubit este resetat automat la |0〉 la începutul fiecărei execuții a unui Circuit. Qiskit oferă, de asemenea, instrucțiuni pentru resetarea Qubiților sau pregătirea unor stări personalizate în timpul calculului.
Scopul demonstrației: Arată cum să inițializezi Qubiții în Qiskit, atât la start cât și în mijlocul Circuit-ului. Vom demonstra folosirea instrucțiunii reset și a metodelor de pregătire a stărilor.
Exercițiul 2: Pregătește o Stare Specifică
În blocul de cod de mai jos, completează QuantumCircuit pentru a pregăti starea . Aceasta înseamnă că Qubit-ul 0 trebuie să fie în starea și Qubit-ul 1 în starea . Folosește Gate-ul și instrucțiunea corespunzătoare pentru a realiza acest lucru.
from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator
# Create a circuit to initialize qubits to |10> and verify by measurement
qc_init = QuantumCircuit(2, 2)
# --- YOUR CODE HERE ---
# 1. Set qubit 1 to the |1> state
# 2. Explicitly reset qubit 0 to the |0> state
# --- END YOUR CODE ---
qc_init.measure([0, 1], [0, 1])
qc_init.draw('mpl')
# Run the circuit and check the outcome
sim_backend = AerSimulator()
pm = generate_preset_pass_manager(backend=sim_backend, optimization_level=1)
isa_qc_init = pm.run(qc_init)
sampler = Sampler(mode=sim_backend)
job = sampler.run([isa_qc_init], shots=1024)
result = job.result()
counts = result[0].data.c.get_counts()
print("Outcome of |10> state measured in Z-basis:", counts)
plot_histogram(counts)
Ar trebui să vezi 10 (binar pentru qubit1=1, qubit0=0) cu probabilitate de 100% din simulare, ceea ce înseamnă că Qubit-ul 1 a fost pregătit cu succes în |1〉 și Qubit-ul 0 în |0〉.
Acum, pentru o pregătire mai generală a stării, Qiskit permite inițializarea la stări arbitrare folosind metoda initialize. De exemplu, să pregătim un Qubit în starea , care este o stare de superpoziție, și o pereche de Qubiți în starea Bell :
import numpy as np
# Initialize a single qubit in |+> state and measure in Z-basis
qc_plus = QuantumCircuit(1, 1)
state_plus = [1/np.sqrt(2), 1/np.sqrt(2)] # amplitude for |0> and |1>
qc_plus.initialize(state_plus, 0)
qc_plus.measure(0, 0)
# Initialize two qubits in a Bell state manually
qc_bell = QuantumCircuit(2, 2)
bell_state = [1/np.sqrt(2), 0, 0, 1/np.sqrt(2)] # amplitudes for |00>,|01>,|10>,|11>
qc_bell.initialize(bell_state, [0, 1])
qc_bell.measure([0, 1], [0, 1])
# Transpile and run the initialization circuits
isa_qc_plus = pm.run(qc_plus)
job_plus = sampler.run([isa_qc_plus], shots=1024)
result_plus = job_plus.result()
counts_plus = result_plus[0].data.c.get_counts()
print("Outcome of |+> state measured in Z-basis:", counts_plus)
isa_qc_bell = pm.run(qc_bell)
job_bell = sampler.run([isa_qc_bell], shots=1024)
result_bell = job_bell.result()
counts_bell = result_bell[0].data.c.get_counts()
print("Outcome of Bell state measured in Z-basis:", counts_bell)
Outcome of |+> state measured in Z-basis: {'1': 499, '0': 525}
Outcome of Bell state measured in Z-basis: {'00': 508, '11': 516}
Rezultate așteptate: Starea |+〉 cu un singur Qubit, atunci când este măsurată, va produce 0 și 1 cu probabilitate de aproximativ 50% fiecare. Măsurarea stării Bell ar trebui s ă dea aproximativ 50% 00 și 50% 11. Dacă le observi, confirmă că inițializarea la acele stări a fost realizată cu succes.
Inițializare la mijlocul Circuit-ului: Instrucțiunea reset din Qiskit poate fi folosită în mijlocul unui Circuit pentru a reinițializa un Qubit la |0〉 în timp real. De exemplu, în codurile de corectare a erorilor sau în algoritmii iterativi, se măsoară adesea un Qubit și apoi se resetează pentru reutilizare. Operația reset este deterministă; elimină orice stare existentă și readuce Qubit-ul la starea de bază.
Exemplu pe dispozitiv: Pe hardware precum ibmq_brisbane (127 Qubiți) sau orice dispozitiv IBM, toți Qubiții încep în |0〉 implicit atunci când se execută un job. Dacă ai nevoie de o stare de pornire diferită, ai aplica Gate-uri la începutul Circuit-ului (așa cum am făcut cu X pentru a obține |1〉). Reinițializarea continuă (pentru corectarea erorilor cuantice) este un subiect activ de cercetare deoarece realizarea ei rapidă este o provocare. Din fericire, pentru utilizare de bază, capacitatea de a porni de la zero în |0…0〉 este disponibilă și am demonstrat cum să atingem și alte stări de pornire dorite.
3. Criteriul 3 – Timp de Coerență Lung (Decoerență vs Timp de Poartă)
Criteriul 3: "Timpi de decoerență relevanți lungi, mult mai lungi decât timpul de operare al porților." Aceasta abordează necesitatea ca qubiții să-și mențină starea cuantică suficient de mult timp pentru a efectua operațiile necesare. Fiecare qubit are un timp T₁ (timp de relaxare energetică, cât de repede |1〉 se descompune la |0〉) și un timp T₂ (timp de defazare, cât de repede coerența de fază relativă se pierde). Pentru ca un calculator cuantic să funcționeze, aceste scări de timp trebuie să depășească cu mult durata operațiilor de poartă.
Scopul demonstrației: Investigarea coerenței qubitului în Qiskit prin arătarea modului în care decoerența afectează rezultatele circuitelor pe măsură ce lungimea de execuție crește. Vom folosi un backend fals cu timpuri T1/T2 cunoscute pentru a simula acest efect.
Pentru a demonstra impactul coerenței finite, vom simula un experiment de decădere T1. Vom pregăti un qubit în starea |1〉, vom aștepta un timp folosind o instrucțiune delay, iar apoi vom măsura. Ne așteptăm ca probabilitatea de a măsura |1〉 să scadă pe măsură ce întârzierea crește.
# This part is done for you. We are creating a list of circuits,
# each with a different delay time.
time_delays_ns = [0, 50000, 100000, 150000, 200000, 250000, 300000] # delay durations in ns
decay_expts = []
for delay in time_delays_ns:
qc = QuantumCircuit(1, 1)
qc.x(0) # initialize qubit to |1>
if delay > 0:
qc.delay(delay, 0, unit='ns') # wait 'delay' nanoseconds
qc.measure(0, 0)
decay_expts.append(qc)
decay_expts[1].draw('mpl') # Visualize one of the circuits
Exercițiul 3: Simularea unui Experiment de Decădere T1
Acum, folosește un simulator cu zgomot bazat pe FakeVigo (care are timpi T1 de ~50-100 µs) pentru a rula aceste circuite. Simulatorul va aplica automat erorile T1/T2 în timpul instrucțiunilor delay. Transpilează circuitele pentru acest backend și execută-le.
from qiskit_ibm_runtime.fake_provider import FakeVigoV2 as FakeVigo
from qiskit_aer import AerSimulator
# --- YOUR CODE HERE ---
# 1. Create a noisy simulator from the FakeVigo backend
###sim_vigo = ...
# 2. Transpile the list of circuits for this simulator
###pm = ...
###isa_decay_expts = ...
# 3. Use the Sampler to run all the transpiled circuits in a single job
###sampler = ...
###job = ...
###result = ...
# --- END YOUR CODE ---
# This part is done for you to analyze and print the results.
for idx, (delay, qc) in enumerate(zip(time_delays_ns, isa_decay_expts)):
counts = result[idx].data.c.get_counts()
p1 = counts.get('1', 0) / 1000 # Assuming 1000 shots
print(f"Delay {delay} ns: P(qubit=1) = {p1:.3f}")
4. Criteriul 4 – Set Universal de Porți Cuantice
Criteriul 4: "Un set 'universal' de porți cuantice." Aceasta înseamnă că hardware-ul nostru trebuie să ne permită să efectuăm orice calcul cuantic prin compunerea unui set finit de porți de bază. În informatica clasică, NAND este universal; în domeniul cuantic, există multe opțiuni de seturi universale de porți (de ex. {H, T, CNOT} sau porțile native ale unui anumit dispozitiv). Dispozitivele IBM, de exemplu, au un set de operații native precum rotații arbitrare pe un singur qubit și CNOT-uri între anumiți qubiți, care împreună sunt universale. Sarcina Qiskit este adesea să compileze porțile de nivel înalt în aceste porți de bază.
Scopul demonstrației: Ilustrarea universalității porților prin arătarea modului în care Qiskit descompune porțile. Vom lua o poartă non-nativă (cum ar fi o poartă Toffoli pe 3 qubiți, CCX) și vom vedea cum se descompune în porțile de bază ale dispozitivului. Aceasta demonstrează că setul de porți furnizat este cu adevărat universal – poate produce operația mai complexă.
Mai întâi, să vedem care sunt porțile de bază pentru un backend IBM tipic. Vom interoga configurația unui dispozitiv (sau versiunea sa falsă). De exemplu, porțile de bază ale ibmq_brisbane:
Ar trebui să observi că probabilitatea P(qubit=1) scade pe măsură ce timpul de întârziere crește, urmând o curbă de decădere exponențială caracteristică relaxării T1. Aceasta demonstrează direct modul în care timpul de coerență finit duce la erori de calcul dacă circuitul rulează prea mult timp.
Impactul asupra algoritmilor: Dacă încerci un algoritm mai lung (cu multe porți secvențiale), timpul total de execuție ar putea să se apropie de T2 sau să îl depășească, provocând pierderea coerenței stării înainte de final. Acesta este motivul pentru care îmbunătățirea timpilor de coerență și accelerarea porților sunt două dintre cele mai critice obiective în cercetarea hardware-ului cuantic.
from qiskit_ibm_runtime.fake_provider import FakeBrisbane
fake_brisbane = FakeBrisbane()
print("Basis gates for ibmq_brisbane:", fake_brisbane.configuration().basis_gates)
Basis gates for ibmq_brisbane: ['ecr', 'id', 'rz', 'sx', 'x']
Aceasta ar putea afișa ceva de genul ['id', 'rz', 'sx', 'x', 'ecr']. Acestea sunt operațiile primitive pe care hardware-ul le suportă nativ (Identity/no-op, rotație RZ, poarta sqrt(X), poarta X și controlled-X). Orice altă poartă trebuie compusă din acestea. Se știe că acest set este universal pentru calculul cuantic (în esență, rotații pe un singur qubit plus o poartă de împletire pe doi qubiți formează un set universal).
Acum, ia o poartă Toffoli (CCX) ca exemplu de test. CCX inversează un qubit țintă doar dacă doi qubiți de control sunt ambii 1. Nu este o poartă nativă pe hardware-ul IBM. Qiskit furnizează o instrucțiune ccx, dar în mod intern o va descompune.
Exercițiul 4: Descompunerea unei Porți Toffoli
Completează codul de mai jos pentru a construi un circuit cu o poartă Toffoli (CCX) și apoi folosește Qiskit pentru a o descompune în porțile de bază native ale backend-ului FakeBrisbane.
from qiskit import QuantumCircuit
from qiskit_ibm_runtime.fake_provider import FakeBrisbane
# The fake_brisbane backend from the previous cell is reused here.
# --- YOUR CODE HERE ---
# 1. Create a circuit that can accommodate a Toffoli gate
###qc_toffoli = ...
# Apply a CCX gate with controls on qubits 0, 1 and target on qubit 2
# 2. Transpile the circuit to the fake Brisbane backend
###pm = ...
###isa_qc_toffoli = ...
# --- END YOUR CODE ---
print("Toffoli circuit before decomposition:")
print(qc_toffoli)
print("\nToffoli circuit after transpiling to Brisbane basis:")
# The .draw() method will now show the decomposed circuit
print(isa_qc_toffoli.draw(fold=120))
În ieșirea transpilată, ar trebui să vezi CCX înlocuit de o secvență de porți mai simple, cum ar fi rz, sx și ecr. Aceasta dovedește că porțile native sunt suficiente pentru a exprima Toffoli.
Universalitate în practică: Exercițiul de mai sus arată că o poartă complexă pe 3 qubiți a fost construită din unele mai simple. În general, orice unitar multi-qubit poate fi compus din porți pe 1 și 2 qubiți. Transpiler-ul este o componentă crucială a oricărui stack de software cuantic, deoarece face legătura între algoritmii abstracți pe care vrem să-i rulăm și operațiile fizice pe care un anumit dispozitiv cuantic le poate efectua efectiv.
Exemplu de dispozitiv: Dispozitivul ibmq_brisbane folosește arhitectura Eagle cu porțile de bază prezentate mai sus. Aceasta înseamnă că orice algoritm trimis la acele dispozitive va fi convertit în secvențe ale acelor operații. Acest criteriu se referă în esență la controlabilitate; avem suficiente comenzi pentru a efectua orice operație necesară pe qubiții noștri.
5. Criteriul 5 – Măsurarea Qubitului
Criteriul 5: "O capacitate de măsurare specifică qubitului." Starea fiecărui qubit trebuie să fie măsurabilă (de obicei în baza computațională, |0〉 sau |1〉). Cu alte cuvinte, după rularea unui circuit cuantic, trebuie să putem citi fiecare qubit ca un bit clasic de 0/1. Acest criteriu se referă la a avea detectori fiabili pentru fiecare qubit și capacitatea de a selecta ce qubiți să măsori.
Scopul demonstrației: Arată cum să efectuezi măsurători în Qiskit pe simulatoare și dispozitive reale, și evidențiază diferențele (cum ar fi zgomotul de măsurare). Vom măsura câțiva qubiți în diverse stări și vom examina rezultatele. De asemenea, vom demonstra cum pot apărea erori de citire prin compararea rezultatelor simulatorului cu cele ale hardware-ului.
Mai întâi, un exemplu simplu de măsurare:
qc_measure = QuantumCircuit(2, 2)
qc_measure.x(0) # qubit 0 -> |1>, qubit 1 stays |0>
qc_measure.measure([0, 1], [0, 1])
qc_measure.draw('mpl')
sim_backend = AerSimulator()
pm = generate_preset_pass_manager(backend=sim_backend, optimization_level=1)
isa_qc_measure = pm.run(qc_measure)
job = sampler.run([isa_qc_measure], shots=1000)
result = job.result()
counts = result[0].data.c.get_counts()
print("Simulator measurement counts:", counts)
Simulator measurement counts: {'01': 1000}
Ne așteptăm la 1000 de numărări de 01 pe simulator. Acum, să vedem eroarea de măsurare în acțiune prin simularea sa. Putem adăuga o eroare de citire la simulatorul nostru Aer. Qiskit Aer ne permite să definim o ReadoutError și să o atașăm qubiților dintr-un model de zgomot.
Exercițiul 5: Simularea Erorii de Citire
Completează codul pentru a defini un model simplu de eroare de citire în care fiecare qubit are o șansă de 2% de a fi măsurat incorect (un 0 este citit ca 1, sau un 1 ca 0). Apoi, rulează circuitul de măsurare cu acest model de zgomot.
from qiskit_aer.noise import NoiseModel, ReadoutError
# --- YOUR CODE HERE ---
# 1. Define a 2% readout error for each single qubit.
# The format is a list of lists of probabilities: [[P(0|0), P(1|0)], [P(0|1), P(1|1)]]
# P(A|B) is the probability of measuring A given the state was |B>.
###ro_error = ...
# 2. Create a new noise model
###noise_model_ro = ...
# 3. Add the readout error to all qubits in the noise model
... # Hint: Use the add_all_qubit_readout_error method
# --- END YOUR CODE ---
sim_backend.set_options(noise_model=noise_model_ro)
pm = generate_preset_pass_manager(backend=sim_backend, optimization_level=1)
isa_qc_measure = pm.run(qc_measure)
# Run the measurement circuit with readout noise
sampler = Sampler(mode=sim_backend)
job = sampler.run([isa_qc_measure], shots=1024)
result = job.result()
counts = result[0].data.c.get_counts()
print("Simulation with 2% readout error:", counts)
Această ieșire simulată va arăta câteva numărări eronate (precum 11, 00, 10) similare cu ceea ce ar putea produce hardware-ul real, demonstrând impactul măsurătorilor imperfecte.
Exemplu de dispozitiv: Pe un dispozitiv real precum ibmq_brisbane, ai putea rula același circuit și ai vedea probabil numărări non-nule similare pentru rezultatele incorecte. Datele de calibrare ale dispozitivului listează o eroare de citire pentru fiecare qubit. Capacitatea de a ținti și citi qubiți specifici este crucială, iar înțelegerea caracteristicilor lor de eroare este esențială pentru obținerea unor rezultate semnificative. Rularea pe un dispozitiv real a fost demonstrată în Exercițiul 1b: Rulare pe un calculator IBM Quantum real.
Criteriile Comunicării Cuantice (Qubiți Zburători)
DiVincenzo a mai listat două criterii specifice comunicării cuantice, importante dacă se construiește un calculator cuantic în rețea:
- Capacitatea de a interconverta qubiți staționari și zburători. (De ex., maparea unui qubit dintr-un procesor pe un foton care poate călători.)
- Capacitatea de a transmite fidel qubiți zburători între locații. (De ex., trimiterea unui foton qubit printr-o fibră fără pierderea informației cuantice.)
Acestea depășesc utilizarea standard a Qiskit, deoarece Qiskit se ocupă în principal de qubiți staționari pe un cip. Cu toate acestea, putem ilustra conceptul acestor criterii cu un exemplu simplu: teleportarea cuantică. Teleportarea arată conversia stării unui qubit staționar în informații transportate de o pereche împletită (partea „zburătoare") și comunicare clasică, care este apoi utilizată pentru a reconstitui starea pe un alt qubit staționar din altă locație.
Activitate recomandată: Parcurge modulul Quantum Teleportation din Qiskit in Classrooms
Modulul Quantum Teleportation din Qiskit in Classrooms, realizat de Dr. Katie McCormick, te va ghida prin unul dintre cele mai fascinante protocoale din informația cuantică: teleportarea cuantică, prin care o stare cuantică (un qubit) este trimisă de la Alice la Bob folosind împletire și doar doi biți clasici. Vei învăța procedura completă de teleportare pas cu pas — cum să pregătești perechea Bell împletită, cum să efectuezi o măsurare în baza Bell de partea lui Alice, cum să transmiți rezultatele clasice și cum să aplici poarta cuantică corectă pe qubit-ul lui Bob pentru a recupera perfect starea originală. Pe parcurs, vei explora de ce teleportarea informației unui qubit nu încalcă teorema de non-clonare și nici nu depășește viteza luminii. Prin exerciții practice folosind hardware-ul IBM Quantum sau simulatoare, vei dobândi o înțelegere practică a măsurătorilor, a împletirii și a controlului feed-forward în acțiune.
Stăpânind teleportarea cuantică, vei înțelege cum să codifici, transmiți și recuperezi informații cuantice între noduri distincte — punând bazele pentru rețele cuantice, sisteme de repetoare, scheme de comunicare securizată și calcul cuantic modular scalabil.
Cum se leagă aceasta de criteriile 6 & 7: Într-o rețea cuantică reală, perechea împletită partajată ar fi creată prin distribuirea qubiților „zburători" (cum ar fi fotonii) între locațiile lui Alice și Bob (Criteriul 7: transmisie fidelă). Protocolul de teleportare în sine servește apoi ca o modalitate de a mapa starea qubitului staționar al lui Alice pe jumătatea sa din perechea împletită, „trimițând" efectiv starea la Bob (Criteriul 6: interconversie). Qiskit ne permite să simulăm perfect logica protocolului, oferind un model conceptual pentru modul în care aceste criterii sunt îndeplinite în arhitecturile de comunicare.
Concluzie și Rezumat
Am conceput o serie de exerciții orientate spre cod pentru a ilustra criteriile DiVincenzo folosind Qiskit. Prin aceste exemple practice, ai explorat modul în care o platformă reală de calcul cuantic îndeplinește fiecare cerință:
- Scalabilitate: construirea circuitelor pe mai mulți qubiți și înțelegerea scalării zgomotului.
- Inițializare: utilizarea resetărilor și a preparării stărilor pentru a porni în mod fiabil calculele în stări cunoscute.
- Porți Universale: transpilarea operațiilor complexe în porțile de bază ale unui dispozitiv, dovedind că putem efectua orice calcul.
- Măsurare: citirea qubiților și gestionarea erorilor realiste de citire.
- Coerență: observarea efectului T₁, T₂ finit asupra fidelității algoritmilor și nevoia ca operațiile să fie rapide în raport cu decoerența.
Pentru completitudine, am atins și aspectele comunicării cuantice prin intermediul modulului Quantum Teleportation din Qiskit in Classrooms, legând ultimele două criterii (qubiți zburători).
În final, merită remarcat cum se reunesc aceste criterii într-un calculator cuantic real, precum cel al IBM. Un dispozitiv precum ibmq_brisbane are 127 de qubiți superconductori (Criteriul 1), fiecare pornind în |0〉 (Criteriul 2), cu un set de porți calibrat și compilatoare pentru universalitate (Criteriul 4), rezonatoare de citire cu microunde pentru fiecare qubit (Criteriul 5), și timpi de coerență de ordinul sutelor de microsecunde față de operații de nanosecunde (Criteriul 3). Pentru experimente de rețele cuantice, IBM și alții explorează transducția microunde-optică pentru qubiții zburători și împletirea qubiților la distanță (Criteriile 6 & 7); acestea sunt domenii active de cercetare.
Completând exercițiile din acest notebook, nu doar că ai văzut definițiile criteriilor DiVincenzo, ci le-ai atins prin cod; construind intuiție despre ce înseamnă fiecare cerință pentru hardware-ul și algoritmii cuantici reali. Nu ezita să extinzi aceste experimente și programare cuantică fericită!