Skip to content
This repository has been archived by the owner on Nov 16, 2023. It is now read-only.

Commit

Permalink
Update optimizer to accept new eigensolvers
Browse files Browse the repository at this point in the history
  • Loading branch information
garrison committed Dec 8, 2022
1 parent 54fb842 commit d3143c0
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 9 deletions.
41 changes: 32 additions & 9 deletions qrao/quantum_random_access_optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,17 @@
import numpy as np

from qiskit import QuantumCircuit
from qiskit.algorithms import (
from qiskit.algorithms.minimum_eigensolvers import (
MinimumEigensolver,
MinimumEigensolverResult,
NumPyMinimumEigensolver,
)
from qiskit.algorithms.minimum_eigen_solvers import (
MinimumEigensolver as LegacyMinimumEigensolver,
MinimumEigensolverResult as LegacyMinimumEigensolverResult,
NumPyMinimumEigensolver as LegacyNumPyMinimumEigensolver,
)
from qiskit.opflow import StateFn

from qiskit_optimization.algorithms import (
OptimizationAlgorithm,
Expand Down Expand Up @@ -58,7 +64,9 @@ def __init__(
variables: List[Variable],
status: OptimizationResultStatus,
samples: Optional[List[SolutionSample]],
relaxed_results: MinimumEigensolverResult,
relaxed_results: Union[
MinimumEigensolverResult, LegacyMinimumEigensolverResult
],
rounding_results: RoundingResult,
relaxed_results_offset: float,
sense: int,
Expand Down Expand Up @@ -88,7 +96,9 @@ def __init__(
self._sense = sense

@property
def relaxed_results(self) -> MinimumEigensolverResult:
def relaxed_results(
self,
) -> Union[MinimumEigensolverResult, LegacyMinimumEigensolverResult]:
"""Variationally obtained ground state of the relaxed Hamiltonian"""
return self._relaxed_results

Expand Down Expand Up @@ -132,7 +142,7 @@ class QuantumRandomAccessOptimizer(OptimizationAlgorithm):

def __init__(
self,
min_eigen_solver: MinimumEigensolver,
min_eigen_solver: Union[MinimumEigensolver, LegacyMinimumEigensolver],
encoding: QuantumRandomAccessEncoding,
rounding_scheme: Optional[RoundingScheme] = None,
):
Expand All @@ -156,12 +166,14 @@ def __init__(
self.rounding_scheme = rounding_scheme

@property
def min_eigen_solver(self) -> MinimumEigensolver:
def min_eigen_solver(self) -> Union[MinimumEigensolver, LegacyMinimumEigensolver]:
"""The minimum eigensolver."""
return self._min_eigen_solver

@min_eigen_solver.setter
def min_eigen_solver(self, min_eigen_solver: MinimumEigensolver) -> None:
def min_eigen_solver(
self, min_eigen_solver: Union[MinimumEigensolver, LegacyMinimumEigensolver]
) -> None:
"""Set the minimum eigensolver."""
if not min_eigen_solver.supports_aux_operators():
raise TypeError(
Expand Down Expand Up @@ -196,7 +208,11 @@ def get_compatibility_msg(self, problem: QuadraticProgram) -> str:
)
return ""

def solve_relaxed(self) -> Tuple[MinimumEigensolverResult, RoundingContext]:
def solve_relaxed(
self,
) -> Tuple[
Union[MinimumEigensolverResult, LegacyMinimumEigensolverResult], RoundingContext
]:
"""Solve the relaxed Hamiltonian given the ``encoding`` provided to the constructor."""
# Get the ordered list of operators that correspond to each decision
# variable. This line assumes the variables are numbered consecutively
Expand Down Expand Up @@ -230,10 +246,17 @@ def solve_relaxed(self) -> Tuple[MinimumEigensolverResult, RoundingContext]:
circuit = self.min_eigen_solver.ansatz.bind_parameters(
relaxed_results.optimal_point
)
elif isinstance(self.min_eigen_solver, NumPyMinimumEigensolver):
elif isinstance(
self.min_eigen_solver,
(NumPyMinimumEigensolver, LegacyNumPyMinimumEigensolver),
):
statevector = relaxed_results.eigenstate
if isinstance(statevector, StateFn):
# This code path is triggered only with using
# LegacyNumPyMinimumEigensolver
statevector = statevector.primitive
circuit = QuantumCircuit(self.encoding.num_qubits)
circuit.initialize(statevector.primitive)
circuit.initialize(statevector)
else:
circuit = None

Expand Down
16 changes: 16 additions & 0 deletions tests/test_quantum_random_access_optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,18 @@
"""Tests for QuantumRandomAccessOptimizer."""

from unittest import TestCase
import pytest

from qiskit.utils import QuantumInstance
from qiskit.algorithms.minimum_eigensolvers import (
VQE,
NumPyMinimumEigensolver,
MinimumEigensolverResult,
)
from qiskit.algorithms.minimum_eigen_solvers import (
NumPyMinimumEigensolver as LegacyNumPyMinimumEigensolver,
MinimumEigensolverResult as LegacyMinimumEigensolverResult,
)
from qiskit.circuit.library import RealAmplitudes, QAOAAnsatz
from qiskit.algorithms.optimizers import SPSA
from qiskit.primitives import Estimator
Expand Down Expand Up @@ -93,6 +98,17 @@ def test_solve_relaxed_numpy(self):
self.assertIsInstance(relaxed_results, MinimumEigensolverResult)
self.assertIsInstance(rounding_context, RoundingContext)

@pytest.mark.filterwarnings("ignore::PendingDeprecationWarning")
def test_solve_relaxed_legacy_numpy(self):
"""Test QuantumRandomAccessOptimizer with legacy NumPyMinimumEigensolver."""
np_solver = LegacyNumPyMinimumEigensolver()
qrao = QuantumRandomAccessOptimizer(
encoding=self.encoding, min_eigen_solver=np_solver
)
relaxed_results, rounding_context = qrao.solve_relaxed()
self.assertIsInstance(relaxed_results, LegacyMinimumEigensolverResult)
self.assertIsInstance(rounding_context, RoundingContext)

def test_different_problem(self):
"""Test passing a different problem to solve() than the encoding."""
np_solver = NumPyMinimumEigensolver()
Expand Down

0 comments on commit d3143c0

Please sign in to comment.