Skip to content

Commit ffc67c7

Browse files
committed
Use estimate_observables function
1 parent e9e37e7 commit ffc67c7

File tree

3 files changed

+90
-75
lines changed

3 files changed

+90
-75
lines changed

qiskit/algorithms/minimum_eigensolvers/vqe.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
from ..variational_algorithm import VariationalAlgorithm, VariationalResult
3535
from .minimum_eigensolver import MinimumEigensolver, MinimumEigensolverResult
3636

37-
# from qiskit.algorithms.observables_evaluator import eval_observables
37+
from ..observables_evaluator import estimate_observables
3838

3939
logger = logging.getLogger(__name__)
4040

@@ -201,12 +201,9 @@ def compute_minimum_eigenvalue(
201201
result.optimal_point,
202202
)
203203

204-
if aux_operators:
205-
# not None and not empty list or dict
204+
if aux_operators is not None:
206205
bound_ansatz = ansatz.bind_parameters(opt_result.x)
207-
# aux_values = eval_observables(self.estimator, bound_ansatz, aux_operators)
208-
# TODO remove once eval_operators have been ported.
209-
aux_values = self._eval_aux_ops(bound_ansatz, aux_operators)
206+
aux_values = estimate_observables(self.estimator, bound_ansatz, aux_operators)
210207
result.aux_operator_eigenvalues = aux_values
211208

212209
return result

test/python/algorithms/minimum_eigensolvers/test_numpy_minimum_eigensolver.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
from ddt import ddt, data
2020

2121
from qiskit.algorithms.minimum_eigensolvers import NumPyMinimumEigensolver
22-
from qiskit.opflow import PauliSumOp, X, Y, Z
22+
from qiskit.opflow import PauliSumOp
23+
from qiskit.quantum_info import SparsePauliOp
2324

2425

2526
@ddt
@@ -125,11 +126,12 @@ def criterion(x, v, a_v):
125126
self.assertEqual(result.eigenstate, None)
126127
self.assertEqual(result.aux_operator_eigenvalues, None)
127128

128-
@data(X, Y, Z)
129+
@data("X", "Y", "Z")
129130
def test_cme_1q(self, op):
130131
"""Test for 1 qubit operator"""
131132
algo = NumPyMinimumEigensolver()
132-
result = algo.compute_minimum_eigenvalue(operator=op)
133+
operator = PauliSumOp.from_list([(op, 1.0)])
134+
result = algo.compute_minimum_eigenvalue(operator=operator)
133135
self.assertAlmostEqual(result.eigenvalue, -1)
134136

135137
def test_cme_aux_ops_dict(self):

test/python/algorithms/minimum_eigensolvers/test_vqe.py

+82-66
Original file line numberDiff line numberDiff line change
@@ -363,77 +363,93 @@ def test_aux_operators_list(self):
363363
"""Test list-based aux_operators."""
364364
vqe = VQE(Estimator(), self.ry_wavefunction, SLSQP(maxiter=300))
365365

366-
# Start with an empty list
367-
result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=[])
368-
self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6)
369-
self.assertIsNone(result.aux_operator_eigenvalues)
370-
371-
# Go again with two auxiliary operators
372-
aux_op1 = PauliSumOp.from_list([("II", 2.0)])
373-
aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)])
374-
aux_ops = [aux_op1, aux_op2]
375-
result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops)
376-
self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6)
377-
self.assertEqual(len(result.aux_operator_eigenvalues), 2)
378-
# expectation values
379-
self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0], 2, places=6)
380-
self.assertAlmostEqual(result.aux_operator_eigenvalues[1][0], 0, places=6)
381-
# standard deviations
382-
self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1], 0.0)
383-
self.assertAlmostEqual(result.aux_operator_eigenvalues[1][1], 0.0)
384-
385-
# Go again with additional zero operator
386-
# TODO waiting for eval_operators to be ported.
387-
# extra_ops = [*aux_ops, 0]
388-
# result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=extra_ops)
389-
# self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6)
390-
# self.assertEqual(len(result.aux_operator_eigenvalues), 3)
391-
# # # expectation values
392-
# self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0], 2, places=6)
393-
# self.assertAlmostEqual(result.aux_operator_eigenvalues[1][0], 0, places=6)
394-
# self.assertEqual(result.aux_operator_eigenvalues[2][0], 0.0)
395-
# # # standard deviations
396-
# self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1], 0.0)
397-
# self.assertAlmostEqual(result.aux_operator_eigenvalues[1][1], 0.0)
398-
# self.assertAlmostEqual(result.aux_operator_eigenvalues[2][1], 0.0)
366+
with self.subTest("Test with an empty list."):
367+
result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=[])
368+
self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6)
369+
self.assertIsInstance(result.aux_operator_eigenvalues, list)
370+
self.assertEqual(len(result.aux_operator_eigenvalues), 0)
371+
372+
with self.subTest("Test with two auxiliary operators."):
373+
aux_op1 = PauliSumOp.from_list([("II", 2.0)])
374+
aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)])
375+
aux_ops = [aux_op1, aux_op2]
376+
result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops)
377+
self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6)
378+
self.assertEqual(len(result.aux_operator_eigenvalues), 2)
379+
# expectation values
380+
self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0], 2.0, places=6)
381+
self.assertAlmostEqual(result.aux_operator_eigenvalues[1][0], 0.0, places=6)
382+
# variances
383+
self.assertEqual(result.aux_operator_eigenvalues[0][1][0], 0.0)
384+
self.assertEqual(result.aux_operator_eigenvalues[1][1][0], 0.0)
385+
# shots
386+
self.assertEqual(result.aux_operator_eigenvalues[0][1][1], 0)
387+
self.assertEqual(result.aux_operator_eigenvalues[1][1][1], 0)
388+
389+
with self.subTest("Test with additional zero operator."):
390+
extra_ops = [*aux_ops, 0]
391+
result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=extra_ops)
392+
self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6)
393+
self.assertEqual(len(result.aux_operator_eigenvalues), 3)
394+
# expectation values
395+
self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0], 2.0, places=6)
396+
self.assertAlmostEqual(result.aux_operator_eigenvalues[1][0], 0.0, places=6)
397+
self.assertAlmostEqual(result.aux_operator_eigenvalues[2][0], 0.0)
398+
# variances
399+
self.assertEqual(result.aux_operator_eigenvalues[0][1][0], 0.0)
400+
self.assertEqual(result.aux_operator_eigenvalues[1][1][0], 0.0)
401+
self.assertEqual(result.aux_operator_eigenvalues[2][1][0], 0.0)
402+
# shots
403+
self.assertEqual(result.aux_operator_eigenvalues[0][1][1], 0)
404+
self.assertEqual(result.aux_operator_eigenvalues[1][1][1], 0)
405+
self.assertEqual(result.aux_operator_eigenvalues[2][1][1], 0)
399406

400407
def test_aux_operators_dict(self):
401408
"""Test dictionary compatibility of aux_operators"""
402409
vqe = VQE(Estimator(), self.ry_wavefunction, SLSQP(maxiter=300))
403410

404-
# Start with an empty dictionary
405-
result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators={})
406-
self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6)
407-
self.assertIsNone(result.aux_operator_eigenvalues)
408-
409-
# Go again with two auxiliary operators
410-
aux_op1 = PauliSumOp.from_list([("II", 2.0)])
411-
aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)])
412-
aux_ops = {"aux_op1": aux_op1, "aux_op2": aux_op2}
413-
result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops)
414-
self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6)
415-
self.assertEqual(len(result.aux_operator_eigenvalues), 2)
416-
# expectation values
417-
self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op1"][0], 2, places=5)
418-
self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op2"][0], 0, places=5)
419-
# standard deviations
420-
self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op1"][1], 0.0)
421-
self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op2"][1], 0.0)
422-
423-
# TODO waiting for eval_operators to be ported.
424-
# Go again with additional zero operator
425-
# extra_ops = {**aux_ops, "zero_operator": 0}
426-
# result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=extra_ops)
427-
# self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6)
428-
# self.assertEqual(len(result.aux_operator_eigenvalues), 3)
429-
# # expectation values
430-
# self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op1"][0], 2, places=5)
431-
# self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op2"][0], 0, places=5)
432-
# self.assertEqual(result.aux_operator_eigenvalues["zero_operator"][0], 0.0)
433-
# # standard deviations
434-
# self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op1"][1], 0.0)
435-
# self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op2"][1], 0.0)
436-
# self.assertAlmostEqual(result.aux_operator_eigenvalues["zero_operator"][1], 0.0)
411+
with self.subTest("Test with an empty dictionary."):
412+
result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators={})
413+
self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6)
414+
# self.assertIsNone(result.aux_operator_eigenvalues)
415+
self.assertIsInstance(result.aux_operator_eigenvalues, dict)
416+
self.assertEqual(len(result.aux_operator_eigenvalues), 0)
417+
418+
with self.subTest("Test with two auxiliary operators."):
419+
aux_op1 = PauliSumOp.from_list([("II", 2.0)])
420+
aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)])
421+
aux_ops = {"aux_op1": aux_op1, "aux_op2": aux_op2}
422+
result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops)
423+
self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6)
424+
self.assertEqual(len(result.aux_operator_eigenvalues), 2)
425+
426+
# expectation values
427+
self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op1"][0], 2, places=5)
428+
self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op2"][0], 0, places=5)
429+
# variances
430+
self.assertEqual(result.aux_operator_eigenvalues["aux_op1"][1][0], 0.0)
431+
self.assertEqual(result.aux_operator_eigenvalues["aux_op2"][1][0], 0.0)
432+
# shots
433+
self.assertEqual(result.aux_operator_eigenvalues["aux_op1"][1][1], 0)
434+
self.assertEqual(result.aux_operator_eigenvalues["aux_op2"][1][1], 0)
435+
436+
with self.subTest("Test with additional zero operator."):
437+
extra_ops = {**aux_ops, "zero_operator": 0}
438+
result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=extra_ops)
439+
self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6)
440+
self.assertEqual(len(result.aux_operator_eigenvalues), 3)
441+
# expectation values
442+
self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op1"][0], 2, places=5)
443+
self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op2"][0], 0, places=5)
444+
self.assertAlmostEqual(result.aux_operator_eigenvalues["zero_operator"][0], 0.0)
445+
# variances
446+
self.assertEqual(result.aux_operator_eigenvalues["aux_op1"][1][0], 0.0)
447+
self.assertEqual(result.aux_operator_eigenvalues["aux_op2"][1][0], 0.0)
448+
self.assertEqual(result.aux_operator_eigenvalues["zero_operator"][1][0], 0.0)
449+
# shots
450+
self.assertEqual(result.aux_operator_eigenvalues["aux_op1"][1][1], 0)
451+
self.assertEqual(result.aux_operator_eigenvalues["aux_op2"][1][1], 0)
452+
self.assertEqual(result.aux_operator_eigenvalues["zero_operator"][1][1], 0)
437453

438454

439455
if __name__ == "__main__":

0 commit comments

Comments
 (0)