diff --git a/qiskit/primitives/estimatorv2converter.py b/qiskit/primitives/estimatorv2converter.py index 73c6a15f8c3b..f803ad55e9e9 100644 --- a/qiskit/primitives/estimatorv2converter.py +++ b/qiskit/primitives/estimatorv2converter.py @@ -15,7 +15,8 @@ """ from __future__ import annotations -from collections.abc import Iterable, Sequence +from collections.abc import Iterable +from warnings import warn import numpy as np @@ -46,7 +47,7 @@ def __init__( def run( self, pubs: Iterable[EstimatorPubLike], *, precision: float | None = None - ) -> BasePrimitiveJob[PrimitiveResult[PubResult]]: + ) -> PrimitiveJob[PrimitiveResult[PubResult]]: coerced_pubs = [EstimatorPub.coerce(pub, precision) for pub in pubs] job = PrimitiveJob(self._run, coerced_pubs) @@ -60,18 +61,19 @@ def _run_pub(self, pub: EstimatorPub) -> PubResult: circuit = pub.circuit observables = pub.observables parameter_values = pub.parameter_values - precision = pub.precision + if pub.precision is not None: + warn("Precision is not defined yet. Ignored now.") out_shape = np.broadcast_shapes(pub.observables.shape, pub.parameter_values.shape) - param_broad = np.broadcast_to(pub.parameter_values, out_shape) - param_object = np.zeros(pub.parameter_values.shape, dtype=object) - param_array = pub.parameter_values.as_array(circuit.parameters) - for idx in np.ndindex(pub.parameter_values.shape): + + param_object = np.zeros(parameter_values.shape, dtype=object) + param_array = parameter_values.as_array(circuit.parameters) + for idx in np.ndindex(parameter_values.shape): param_object[idx] = param_array[idx].tolist() obs_list = [] param_list = [] - for obs, param in np.broadcast(pub.observables, param_object): + for obs, param in np.broadcast(observables, param_object): spo = SparsePauliOp.from_list(list(obs.items())) obs_list.append(spo) param_list.append(param) @@ -80,8 +82,9 @@ def _run_pub(self, pub: EstimatorPub) -> PubResult: result = self._estimatorv1.run([circuit] * size, obs_list, param_list).result() evs = result.values.reshape(out_shape) stds_list = [ - np.sqrt(dat.get("variance", 0) / dat.get("shots", 1)) for dat in result.metadata + np.sqrt(dat.get("variance", np.nan) / dat.get("shots", 1)) for dat in result.metadata ] stds = np.array(stds_list).reshape(out_shape) data_bin = self._make_data_bin(pub)(evs=evs, stds=stds) - return PubResult(data_bin, metadata={"precision": precision}) + metadata = result.metadata + return PubResult(data_bin, metadata=metadata) diff --git a/test/python/primitives/test_estimatorv2converter.py b/test/python/primitives/test_estimatorv2converter.py index dfea663c54b1..48425edb3244 100644 --- a/test/python/primitives/test_estimatorv2converter.py +++ b/test/python/primitives/test_estimatorv2converter.py @@ -19,7 +19,7 @@ from qiskit.circuit import Parameter, QuantumCircuit from qiskit.circuit.library import RealAmplitudes -from qiskit.primitives import Estimator, EstimatorV2Converter, StatevectorEstimator +from qiskit.primitives import Estimator, EstimatorV2Converter from qiskit.primitives.containers.bindings_array import BindingsArray from qiskit.primitives.containers.estimator_pub import EstimatorPub from qiskit.primitives.containers.observables_array import ObservablesArray @@ -133,7 +133,6 @@ def test_run_single_circuit_observable(self): self.subTest(f"{val}") result = est.run([(qc, op, val)]).result() np.testing.assert_allclose(result[0].data.evs, target) - self.assertEqual(result[0].metadata["precision"], 0) with self.subTest("One parameter"): param = Parameter("x") @@ -267,21 +266,24 @@ def test_run_numpy_params(self): def test_precision_seed(self): """Test for precision and seed""" precision = 0.1 - shots = int(1 / precision) # TODO: define the relation between precision and shots - estimator_v1 = Estimator({"seed": 1, "shots": shots}) + shots = int(1 / precision**2) # TODO: define the relation between precision and shots + estimator_v1 = Estimator(options={"seed": 1, "shots": shots}) estimator = EstimatorV2Converter(estimator_v1) psi1 = self.psi[0] hamiltonian1 = self.hamiltonian[0] theta1 = self.theta[0] job = estimator.run([(psi1, hamiltonian1, [theta1])]) result = job.result() - np.testing.assert_allclose(result[0].data.evs, [1.901141473854881]) + print(result[0].data.evs[0]) + np.testing.assert_allclose(result[0].data.evs, [1.5856819871431034]) # The result of the second run is the same job = estimator.run([(psi1, hamiltonian1, [theta1]), (psi1, hamiltonian1, [theta1])]) result = job.result() - np.testing.assert_allclose(result[0].data.evs, [1.901141473854881]) - np.testing.assert_allclose(result[1].data.evs, [1.901141473854881]) - # precision=0 impliese the exact expectation value + np.testing.assert_allclose(result[0].data.evs, [1.5856819871431034]) + np.testing.assert_allclose(result[1].data.evs, [1.5856819871431034]) + # precision=0 is equivalent to shots=None + estimator_v1 = Estimator(options={"seed": 1, "shots": None}) + estimator = EstimatorV2Converter(estimator_v1) job = estimator.run([(psi1, hamiltonian1, [theta1])], precision=0) result = job.result() np.testing.assert_allclose(result[0].data.evs, [1.5555572817900956])