From 9af5138209202926b10e8ff4fdc5a376bc1a2876 Mon Sep 17 00:00:00 2001 From: Julia Plewa Date: Fri, 17 Dec 2021 20:29:35 +0100 Subject: [PATCH 1/2] Add option to run MLAE circuits separately --- .../algorithms/amplitude_estimators/mlae.py | 20 ++++++++++--- .../algorithms/test_amplitude_estimators.py | 30 +++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/qiskit/algorithms/amplitude_estimators/mlae.py b/qiskit/algorithms/amplitude_estimators/mlae.py index 378512fefa4f..db3e07a1ea95 100644 --- a/qiskit/algorithms/amplitude_estimators/mlae.py +++ b/qiskit/algorithms/amplitude_estimators/mlae.py @@ -53,6 +53,7 @@ def __init__( evaluation_schedule: Union[List[int], int], minimizer: Optional[MINIMIZER] = None, quantum_instance: Optional[Union[QuantumInstance, BaseBackend, Backend]] = None, + run_circuits_as_one_job: bool = True, ) -> None: r""" Args: @@ -66,6 +67,9 @@ def __init__( 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 + run_circuits_as_one_job: If set to True, the necessary circuits will be submitted as + one job. Otherwise, each circuit will be run separately. This is useful for + backends that don't support multi-circuit experiments. Raises: ValueError: If the number of oracle circuits is smaller than 1. @@ -99,6 +103,8 @@ def default_minimizer(objective_fn, bounds): else: self._minimizer = minimizer + self._run_circuits_as_one_job = run_circuits_as_one_job + @property def quantum_instance(self) -> Optional[QuantumInstance]: """Get the quantum instance. @@ -286,12 +292,18 @@ def estimate( result.shots = 1 else: - # run circuit on QASM simulator + # construct circuits circuits = self.construct_circuits(estimation_problem, measurement=True) - ret = self._quantum_instance.execute(circuits) - # get counts and construct MLE input - result.circuit_results = [ret.get_counts(circuit) for circuit in circuits] + # run circuit on QASM simulator, get counts, and construct MLE input + if self._run_circuits_as_one_job: + ret = self._quantum_instance.execute(circuits) + result.circuit_results = [ret.get_counts(circuit) for circuit in circuits] + else: + rets = [self._quantum_instance.execute(circuit) for circuit in circuits] + result.circuit_results = [ + ret.get_counts(circuit) for ret, circuit in zip(rets, circuits) + ] # to count the number of Q-oracle calls result.shots = self._quantum_instance._run_config.shots diff --git a/test/python/algorithms/test_amplitude_estimators.py b/test/python/algorithms/test_amplitude_estimators.py index e1351651ec53..a69f1efb4a06 100644 --- a/test/python/algorithms/test_amplitude_estimators.py +++ b/test/python/algorithms/test_amplitude_estimators.py @@ -547,5 +547,35 @@ def is_good_state(bitstr): self.assertAlmostEqual(result.estimation, expect, places=5) +@ddt +class TestMaximumLikelihoodAmplitudeEstimation(QiskitAlgorithmsTestCase): + """Specific tests for Maximum Likelihood AE.""" + + def test_sequential_circuit_submission(self): + """Test that the results are correct when circuits are submitted separately.""" + prob = 0.2 + a_op = BernoulliStateIn(prob) + q_op = BernoulliGrover(prob) + problem = EstimationProblem(a_op, objective_qubits=[0], grover_operator=q_op) + + # construct algo + quantum_instance = QuantumInstance( + backend=BasicAer.get_backend("qasm_simulator"), + shots=1000, + seed_simulator=2, + seed_transpiler=2, + ) + mlae = MaximumLikelihoodAmplitudeEstimation( + evaluation_schedule=5, + quantum_instance=quantum_instance, + run_circuits_as_one_job=False, + ) + + # run the algo + result = mlae.estimate(problem) + + self.assertAlmostEqual(prob, result.estimation, places=3, msg=f"estimate failed") + + if __name__ == "__main__": unittest.main() From 068d56f2d619c7d39cc42d9ba6623e890adc2ed1 Mon Sep 17 00:00:00 2001 From: Julia Plewa Date: Fri, 17 Dec 2021 21:05:30 +0100 Subject: [PATCH 2/2] Fix lint error --- test/python/algorithms/test_amplitude_estimators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/python/algorithms/test_amplitude_estimators.py b/test/python/algorithms/test_amplitude_estimators.py index a69f1efb4a06..33c28f7c9236 100644 --- a/test/python/algorithms/test_amplitude_estimators.py +++ b/test/python/algorithms/test_amplitude_estimators.py @@ -574,7 +574,7 @@ def test_sequential_circuit_submission(self): # run the algo result = mlae.estimate(problem) - self.assertAlmostEqual(prob, result.estimation, places=3, msg=f"estimate failed") + self.assertAlmostEqual(prob, result.estimation, places=3, msg="estimate failed") if __name__ == "__main__":