Source code for openfermioncirq.trotter.trotter_algorithm

#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

"""Classes for representing algorithms for performing Trotter steps."""

from typing import Optional, Sequence, TYPE_CHECKING, Tuple, Union

import abc

import cirq
import openfermion

if TYPE_CHECKING:
    # pylint: disable=unused-import
    from typing import Set, Type


Hamiltonian = Union[
        openfermion.FermionOperator,
        openfermion.QubitOperator,
        openfermion.InteractionOperator,
        openfermion.DiagonalCoulombHamiltonian]


[docs]class TrotterStep(metaclass=abc.ABCMeta): """A method for performing a Trotter step. This class assumes that Hamiltonian evolution using a Trotter-Suzuki product formula is performed in the following steps: 1. Perform some preparatory operations (for instance, a basis change). 2. Perform a number of Trotter steps. Each Trotter step may induce a permutation on the ordering in which qubits represent fermionic modes. 3. Perform some finishing operations. Attributes: hamiltonian: The Hamiltonian being simulated. """
[docs] def __init__(self, hamiltonian: Hamiltonian) -> None: self.hamiltonian = hamiltonian
def prepare(self, qubits: Sequence[cirq.Qid], control_qubit: Optional[cirq.Qid]=None ) -> cirq.OP_TREE: """Operations to perform before doing the Trotter steps. Args: qubits: The qubits on which to perform operations. They should be sorted so that the j-th qubit in the Sequence holds the occupation of the j-th fermionic mode. hamiltonian: The Hamiltonian to simulate. control_qubit: The control qubit, if the algorithm is controlled. """ # Default: do nothing return () @abc.abstractmethod def trotter_step( self, qubits: Sequence[cirq.Qid], time: float, control_qubit: Optional[cirq.Qid]=None ) -> cirq.OP_TREE: """Yield operations to perform a Trotter step. Args: qubits: The qubits on which to apply the Trotter step. hamiltonian: The Hamiltonian to simulate. time: The evolution time. control_qubit: The control qubit, if the algorithm is controlled. """ def step_qubit_permutation(self, qubits: Sequence[cirq.Qid], control_qubit: Optional[cirq.Qid]=None ) -> Tuple[Sequence[cirq.Qid], Optional[cirq.Qid]]: """The qubit permutation induced by a single Trotter step. Returns: A tuple whose first element is the new list of system qubits and second element is the new control qubit """ # Default: identity permutation return qubits, control_qubit def finish(self, qubits: Sequence[cirq.Qid], n_steps: int, control_qubit: Optional[cirq.Qid]=None, omit_final_swaps: bool=False ) -> cirq.OP_TREE: """Operations to perform after all Trotter steps are done. Args: qubits: The qubits on which to perform operations. hamiltonian: The Hamiltonian to simulate. n_steps: The total number of Trotter steps that have been performed. control_qubit: The control qubit, if the algorithm is controlled. omit_final_swaps: Whether or not to omit swap gates at the end of the circuit. """ # Default: do nothing return ()
[docs]class TrotterAlgorithm(metaclass=abc.ABCMeta): """An algorithm for performing a Trotter step. A Trotter step algorithm contains methods for performing a symmetric or asymmetric Trotter step and their controlled versions. It does not need to support all the possibilities; for instance, it may support only symmetric Trotter steps with no control qubit. Support for a kind of Trotter step is implemented by overriding the methods of this class. Attributes: supported_types: A set containing types of Hamiltonian representations that can be simulated using this Trotter step algorithm. For example, {DiagonalCoulombHamiltonian, InteractionOperator}. """ supported_types = set() # type: Set[Type[Hamiltonian]] def symmetric(self, hamiltonian: Hamiltonian) -> Optional[TrotterStep]: return None def asymmetric(self, hamiltonian: Hamiltonian) -> Optional[TrotterStep]: return None def controlled_symmetric(self, hamiltonian: Hamiltonian ) -> Optional[TrotterStep]: return None def controlled_asymmetric(self, hamiltonian: Hamiltonian ) -> Optional[TrotterStep]: return None