Skip to content

Commit 3326f36

Browse files
authored
Bring canonicalization of FSimGate and PhasedFSimGate angles b/w [-pi, pi) (#4576)
* Bring canonicalization of fsim/phasedfsim angles b/w [-pi, pi) * Get rid of numerical error in fsim angles canonicalization
1 parent f44b457 commit 3326f36

File tree

3 files changed

+33
-27
lines changed

3 files changed

+33
-27
lines changed

cirq-core/cirq/ops/fsim_gate.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,20 @@
3535

3636

3737
def _canonicalize(value: Union[float, sympy.Basic]) -> Union[float, sympy.Basic]:
38-
"""Assumes value is 2π-periodic and shifts it into [-π, π]."""
38+
"""Assumes value is 2π-periodic and shifts it into [-π, π)."""
3939
if protocols.is_parameterized(value):
4040
return value
4141
period = 2 * np.pi
42-
return value - period * np.round(value / period)
42+
return value - period * np.floor((value + np.pi) / period)
4343

4444

4545
def _zero_mod_pi(param: Union[float, sympy.Basic]) -> bool:
46-
"""Returns True iff param, assumed to be in [-pi, pi], is 0 (mod pi)."""
47-
return param in (-np.pi, 0.0, np.pi, -sympy.pi, sympy.pi)
46+
"""Returns True iff param, assumed to be in [-pi, pi), is 0 (mod pi)."""
47+
return param in (0.0, -np.pi, -sympy.pi)
4848

4949

5050
def _half_pi_mod_pi(param: Union[float, sympy.Basic]) -> bool:
51-
"""Returns True iff param, assumed to be in [-pi, pi], is pi/2 (mod pi)."""
51+
"""Returns True iff param, assumed to be in [-pi, pi), is pi/2 (mod pi)."""
5252
return param in (-np.pi / 2, np.pi / 2, -sympy.pi / 2, sympy.pi / 2)
5353

5454

cirq-core/cirq/ops/fsim_gate_test.py

+26-21
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ def test_fsim_eq():
4242
eq.add_equality_group(cirq.FSimGate(0, 0))
4343
eq.add_equality_group(cirq.FSimGate(1, 1))
4444
eq.add_equality_group(cirq.FSimGate(1, 2).on(a, b), cirq.FSimGate(1, 2).on(b, a))
45+
eq.add_equality_group(cirq.FSimGate(np.pi, np.pi), cirq.FSimGate(-np.pi, -np.pi))
4546

4647

4748
def test_fsim_approx_eq():
@@ -73,26 +74,26 @@ def test_fsim_circuit():
7374
cirq.testing.assert_has_diagram(
7475
c,
7576
"""
76-
0: ───FSim(0.5π, π)───FSim(-π, 0.5π)───
77-
│ │
78-
1: ───FSim(0.5π, π)───FSim(-π, 0.5π)───
77+
0: ───FSim(0.5π, -π)───FSim(-π, 0.5π)───
78+
79+
1: ───FSim(0.5π, -π)───FSim(-π, 0.5π)───
7980
""",
8081
)
8182
cirq.testing.assert_has_diagram(
8283
c,
8384
"""
84-
0: ---FSim(0.5pi, pi)---FSim(-pi, 0.5pi)---
85-
| |
86-
1: ---FSim(0.5pi, pi)---FSim(-pi, 0.5pi)---
85+
0: ---FSim(0.5pi, -pi)---FSim(-pi, 0.5pi)---
86+
| |
87+
1: ---FSim(0.5pi, -pi)---FSim(-pi, 0.5pi)---
8788
""",
8889
use_unicode_characters=False,
8990
)
9091
cirq.testing.assert_has_diagram(
9192
c,
9293
"""
93-
0: ---FSim(1.5707963267948966, pi)---FSim(-pi, 1.5707963267948966)---
94-
| |
95-
1: ---FSim(1.5707963267948966, pi)---FSim(-pi, 1.5707963267948966)---
94+
0: ---FSim(1.5707963267948966, -pi)---FSim(-pi, 1.5707963267948966)---
95+
| |
96+
1: ---FSim(1.5707963267948966, -pi)---FSim(-pi, 1.5707963267948966)---
9697
""",
9798
use_unicode_characters=False,
9899
precision=None,
@@ -379,6 +380,10 @@ def test_phased_fsim_eq():
379380
eq.add_equality_group(cirq.PhasedFSimGate(1, s, 0, 0, 0))
380381
eq.add_equality_group(cirq.PhasedFSimGate(r, 1, 0, 0, 0))
381382
eq.add_equality_group(cirq.PhasedFSimGate(s, 1, 0, 0, 0))
383+
eq.add_equality_group(
384+
cirq.PhasedFSimGate(np.pi, np.pi, np.pi, np.pi, np.pi),
385+
cirq.PhasedFSimGate(-np.pi, -np.pi, -np.pi, -np.pi, -np.pi),
386+
)
382387

383388
# Regions of insensitivity to zeta and chi
384389
eq.add_equality_group(
@@ -392,7 +397,7 @@ def test_phased_fsim_eq():
392397
cirq.PhasedFSimGate(sympy.pi / 2, 0, 0, 4, 5), cirq.PhasedFSimGate(sympy.pi / 2, 2, 0, 4, 5)
393398
)
394399
eq.add_equality_group(
395-
cirq.PhasedFSimGate(sympy.pi, 0, 0, 4, 5), cirq.PhasedFSimGate(sympy.pi, 0, 3, 4, 5)
400+
cirq.PhasedFSimGate(-sympy.pi, 0, 0, 4, 5), cirq.PhasedFSimGate(-sympy.pi, 0, 3, 4, 5)
396401
)
397402

398403
# Symmetries under qubit exchange
@@ -410,8 +415,8 @@ def test_phased_fsim_eq():
410415
cirq.PhasedFSimGate(1, -np.pi, np.pi, 4, 5).on(b, a),
411416
)
412417
eq.add_equality_group(
413-
cirq.PhasedFSimGate(1, sympy.pi, -sympy.pi, r, 5).on(a, b),
414-
cirq.PhasedFSimGate(1, sympy.pi, -sympy.pi, r, 5).on(b, a),
418+
cirq.PhasedFSimGate(1, -sympy.pi, -sympy.pi, r, 5).on(a, b),
419+
cirq.PhasedFSimGate(1, -sympy.pi, -sympy.pi, r, 5).on(b, a),
415420
)
416421
eq.add_equality_group(cirq.PhasedFSimGate(sympy.pi / 3, 2, 0, 4, 5).on(a, b))
417422
eq.add_equality_group(cirq.PhasedFSimGate(sympy.pi / 3, 2, 0, 4, 5).on(b, a))
@@ -479,27 +484,27 @@ def test_phased_fsim_circuit():
479484
cirq.testing.assert_has_diagram(
480485
c,
481486
"""
482-
0: ───PhFSim(0.5π, π, 0.5π, 0, -0.25π)───PhFSim(-π, 0.5π, 0.1π, 0.2π, 0.3π)───
483-
│ │
484-
1: ───PhFSim(0.5π, π, 0.5π, 0, -0.25π)───PhFSim(-π, 0.5π, 0.1π, 0.2π, 0.3π)───
487+
0: ───PhFSim(0.5π, -π, 0.5π, 0, -0.25π)───PhFSim(-π, 0.5π, 0.1π, 0.2π, 0.3π)───
488+
489+
1: ───PhFSim(0.5π, -π, 0.5π, 0, -0.25π)───PhFSim(-π, 0.5π, 0.1π, 0.2π, 0.3π)───
485490
""",
486491
)
487492
# pylint: disable=line-too-long
488493
cirq.testing.assert_has_diagram(
489494
c,
490495
"""
491-
0: ---PhFSim(0.5pi, pi, 0.5pi, 0, -0.25pi)---PhFSim(-pi, 0.5pi, 0.1pi, 0.2pi, 0.3pi)---
492-
| |
493-
1: ---PhFSim(0.5pi, pi, 0.5pi, 0, -0.25pi)---PhFSim(-pi, 0.5pi, 0.1pi, 0.2pi, 0.3pi)---
496+
0: ---PhFSim(0.5pi, -pi, 0.5pi, 0, -0.25pi)---PhFSim(-pi, 0.5pi, 0.1pi, 0.2pi, 0.3pi)---
497+
| |
498+
1: ---PhFSim(0.5pi, -pi, 0.5pi, 0, -0.25pi)---PhFSim(-pi, 0.5pi, 0.1pi, 0.2pi, 0.3pi)---
494499
""",
495500
use_unicode_characters=False,
496501
)
497502
cirq.testing.assert_has_diagram(
498503
c,
499504
"""
500-
0: ---PhFSim(1.5707963267948966, pi, 1.5707963267948966, 0, -0.7853981633974483)---PhFSim(-pi, 1.5707963267948966, 0.3141592653589793, 0.6283185307179586, 0.9424777960769379)---
501-
| |
502-
1: ---PhFSim(1.5707963267948966, pi, 1.5707963267948966, 0, -0.7853981633974483)---PhFSim(-pi, 1.5707963267948966, 0.3141592653589793, 0.6283185307179586, 0.9424777960769379)---
505+
0: ---PhFSim(1.5707963267948966, -pi, 1.5707963267948966, 0, -0.7853981633974483)---PhFSim(-pi, 1.5707963267948966, 0.3141592653589793, 0.6283185307179586, 0.9424777960769379)---
506+
| |
507+
1: ---PhFSim(1.5707963267948966, -pi, 1.5707963267948966, 0, -0.7853981633974483)---PhFSim(-pi, 1.5707963267948966, 0.3141592653589793, 0.6283185307179586, 0.9424777960769379)---
503508
""",
504509
use_unicode_characters=False,
505510
precision=None,

cirq-google/cirq_google/serialization/common_serializers_test.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,8 @@ def test_wait_gate_multi_qubit():
556556
(cirq.CZ, 0, np.pi),
557557
(cirq.CZ ** -1.0, 0, np.pi),
558558
(cirq.FSimGate(theta=0, phi=0), 0, 0),
559-
(cirq.FSimGate(theta=0, phi=np.pi), 0, np.pi),
559+
(cirq.FSimGate(theta=0, phi=np.pi), 0, -np.pi),
560+
(cirq.FSimGate(theta=0, phi=-np.pi), 0, -np.pi),
560561
(cirq.FSimGate(theta=np.pi / 4, phi=0), np.pi / 4, 0),
561562
(cirq.FSimGate(theta=7 * np.pi / 4, phi=0), -np.pi / 4, 0),
562563
(cirq.FSimGate(theta=-np.pi / 4, phi=0), -np.pi / 4, 0),

0 commit comments

Comments
 (0)