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

Commit d3143c0

Browse files
committed
Update optimizer to accept new eigensolvers
Parts of this follow qiskit-community/qiskit-optimization#436
1 parent 54fb842 commit d3143c0

File tree

2 files changed

+48
-9
lines changed

2 files changed

+48
-9
lines changed

qrao/quantum_random_access_optimizer.py

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,17 @@
1818
import numpy as np
1919

2020
from qiskit import QuantumCircuit
21-
from qiskit.algorithms import (
21+
from qiskit.algorithms.minimum_eigensolvers import (
2222
MinimumEigensolver,
2323
MinimumEigensolverResult,
2424
NumPyMinimumEigensolver,
2525
)
26+
from qiskit.algorithms.minimum_eigen_solvers import (
27+
MinimumEigensolver as LegacyMinimumEigensolver,
28+
MinimumEigensolverResult as LegacyMinimumEigensolverResult,
29+
NumPyMinimumEigensolver as LegacyNumPyMinimumEigensolver,
30+
)
31+
from qiskit.opflow import StateFn
2632

2733
from qiskit_optimization.algorithms import (
2834
OptimizationAlgorithm,
@@ -58,7 +64,9 @@ def __init__(
5864
variables: List[Variable],
5965
status: OptimizationResultStatus,
6066
samples: Optional[List[SolutionSample]],
61-
relaxed_results: MinimumEigensolverResult,
67+
relaxed_results: Union[
68+
MinimumEigensolverResult, LegacyMinimumEigensolverResult
69+
],
6270
rounding_results: RoundingResult,
6371
relaxed_results_offset: float,
6472
sense: int,
@@ -88,7 +96,9 @@ def __init__(
8896
self._sense = sense
8997

9098
@property
91-
def relaxed_results(self) -> MinimumEigensolverResult:
99+
def relaxed_results(
100+
self,
101+
) -> Union[MinimumEigensolverResult, LegacyMinimumEigensolverResult]:
92102
"""Variationally obtained ground state of the relaxed Hamiltonian"""
93103
return self._relaxed_results
94104

@@ -132,7 +142,7 @@ class QuantumRandomAccessOptimizer(OptimizationAlgorithm):
132142

133143
def __init__(
134144
self,
135-
min_eigen_solver: MinimumEigensolver,
145+
min_eigen_solver: Union[MinimumEigensolver, LegacyMinimumEigensolver],
136146
encoding: QuantumRandomAccessEncoding,
137147
rounding_scheme: Optional[RoundingScheme] = None,
138148
):
@@ -156,12 +166,14 @@ def __init__(
156166
self.rounding_scheme = rounding_scheme
157167

158168
@property
159-
def min_eigen_solver(self) -> MinimumEigensolver:
169+
def min_eigen_solver(self) -> Union[MinimumEigensolver, LegacyMinimumEigensolver]:
160170
"""The minimum eigensolver."""
161171
return self._min_eigen_solver
162172

163173
@min_eigen_solver.setter
164-
def min_eigen_solver(self, min_eigen_solver: MinimumEigensolver) -> None:
174+
def min_eigen_solver(
175+
self, min_eigen_solver: Union[MinimumEigensolver, LegacyMinimumEigensolver]
176+
) -> None:
165177
"""Set the minimum eigensolver."""
166178
if not min_eigen_solver.supports_aux_operators():
167179
raise TypeError(
@@ -196,7 +208,11 @@ def get_compatibility_msg(self, problem: QuadraticProgram) -> str:
196208
)
197209
return ""
198210

199-
def solve_relaxed(self) -> Tuple[MinimumEigensolverResult, RoundingContext]:
211+
def solve_relaxed(
212+
self,
213+
) -> Tuple[
214+
Union[MinimumEigensolverResult, LegacyMinimumEigensolverResult], RoundingContext
215+
]:
200216
"""Solve the relaxed Hamiltonian given the ``encoding`` provided to the constructor."""
201217
# Get the ordered list of operators that correspond to each decision
202218
# variable. This line assumes the variables are numbered consecutively
@@ -230,10 +246,17 @@ def solve_relaxed(self) -> Tuple[MinimumEigensolverResult, RoundingContext]:
230246
circuit = self.min_eigen_solver.ansatz.bind_parameters(
231247
relaxed_results.optimal_point
232248
)
233-
elif isinstance(self.min_eigen_solver, NumPyMinimumEigensolver):
249+
elif isinstance(
250+
self.min_eigen_solver,
251+
(NumPyMinimumEigensolver, LegacyNumPyMinimumEigensolver),
252+
):
234253
statevector = relaxed_results.eigenstate
254+
if isinstance(statevector, StateFn):
255+
# This code path is triggered only with using
256+
# LegacyNumPyMinimumEigensolver
257+
statevector = statevector.primitive
235258
circuit = QuantumCircuit(self.encoding.num_qubits)
236-
circuit.initialize(statevector.primitive)
259+
circuit.initialize(statevector)
237260
else:
238261
circuit = None
239262

tests/test_quantum_random_access_optimizer.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,18 @@
1313
"""Tests for QuantumRandomAccessOptimizer."""
1414

1515
from unittest import TestCase
16+
import pytest
1617

1718
from qiskit.utils import QuantumInstance
1819
from qiskit.algorithms.minimum_eigensolvers import (
1920
VQE,
2021
NumPyMinimumEigensolver,
2122
MinimumEigensolverResult,
2223
)
24+
from qiskit.algorithms.minimum_eigen_solvers import (
25+
NumPyMinimumEigensolver as LegacyNumPyMinimumEigensolver,
26+
MinimumEigensolverResult as LegacyMinimumEigensolverResult,
27+
)
2328
from qiskit.circuit.library import RealAmplitudes, QAOAAnsatz
2429
from qiskit.algorithms.optimizers import SPSA
2530
from qiskit.primitives import Estimator
@@ -93,6 +98,17 @@ def test_solve_relaxed_numpy(self):
9398
self.assertIsInstance(relaxed_results, MinimumEigensolverResult)
9499
self.assertIsInstance(rounding_context, RoundingContext)
95100

101+
@pytest.mark.filterwarnings("ignore::PendingDeprecationWarning")
102+
def test_solve_relaxed_legacy_numpy(self):
103+
"""Test QuantumRandomAccessOptimizer with legacy NumPyMinimumEigensolver."""
104+
np_solver = LegacyNumPyMinimumEigensolver()
105+
qrao = QuantumRandomAccessOptimizer(
106+
encoding=self.encoding, min_eigen_solver=np_solver
107+
)
108+
relaxed_results, rounding_context = qrao.solve_relaxed()
109+
self.assertIsInstance(relaxed_results, LegacyMinimumEigensolverResult)
110+
self.assertIsInstance(rounding_context, RoundingContext)
111+
96112
def test_different_problem(self):
97113
"""Test passing a different problem to solve() than the encoding."""
98114
np_solver = NumPyMinimumEigensolver()

0 commit comments

Comments
 (0)