def test_register_observable(): class _FooObservable(Observable): def __init__(self): super().__init__(qubit_count=1, ascii_symbols=["foo"]) Observable.register_observable(_FooObservable) assert Observable._FooObservable().name == _FooObservable().name
def test_add_result_type_observable_no_conflict_all(): expected = [ ResultType.Variance(observable=Observable.Y()), ResultType.Expectation(observable=Observable.Y()), ] circ = Circuit(expected) assert circ.result_types == expected
def test_multiple_result_types(): circ = ( Circuit() .cnot(0, 2) .cnot(1, 3) .h(0) .variance(observable=Observable.Y(), target=0) .expectation(observable=Observable.Y(), target=2) .sample(observable=Observable.Y()) ) expected = ( "T : | 0 |1| Result Types |", " ", "q0 : -C---H-Variance(Y)----Sample(Y)-", " | | ", "q1 : -|-C------------------Sample(Y)-", " | | | ", "q2 : -X-|---Expectation(Y)-Sample(Y)-", " | | ", "q3 : ---X------------------Sample(Y)-", "", "T : | 0 |1| Result Types |", ) expected = "\n".join(expected) assert AsciiCircuitDiagram.build_diagram(circ) == expected
def test_add_result_type_observable_conflict_different_selected_targets_then_all_target( ): circ = Circuit().add_result_type( ResultType.Expectation(observable=Observable.Z(), target=[0])) circ.add_result_type( ResultType.Expectation(observable=Observable.Y(), target=[1])) circ.add_result_type(ResultType.Expectation(observable=Observable.Y()))
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 result_types_zero_shots_bell_pair_testing(device: Device, include_state_vector: bool, run_kwargs: Dict[str, Any]): circuit = (Circuit().h(0).cnot( 0, 1).expectation(observable=Observable.H() @ Observable.X(), target=[0, 1]).amplitude(["01", "10", "00", "11"])) if include_state_vector: circuit.state_vector() result = device.run(circuit, **run_kwargs).result() assert len(result.result_types) == 3 if include_state_vector else 2 assert np.allclose( result.get_value_by_result_type( ResultType.Expectation(observable=Observable.H() @ Observable.X(), target=[0, 1])), 1 / np.sqrt(2), ) if include_state_vector: assert np.allclose( result.get_value_by_result_type(ResultType.StateVector()), np.array([1, 0, 0, 1]) / np.sqrt(2), ) assert result.get_value_by_result_type( ResultType.Amplitude(["01", "10", "00", "11"])) == { "01": 0j, "10": 0j, "00": (1 / np.sqrt(2)), "11": (1 / np.sqrt(2)), }
def test_tensor_product_rmatmul_observable(): t1 = Observable.TensorProduct([Observable.Z(), Observable.I(), Observable.X()]) o1 = Observable.I() t = o1 @ t1 assert t.to_ir() == ["i", "z", "i", "x"] assert t.qubit_count == 4 assert t.ascii_symbols == tuple(["I@Z@I@X"] * 4)
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_apply(): noise_model = (NoiseModel().add_noise(PauliChannel( 0.01, 0.02, 0.03), GateCriteria(Gate.I, [0, 1])).add_noise( Depolarizing(0.04), GateCriteria(Gate.H)).add_noise( TwoQubitDepolarizing(0.05), GateCriteria(Gate.CNot, [0, 1])).add_noise( PauliChannel(0.06, 0.07, 0.08), GateCriteria(Gate.H, [0, 1])).add_noise( Depolarizing(0.10), UnitaryGateCriteria(h_unitary(), 0)).add_noise( Depolarizing(0.06), ObservableCriteria(Observable.Z, 0)).add_noise( Depolarizing(0.09), QubitInitializationCriteria(0))) layer1 = Circuit().h(0).cnot(0, 1).sample(Observable.Z(), 0) layer2 = Circuit().unitary([0], h_unitary().to_matrix()) circuit = layer1 + layer2 noisy_circuit_from_circuit = noise_model.apply(circuit) expected_circuit = (Circuit().depolarizing(0, 0.09).h(0).depolarizing( 0, 0.04).pauli_channel(0, 0.06, 0.07, 0.08).cnot( 0, 1).two_qubit_depolarizing(0, 1, 0.05).unitary( [0], h_unitary().to_matrix()).depolarizing( 0, 0.10).apply_readout_noise(Depolarizing(0.06), 0).sample(Observable.Z(), 0)) assert noisy_circuit_from_circuit == expected_circuit
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 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_add_result_type_same_observable_wrong_target_order_tensor_product(): Circuit().add_result_type( ResultType.Expectation( observable=Observable.Y() @ Observable.X(), target=[0, 1])).add_result_type( ResultType.Variance(observable=Observable.Y() @ Observable.X(), target=[1, 0]))
def test_matmul_observable(): o1 = Observable.I() o2 = Observable.Z() o3 = o1 @ o2 assert isinstance(o3, Observable.TensorProduct) assert o3.qubit_count == 2 assert o3.to_ir() == ["i", "z"] assert o3.ascii_symbols == ("I@Z", "I@Z")
def test_flattened_tensor_product(): observable_one = Observable.Z() @ Observable.Y() observable_two = Observable.X() @ Observable.H() actual = Observable.TensorProduct([observable_one, observable_two]) expected = Observable.TensorProduct( [Observable.Z(), Observable.Y(), Observable.X(), Observable.H()] ) assert expected == actual
def test_observable_equality(): o1 = Observable.I() o2 = Observable.I() o3 = Observable.Z() o4 = "a" assert o1 == o2 assert o1 != o3 assert o1 != o4
def test_add_result_type_same_observable_wrong_target_order_tensor_product(): circ = (Circuit().add_result_type( ResultType.Expectation( observable=Observable.Y() @ Observable.X(), target=[0, 1])).add_result_type( ResultType.Variance(observable=Observable.Y() @ Observable.X(), target=[1, 0]))) assert not circ.observables_simultaneously_measurable assert not circ.basis_rotation_instructions
def test_basis_rotation_instructions_multiple_result_types_tensor_product_probability( ): circ = (Circuit().h(0).cnot(0, 1).cnot(1, 2).probability([0, 1]).sample( observable=Observable.Z() @ Observable.Z() @ Observable.H(), target=[0, 1, 2]).variance(observable=Observable.H(), target=[2])) expected = [ Instruction(Gate.Ry(-np.pi / 4), 2), ] assert circ.basis_rotation_instructions == expected
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_observable_conflict_different_selected_targets_then_all_target( ): circ = Circuit().add_result_type( ResultType.Expectation(observable=Observable.Z(), target=[0])) circ.add_result_type( ResultType.Expectation(observable=Observable.Y(), target=[1])) circ.add_result_type(ResultType.Expectation(observable=Observable.Y())) assert not circ.observables_simultaneously_measurable assert not circ.basis_rotation_instructions
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_basis_rotation_instructions_multiple_result_types_specified_all_same_targets( ): circ = (Circuit().h(0).cnot( 0, 1).sample(observable=Observable.H(), target=[0]).expectation(observable=Observable.H())) expected = [ Instruction(Gate.Ry(-np.pi / 4), 0), Instruction(Gate.Ry(-np.pi / 4), 1) ] assert circ.basis_rotation_instructions == expected
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 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 result_types_noncommuting_flipped_targets_testing(device: Device, run_kwargs: Dict[str, Any]): circuit = ( Circuit() .h(0) .cnot(0, 1) .expectation(observable=Observable.H() @ Observable.X(), target=[0, 1]) .expectation(observable=Observable.H() @ Observable.X(), target=[1, 0]) ) result = device.run(circuit, shots=0, **run_kwargs).result() assert np.allclose(result.values[0], np.sqrt(2) / 2) assert np.allclose(result.values[1], np.sqrt(2) / 2)
def test_obs_rt_equality(): a1 = ObservableResultType(ascii_symbols=["Obs"], observable=Observable.X(), target=0) a2 = ObservableResultType(ascii_symbols=["Obs"], observable=Observable.X(), target=0) a3 = ObservableResultType(ascii_symbols=["Obs"], observable=Observable.X(), target=1) a4 = "hi" assert a1 == a2 assert a1 != a3 assert a1 != a4 assert ResultType.Variance(observable=Observable.Y(), target=0) != ResultType.Expectation( observable=Observable.Y(), target=0 )
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 result_types_observable_not_in_instructions(device: Device, run_kwargs: Dict[str, Any]): shots = run_kwargs["shots"] tol = get_tol(shots) bell = (Circuit().h(0).cnot(0, 1).expectation(observable=Observable.X(), target=[2]).variance( observable=Observable.Y(), target=[3])) result = device.run(bell, **run_kwargs).result() assert np.allclose(result.values[0], 0, **tol) assert np.allclose(result.values[1], 1, **tol)
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]).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 test_basis_rotation_instructions_tensor_product(): circ = (Circuit().h(0).cnot(0, 1).expectation( observable=Observable.X() @ Observable.Y() @ Observable.Y(), target=[0, 1, 2])) expected = [ Instruction(Gate.H(), 0), Instruction(Gate.Z(), 1), Instruction(Gate.S(), 1), Instruction(Gate.H(), 1), Instruction(Gate.Z(), 2), Instruction(Gate.S(), 2), Instruction(Gate.H(), 2), ] assert circ.basis_rotation_instructions == expected
def result_types_nonzero_shots_bell_pair_testing(device: Device, run_kwargs: Dict[str, Any]): circuit = ( Circuit() .h(0) .cnot(0, 1) .expectation(observable=Observable.H() @ Observable.X(), target=[0, 1]) .sample(observable=Observable.H() @ Observable.X(), target=[0, 1]) ) result = device.run(circuit, **run_kwargs).result() assert len(result.result_types) == 2 assert ( 0.6 < result.get_value_by_result_type( ResultType.Expectation(observable=Observable.H() @ Observable.X(), target=[0, 1]) ) < 0.8 ) assert ( len( result.get_value_by_result_type( ResultType.Sample(observable=Observable.H() @ Observable.X(), target=[0, 1]) ) ) == run_kwargs["shots"] )