1111# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212# See the License for the specific language governing permissions and
1313# limitations under the License.
14+ from collections import Counter
1415from functools import cached_property
1516from typing import cast , Dict , Set , Tuple , TYPE_CHECKING , Union
1617
1718import numpy as np
1819from attrs import field , frozen
1920from numpy .typing import NDArray
2021
21- from qualtran import bloq_example , BloqDocSpec , GateWithRegisters , Signature , Soquet
22+ from qualtran import Bloq , bloq_example , BloqDocSpec , CtrlSpec , Signature , Soquet
23+ from qualtran .bloqs .basic_gates .su2_rotation import SU2RotationGate
2224from qualtran .bloqs .qsp .generalized_qsp import GeneralizedQSP
2325from qualtran .bloqs .qubitization .qubitization_walk_operator import QubitizationWalkOperator
2426from qualtran .linalg .polynomial .jacobi_anger_approximations import (
3436
3537
3638@frozen
37- class HamiltonianSimulationByGQSP (GateWithRegisters ):
39+ class HamiltonianSimulationByGQSP (Bloq ):
3840 r"""Hamiltonian simulation using Generalized QSP given a qubitized quantum walk operator.
3941
4042 Given the Szegedy Quantum Walk Operator for a Hamiltonian $H$ constructed from SELECT and PREPARE oracles,
@@ -161,7 +163,6 @@ def __add_prepare(
161163 return gqsp_soqs , prepare_out_soqs
162164
163165 def build_composite_bloq (self , bb : 'BloqBuilder' , ** soqs : 'SoquetT' ) -> Dict [str , 'SoquetT' ]:
164- # TODO open issue: alloc/free does not work with cirq api
165166 state_prep_ancilla : Dict [str , 'SoquetT' ] = {
166167 reg .name : bb .allocate (reg .total_bits ())
167168 for reg in self .walk_operator .prepare .junk_registers
@@ -182,19 +183,16 @@ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str
182183 return soqs
183184
184185 def build_call_graph (self , ssa : 'SympySymbolAllocator' ) -> Set ['BloqCountT' ]:
185- if self .is_symbolic ():
186- from qualtran .bloqs .basic_gates .su2_rotation import SU2RotationGate
187-
188- d = self .degree
189- return {
190- (self .walk_operator .prepare , 1 ),
191- (self .walk_operator .prepare .adjoint (), 1 ),
192- (self .walk_operator .controlled (control_values = [0 ]), d ),
193- (self .walk_operator .adjoint ().controlled (), d ),
194- (SU2RotationGate .arbitrary (ssa ), 2 * d + 1 ),
195- }
196-
197- return super ().build_call_graph (ssa )
186+ counts = Counter [Bloq ]()
187+
188+ d = self .degree
189+ counts [self .walk_operator .prepare ] += 1
190+ counts [self .walk_operator .prepare .adjoint ()] += 1
191+ counts [self .walk_operator .controlled (ctrl_spec = CtrlSpec (cvs = 0 ))] += d
192+ counts [self .walk_operator .adjoint ().controlled ()] += d
193+ counts [SU2RotationGate .arbitrary (ssa )] += 2 * d + 1
194+
195+ return set (counts .items ())
198196
199197
200198@bloq_example
0 commit comments