Simula un modello di Ising kicked a 127 qubit
In questa guida usiamo il pacchetto pauli-prop per simulare classicamente la dinamica temporale di un modello di Ising kicked a 127 qubit su un reticolo heavy-hex e approssimare la magnetizzazione del singolo sito, . L'Hamiltoniana considerata è:
dove descrive l'accoppiamento tra spin primi vicini, , e è il campo trasverso globale. Una decomposizione di Trotter del primo ordine dell'operatore evoluto nel tempo verrà implementata come circuito quantistico, , su passi di Trotter. La costante di accoppiamento, , sarà fissata a in modo che sia di Clifford ogni volta che .
Flusso di lavoro:
-
Crea circuiti quantistici che implementano il modello di Ising trotterizzato
- Fai variare tra i punti di Clifford, e
-
Scegli un sito al centro del reticolo (qubit ) e stima la magnetizzazione dopo passi di Trotter per ciascun circuito
-
Osserva la magnetizzazione scendere da a mentre passa da un punto di Clifford all'altro
Crea i circuiti
Per prima cosa usiamo FakeSherbrooke da qiskit-ibm-runtime per ottenere gli indici degli archi della mappa di accoppiamento della QPU Eagle a 127 qubit. Una volta ottenuti gli indici degli archi, creiamo i circuiti di Trotter per i diversi valori di che vogliamo simulare. I circuiti implementeranno una trotterizzazione del primo ordine dell'Hamiltoniana usando 20 passi di Trotter e 5420 gate.
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"matplotlib": "matplotlib", "numpy": "numpy", "pauli_prop": "pauli-prop", "qiskit": "qiskit", "qiskit_ibm_runtime": "qiskit-ibm-runtime"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
import numpy as np
from qiskit import QuantumCircuit
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
# Get the edges in the device coupling map
backend = FakeSherbrooke()
edges = backend.coupling_map.get_edges()
# Num Trotter steps
num_steps = 20
# Create Trotter circuits with varying global fields
hs = [i * np.pi / 32 for i in range(17)]
circuits = []
for h in hs:
circuit = QuantumCircuit(backend.num_qubits)
for _ in range(num_steps):
circuit.rx(h, [i for i in range(backend.num_qubits)])
for edge in edges:
circuit.rzz(-np.pi / 2, edge[0], edge[1])
circuits.append(circuit)
Simula la dinamica temporale con la propagazione di Pauli
Successivamente specifichiamo l'osservabile, , che vogliamo misurare. In questo caso stimiamo .
Per studiare la magnetizzazione tra i punti di Clifford, propaghiamo approssimativamente all'inizio del circuito, , ottenendo una nuova osservabile, .
Durante la propagazione, il numero di termini dell'osservabile evoluta cresce esponenzialmente nel numero di gate, quindi di solito è necessario limitare quanto può crescere. Qui limitiamo il numero di termini in a e tronchiamo i termini con coefficienti più piccoli di . Il troncamento dei termini introduce un certo errore.
Una volta ottenuto , possiamo stimare facilmente il valore di aspettazione, , sommando i coefficienti dei termini diagonali in (termini costituiti solo da I o Z su tutti i qubit).
Impostiamo frame='h' per specificare che vogliamo far evolvere l'osservabile nel quadro di Heisenberg (). Usa frame=s per l'evoluzione di Schrödinger ().
import time
from pauli_prop import propagate_through_circuit
from qiskit.quantum_info import Pauli, SparsePauliOp
# Z_62 observable
id_pauli = Pauli("I" * backend.num_qubits)
observable = SparsePauliOp(id_pauli.dot(Pauli("Z"), [62]))
# Estimate the single-site magnetization for varying magnetic fields
times = []
approx_evs = []
for circuit in circuits:
st = time.perf_counter()
propagated_obs = propagate_through_circuit(
observable, circuit, 100_000, 1e-5, frame="h"
)[0]
times.append(time.perf_counter() - st)
approx_evs.append(
float(
propagated_obs.coeffs[~propagated_obs.paulis.x.any(axis=1)].sum()
)
)
print(f"Finished {len(circuits)} simulations in {sum(times):.0f}s")
Finished 17 simulations in 494s
Visualizza
Infine, tracciamo il grafico della magnetizzazione in funzione di . Quando , il circuito non influisce sullo stato iniziale nella base computazionale, e sappiamo che . Man mano che si allontana da , la magnetizzazione decade in modo monotono finché raggiunge il successivo angolo di Clifford, , e la magnetizzazione converge a .
import matplotlib.pyplot as plt
plt.xlabel(r"$R_x$ angle $\theta_h$")
plt.ylabel(r"$\langle Z_{62} \rangle$")
plt.plot(hs, approx_evs, marker="o")
[<matplotlib.lines.Line2D at 0x123f68b00>]
