Aller au contenu principal

Expérience à l'échelle de l'utilité II

remarque

Yukio Kawashima (12 juillet 2024)

Télécharge le PDF de la conférence originale. Note que certains extraits de code peuvent devenir obsolètes, car ce sont des images statiques.

Le temps de QPU approximatif pour exécuter cette expérience est de 2 min 30 s.

(Ce notebook reprend des textes, illustrations et codes provenant d'un notebook tutoriel désormais obsolète pour Qiskit Algorithms.)

1. Introduction et rappel de l'évolution temporelle

Ce notebook reprend les méthodes et techniques de la leçon 7. Notre objectif est de résoudre numériquement l'équation de Schrödinger dépendante du temps. Comme nous l'avons vu dans la leçon 7, la trotterisation consiste en l'application successive d'une porte quantique ou d'un ensemble de portes, choisies pour approximer l'évolution temporelle d'un système sur une tranche de temps. Nous reprenons cette discussion ici pour plus de commodité. N'hésite pas à passer directement aux cellules de code ci-dessous si tu as récemment révisé la leçon 7.

D'après l'équation de Schrödinger, l'évolution temporelle d'un système initialement dans l'état ψ(0)\vert\psi(0)\rangle prend la forme :

ψ(t)=eiHtψ(0),\vert \psi(t) \rangle = e^{-i H t} \vert \psi(0) \rangle \text{,}

HH est l'Hamiltonien indépendant du temps qui gouverne le système. Nous considérons un Hamiltonien qui peut s'écrire comme une somme pondérée de termes de Pauli H=jajPjH=\sum_j a_j P_j, où PjP_j représente un produit tensoriel de termes de Pauli agissant sur nn qubits. En particulier, ces termes de Pauli peuvent commuter entre eux, ou non. Étant donné un état au temps t=0t=0, comment obtenir l'état du système à un temps ultérieur ψ(t)|\psi(t)\rangle à l'aide d'un ordinateur quantique ? L'exponentielle d'un opérateur se comprend le plus facilement via sa série de Taylor :

eiHt=1iHt12H2t2+...e^{-i H t} = 1-iHt-\frac{1}{2}H^2t^2+...

Certaines exponentielles très basiques, comme eiZe^{iZ}, peuvent être implémentées facilement sur des ordinateurs quantiques à l'aide d'un ensemble compact de portes quantiques. La plupart des Hamiltoniens d'intérêt n'auront pas un seul terme, mais en auront plusieurs. Observe ce qui se passe si H=H1+H2H = H_1+H_2 :

eiHt=1i(H1+H2)t12(H1+H2)2t2+...e^{-i H t} = 1-i(H_1+H_2)t-\frac{1}{2}(H_1+H_2)^2t^2+...

Lorsque H1H_1 et H2H_2 commutent, nous retrouvons le cas familier (également valable pour des nombres, et pour les variables aa et bb ci-dessous) :

ei(a+b)t=eiateibte^{-i (a+b) t} = e^{-i a t}e^{-i b t}

Mais lorsque les opérateurs ne commutent pas, les termes ne peuvent pas être réarrangés dans la série de Taylor pour simplifier de cette manière. Ainsi, exprimer des Hamiltoniens complexes à l'aide de portes quantiques constitue un défi.

Une solution consiste à considérer un temps tt très petit, de sorte que le terme du premier ordre dans le développement de Taylor domine. Sous cette hypothèse :

ei(H1+H2)t1i(H1+H2)t(1iH1t)(1iH2t)eiH1teiH2te^{-i (H_1+H_2) t} \approx 1-i(H_1+H_2)t \approx (1-i H_1 t)(1-i H_2 t) \approx e^{-i H_1 t}e^{-i H_2 t}

Bien sûr, il se peut que nous ayons besoin de faire évoluer notre état sur une durée plus longue. Cela s'obtient en utilisant de nombreux petits pas de temps de ce type. Ce procédé s'appelle la trotterisation :

ψ(t)(jeiajPjt/r)rψ(0),\vert \psi(t) \rangle \approx \left(\prod_j e^{-i a_j P_j t/r} \right)^r \vert\psi(0) \rangle \text{,}

Ici, t/rt/r est la tranche de temps (le pas d'évolution) que nous choisissons. On obtient ainsi une porte qui doit être appliquée rr fois. Un pas de temps plus petit conduit à une approximation plus précise. Cependant, cela mène aussi à des circuits plus profonds, ce qui, en pratique, entraîne une accumulation d'erreurs plus importante (une préoccupation non négligeable sur les dispositifs quantiques actuels).

Aujourd'hui, nous allons étudier l'évolution temporelle du modèle d'Ising sur des réseaux linéaires de N=2N=2 et N=6N=6 sites. Ces réseaux consistent en un ensemble de spins σi\sigma_i qui n'interagissent qu'avec leurs plus proches voisins. Ces spins peuvent avoir deux orientations : \uparrow et \downarrow, qui correspondent respectivement à une magnétisation de +1+1 et 1-1.

H=Ji=0N2ZiZi+1hi=0N1Xi,H = - J \sum_{i=0}^{N-2} Z_i Z_{i+1} - h \sum_{i=0}^{N-1} X_i \text{,}

JJ décrit l'énergie d'interaction, et hh l'intensité d'un champ externe (dans la direction x ci-dessus, mais nous allons modifier cela). Écrivons cette expression à l'aide des matrices de Pauli, en considérant que le champ externe forme un angle α\alpha par rapport à la direction transversale,

H=Ji=0N2ZiZi+1hi=0N1(sinαZi+cosαXi).H = -J \sum_{i=0}^{N-2} Z_i Z_{i+1} -h \sum_{i=0}^{N-1} (\sin\alpha Z_i + \cos\alpha X_i) \text{.}

Cet Hamiltonien est utile car il nous permet d'étudier facilement les effets d'un champ externe. Dans la base computationnelle, le système sera encodé de la manière suivante :

État quantiqueReprésentation de spin
0000\lvert 0 0 0 0 \rangle\uparrow\uparrow\uparrow\uparrow
1000\lvert 1 0 0 0 \rangle\downarrow\uparrow\uparrow\uparrow
\ldots\ldots
1111\lvert 1 1 1 1 \rangle\downarrow\downarrow\downarrow\downarrow

Nous allons commencer à étudier l'évolution temporelle d'un tel système quantique. Plus précisément, nous visualiserons l'évolution temporelle de certaines propriétés du système, comme la magnétisation.

# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-aer qiskit-ibm-runtime
# Check the version of Qiskit
import qiskit

qiskit.__version__
'2.0.2'
# Import the qiskit library

import numpy as np
import warnings

from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library import PauliEvolutionGate
from qiskit.quantum_info import SparsePauliOp
from qiskit.synthesis import LieTrotter
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

from qiskit_aer import AerSimulator
from qiskit_ibm_runtime import QiskitRuntimeService, Estimator

warnings.filterwarnings("ignore")

2. Définition de l'Hamiltonien d'Ising à champ transverse

Nous considérons ici le modèle d'Ising unidimensionnel à champ transverse.

Tout d'abord, nous allons créer une fonction qui prend en entrée les paramètres du système NN, JJ et hh, et renvoie notre Hamiltonien sous forme de SparsePauliOp. Un SparsePauliOp est une représentation creuse d'un opérateur en termes de termes de Pauli pondérés.

2.1 Activité 1

Construis une fonction pour créer un Hamiltonien d'Ising à champ transverse (voir l'équation ci-dessus) avec pour arguments « le nombre de qubits », « le paramètre J » et « le paramètre h ». Essaie de le faire par toi-même en t'appuyant sur les exemples précédents. Fais défiler vers le bas pour voir la solution.

Solution :

def get_hamiltonian(nqubits, J, h):
# List of Hamiltonian terms as 3-tuples containing
# (1) the Pauli string,
# (2) the qubit indices corresponding to the Pauli string,
# (3) the coefficient.
ZZ_tuples = [("ZZ", [i, i + 1], -J) for i in range(0, nqubits - 1)]
X_tuples = [("X", [i], -h) for i in range(0, nqubits)]

# We create the Hamiltonian as a SparsePauliOp, via the method
# `from_sparse_list`, and multiply by the interaction term.
hamiltonian = SparsePauliOp.from_sparse_list(
[*ZZ_tuples, *X_tuples], num_qubits=nqubits
)
return hamiltonian.simplify()

Nous allons commencer à étudier l'évolution temporelle d'un système quantique tout en suivant la magnétisation. Nous comparons ici les résultats des simulateurs Statevector et Matrix Product State.

Définition de l'Hamiltonien

Le système que nous considérons maintenant a une taille de N=20N=20.

n_qubits = 20
hamiltonian = get_hamiltonian(nqubits=n_qubits, J=1.0, h=-5.0)
hamiltonian
SparsePauliOp(['IIIIIIIIIIIIIIIIIIZZ', 'IIIIIIIIIIIIIIIIIZZI', 'IIIIIIIIIIIIIIIIZZII', 'IIIIIIIIIIIIIIIZZIII', 'IIIIIIIIIIIIIIZZIIII', 'IIIIIIIIIIIIIZZIIIII', 'IIIIIIIIIIIIZZIIIIII', 'IIIIIIIIIIIZZIIIIIII', 'IIIIIIIIIIZZIIIIIIII', 'IIIIIIIIIZZIIIIIIIII', 'IIIIIIIIZZIIIIIIIIII', 'IIIIIIIZZIIIIIIIIIII', 'IIIIIIZZIIIIIIIIIIII', 'IIIIIZZIIIIIIIIIIIII', 'IIIIZZIIIIIIIIIIIIII', 'IIIZZIIIIIIIIIIIIIII', 'IIZZIIIIIIIIIIIIIIII', 'IZZIIIIIIIIIIIIIIIII', 'ZZIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIX', 'IIIIIIIIIIIIIIIIIIXI', 'IIIIIIIIIIIIIIIIIXII', 'IIIIIIIIIIIIIIIIXIII', 'IIIIIIIIIIIIIIIXIIII', 'IIIIIIIIIIIIIIXIIIII', 'IIIIIIIIIIIIIXIIIIII', 'IIIIIIIIIIIIXIIIIIII', 'IIIIIIIIIIIXIIIIIIII', 'IIIIIIIIIIXIIIIIIIII', 'IIIIIIIIIXIIIIIIIIII', 'IIIIIIIIXIIIIIIIIIII', 'IIIIIIIXIIIIIIIIIIII', 'IIIIIIXIIIIIIIIIIIII', 'IIIIIXIIIIIIIIIIIIII', 'IIIIXIIIIIIIIIIIIIII', 'IIIXIIIIIIIIIIIIIIII', 'IIXIIIIIIIIIIIIIIIII', 'IXIIIIIIIIIIIIIIIIII', 'XIIIIIIIIIIIIIIIIIII'],
coeffs=[-1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,
-1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,
-1.+0.j, -1.+0.j, -1.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j,
5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j,
5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j])

Configuration des paramètres de la simulation d'évolution temporelle

Nous utiliserons ici la formule de Lie–Trotter (premier ordre).

num_timesteps = 20
evolution_time = 2.0
dt = evolution_time / num_timesteps
product_formula_lt = LieTrotter()

Préparation du circuit quantique (état initial)

Crée un état initial. Nous partirons de l'état fondamental, qui est un état ferromagnétique (tout en haut ou tout en bas). Ici, nous utilisons un exemple où tous les spins sont en haut (ce qui correspond à tout '0').

initial_circuit = QuantumCircuit(n_qubits)
initial_circuit.prepare_state("00000000000000000000")
# Change reps and see the difference when you decompose the circuit
initial_circuit.decompose(reps=1).draw("mpl")

Output of the previous code cell

Préparation du circuit quantique 2 (circuit unique pour l'évolution temporelle)

Nous construisons ici un circuit pour un unique pas de temps à l'aide de Lie–Trotter. La formule du produit de Lie (premier ordre) est implémentée dans la classe LieTrotter. Une formule du premier ordre consiste en l'approximation énoncée dans l'introduction, où l'exponentielle matricielle d'une somme est approximée par un produit d'exponentielles matricielles :

eH1+H2eH1eH2e^{H_1+H_2} \approx e^{H_1} e^{H_2}

Comptons les opérations de ce circuit.

single_step_evolution_gates_lt = PauliEvolutionGate(
hamiltonian, dt, synthesis=product_formula_lt
)
single_step_evolution_lt = QuantumCircuit(n_qubits)
single_step_evolution_lt.append(
single_step_evolution_gates_lt, single_step_evolution_lt.qubits
)

print(
f"""
Trotter step with Lie-Trotter
-----------------------------
Depth: {single_step_evolution_lt.decompose(reps=3).depth()}
Gate count: {len(single_step_evolution_lt.decompose(reps=3))}
Nonlocal gate count: {single_step_evolution_lt.decompose(reps=3).num_nonlocal_gates()}
Gate breakdown: {", ".join([f"{k.upper()}: {v}" for k, v in single_step_evolution_lt.decompose(reps=3).count_ops().items()])}
"""
)
single_step_evolution_lt.decompose(reps=3).draw("mpl", fold=-1)
Trotter step with Lie-Trotter
-----------------------------
Depth: 58
Gate count: 77
Nonlocal gate count: 38
Gate breakdown: CX: 38, U3: 20, U1: 19

Output of the previous code cell

Définition des opérateurs à mesurer

Définissons un opérateur de magnétisation iZi/N\sum_i Z_i / N.

magnetization = (
SparsePauliOp.from_sparse_list(
[("Z", [i], 1.0) for i in range(0, n_qubits)], num_qubits=n_qubits
)
/ n_qubits
)
print("magnetization : ", magnetization)
magnetization : SparsePauliOp(['IIIIIIIIIIIIIIIIIIIZ', 'IIIIIIIIIIIIIIIIIIZI', 'IIIIIIIIIIIIIIIIIZII', 'IIIIIIIIIIIIIIIIZIII', 'IIIIIIIIIIIIIIIZIIII', 'IIIIIIIIIIIIIIZIIIII', 'IIIIIIIIIIIIIZIIIIII', 'IIIIIIIIIIIIZIIIIIII', 'IIIIIIIIIIIZIIIIIIII', 'IIIIIIIIIIZIIIIIIIII', 'IIIIIIIIIZIIIIIIIIII', 'IIIIIIIIZIIIIIIIIIII', 'IIIIIIIZIIIIIIIIIIII', 'IIIIIIZIIIIIIIIIIIII', 'IIIIIZIIIIIIIIIIIIII', 'IIIIZIIIIIIIIIIIIIII', 'IIIZIIIIIIIIIIIIIIII', 'IIZIIIIIIIIIIIIIIIII', 'IZIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIII'],
coeffs=[0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j,
0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j,
0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j, 0.05+0.j])

Exécution de la simulation d'évolution temporelle

Nous allons suivre la magnétisation (valeur d'espérance de l'opérateur de magnétisation). Nous utiliserons les simulateurs Statevector et MPS et comparerons les résultats.

# Step 1. Map the problem
# Initiate the circuit
evolved_state = QuantumCircuit(initial_circuit.num_qubits)
# Start from the initial spin configuration
evolved_state.append(initial_circuit, evolved_state.qubits)

# Define backend (simulator)
# MPS
backend_mps = AerSimulator(method="matrix_product_state")
# Statevector
backend_sv = AerSimulator(method="statevector")

# Set Runtime Estimator
# MPS
estimator_mps = Estimator(mode=backend_mps)
# Statevector
estimator_sv = Estimator(mode=backend_sv)

# Step 2. Optimize
# Set pass manager
# MPS
pm_mps = generate_preset_pass_manager(optimization_level=3, backend=backend_mps)
# Statevector
pm_sv = generate_preset_pass_manager(optimization_level=3, backend=backend_sv)

# Transpile initial circuit
# MPS
evolved_state_mps = pm_mps.run(evolved_state)
# Statevector
evolved_state_sv = pm_sv.run(evolved_state)

# Apply layout to the operator
# MPS
magnetization_mps = magnetization.apply_layout(evolved_state_mps.layout)
# Statevector
magnetization_sv = magnetization.apply_layout(evolved_state_sv.layout)

mag_mps_list = []
mag_sv_list = []

# Step 3. Run the circuit
# Estimate expectation values for t=0.0: MPS
job = estimator_mps.run([(evolved_state_mps, [magnetization_mps])])
# Get estimated expectation values: MPS
evs = job.result()[0].data.evs
# Collect data: MPS
mag_mps_list.append(evs[0])

# Estimate expectation values for t=0.0: Statevector
job = estimator_sv.run([(evolved_state_sv, [magnetization_sv])])
# Get estimated expectation values: Statevector
evs = job.result()[0].data.evs
# Collect data: Statevector
mag_sv_list.append(evs[0])

# Start time evolution
for n in range(num_timesteps):
# Step 1. Map the problem
# Expand the circuit to describe delta-t
evolved_state.append(single_step_evolution_lt, evolved_state.qubits)
# Step 2. Optimize
# Transpile the circuit: MPS
evolved_state_mps = pm_mps.run(evolved_state)
# Apply the physical layout of the qubits to the operator: MPS
magnetization_mps = magnetization.apply_layout(evolved_state_mps.layout)
# Step 3. Run the circuit
# Estimate expectation values at delta-t: MPS
job = estimator_mps.run([(evolved_state_mps, [magnetization_mps])])
# Get estimated expectation values: MPS
evs = job.result()[0].data.evs
# Collect data: MPS
mag_mps_list.append(evs[0])

# Step 2. Optimize
# Transpile the circuit: Statevector
evolved_state_sv = pm_sv.run(evolved_state)
# Apply the physical layout of the qubits to the operator: Statevector
magnetization_sv = magnetization.apply_layout(evolved_state_sv.layout)
# Step 3. Run the circuit
# Estimate expectation values at delta-t: Statevector
job = estimator_sv.run([(evolved_state_sv, [magnetization_sv])])
# Get estimated expectation values: Statevector
evs = job.result()[0].data.evs
# Collect data: Statevector
mag_sv_list.append(evs[0])

# Transform the list of expectation values (at each time step) to arrays
mag_mps_array = np.array(mag_mps_list)
mag_sv_array = np.array(mag_sv_list)

Représentation graphique de l'évolution temporelle des observables

Nous traçons les valeurs d'espérance mesurées en fonction du temps. Confirme que les résultats des simulateurs statevector et matrix product state coïncident.

import matplotlib.pyplot as plt

# Step 4. Post-processing
fig, axes = plt.subplots(2, sharex=True)
times = np.linspace(0, evolution_time, num_timesteps + 1) # includes initial state
axes[0].plot(
times, mag_mps_array, label="MPS", marker="x", c="darkmagenta", ls="-", lw=0.8
)
axes[1].plot(
times, mag_sv_array, label="SV", marker="x", c="darkmagenta", ls="-", lw=0.8
)

axes[0].set_ylabel("MPS")
axes[1].set_ylabel("Statevector")
axes[1].set_xlabel("Time")
fig.suptitle("Observable evolution")
Text(0.5, 0.98, 'Observable evolution')

Output of the previous code cell

Nous allons commencer à étudier l'évolution temporelle d'un système quantique tout en suivant ses propriétés. Nous comparons ici les résultats du simulateur Matrix Product State avec ceux du dispositif quantique réel.

2.2 Activité 2

Définition de l'Hamiltonien

Le système que nous considérons maintenant a une taille de N=70N=70. Note que les autres conditions sont les mêmes que dans le problème à 20 qubits. Essaie de le faire par toi-même ; fais défiler vers le bas pour voir la solution.

Solution :

# Set the number of qubits
n_qubits2 = 70
# Construct the Hamiltonian by calling the function you made in Activity 1
hamiltonian2 = get_hamiltonian(nqubits=n_qubits2, J=1.0, h=-5.0)
hamiltonian2
SparsePauliOp(['IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZ', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZI', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIX', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXI', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IXIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'XIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII'],
coeffs=[-1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,
-1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,
-1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,
-1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,
-1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,
-1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,
-1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,
-1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,
-1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, 5.+0.j, 5.+0.j, 5.+0.j,
5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j,
5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j,
5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j,
5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j,
5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j,
5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j,
5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j, 5.+0.j,
5.+0.j, 5.+0.j, 5.+0.j])

2.3 Activité 3

Crée un état initial. Nous partirons de l'état fondamental, qui est un état ferromagnétique (tout en haut ou tout en bas). Ici, nous utilisons un exemple où tous les spins sont en haut (ce qui correspond à tout '0'). Essaie de le faire par toi-même ; fais défiler vers le bas pour voir la solution.

Solution :

# Initiate the (quantum)circuit
initial_circuit2 = QuantumCircuit(n_qubits2)
# Use QuantumCircuit.prepare_state() to define the initial state
initial_circuit2.prepare_state(
"0000000000000000000000000000000000000000000000000000000000000000000000"
)
# Change reps and see the difference when you decompose the circuit
initial_circuit2.decompose(reps=1).draw("mpl")

Output of the previous code cell

2.4 Activité 4

Préparation du circuit quantique 2 (circuit unique pour l'évolution temporelle) pour le problème à 70 qubits

Nous construisons ici un circuit pour un unique pas de temps à l'aide de Lie–Trotter. Exactement comme dans le cas à 20 qubits, la formule du produit de Lie (premier ordre) est implémentée dans la classe LieTrotter. Là encore, la formule du premier ordre consiste en l'approximation énoncée précédemment :

eH1+H2eH1eH2e^{H_1+H_2} \approx e^{H_1} e^{H_2}

Essaie de le faire par toi-même, en partant de l'exemple du cas à 20 qubits. Comme précédemment, compte les opérations de ce circuit.

Solution :

# Construct the gates using PauliEvolutionGate()
single_step_evolution_gates_lt2 = PauliEvolutionGate(
hamiltonian2, dt, synthesis=LieTrotter()
)
# Initiate the quantum circuit
single_step_evolution_lt2 = QuantumCircuit(n_qubits2)
# Append the gates defined above
single_step_evolution_lt2.append(
single_step_evolution_gates_lt2, single_step_evolution_lt2.qubits
)

print(
f"""
Trotter step with Lie-Trotter
-----------------------------
Depth: {single_step_evolution_lt2.decompose(reps=3).depth()}
Gate count: {len(single_step_evolution_lt2.decompose(reps=3))}
Nonlocal gate count: {single_step_evolution_lt2.decompose(reps=3).num_nonlocal_gates()}
Gate breakdown: {", ".join([f"{k.upper()}: {v}" for k, v in single_step_evolution_lt2.decompose(reps=3).count_ops().items()])}
"""
)
single_step_evolution_lt2.decompose(reps=3).draw("mpl", fold=-1)
Trotter step with Lie-Trotter
-----------------------------
Depth: 208
Gate count: 277
Nonlocal gate count: 138
Gate breakdown: CX: 138, U3: 70, U1: 69

Output of the previous code cell

2.5 Activité 5

Définition des opérateurs à mesurer

Nous définissons un opérateur de magnétisation exactement analogue à celui du cas à 20 qubits : iZi/N\sum_i Z_i / N. Essaie de le faire par toi-même en modifiant la solution du cas à 20 qubits.

Solution :

# Define the magnetization operator in SparsePauliOp
magnetization2 = (
SparsePauliOp.from_sparse_list(
[("Z", [i], 1.0) for i in range(0, n_qubits2)], num_qubits=n_qubits2
)
/ n_qubits2
)
print("magnetization : ", magnetization2)
magnetization : SparsePauliOp(['IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZ', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZI', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IIZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'IZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII', 'ZIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII'],
coeffs=[0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,
0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,
0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,
0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,
0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,
0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,
0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,
0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,
0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,
0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,
0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,
0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,
0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,
0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,
0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,
0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,
0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j, 0.01428571+0.j,
0.01428571+0.j, 0.01428571+0.j])

2.6 Activité 6

Exécution de la simulation d'évolution temporelle

Nous allons suivre la magnétisation (valeur d'espérance de l'opérateur de magnétisation). Nous utiliserons le simulateur MPS pour obtenir la valeur de référence à laquelle comparer les résultats calculés sur le matériel. Tu as déjà utilisé le simulateur MPS auparavant dans ce tutoriel. Modifie cet exemple là où nécessaire pour l'adapter à ce nouveau calcul.

Solution :

# Step 1. Map the problem
# Initiate the circuit
evolved_state2 = QuantumCircuit(initial_circuit2.num_qubits)
# Start from the initial spin configuration
evolved_state2.append(initial_circuit2, evolved_state2.qubits)
# Define backend (MPs simulator)
backend_mps2 = AerSimulator(method="matrix_product_state")
# Initiate Runtime Estimator
estimator_mps2 = Estimator(mode=backend_mps2)
# Step 2. Optimize
# Initiate pass manager
pm_mps2 = generate_preset_pass_manager(optimization_level=3, backend=backend_mps2)
# Transpile
evolved_state_mps2 = pm_mps2.run(evolved_state2)
# Apply qubit layout to the observable to measure
magnetization_mps2 = magnetization2.apply_layout(evolved_state_mps2.layout)
# Initiate list
mag_mps_list2 = []
# Step 3. Run the circuit
# Estimate expectation values for t=0.0
job = estimator_mps2.run([(evolved_state_mps2, [magnetization_mps2])])
# Get estimated expectation values
evs = job.result()[0].data.evs
# Append to list
mag_mps_list2.append(evs[0])

# Start time evolution
for n in range(num_timesteps):
# Step 1. Map the problem
# Expand the circuit to describe delta-t
evolved_state2.append(single_step_evolution_lt2, evolved_state2.qubits)
# Step 2. Optimize
# Transpile the circuit
evolved_state_mps2 = pm_mps2.run(evolved_state2)
# Apply the physical layout of the qubits to the operator
magnetization_mps2 = magnetization2.apply_layout(evolved_state_mps2.layout)
# Step 3. Run the circuit
# Estimate expectation values at delta-t
job = estimator_mps2.run([(evolved_state_mps2, [magnetization_mps2])])
# Get estimated expectation values
evs = job.result()[0].data.evs
# Append to list
mag_mps_list2.append(evs[0])
# Transform the list of expectation values (at each time step) to arrays
mag_mps_array2 = np.array(mag_mps_list2)

Comme dans toutes les leçons précédentes, nous allons mettre en œuvre le cadre des « Qiskit patterns ». La leçon, jusqu'ici, s'est concentrée sur la création des circuits quantiques corrects pour décrire notre problème. Cela correspond en fait à l'Étape 1.

Étape 2 : optimisation pour le matériel cible

Nous commençons par définir le backend cible.

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
backend.name
'ibm_kingston'

Nous transpilons les circuits et les rassemblons dans une liste. Cela peut prendre quelques minutes.

pm_hw = generate_preset_pass_manager(optimization_level=3, backend=backend)
circuit_isa = []
# Step 1. Map the problem
evolved_state_hw = QuantumCircuit(initial_circuit2.num_qubits)
evolved_state_hw.append(initial_circuit2, evolved_state_hw.qubits)
# Step 2. Optimize
circuit_isa.append(pm_hw.run(evolved_state_hw))

for n in range(num_timesteps):
# Step 1. Map the problem
evolved_state_hw.append(single_step_evolution_lt2, evolved_state_hw.qubits)
# Step 2. Optimize
circuit_isa.append(pm_hw.run(evolved_state_hw))

Étape 3 : exécution sur le matériel cible

Nous allons définir l'Estimator de Runtime et construire la liste des PUB. Nous devons aussi appliquer le layout aux opérateurs à mesurer.

# Step 2. Optimize
estimator_hw = Estimator(mode=backend)
pub_list = []
for circuit in circuit_isa:
temp = (circuit, magnetization2.apply_layout(circuit.layout))
pub_list.append(temp)

Nous sommes maintenant prêts à exécuter le job.

job = estimator_hw.run(pub_list)
job_id = job.job_id()
print(job_id)
d147hfdqf56g0081sxs0
# check job status
job.status()
'DONE'

Étape 4 : post-traitement des résultats

Nous allons d'abord récupérer les résultats.

job = service.job(job_id)
pub_result = job.result()

Nous devons maintenant extraire les valeurs d'espérance de ces résultats.

mag_hw_list = []
for res in pub_result:
evs = res.data.evs
mag_hw_list.append(evs)

Nous utiliserons cela pour la comparaison ci-dessous. Voyons d'abord si nous pouvons optimiser encore davantage nos circuits.

3. Solution utilisant un véritable ordinateur quantique II

Revenons à l'étape 1 des Qiskit patterns, et voyons si nous pouvons réduire la profondeur de notre circuit.

3.1 Étape 1. Mapper le problème sur des circuits et des opérateurs quantiques

Activité 7

Construis un circuit d'évolution temporelle. Utilise tes connaissances des leçons précédentes pour essayer de réduire la profondeur du circuit.

Solution :

# Define J
J = 1.0
# Define h
h = -5.0
# Create instruction for rotation around ZZ:
# Initiate the circuit (use 2 qubits)
Rzz_circ = QuantumCircuit(2)
# Add Rzz gate (do not forget to multiply the angle by 2.0)
Rzz_circ.rzz(-J * dt * 2.0, 0, 1)
# Transform the QuantumCircuit to instruction (QuantumCircuit.to_instruction())
Rzz_instr = Rzz_circ.to_instruction(label="RZZ")

# Create instruction for rotation around X:
# Initiate the circuit (use 1 qubit)
Rx_circ = QuantumCircuit(1)
# Add Rx gate (do not forget to multiply the angle by 2.0)
Rx_circ.rx(-h * dt * 2.0, 0)
# Transform the QuantumCircuit to instruction (QuantumCircuit.to_instruction())
Rx_instr = Rx_circ.to_instruction(label="RX")

# Define the interaction list
interaction_list = [
[[i, i + 1] for i in range(0, n_qubits2 - 1, 2)],
[[i, i + 1] for i in range(1, n_qubits2 - 1, 2)],
] # linear chain

# Define the registers
qr = QuantumRegister(n_qubits2)
# Initiate the circuit
single_step_evolution_sh = QuantumCircuit(qr)
# Construct the Rzz gates
for i, color in enumerate(interaction_list):
for interaction in color:
single_step_evolution_sh.append(Rzz_instr, interaction)

# Construct the Rx gates
for i in range(0, n_qubits2):
single_step_evolution_sh.append(Rx_instr, [i])

print(
f"""
Trotter step with Lie-Trotter
-----------------------------
Depth: {single_step_evolution_sh.decompose(reps=3).depth()}
Gate count: {len(single_step_evolution_sh.decompose(reps=3))}
Nonlocal gate count: {single_step_evolution_sh.decompose(reps=3).num_nonlocal_gates()}
Gate breakdown: {", ".join([f"{k.upper()}: {v}" for k, v in single_step_evolution_sh.decompose(reps=3).count_ops().items()])}
"""
)

single_step_evolution_sh.decompose(reps=2).draw("mpl")
Trotter step with Lie-Trotter
-----------------------------
Depth: 7
Gate count: 277
Nonlocal gate count: 138
Gate breakdown: CX: 138, U3: 70, U1: 69

Output of the previous code cell

Ce fut un franc succès. Nous pouvons maintenant poursuivre avec les étapes restantes des Qiskit patterns.

3.2 Étape 2. Optimiser pour le matériel cible

Transpile les circuits et rassemble-les dans une liste. Là encore, cela peut prendre quelques minutes.

pm_hw2 = generate_preset_pass_manager(backend=backend, optimization_level=3)
circuit_isa2 = []
# Step 1. Map the problem
evolved_state_hw2 = QuantumCircuit(initial_circuit2.num_qubits)
evolved_state_hw2.append(initial_circuit2, evolved_state_hw2.qubits)
# Step 2. Optimize
circuit_isa2.append(pm_hw2.run(evolved_state_hw2))
for n in range(num_timesteps):
# Step 1. Map the problem
evolved_state_hw2.append(single_step_evolution_sh, evolved_state_hw2.qubits)
# Step 2. Optimize
circuit_isa2.append(pm_hw2.run(evolved_state_hw2))

Définis l'Estimator de Runtime et construis la liste des PUB.

estimator_hw2 = Estimator(mode=backend)
pub_list2 = []
for circuit in circuit_isa2:
temp = (circuit, magnetization2.apply_layout(circuit.layout))
pub_list2.append(temp)

3.3 Étape 3. Exécuter sur le matériel cible

Exécute le job.

job2 = estimator_hw2.run(pub_list2)
job2_id = job2.job_id()
print(job2_id)
d147qqeqf56g0081sye0
# check job status
job2.status()
'DONE'

Récupère les résultats.

job2 = service.job(job2_id)
pub_result2 = job2.result()

3.4 Étape 4. Post-traitement

Extrais les valeurs d'espérance des résultats.

mag_hw_list2 = []
for res in pub_result2:
evs = res.data.evs
mag_hw_list2.append(evs)

Transforme la liste en tableaux numpy en vue du tracé.

mag_hw_array = np.array(mag_hw_list)
mag_hw_array2 = np.array(mag_hw_list2)

Traçons maintenant les résultats et comparons les résultats du matériel (circuit par défaut et circuit peu profond) avec ceux du simulateur MPS. Comment l'erreur du matériel réel influence-t-elle les résultats ?

fig, axes = plt.subplots(3, sharex=True)
times = np.linspace(0, evolution_time, num_timesteps + 1) # includes initial state
axes[0].plot(
times, mag_mps_array2, label="MPS", marker="x", c="darkmagenta", ls="-", lw=0.8
)
axes[1].plot(
times, mag_hw_array, label="HW", marker="x", c="darkmagenta", ls="-", lw=0.8
)
axes[2].plot(
times, mag_hw_array2, label="HW2", marker="x", c="darkmagenta", ls="-", lw=0.8
)
axes[0].set_ylabel("MPS")
axes[1].set_ylabel("HW")
axes[2].set_ylabel("HW2")
axes[2].set_xlabel("Time")
fig.suptitle("Observable evolution")
Text(0.5, 0.98, 'Observable evolution')

Output of the previous code cell

Félicitations ! Tu as franchi une étape de plus dans ton parcours vers l'informatique quantique à l'échelle de l'utilité. Il ne reste plus qu'une seule leçon !