From 2e0514fc05412afb192645be0e10c531c4c9fc93 Mon Sep 17 00:00:00 2001 From: Takashi Imamichi Date: Sat, 3 Dec 2022 14:32:13 +0900 Subject: [PATCH 1/2] simplify GroverOptimizer --- .../algorithms/grover_optimizer.py | 31 ++++++++----------- test/algorithms/test_grover_optimizer.py | 5 +-- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/qiskit_optimization/algorithms/grover_optimizer.py b/qiskit_optimization/algorithms/grover_optimizer.py index b8359c0c6..9a625746a 100644 --- a/qiskit_optimization/algorithms/grover_optimizer.py +++ b/qiskit_optimization/algorithms/grover_optimizer.py @@ -14,33 +14,30 @@ import logging import math -from copy import deepcopy -from typing import Optional, Dict, Union, List, cast import warnings +from copy import deepcopy +from typing import Dict, List, Optional, Union, cast import numpy as np - from qiskit import QuantumCircuit, QuantumRegister from qiskit.algorithms import AmplificationProblem -from qiskit.utils import QuantumInstance, algorithm_globals from qiskit.algorithms.amplitude_amplifiers.grover import Grover from qiskit.circuit.library import QuadraticForm from qiskit.primitives import BaseSampler from qiskit.providers import Backend from qiskit.quantum_info import partial_trace +from qiskit.utils import QuantumInstance, algorithm_globals + +from ..converters.quadratic_program_to_qubo import QuadraticProgramConverter, QuadraticProgramToQubo +from ..exceptions import QiskitOptimizationError +from ..problems import Variable +from ..problems.quadratic_program import QuadraticProgram from .optimization_algorithm import ( - OptimizationResultStatus, OptimizationAlgorithm, OptimizationResult, + OptimizationResultStatus, SolutionSample, ) -from ..converters.quadratic_program_to_qubo import ( - QuadraticProgramToQubo, - QuadraticProgramConverter, -) -from ..exceptions import QiskitOptimizationError -from ..problems import Variable -from ..problems.quadratic_program import QuadraticProgram logger = logging.getLogger(__name__) @@ -370,13 +367,11 @@ def _get_prob_dist(self, qc: QuantumCircuit) -> Dict[str, float]: except Exception as exc: raise QiskitOptimizationError("Sampler job failed.") from exc quasi_dist = result.quasi_dists[0] - bit_length = (len(quasi_dist) - 1).bit_length() - prob_dist = {f"{i:0{bit_length}b}"[::-1]: v for i, v in quasi_dist.items()} - self._circuit_results = { - f"{i:0{bit_length}b}": v**0.5 - for i, v in quasi_dist.items() - if not np.isclose(v, 0) + raw_prob_dist = { + k: v for k, v in quasi_dist.binary_probabilities(qc.num_qubits).items() if v > 1e-6 } + prob_dist = {k[::-1]: v for k, v in raw_prob_dist.items()} + self._circuit_results = {i: v**0.5 for i, v in raw_prob_dist.items()} else: result = self._quantum_instance.execute(qc) if self._quantum_instance.is_statevector: diff --git a/test/algorithms/test_grover_optimizer.py b/test/algorithms/test_grover_optimizer.py index a39c4f202..173addefa 100644 --- a/test/algorithms/test_grover_optimizer.py +++ b/test/algorithms/test_grover_optimizer.py @@ -20,7 +20,6 @@ from docplex.mp.model import Model from qiskit.utils import QuantumInstance, algorithm_globals, optionals from qiskit.algorithms.minimum_eigensolvers import NumPyMinimumEigensolver -from qiskit.primitives import Sampler from qiskit_optimization.algorithms import ( GroverOptimizer, MinimumEigenOptimizer, @@ -46,6 +45,7 @@ def setUp(self): super().setUp() algorithm_globals.random_seed = 1 from qiskit_aer import Aer + from qiskit_aer.primitives import Sampler self.sv_simulator = QuantumInstance( Aer.get_backend("aer_simulator_statevector"), @@ -57,6 +57,7 @@ def setUp(self): seed_simulator=123, seed_transpiler=123, ) + self.sampler = Sampler(run_options={"seed_simulator": 123}) self.n_iter = 8 def _prepare_grover_optimizer( @@ -84,7 +85,7 @@ def _prepare_grover_optimizer( num_value_qubits=num_value_qubits, num_iterations=num_iterations, converters=converters, - sampler=Sampler(), + sampler=self.sampler, ) return grover_optimizer From 08229d68cd4340362338c97df6ac41a94e79facd Mon Sep 17 00:00:00 2001 From: Takashi Imamichi Date: Mon, 5 Dec 2022 23:05:59 +0900 Subject: [PATCH 2/2] remove a warning that users cannot resolve --- qiskit_optimization/algorithms/grover_optimizer.py | 4 +++- .../algorithms/optimization_algorithm.py | 10 +++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/qiskit_optimization/algorithms/grover_optimizer.py b/qiskit_optimization/algorithms/grover_optimizer.py index 9a625746a..f77da7e0b 100644 --- a/qiskit_optimization/algorithms/grover_optimizer.py +++ b/qiskit_optimization/algorithms/grover_optimizer.py @@ -368,7 +368,9 @@ def _get_prob_dist(self, qc: QuantumCircuit) -> Dict[str, float]: raise QiskitOptimizationError("Sampler job failed.") from exc quasi_dist = result.quasi_dists[0] raw_prob_dist = { - k: v for k, v in quasi_dist.binary_probabilities(qc.num_qubits).items() if v > 1e-6 + k: v + for k, v in quasi_dist.binary_probabilities(qc.num_qubits).items() + if v >= self._MIN_PROBABILITY } prob_dist = {k[::-1]: v for k, v in raw_prob_dist.items()} self._circuit_results = {i: v**0.5 for i, v in raw_prob_dist.items()} diff --git a/qiskit_optimization/algorithms/optimization_algorithm.py b/qiskit_optimization/algorithms/optimization_algorithm.py index 4b8fb3080..d67c9b73b 100644 --- a/qiskit_optimization/algorithms/optimization_algorithm.py +++ b/qiskit_optimization/algorithms/optimization_algorithm.py @@ -15,8 +15,8 @@ from abc import ABC, abstractmethod from dataclasses import dataclass from enum import Enum +from logging import getLogger from typing import Any, Dict, List, Optional, Tuple, Type, Union, cast -from warnings import warn import numpy as np from qiskit.opflow import DictStateFn, StateFn @@ -27,6 +27,8 @@ from ..exceptions import QiskitOptimizationError from ..problems.quadratic_program import QuadraticProgram, Variable +logger = getLogger(__name__) + class OptimizationResultStatus(Enum): """Termination status of an optimization algorithm.""" @@ -137,7 +139,7 @@ def __init__( if samples: sum_prob = np.sum([e.probability for e in samples]) if not np.isclose(sum_prob, 1.0): - warn(f"The sum of probability of samples is not close to 1: {sum_prob}") + logger.debug("The sum of probability of samples is not close to 1: %f", sum_prob) self._samples = samples else: self._samples = [ @@ -291,6 +293,8 @@ def samples(self) -> List[SolutionSample]: class OptimizationAlgorithm(ABC): """An abstract class for optimization algorithms in Qiskit's optimization module.""" + _MIN_PROBABILITY = 1e-6 + @abstractmethod def get_compatibility_msg(self, problem: QuadraticProgram) -> str: """Checks whether a given problem can be solved with the optimizer implementing this method. @@ -522,7 +526,7 @@ def _interpret_samples( def _eigenvector_to_solutions( eigenvector: Union[QuasiDistribution, Statevector, dict, np.ndarray, StateFn], qubo: QuadraticProgram, - min_probability: float = 1e-6, + min_probability: float = _MIN_PROBABILITY, ) -> List[SolutionSample]: """Convert the eigenvector to the bitstrings and corresponding eigenvalues.