Nota

Esta página fue generada a partir de docs/tutorials/00_amplitude_estimation.ipynb.

Estimación de Amplitud Cuántica#

Dado un operador \(\mathcal{A}\) que actúa como

\[\mathcal{A}|0\rangle = \sqrt{1 - a}|\Psi_0\rangle + \sqrt{a}|\Psi_1\rangle\]

La Estimación de Amplitud Cuántica (Quantum Amplitude Estimation, QAE) es la tarea de encontrar una estimación de la amplitud \(a\) del estado \(|\Psi_1\rangle\):

\[a = |\langle\Psi_1 | \Psi_1\rangle|^2.\]

Esta tarea fue investigada por primera vez por Brassard et al. [1] en 2000 y su algoritmo utiliza una combinación del operador Grover

\[\mathcal{Q} = \mathcal{A}\mathcal{S}_0\mathcal{A}^\dagger\mathcal{S}_{\Psi_1}\]

donde \(\mathcal{S}_0\) y \(\mathcal{S}_{\Psi_1}\) son reflexiones sobre los estados \(|0\rangle\) y \(|\Psi_1\rangle\), respectivamente, y la estimación de fase. Sin embargo, este algoritmo, llamado AmplitudeEstimation en Qiskit Algorithms, requiere circuitos grandes y es computacionalmente costoso. Por lo tanto, se han propuesto otras variantes de QAE, que mostraremos en este tutorial para un ejemplo simple.

En nuestro ejemplo, \(\mathcal{A}\) describe una variable aleatoria de Bernoulli con (supongamos desconocida) probabilidad de éxito \(p\):

\[\mathcal{A}|0\rangle = \sqrt{1 - p}|0\rangle + \sqrt{p}|1\rangle.\]

En una computadora cuántica, podemos modelar este operador con una rotación alrededor del eje \(Y\) de un solo qubit

\[\mathcal{A} = R_Y(\theta_p), \theta_p = 2\sin^{-1}(\sqrt{p}).\]

El operador Grover para este caso es particularmente simple

\[\mathcal{Q} = R_Y(2\theta_p),\]

cuyas potencias son muy fáciles de calcular: \(\mathcal{Q}^k = R_Y(2k\theta_p)\).

Fijaremos la probabilidad que queremos estimar en \(p = 0.2\).

[1]:
p = 0.2

Ahora podemos definir circuitos para \(\mathcal{A}\) y \(\mathcal{Q}\).

[2]:
import numpy as np
from qiskit.circuit import QuantumCircuit


class BernoulliA(QuantumCircuit):
    """A circuit representing the Bernoulli A operator."""

    def __init__(self, probability):
        super().__init__(1)  # circuit on 1 qubit

        theta_p = 2 * np.arcsin(np.sqrt(probability))
        self.ry(theta_p, 0)


class BernoulliQ(QuantumCircuit):
    """A circuit representing the Bernoulli Q operator."""

    def __init__(self, probability):
        super().__init__(1)  # circuit on 1 qubit

        self._theta_p = 2 * np.arcsin(np.sqrt(probability))
        self.ry(2 * self._theta_p, 0)

    def power(self, k):
        # implement the efficient power of Q
        q_k = QuantumCircuit(1)
        q_k.ry(2 * k * self._theta_p, 0)
        return q_k
[3]:
A = BernoulliA(p)
Q = BernoulliQ(p)

Flujo de Trabajo de Estimación de Amplitud#

Qiskit Algorithms implementa varios algoritmos QAE que se derivan de la interfaz AmplitudeEstimator. En el inicializador especificamos la configuración específica del algoritmo y el método de estimate que hace todo el trabajo, toma un EstimationProblem como entrada y devuelve un objeto AmplitudeEstimationResult. Dado que todas las variantes de QAE siguen la misma interfaz, podemos usarlas todas para resolver la misma instancia de problema.

A continuación, ejecutaremos todos los diferentes algoritmos de QAE. Para hacerlo, primero definimos el problema de estimación que contendrá los operadores \(\mathcal{A}\) y \(\mathcal{Q}\) así como también cómo identificar el estado \(|\Psi_1\rangle\), que en este ejemplo simple es \(|1\rangle\).

[4]:
from qiskit_algorithms import EstimationProblem

problem = EstimationProblem(
    state_preparation=A,  # A operator
    grover_operator=Q,  # Q operator
    objective_qubits=[0],  # the "good" state Psi1 is identified as measuring |1> in qubit 0
)

Para ejecutar circuitos usaremos Sampler.

[5]:
from qiskit.primitives import Sampler

sampler = Sampler()

AE Canónica#

Ahora solucionemos esto con la implementación QAE original de Brassard et al. [1].

[6]:
from qiskit_algorithms import AmplitudeEstimation

ae = AmplitudeEstimation(
    num_eval_qubits=3,  # the number of evaluation qubits specifies circuit width and accuracy
    sampler=sampler,
)

Con el algoritmo definido, podemos llamar al método estimate y proporcionarle el problema a resolver.

[7]:
ae_result = ae.estimate(problem)

La estimación está disponible en la llave de estimation:

[8]:
print(ae_result.estimation)
0.1464466

¡Vemos que esta no es una estimación muy buena para nuestro objetivo de \(p=0.2\)! Eso se debe al hecho de que la AE canónica está restringida a una cuadrícula discreta, especificada por el número de qubits de evaluación:

[9]:
import matplotlib.pyplot as plt

# plot estimated values
gridpoints = list(ae_result.samples.keys())
probabilities = list(ae_result.samples.values())

plt.bar(gridpoints, probabilities, width=0.5 / len(probabilities))
plt.axvline(p, color="r", ls="--")
plt.xticks(size=15)
plt.yticks([0, 0.25, 0.5, 0.75, 1], size=15)
plt.title("Estimated Values", size=15)
plt.ylabel("Probability", size=15)
plt.xlabel(r"Amplitude $a$", size=15)
plt.ylim((0, 1))
plt.grid()
plt.show()
../_images/tutorials_00_amplitude_estimation_18_0.png

Para mejorar la estimación, podemos interpolar las probabilidades de medición y calcular el estimador de máxima verosimilitud que produce esta distribución de probabilidad:

[10]:
print("Interpolated MLE estimator:", ae_result.mle)
Interpolated MLE estimator: 0.19999999406856905

Podemos echar un vistazo al circuito que AE ejecuta:

[11]:
ae_circuit = ae.construct_circuit(problem)
ae_circuit.decompose().draw(
    "mpl", style="iqx"
)  # decompose 1 level: exposes the Phase estimation circuit!
[11]:
../_images/tutorials_00_amplitude_estimation_22_0.png
[12]:
from qiskit import transpile


basis_gates = ["h", "ry", "cry", "cx", "ccx", "p", "cp", "x", "s", "sdg", "y", "t", "cz"]
transpile(ae_circuit, basis_gates=basis_gates, optimization_level=2).draw("mpl", style="iqx")
[12]:
../_images/tutorials_00_amplitude_estimation_23_0.png

Estimación de Amplitud Iterativa#

Véase [2].

[13]:
from qiskit_algorithms import IterativeAmplitudeEstimation

iae = IterativeAmplitudeEstimation(
    epsilon_target=0.01,  # target accuracy
    alpha=0.05,  # width of the confidence interval
    sampler=sampler,
)
iae_result = iae.estimate(problem)

print("Estimate:", iae_result.estimation)
Estimate: 0.2

¡Los circuitos de aquí solo consisten en potencias de Grover y son mucho más baratos!

[14]:
iae_circuit = iae.construct_circuit(problem, k=3)
iae_circuit.draw("mpl", style="iqx")
[14]:
../_images/tutorials_00_amplitude_estimation_27_0.png

Estimación de Amplitud de Máxima Verosimilitud#

Véase [3].

[15]:
from qiskit_algorithms import MaximumLikelihoodAmplitudeEstimation

mlae = MaximumLikelihoodAmplitudeEstimation(
    evaluation_schedule=3,  # log2 of the maximal Grover power
    sampler=sampler,
)
mlae_result = mlae.estimate(problem)

print("Estimate:", mlae_result.estimation)
Estimate: 0.20002237175368104

Estimación de Amplitud Más Rápida#

Véase [4].

[18]:
from qiskit_algorithms import FasterAmplitudeEstimation

fae = FasterAmplitudeEstimation(
    delta=0.01,  # target accuracy
    maxiter=3,  # determines the maximal power of the Grover operator
    sampler=sampler,
)
fae_result = fae.estimate(problem)

print("Estimate:", fae_result.estimation)
Estimate: 0.2030235918323876

Referencias#

[1] Quantum Amplitude Amplification and Estimation. Brassard et al (2000). https://arxiv.org/abs/quant-ph/0005055

[2] Iterative Quantum Amplitude Estimation. Grinko, D., Gacon, J., Zoufal, C., & Woerner, S. (2019). https://arxiv.org/abs/1912.05559

[3] Amplitude Estimation without Phase Estimation. Suzuki, Y., Uno, S., Raymond, R., Tanaka, T., Onodera, T., & Yamamoto, N. (2019). https://arxiv.org/abs/1904.10246

[4] Faster Amplitude Estimation. K. Nakaji (2020). https://arxiv.org/pdf/2003.02417.pdf

[17]:
import qiskit.tools.jupyter

%qiskit_version_table
%qiskit_copyright

Version Information

SoftwareVersion
qiskitNone
qiskit-terra0.45.0.dev0+c626be7
qiskit_ibm_provider0.6.1
qiskit_algorithms0.2.0
System information
Python version3.9.7
Python compilerGCC 7.5.0
Python builddefault, Sep 16 2021 13:09:58
OSLinux
CPUs2
Memory (Gb)5.778430938720703
Fri Aug 18 15:44:17 2023 EDT

This code is a part of Qiskit

© Copyright IBM 2017, 2023.

This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.

[ ]: