Vai al contenuto principale

Introduzione Pratica ai Criteri di DiVincenzo con Qiskit 2

Introduzione

Il fisico David DiVincenzo ha delineato cinque requisiti fondamentali per qualsiasi implementazione fisica di un computer quantistico, più due criteri aggiuntivi per la comunicazione quantistica. In questo notebook, sperimenteremo ciascun criterio di DiVincenzo attraverso dimostrazioni pratiche con Qiskit. Invece di approfondire la teoria, ogni sezione spiega brevemente un criterio e poi fornisce esercizi di codice usando Qiskit 2. Eseguirai Circuit su simulatori e veri dispositivi IBM Quantum per esplorare ogni principio in modo pratico.

I Cinque Criteri di DiVincenzo per il Calcolo Quantistico:

  1. Un sistema fisico scalabile con Qubit ben caratterizzati.
  2. Capacità di inizializzare i Qubit a un semplice stato fiduciale (es. |00…0〉).
  3. Tempi di decoerenza lunghi (la coerenza del Qubit deve essere molto più lunga del tempo di operazione del Gate).
  4. Un insieme universale di Gate quantistici (in grado di eseguire operazioni unitarie arbitrarie).
  5. Capacità di misura specifica per Qubit (leggere lo stato di ciascun Qubit).

(DiVincenzo ha descritto anche due criteri per la comunicazione quantistica: la capacità di interconvertire Qubit stazionari e "volanti", e di trasmettere fedelmente i Qubit volanti tra posizioni diverse. Li includiamo in un'attività consigliata alla fine di questo notebook.)

Ciascuna delle sezioni seguenti corrisponde a un criterio. Useremo Qiskit per illustrare il concetto con codice ed esperimenti interattivi che puoi provare. Ad esempio, vedremo come l'aumento del numero di Qubit e della profondità del Circuit influisce sui risultati (Criterio 1), come reimpostare e preparare gli stati dei Qubit (Criterio 2), come misurare i Qubit su simulatori rispetto a dispositivi reali (Criterio 4), come Qiskit compone Gate universali (Criterio 3), e come la coerenza finita (T₁, T₂) impatta sui calcoli (Criterio 5). Alla fine, avrai un'intuizione più profonda di cosa significa in pratica ciascun criterio di DiVincenzo e di come Qiskit permette di sperimentare con essi.

# 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. Criterio 1 – Qubit Scalabili e Ben Caratterizzati

Criterio 1: "Un sistema fisico scalabile con Qubit ben caratterizzati." Questo significa che abbiamo bisogno di una piattaforma hardware quantistica in cui possiamo aumentare il numero di Qubit e controllarli comunque in modo affidabile. Le proprietà di ciascun Qubit (livelli energetici, tassi di errore, connettività, ecc.) devono essere ben comprese. In sostanza, vogliamo costruire Circuit più grandi senza che il sistema si deteriori. In pratica, man mano che aumentiamo il numero di Qubit o la profondità del Circuit, gli errori e la decoerenza si accumulano, quindi dimostrare la scalabilità significa anche capire come l'aumento delle dimensioni influisce sulle prestazioni.

Obiettivo della Demo: Usare Qiskit per mostrare l'effetto dell'aumento delle dimensioni di un Circuit (per numero di Qubit o profondità dei Gate) sulla fedeltà dell'output. Simuleremo uno scenario ideale rispetto a uno rumoroso per vedere come un sistema più grande o un Circuit più profondo soccombono alla decoerenza e agli errori.

Per prima cosa, costruiamo uno stato entangled di piccole dimensioni (stato GHZ) su 3 Qubit, poi uno più grande su 5 Qubit, come semplice test di scalabilità. Uno stato GHZ di n Qubit è 12(0...0+1...1)\frac{1}{\sqrt{2}}(|0...0\rangle + |1...1\rangle). In una simulazione ideale, misurare un GHZ di n Qubit produce solo due risultati (tutti 0 o tutti 1) con uguale probabilità. Confronteremo l'output ideale con l'output rumoroso all'aumentare di n o della profondità del Circuit.

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}

Quantum circuit diagram

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}

Code output

Risultato atteso (caso ideale): Il GHZ a 3 Qubit produce idealmente circa il 50% 000 e il 50% 111 nei conteggi. Il GHZ a 5 Qubit produce circa il 50% 00000 e il 50% 11111. Non compaiono altre sequenze di bit perché lo stato è idealmente completamente coerente ed entangled. Dovresti vedere due barre alte nell'istogramma per ciascun Circuit, corrispondenti ai risultati tutto-zeri e tutto-uni.

Vediamo ora cosa succede in un ambiente rumoroso. Useremo le funzionalità di modello di rumore di Qiskit Aer per imitare gli errori di un dispositivo reale. Ad esempio, possiamo prendere le proprietà di un Backend IBM per creare un modello di rumore che include errori dei Gate, tempi di Gate finiti, rilassamento del Qubit (T₁), dephasing (T₂) ed errori di lettura. Qui useremo un fake backend che rappresenta il dispositivo IBM Quantum Brisbane per generare un modello di rumore, e ri-eseguiremo i Circuit GHZ attraverso di esso.

Esercizio 1a: Simulare con Rumore

Completa il codice seguente per simulare i Circuit GHZ su un simulatore rumoroso basato sul Backend FakeBrisbane. Questo ti mostrerà come le prestazioni degradano man mano che il sistema scala in un ambiente di rumore realistico.

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))

Esercizio 1b: Eseguire su un vero computer IBM Quantum

Il codice seguente esegue i Circuit GHZ su un vero computer IBM Quantum. Questo ti mostrerà come le prestazioni degradano su un dispositivo reale.

# 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))

Risultato atteso (rumoroso vs ideale): Con il rumore, sia simulato che su un dispositivo reale, lo stato GHZ è meno perfetto. Vedrai risultati aggiuntivi oltre a tutti-0 e tutti-1. Per 3 Qubit, invece del 100% in 000/111, una certa probabilità si distribuisce su altre sequenze di bit (es. 001, 010, ecc.) a causa di errori dei Gate o della decoerenza che inverte alcuni Qubit. Per 5 Qubit, l'effetto è ancora più pronunciato; il Circuit più grande (più Qubit e Gate CNOT) accumula più errori, quindi i picchi tutto-0 e tutto-1 sono più bassi, e compaiono molti altri risultati. Questa tendenza illustra la sfida della scalabilità: man mano che aumentiamo le dimensioni, mantenere un'alta fedeltà diventa più difficile senza la correzione degli errori.

Intuizione: Un computer quantistico scalabile deve preservare le correlazioni quantistiche man mano che il sistema cresce. I nostri esempi mostrano come l'aumento del numero di Qubit/profondità dei Gate provochi un calo della fedeltà dei risultati in presenza di rumore. I criteri rimanenti si occuperanno di mantenere quei Qubit ben controllati (basso tasso di errore, inizializzabili, ecc.) man mano che si scala.

2. Criterio 2 – Inizializzazione dei Qubit

Criterio 2: "La capacità di inizializzare lo stato dei Qubit a un semplice stato fiduciale, come |000…〉." Tutti i Qubit devono partire in modo affidabile da uno stato di riferimento noto (tipicamente lo stato fondamentale |0〉 per ogni Qubit). L'inizializzazione è essenziale affinché gli algoritmi partano da zero. In pratica, sui dispositivi quantum IBM ogni Qubit viene automaticamente reimpostato a |0〉 all'inizio di ogni esecuzione del Circuit. Qiskit fornisce anche istruzioni per reimpostare i Qubit o preparare stati personalizzati durante una computazione.

Obiettivo della Demo: Mostrare come inizializzare i Qubit in Qiskit, sia all'inizio che a metà Circuit. Dimostreremo l'uso dell'istruzione reset e dei metodi di preparazione degli stati.

Esercizio 2: Preparare uno Stato Specifico

Nel blocco di codice seguente, completa il QuantumCircuit per preparare lo stato 10|10\rangle. Questo significa che il Qubit 0 deve essere nello stato 0|0\rangle e il Qubit 1 nello stato 1|1\rangle. Usa il Gate e l'istruzione appropriati per ottenere questo risultato.

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)

Dovresti vedere 10 (binario per qubit1=1, qubit0=0) con il 100% di probabilità dalla simulazione, il che significa che il Qubit 1 è stato preparato con successo in |1〉 e il Qubit 0 in |0〉.

Ora, per una preparazione di stato più generale, Qiskit consente l'inizializzazione a stati arbitrari usando il metodo initialize. Ad esempio, prepariamo un Qubit nello stato +=(0+1)/2|+\rangle = (|0\rangle+|1\rangle)/\sqrt{2}, che è uno stato di sovrapposizione, e una coppia di Qubit nello stato di Bell (00+11)/2(|00\rangle+|11\rangle)/\sqrt{2}:

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}

Risultati attesi: Lo stato |+〉 di un singolo Qubit, quando misurato, produrrà 0 e 1 con circa il 50% di probabilità ciascuno. La misura dello stato di Bell dovrebbe dare circa il 50% 00 e il 50% 11. Se vedi questi risultati, conferma che la nostra inizializzazione a quegli stati ha avuto successo.

Inizializzazione a metà Circuit: Il reset di Qiskit può essere usato nel mezzo di un Circuit per reinizializzare un Qubit a |0〉 al volo. Ad esempio, nei codici di correzione degli errori o negli algoritmi iterativi, spesso si misura un Qubit e poi lo si reimposta per riutilizzarlo. L'operazione reset è deterministica; scarica qualsiasi stato esistente e riporta il Qubit allo stato fondamentale.

Esempio su dispositivo: Su hardware come ibmq_brisbane (127 Qubit) o qualsiasi dispositivo IBM, tutti i Qubit partono da |0〉 per impostazione predefinita quando viene eseguito un job. Se hai bisogno di uno stato iniziale diverso, applicheresti dei Gate all'inizio (come abbiamo fatto con X per ottenere |1〉). La re-inizializzazione continua (per la correzione quantistica degli errori) è un argomento di ricerca attiva perché farla rapidamente è impegnativo. Per fortuna, per l'uso di base, la capacità di ripartire da zero in |0…0〉 è disponibile e abbiamo dimostrato come ottenere anche altri stati iniziali desiderati.

3. Criterio 3 – Lungo Tempo di Coerenza (Decoerenza vs Tempo di Gate)

Criterio 3: "Lunghi tempi di decoerenza rilevanti, molto più lunghi del tempo di operazione del Gate." Questo riguarda la necessità che i Qubit mantengano il loro stato quantistico abbastanza a lungo da eseguire le operazioni necessarie. Ogni Qubit ha un tempo T₁ (tempo di rilassamento energetico, con quale velocità |1〉 decade a |0〉) e un tempo T₂ (tempo di sfasamento, con quale velocità viene persa la coerenza di fase relativa). Affinché un computer quantistico funzioni, queste scale temporali devono essere molto superiori alla durata delle operazioni di Gate.

Obiettivo della Demo: Analizzare la coerenza dei Qubit in Qiskit mostrando come la decoerenza influisce sui risultati del Circuit man mano che la lunghezza dell'esecuzione cresce. Utilizzeremo un Backend fittizio con tempi T1/T2 noti per simulare questo effetto.

Per dimostrare l'impatto della coerenza finita, simuleremo un esperimento di decadimento T1. Prepareremo un Qubit nello stato |1〉, aspetteremo per un certo tempo usando l'istruzione delay, poi misureremo. Ci aspettiamo che la probabilità di misurare |1〉 diminuisca all'aumentare del ritardo.

# 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

Quantum circuit diagram

Esercizio 3: Simula un Esperimento di Decadimento T1

Ora usa un simulatore rumoroso basato su FakeVigo (che ha tempi T1 di ~50-100 µs) per eseguire questi Circuit. Il simulatore applicherà automaticamente gli errori T1/T2 durante le istruzioni delay. Esegui il transpiling dei Circuit per questo backend ed eseguili.

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. Criterio 4 – Set Universale di Gate Quantistici

Criterio 4: "Un set 'universale' di Gate quantistici." Ciò significa che il nostro hardware deve permetterci di eseguire qualsiasi computazione quantistica componendo un insieme finito di Gate di base. Nell'informatica classica, NAND è universale; in quella quantistica esistono molte scelte di set di Gate universali (ad es. {H, T, CNOT} o i Gate nativi di una determinata macchina). I dispositivi IBM, per esempio, hanno un set di operazioni native come rotazioni arbitrarie a singolo Qubit e CNOT tra certi Qubit, che insieme sono universali. Il compito del Transpiler di Qiskit è spesso compilare i Gate di alto livello in questi Gate di base.

Obiettivo della Demo: Illustrare l'universalità dei Gate mostrando come Qiskit decomponga i Gate. Prenderemo un Gate non nativo (come il Gate di Toffoli a 3 Qubit, CCX) e vedremo come si scompone nei Gate di base del dispositivo. Questo dimostra che il set di Gate fornito è davvero universale – riesce a produrre l'operazione più complessa.

Innanzitutto, vediamo quali sono i Gate di base per un tipico Backend IBM. Interrogheremo la configurazione di un dispositivo (o la sua versione fittizia). Per esempio, i Gate di base di ibmq_brisbane: Dovresti osservare che la probabilità P(qubit=1) diminuisce all'aumentare del tempo di ritardo, seguendo una curva di decadimento esponenziale caratteristica del rilassamento T1. Questo dimostra direttamente come il tempo di coerenza finito porti a errori computazionali se il Circuit viene eseguito troppo a lungo.

Impatto sugli algoritmi: Se provi un algoritmo più lungo (con molti Gate sequenziali), il tempo di esecuzione totale potrebbe avvicinarsi a T2 o superarlo, causando la perdita di coerenza dello stato prima della fine. Ecco perché migliorare i tempi di coerenza e rendere i Gate più veloci sono due degli obiettivi più critici nella ricerca sull'hardware quantistico.

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']

L'output potrebbe essere qualcosa come ['id', 'rz', 'sx', 'x', 'ecr']. Queste sono le operazioni primitive che l'hardware supporta nativamente (Identità/no-op, rotazione RZ, Gate sqrt(X), Gate X e controlled-X). Qualsiasi altro Gate deve essere composto da questi. Questo set è noto per essere universale per il calcolo quantistico (essenzialmente rotazioni a singolo Qubit più un Gate entangolante a due Qubit formano un set universale).

Ora, prendi un Gate di Toffoli (CCX) come caso di test. CCX inverte un Qubit target solo se due Qubit di controllo sono entrambi 1. Non è un Gate nativo sull'hardware IBM. Qiskit fornisce un'istruzione ccx, ma internamente la decomporrà.

Esercizio 4: Decomposizione di un Gate di Toffoli

Completa il codice qui sotto per costruire un Circuit con un Gate di Toffoli (CCX) e poi usa Qiskit per scomporlo nei Gate di base nativi del Backend 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))

Nell'output traspilato, dovresti vedere il CCX sostituito da una sequenza di Gate più elementari come rz, sx e ecr. Questo dimostra che i Gate nativi sono sufficienti per esprimere il Toffoli.

Universalità in pratica: L'esercizio precedente mostra che un Gate complesso a 3 Qubit è stato costruito da Gate più semplici. In generale, qualsiasi unitaria multi-Qubit può essere composta da Gate a 1 e 2 Qubit. Il Transpiler è un componente fondamentale di qualsiasi stack software quantistico, poiché colma il divario tra gli algoritmi astratti che vogliamo eseguire e le operazioni fisiche che un dispositivo quantistico specifico può effettivamente eseguire.

Esempio con dispositivo reale: Il dispositivo ibmq_brisbane usa l'architettura Eagle con i Gate di base mostrati sopra. Ciò significa che qualsiasi algoritmo inviato a quelle macchine verrà convertito in sequenze di tali operazioni. Questo criterio riguarda essenzialmente la controllabilità; abbiamo abbastanza gradi di controllo per eseguire qualsiasi operazione necessaria sui nostri Qubit.

5. Criterio 5 – Misurazione dei Qubit

Criterio 5: "Una capacità di misurazione specifica per ogni Qubit." Lo stato di ogni Qubit deve essere misurabile (tipicamente nella base computazionale, |0〉 o |1〉). In altre parole, dopo aver eseguito un Circuit quantistico, dobbiamo leggere ogni Qubit come un bit classico 0/1. Questo criterio riguarda la disponibilità di rilevatori affidabili per ogni Qubit e la possibilità di selezionare quali Qubit misurare.

Obiettivo della Demo: Mostrare come eseguire misurazioni in Qiskit su simulatori e dispositivi reali, evidenziando le differenze (come il rumore di misurazione). Misureremo alcuni Qubit in vari stati ed esamineremo i risultati. Dimostreremo anche come potrebbero manifestarsi gli errori di lettura confrontando i risultati del simulatore con quelli dell'hardware.

Prima di tutto, un semplice esempio di misurazione:

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')

Quantum circuit diagram

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}

Ci aspettiamo 1000 conteggi di 01 sul simulatore. Ora, vediamo l'errore di misurazione in azione simulandolo. Possiamo aggiungere un errore di lettura al nostro simulatore Aer. Qiskit Aer ci permette di definire un ReadoutError e di associarlo ai Qubit in un modello di rumore.

Esercizio 5: Simula l'Errore di Lettura

Completa il codice per definire un semplice modello di errore di lettura in cui ogni Qubit ha una probabilità del 2% di essere misurato in modo errato (uno 0 viene letto come 1, o un 1 come 0). Poi, esegui il Circuit di misurazione con questo modello di rumore.

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)

Questo output simulato mostrerà alcuni conteggi erronei (come 11, 00, 10) simili a quelli che l'hardware reale potrebbe produrre, dimostrando l'impatto di una misurazione imperfetta.

Esempio con dispositivo reale: Su un dispositivo reale come ibmq_brisbane, potresti eseguire lo stesso Circuit e probabilmente vedresti conteggi non nulli simili per i risultati errati. I dati di calibrazione del dispositivo riportano un errore di lettura per ogni Qubit. La capacità di selezionare e leggere Qubit specifici è fondamentale, e comprendere le loro caratteristiche di errore è la chiave per ottenere risultati significativi. L'esecuzione su un dispositivo reale è stata dimostrata nell'Esercizio 1b: Esegui su un computer IBM Quantum reale.

Criteri per la Comunicazione Quantistica (Qubit Volanti)

DiVincenzo ha elencato anche due criteri specifici per la comunicazione quantistica, importanti per costruire un computer quantistico in rete:

  1. Capacità di interconvertire Qubit stazionari e volanti. (Ad es., mappare un Qubit in un processore su un fotone che può viaggiare.)
  2. Capacità di trasmettere fedelmente Qubit volanti tra luoghi diversi. (Ad es., inviare un Qubit fotone attraverso una fibra senza perdere informazioni quantistiche.)

Questi vanno oltre l'uso standard di Qiskit perché Qiskit si occupa principalmente di Qubit stazionari su un chip. Tuttavia, possiamo illustrare il concetto di questi criteri con un semplice esempio: il teletrasporto quantistico. Il teletrasporto mostra come convertire lo stato di un Qubit stazionario in informazioni trasportate da una coppia entangolata (la parte "volante") e dalla comunicazione classica, che vengono poi utilizzate per ricostruire lo stato su un altro Qubit stazionario altrove.

Il modulo Quantum Teleportation di Qiskit in Classrooms, a cura della Dr. Katie McCormick, ti guiderà attraverso uno dei protocolli più affascinanti dell'informazione quantistica: il teletrasporto quantistico, in cui uno stato quantistico (un Qubit) viene inviato da Alice a Bob usando l'entanglement e solo due bit classici. Imparerai la procedura completa di teletrasporto passo dopo passo: come preparare la coppia di Bell entangolata, eseguire una misurazione nella base di Bell dal lato di Alice, trasmettere i risultati classici e applicare il Gate quantistico corretto al Qubit di Bob per recuperare perfettamente lo stato originale. Lungo il percorso, esplorerai perché teletrasportare le informazioni di un Qubit non viola il teorema di no-cloning né supera la velocità della luce. Attraverso esercizi pratici con hardware IBM Quantum o simulatori, acquisirai una comprensione concreta di misurazione, entanglement e controllo feed-forward in azione.

Padroneggiando il teletrasporto quantistico, capirai come codificare, trasmettere e recuperare informazioni quantistiche tra nodi distinti, ponendo le basi per reti quantistiche, sistemi ripetitori, schemi di comunicazione sicura e calcolo quantistico modulare scalabile. Come si relaziona ai criteri 6 e 7: In una vera rete quantistica, la coppia entangolata condivisa verrebbe creata distribuendo Qubit "volanti" (come i fotoni) tra le sedi di Alice e Bob (Criterio 7: trasmissione fedele). Il protocollo di teletrasporto stesso serve poi come modo per mappare lo stato del Qubit stazionario di Alice sulla sua metà della coppia entangolata, inviandolo di fatto a Bob (Criterio 6: interconversione). Qiskit ci permette di simulare perfettamente la logica del protocollo, fornendo un modello concettuale di come questi criteri vengono soddisfatti nelle architetture di comunicazione.

Conclusioni e Riepilogo

Abbiamo progettato una serie di esercizi incentrati sul codice per illustrare i criteri di DiVincenzo usando Qiskit. Attraverso questi esempi pratici, hai esplorato come una piattaforma di calcolo quantistico reale soddisfi ogni requisito:

  • Scalabilità: costruire Circuit su più Qubit e comprendere come il rumore scala.
  • Inizializzazione: usare reset e preparazione di stato per avviare le computazioni in modo affidabile in stati noti.
  • Gate Universali: traspilare operazioni complesse nei Gate di base di una macchina, dimostrando di poter eseguire qualsiasi computazione.
  • Misurazione: leggere i Qubit e gestire realistici errori di lettura.
  • Coerenza: osservare l'effetto del T₁, T₂ finiti sulla fedeltà degli algoritmi e la necessità che le operazioni siano veloci rispetto alla decoerenza.

Per completezza, abbiamo anche accennato agli aspetti della comunicazione quantistica tramite il modulo Quantum Teleportation di Qiskit in Classrooms, collegando gli ultimi due criteri (Qubit volanti).

Infine, vale la pena notare come questi criteri si uniscano in un computer quantistico reale come quello di IBM. Un dispositivo come ibmq_brisbane ha 127 Qubit superconduttori (Criterio 1), ognuno dei quali parte da |0〉 (Criterio 2), con un set di Gate calibrato e compilatori per l'universalità (Criterio 4), risonatori di lettura a microonde per ogni Qubit (Criterio 5), e tempi di coerenza dell'ordine delle centinaia di microsecondi contro operazioni in nanosecondi (Criterio 3). Per gli esperimenti di rete quantistica, IBM e altri stanno esplorando la trasduzione da microonde a ottico per i Qubit volanti, e l'entanglement di Qubit distanti (Criteri 6 e 7); queste sono aree di ricerca attive.

Completando gli esercizi in questo notebook, non hai solo visto le definizioni dei criteri di DiVincenzo, ma li hai toccati attraverso il codice; sviluppando intuizione su cosa significa ogni requisito per l'hardware e gli algoritmi quantistici reali. Sentiti libero di estendere questi esperimenti, e buon calcolo quantistico!