From def1f8a7b6933fed3df959be27c243dbcc6230f8 Mon Sep 17 00:00:00 2001 From: Atsushi Matsuo Date: Thu, 6 May 2021 17:16:54 +0900 Subject: [PATCH 1/7] fix oracle_evaluation for PhaseOracle --- qiskit/algorithms/amplitude_amplifiers/grover.py | 8 ++++++-- test/python/algorithms/test_grover.py | 11 ++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/qiskit/algorithms/amplitude_amplifiers/grover.py b/qiskit/algorithms/amplitude_amplifiers/grover.py index 3ac664eef0e3..ed6ae8842cf4 100644 --- a/qiskit/algorithms/amplitude_amplifiers/grover.py +++ b/qiskit/algorithms/amplitude_amplifiers/grover.py @@ -18,8 +18,8 @@ from typing import Iterator, List, Optional, Union import numpy as np - from qiskit import ClassicalRegister, QuantumCircuit +from qiskit.circuit.library import PhaseOracle from qiskit.providers import Backend, BaseBackend from qiskit.quantum_info import partial_trace from qiskit.utils import QuantumInstance @@ -249,7 +249,11 @@ def amplify(self, amplification_problem: AmplificationProblem) -> "GroverResult" ) all_circuit_results.append(circuit_results) - oracle_evaluation = amplification_problem.is_good_state(top_measurement) + if isinstance(amplification_problem.oracle, PhaseOracle): + oracle_evaluation = amplification_problem.is_good_state(top_measurement[::-1]) + else: + oracle_evaluation = amplification_problem.is_good_state(top_measurement) + if oracle_evaluation is True: break # we found a solution diff --git a/test/python/algorithms/test_grover.py b/test/python/algorithms/test_grover.py index bea82b1c3d9e..f52e27250198 100644 --- a/test/python/algorithms/test_grover.py +++ b/test/python/algorithms/test_grover.py @@ -21,7 +21,7 @@ from qiskit import BasicAer, QuantumCircuit from qiskit.utils import QuantumInstance from qiskit.algorithms import Grover, AmplificationProblem -from qiskit.circuit.library import GroverOperator +from qiskit.circuit.library import GroverOperator, PhaseOracle from qiskit.quantum_info import Operator, Statevector @@ -233,6 +233,15 @@ def test_max_probability(self): result = grover.amplify(problem) self.assertEqual(result.max_probability, 1.0) + def test_oracle_evaluation(self): + """Test oracle_evaluation for PhaseOracle""" + oracle = PhaseOracle("x1 & x2 & (not x3)") + problem = AmplificationProblem(oracle, is_good_state=oracle.evaluate_bitstring) + grover = Grover(quantum_instance=self.qasm) + result = grover.amplify(problem) + self.assertTrue(result.oracle_evaluation) + self.assertEqual("011", result.top_measurement) + if __name__ == "__main__": unittest.main() From bed002a51134e5858f66e19df4c162fd3ea5c218 Mon Sep 17 00:00:00 2001 From: Atsushi Matsuo Date: Wed, 16 Jun 2021 12:28:20 +0900 Subject: [PATCH 2/7] reverse a bit order in phase oracle --- qiskit/algorithms/amplitude_amplifiers/grover.py | 7 ++----- qiskit/circuit/library/phase_oracle.py | 5 +++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/qiskit/algorithms/amplitude_amplifiers/grover.py b/qiskit/algorithms/amplitude_amplifiers/grover.py index 3d02763c0f7d..ce76befdaa13 100644 --- a/qiskit/algorithms/amplitude_amplifiers/grover.py +++ b/qiskit/algorithms/amplitude_amplifiers/grover.py @@ -17,8 +17,8 @@ from typing import Iterator, List, Optional, Union import numpy as np + from qiskit import ClassicalRegister, QuantumCircuit -from qiskit.circuit.library import PhaseOracle from qiskit.providers import Backend, BaseBackend from qiskit.quantum_info import partial_trace from qiskit.utils import QuantumInstance @@ -246,10 +246,7 @@ def amplify(self, amplification_problem: AmplificationProblem) -> "GroverResult" ) all_circuit_results.append(circuit_results) - if isinstance(amplification_problem.oracle, PhaseOracle): - oracle_evaluation = amplification_problem.is_good_state(top_measurement[::-1]) - else: - oracle_evaluation = amplification_problem.is_good_state(top_measurement) + oracle_evaluation = amplification_problem.is_good_state(top_measurement) if oracle_evaluation is True: break # we found a solution diff --git a/qiskit/circuit/library/phase_oracle.py b/qiskit/circuit/library/phase_oracle.py index be3301c117e1..138933d53fd1 100644 --- a/qiskit/circuit/library/phase_oracle.py +++ b/qiskit/circuit/library/phase_oracle.py @@ -80,11 +80,12 @@ def evaluate_bitstring(self, bitstring: str) -> bool: """Evaluate the oracle on a bitstring. This evaluation is done classically without any quantum circuit. Args: - bitstring: The bitstring for which to evaluate. + bitstring: The bitstring for which to evaluate. The input bitstring is expected to be + in little-endian order. Returns: True if the bitstring is a good state, False otherwise. """ - return self.boolean_expression.simulate(bitstring) + return self.boolean_expression.simulate(bitstring[::-1]) @classmethod def from_dimacs_file(cls, filename: str): From c823401625496c8db553b36727b953a69a3b623b Mon Sep 17 00:00:00 2001 From: Atsushi Matsuo Date: Wed, 16 Jun 2021 12:51:02 +0900 Subject: [PATCH 3/7] fix lint --- qiskit/algorithms/amplitude_amplifiers/grover.py | 1 - 1 file changed, 1 deletion(-) diff --git a/qiskit/algorithms/amplitude_amplifiers/grover.py b/qiskit/algorithms/amplitude_amplifiers/grover.py index ce76befdaa13..e397481b49e4 100644 --- a/qiskit/algorithms/amplitude_amplifiers/grover.py +++ b/qiskit/algorithms/amplitude_amplifiers/grover.py @@ -247,7 +247,6 @@ def amplify(self, amplification_problem: AmplificationProblem) -> "GroverResult" all_circuit_results.append(circuit_results) oracle_evaluation = amplification_problem.is_good_state(top_measurement) - if oracle_evaluation is True: break # we found a solution From e3e60866b04c166c3b44fad774a2d61855f9dd98 Mon Sep 17 00:00:00 2001 From: Atsushi Matsuo Date: Wed, 16 Jun 2021 15:37:23 +0900 Subject: [PATCH 4/7] fix lint --- qiskit/circuit/library/phase_oracle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/circuit/library/phase_oracle.py b/qiskit/circuit/library/phase_oracle.py index 138933d53fd1..abdc619de664 100644 --- a/qiskit/circuit/library/phase_oracle.py +++ b/qiskit/circuit/library/phase_oracle.py @@ -81,7 +81,7 @@ def evaluate_bitstring(self, bitstring: str) -> bool: This evaluation is done classically without any quantum circuit. Args: bitstring: The bitstring for which to evaluate. The input bitstring is expected to be - in little-endian order. + in little-endian order. Returns: True if the bitstring is a good state, False otherwise. """ From 78d3ee22c0719201557dbc82c69c0e044de124aa Mon Sep 17 00:00:00 2001 From: Atsushi Matsuo Date: Wed, 16 Jun 2021 16:52:04 +0900 Subject: [PATCH 5/7] fix lint --- qiskit/circuit/library/phase_oracle.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qiskit/circuit/library/phase_oracle.py b/qiskit/circuit/library/phase_oracle.py index abdc619de664..f15198b17728 100644 --- a/qiskit/circuit/library/phase_oracle.py +++ b/qiskit/circuit/library/phase_oracle.py @@ -79,9 +79,11 @@ def synthesizer(boolean_expression): def evaluate_bitstring(self, bitstring: str) -> bool: """Evaluate the oracle on a bitstring. This evaluation is done classically without any quantum circuit. + Args: bitstring: The bitstring for which to evaluate. The input bitstring is expected to be - in little-endian order. + in little-endian order. + Returns: True if the bitstring is a good state, False otherwise. """ From 9c8c36790c2d962b878cdb651cd0f0c6ef13d690 Mon Sep 17 00:00:00 2001 From: Atsushi Matsuo Date: Wed, 16 Jun 2021 16:58:43 +0900 Subject: [PATCH 6/7] fix black --- qiskit/circuit/library/phase_oracle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/circuit/library/phase_oracle.py b/qiskit/circuit/library/phase_oracle.py index f15198b17728..bd1033fe55ab 100644 --- a/qiskit/circuit/library/phase_oracle.py +++ b/qiskit/circuit/library/phase_oracle.py @@ -83,7 +83,7 @@ def evaluate_bitstring(self, bitstring: str) -> bool: Args: bitstring: The bitstring for which to evaluate. The input bitstring is expected to be in little-endian order. - + Returns: True if the bitstring is a good state, False otherwise. """ From 5846008214827d5d4beae68afa2e2de6791156e3 Mon Sep 17 00:00:00 2001 From: Julien Gacon Date: Fri, 18 Jun 2021 14:21:58 +0200 Subject: [PATCH 7/7] add reno --- .../notes/fix_phaseoracle_evaluate-52be05221d2761aa.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 releasenotes/notes/fix_phaseoracle_evaluate-52be05221d2761aa.yaml diff --git a/releasenotes/notes/fix_phaseoracle_evaluate-52be05221d2761aa.yaml b/releasenotes/notes/fix_phaseoracle_evaluate-52be05221d2761aa.yaml new file mode 100644 index 000000000000..6b89c0fb7f8c --- /dev/null +++ b/releasenotes/notes/fix_phaseoracle_evaluate-52be05221d2761aa.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + Fix a bug where the bit-order in + :meth:`qiskit.circuit.library.PhaseOracle.evaluate_bitstring` did not agree with the + order of the measured bitstring. This fix also affects the execution of Grover's algorithm + if the oracle is specified as :class:`~qiskit.circuit.library.PhaseOracle`, which now + correctly identifies the correct bitstring.