Sari la conținutul principal
Acest proiect este în versiune beta. Ai găsit o eroare? Deschide un issue pe GitHub. Ai o întrebare sau o idee? Întreabă în Discussions — ne-ar plăcea să aflăm părerea ta!
Cum este calitatea traducerii pe această pagină?

Simulează un model Ising cu lovituri (kicked Ising) cu 127 de qubiți

În acest ghid folosim pachetul pauli-prop pentru a simula clasic dinamica în timp a unui model Ising cu lovituri (kicked Ising) cu 127 de qubiți pe o rețea heavy-hex și pentru a aproxima magnetizarea pe un singur situs, ⟨Z62⟩\langle Z_{62} \rangle. Hamiltonianul considerat este:

H=−J∑⟨i,j⟩ZiZj+h∑iXiH = -J\sum\limits_{\langle i,j \rangle} Z_iZ_j + h\sum\limits_iX_i

unde J>0J>0 descrie cuplajul dintre spinii vecini cei mai apropiați, i<ji<j, iar hh este câmpul transversal global. O descompunere Trotter de ordinul întâi a operatorului evoluat în timp va fi implementată ca un circuit cuantic, UU, pe parcursul a 2020 de pași Trotter. Constanta de cuplaj, JJ, va fi fixată la J=−π2J=-\frac{\pi}{2}, astfel încât UU este Clifford oricând hmod  π2=0h\mod\frac{\pi}{2}=0.

Flux de lucru:

  • Creează circuite cuantice care implementează modelul Ising Trotterizat

    • Variază hh între punctele Clifford, 0.00.0 și π2\frac{\pi}{2}
  • Alege un situs din mijlocul rețelei (qubitul 6262) și estimează magnetizarea după 2020 de pași Trotter pentru fiecare circuit

  • Observă cum magnetizarea scade de la 1.01.0 la 0.00.0 pe măsură ce hh se deplasează de la un punct Clifford la altul

Creează circuitele​

Mai întâi, folosim FakeSherbrooke din qiskit-ibm-runtime pentru a obține indicii muchiilor hărții de cuplaj a QPU-ului Eagle cu 127 de qubiți. Odată ce avem indicii muchiilor, creăm circuitele Trotter pentru valorile variabile ale lui hh pe care vrem să le simulăm. Circuitele vor implementa o Trotterizare de ordinul întâi a Hamiltonianului folosind 20 de pași Trotter și 5420 de porți.

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

Simulează dinamica în timp cu propagare Pauli​

În continuare specificăm observabila, OO, pe care vrem să o măsurăm. În acest caz, estimăm ⟨Z62⟩\langle Z_{62} \rangle.

Pentru a studia magnetizarea între punctele Clifford, propagăm aproximativ OO până la începutul circuitului, UU, rezultând o nouă observabilă, O′≈U†OUO^\prime \approx U^{\dagger}OU.

În timpul propagării, numărul de termeni din observabila evoluată crește exponențial cu numărul de porți, deci de obicei este necesar să limităm cât de mult poate crește. Aici limităm numărul de termeni din O′O^\prime la 10510^5 și trunchiem termenii cu coeficienți mai mici decât 10−510^{-5}. Trunchierea termenilor introduce o anumită eroare. Odată ce avem O′O^\prime, putem estima ușor valoarea de așteptare, ⟨0∣U†OU∣0⟩=⟨0∣O′∣0⟩\langle0|U^{\dagger}OU|0\rangle = \langle0|O^\prime|0\rangle, însumând coeficienții termenilor diagonali din O′O^\prime (termeni formați doar din I sau Z pe toți qubiții).

Setăm frame='h' pentru a specifica că vrem să evoluăm observabila în cadrul Heisenberg (U†OUU^{\dagger}OU). Folosește frame=s pentru evoluția Schrödinger (UOU†UOU^{\dagger}).

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

Vizualizează​

În final, reprezentăm grafic magnetizarea în funcție de hh. Când h=0h=0, circuitul nu afectează starea inițială în baza computațională, și știm că ⟨0∣O∣0⟩=1.0\langle0|O|0\rangle = 1.0. Pe măsură ce hh se îndepărtează de 00, magnetizarea scade monoton până când hh ajunge la următorul unghi Clifford, π2\frac{\pi}{2}, iar magnetizarea converge la 00.

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

Output of the previous code cell