def test_fusion_two_qubits(self): """Test 2-qubit fusion""" shots = 100 num_qubits = 8 reps = 3 circuit = RealAmplitudes(num_qubits=num_qubits, entanglement='linear', reps=reps) param_binds = {} for param in circuit.parameters: param_binds[param] = np.random.random() circuit = transpile(circuit.bind_parameters(param_binds), backend=self.SIMULATOR, optimization_level=0) circuit.measure_all() qobj = assemble([circuit], self.SIMULATOR, shots=shots, seed_simulator=1) backend_options = self.fusion_options(enabled=True, threshold=1) backend_options['fusion_verbose'] = True backend_options['fusion_enable.2_qubits'] = False result_disabled = self.SIMULATOR.run(qobj, **backend_options).result() meta_disabled = self.fusion_metadata(result_disabled) backend_options['fusion_enable.2_qubits'] = True result_enabled = self.SIMULATOR.run(qobj, **backend_options).result() meta_enabled = self.fusion_metadata(result_enabled) self.assertTrue(getattr(result_disabled, 'success', 'False')) self.assertTrue(getattr(result_enabled, 'success', 'False')) self.assertTrue( len(meta_enabled['output_ops']) if 'output_ops' in meta_enabled else len(circuit.ops) < len(meta_disabled['output_ops']) if 'output_ops' in meta_disabled else len(circuit.ops))
class TestEstimator(QiskitTestCase): """Test Estimator""" def setUp(self): super().setUp() self.ansatz = RealAmplitudes(num_qubits=2, reps=2) self.observable = PauliSumOp.from_list([ ("II", -1.052373245772859), ("IZ", 0.39793742484318045), ("ZI", -0.39793742484318045), ("ZZ", -0.01128010425623538), ("XX", 0.18093119978423156), ]) self.expvals = -1.0284380963435145, -1.284366511861733 self.psi = (RealAmplitudes(num_qubits=2, reps=2), RealAmplitudes(num_qubits=2, reps=3)) self.params = tuple(psi.parameters for psi in self.psi) self.hamiltonian = ( SparsePauliOp.from_list([("II", 1), ("IZ", 2), ("XI", 3)]), SparsePauliOp.from_list([("IZ", 1)]), SparsePauliOp.from_list([("ZI", 1), ("ZZ", 1)]), ) self.theta = ( [0, 1, 1, 2, 3, 5], [0, 1, 1, 2, 3, 5, 8, 13], [1, 2, 3, 4, 5, 6], ) def test_estimator(self): """test for a simple use case""" lst = [("XX", 1), ("YY", 2), ("ZZ", 3)] with self.subTest("PauliSumOp"): observable = PauliSumOp.from_list(lst) ansatz = RealAmplitudes(num_qubits=2, reps=2) with self.assertWarns(DeprecationWarning): est = Estimator([ansatz], [observable]) result = est([0], [0], parameter_values=[[0, 1, 1, 2, 3, 5]]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1.84209213]) with self.subTest("SparsePauliOp"): observable = SparsePauliOp.from_list(lst) ansatz = RealAmplitudes(num_qubits=2, reps=2) with self.assertWarns(DeprecationWarning): est = Estimator([ansatz], [observable]) result = est([0], [0], parameter_values=[[0, 1, 1, 2, 3, 5]]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1.84209213]) def test_estimator_param_reverse(self): """test for the reverse parameter""" observable = PauliSumOp.from_list([("XX", 1), ("YY", 2), ("ZZ", 3)]) ansatz = RealAmplitudes(num_qubits=2, reps=2) with self.assertWarns(DeprecationWarning): est = Estimator([ansatz], [observable], [ansatz.parameters[::-1]]) result = est([0], [0], parameter_values=[[0, 1, 1, 2, 3, 5][::-1]]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1.84209213]) def test_init_observable_from_operator(self): """test for evaluate without parameters""" circuit = self.ansatz.bind_parameters([0, 1, 1, 2, 3, 5]) matrix = Operator([ [-1.06365335, 0.0, 0.0, 0.1809312], [0.0, -1.83696799, 0.1809312, 0.0], [0.0, 0.1809312, -0.24521829, 0.0], [0.1809312, 0.0, 0.0, -1.06365335], ]) with self.assertWarns(DeprecationWarning): est = Estimator([circuit], [matrix]) result = est([0], [0]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [-1.284366511861733]) def test_evaluate(self): """test for evaluate""" with self.assertWarns(DeprecationWarning): est = Estimator([self.ansatz], [self.observable]) result = est([0], [0], parameter_values=[[0, 1, 1, 2, 3, 5]]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [-1.284366511861733]) def test_evaluate_multi_params(self): """test for evaluate with multiple parameters""" with self.assertWarns(DeprecationWarning): est = Estimator([self.ansatz], [self.observable]) result = est([0] * 2, [0] * 2, parameter_values=[[0, 1, 1, 2, 3, 5], [1, 1, 2, 3, 5, 8]]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [-1.284366511861733, -1.3187526349078742]) def test_evaluate_no_params(self): """test for evaluate without parameters""" circuit = self.ansatz.bind_parameters([0, 1, 1, 2, 3, 5]) with self.assertWarns(DeprecationWarning): est = Estimator([circuit], [self.observable]) result = est([0], [0]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [-1.284366511861733]) def test_run_with_multiple_observables_and_none_parameters(self): """test for evaluate without parameters""" circuit = QuantumCircuit(3) circuit.h(0) circuit.cx(0, 1) circuit.cx(1, 2) with self.assertWarns(DeprecationWarning): est = Estimator(circuit, ["ZZZ", "III"]) result = est(circuits=[0, 0], observables=[0, 1]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [0.0, 1.0]) def test_estimator_example(self): """test for Estimator example""" psi1 = RealAmplitudes(num_qubits=2, reps=2) psi2 = RealAmplitudes(num_qubits=2, reps=3) params1 = psi1.parameters params2 = psi2.parameters op1 = SparsePauliOp.from_list([("II", 1), ("IZ", 2), ("XI", 3)]) op2 = SparsePauliOp.from_list([("IZ", 1)]) op3 = SparsePauliOp.from_list([("ZI", 1), ("ZZ", 1)]) with self.assertWarns(DeprecationWarning): est = Estimator([psi1, psi2], [op1, op2, op3], [params1, params2]) theta1 = [0, 1, 1, 2, 3, 5] theta2 = [0, 1, 1, 2, 3, 5, 8, 13] theta3 = [1, 2, 3, 4, 5, 6] # calculate [ <psi1(theta1)|op1|psi1(theta1)> ] with self.assertWarns(DeprecationWarning): result = est([0], [0], [theta1]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1.5555572817900956]) self.assertEqual(len(result.metadata), 1) # calculate [ <psi1(theta1)|op2|psi1(theta1)>, <psi1(theta1)|op3|psi1(theta1)> ] with self.assertWarns(DeprecationWarning): result = est([0, 0], [1, 2], [theta1] * 2) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [-0.5516530027638437, 0.07535238795415422]) self.assertEqual(len(result.metadata), 2) # calculate [ <psi2(theta2)|op2|psi2(theta2)> ] with self.assertWarns(DeprecationWarning): result = est([1], [1], [theta2]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [0.17849238433885167]) self.assertEqual(len(result.metadata), 1) # calculate [ <psi1(theta1)|op1|psi1(theta1)>, <psi1(theta3)|op1|psi1(theta3)> ] with self.assertWarns(DeprecationWarning): result = est([0, 0], [0, 0], [theta1, theta3]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1.5555572817900956, 1.0656325933346835]) self.assertEqual(len(result.metadata), 2) # calculate [ <psi1(theta1)|op1|psi1(theta1)>, # <psi2(theta2)|op2|psi2(theta2)>, # <psi1(theta3)|op3|psi1(theta3)> ] with self.assertWarns(DeprecationWarning): result = est([0, 1, 0], [0, 1, 2], [theta1, theta2, theta3]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose( result.values, [1.5555572817900956, 0.17849238433885167, -1.0876631752254926]) self.assertEqual(len(result.metadata), 3) # It is possible to pass objects. # calculate [ <psi2(theta2)|H2|psi2(theta2)> ] with self.assertWarns(DeprecationWarning): result = est([psi2], [op2], [theta2]) np.testing.assert_allclose(result.values, [0.17849238433885167]) self.assertEqual(len(result.metadata), 1) def test_1qubit(self): """Test for 1-qubit cases""" qc = QuantumCircuit(1) qc2 = QuantumCircuit(1) qc2.x(0) op = SparsePauliOp.from_list([("I", 1)]) op2 = SparsePauliOp.from_list([("Z", 1)]) with self.assertWarns(DeprecationWarning): est = Estimator([qc, qc2], [op, op2], [[]] * 2) result = est([0], [0], [[]]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1]) with self.assertWarns(DeprecationWarning): result = est([0], [1], [[]]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1]) with self.assertWarns(DeprecationWarning): result = est([1], [0], [[]]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1]) with self.assertWarns(DeprecationWarning): result = est([1], [1], [[]]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [-1]) def test_2qubits(self): """Test for 2-qubit cases (to check endian)""" qc = QuantumCircuit(2) qc2 = QuantumCircuit(2) qc2.x(0) op = SparsePauliOp.from_list([("II", 1)]) op2 = SparsePauliOp.from_list([("ZI", 1)]) op3 = SparsePauliOp.from_list([("IZ", 1)]) with self.assertWarns(DeprecationWarning): est = Estimator([qc, qc2], [op, op2, op3], [[]] * 2) result = est([0], [0], [[]]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1]) with self.assertWarns(DeprecationWarning): result = est([1], [0], [[]]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1]) with self.assertWarns(DeprecationWarning): result = est([0], [1], [[]]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1]) with self.assertWarns(DeprecationWarning): result = est([1], [1], [[]]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1]) with self.assertWarns(DeprecationWarning): result = est([0], [2], [[]]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1]) with self.assertWarns(DeprecationWarning): result = est([1], [2], [[]]) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [-1]) def test_errors(self): """Test for errors""" qc = QuantumCircuit(1) qc2 = QuantumCircuit(2) op = SparsePauliOp.from_list([("I", 1)]) op2 = SparsePauliOp.from_list([("II", 1)]) with self.assertWarns(DeprecationWarning): est = Estimator([qc, qc2], [op, op2], [[]] * 2) with self.assertRaises(QiskitError), self.assertWarns( DeprecationWarning): est([0], [1], [[]]) with self.assertRaises(QiskitError), self.assertWarns( DeprecationWarning): est([1], [0], [[]]) with self.assertRaises(QiskitError), self.assertWarns( DeprecationWarning): est([0], [0], [[1e4]]) with self.assertRaises(QiskitError), self.assertWarns( DeprecationWarning): est([1], [1], [[1, 2]]) with self.assertRaises(QiskitError), self.assertWarns( DeprecationWarning): est([0, 1], [1], [[1]]) with self.assertRaises(QiskitError), self.assertWarns( DeprecationWarning): est([0], [0, 1], [[1]]) def test_empty_parameter(self): """Test for empty parameter""" n = 2 qc = QuantumCircuit(n) op = SparsePauliOp.from_list([("I" * n, 1)]) with self.assertWarns(DeprecationWarning): estimator = Estimator(circuits=[qc] * 10, observables=[op] * 10) with self.subTest("one circuit"): with self.assertWarns(DeprecationWarning): result = estimator([0], [1], shots=1000) np.testing.assert_allclose(result.values, [1]) self.assertEqual(len(result.metadata), 1) with self.subTest("two circuits"): with self.assertWarns(DeprecationWarning): result = estimator([2, 4], [3, 5], shots=1000) np.testing.assert_allclose(result.values, [1, 1]) self.assertEqual(len(result.metadata), 2) def test_numpy_params(self): """Test for numpy array as parameter values""" qc = RealAmplitudes(num_qubits=2, reps=2) op = SparsePauliOp.from_list([("IZ", 1), ("XI", 2), ("ZY", -1)]) k = 5 params_array = np.random.rand(k, qc.num_parameters) params_list = params_array.tolist() params_list_array = list(params_array) with self.assertWarns(DeprecationWarning): estimator = Estimator(circuits=qc, observables=op) target = estimator([0] * k, [0] * k, params_list) with self.subTest("ndarrary"): with self.assertWarns(DeprecationWarning): result = estimator([0] * k, [0] * k, params_array) self.assertEqual(len(result.metadata), k) np.testing.assert_allclose(result.values, target.values) with self.subTest("list of ndarray"): with self.assertWarns(DeprecationWarning): result = estimator([0] * k, [0] * k, params_list_array) self.assertEqual(len(result.metadata), k) np.testing.assert_allclose(result.values, target.values) def test_passing_objects(self): """Test passsing object for Estimator.""" with self.subTest("Valid test"): with self.assertWarns(DeprecationWarning): estimator = Estimator([self.ansatz], [self.observable]) result = estimator( circuits=[self.ansatz, self.ansatz], observables=[self.observable, self.observable], parameter_values=[list(range(6)), [0, 1, 1, 2, 3, 5]], ) self.assertAlmostEqual(result.values[0], self.expvals[0]) self.assertAlmostEqual(result.values[1], self.expvals[1]) with self.subTest("Invalid circuit test"): circuit = QuantumCircuit(2) with self.assertWarns(DeprecationWarning): estimator = Estimator([self.ansatz], [self.observable]) with self.assertRaises(QiskitError), self.assertWarns( DeprecationWarning): result = estimator( circuits=[self.ansatz, circuit], observables=[self.observable, self.observable], parameter_values=[list(range(6)), [0, 1, 1, 2, 3, 5]], ) with self.subTest("Invalid observable test"): observable = SparsePauliOp(["ZX"]) with self.assertWarns(DeprecationWarning): estimator = Estimator([self.ansatz], [self.observable]) with self.assertRaises(QiskitError), self.assertWarns( DeprecationWarning): result = estimator( circuits=[self.ansatz, self.ansatz], observables=[observable, self.observable], parameter_values=[list(range(6)), [0, 1, 1, 2, 3, 5]], ) def test_deprecated_arguments(self): """test for deprecated arguments""" with self.assertWarns(DeprecationWarning): est = Estimator([self.ansatz], [self.observable]) result = est( circuit_indices=[0], observable_indices=[0], parameter_values=[[0, 1, 1, 2, 3, 5]], ) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [-1.284366511861733]) def test_with_shots_option(self): """test with shots option.""" with self.assertWarns(DeprecationWarning): est = Estimator([self.ansatz], [self.observable]) result = est([0], [0], parameter_values=[[0, 1, 1, 2, 3, 5]], shots=1024, seed=15) self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [-1.307397243478641]) def test_with_shots_option_none(self): """test with shots=None option. Seed is ignored then.""" with self.assertWarns(DeprecationWarning): est = Estimator([self.ansatz], [self.observable]) result_42 = est([0], [0], parameter_values=[[0, 1, 1, 2, 3, 5]], shots=None, seed=42) result_15 = est([0], [0], parameter_values=[[0, 1, 1, 2, 3, 5]], shots=None, seed=15) np.testing.assert_allclose(result_42.values, result_15.values) def test_estimator_run(self): """Test Estimator.run()""" psi1, psi2 = self.psi hamiltonian1, hamiltonian2, hamiltonian3 = self.hamiltonian theta1, theta2, theta3 = self.theta estimator = Estimator() # Specify the circuit and observable by indices. # calculate [ <psi1(theta1)|H1|psi1(theta1)> ] job = estimator.run([psi1], [hamiltonian1], [theta1]) self.assertIsInstance(job, JobV1) result = job.result() self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1.5555572817900956]) # Objects can be passed instead of indices. # Note that passing objects has an overhead # since the corresponding indices need to be searched. # User can append a circuit and observable. # calculate [ <psi2(theta2)|H2|psi2(theta2)> ] result2 = estimator.run([psi2], [hamiltonian1], [theta2]).result() np.testing.assert_allclose(result2.values, [2.97797666]) # calculate [ <psi1(theta1)|H2|psi1(theta1)>, <psi1(theta1)|H3|psi1(theta1)> ] result3 = estimator.run([psi1, psi1], [hamiltonian2, hamiltonian3], [theta1] * 2).result() np.testing.assert_allclose(result3.values, [-0.551653, 0.07535239]) # calculate [ <psi1(theta1)|H1|psi1(theta1)>, # <psi2(theta2)|H2|psi2(theta2)>, # <psi1(theta3)|H3|psi1(theta3)> ] result4 = estimator.run([psi1, psi2, psi1], [hamiltonian1, hamiltonian2, hamiltonian3], [theta1, theta2, theta3]).result() np.testing.assert_allclose(result4.values, [1.55555728, 0.17849238, -1.08766318]) def test_estiamtor_run_no_params(self): """test for estimator without parameters""" circuit = self.ansatz.bind_parameters([0, 1, 1, 2, 3, 5]) est = Estimator() result = est.run([circuit], [self.observable]).result() self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [-1.284366511861733]) def test_run_1qubit(self): """Test for 1-qubit cases""" qc = QuantumCircuit(1) qc2 = QuantumCircuit(1) qc2.x(0) op = SparsePauliOp.from_list([("I", 1)]) op2 = SparsePauliOp.from_list([("Z", 1)]) est = Estimator() result = est.run([qc], [op], [[]]).result() self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1]) result = est.run([qc], [op2], [[]]).result() self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1]) result = est.run([qc2], [op], [[]]).result() self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1]) result = est.run([qc2], [op2], [[]]).result() self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [-1]) def test_run_2qubits(self): """Test for 2-qubit cases (to check endian)""" qc = QuantumCircuit(2) qc2 = QuantumCircuit(2) qc2.x(0) op = SparsePauliOp.from_list([("II", 1)]) op2 = SparsePauliOp.from_list([("ZI", 1)]) op3 = SparsePauliOp.from_list([("IZ", 1)]) est = Estimator() result = est.run([qc], [op], [[]]).result() self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1]) result = est.run([qc2], [op], [[]]).result() self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1]) result = est.run([qc], [op2], [[]]).result() self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1]) result = est.run([qc2], [op2], [[]]).result() self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1]) result = est.run([qc], [op3], [[]]).result() self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [1]) result = est.run([qc2], [op3], [[]]).result() self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [-1]) def test_run_errors(self): """Test for errors""" qc = QuantumCircuit(1) qc2 = QuantumCircuit(2) op = SparsePauliOp.from_list([("I", 1)]) op2 = SparsePauliOp.from_list([("II", 1)]) est = Estimator() with self.assertRaises(QiskitError): est.run([qc], [op2], [[]]).result() with self.assertRaises(QiskitError): est.run([qc2], [op], [[]]).result() with self.assertRaises(QiskitError): est.run([qc], [op], [[1e4]]).result() with self.assertRaises(QiskitError): est.run([qc2], [op2], [[1, 2]]).result() with self.assertRaises(QiskitError): est.run([qc, qc2], [op2], [[1]]).result() with self.assertRaises(QiskitError): est.run([qc], [op, op2], [[1]]).result() def test_run_numpy_params(self): """Test for numpy array as parameter values""" qc = RealAmplitudes(num_qubits=2, reps=2) op = SparsePauliOp.from_list([("IZ", 1), ("XI", 2), ("ZY", -1)]) k = 5 params_array = np.random.rand(k, qc.num_parameters) params_list = params_array.tolist() params_list_array = list(params_array) estimator = Estimator() target = estimator.run([qc] * k, [op] * k, params_list).result() with self.subTest("ndarrary"): result = estimator.run([qc] * k, [op] * k, params_array).result() self.assertEqual(len(result.metadata), k) np.testing.assert_allclose(result.values, target.values) with self.subTest("list of ndarray"): result = estimator.run([qc] * k, [op] * k, params_list_array).result() self.assertEqual(len(result.metadata), k) np.testing.assert_allclose(result.values, target.values) def test_run_with_shots_option(self): """test with shots option.""" est = Estimator() result = est.run( [self.ansatz], [self.observable], parameter_values=[[0, 1, 1, 2, 3, 5]], shots=1024, seed=15, ).result() self.assertIsInstance(result, EstimatorResult) np.testing.assert_allclose(result.values, [-1.307397243478641])