Skip to content

Commit

Permalink
Fixing and documenting how the Estimator calculates stds (Qiskit#12670
Browse files Browse the repository at this point in the history
)

* riverlane paper

* docs

* improvement

* empty

* fix linting and add abs

* Update qiskit/primitives/backend_estimator_v2.py

Co-authored-by: Takashi Imamichi <31178928+t-imamichi@users.noreply.github.com>

* CR

* Update qiskit/primitives/backend_estimator_v2.py

Co-authored-by: Ian Hincks <ian.hincks@gmail.com>

* CR

* indent

* Update releasenotes/notes/backend-estimator-v2-variance-905c953415ad0e29.yaml

Co-authored-by: Takashi Imamichi <31178928+t-imamichi@users.noreply.github.com>

---------

Co-authored-by: Takashi Imamichi <31178928+t-imamichi@users.noreply.github.com>
Co-authored-by: Ian Hincks <ian.hincks@gmail.com>
  • Loading branch information
3 people authored and Procatv committed Aug 1, 2024
1 parent f02ac31 commit 6078e93
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 4 deletions.
26 changes: 22 additions & 4 deletions qiskit/primitives/backend_estimator_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class _PreprocessedData:


class BackendEstimatorV2(BaseEstimatorV2):
"""Evaluates expectation values for provided quantum circuit and observable combinations
r"""Evaluates expectation values for provided quantum circuit and observable combinations.
The :class:`~.BackendEstimatorV2` class is a generic implementation of the
:class:`~.BaseEstimatorV2` interface that is used to wrap a :class:`~.BackendV2`
Expand All @@ -87,7 +87,19 @@ class BackendEstimatorV2(BaseEstimatorV2):
precludes doing any provider- or backend-specific optimizations.
This class does not perform any measurement or gate mitigation, and, presently, is only
compatible with Pauli-based observables.
compatible with Pauli-based observables. More formally, given an observable of the type
:math:`O=\sum_{i=1}^Na_iP_i`, where :math:`a_i` is a complex number and :math:`P_i` is a
Pauli operator, the estimator calculates the expectation :math:`\mathbb{E}(P_i)` of each
:math:`P_i` and finally calculates the expectation value of :math:`O` as
:math:`\mathbb{E}(O)=\sum_{i=1}^Na_i\mathbb{E}(P_i)`. The reported ``std`` is calculated
as
.. math::
\frac{\sum_{i=1}^{n}|a_i|\sqrt{\textrm{Var}\big(P_i\big)}}{\sqrt{N}}\:,
where :math:`\textrm{Var}(P_i)` is the variance of :math:`P_i`, :math:`N=O(\epsilon^{-2})` is
the number of shots, and :math:`\epsilon` is the target precision [1].
Each tuple of ``(circuit, observables, <optional> parameter values, <optional> precision)``,
called an estimator primitive unified bloc (PUB), produces its own array-based result. The
Expand All @@ -104,6 +116,12 @@ class BackendEstimatorV2(BaseEstimatorV2):
* ``seed_simulator``: The seed to use in the simulator. If None, a random seed will be used.
Default: None.
**Reference:**
[1] O. Crawford, B. van Straaten, D. Wang, T. Parks, E. Campbell, St. Brierley,
Efficient quantum measurement of Pauli operators in the presence of finite sampling error.
`Quantum 5, 385 <https://doi.org/10.22331/q-2021-01-20-385>`_
"""

def __init__(
Expand Down Expand Up @@ -254,8 +272,8 @@ def _postprocess_pub(
for pauli, coeff in bc_obs[index].items():
expval, variance = expval_map[param_index, pauli]
evs[index] += expval * coeff
variances[index] += variance * coeff**2
stds = np.sqrt(variances / shots)
variances[index] += np.abs(coeff) * variance**0.5
stds = variances / np.sqrt(shots)
data_bin = DataBin(evs=evs, stds=stds, shape=evs.shape)
return PubResult(data_bin, metadata={"target_precision": pub.precision})

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
fixes:
- |
Changes the way in which the :class:`.BackendEstimatorV2` class calculates the ``std`` to ensure that
it matches the correct formula.

0 comments on commit 6078e93

Please sign in to comment.