Skip to content

Commit

Permalink
fix: QNSPSA with max_evals_grouped exceeding 1
Browse files Browse the repository at this point in the history
Co-authored-by: Julien Gacon <gaconju@gmail.com>
  • Loading branch information
mrossinek and Cryoris committed Nov 23, 2022
1 parent 93fbc0d commit a98ea80
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 a98ea80

Please sign in to comment.