55from bloqade .pyqrack import PyQrackQubit
66
77
8- @dataclass
8+ @dataclass ( frozen = True )
99class OperatorRuntimeABC :
1010 def apply (self , * qubits : PyQrackQubit , adjoint : bool = False ) -> None :
1111 raise NotImplementedError (
@@ -16,7 +16,7 @@ def control_apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
1616 raise NotImplementedError (f"Can't apply controlled version of { self } " )
1717
1818
19- @dataclass
19+ @dataclass ( frozen = True )
2020class OperatorRuntime (OperatorRuntimeABC ):
2121 method_name : str
2222
@@ -36,7 +36,7 @@ def control_apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
3636 getattr (target .sim_reg , method_name )(target .addr , ctrls )
3737
3838
39- @dataclass
39+ @dataclass ( frozen = True )
4040class ControlRuntime (OperatorRuntimeABC ):
4141 op : OperatorRuntimeABC
4242 n_controls : int
@@ -48,7 +48,7 @@ def apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
4848 self .op .control_apply (target , * ctrls , adjoint = adjoint )
4949
5050
51- @dataclass
51+ @dataclass ( frozen = True )
5252class ProjectorRuntime (OperatorRuntimeABC ):
5353 to_state : bool
5454
@@ -62,7 +62,7 @@ def control_apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
6262 target .sim_reg .mcmtrx (ctrls , m , target .addr )
6363
6464
65- @dataclass
65+ @dataclass ( frozen = True )
6666class IdentityRuntime (OperatorRuntimeABC ):
6767 # TODO: do we even need sites? The apply never does anything
6868 sites : int
@@ -74,7 +74,7 @@ def control_apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
7474 pass
7575
7676
77- @dataclass
77+ @dataclass ( frozen = True )
7878class MultRuntime (OperatorRuntimeABC ):
7979 lhs : OperatorRuntimeABC
8080 rhs : OperatorRuntimeABC
@@ -97,7 +97,7 @@ def control_apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
9797 self .lhs .control_apply (* qubits , adjoint = adjoint )
9898
9999
100- @dataclass
100+ @dataclass ( frozen = True )
101101class KronRuntime (OperatorRuntimeABC ):
102102 lhs : OperatorRuntimeABC
103103 rhs : OperatorRuntimeABC
@@ -107,7 +107,7 @@ def apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
107107 self .rhs .apply (qubits [1 ], adjoint = adjoint )
108108
109109
110- @dataclass
110+ @dataclass ( frozen = True )
111111class ScaleRuntime (OperatorRuntimeABC ):
112112 op : OperatorRuntimeABC
113113 factor : complex
@@ -140,7 +140,37 @@ def control_apply(self, *qubits: PyQrackQubit, adjoint: bool = False) -> None:
140140 target .sim_reg .mcmtrx (ctrls , m , target .addr )
141141
142142
143- @dataclass
143+ @dataclass (frozen = True )
144+ class PhaseOpRuntime (OperatorRuntimeABC ):
145+ theta : float
146+ global_ : bool
147+
148+ def mat (self , adjoint : bool ):
149+ sign = (- 1 ) ** (not adjoint )
150+ phase = np .exp (sign * 1j * self .theta )
151+ return [self .global_ * phase , 0 , 0 , phase ]
152+
153+ def apply (self , * qubits : PyQrackQubit , adjoint : bool = False ) -> None :
154+ target = qubits [- 1 ]
155+ target .sim_reg .mtrx (self .mat (adjoint = adjoint ), target .addr )
156+
157+ def control_apply (self , * qubits : PyQrackQubit , adjoint : bool = False ) -> None :
158+ target = qubits [- 1 ]
159+ ctrls = [qbit .addr for qbit in qubits [:- 1 ]]
160+
161+ m = self .mat (adjoint = adjoint )
162+
163+ target .sim_reg .mcmtrx (ctrls , m , target .addr )
164+
165+
166+ @dataclass (frozen = True )
167+ class RotRuntime (OperatorRuntimeABC ):
168+ axis : OperatorRuntimeABC
169+ angle : float
170+ # TODO: how does this work?
171+
172+
173+ @dataclass (frozen = True )
144174class AdjointRuntime (OperatorRuntimeABC ):
145175 op : OperatorRuntimeABC
146176
0 commit comments