Simule um modelo de Ising com chutes de 127 qubits
Neste guia, usamos o pacote pauli-prop para simular classicamente a dinâmica temporal de um modelo de Ising com chutes de 127 qubits em uma rede heavy-hex e aproximar a magnetização de um único sítio, . O Hamiltoniano considerado é:
onde descreve o acoplamento de spins vizinhos mais próximos, , e é o campo transversal global. Uma decomposição de Trotter de primeira ordem do operador evoluído no tempo será implementada como um circuito quântico, , ao longo de passos de Trotter. A constante de acoplamento, , será fixada em , de modo que seja Clifford sempre que .
Fluxo de trabalho:
-
Crie circuitos quânticos que implementem o modelo de Ising com Trotterização
- Varie entre os pontos de Clifford, e
-
Escolha um sítio no meio da rede (qubit ) e estime a magnetização após passos de Trotter para cada circuito
-
Observe a magnetização cair de para conforme se move de um ponto de Clifford para outro
Crie os circuitos
Primeiro, usamos FakeSherbrooke de qiskit-ibm-runtime para obter os índices das arestas do mapa de acoplamento da QPU Eagle de 127 qubits. Depois de obter os índices das arestas, criamos os circuitos de Trotter para os diferentes valores de que queremos simular. Os circuitos implementarão uma Trotterização de primeira ordem do Hamiltoniano usando 20 passos de Trotter e 5420 portas.
# 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)
Simule a dinâmica temporal com propagação de Pauli
Em seguida, especificamos o observável, , que queremos medir. Neste caso, estimamos .
Para estudar a magnetização entre os pontos de Clifford, propagamos de forma aproximada até o início do circuito, , resultando em um novo observável, .
Durante a propagação, o número de termos no observável evoluído cresce exponencialmente com o número de portas, então geralmente é necessário limitar o quanto ele pode crescer. Aqui, limitamos o número de termos em a e truncamos termos com coeficientes menores que . O truncamento de termos gera algum erro.
Depois de obter , podemos estimar facilmente o valor esperado, , somando os coeficientes dos termos diagonais em (termos que consistem apenas em I ou Z em todos os qubits).
Definimos frame='h' para especificar que queremos evoluir o observável no referencial de Heisenberg (). Use frame=s para a evolução de 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
Visualizar
Por fim, plotamos a magnetização em função de . Quando , o circuito não afeta o estado inicial na base computacional, e sabemos que . À medida que se afasta de , a magnetização decai monotonicamente até que alcance o próximo ângulo de Clifford, , e a magnetização converge para .
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>]
