-
Notifications
You must be signed in to change notification settings - Fork 373
/
trotter_algorithm.py
138 lines (111 loc) · 5.2 KB
/
trotter_algorithm.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# 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
from openfermion import ops
if TYPE_CHECKING:
# pylint: disable=unused-import
from typing import Set, Type
Hamiltonian = Union[ops.FermionOperator, ops.QubitOperator, ops.
InteractionOperator, ops.DiagonalCoulombHamiltonian]
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.
"""
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 ()
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