Quantum Amplitude Estimation#
- QAE(args, state_function, oracle_function, kwargs_oracle={}, precision=None, target=None)[source]#
This method implements the canonical quantum amplitude estimation (QAE) algorithm by Brassard et al..
The problem of quantum amplitude estimation is described as follows:
Given a unitary operator \(\mathcal{A}\), let \(\ket{\Psi}=\mathcal{A}\ket{0}\).
Write \(\ket{\Psi}=\ket{\Psi_1}+\ket{\Psi_0}\) as a superposition of the orthogonal good and bad components of \(\ket{\Psi}\).
Find an estimate for \(a=\langle\Psi_1|\Psi_1\rangle\), the probability that a measurement of \(\ket{\Psi}\) yields a good state.
- Parameters:
- argsQuantumVariable or list[QuantumVariable]
The (list of) QuantumVariables which represent the state, the quantum amplitude estimation is performed on.
- state_functionfunction
A Python function preparing the state \(\ket{\Psi}\). This function will receive the variables in the list
args
as arguments in the course of this algorithm.- oracle_functionfunction
A Python function tagging the good state \(\ket{\Psi_1}\). This function will receive the variables in the list
args
as arguments in the course of this algorithm.- kwargs_oracledict, optional
A dictionary containing keyword arguments for the oracle. The default is {}.
- precisionint, optional
The precision of the estimation. The default is None.
- targetQuantumFloat, optional
A target QuantumFloat to perform the estimation into. The default is None. If given neither a precision nor a target, an Exception will be raised.
- Returns:
- resQuantumFloat
A QuantumFloat encoding the angle \(\theta\) as a fraction of \(\pi\), such that \(\tilde{a}=\sin^2(\theta)\) is an estimate for \(a\).
More precisely, we have \(\theta=\pi\frac{y}{M}\) for \(y\in\{0,\dotsc,M-1\}\) and \(M=2^{\text{precision}}\). After measurement, the estimate \(\tilde{a}=\sin^2(\theta)\) satisfies
\[|a-\tilde{a}|\leq\frac{2\pi}{M}+\frac{\pi^2}{M^2}\]with probability of at least \(8/\pi^2\).
Examples
We define a function that prepares the state \(\ket{\Psi}=\cos(\frac{\pi}{8})\ket{0}+\sin(\frac{\pi}{8})\ket{1}\) and an oracle that tags the good state \(\ket{1}\). In this case, we have \(a=\sin^2(\frac{\pi}{8})\).
from qrisp import z, ry, QuantumBool, QAE import numpy as np def state_function(qb): ry(np.pi/4,qb) def oracle_function(qb): z(qb) qb = QuantumBool() res = QAE([qb], state_function, oracle_function, precision=3)
>>> res.get_measurement() {0.125: 0.5, 0.875: 0.5}
That is, after measurement we find \(\theta=\frac{\pi}{8}\) or \(\theta=\frac{7\pi}{8}\) with probability \(\frac12\), respectively. Therefore, we obtain the estimate \(\tilde{a}=\sin^2(\frac{\pi}{8})\) or \(\tilde{a}=\sin^2(\frac{7\pi}{8})\). In this case, both results coincide with the exact value \(a\).
Numerical integration
Here, we demonstarate how to use QAE for numerical integration.
Consider a continuous function \(f\colon[0,1]\rightarrow[0,1]\). We wish to evaluate
\[A=\int_0^1f(x)\mathrm dx.\]For this, we set up the corresponding
state_function
acting on theinput_list
:from qrisp import QuantumFloat, QuantumBool, control, z, h, ry, QAE import numpy as np n = 6 inp = QuantumFloat(n,-n) tar = QuantumBool() input_list = [inp, tar]
Here, \(N=2^n\) is the number of sampling points the function \(f\) is evaluated on. The
state_function
acts as\[\ket{0}\ket{0}\rightarrow\frac{1}{\sqrt{N}}\sum\limits_{x=0}^{N-1}\ket{x}\left(\sqrt{1-f(x/N)}\ket{0}+\sqrt{f(x/N)}\ket{1}\right).\]Then the probability of measuring \(1\) in the target state
tar
is\[p(1)=\frac{1}{N}\sum\limits_{x=0}^{N-1}f(x/N),\]which acts as an approximation for the value of the integral \(A\).
The
oracle_function
, therefore, tags the \(\ket{1}\) state of the target state:def oracle_function(inp, tar): z(tar)
For example, if \(f(x)=\sin^2(x)\) the
state_function
can be implemented as follows:def state_function(inp, tar): h(inp) N = 2**inp.size for k in range(inp.size): with control(inp[k]): ry(2**(k+1)/N,tar)
Finally, we apply QAE and obtain an estimate \(a\) for the value of the integral \(A=0.27268\).
prec = 6 res = QAE(input_list, state_function, oracle_function, precision=prec) meas_res = res.get_measurement() theta = np.pi*max(meas_res, key=meas_res.get) a = np.sin(theta)**2
>>> a 0.26430