Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 10 additions & 92 deletions qiskit/algorithms/amplitude_amplifiers/amplification_problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,74 +50,18 @@ def __init__(self,
applied on the measurement outcome of these qubits.
is_good_state: A function to check whether a string represents a good state.
"""
self._oracle = oracle
self._state_preparation = state_preparation
self._grover_operator = grover_operator
self._post_processing = post_processing
self._objective_qubits = objective_qubits
self._is_good_state = is_good_state

@property
def oracle(self) -> Union[QuantumCircuit, Statevector]:
"""Return the oracle.

Returns:
The oracle.
"""
return self._oracle

@oracle.setter
def oracle(self, oracle: Union[QuantumCircuit, Statevector]) -> None:
"""Set the oracle.

Args:
oracle: The oracle.
"""
self._oracle = oracle

@property
def state_preparation(self) -> QuantumCircuit:
r"""Get the state preparation operator :math:`\mathcal{A}`.

Returns:
The :math:`\mathcal{A}` operator as `QuantumCircuit`.
"""
if self._state_preparation is None:
state_preparation = QuantumCircuit(self.oracle.num_qubits)
state_preparation.h(state_preparation.qubits)
return state_preparation

return self._state_preparation

@state_preparation.setter
def state_preparation(self, state_preparation: Optional[QuantumCircuit]) -> None:
r"""Set the :math:`\mathcal{A}` operator. If None, a layer of Hadamard gates is used.

Args:
state_preparation: The new :math:`\mathcal{A}` operator or None.
"""
self._state_preparation = state_preparation
self.oracle = oracle

@property
def post_processing(self) -> Callable[[str], Any]:
"""Apply post processing to the input value.

Returns:
A handle to the post processing function. Acts as identity by default.
"""
if self._post_processing is None:
return lambda x: x

return self._post_processing

@post_processing.setter
def post_processing(self, post_processing: Callable[[str], Any]) -> None:
"""Set the post processing function.
if state_preparation:
self.state_preparation = state_preparation
else:
self.state_preparation = QuantumCircuit(oracle.num_qubits)
self.state_preparation.h(range(oracle.num_qubits))

Args:
post_processing: A handle to the post processing function.
"""
self._post_processing = post_processing
self.grover_operator = grover_operator or GroverOperator(oracle, self.state_preparation)
self.post_processing = post_processing or (lambda x: x)
self._objective_qubits = objective_qubits
self._is_good_state = is_good_state

@property
def objective_qubits(self) -> List[int]:
Expand Down Expand Up @@ -174,29 +118,3 @@ def is_good_state(self,
is_good_state: A function to determine whether a bitstring represents a good state.
"""
self._is_good_state = is_good_state

@property
def grover_operator(self) -> Optional[QuantumCircuit]:
r"""Get the :math:`\mathcal{Q}` operator, or Grover operator.

If the Grover operator is not set, we try to build it from the :math:`\mathcal{A}` operator
and `objective_qubits`. This only works if `objective_qubits` is a list of integers.

Returns:
The Grover operator, or None if neither the Grover operator nor the
:math:`\mathcal{A}` operator is set.
"""
if self._grover_operator is None:
return GroverOperator(self.oracle, self.state_preparation)
return self._grover_operator

@grover_operator.setter
def grover_operator(self, grover_operator: Optional[QuantumCircuit]) -> None:
r"""Set the :math:`\mathcal{Q}` operator.

If None, this operator is constructed from the ``oracle`` and ``state_preparation``.

Args:
grover_operator: The new :math:`\mathcal{Q}` operator or None.
"""
self._grover_operator = grover_operator
85 changes: 3 additions & 82 deletions qiskit/algorithms/amplitude_amplifiers/amplitude_amplifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
"""The interface for amplification algorithms and results."""

from abc import ABC, abstractmethod
from typing import Optional, Any, Union, Dict, List

import numpy as np

from .amplification_problem import AmplificationProblem
from ..algorithm_result import AlgorithmResult
Expand Down Expand Up @@ -43,82 +40,6 @@ class AmplitudeAmplifierResult(AlgorithmResult):

def __init__(self) -> None:
super().__init__()
self._top_measurement = None
self._assignment = None
self._oracle_evaluation = None

@property
def top_measurement(self) -> Optional[str]:
"""The most frequently measured output as bitstring.

Returns:
The most frequently measured output state.
"""
return self._top_measurement

@top_measurement.setter
def top_measurement(self, value: str) -> None:
"""Set the most frequently measured bitstring.

Args:
value: A new value for the top measurement.
"""
self._top_measurement = value

@property
def assignment(self) -> Any:
"""The post-processed value of the most likely bitstring.

Returns:
The output of the ``post_processing`` function of the respective
``AmplificationProblem``, where the input is the ``top_measurement``. The type
is the same as the return type of the post-processing function.
"""
return self._assignment

@assignment.setter
def assignment(self, value: Any) -> None:
"""Set the value for the assignment.

Args:
value: A new value for the assignment/solution.
"""
self._assignment = value

@property
def oracle_evaluation(self) -> bool:
"""Whether the classical oracle evaluation of the top measurement was True or False.

Returns:
The classical oracle evaluation of the top measurement.
"""
return self._oracle_evaluation

@oracle_evaluation.setter
def oracle_evaluation(self, value: bool) -> None:
"""Set the classical oracle evaluation of the top measurement.

Args:
value: A new value for the classical oracle evaluation.
"""
self._oracle_evaluation = value

@property
def circuit_results(self) -> Optional[Union[List[np.ndarray], List[Dict[str, int]]]]:
"""Return the circuit results. Can be a statevector or counts dictionary."""
return self._circuit_results

@circuit_results.setter
def circuit_results(self, value: Union[List[np.ndarray], List[Dict[str, int]]]) -> None:
"""Set the circuit results."""
self._circuit_results = value

@property
def max_probability(self) -> float:
"""Return the maximum sampling probability."""
return self._max_probability

@max_probability.setter
def max_probability(self, value: float) -> None:
"""Set the maximum sampling probability."""
self._max_probability = value
self.top_measurement = None
self.assignment = None
self.oracle_evaluation = None
26 changes: 4 additions & 22 deletions qiskit/algorithms/amplitude_amplifiers/grover.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ def amplify(self, amplification_problem: AmplificationProblem) -> 'GroverResult'
oracle_evaluation = False
all_circuit_results = []
max_probability = 0
shots = 0

for _ in range(max_iterations): # iterate at most to the max number of iterations
# get next power and check if allowed
Expand Down Expand Up @@ -309,24 +308,7 @@ class GroverResult(AmplitudeAmplifierResult):

def __init__(self) -> None:
super().__init__()
self._iterations = None
self._circuit_results = None
self._shots = None

@property
def iterations(self) -> List[int]:
"""All the powers of the Grover operator that have been tried.

Returns:
The powers of the Grover operator tested.
"""
return self._iterations

@iterations.setter
def iterations(self, value: List[int]) -> None:
"""Set the powers of the Grover operator that have been tried.

Args:
value: A new value for the powers.
"""
self._iterations = value
self.iterations = None
self.circuit_results = None
self.shots = None
self.max_probability = None
84 changes: 7 additions & 77 deletions qiskit/algorithms/amplitude_estimators/ae.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,83 +379,13 @@ class AmplitudeEstimationResult(AmplitudeEstimatorResult):

def __init__(self) -> None:
super().__init__()
self._num_evaluation_qubits = None
self._mle = None
self._mle_processed = None
self._samples = None
self._samples_processed = None
self._y_measurements = None
self._max_probability = None

@property
def num_evaluation_qubits(self) -> int:
"""Returns the number of evaluation qubits."""
return self._num_evaluation_qubits

@num_evaluation_qubits.setter
def num_evaluation_qubits(self, num_evaluation_qubits: int) -> None:
"""Set the number of evaluation qubits."""
self._num_evaluation_qubits = num_evaluation_qubits

@property
def mle_processed(self) -> float:
"""Return the post-processed MLE for the amplitude."""
return self._mle_processed

@mle_processed.setter
def mle_processed(self, value: float) -> None:
"""Set the post-processed MLE for the amplitude."""
self._mle_processed = value

@property
def samples_processed(self) -> Dict[float, float]:
"""Return the post-processed measurement samples with their measurement probability."""
return self._samples_processed

@samples_processed.setter
def samples_processed(self, value: Dict[float, float]) -> None:
"""Set the post-processed measurement samples."""
self._samples_processed = value

@property
def mle(self) -> float:
r"""Return the MLE for the amplitude, in $[0, 1]$."""
return self._mle

@mle.setter
def mle(self, value: float) -> None:
r"""Set the MLE for the amplitude, in $[0, 1]$."""
self._mle = value

@property
def samples(self) -> Dict[float, float]:
"""Return the measurement samples with their measurement probability."""
return self._samples

@samples.setter
def samples(self, value: Dict[float, float]) -> None:
"""Set the measurement samples with their measurement probability."""
self._samples = value

@property
def measurements(self) -> Dict[int, float]:
"""Return the measurements as integers with their measurement probability."""
return self._y_measurements

@measurements.setter
def measurements(self, value: Dict[int, float]) -> None:
"""Set the measurements as integers with their measurement probability."""
self._y_measurements = value

@property
def max_probability(self) -> float:
"""Return the maximum sampling probability."""
return self._max_probability

@max_probability.setter
def max_probability(self, value: float) -> None:
"""Set the maximum sampling probability."""
self._max_probability = value
self.num_evaluation_qubits = None
self.mle = None
self.mle_processed = None
self.samples = None
self.samples_processed = None
self.measurements = None
self.max_probability = None


def _compute_fisher_information(result: AmplitudeEstimationResult, observed: bool = False) -> float:
Expand Down
Loading