Skip to main content
IBM Quantum Platform

Utilizar diferentes normas Lp para el truncamiento del término de Pauli

Nota: Antes de leer esta guía, debes consultar la guía sobre los términos de Pauli truncados, en la que se describe el truncamiento de los términos de Pauli de bajo peso que se integra en el método de retropropagación basándose en un « TruncationErrorBudget » especificado.

En esta guía, aprenderás sobre el argumento de palabra clave «backpropagate» p_norm, que se puede utilizar para modificar la norma Lp empleada para estimar el error derivado de los términos de Pauli truncados.


Construye un circuito de ejemplo

Esta guía utiliza el mismo circuito de ejemplo que la guía sobre los términos truncados de Pauli :

import rustworkx.generators
from qiskit.synthesis import LieTrotter
from qiskit_addon_utils.problem_generators import (
    PauliOrderStrategy,
    generate_time_evolution_circuit,
    generate_xyz_hamiltonian,
)
from qiskit_addon_utils.slicing import combine_slices, slice_by_gate_types

# Generate a linear chain of 10 qubits
num_qubits = 10
linear_chain = rustworkx.generators.path_graph(num_qubits)

# Use an arbitrary XY model
hamiltonian = generate_xyz_hamiltonian(
    linear_chain,
    coupling_constants=(0.05, 0.02, 0.0),
    ext_magnetic_field=(0.02, 0.08, 0.0),
    pauli_order_strategy=PauliOrderStrategy.InteractionThenColor,
)
# Evolve for some time
circuit = generate_time_evolution_circuit(
    hamiltonian, synthesis=LieTrotter(reps=3), time=2.0
)
# slice the circuit by gate type
slices = slice_by_gate_types(circuit)

# For visualization purposes only, recombine the slices with barriers between them and draw the resulting circuit
combine_slices(slices, include_barriers=True).draw("mpl", fold=50, scale=0.6)

Output:

Output of the previous code cell

Define una observable para la magnetización total:

from qiskit.quantum_info import SparsePauliOp

obs = SparsePauliOp.from_sparse_list(
    [("Z", [i], 1.0) for i in range(num_qubits)], num_qubits=num_qubits
)

A modo de referencia, calcula el valor exacto de la esperanza:

from qiskit.primitives import StatevectorEstimator

estimator = StatevectorEstimator()
job = estimator.run([(circuit, obs)])
res = job.result()
exact_exp = res[0].data.evs
print(exact_exp)

Output:

9.318197859862146

Utiliza la norma « L1 »

Por defecto, y tal y como ya has visto en la guía sobre los términos truncados de Pauli, p_norm=1, lo que significa que el error se estima como:

ψΔψPTcP|\langle\psi|\Delta|\psi\rangle| \leq \sum_{P\in\mathcal{T}} |c_P|

donde ψ\psi es el estado cuántico, Δ\Delta es la diferencia real entre la observable exacta y la truncada (que se desconoce), T\mathcal{T} es el conjunto de términos de Pauli que se han truncado, y cPc_P es el coeficiente de los términos de Pauli. Esta desigualdad constituye un límite superior riguroso, aunque muy holgado, para la mayoría de los casos.

Esta guía realiza la retropropagación de seis secciones del circuito de ejemplo, utilizando un error constante por sección de 0.001. Este valor debe entenderse como el presupuesto dentro del marco establecido p_norm.

from qiskit_addon_obp.utils.truncating import setup_budget

l1_truncation_error_budget = setup_budget(max_error_per_slice=0.001, p_norm=1)
print(l1_truncation_error_budget)

Output:

TruncationErrorBudget(per_slice_budget=[0.001], max_error_total=inf, p_norm=1)
from qiskit_addon_obp import backpropagate

max_slices = 6
l1_bp_obs, l1_remaining_slices, l1_metadata = backpropagate(
    obs,
    slices[-max_slices:],
    truncation_error_budget=l1_truncation_error_budget,
)
l1_reduced_circuit = combine_slices(
    slices[:-max_slices] + l1_remaining_slices
)
print(
    f"Backpropagated {max_slices - len(l1_remaining_slices)} circuit slices."
)
print(
    f"New observable contains {len(l1_bp_obs)} terms and {len(l1_bp_obs.group_commuting(qubit_wise=True))} commuting groups."
)

Output:

Backpropagated 6 circuit slices.
New observable contains 116 terms and 10 commuting groups.

Ahora podemos calcular el valor esperado de la observable retropropagada, así como el error con respecto a la referencia exacta:

estimator = StatevectorEstimator()
job = estimator.run([(l1_reduced_circuit, l1_bp_obs)])
res = job.result()
l1_exp = res[0].data.evs
l1_error = exact_exp - l1_exp
print(l1_exp, l1_error)

Output:

9.317869899338842 0.00032796052330397174

Por último, podemos representar gráficamente el error producido durante la retropropagación de cada corte, así como el error acumulado. El error acumulado es la suma de los errores de cada segmento. Podemos observar que el error acumulado es un límite superior muy aproximado del error real.

from matplotlib import pyplot as plt
from qiskit_addon_obp.utils.visualization import (
    plot_accumulated_error,
    plot_slice_errors,
)

fig, axes = plt.subplots(1, 2, figsize=(14, 5))
axes[1].plot([6], [l1_error], "x", color="red", label="actual error")
plot_slice_errors(l1_metadata, axes[0])
plot_accumulated_error(l1_metadata, axes[1])

Output:

Output of the previous code cell

Utiliza la norma « L2 »

Se podría argumentar que la norma « L2 » es una mejor aproximación al error incurrido que la norma « L1 ». Esto se debe a que podemos suponer que el estado cuántico ψ|\psi\rangle procede de un conjunto aleatorio de Haar, en cuyo caso el error incurrido sigue una distribución con una media nula y una varianza que puede limitarse aproximadamente mediante la norma de L2 :

ψΔψ(PTcP2)1/2|\langle\psi|\Delta|\psi\rangle| \lesssim \left( \sum_{P\in\mathcal{T}} |c_P|^2 \right)^{1/2}

Aunque el límite no es riguroso, solo se incumplirá en casos patológicos.

Volvemos a realizar la retropropagación en seis secciones del circuito de ejemplo, utilizando un error máximo por sección de 0.001 (esta vez, interpretado según la norma L2 ).

l2_truncation_error_budget = setup_budget(max_error_per_slice=0.001, p_norm=2)
print(l2_truncation_error_budget)

Output:

TruncationErrorBudget(per_slice_budget=[0.001], max_error_total=inf, p_norm=2)
max_slices = 6
l2_bp_obs, l2_remaining_slices, l2_metadata = backpropagate(
    obs,
    slices[-max_slices:],
    truncation_error_budget=l2_truncation_error_budget,
)
l2_reduced_circuit = combine_slices(
    slices[:-max_slices] + l2_remaining_slices
)
print(
    f"Backpropagated {max_slices - len(l2_remaining_slices)} circuit slices."
)
print(
    f"New observable contains {len(l2_bp_obs)} terms and {len(l2_bp_obs.group_commuting(qubit_wise=True))} commuting groups."
)

Output:

Backpropagated 6 circuit slices.
New observable contains 84 terms and 6 commuting groups.

De nuevo, calculamos el valor esperado de la observable retropropagada y el error con respecto a la referencia exacta:

estimator = StatevectorEstimator()
job = estimator.run([(l2_reduced_circuit, l2_bp_obs)])
res = job.result()
l2_exp = res[0].data.evs
l2_error = exact_exp - l2_exp
print(l2_exp, l2_error)

Output:

9.317829770853422 0.00036808900872387085

Al representar gráficamente los errores incurridos por segmento y el error acumulado, se obtiene un panorama similar al anterior.

fig, axes = plt.subplots(1, 2, figsize=(14, 5))
axes[1].plot([6], [l2_error], "x", color="red", label="actual error")
plot_slice_errors(l2_metadata, axes[0])
plot_accumulated_error(l2_metadata, axes[1])

Output:

Output of the previous code cell

Ten en cuenta que el error acumulado es, una vez más, la suma de los errores de cada corte. Este es otro límite aproximado debido a la desigualdad de Minkowski, ya que tenemos que calcular este límite de forma recursiva:

ψΔiψψΔ~i1ψ+(PTicP2)1/2=ψΔ~iψ|\langle\psi|\Delta_{i}|\psi\rangle| \leq |\langle\psi|\tilde{\Delta}_{i-1}|\psi\rangle| + \left( \sum_{P\in\mathcal{T_i}} |c_P|^2 \right)^{1/2} = |\langle\psi|\tilde{\Delta}_{i}|\psi\rangle|

donde el nuevo subíndice ii indica la iteración actual del corte, de modo que Δi\Delta_i es el error real en la iteración de retropropagación ii, Δ~i1\tilde{\Delta}_{i-1} es el error de truncamiento aproximado de la iteración i1i-1, y Ti\mathcal{T}_i es el conjunto de términos de Pauli truncados en la iteración ii.

¿Le ha resultado útil esta página?
Informe de un error, de una errata o solicite contenido en GitHub.