Skip to main content
IBM Quantum Platform

Simulación eficiente de circuitos estabilizadores con primitivas Aer de Qiskit

  • El código de esta página se ha desarrollado teniendo en cuenta los siguientes requisitos. Recomendamos utilizar estas versiones o versiones más recientes.

    qiskit[all]~=2.5.0
    qiskit-aer~=0.17
    

Esta página muestra cómo usar las primitivas Qiskit Aer para simular eficientemente circuitos estabilizadores, incluyendo aquellos sujetos a ruido Pauli.

Los circuitos estabilizadores, también conocidos como circuitos Clifford, son una importante clase restringida de circuitos cuánticos que pueden simularse de manera eficiente de forma clásica. Hay varias formas equivalentes de definir los circuitos estabilizadores. Una definición es que un circuito estabilizador es un circuito cuántico que consta únicamente de las siguientes puertas:

Nótese que usando Hadamard y S, podemos construir cualquier puerta de rotación Pauli ( RxR_x, RyR_y y RzR_z ) que tenga un ángulo contenido en el conjunto {0,π2,π,3π2}\{0, \frac{\pi}{2}, \pi, \frac{3\pi}{2}\} (hasta la fase global), por lo que también podemos incluir estas puertas en la definición.

Los circuitos estabilizadores son importantes para el estudio de la corrección cuántica de errores. Su simulabilidad clásica también los hace útiles para verificar los resultados de los ordenadores cuánticos. Por ejemplo, supongamos que desea ejecutar un circuito cuántico que utiliza 100 qubits en un ordenador cuántico. ¿Cómo se sabe que el ordenador cuántico se comporta correctamente? Un circuito cuántico de 100 qubits está fuera del alcance de la simulación clásica por fuerza bruta. Modificando su circuito para que se convierta en un circuito estabilizador, puede ejecutar circuitos en el ordenador cuántico que tengan una estructura similar a la de su circuito deseado, pero que pueda simular en un ordenador clásico. Si comprueba la salida del ordenador cuántico en los circuitos estabilizadores, podrá estar seguro de que también se comporta correctamente en los circuitos no estabilizadores. Véase Evidence for the utility of quantum computing before fault tolerance para un ejemplo de esta idea en la práctica.

Exact and noisy simulation with Qiskit Aer primitives muestra cómo utilizar Qiskit Aer para realizar simulaciones exactas y ruidosas de circuitos cuánticos genéricos. Consideremos el circuito de ejemplo utilizado en ese artículo, un circuito de 8 qubits construido utilizando efficient_su2 :

from qiskit.circuit.library import efficient_su2

n_qubits = 8
circuit = efficient_su2(n_qubits)
circuit.draw("mpl")

Output:

Output of the previous code cell

Utilizando Qiskit Aer, hemos podido simular este circuito fácilmente. Sin embargo, supongamos que fijamos el número de qubits en 500:

n_qubits = 500
circuit = efficient_su2(n_qubits)
# don't try to draw the circuit because it's too large

Dado que el coste de simulación de los circuitos cuánticos aumenta exponencialmente con el número de qubits, un circuito tan grande superaría en general las capacidades incluso de un simulador de alto rendimiento como Qiskit Aer. La simulación clásica de circuitos cuánticos genéricos resulta inviable cuando el número de qubits supera aproximadamente entre 50 y 100 qubits. Sin embargo, nótese que el circuito efficient_su2 está parametrizado por ángulos en las puertas RyR_y y RzR_z. Si todos estos ángulos están contenidos en el conjunto {0,π2,π,3π2}\{0, \frac{\pi}{2}, \pi, \frac{3\pi}{2}\}, entonces el circuito es un circuito estabilizador, ¡y puede ser simulado eficientemente!

En la siguiente celda, ejecutamos el circuito con la primitiva Sampler respaldada por el simulador de circuito estabilizador, utilizando parámetros elegidos aleatoriamente de forma que se garantice que el circuito es un circuito estabilizador.

import numpy as np
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_aer import AerSimulator
from qiskit_aer.primitives import SamplerV2 as Sampler

measured_circuit = circuit.copy()
measured_circuit.measure_all()

rng = np.random.default_rng(1234)
params = rng.choice(
    [0, np.pi / 2, np.pi, 3 * np.pi / 2],
    size=circuit.num_parameters,
)

# Initialize a Sampler backed by the stabilizer circuit simulator
exact_sampler = Sampler(
    options=dict(backend_options=dict(method="stabilizer"))
)
# The circuit needs to be transpiled to the AerSimulator target
pass_manager = generate_preset_pass_manager(
    1, AerSimulator(method="stabilizer")
)
isa_circuit = pass_manager.run(measured_circuit)
pub = (isa_circuit, params)
job = exact_sampler.run([pub])
result = job.result()
pub_result = result[0]
counts = pub_result.data.meas.get_counts()

El simulador de circuitos estabilizadores también admite la simulación de ruido, pero sólo para una clase restringida de modelos de ruido. En concreto, cualquier ruido cuántico debe caracterizarse por un canal de error Pauli. El error de despolarización entra en esta categoría, por lo que también puede simularse. También se pueden simular canales de ruido clásicos como el error de lectura.

La siguiente celda de código ejecuta la misma simulación que antes, pero esta vez especificando un modelo de ruido que añade un error de despolarización del 2% a cada puerta CX, así como un error de lectura que invierte cada bit medido con un 5% de probabilidad.

from qiskit_aer.noise import NoiseModel, depolarizing_error, ReadoutError

noise_model = NoiseModel()
cx_depolarizing_prob = 0.02
bit_flip_prob = 0.05
noise_model.add_all_qubit_quantum_error(
    depolarizing_error(cx_depolarizing_prob, 2), ["cx"]
)
noise_model.add_all_qubit_readout_error(
    ReadoutError(
        [
            [1 - bit_flip_prob, bit_flip_prob],
            [bit_flip_prob, 1 - bit_flip_prob],
        ]
    )
)

noisy_sampler = Sampler(
    options=dict(
        backend_options=dict(method="stabilizer", noise_model=noise_model)
    )
)
job = noisy_sampler.run([pub])
result = job.result()
pub_result = result[0]
counts = pub_result.data.meas.get_counts()

Ahora, utilicemos la primitiva Estimador respaldada por el simulador del estabilizador para calcular el valor de la expectativa del observable ZZZZZ \cdots Z. Debido a la estructura especial de los circuitos estabilizadores, es muy probable que el resultado sea 0.

from qiskit.quantum_info import SparsePauliOp
from qiskit_aer.primitives import EstimatorV2 as Estimator

observable = SparsePauliOp("Z" * n_qubits)

exact_estimator = Estimator(
    options=dict(backend_options=dict(method="stabilizer")),
)
isa_circuit = pass_manager.run(circuit)
pub = (isa_circuit, observable, params)
job = exact_estimator.run([pub])
result = job.result()
pub_result = result[0]
exact_value = float(pub_result.data.evs)
exact_value

Output:

0.0

Próximos pasos

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