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
Exemple #16
0
    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)
Exemple #17
0
    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)
Exemple #18
0
    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
Exemple #22
0
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)]
Exemple #24
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)


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,
    ),