mirror of https://github.com/Qiskit/qiskit.git
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:
parent
e5ea411837
commit
324c875eba
|
@ -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
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixes a bug causing QNSPSA to fail when ``max_evals_grouped`` was set to a
|
||||
value larger than 1.
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue