Skip to content

Commit

Permalink
Rewrite Amplitude Estimators with Primitives
Browse files Browse the repository at this point in the history
  • Loading branch information
manoelmarques committed Aug 31, 2022
1 parent 69ad6c6 commit d7dd578
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 17 deletions.
34 changes: 30 additions & 4 deletions qiskit/algorithms/amplitude_estimators/ae.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2018, 2020.
# (C) Copyright IBM 2018, 2022.
#
# 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
Expand All @@ -14,13 +14,16 @@

from typing import Optional, Union, List, Tuple, Dict
from collections import OrderedDict
import warnings
import numpy as np
from scipy.stats import chi2, norm
from scipy.optimize import bisect

from qiskit import QuantumCircuit, ClassicalRegister
from qiskit.providers import Backend
from qiskit.primitives import BaseSampler
from qiskit.utils import QuantumInstance
from qiskit.utils.deprecation import deprecate_function
from .amplitude_estimator import AmplitudeEstimator, AmplitudeEstimatorResult
from .ae_utils import pdf_a, derivative_log_pdf_a, bisect_max
from .estimation_problem import EstimationProblem
Expand Down Expand Up @@ -59,6 +62,7 @@ def __init__(
phase_estimation_circuit: Optional[QuantumCircuit] = None,
iqft: Optional[QuantumCircuit] = None,
quantum_instance: Optional[Union[QuantumInstance, Backend]] = None,
sampler: Optional[BaseSampler] = None,
) -> None:
r"""
Args:
Expand All @@ -68,7 +72,9 @@ def __init__(
`qiskit.circuit.library.PhaseEstimation` when None.
iqft: The inverse quantum Fourier transform component, defaults to using a standard
implementation from `qiskit.circuit.library.QFT` when None.
quantum_instance: The backend (or `QuantumInstance`) to execute the circuits on.
quantum_instance: Pending deprecation\: The backend (or `QuantumInstance`) to execute
the circuits on.
sampler: base sampler
Raises:
ValueError: If the number of evaluation qubits is smaller than 1.
Expand All @@ -79,6 +85,13 @@ def __init__(
super().__init__()

# set quantum instance
if quantum_instance is not None:
warnings.warn(
"The quantum_instance argument has been superseded by the sampler argument. "
"This argument will be deprecated in a future release and subsequently "
"removed after that.",
category=PendingDeprecationWarning,
)
self.quantum_instance = quantum_instance

# get parameters
Expand All @@ -87,19 +100,32 @@ def __init__(

self._iqft = iqft
self._pec = phase_estimation_circuit
self._sampler = sampler

@property
@deprecate_function(
"The AmplitudeEstimation.quantum_instance getter is pending deprecation. "
"This property will be deprecated in a future release and subsequently "
"removed after that.",
category=PendingDeprecationWarning,
)
def quantum_instance(self) -> Optional[QuantumInstance]:
"""Get the quantum instance.
"""Pending deprecation: Get the quantum instance.
Returns:
The quantum instance used to run this algorithm.
"""
return self._quantum_instance

@quantum_instance.setter
@deprecate_function(
"The AmplitudeEstimation.quantum_instance setter is pending deprecation. "
"This property will be deprecated in a future release and subsequently "
"removed after that.",
category=PendingDeprecationWarning,
)
def quantum_instance(self, quantum_instance: Union[QuantumInstance, Backend]) -> None:
"""Set quantum instance.
"""Pending deprecation: Set quantum instance.
Args:
quantum_instance: The quantum instance used to run this algorithm.
Expand Down
35 changes: 31 additions & 4 deletions qiskit/algorithms/amplitude_estimators/fae.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2017, 2020.
# (C) Copyright IBM 2017, 2022.
#
# 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
Expand All @@ -13,11 +13,14 @@
"""Faster Amplitude Estimation."""

from typing import Optional, Union, List, Tuple
import warnings
import numpy as np

from qiskit.circuit import QuantumCircuit, ClassicalRegister
from qiskit.providers import Backend
from qiskit.primitives import BaseSampler
from qiskit.utils import QuantumInstance
from qiskit.utils.deprecation import deprecate_function
from qiskit.algorithms.exceptions import AlgorithmError

from .amplitude_estimator import AmplitudeEstimator, AmplitudeEstimatorResult
Expand Down Expand Up @@ -51,13 +54,16 @@ def __init__(
maxiter: int,
rescale: bool = True,
quantum_instance: Optional[Union[QuantumInstance, Backend]] = None,
sampler: Optional[BaseSampler] = None,
) -> None:
r"""
Args:
delta: The probability that the true value is outside of the final confidence interval.
maxiter: The number of iterations, the maximal power of Q is `2 ** (maxiter - 1)`.
rescale: Whether to rescale the problem passed to `estimate`.
quantum_instance: The quantum instance or backend to run the circuits.
quantum_instance: Pending deprecation\: The quantum instance or backend
to run the circuits.
sampler: base sampler
.. note::
Expand All @@ -66,25 +72,46 @@ def __init__(
"""
super().__init__()
# set quantum instance
if quantum_instance is not None:
warnings.warn(
"The quantum_instance argument has been superseded by the sampler argument. "
"This argument will be deprecated in a future release and subsequently "
"removed after that.",
category=PendingDeprecationWarning,
)
self.quantum_instance = quantum_instance
self._shots = (int(1944 * np.log(2 / delta)), int(972 * np.log(2 / delta)))
self._rescale = rescale
self._delta = delta
self._maxiter = maxiter
self._num_oracle_calls = 0
self._sampler = sampler

@property
@deprecate_function(
"The FasterAmplitudeEstimation.quantum_instance getter is pending deprecation. "
"This property will be deprecated in a future release and subsequently "
"removed after that.",
category=PendingDeprecationWarning,
)
def quantum_instance(self) -> Optional[QuantumInstance]:
"""Get the quantum instance.
"""Pending deprecation: Get the quantum instance.
Returns:
The quantum instance used to run this algorithm.
"""
return self._quantum_instance

@quantum_instance.setter
@deprecate_function(
"The FasterAmplitudeEstimation.quantum_instance setter is pending deprecation. "
"This property will be deprecated in a future release and subsequently "
"removed after that.",
category=PendingDeprecationWarning,
)
def quantum_instance(self, quantum_instance: Union[QuantumInstance, Backend]) -> None:
"""Set quantum instance.
"""Pending deprecation: Set quantum instance.
Args:
quantum_instance: The quantum instance used to run this algorithm.
Expand Down
33 changes: 29 additions & 4 deletions qiskit/algorithms/amplitude_estimators/iae.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2018, 2020.
# (C) Copyright IBM 2018, 2022.
#
# 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
Expand All @@ -13,12 +13,15 @@
"""The Iterative Quantum Amplitude Estimation Algorithm."""

from typing import Optional, Union, List, Tuple, Dict, cast
import warnings
import numpy as np
from scipy.stats import beta

from qiskit import ClassicalRegister, QuantumCircuit
from qiskit.providers import Backend
from qiskit.primitives import BaseSampler
from qiskit.utils import QuantumInstance
from qiskit.utils.deprecation import deprecate_function

from .amplitude_estimator import AmplitudeEstimator, AmplitudeEstimatorResult
from .estimation_problem import EstimationProblem
Expand Down Expand Up @@ -53,6 +56,7 @@ def __init__(
confint_method: str = "beta",
min_ratio: float = 2,
quantum_instance: Optional[Union[QuantumInstance, Backend]] = None,
sampler: Optional[BaseSampler] = None,
) -> None:
r"""
The output of the algorithm is an estimate for the amplitude `a`, that with at least
Expand All @@ -66,7 +70,8 @@ def __init__(
each iteration, can be 'chernoff' for the Chernoff intervals or 'beta' for the
Clopper-Pearson intervals (default)
min_ratio: Minimal q-ratio (:math:`K_{i+1} / K_i`) for FindNextK
quantum_instance: Quantum Instance or Backend
quantum_instance: Pending deprecation\: Quantum Instance or Backend
sampler: base sampler
Raises:
AlgorithmError: if the method to compute the confidence intervals is not supported
Expand All @@ -89,26 +94,46 @@ def __init__(
super().__init__()

# set quantum instance
if quantum_instance is not None:
warnings.warn(
"The quantum_instance argument has been superseded by the sampler argument. "
"This argument will be deprecated in a future release and subsequently "
"removed after that.",
category=PendingDeprecationWarning,
)
self.quantum_instance = quantum_instance

# store parameters
self._epsilon = epsilon_target
self._alpha = alpha
self._min_ratio = min_ratio
self._confint_method = confint_method
self._sampler = sampler

@property
@deprecate_function(
"The IterativeAmplitudeEstimation.quantum_instance getter is pending deprecation. "
"This property will be deprecated in a future release and subsequently "
"removed after that.",
category=PendingDeprecationWarning,
)
def quantum_instance(self) -> Optional[QuantumInstance]:
"""Get the quantum instance.
"""Pending deprecation: Get the quantum instance.
Returns:
The quantum instance used to run this algorithm.
"""
return self._quantum_instance

@quantum_instance.setter
@deprecate_function(
"The IterativeAmplitudeEstimation.quantum_instance setter is pending deprecation. "
"This property will be deprecated in a future release and subsequently "
"removed after that.",
category=PendingDeprecationWarning,
)
def quantum_instance(self, quantum_instance: Union[QuantumInstance, Backend]) -> None:
"""Set quantum instance.
"""Pending deprecation: Set quantum instance.
Args:
quantum_instance: The quantum instance used to run this algorithm.
Expand Down
36 changes: 31 additions & 5 deletions qiskit/algorithms/amplitude_estimators/mlae.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2018, 2020.
# (C) Copyright IBM 2018, 2022.
#
# 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
Expand All @@ -13,13 +13,16 @@
"""The Maximum Likelihood Amplitude Estimation algorithm."""

from typing import Optional, List, Union, Tuple, Dict, Callable
import warnings
import numpy as np
from scipy.optimize import brute
from scipy.stats import norm, chi2

from qiskit.providers import Backend
from qiskit import ClassicalRegister, QuantumRegister, QuantumCircuit
from qiskit.utils import QuantumInstance
from qiskit.primitives import BaseSampler
from qiskit.utils.deprecation import deprecate_function

from .amplitude_estimator import AmplitudeEstimator, AmplitudeEstimatorResult
from .estimation_problem import EstimationProblem
Expand Down Expand Up @@ -52,6 +55,7 @@ def __init__(
evaluation_schedule: Union[List[int], int],
minimizer: Optional[MINIMIZER] = None,
quantum_instance: Optional[Union[QuantumInstance, Backend]] = None,
sampler: Optional[BaseSampler] = None,
) -> None:
r"""
Args:
Expand All @@ -64,7 +68,8 @@ def __init__(
according to ``evaluation_schedule``. The minimizer takes a function as first
argument and a list of (float, float) tuples (as bounds) as second argument and
returns a single float which is the found minimum.
quantum_instance: Quantum Instance or Backend
quantum_instance: Pending deprecation\: Quantum Instance or Backend
sampler: base sampler
Raises:
ValueError: If the number of oracle circuits is smaller than 1.
Expand All @@ -73,6 +78,13 @@ def __init__(
super().__init__()

# set quantum instance
if quantum_instance is not None:
warnings.warn(
"The quantum_instance argument has been superseded by the sampler argument. "
"This argument will be deprecated in a future release and subsequently "
"removed after that.",
category=PendingDeprecationWarning,
)
self.quantum_instance = quantum_instance

# get parameters
Expand All @@ -98,18 +110,32 @@ def default_minimizer(objective_fn, bounds):
else:
self._minimizer = minimizer

self._sampler = sampler

@property
@deprecate_function(
"The MaximumLikelihoodAmplitudeEstimation.quantum_instance getter is pending deprecation. "
"This property will be deprecated in a future release and subsequently "
"removed after that.",
category=PendingDeprecationWarning,
)
def quantum_instance(self) -> Optional[QuantumInstance]:
"""Get the quantum instance.
"""Pending deprecation: Get the quantum instance.
Returns:
The quantum instance used to run this algorithm.
"""
return self._quantum_instance

@quantum_instance.setter
@deprecate_function(
"The MaximumLikelihoodAmplitudeEstimation.quantum_instance setter is pending deprecation. "
"This property will be deprecated in a future release and subsequently "
"removed after that.",
category=PendingDeprecationWarning,
)
def quantum_instance(self, quantum_instance: Union[QuantumInstance, Backend]) -> None:
"""Set quantum instance.
"""Pending deprecation: Set quantum instance.
Args:
quantum_instance: The quantum instance used to run this algorithm.
Expand Down Expand Up @@ -148,7 +174,7 @@ def construct_circuits(
qc_0.compose(estimation_problem.state_preparation, inplace=True)

for k in self._evaluation_schedule:
qc_k = qc_0.copy(name="qc_a_q_%s" % k)
qc_k = qc_0.copy(name=f"qc_a_q_{k}")

if k != 0:
qc_k.compose(estimation_problem.grover_operator.power(k), inplace=True)
Expand Down

0 comments on commit d7dd578

Please sign in to comment.