Source code for mitiq.qse.qse

# Copyright (C) Unitary Fund
#
# This source code is licensed under the GPL license (v3) found in the
# LICENSE file in the root directory of this source tree.


"""High-level Quantum Susbapce Expansion tools."""

from functools import wraps
from typing import Callable, Dict, List, Sequence, Union

from mitiq import QPROGRAM, Executor, Observable, PauliString, QuantumResult
from mitiq.qse.qse_utils import (
    get_expectation_value_for_observable,
    get_projector,
)


[docs] def execute_with_qse( circuit: QPROGRAM, executor: Union[Executor, Callable[[QPROGRAM], QuantumResult]], check_operators: Sequence[PauliString], code_hamiltonian: Observable, observable: Observable, pauli_string_to_expectation_cache: Dict[PauliString, complex] = {}, ) -> float: """Function for the calculation of an observable from some circuit of interest to be mitigated with quantum subspace expansion (QSE). Args: circuit: Quantum program to execute with error mitigation. executor: Executes a circuit and returns a `QuantumResult`. check_operators: List of check operators that define the stabilizer code space. code_hamiltonian: Hamiltonian of the code space. observable: Observable to compute the mitigated expectation value of. pauli_string_to_expectation_cache: Cache for expectation values of Pauli strings used to compute the projector and the observable. Returns: The expectation value estimated with QSE. """ projector = get_projector( circuit, executor, check_operators, code_hamiltonian, pauli_string_to_expectation_cache, ) # Compute the expectation value of the observable: <P O P> pop = get_expectation_value_for_observable( circuit, executor, projector * observable * projector, pauli_string_to_expectation_cache, ) # Compute the normalization factor: <P P> pp = get_expectation_value_for_observable( circuit, executor, projector * projector, pauli_string_to_expectation_cache, ) return pop / pp
[docs] def mitigate_executor( executor: Callable[[QPROGRAM], QuantumResult], check_operators: Sequence[PauliString], code_hamiltonian: Observable, observable: Observable, pauli_string_to_expectation_cache: Dict[PauliString, complex] = {}, ) -> Callable[[QPROGRAM], float]: """Returns a modified version of the input 'executor' which is error-mitigated with quantum subspace expansion (QSE). Args: executor: Executes a circuit and returns a `QuantumResult`. check_operators: List of check operators that define the stabilizer code space. code_hamiltonian: Hamiltonian of the code space. observable: Observable to compute the mitigated expectation value for. pauli_string_to_expectation_cache: Cache for expectation values of Pauli strings used to compute the projector and the observable. Returns: The error-mitigated version of the input executor. """ executor_obj = Executor(executor) if not executor_obj.can_batch: @wraps(executor) def new_executor(circuit: QPROGRAM) -> float: return execute_with_qse( circuit, executor, check_operators, code_hamiltonian, observable, pauli_string_to_expectation_cache, ) else: @wraps(executor) def new_executor(circuits: List[QPROGRAM]) -> List[float]: return [ execute_with_qse( circuit, executor, check_operators, code_hamiltonian, observable, pauli_string_to_expectation_cache, ) for circuit in circuits ] return new_executor
[docs] def qse_decorator( check_operators: Sequence[PauliString], code_hamiltonian: Observable, observable: Observable, pauli_string_to_expectation_cache: Dict[PauliString, complex] = {}, ) -> Callable[ [Callable[[QPROGRAM], QuantumResult]], Callable[[QPROGRAM], float] ]: """Decorator which adds an error-mitigation layer based on quantum subspace expansion (QSE) to an executor function, i.e., a function which executes a quantum circuit with an arbitrary backend and returns a ``QuantumResult``. Args: check_operators: List of check operators that define the stabilizer code space. code_hamiltonian: Hamiltonian of the code space. observable: Observable to compute the mitigated expectation value of. pauli_string_to_expectation_cache: Cache for expectation values of Pauli strings used to compute the projector and the observable. Returns: The error-mitigating decorator to be applied to an executor function. """ def decorator( executor: Callable[[QPROGRAM], QuantumResult], ) -> Callable[[QPROGRAM], float]: val = mitigate_executor( executor, check_operators, code_hamiltonian, observable, pauli_string_to_expectation_cache, ) return val return decorator