fix: QNSPSA with max_evals_grouped exceeding 1 (#9182)

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>
This commit is contained in:
Max Rossmannek 2022-11-23 13:38:19 +01:00 committed by GitHub
parent e5ea411837
commit 324c875eba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 2 deletions

View File

@ -311,8 +311,18 @@ class QNSPSA(SPSA):
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

View File

@ -0,0 +1,5 @@
---
fixes:
- |
Fixes a bug causing QNSPSA to fail when ``max_evals_grouped`` was set to a
value larger than 1.

View File

@ -19,7 +19,7 @@ import numpy as np
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
@ -222,3 +222,36 @@ class TestSPSA(QiskitAlgorithmsTestCase):
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)