Skip to content

Commit 3b19e04

Browse files
authored
Make xmon gates parameterizable (#427)
* parameterize xmon gates * mostly revert to old xmon gate code * revert depolarizer channel change
1 parent 35fe511 commit 3b19e04

File tree

6 files changed

+76
-16
lines changed

6 files changed

+76
-16
lines changed

cirq/google/xmon_gates.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ class Exp11Gate(XmonGate,
111111
ops.TextDiagrammableGate,
112112
ops.InterchangeableQubitsGate,
113113
ops.PhaseableGate,
114+
ops.ParameterizableGate,
114115
PotentialImplementation):
115116
"""A two-qubit interaction that phases the amplitude of the 11 state.
116117
@@ -160,7 +161,7 @@ def text_diagram_wire_symbols(self,
160161
qubit_count=None,
161162
use_unicode_characters=True,
162163
precision=3):
163-
return 'Z', 'Z'
164+
return '@', 'Z'
164165

165166
def text_diagram_exponent(self):
166167
return self.half_turns
@@ -183,14 +184,21 @@ def __ne__(self, other):
183184
return not self == other
184185

185186
def __hash__(self):
186-
return hash((ops.Rot11Gate, self.half_turns))
187+
return hash((Exp11Gate, self.half_turns))
188+
189+
def is_parameterized(self) -> bool:
190+
return isinstance(self.half_turns, Symbol)
191+
192+
def with_parameters_resolved_by(self, param_resolver) -> 'Exp11Gate':
193+
return Exp11Gate(half_turns=param_resolver.value_of(self.half_turns))
187194

188195

189196
class ExpWGate(XmonGate,
190197
ops.SingleQubitGate,
191198
ops.TextDiagrammableGate,
192199
ops.PhaseableGate,
193200
ops.BoundedEffectGate,
201+
ops.ParameterizableGate,
194202
PotentialImplementation):
195203
"""A rotation around an axis in the XY plane of the Bloch sphere.
196204
@@ -325,10 +333,20 @@ def __hash__(self):
325333
return hash((ops.RotYGate, self.half_turns))
326334
return hash((ExpWGate, self.half_turns, self.axis_half_turns))
327335

336+
def is_parameterized(self) -> bool:
337+
return (isinstance(self.half_turns, Symbol) or
338+
isinstance(self.axis_half_turns, Symbol))
339+
340+
def with_parameters_resolved_by(self, param_resolver) -> 'ExpWGate':
341+
return ExpWGate(
342+
half_turns=param_resolver.value_of(self.half_turns),
343+
axis_half_turns=param_resolver.value_of(self.axis_half_turns))
344+
328345

329346
class ExpZGate(XmonGate,
330347
ops.SingleQubitGate,
331348
ops.TextDiagrammableGate,
349+
ops.ParameterizableGate,
332350
PotentialImplementation):
333351
"""A rotation around the Z axis of the Bloch sphere.
334352
@@ -384,7 +402,7 @@ def has_matrix(self):
384402
def matrix(self):
385403
if not self.has_matrix():
386404
raise ValueError("Don't have a known matrix.")
387-
return ops.RotZGate(half_turns=self.half_turns).matrix()
405+
return np.diag([(-1j)**self.half_turns, 1j**self.half_turns])
388406

389407
def trace_distance_bound(self):
390408
if isinstance(self.half_turns, Symbol):
@@ -427,6 +445,12 @@ def __ne__(self, other):
427445
def __hash__(self):
428446
return hash((ExpZGate, self.half_turns))
429447

448+
def is_parameterized(self) -> bool:
449+
return isinstance(self.half_turns, Symbol)
450+
451+
def with_parameters_resolved_by(self, param_resolver) -> 'ExpZGate':
452+
return ExpZGate(half_turns=param_resolver.value_of(self.half_turns))
453+
430454

431455
def _canonicalize_half_turns(
432456
half_turns: Union[Symbol, float]

cirq/google/xmon_gates_test.py

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
import pytest
15+
import numpy as np
1516
from google.protobuf import message, text_format
1617

1718
from cirq.api.google.v1 import operations_pb2
@@ -20,6 +21,7 @@
2021
XmonGate, XmonQubit, XmonMeasurementGate, ExpZGate, Exp11Gate, ExpWGate,
2122
)
2223
from cirq.ops import KnownMatrixGate, ReversibleGate
24+
from cirq.study import ParamResolver
2325
from cirq.value import Symbol
2426
from cirq.testing import EqualsTester
2527

@@ -127,6 +129,27 @@ def test_z_to_proto():
127129
""")
128130

129131

132+
def test_z_matrix():
133+
assert np.allclose(ExpZGate(half_turns=1).matrix(),
134+
np.array([[-1j, 0], [0, 1j]]))
135+
assert np.allclose(ExpZGate(half_turns=0.5).matrix(),
136+
np.array([[1 - 1j, 0], [0, 1 + 1j]]) / np.sqrt(2))
137+
assert np.allclose(ExpZGate(half_turns=0).matrix(),
138+
np.array([[1, 0], [0, 1]]))
139+
assert np.allclose(ExpZGate(half_turns=-0.5).matrix(),
140+
np.array([[1 + 1j, 0], [0, 1 - 1j]]) / np.sqrt(2))
141+
142+
143+
def test_z_parameterize():
144+
parameterized_gate = ExpZGate(half_turns=Symbol('a'))
145+
assert parameterized_gate.is_parameterized()
146+
with pytest.raises(ValueError):
147+
_ = parameterized_gate.matrix()
148+
resolver = ParamResolver({'a': 0.1})
149+
resolved_gate = parameterized_gate.with_parameters_resolved_by(resolver)
150+
assert resolved_gate == ExpZGate(half_turns=0.1)
151+
152+
130153
def test_cz_eq():
131154
eq = EqualsTester()
132155
eq.make_equality_pair(lambda: Exp11Gate(half_turns=0))
@@ -179,6 +202,22 @@ def test_cz_to_proto():
179202
""")
180203

181204

205+
def test_cz_potential_implementation():
206+
ex = Extensions()
207+
assert not ex.can_cast(Exp11Gate(half_turns=Symbol('a')), KnownMatrixGate)
208+
assert ex.can_cast(Exp11Gate(), KnownMatrixGate)
209+
210+
211+
def test_cz_parameterize():
212+
parameterized_gate = Exp11Gate(half_turns=Symbol('a'))
213+
assert parameterized_gate.is_parameterized()
214+
with pytest.raises(ValueError):
215+
_ = parameterized_gate.matrix()
216+
resolver = ParamResolver({'a': 0.1})
217+
resolved_gate = parameterized_gate.with_parameters_resolved_by(resolver)
218+
assert resolved_gate == Exp11Gate(half_turns=0.1)
219+
220+
182221
def test_w_eq():
183222
eq = EqualsTester()
184223
eq.add_equality_group(ExpWGate(),
@@ -270,7 +309,12 @@ def test_w_potential_implementation():
270309
assert ex.can_cast(ExpWGate(), ReversibleGate)
271310

272311

273-
def test_cz_potential_implementation():
274-
ex = Extensions()
275-
assert not ex.can_cast(Exp11Gate(half_turns=Symbol('a')), KnownMatrixGate)
276-
assert ex.can_cast(Exp11Gate(), KnownMatrixGate)
312+
def test_w_parameterize():
313+
parameterized_gate = ExpWGate(half_turns=Symbol('a'),
314+
axis_half_turns=Symbol('b'))
315+
assert parameterized_gate.is_parameterized()
316+
with pytest.raises(ValueError):
317+
_ = parameterized_gate.matrix()
318+
resolver = ParamResolver({'a': 0.1, 'b': 0.2})
319+
resolved_gate = parameterized_gate.with_parameters_resolved_by(resolver)
320+
assert resolved_gate == ExpWGate(half_turns=0.1, axis_half_turns=0.2)

cirq/ops/gate_features.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,4 @@ def with_parameters_resolved_by(self,
258258
259259
Returns a gate of the same type, but with all Symbols replaced with
260260
floats according to the given ParamResolver.
261-
262-
Raises:
263-
ValueError: The gate has no parameters to resolve.
264261
"""

cirq/ops/partial_reflection_gate.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,5 @@ def is_parameterized(self) -> bool:
138138

139139
def with_parameters_resolved_by(self,
140140
param_resolver) -> 'PartialReflectionGate':
141-
if not self.is_parameterized():
142-
raise ValueError("Gate does not have any parameters to resolve.")
143141
return self._with_half_turns(
144142
half_turns=param_resolver.value_of(self.half_turns))

cirq/ops/partial_reflection_gate_test.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
from typing import Union
1616

1717
import numpy as np
18-
import pytest
1918

2019
import cirq
2120
from cirq.ops.partial_reflection_gate import PartialReflectionGate
@@ -84,5 +83,3 @@ def test_partial_reflection_gate_with_parameters_resolved_by():
8483
resolver = ParamResolver({'a': 0.1})
8584
resolved_gate = gate.with_parameters_resolved_by(resolver)
8685
assert resolved_gate.half_turns == 0.1
87-
with pytest.raises(ValueError):
88-
_ = resolved_gate.with_parameters_resolved_by(resolver)

docs/simulation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ circuit.append(basic_circuit())
3434

3535
print(circuit)
3636
# prints
37-
# (0, 0): ───X^0.5───Z───X^0.5───M───
37+
# (0, 0): ───X^0.5───@───X^0.5───M───
3838
#
3939
# (1, 0): ───X^0.5───Z───X^0.5───M───
4040
```

0 commit comments

Comments
 (0)