def result_types_tensor_hermitian_hermitian_testing(device: Device, run_kwargs: Dict[str, Any]): shots = run_kwargs["shots"] theta = 0.432 phi = 0.123 varphi = -0.543 matrix1 = np.array([[1, 2], [2, 4]]) matrix2 = np.array( [ [-6, 2 + 1j, -3, -5 + 2j], [2 - 1j, 0, 2 - 1j, -5 + 4j], [-3, 2 + 1j, 0, -4 + 3j], [-5 - 2j, -5 - 4j, -4 - 3j, -6], ] ) obs = Observable.Hermitian(matrix1) @ Observable.Hermitian(matrix2) obs_targets = [0, 1, 2] circuit = get_result_types_three_qubit_circuit(theta, phi, varphi, obs, obs_targets, shots) result = device.run(circuit, **run_kwargs).result() expected_mean = -4.30215023196904 expected_var = 370.71292282796804 expected_eigs = np.array([-70.90875406, -31.04969387, 0, 3.26468993, 38.693758]) assert_variance_expectation_sample_result( result, shots, expected_var, expected_mean, expected_eigs )
def result_types_all_selected_testing(device: Device, run_kwargs: Dict[str, Any], test_program: bool = True): shots = run_kwargs["shots"] theta = 0.543 array = np.array([[1, 2j], [-2j, 0]]) circuit = (Circuit().rx(0, theta).rx(1, theta).variance( Observable.Hermitian(array)).expectation(Observable.Hermitian(array), 0)) if shots: circuit.add_result_type( ResultType.Sample(Observable.Hermitian(array), 1)) tasks = (circuit, ) if not test_program else (circuit, circuit.to_ir( ir_type=IRType.OPENQASM)) for task in tasks: result = device.run(task, **run_kwargs).result() expected_mean = 2 * np.sin(theta) + 0.5 * np.cos(theta) + 0.5 var = 0.25 * (np.sin(theta) - 4 * np.cos(theta))**2 expected_var = [var, var] expected_eigs = np.linalg.eigvalsh(array) assert_variance_expectation_sample_result(result, shots, expected_var, expected_mean, expected_eigs)
def test_hermitian_equality(): matrix = Observable.H().to_matrix() a1 = Observable.Hermitian(matrix=matrix) a2 = Observable.Hermitian(matrix=matrix) a3 = Observable.Hermitian(matrix=Observable.I().to_matrix()) a4 = "hi" assert a1 == a2 assert a1 != a3 assert a1 != a4
def test_add_result_type_same_observable_wrong_target_order_hermitian(): array = np.eye(4) Circuit().add_result_type( ResultType.Expectation( observable=Observable.Hermitian(matrix=array), target=[0, 1])).add_result_type( ResultType.Variance( observable=Observable.Hermitian(matrix=array), target=[1, 0]))
def test_add_result_type_same_observable_wrong_target_order_hermitian(): array = np.eye(4) circ = (Circuit().add_result_type( ResultType.Expectation( observable=Observable.Hermitian(matrix=array), target=[0, 1])).add_result_type( ResultType.Variance( observable=Observable.Hermitian(matrix=array), target=[1, 0]))) assert not circ.observables_simultaneously_measurable assert not circ.basis_rotation_instructions
def test_basis_rotation_instructions_multiple_result_types_same_targets_hermitian( ): circ = (Circuit().h(0).cnot(0, 1).sample( observable=Observable.Hermitian(matrix=np.array([[1, 0], [0, -1]])), target=[1]).expectation(observable=Observable.Hermitian( matrix=np.array([[1, 0], [0, -1]])), target=[1])) expected = [ Instruction(Gate.Unitary(matrix=np.array([[0, 1], [1, 0]])), target=[1]) ] assert circ.basis_rotation_instructions == expected
def test_basis_rotation_instructions_multiple_result_types_tensor_product_hermitian_qubit_count_2( ): circ = (Circuit().h(0).cnot(0, 1).cnot(1, 2).expectation( observable=Observable.I(), target=[1]).sample( observable=Observable.Hermitian(matrix=np.eye(4)) @ Observable.H(), target=[0, 1, 2]).variance(observable=Observable.H(), target=[ 2 ]).variance(observable=Observable.Hermitian(matrix=np.eye(4)), target=[0, 1]).expectation(observable=Observable.I(), target=[0])) expected = [ Instruction(Gate.Unitary(matrix=np.eye(4)), target=[0, 1]), Instruction(Gate.Ry(-np.pi / 4), 2), ] assert circ.basis_rotation_instructions == expected
def result_types_tensor_y_hermitian_testing(device: Device, run_kwargs: Dict[str, Any]): shots = run_kwargs["shots"] theta = 0.432 phi = 0.123 varphi = -0.543 array = np.array( [ [-6, 2 + 1j, -3, -5 + 2j], [2 - 1j, 0, 2 - 1j, -5 + 4j], [-3, 2 + 1j, 0, -4 + 3j], [-5 - 2j, -5 - 4j, -4 - 3j, -6], ] ) obs = Observable.Y() @ Observable.Hermitian(array) obs_targets = [0, 1, 2] circuit = get_result_types_three_qubit_circuit(theta, phi, varphi, obs, obs_targets, shots) result = device.run(circuit, **run_kwargs).result() expected_mean = 1.4499810303182408 expected_var = 74.03174647518193 y_array = np.array([[0, -1j], [1j, 0]]) expected_eigs = np.linalg.eigvalsh(np.kron(y_array, array)) assert_variance_expectation_sample_result( result, shots, expected_var, expected_mean, expected_eigs )
def test_multiple_result_types_with_custom_hermitian_ascii_symbol(): herm_matrix = (Observable.Y() @ Observable.Z()).to_matrix() circ = (Circuit().cnot(0, 2).cnot(1, 3).h(0).variance( observable=Observable.Y(), target=0).expectation(observable=Observable.Y(), target=3).expectation( observable=Observable.Hermitian( matrix=herm_matrix, display_name="MyHerm", ), target=[1, 2], )) expected = ( "T : | 0 |1| Result Types |", " ", "q0 : -C---H-Variance(Y)---------", " | ", "q1 : -|-C---Expectation(MyHerm)-", " | | | ", "q2 : -X-|---Expectation(MyHerm)-", " | ", "q3 : ---X---Expectation(Y)------", "", "T : | 0 |1| Result Types |", ) expected = "\n".join(expected) assert AsciiCircuitDiagram.build_diagram(circ) == expected
def test_multiple_result_types_with_state_vector_amplitude(): circ = ( Circuit() .cnot(0, 2) .cnot(1, 3) .h(0) .variance(observable=Observable.Y(), target=0) .expectation(observable=Observable.Y(), target=3) .expectation(observable=Observable.Hermitian(np.array([[1.0, 0.0], [0.0, 1.0]])), target=1) .amplitude(["0001"]) .state_vector() ) expected = ( "T : | 0 |1| Result Types |", " ", "q0 : -C---H-Variance(Y)------------", " | ", "q1 : -|-C---Expectation(Hermitian)-", " | | ", "q2 : -X-|--------------------------", " | ", "q3 : ---X---Expectation(Y)---------", "", "T : | 0 |1| Result Types |", "", "Additional result types: Amplitude(0001), StateVector", ) expected = "\n".join(expected) assert AsciiCircuitDiagram.build_diagram(circ) == expected
def test_basis_rotation_instructions_multiple_result_types_different_hermitian_targets( ): circ = (Circuit().h(0).cnot(0, 1).sample( observable=Observable.Hermitian(matrix=np.array([[1, 0], [0, -1]])), target=[1]).expectation( observable=Observable.Hermitian(matrix=np.array([[0, 1], [1, 0]])), target=[0])) expected = [ Instruction( Gate.Unitary(matrix=1.0 / np.sqrt(2.0) * np.array([[1.0, 1.0], [1.0, -1.0]], dtype=complex)), target=[0], ), Instruction(Gate.Unitary(matrix=np.array([[0, 1], [1, 0]])), target=[1]), ] assert circ.basis_rotation_instructions == expected
def test_tensor_product_matmul_tensor(): t1 = Observable.TensorProduct([Observable.Z(), Observable.I(), Observable.X()]) t2 = Observable.TensorProduct( [Observable.Hermitian(matrix=Observable.I().to_matrix()), Observable.Y()] ) t3 = t1 @ t2 assert t3.to_ir() == ["z", "i", "x", [[[1.0, 0], [0, 0]], [[0, 0], [1.0, 0]]], "y"] assert t3.qubit_count == 5 assert t3.ascii_symbols == tuple(["Z@I@X@Hermitian@Y"] * 5)
def result_types_noncommuting_all(device: Device, run_kwargs: Dict[str, Any]): array = np.array([[1, 2j], [-2j, 0]]) circuit = (Circuit().h(0).cnot( 0, 1).expectation(observable=Observable.Hermitian(array)).expectation( observable=Observable.X())) tasks = (circuit, circuit.to_ir(ir_type=IRType.OPENQASM)) for task in tasks: result = device.run(task, shots=0, **run_kwargs).result() assert np.allclose(result.values[0], [0.5, 0.5]) assert np.allclose(result.values[1], [0, 0])
def result_types_hermitian_testing(device: Device, run_kwargs: Dict[str, Any]): shots = run_kwargs["shots"] theta = 0.543 array = np.array([[1, 2j], [-2j, 0]]) circuit = (Circuit().rx(0, theta).variance(Observable.Hermitian(array), 0).expectation( Observable.Hermitian(array), 0)) if shots: circuit.add_result_type( ResultType.Sample(Observable.Hermitian(array), 0)) result = device.run(circuit, **run_kwargs).result() expected_mean = 2 * np.sin(theta) + 0.5 * np.cos(theta) + 0.5 expected_var = 0.25 * (np.sin(theta) - 4 * np.cos(theta))**2 expected_eigs = np.linalg.eigvalsh(array) assert_variance_expectation_sample_result(result, shots, expected_var, expected_mean, expected_eigs)
def test_basis_rotation_instructions_multiple_result_types_tensor_product_hermitian( ): circ = (Circuit().h(0).cnot(0, 1).cnot(1, 2).sample( observable=Observable.Hermitian(matrix=np.array([[1, 0], [0, -1]])) @ Observable.H(), target=[0, 1], ).variance( observable=Observable.Hermitian(matrix=np.array([[1, 0], [0, -1]])) @ Observable.H(), target=[0, 1], ).expectation( observable=Observable.Hermitian(matrix=np.array([[0, 1], [1, 0]])), target=[2])) expected = [ Instruction(Gate.Unitary(matrix=np.array([[0, 1], [1, 0]])), target=[0]), Instruction(Gate.Ry(-np.pi / 4), 1), Instruction( Gate.Unitary(matrix=1.0 / np.sqrt(2.0) * np.array([[1.0, 1.0], [1.0, -1.0]], dtype=complex)), target=[2], ), ] assert circ.basis_rotation_instructions == expected
def result_types_tensor_z_hermitian_testing(device: Device, run_kwargs: Dict[str, Any]): shots = run_kwargs["shots"] theta = 0.432 phi = 0.123 varphi = -0.543 array = np.array([ [-6, 2 + 1j, -3, -5 + 2j], [2 - 1j, 0, 2 - 1j, -5 + 4j], [-3, 2 + 1j, 0, -4 + 3j], [-5 - 2j, -5 - 4j, -4 - 3j, -6], ]) obs = Observable.Z() @ Observable.Hermitian(array) obs_targets = [0, 1, 2] circuit = get_result_types_three_qubit_circuit(theta, phi, varphi, obs, obs_targets, shots) tasks = (circuit, circuit.to_ir(ir_type=IRType.OPENQASM)) for task in tasks: result = device.run(task, **run_kwargs).result() expected_mean = 0.5 * ( -6 * np.cos(theta) * (np.cos(varphi) + 1) - 2 * np.sin(varphi) * (np.cos(theta) + np.sin(phi) - 2 * np.cos(phi)) + 3 * np.cos(varphi) * np.sin(phi) + np.sin(phi)) expected_var = ( 1057 - np.cos(2 * phi) + 12 * (27 + np.cos(2 * phi)) * np.cos(varphi) - 2 * np.cos(2 * varphi) * np.sin(phi) * (16 * np.cos(phi) + 21 * np.sin(phi)) + 16 * np.sin(2 * phi) - 8 * (-17 + np.cos(2 * phi) + 2 * np.sin(2 * phi)) * np.sin(varphi) - 8 * np.cos(2 * theta) * (3 + 3 * np.cos(varphi) + np.sin(varphi))**2 - 24 * np.cos(phi) * (np.cos(phi) + 2 * np.sin(phi)) * np.sin(2 * varphi) - 8 * np.cos(theta) * (4 * np.cos(phi) * (4 + 8 * np.cos(varphi) + np.cos(2 * varphi) - (1 + 6 * np.cos(varphi)) * np.sin(varphi)) + np.sin(phi) * (15 + 8 * np.cos(varphi) - 11 * np.cos(2 * varphi) + 42 * np.sin(varphi) + 3 * np.sin(2 * varphi)))) / 16 z_array = np.diag([1, -1]) expected_eigs = np.linalg.eigvalsh(np.kron(z_array, array)) assert_variance_expectation_sample_result(result, shots, expected_var, expected_mean, expected_eigs)
def result_types_noncommuting_testing(device: Device, run_kwargs: Dict[str, Any]): shots = 0 theta = 0.432 phi = 0.123 varphi = -0.543 array = np.array( [ [-6, 2 + 1j, -3, -5 + 2j], [2 - 1j, 0, 2 - 1j, -5 + 4j], [-3, 2 + 1j, 0, -4 + 3j], [-5 - 2j, -5 - 4j, -4 - 3j, -6], ] ) obs1 = Observable.X() @ Observable.Y() obs1_targets = [0, 2] obs2 = Observable.Z() @ Observable.Z() obs2_targets = [0, 2] obs3 = Observable.Y() @ Observable.Hermitian(array) obs3_targets = [0, 1, 2] circuit = ( get_result_types_three_qubit_circuit(theta, phi, varphi, obs1, obs1_targets, shots) .expectation(obs2, obs2_targets) .expectation(obs3, obs3_targets) ) result = device.run(circuit, **run_kwargs).result() expected_mean1 = np.sin(theta) * np.sin(phi) * np.sin(varphi) expected_var1 = ( 8 * np.sin(theta) ** 2 * np.cos(2 * varphi) * np.sin(phi) ** 2 - np.cos(2 * (theta - phi)) - np.cos(2 * (theta + phi)) + 2 * np.cos(2 * theta) + 2 * np.cos(2 * phi) + 14 ) / 16 expected_mean2 = 0.849694136476246 expected_mean3 = 1.4499810303182408 assert np.allclose(result.values[0], expected_var1) assert np.allclose(result.values[1], expected_mean1) assert np.allclose(result.values[2], expected_mean2) assert np.allclose(result.values[3], expected_mean3)
def test_hermitian_eigenvalues(matrix, eigenvalues): compare_eigenvalues(Observable.Hermitian(matrix=matrix), eigenvalues)
ir.Expectation, {"observable": Observable.Z(), "target": [0]}, {"observable": ["z"], "targets": [0]}, ), ( ResultType.Expectation, "expectation", ir.Expectation, {"observable": Observable.Z() @ Observable.I() @ Observable.X(), "target": [0, 1, 2]}, {"observable": ["z", "i", "x"], "targets": [0, 1, 2]}, ), ( ResultType.Expectation, "expectation", ir.Expectation, {"observable": Observable.Hermitian(matrix=Observable.I().to_matrix()), "target": [0]}, {"observable": [[[[1.0, 0], [0, 0]], [[0, 0], [1.0, 0]]]], "targets": [0]}, ), ( ResultType.Expectation, "expectation", ir.Expectation, {"observable": Observable.Hermitian(matrix=Observable.I().to_matrix()), "target": None}, {"observable": [[[[1.0, 0], [0, 0]], [[0, 0], [1.0, 0]]]]}, ), ( ResultType.Sample, "sample", ir.Sample, {"observable": Observable.Z(), "target": [0]}, {"observable": ["z"], "targets": [0]},
def test_hermitian_eigenvalues(matrix, eigenvalues): assert np.allclose(Observable.Hermitian(matrix=matrix).eigenvalues, eigenvalues)
"a" @ Observable.TensorProduct( [Observable.Z(), Observable.I(), Observable.X()]) @pytest.mark.parametrize( "observable,eigenvalues", [ (Observable.X() @ Observable.Y(), np.array([1, -1, -1, 1])), (Observable.X() @ Observable.Y() @ Observable.Z(), np.array([1, -1, -1, 1, -1, 1, 1, -1])), (Observable.X() @ Observable.Y() @ Observable.I(), np.array([1, 1, -1, -1, -1, -1, 1, 1])), ( Observable.X() @ Observable.Hermitian( np.array([[-1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])) @ Observable.Y(), np.array([-1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1]), ), ], ) def test_tensor_product_eigenvalues(observable, eigenvalues): compare_eigenvalues(observable, eigenvalues) # Test caching observable._factors = () compare_eigenvalues(observable, eigenvalues) @pytest.mark.parametrize( "observable,basis_rotation_gates", [
def test_hermitian_to_ir(): matrix = Observable.I().to_matrix() obs = Observable.Hermitian(matrix=matrix) assert obs.to_ir() == [[[[1, 0], [0, 0]], [[0, 0], [1, 0]]]]
def test_hermitian_invalid_matrix(matrix): Observable.Hermitian(matrix=matrix)
{ "observable": Observable.Z() @ Observable.I() @ Observable.X(), "target": [0, 1, 2] }, { "observable": ["z", "i", "x"], "targets": [0, 1, 2] }, ), ( ResultType.Expectation, "expectation", ir.Expectation, { "observable": Observable.Hermitian(matrix=Observable.I().to_matrix()), "target": [0] }, { "observable": [[[[1.0, 0], [0, 0]], [[0, 0], [1.0, 0]]]], "targets": [0] }, ), ( ResultType.Expectation, "expectation", ir.Expectation, { "observable": Observable.Hermitian(matrix=Observable.I().to_matrix()), "target": None
"h(q[3])", ), ( Observable.H(), OpenQASMSerializationProperties(qubit_reference_type=QubitReferenceType.PHYSICAL), [3], "h($3)", ), ( Observable.H(), OpenQASMSerializationProperties(qubit_reference_type=QubitReferenceType.VIRTUAL), None, "h all", ), ( Observable.Hermitian(np.eye(4)), OpenQASMSerializationProperties(qubit_reference_type=QubitReferenceType.VIRTUAL), [1, 2], "hermitian([[1+0im, 0im, 0im, 0im], [0im, 1+0im, 0im, 0im], " "[0im, 0im, 1+0im, 0im], [0im, 0im, 0im, 1+0im]]) q[1], q[2]", ), ( Observable.Hermitian(np.eye(4)), OpenQASMSerializationProperties(qubit_reference_type=QubitReferenceType.PHYSICAL), [1, 2], "hermitian([[1+0im, 0im, 0im, 0im], [0im, 1+0im, 0im, 0im], " "[0im, 0im, 1+0im, 0im], [0im, 0im, 0im, 1+0im]]) $1, $2", ), ( Observable.Hermitian(np.eye(2)), OpenQASMSerializationProperties(qubit_reference_type=QubitReferenceType.VIRTUAL),
def test_hermitian_str(): assert ( str(Observable.Hermitian(matrix=np.array([[1.0, 0.0], [0.0, 1.0]]))) == "Hermitian('qubit_count': 1, 'matrix': [[1.+0.j 0.+0.j], [0.+0.j 1.+0.j]])" )
def test_observable_from_ir_hermitian(): ir_observable = [[[[1, 0], [0, 0]], [[0, 0], [1, 0]]]] actual_observable = observable_from_ir(ir_observable) assert actual_observable == Observable.Hermitian( matrix=np.array([[1.0, 0.0], [0.0, 1.0]]))
def test_hermitian_basis_rotation_gates(matrix, basis_rotation_matrix): expected_unitary = Gate.Unitary(matrix=basis_rotation_matrix) actual_rotation_gates = Observable.Hermitian( matrix=matrix).basis_rotation_gates assert actual_rotation_gates == tuple([expected_unitary]) assert expected_unitary.matrix_equivalence(actual_rotation_gates[0])