Skip to content

Commit

Permalink
fix: QNSPSA with max_evals_grouped exceeding 1 (#9182)
Browse files Browse the repository at this point in the history
Co-authored-by: Julien Gacon <gaconju@gmail.com>

Co-authored-by: Julien Gacon <gaconju@gmail.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
(cherry picked from commit 324c875)
  • Loading branch information
mrossinek authored and mergify[bot] committed Nov 23, 2022
1 parent 12c8847 commit 1b123d6
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 2 deletions.
12 changes: 11 additions & 1 deletion qiskit/algorithms/optimizers/qnspsa.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,18 @@ def get_fidelity(

fid = ComputeUncompute(sampler)

num_parameters = circuit.num_parameters

def fidelity(values_x, values_y):
result = fid.run(circuit, circuit, values_x, values_y).result()
values_x = np.reshape(values_x, (-1, num_parameters)).tolist()
batch_size_x = len(values_x)

values_y = np.reshape(values_y, (-1, num_parameters)).tolist()
batch_size_y = len(values_y)

result = fid.run(
batch_size_x * [circuit], batch_size_y * [circuit], values_x, values_y
).result()
return np.asarray(result.fidelities)

return fidelity
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
fixes:
- |
Fixes a bug causing QNSPSA to fail when ``max_evals_grouped`` was set to a
value larger than 1.
35 changes: 34 additions & 1 deletion test/python/algorithms/optimizers/test_spsa.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

from qiskit.algorithms.optimizers import SPSA, QNSPSA
from qiskit.circuit.library import PauliTwoDesign
from qiskit.primitives import Sampler
from qiskit.primitives import Estimator, Sampler
from qiskit.providers.basicaer import StatevectorSimulatorPy
from qiskit.opflow import I, Z, StateFn, MatrixExpectation
from qiskit.utils import algorithm_globals
Expand Down Expand Up @@ -222,3 +222,36 @@ def test_qnspsa_fidelity_primitives(self):
result = fidelity(initial_point, initial_point)

self.assertAlmostEqual(result[0], 1)

def test_qnspsa_max_evals_grouped(self):
"""Test using max_evals_grouped with QNSPSA."""
circuit = PauliTwoDesign(3, reps=1, seed=1)
num_parameters = circuit.num_parameters
obs = Z ^ Z ^ I

estimator = Estimator(options={"seed": 12})

initial_point = np.array(
[0.82311034, 0.02611798, 0.21077064, 0.61842177, 0.09828447, 0.62013131]
)

def objective(x):
x = np.reshape(x, (-1, num_parameters)).tolist()
n = len(x)
return estimator.run(n * [circuit], n * [obs.primitive], x).result().values.real

fidelity = QNSPSA.get_fidelity(circuit)
optimizer = QNSPSA(fidelity)
optimizer.maxiter = 1
optimizer.learning_rate = 0.05
optimizer.perturbation = 0.05
optimizer.set_max_evals_grouped(50) # greater than 1

result = optimizer.minimize(objective, initial_point)

with self.subTest("check final accuracy"):
self.assertAlmostEqual(result.fun[0], 0.473, places=3)

with self.subTest("check number of function calls"):
expected_nfev = 8 # 7 * maxiter + 1
self.assertEqual(result.nfev, expected_nfev)

0 comments on commit 1b123d6

Please sign in to comment.