Mabilisang simula
title: Quickstart description: Isang quickstart na gabay para sa pauli-prop na Qiskit addons package
Sa gabay na ito, gagamitin natin ang pauli-prop package para i-simulate nang classical ang time dynamics ng isang 10-qubit na kicked Ising model sa 1D spin chain.
Ihanda ang mga input para sa Pauli propagation
Ang Hamiltonian na isinasaalang-alang ay:
kung saan ang ay naglalarawan ng coupling ng mga magkatabing spin, , at ang ay ang global na transverse field. Ang first-order na Trotter decomposition ng time-evolved na operator ay ipapatupad bilang isang quantum circuit, , sa loob ng Trotter step. Ang coupling constant, , ay ifi-fix sa , at ang ay ifi-fix sa . Ang mga interaksyong ay ipapatupad gamit ang mga Clifford gate (, , ).
Ipinapatupad natin ang Trotterized na time evolution bilang isang quantum circuit at gumagamit ng para sa mga non-Clifford na rotation sa paligid ng x-axis. Habang lumalayo ang mga anggulong ito sa mga Clifford angle (halimbawa, ), mas nagiging mahirap i-simulate ang sistema gamit ang mga Pauli propagation method.
Para sa pagpili ng observable, isinasaalang-alang natin ang average na single-site magnetization, , kung saan ang ay ang bilang ng mga spin.
# 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_aer": "qiskit-aer"}
_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.quantum_info import SparsePauliOp
from qiskit.transpiler import CouplingMap
num_qubits = 10
coupling_map = CouplingMap.from_line(num_qubits, bidirectional=False)
# Num Trotter steps
num_steps = 20
theta_rx = np.pi / 6
# Average single-site magnetization
observable = (
SparsePauliOp(
[
"I" * iq + "Z" + "I" * (num_qubits - iq - 1)
for iq in range(num_qubits)
]
)
/ num_qubits
)
# Create the Trotter circuit
num_qubits = 10
num_steps = 20
theta_rx = np.pi / 6
circuit = QuantumCircuit(num_qubits)
edges = CouplingMap.from_line(num_qubits, bidirectional=False).get_edges()
for _ in range(num_steps):
circuit.rx(theta_rx, [i for i in range(num_qubits)])
for edge in edges:
circuit.sdg(edge)
circuit.ry(np.pi / 2, edge[1])
circuit.cx(edge[0], edge[1])
circuit.ry(-np.pi / 2, edge[1])
circuit.draw("mpl", fold=-1)
I-simulate ang time evolution ng sistema gamit ang Pauli propagation
Kapag mayroon na tayong circuit, , at observable, , madali nating mai-simulate ang sistema sa ilang hakbang:
-
Hatiin ang sa Clifford na bahagi nito, , at non-Clifford na bahagi, , para ang , gamit ang
evolve_through_cliffords -
I-propagate ang sa pamamagitan ng , na magreresulta sa bagong operator, , gamit ang
pauli_prop.propagate_through_circuit -
I-evolve ang sa Clifford na bahagi ng circuit gamit ang suporta sa Clifford evolution na built-in sa Qiskit
-
Tantiyahin ang expectation value bilang sa pamamagitan ng pagsasama-sama ng mga coefficient sa na nauugnay sa mga fully-diagonal na Pauli term (mga Pauli term na naglalaman ng
IoZsa lahat ng qubit). Tandaan, isa itong approximation dahil nag-truncate tayo ng mga term mula sa habang pina-propagate ito sa non-Clifford na bahagi ng circuit.
import time
from pauli_prop import evolve_through_cliffords, propagate_through_circuit
cliff, non_cliff = evolve_through_cliffords(circuit)
max_terms_list = [10**i for i in range(8)]
approx_evs = []
durations = []
for max_terms in max_terms_list:
st = time.perf_counter()
evolved_obs = propagate_through_circuit(
observable, non_cliff, max_terms=max_terms, atol=1e-12, frame="h"
)[0]
evolved_obs.paulis = evolved_obs.paulis.evolve(cliff, frame="h")
durations.append(time.perf_counter() - st)
approx_evs.append(
float(evolved_obs.coeffs[~evolved_obs.paulis.x.any(axis=1)].sum())
)
Habang nagpapatakbo tayo ng mas malalaking kalkulasyon, mas nagiging tumpak ang mga approximation ng expectation value. Sa halimbawang ito, napupuno natin ang buong Pauli space sa humigit-kumulang , na makikita sa pagpapatag ng kurba sa pagitan ng huling dalawang punto.
Bagama't monotonic ang convergence na ipinapakita ng plot sa ibaba, karaniwang hindi monotonic ang convergence ng mga Pauli propagation simulation. Hindi kakaiba na makakita ng "bumpy" na behavior sa ganitong uri ng mga plot.
import matplotlib.pyplot as plt
from qiskit_aer import AerSimulator
sim_circ = circuit.copy()
sim_circ.save_statevector()
backend = AerSimulator(method="statevector")
psi = backend.run(sim_circ).result().data()["statevector"]
exact_ev = psi.expectation_value(observable)
ax1 = plt.gca()
ax1.plot(max_terms_list, approx_evs, marker="o", label="Approximate")
ax1.axhline(exact_ev, linestyle="--", color="green", label="Exact")
ax1.set_xscale("log")
ax1.set_xlabel("# terms kept")
ax1.set_ylabel(r"$\frac{1}{N} \sum_{i=1}^{N} \langle z_i \rangle$")
ax2 = ax1.twinx()
ax2.plot(
max_terms_list, durations, marker=".", label="Runtime", color="orange"
)
ax2.set_ylabel("Runtime (s)", color="orange")
ax2.set_yscale("log")
handles1, labels1 = ax1.get_legend_handles_labels()
handles2, labels2 = ax2.get_legend_handles_labels()
ax1.legend(handles1 + handles2, labels1 + labels2, loc="lower right")
plt.title(f"Simulating {num_steps}-step 1D Ising Model")
Text(0.5, 1.0, 'Simulating 20-step 1D Ising Model')

