def test_expectation_value_with_noisy_simulator(self, noisy_simulator): # Given # Initialize in |1> state circuit = Circuit([X(0)]) # Flip qubit an even number of times to remain in the |1> state, but allow # decoherence to take effect circuit += Circuit([X(0) for i in range(10)]) qubit_operator = QubitOperator("Z0") noisy_simulator.n_samples = 8192 # When estimation_tasks = [ EstimationTask(qubit_operator, circuit, noisy_simulator.n_samples) ] expectation_values_10_gates = estimate_expectation_values_by_averaging( noisy_simulator, estimation_tasks)[0] # Then assert isinstance(expectation_values_10_gates, ExpectationValues) assert len(expectation_values_10_gates.values) == 1 assert expectation_values_10_gates.values[0] > -1 assert expectation_values_10_gates.values[0] < 0.0 assert isinstance(noisy_simulator, QiskitSimulator) assert noisy_simulator.device_name == "qasm_simulator" assert noisy_simulator.n_samples == 8192 assert isinstance(noisy_simulator.noise_model, AerNoise.NoiseModel) assert noisy_simulator.device_connectivity is not None assert noisy_simulator.basis_gates is not None # Given # Initialize in |1> state circuit = Circuit([X(0)]) # Flip qubit an even number of times to remain in the |1> state, but allow # decoherence to take effect circuit += Circuit([X(0) for i in range(50)]) qubit_operator = QubitOperator("Z0") noisy_simulator.n_samples = 8192 # When estimation_tasks = [ EstimationTask(qubit_operator, circuit, noisy_simulator.n_samples) ] expectation_values_50_gates = estimate_expectation_values_by_averaging( noisy_simulator, estimation_tasks)[0] # Then assert isinstance(expectation_values_50_gates, ExpectationValues) assert len(expectation_values_50_gates.values) == 1 assert expectation_values_50_gates.values[0] > -1 assert expectation_values_50_gates.values[0] < 0.0 assert (expectation_values_50_gates.values[0] > expectation_values_10_gates.values[0]) assert isinstance(noisy_simulator, QiskitSimulator) assert noisy_simulator.device_name == "qasm_simulator" assert noisy_simulator.n_samples == 8192 assert isinstance(noisy_simulator.noise_model, AerNoise.NoiseModel) assert noisy_simulator.device_connectivity is not None assert noisy_simulator.basis_gates is not None
def estimation_tasks(self): task_1 = EstimationTask(IsingOperator("Z0"), circuit=Circuit(Program(X(0))), number_of_shots=10) task_2 = EstimationTask( IsingOperator("Z0"), circuit=Circuit(Program(RZ(np.pi / 2, 0))), number_of_shots=20, ) task_3 = EstimationTask( IsingOperator((), coefficient=2.0), circuit=Circuit(Program(RY(np.pi / 4, 0))), number_of_shots=30, ) return [task_1, task_2, task_3]
def test_optimization_level_of_transpiler(self): # Given noise_model, connectivity = get_qiskit_noise_model( "ibmqx2", api_token=os.getenv("ZAPATA_IBMQ_API_TOKEN")) simulator = QiskitSimulator( "qasm_simulator", n_samples=8192, noise_model=noise_model, device_connectivity=connectivity, optimization_level=0, ) qubit_operator = QubitOperator("Z0") # Initialize in |1> state circuit = Circuit([X(0)]) # Flip qubit an even number of times to remain in the |1> state, but allow # decoherence to take effect circuit += Circuit([X(0) for i in range(50)]) # When estimation_tasks = [ EstimationTask(qubit_operator, circuit, simulator.n_samples) ] expectation_values_no_compilation = estimate_expectation_values_by_averaging( simulator, estimation_tasks) simulator.optimization_level = 3 expectation_values_full_compilation = estimate_expectation_values_by_averaging( simulator, estimation_tasks) # Then assert (expectation_values_full_compilation[0].values[0] < expectation_values_no_compilation[0].values[0])
def _validate_expectation_value_includes_coefficients( estimator: EstimateExpectationValues, ): estimation_tasks = [ EstimationTask(IsingOperator("Z0"), Circuit([RX(np.pi / 3)(0)]), 10000), EstimationTask(IsingOperator("Z0", 19.971997), Circuit([RX(np.pi / 3)(0)]), 10000), ] expectation_values = estimator( backend=_backend, estimation_tasks=estimation_tasks, ) return not np.array_equal(expectation_values[0].values, expectation_values[1].values)
def test_two_qubit_parametric_gates_using_expectation_values( self, backend_for_gates_test, initial_gates, tested_gate, params, operators, target_values, ): n_samples = 1000 # Given gate_1 = builtin_gate_by_name(initial_gates[0])(0) gate_2 = builtin_gate_by_name(initial_gates[1])(1) gate_3 = builtin_gate_by_name(tested_gate)(*params)(0, 1) circuit = Circuit([gate_1, gate_2, gate_3]) sigma = 1 / np.sqrt(n_samples) for i, operator in enumerate(operators): # When operator = QubitOperator(operator) estimation_tasks = [EstimationTask(operator, circuit, n_samples)] expectation_values = estimate_expectation_values_by_averaging( backend_for_gates_test, estimation_tasks) calculated_value = expectation_values.values[0] # Then assert calculated_value == pytest.approx(target_values[i], abs=sigma * 5)
def test_group_greedily_all_different_groups(self): target_operator = 10.0 * QubitOperator("Z0") target_operator -= 3.0 * QubitOperator("Y0") target_operator += 1.0 * QubitOperator("X0") target_operator += 20.0 * QubitOperator("") expected_operators = [ 10.0 * QubitOperator("Z0"), -3.0 * QubitOperator("Y0"), 1.0 * QubitOperator("X0"), 20.0 * QubitOperator(""), ] circuit = Circuit(Program(X(0))) estimation_tasks = [EstimationTask(target_operator, circuit, None)] grouped_tasks = group_greedily(estimation_tasks) for task, operator in zip(grouped_tasks, expected_operators): assert task.operator == operator for initial_task, modified_task in zip(estimation_tasks, grouped_tasks): assert modified_task.circuit == initial_task.circuit assert modified_task.number_of_shots == initial_task.number_of_shots
def get_expectation_values_for_qubit_operator( backend_specs: Specs, circuit: Union[str, Circuit, Dict], qubit_operator: Union[str, SymbolicOperator, Dict], ): """Measure the expectation values of the terms in an input operator with respect to the state prepared by the input circuit on the backend described by the `backend_specs`. The results are serialized into a JSON under the file: "expectation-values.json" Args: backend_specs: The backend on which to run the quantum circuit circuit: The circuit that prepares the state to be measured qubit_operator: The operator to measure """ if isinstance(circuit, str): circuit = load_circuit(circuit) elif isinstance(circuit, dict): circuit = circuit_from_dict(circuit) if isinstance(qubit_operator, str): qubit_operator = load_qubit_operator(qubit_operator) elif isinstance(qubit_operator, dict): qubit_operator = convert_dict_to_qubitop(qubit_operator) if isinstance(backend_specs, str): backend_specs = json.loads(backend_specs) backend = cast(QuantumBackend, create_object(backend_specs)) estimation_tasks = [ EstimationTask(qubit_operator, circuit, backend.n_samples) ] expectation_values = estimate_expectation_values_by_averaging( backend, estimation_tasks) save_expectation_values(expectation_values[0], "expectation-values.json")
def test_group_individually(self): target_operator = 10.0 * QubitOperator("Z0") target_operator += 5.0 * QubitOperator("Z1") target_operator -= 3.0 * QubitOperator("Y0") target_operator += 1.0 * QubitOperator("X0") target_operator += 20.0 * QubitOperator("") expected_operator_terms_per_frame = [ (10.0 * QubitOperator("Z0")).terms, (5.0 * QubitOperator("Z1")).terms, (-3.0 * QubitOperator("Y0")).terms, (1.0 * QubitOperator("X0")).terms, (20.0 * QubitOperator("")).terms, ] circuit = Circuit(Program(X(0))) estimation_tasks = [EstimationTask(target_operator, circuit, None)] grouped_tasks = group_individually(estimation_tasks) assert len(grouped_tasks) == 5 for task in grouped_tasks: assert task.operator.terms in expected_operator_terms_per_frame
def test_one_qubit_non_parametric_gates_using_expectation_values( self, backend_for_gates_test, initial_gate, tested_gate, target_values): n_samples = 1000 # Given gate_1 = builtin_gate_by_name(initial_gate)(0) gate_2 = builtin_gate_by_name(tested_gate)(0) circuit = Circuit([gate_1, gate_2]) operators = [ QubitOperator("[]"), QubitOperator("[X0]"), QubitOperator("[Y0]"), QubitOperator("[Z0]"), ] sigma = 1 / np.sqrt(n_samples) for i, operator in enumerate(operators): # When estimation_tasks = [EstimationTask(operator, circuit, n_samples)] expectation_values = estimate_expectation_values_by_averaging( backend_for_gates_test, estimation_tasks) calculated_value = expectation_values.values[0] # Then assert calculated_value == pytest.approx(target_values[i], abs=sigma * 3)
def _validate_constant_terms_are_included_in_output( estimator: EstimateExpectationValues, ): estimation_tasks = [ EstimationTask(IsingOperator("Z0"), Circuit([H(0)]), 10000), EstimationTask( IsingOperator("Z0") + IsingOperator("[]", 19.971997), Circuit([H(0)]), 10000, ), ] expectation_values = estimator( backend=_backend, estimation_tasks=estimation_tasks, ) return not np.array_equal(expectation_values[0].values, expectation_values[1].values)
def test_raises_exception_if_operator_is_not_ising(self, estimator, backend, circuit): # Given estimation_tasks = [EstimationTask(QubitOperator("X0"), circuit, 10)] with pytest.raises(TypeError): estimator( backend=backend, estimation_tasks=estimation_tasks, )
def test_evaluate_estimation_circuits_no_symbols( self, circuits, ): evaluate_circuits = partial(evaluate_estimation_circuits, symbols_maps=[[] for _ in circuits]) operator = QubitOperator() estimation_tasks = [ EstimationTask(operator, circuit, 1) for circuit in circuits ] new_estimation_tasks = evaluate_circuits(estimation_tasks) for old_task, new_task in zip(estimation_tasks, new_estimation_tasks): assert old_task.circuit == new_task.circuit
def test_allocate_shots_uniformly( self, frame_operators, n_samples, target_n_samples_list, ): allocate_shots = partial(allocate_shots_uniformly, number_of_shots=n_samples) circuit = Circuit() estimation_tasks = [ EstimationTask(operator, circuit, 1) for operator in frame_operators ] new_estimation_tasks = allocate_shots(estimation_tasks) for task, target_n_samples in zip(new_estimation_tasks, target_n_samples_list): assert task.number_of_shots == target_n_samples
def test_cvar_estimator_returns_correct_values(self, estimator, backend, operator): # Given estimation_tasks = [EstimationTask(operator, Circuit([H(0)]), 10000)] if estimator.alpha <= 0.5: target_value = -1 else: target_value = (-1 * 0.5 + 1 * (estimator.alpha - 0.5)) / estimator.alpha # When expectation_values = estimator( backend=backend, estimation_tasks=estimation_tasks, ) # Then assert expectation_values[0].values == pytest.approx(target_value, abs=2e-1)
def test_group_greedily_all_comeasureable(self): target_operator = 10.0 * QubitOperator("Y0") target_operator -= 3.0 * QubitOperator("Y0 Y1") target_operator += 1.0 * QubitOperator("Y1") target_operator += 20.0 * QubitOperator("Y0 Y1 Y2") circuit = Circuit(Program([X(0), X(1), X(2)])) estimation_tasks = [EstimationTask(target_operator, circuit, None)] grouped_tasks = group_greedily(estimation_tasks) assert len(grouped_tasks) == 1 assert grouped_tasks[0].operator == target_operator for initial_task, modified_task in zip(estimation_tasks, grouped_tasks): assert modified_task.circuit == initial_task.circuit assert modified_task.number_of_shots == initial_task.number_of_shots
def test_two_qubit_parametric_gates_using_expectation_values( self, backend_for_gates_test, initial_gates, tested_gate, params, operators, target_values, ): if backend_for_gates_test.n_samples is None: pytest.xfail( "This test won't work for simulators without sampling, it's covered by " "a test in QuantumSimulatorTests.") # Given qubit_list = [Qubit(0), Qubit(1)] gate_1 = Gate(initial_gates[0], qubits=[qubit_list[0]]) gate_2 = Gate(initial_gates[1], qubits=[qubit_list[1]]) gate_3 = Gate(tested_gate, params=params, qubits=qubit_list) circuit = Circuit() circuit.qubits = qubit_list circuit.gates = [gate_1, gate_2, gate_3] sigma = 1 / np.sqrt(backend_for_gates_test.n_samples) for i, operator in enumerate(operators): # When operator = QubitOperator(operator) estimation_tasks = [ EstimationTask(operator, circuit, backend_for_gates_test.n_samples) ] expectation_values = estimate_expectation_values_by_averaging( backend_for_gates_test, estimation_tasks) calculated_value = expectation_values.values[0] # Then assert calculated_value == pytest.approx(target_values[i], abs=sigma * 5)
def test_gibbs_estimator_returns_correct_values(self, estimator, backend, operator): # Given estimation_tasks = [EstimationTask(operator, Circuit([H(0)]), 10000)] expval_0 = np.exp(1 * -estimator.alpha) # Expectation value of bitstring 0 expval_1 = np.exp(-1 * -estimator.alpha) # Expectation value of bitstring 1 # Target value is the -log of the mean of the expectation values of the 2 bitstrings target_value = -np.log((expval_1 + expval_0) / 2) # When expectation_values = estimator( backend=backend, estimation_tasks=estimation_tasks, ) # Then assert expectation_values[0].values == pytest.approx(target_value, abs=2e-2)
def test_one_qubit_non_parametric_gates_using_expectation_values( self, backend_for_gates_test, initial_gate, tested_gate, target_values): if backend_for_gates_test.n_samples is None: pytest.xfail( "This test won't work for simulators without sampling, it should be " "covered by a test in QuantumSimulatorTests.") # Given qubit_list = [Qubit(0)] gate_1 = Gate(initial_gate, qubits=qubit_list) gate_2 = Gate(tested_gate, qubits=qubit_list) circuit = Circuit() circuit.qubits = qubit_list circuit.gates = [gate_1, gate_2] operators = [ QubitOperator("[]"), QubitOperator("[X0]"), QubitOperator("[Y0]"), QubitOperator("[Z0]"), ] sigma = 1 / np.sqrt(backend_for_gates_test.n_samples) for i, operator in enumerate(operators): # When estimation_tasks = [ EstimationTask(operator, circuit, backend_for_gates_test.n_samples) ] expectation_values = estimate_expectation_values_by_averaging( backend_for_gates_test, estimation_tasks) calculated_value = expectation_values.values[0] # Then assert calculated_value == pytest.approx(target_values[i], abs=sigma * 3)
def test_evaluate_estimation_circuits_all_symbols( self, circuits, ): symbols_maps = [[ (sympy.Symbol("theta_0"), 0), (sympy.Symbol("theta_1"), 0), (sympy.Symbol("theta_2"), 0), (sympy.Symbol("theta_3"), 0), ] for _ in circuits] evaluate_circuits = partial( evaluate_estimation_circuits, symbols_maps=symbols_maps, ) operator = QubitOperator() estimation_tasks = [ EstimationTask(operator, circuit, 1) for circuit in circuits ] new_estimation_tasks = evaluate_circuits(estimation_tasks) for new_task in new_estimation_tasks: assert new_task.circuit.symbolic_params == []
def test_allocate_shots_proportionally( self, frame_operators, total_n_shots, prior_expectation_values, target_n_samples_list, ): allocate_shots = partial( allocate_shots_proportionally, total_n_shots=total_n_shots, prior_expectation_values=prior_expectation_values, ) circuit = Circuit() estimation_tasks = [ EstimationTask(operator, circuit, 1) for operator in frame_operators ] new_estimation_tasks = allocate_shots(estimation_tasks) for task, target_n_samples in zip(new_estimation_tasks, target_n_samples_list): assert task.number_of_shots == target_n_samples
def test_perform_context_selection(self): target_operators = [] target_operators.append(10.0 * QubitOperator("Z0")) target_operators.append(-3 * QubitOperator("Y0")) target_operators.append(1 * QubitOperator("X0")) target_operators.append(20 * QubitOperator("")) expected_operators = [] expected_operators.append(10.0 * QubitOperator("Z0")) expected_operators.append(-3 * QubitOperator("Z0")) expected_operators.append(1 * QubitOperator("Z0")) expected_operators.append(20 * QubitOperator("")) base_circuit = Circuit(Program(X(0))) x_term_circuit = Circuit(Program(RX(np.pi / 2, 0))) y_term_circuit = Circuit(Program(RY(-np.pi / 2, 0))) expected_circuits = [ base_circuit, base_circuit + x_term_circuit, base_circuit + y_term_circuit, base_circuit, ] estimation_tasks = [ EstimationTask(operator, base_circuit, None) for operator in target_operators ] tasks_with_context_selection = perform_context_selection( estimation_tasks) for task, expected_circuit, expected_operator in zip( tasks_with_context_selection, expected_circuits, expected_operators): assert task.operator.terms == expected_operator.terms assert task.circuit == expected_circuit
class TestEstimatorUtils: def test_get_context_selection_circuit_for_group(self): group = QubitOperator("X0 Y1") - 0.5 * QubitOperator((1, "Y")) circuit, ising_operator = get_context_selection_circuit_for_group( group) # Need to convert to QubitOperator in order to get matrix representation qubit_operator = change_operator_type(ising_operator, QubitOperator) target_unitary = qubit_operator_sparse(group) transformed_unitary = ( circuit.to_unitary().conj().T @ qubit_operator_sparse(qubit_operator) @ circuit.to_unitary()) assert np.allclose(target_unitary.todense(), transformed_unitary) def test_perform_context_selection(self): target_operators = [] target_operators.append(10.0 * QubitOperator("Z0")) target_operators.append(-3 * QubitOperator("Y0")) target_operators.append(1 * QubitOperator("X0")) target_operators.append(20 * QubitOperator("")) expected_operators = [] expected_operators.append(10.0 * QubitOperator("Z0")) expected_operators.append(-3 * QubitOperator("Z0")) expected_operators.append(1 * QubitOperator("Z0")) expected_operators.append(20 * QubitOperator("")) base_circuit = Circuit([X(0)]) x_term_circuit = Circuit([RY(-np.pi / 2)(0)]) y_term_circuit = Circuit([RX(np.pi / 2)(0)]) expected_circuits = [ base_circuit, base_circuit + y_term_circuit, base_circuit + x_term_circuit, base_circuit, ] estimation_tasks = [ EstimationTask(operator, base_circuit, None) for operator in target_operators ] tasks_with_context_selection = perform_context_selection( estimation_tasks) for task, expected_circuit, expected_operator in zip( tasks_with_context_selection, expected_circuits, expected_operators): assert task.operator.terms == expected_operator.terms assert task.circuit == expected_circuit @pytest.fixture() def frame_operators(self): operators = [ 2.0 * IsingOperator((1, "Z")) * IsingOperator((2, "Z")), 1.0 * IsingOperator((3, "Z")) * IsingOperator((0, "Z")), -1.0 * IsingOperator((2, "Z")), ] return operators @pytest.fixture() def circuits(self): circuits = [Circuit() for _ in range(5)] circuits[1] += RX(1.2)(0) circuits[1] += RY(1.5)(1) circuits[1] += RX(-0.0002)(0) circuits[1] += RY(0)(1) for circuit in circuits[2:]: circuit += RX(sympy.Symbol("theta_0"))(0) circuit += RY(sympy.Symbol("theta_1"))(1) circuit += RX(sympy.Symbol("theta_2"))(0) circuit += RY(sympy.Symbol("theta_3"))(1) return circuits @pytest.mark.parametrize( "n_samples, target_n_samples_list", [ (100, [100, 100, 100]), (17, [17, 17, 17]), ], ) def test_allocate_shots_uniformly( self, frame_operators, n_samples, target_n_samples_list, ): allocate_shots = partial(allocate_shots_uniformly, number_of_shots=n_samples) circuit = Circuit() estimation_tasks = [ EstimationTask(operator, circuit, 1) for operator in frame_operators ] new_estimation_tasks = allocate_shots(estimation_tasks) for task, target_n_samples in zip(new_estimation_tasks, target_n_samples_list): assert task.number_of_shots == target_n_samples @pytest.mark.parametrize( "total_n_shots, prior_expectation_values, target_n_samples_list", [ (400, None, [200, 100, 100]), (400, ExpectationValues(np.array([0, 0, 0])), [200, 100, 100]), (400, ExpectationValues(np.array([1, 0.3, 0.3])), [0, 200, 200]), ], ) def test_allocate_shots_proportionally( self, frame_operators, total_n_shots, prior_expectation_values, target_n_samples_list, ): allocate_shots = partial( allocate_shots_proportionally, total_n_shots=total_n_shots, prior_expectation_values=prior_expectation_values, ) circuit = Circuit() estimation_tasks = [ EstimationTask(operator, circuit, 1) for operator in frame_operators ] new_estimation_tasks = allocate_shots(estimation_tasks) for task, target_n_samples in zip(new_estimation_tasks, target_n_samples_list): assert task.number_of_shots == target_n_samples @pytest.mark.parametrize( "n_samples", [-1], ) def test_allocate_shots_uniformly_invalid_inputs( self, n_samples, ): estimation_tasks = [] with pytest.raises(ValueError): allocate_shots_uniformly(estimation_tasks, number_of_shots=n_samples) @pytest.mark.parametrize( "total_n_shots, prior_expectation_values", [ (-1, ExpectationValues(np.array([0, 0, 0]))), ], ) def test_allocate_shots_proportionally_invalid_inputs( self, total_n_shots, prior_expectation_values, ): estimation_tasks = [] with pytest.raises(ValueError): _ = allocate_shots_proportionally(estimation_tasks, total_n_shots, prior_expectation_values) def test_evaluate_estimation_circuits_no_symbols( self, circuits, ): evaluate_circuits = partial(evaluate_estimation_circuits, symbols_maps=[[] for _ in circuits]) operator = QubitOperator() estimation_tasks = [ EstimationTask(operator, circuit, 1) for circuit in circuits ] new_estimation_tasks = evaluate_circuits(estimation_tasks) for old_task, new_task in zip(estimation_tasks, new_estimation_tasks): assert old_task.circuit == new_task.circuit def test_evaluate_estimation_circuits_all_symbols( self, circuits, ): symbols_maps = [[ (sympy.Symbol("theta_0"), 0), (sympy.Symbol("theta_1"), 0), (sympy.Symbol("theta_2"), 0), (sympy.Symbol("theta_3"), 0), ] for _ in circuits] evaluate_circuits = partial( evaluate_estimation_circuits, symbols_maps=symbols_maps, ) operator = QubitOperator() estimation_tasks = [ EstimationTask(operator, circuit, 1) for circuit in circuits ] new_estimation_tasks = evaluate_circuits(estimation_tasks) for new_task in new_estimation_tasks: assert len(new_task.circuit.free_symbols) == 0 def test_group_greedily_all_different_groups(self): target_operator = 10.0 * QubitOperator("Z0") target_operator -= 3.0 * QubitOperator("Y0") target_operator += 1.0 * QubitOperator("X0") target_operator += 20.0 * QubitOperator("") expected_operators = [ 10.0 * QubitOperator("Z0"), -3.0 * QubitOperator("Y0"), 1.0 * QubitOperator("X0"), 20.0 * QubitOperator(""), ] circuit = Circuit([X(0)]) estimation_tasks = [EstimationTask(target_operator, circuit, None)] grouped_tasks = group_greedily(estimation_tasks) for task, operator in zip(grouped_tasks, expected_operators): assert task.operator == operator for initial_task, modified_task in zip(estimation_tasks, grouped_tasks): assert modified_task.circuit == initial_task.circuit assert modified_task.number_of_shots == initial_task.number_of_shots def test_group_greedily_all_comeasureable(self): target_operator = 10.0 * QubitOperator("Y0") target_operator -= 3.0 * QubitOperator("Y0 Y1") target_operator += 1.0 * QubitOperator("Y1") target_operator += 20.0 * QubitOperator("Y0 Y1 Y2") circuit = Circuit([X(0), X(1), X(2)]) estimation_tasks = [EstimationTask(target_operator, circuit, None)] grouped_tasks = group_greedily(estimation_tasks) assert len(grouped_tasks) == 1 assert grouped_tasks[0].operator == target_operator for initial_task, modified_task in zip(estimation_tasks, grouped_tasks): assert modified_task.circuit == initial_task.circuit assert modified_task.number_of_shots == initial_task.number_of_shots def test_group_individually(self): target_operator = 10.0 * QubitOperator("Z0") target_operator += 5.0 * QubitOperator("Z1") target_operator -= 3.0 * QubitOperator("Y0") target_operator += 1.0 * QubitOperator("X0") target_operator += 20.0 * QubitOperator("") expected_operator_terms_per_frame = [ (10.0 * QubitOperator("Z0")).terms, (5.0 * QubitOperator("Z1")).terms, (-3.0 * QubitOperator("Y0")).terms, (1.0 * QubitOperator("X0")).terms, (20.0 * QubitOperator("")).terms, ] circuit = Circuit([X(0)]) estimation_tasks = [EstimationTask(target_operator, circuit, None)] grouped_tasks = group_individually(estimation_tasks) assert len(grouped_tasks) == 5 for task in grouped_tasks: assert task.operator.terms in expected_operator_terms_per_frame @pytest.mark.parametrize( ",".join([ "estimation_tasks", "ref_estimation_tasks_to_measure", "ref_non_measured_estimation_tasks", "ref_indices_to_measure", "ref_non_measured_indices", ]), [ ( [ EstimationTask(IsingOperator("2[Z0] + 3 [Z1 Z2]"), Circuit([X(0)]), 10), EstimationTask( IsingOperator("2[Z0] + 3 [Z1 Z2] + 4[]"), Circuit([RZ(np.pi / 2)(0)]), 1000, ), EstimationTask( IsingOperator("4[Z3]"), Circuit([RY(np.pi / 2)(0)]), 17, ), ], [ EstimationTask(IsingOperator("2[Z0] + 3 [Z1 Z2]"), Circuit([X(0)]), 10), EstimationTask( IsingOperator("2[Z0] + 3 [Z1 Z2] + 4 []"), Circuit([RZ(np.pi / 2)(0)]), 1000, ), EstimationTask( IsingOperator("4[Z3]"), Circuit([RY(np.pi / 2)(0)]), 17, ), ], [], [0, 1, 2], [], ), ( [ EstimationTask(IsingOperator("2[Z0] + 3 [Z1 Z2]"), Circuit([X(0)]), 10), EstimationTask( IsingOperator("4[] "), Circuit([RZ(np.pi / 2)(0)]), 1000, ), EstimationTask( IsingOperator("4[Z3]"), Circuit([RY(np.pi / 2)(0)]), 17, ), ], [ EstimationTask(IsingOperator("2[Z0] + 3 [Z1 Z2]"), Circuit([X(0)]), 10), EstimationTask( IsingOperator("4[Z3]"), Circuit([RY(np.pi / 2)(0)]), 17, ), ], [ EstimationTask(IsingOperator("4[]"), Circuit([RZ(np.pi / 2)(0)]), 1000) ], [0, 2], [1], ), ( [ EstimationTask(IsingOperator("- 3 []"), Circuit([X(0)]), 0), EstimationTask( IsingOperator("2[Z0] + 3 [Z1 Z2] + 4[]"), Circuit([RZ(np.pi / 2)(0)]), 1000, ), EstimationTask( IsingOperator("4[Z3]"), Circuit([RY(np.pi / 2)(0)]), 17, ), ], [ EstimationTask( IsingOperator("2[Z0] + 3 [Z1 Z2] + 4 []"), Circuit([RZ(np.pi / 2)(0)]), 1000, ), EstimationTask( IsingOperator("4[Z3]"), Circuit([RY(np.pi / 2)(0)]), 17, ), ], [ EstimationTask(IsingOperator("- 3 []"), Circuit([X(0)]), 0), ], [1, 2], [0], ), ( [ EstimationTask(IsingOperator("- 3 []"), Circuit([X(0)]), 0), EstimationTask( IsingOperator("2[Z0] + 3 [Z1 Z2] + 4[]"), Circuit([RZ(np.pi / 2)(0)]), 1000, ), EstimationTask( IsingOperator("4[Z3]"), Circuit([RY(np.pi / 2)(0)]), 0, ), ], [ EstimationTask( IsingOperator("2[Z0] + 3 [Z1 Z2] + 4 []"), Circuit([RZ(np.pi / 2)(0)]), 1000, ), ], [ EstimationTask(IsingOperator("- 3 []"), Circuit([X(0)]), 0), EstimationTask( IsingOperator("4[Z3]"), Circuit([RY(np.pi / 2)(0)]), 0, ), ], [1], [0, 2], ), ], ) def test_split_estimation_tasks_to_measure( self, estimation_tasks, ref_estimation_tasks_to_measure, ref_non_measured_estimation_tasks, ref_indices_to_measure, ref_non_measured_indices, ): ( estimation_task_to_measure, non_measured_estimation_tasks, indices_to_measure, indices_for_non_measureds, ) = split_estimation_tasks_to_measure(estimation_tasks) assert estimation_task_to_measure == ref_estimation_tasks_to_measure assert non_measured_estimation_tasks == ref_non_measured_estimation_tasks assert indices_to_measure == ref_indices_to_measure assert ref_non_measured_indices == indices_for_non_measureds @pytest.mark.parametrize( "estimation_tasks,ref_expectation_values", [ ( [ EstimationTask( IsingOperator("4[] "), Circuit([RZ(np.pi / 2)(0)]), 1000, ), ], [ ExpectationValues( np.asarray([4.0]), correlations=[np.asarray([[0.0]])], estimator_covariances=[np.asarray([[0.0]])], ), ], ), ( [ EstimationTask(IsingOperator("- 2.5 [] - 0.5 []"), Circuit([X(0)]), 0), EstimationTask(IsingOperator("0.001[] "), Circuit([RZ(np.pi / 2)(0)]), 2), EstimationTask( IsingOperator("2.5 [Z1] + 1.0 [Z2 Z3]"), Circuit([RY(np.pi / 2)(0)]), 0, ), ], [ ExpectationValues( np.asarray([-3.0]), correlations=[np.asarray([[0.0]])], estimator_covariances=[np.asarray([[0.0]])], ), ExpectationValues( np.asarray([0.001]), correlations=[np.asarray([[0.0]])], estimator_covariances=[np.asarray([[0.0]])], ), ExpectationValues( np.asarray([0.0]), correlations=[np.asarray([[0.0]])], estimator_covariances=[np.asarray([[0.0]])], ), ], ), ], ) def test_evaluate_non_measured_estimation_tasks(self, estimation_tasks, ref_expectation_values): expectation_values = evaluate_non_measured_estimation_tasks( estimation_tasks) for ex_val, ref_ex_val in zip(expectation_values, ref_expectation_values): assert np.allclose(ex_val.values, ref_ex_val.values) assert np.allclose(ex_val.correlations, ref_ex_val.correlations) assert np.allclose(ex_val.estimator_covariances, ref_ex_val.estimator_covariances) @pytest.mark.parametrize( "estimation_tasks", [ ([ EstimationTask(IsingOperator("- 2.5 [] - 0.5 [Z1]"), Circuit([X(0)]), 1), ]), ([ EstimationTask( IsingOperator("0.001 [Z0]"), Circuit([RZ(np.pi / 2)(0)]), 0, ), EstimationTask(IsingOperator("2.0[] "), Circuit([RZ(np.pi / 2)(0)]), 2), EstimationTask( IsingOperator("1.5 [Z0 Z1]"), Circuit([RY(np.pi / 2)(0)]), 10, ), ]), ], ) def test_evaluate_non_measured_estimation_tasks_fails_with_non_zero_shots( self, estimation_tasks): with pytest.raises(RuntimeError): _ = evaluate_non_measured_estimation_tasks(estimation_tasks)
def estimation_tasks(self, operator, circuit): return [EstimationTask(operator, circuit, 10)]
10, ), ]), ], ) def test_evaluate_non_measured_estimation_tasks_fails_with_non_zero_shots( self, estimation_tasks): with pytest.raises(RuntimeError): _ = evaluate_non_measured_estimation_tasks(estimation_tasks) TEST_CASES_EIGENSTATES = [ ( [ EstimationTask(IsingOperator("Z0"), circuit=Circuit([X(0)]), number_of_shots=10), EstimationTask( IsingOperator((), coefficient=2.0), circuit=Circuit([RY(np.pi / 4)(0)]), number_of_shots=30, ), ], [ExpectationValues(np.array([-1])), ExpectationValues(np.array([2]))], ), ] TEST_CASES_NONEIGENSTATES = [ ( [ EstimationTask(
assert contract(estimator) """ import numpy as np from openfermion import IsingOperator from zquantum.core.circuits import RX, RY, RZ, Circuit, H from zquantum.core.interfaces.estimation import ( EstimateExpectationValues, EstimationTask, ) from zquantum.core.symbolic_simulator import SymbolicSimulator _backend = SymbolicSimulator(seed=1997) _estimation_tasks = [ EstimationTask(IsingOperator("Z0"), Circuit([H(0)]), 10000), EstimationTask( IsingOperator("Z0") + IsingOperator("Z1") + IsingOperator("Z2"), Circuit([H(0), RX(np.pi / 3)(0), H(2)]), 10000, ), EstimationTask( IsingOperator("Z0") + IsingOperator("Z1", 4), Circuit([ RX(np.pi)(0), RY(0.12)(1), RZ(np.pi / 3)(1), RY(1.9213)(0), ]), 10000, ),