We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
upgrade to numpy 1.19
Discover all the issues / test failures related to numpy 0.19 and upgrade our requirements.txt.
More context: https://github.com/quantumlib/Cirq/pull/3106

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cirq/optimizers/decompositions.py`
Content:
```
1 # Copyright 2018 The Cirq Developers
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     https://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 """Utility methods related to optimizing quantum circuits."""
16 
17 import math
18 from typing import List, Optional, Tuple, cast
19 
20 import numpy as np
21 import sympy
22 
23 from cirq import ops, linalg, protocols
24 from cirq.linalg.tolerance import near_zero_mod
25 
26 
27 def is_negligible_turn(turns: float, tolerance: float) -> bool:
28     if isinstance(turns, sympy.Basic):
29         if not turns.is_constant():
30             return False
31         turns = float(turns)
32     return abs(_signed_mod_1(turns)) <= tolerance
33 
34 
35 def _signed_mod_1(x: float) -> float:
36     return (x + 0.5) % 1 - 0.5
37 
38 
39 def single_qubit_matrix_to_pauli_rotations(
40         mat: np.ndarray, atol: float = 0
41 ) -> List[Tuple[ops.Pauli, float]]:
42     """Implements a single-qubit operation with few rotations.
43 
44     Args:
45         mat: The 2x2 unitary matrix of the operation to implement.
46         atol: A limit on the amount of absolute error introduced by the
47             construction.
48 
49     Returns:
50         A list of (Pauli, half_turns) tuples that, when applied in order,
51         perform the desired operation.
52     """
53 
54     def is_clifford_rotation(half_turns):
55         return near_zero_mod(half_turns, 0.5, atol=atol)
56 
57     def to_quarter_turns(half_turns):
58         return round(2 * half_turns) % 4
59 
60     def is_quarter_turn(half_turns):
61         return (is_clifford_rotation(half_turns) and
62                 to_quarter_turns(half_turns) % 2 == 1)
63 
64     def is_half_turn(half_turns):
65         return (is_clifford_rotation(half_turns) and
66                 to_quarter_turns(half_turns) == 2)
67 
68     def is_no_turn(half_turns):
69         return (is_clifford_rotation(half_turns) and
70                 to_quarter_turns(half_turns) == 0)
71 
72     # Decompose matrix
73     z_rad_before, y_rad, z_rad_after = (
74         linalg.deconstruct_single_qubit_matrix_into_angles(mat))
75     z_ht_before = z_rad_before / np.pi - 0.5
76     m_ht = y_rad / np.pi
77     m_pauli = ops.X  # type: ops.Pauli
78     z_ht_after = z_rad_after / np.pi + 0.5
79 
80     # Clean up angles
81     if is_clifford_rotation(z_ht_before):
82         if ((is_quarter_turn(z_ht_before) or is_quarter_turn(z_ht_after)) ^
83             (is_half_turn(m_ht) and is_no_turn(z_ht_before-z_ht_after))):
84             z_ht_before += 0.5
85             z_ht_after -= 0.5
86             m_pauli = ops.Y
87         if is_half_turn(z_ht_before) or is_half_turn(z_ht_after):
88             z_ht_before -= 1
89             z_ht_after += 1
90             m_ht = -m_ht
91     if is_no_turn(m_ht):
92         z_ht_before += z_ht_after
93         z_ht_after = 0
94     elif is_half_turn(m_ht):
95         z_ht_after -= z_ht_before
96         z_ht_before = 0
97 
98     # Generate operations
99     rotation_list = [(ops.Z, z_ht_before), (m_pauli, m_ht), (ops.Z, z_ht_after)]
100     return [(pauli, ht) for pauli, ht in rotation_list if not is_no_turn(ht)]
101 
102 
103 def single_qubit_matrix_to_gates(
104         mat: np.ndarray, tolerance: float = 0
105 ) -> List[ops.SingleQubitGate]:
106     """Implements a single-qubit operation with few gates.
107 
108     Args:
109         mat: The 2x2 unitary matrix of the operation to implement.
110         tolerance: A limit on the amount of error introduced by the
111             construction.
112 
113     Returns:
114         A list of gates that, when applied in order, perform the desired
115             operation.
116     """
117     rotations = single_qubit_matrix_to_pauli_rotations(mat, tolerance)
118     return [cast(ops.SingleQubitGate, pauli)**ht for pauli, ht in rotations]
119 
120 
121 def single_qubit_op_to_framed_phase_form(
122         mat: np.ndarray) -> Tuple[np.ndarray, complex, complex]:
123     """Decomposes a 2x2 unitary M into U^-1 * diag(1, r) * U * diag(g, g).
124 
125     U translates the rotation axis of M to the Z axis.
126     g fixes a global phase factor difference caused by the translation.
127     r's phase is the amount of rotation around M's rotation axis.
128 
129     This decomposition can be used to decompose controlled single-qubit
130     rotations into controlled-Z operations bordered by single-qubit operations.
131 
132     Args:
133       mat:  The qubit operation as a 2x2 unitary matrix.
134 
135     Returns:
136         A 2x2 unitary U, the complex relative phase factor r, and the complex
137         global phase factor g. Applying M is equivalent (up to global phase) to
138         applying U, rotating around the Z axis to apply r, then un-applying U.
139         When M is controlled, the control must be rotated around the Z axis to
140         apply g.
141     """
142     vals, vecs = np.linalg.eig(mat)
143     u = np.conj(vecs).T
144     r = vals[1] / vals[0]
145     g = vals[0]
146     return u, r, g
147 
148 
149 def _deconstruct_single_qubit_matrix_into_gate_turns(
150         mat: np.ndarray) -> Tuple[float, float, float]:
151     """Breaks down a 2x2 unitary into gate parameters.
152 
153     Args:
154         mat: The 2x2 unitary matrix to break down.
155 
156     Returns:
157        A tuple containing the amount to rotate around an XY axis, the phase of
158        that axis, and the amount to phase around Z. All results will be in
159        fractions of a whole turn, with values canonicalized into the range
160        [-0.5, 0.5).
161     """
162     pre_phase, rotation, post_phase = (
163         linalg.deconstruct_single_qubit_matrix_into_angles(mat))
164 
165     # Figure out parameters of the actual gates we will do.
166     tau = 2 * np.pi
167     xy_turn = rotation / tau
168     xy_phase_turn = 0.25 - pre_phase / tau
169     total_z_turn = (post_phase + pre_phase) / tau
170 
171     # Normalize turns into the range [-0.5, 0.5).
172     return (_signed_mod_1(xy_turn), _signed_mod_1(xy_phase_turn),
173             _signed_mod_1(total_z_turn))
174 
175 
176 def single_qubit_matrix_to_phased_x_z(
177         mat: np.ndarray,
178         atol: float = 0
179 ) -> List[ops.SingleQubitGate]:
180     """Implements a single-qubit operation with a PhasedX and Z gate.
181 
182     If one of the gates isn't needed, it will be omitted.
183 
184     Args:
185         mat: The 2x2 unitary matrix of the operation to implement.
186         atol: A limit on the amount of error introduced by the
187             construction.
188 
189     Returns:
190         A list of gates that, when applied in order, perform the desired
191             operation.
192     """
193 
194     xy_turn, xy_phase_turn, total_z_turn = (
195         _deconstruct_single_qubit_matrix_into_gate_turns(mat))
196 
197     # Build the intended operation out of non-negligible XY and Z rotations.
198     result = [
199         ops.PhasedXPowGate(exponent=2 * xy_turn,
200                            phase_exponent=2 * xy_phase_turn),
201         ops.Z**(2 * total_z_turn)
202     ]
203     result = [
204         g for g in result
205         if protocols.trace_distance_bound(g) > atol
206     ]
207 
208     # Special case: XY half-turns can absorb Z rotations.
209     if len(result) == 2 and math.isclose(abs(xy_turn), 0.5, abs_tol=atol):
210         return [
211             ops.PhasedXPowGate(phase_exponent=2 * xy_phase_turn + total_z_turn)
212         ]
213 
214     return result
215 
216 
217 def single_qubit_matrix_to_phxz(
218         mat: np.ndarray,
219         atol: float = 0,
220 ) -> Optional[ops.PhasedXZGate]:
221     """Implements a single-qubit operation with a PhasedXZ gate.
222 
223     Under the hood, this uses deconstruct_single_qubit_matrix_into_angles which
224     converts the given matrix to a series of three rotations around the Z, Y, Z
225     axes. This is then converted to a phased X rotation followed by a Z, in the
226     form of a single PhasedXZ gate.
227 
228     Args:
229         mat: The 2x2 unitary matrix of the operation to implement.
230         atol: A limit on the amount of error introduced by the
231             construction.
232 
233     Returns:
234         A PhasedXZ gate that implements the given matrix, or None if it is
235         close to identity (trace distance <= atol).
236     """
237 
238     xy_turn, xy_phase_turn, total_z_turn = (
239         _deconstruct_single_qubit_matrix_into_gate_turns(mat))
240 
241     # Build the intended operation out of non-negligible XY and Z rotations.
242     g = ops.PhasedXZGate(
243         axis_phase_exponent=2 * xy_phase_turn,
244         x_exponent=2 * xy_turn,
245         z_exponent=2 * total_z_turn,
246     )
247 
248     if protocols.trace_distance_bound(g) <= atol:
249         return None
250 
251     # Special case: XY half-turns can absorb Z rotations.
252     if math.isclose(abs(xy_turn), 0.5, abs_tol=atol):
253         g = ops.PhasedXZGate(
254             axis_phase_exponent=2 * xy_phase_turn + total_z_turn,
255             x_exponent=1,
256             z_exponent=0,
257         )
258 
259     return g
260
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/cirq/optimizers/decompositions.py b/cirq/optimizers/decompositions.py
--- a/cirq/optimizers/decompositions.py
+++ b/cirq/optimizers/decompositions.py
@@ -139,7 +139,7 @@
         When M is controlled, the control must be rotated around the Z axis to
         apply g.
     """
-    vals, vecs = np.linalg.eig(mat)
+    vals, vecs = linalg.unitary_eig(mat)
     u = np.conj(vecs).T
     r = vals[1] / vals[0]
     g = vals[0]

{"golden_diff": "diff --git a/cirq/optimizers/decompositions.py b/cirq/optimizers/decompositions.py\n--- a/cirq/optimizers/decompositions.py\n+++ b/cirq/optimizers/decompositions.py\n@@ -139,7 +139,7 @@\n         When M is controlled, the control must be rotated around the Z axis to\n         apply g.\n     \"\"\"\n-    vals, vecs = np.linalg.eig(mat)\n+    vals, vecs = linalg.unitary_eig(mat)\n     u = np.conj(vecs).T\n     r = vals[1] / vals[0]\n     g = vals[0]\n", "issue": "upgrade to numpy 1.19\nDiscover all the issues / test failures related to numpy 0.19 and upgrade our requirements.txt.\r\nMore context: https://github.com/quantumlib/Cirq/pull/3106\n", "before_files": [{"content": "# Copyright 2018 The Cirq Developers\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Utility methods related to optimizing quantum circuits.\"\"\"\n\nimport math\nfrom typing import List, Optional, Tuple, cast\n\nimport numpy as np\nimport sympy\n\nfrom cirq import ops, linalg, protocols\nfrom cirq.linalg.tolerance import near_zero_mod\n\n\ndef is_negligible_turn(turns: float, tolerance: float) -> bool:\n    if isinstance(turns, sympy.Basic):\n        if not turns.is_constant():\n            return False\n        turns = float(turns)\n    return abs(_signed_mod_1(turns)) <= tolerance\n\n\ndef _signed_mod_1(x: float) -> float:\n    return (x + 0.5) % 1 - 0.5\n\n\ndef single_qubit_matrix_to_pauli_rotations(\n        mat: np.ndarray, atol: float = 0\n) -> List[Tuple[ops.Pauli, float]]:\n    \"\"\"Implements a single-qubit operation with few rotations.\n\n    Args:\n        mat: The 2x2 unitary matrix of the operation to implement.\n        atol: A limit on the amount of absolute error introduced by the\n            construction.\n\n    Returns:\n        A list of (Pauli, half_turns) tuples that, when applied in order,\n        perform the desired operation.\n    \"\"\"\n\n    def is_clifford_rotation(half_turns):\n        return near_zero_mod(half_turns, 0.5, atol=atol)\n\n    def to_quarter_turns(half_turns):\n        return round(2 * half_turns) % 4\n\n    def is_quarter_turn(half_turns):\n        return (is_clifford_rotation(half_turns) and\n                to_quarter_turns(half_turns) % 2 == 1)\n\n    def is_half_turn(half_turns):\n        return (is_clifford_rotation(half_turns) and\n                to_quarter_turns(half_turns) == 2)\n\n    def is_no_turn(half_turns):\n        return (is_clifford_rotation(half_turns) and\n                to_quarter_turns(half_turns) == 0)\n\n    # Decompose matrix\n    z_rad_before, y_rad, z_rad_after = (\n        linalg.deconstruct_single_qubit_matrix_into_angles(mat))\n    z_ht_before = z_rad_before / np.pi - 0.5\n    m_ht = y_rad / np.pi\n    m_pauli = ops.X  # type: ops.Pauli\n    z_ht_after = z_rad_after / np.pi + 0.5\n\n    # Clean up angles\n    if is_clifford_rotation(z_ht_before):\n        if ((is_quarter_turn(z_ht_before) or is_quarter_turn(z_ht_after)) ^\n            (is_half_turn(m_ht) and is_no_turn(z_ht_before-z_ht_after))):\n            z_ht_before += 0.5\n            z_ht_after -= 0.5\n            m_pauli = ops.Y\n        if is_half_turn(z_ht_before) or is_half_turn(z_ht_after):\n            z_ht_before -= 1\n            z_ht_after += 1\n            m_ht = -m_ht\n    if is_no_turn(m_ht):\n        z_ht_before += z_ht_after\n        z_ht_after = 0\n    elif is_half_turn(m_ht):\n        z_ht_after -= z_ht_before\n        z_ht_before = 0\n\n    # Generate operations\n    rotation_list = [(ops.Z, z_ht_before), (m_pauli, m_ht), (ops.Z, z_ht_after)]\n    return [(pauli, ht) for pauli, ht in rotation_list if not is_no_turn(ht)]\n\n\ndef single_qubit_matrix_to_gates(\n        mat: np.ndarray, tolerance: float = 0\n) -> List[ops.SingleQubitGate]:\n    \"\"\"Implements a single-qubit operation with few gates.\n\n    Args:\n        mat: The 2x2 unitary matrix of the operation to implement.\n        tolerance: A limit on the amount of error introduced by the\n            construction.\n\n    Returns:\n        A list of gates that, when applied in order, perform the desired\n            operation.\n    \"\"\"\n    rotations = single_qubit_matrix_to_pauli_rotations(mat, tolerance)\n    return [cast(ops.SingleQubitGate, pauli)**ht for pauli, ht in rotations]\n\n\ndef single_qubit_op_to_framed_phase_form(\n        mat: np.ndarray) -> Tuple[np.ndarray, complex, complex]:\n    \"\"\"Decomposes a 2x2 unitary M into U^-1 * diag(1, r) * U * diag(g, g).\n\n    U translates the rotation axis of M to the Z axis.\n    g fixes a global phase factor difference caused by the translation.\n    r's phase is the amount of rotation around M's rotation axis.\n\n    This decomposition can be used to decompose controlled single-qubit\n    rotations into controlled-Z operations bordered by single-qubit operations.\n\n    Args:\n      mat:  The qubit operation as a 2x2 unitary matrix.\n\n    Returns:\n        A 2x2 unitary U, the complex relative phase factor r, and the complex\n        global phase factor g. Applying M is equivalent (up to global phase) to\n        applying U, rotating around the Z axis to apply r, then un-applying U.\n        When M is controlled, the control must be rotated around the Z axis to\n        apply g.\n    \"\"\"\n    vals, vecs = np.linalg.eig(mat)\n    u = np.conj(vecs).T\n    r = vals[1] / vals[0]\n    g = vals[0]\n    return u, r, g\n\n\ndef _deconstruct_single_qubit_matrix_into_gate_turns(\n        mat: np.ndarray) -> Tuple[float, float, float]:\n    \"\"\"Breaks down a 2x2 unitary into gate parameters.\n\n    Args:\n        mat: The 2x2 unitary matrix to break down.\n\n    Returns:\n       A tuple containing the amount to rotate around an XY axis, the phase of\n       that axis, and the amount to phase around Z. All results will be in\n       fractions of a whole turn, with values canonicalized into the range\n       [-0.5, 0.5).\n    \"\"\"\n    pre_phase, rotation, post_phase = (\n        linalg.deconstruct_single_qubit_matrix_into_angles(mat))\n\n    # Figure out parameters of the actual gates we will do.\n    tau = 2 * np.pi\n    xy_turn = rotation / tau\n    xy_phase_turn = 0.25 - pre_phase / tau\n    total_z_turn = (post_phase + pre_phase) / tau\n\n    # Normalize turns into the range [-0.5, 0.5).\n    return (_signed_mod_1(xy_turn), _signed_mod_1(xy_phase_turn),\n            _signed_mod_1(total_z_turn))\n\n\ndef single_qubit_matrix_to_phased_x_z(\n        mat: np.ndarray,\n        atol: float = 0\n) -> List[ops.SingleQubitGate]:\n    \"\"\"Implements a single-qubit operation with a PhasedX and Z gate.\n\n    If one of the gates isn't needed, it will be omitted.\n\n    Args:\n        mat: The 2x2 unitary matrix of the operation to implement.\n        atol: A limit on the amount of error introduced by the\n            construction.\n\n    Returns:\n        A list of gates that, when applied in order, perform the desired\n            operation.\n    \"\"\"\n\n    xy_turn, xy_phase_turn, total_z_turn = (\n        _deconstruct_single_qubit_matrix_into_gate_turns(mat))\n\n    # Build the intended operation out of non-negligible XY and Z rotations.\n    result = [\n        ops.PhasedXPowGate(exponent=2 * xy_turn,\n                           phase_exponent=2 * xy_phase_turn),\n        ops.Z**(2 * total_z_turn)\n    ]\n    result = [\n        g for g in result\n        if protocols.trace_distance_bound(g) > atol\n    ]\n\n    # Special case: XY half-turns can absorb Z rotations.\n    if len(result) == 2 and math.isclose(abs(xy_turn), 0.5, abs_tol=atol):\n        return [\n            ops.PhasedXPowGate(phase_exponent=2 * xy_phase_turn + total_z_turn)\n        ]\n\n    return result\n\n\ndef single_qubit_matrix_to_phxz(\n        mat: np.ndarray,\n        atol: float = 0,\n) -> Optional[ops.PhasedXZGate]:\n    \"\"\"Implements a single-qubit operation with a PhasedXZ gate.\n\n    Under the hood, this uses deconstruct_single_qubit_matrix_into_angles which\n    converts the given matrix to a series of three rotations around the Z, Y, Z\n    axes. This is then converted to a phased X rotation followed by a Z, in the\n    form of a single PhasedXZ gate.\n\n    Args:\n        mat: The 2x2 unitary matrix of the operation to implement.\n        atol: A limit on the amount of error introduced by the\n            construction.\n\n    Returns:\n        A PhasedXZ gate that implements the given matrix, or None if it is\n        close to identity (trace distance <= atol).\n    \"\"\"\n\n    xy_turn, xy_phase_turn, total_z_turn = (\n        _deconstruct_single_qubit_matrix_into_gate_turns(mat))\n\n    # Build the intended operation out of non-negligible XY and Z rotations.\n    g = ops.PhasedXZGate(\n        axis_phase_exponent=2 * xy_phase_turn,\n        x_exponent=2 * xy_turn,\n        z_exponent=2 * total_z_turn,\n    )\n\n    if protocols.trace_distance_bound(g) <= atol:\n        return None\n\n    # Special case: XY half-turns can absorb Z rotations.\n    if math.isclose(abs(xy_turn), 0.5, abs_tol=atol):\n        g = ops.PhasedXZGate(\n            axis_phase_exponent=2 * xy_phase_turn + total_z_turn,\n            x_exponent=1,\n            z_exponent=0,\n        )\n\n    return g\n", "path": "cirq/optimizers/decompositions.py"}], "after_files": [{"content": "# Copyright 2018 The Cirq Developers\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Utility methods related to optimizing quantum circuits.\"\"\"\n\nimport math\nfrom typing import List, Optional, Tuple, cast\n\nimport numpy as np\nimport sympy\n\nfrom cirq import ops, linalg, protocols\nfrom cirq.linalg.tolerance import near_zero_mod\n\n\ndef is_negligible_turn(turns: float, tolerance: float) -> bool:\n    if isinstance(turns, sympy.Basic):\n        if not turns.is_constant():\n            return False\n        turns = float(turns)\n    return abs(_signed_mod_1(turns)) <= tolerance\n\n\ndef _signed_mod_1(x: float) -> float:\n    return (x + 0.5) % 1 - 0.5\n\n\ndef single_qubit_matrix_to_pauli_rotations(\n        mat: np.ndarray, atol: float = 0\n) -> List[Tuple[ops.Pauli, float]]:\n    \"\"\"Implements a single-qubit operation with few rotations.\n\n    Args:\n        mat: The 2x2 unitary matrix of the operation to implement.\n        atol: A limit on the amount of absolute error introduced by the\n            construction.\n\n    Returns:\n        A list of (Pauli, half_turns) tuples that, when applied in order,\n        perform the desired operation.\n    \"\"\"\n\n    def is_clifford_rotation(half_turns):\n        return near_zero_mod(half_turns, 0.5, atol=atol)\n\n    def to_quarter_turns(half_turns):\n        return round(2 * half_turns) % 4\n\n    def is_quarter_turn(half_turns):\n        return (is_clifford_rotation(half_turns) and\n                to_quarter_turns(half_turns) % 2 == 1)\n\n    def is_half_turn(half_turns):\n        return (is_clifford_rotation(half_turns) and\n                to_quarter_turns(half_turns) == 2)\n\n    def is_no_turn(half_turns):\n        return (is_clifford_rotation(half_turns) and\n                to_quarter_turns(half_turns) == 0)\n\n    # Decompose matrix\n    z_rad_before, y_rad, z_rad_after = (\n        linalg.deconstruct_single_qubit_matrix_into_angles(mat))\n    z_ht_before = z_rad_before / np.pi - 0.5\n    m_ht = y_rad / np.pi\n    m_pauli = ops.X  # type: ops.Pauli\n    z_ht_after = z_rad_after / np.pi + 0.5\n\n    # Clean up angles\n    if is_clifford_rotation(z_ht_before):\n        if ((is_quarter_turn(z_ht_before) or is_quarter_turn(z_ht_after)) ^\n            (is_half_turn(m_ht) and is_no_turn(z_ht_before-z_ht_after))):\n            z_ht_before += 0.5\n            z_ht_after -= 0.5\n            m_pauli = ops.Y\n        if is_half_turn(z_ht_before) or is_half_turn(z_ht_after):\n            z_ht_before -= 1\n            z_ht_after += 1\n            m_ht = -m_ht\n    if is_no_turn(m_ht):\n        z_ht_before += z_ht_after\n        z_ht_after = 0\n    elif is_half_turn(m_ht):\n        z_ht_after -= z_ht_before\n        z_ht_before = 0\n\n    # Generate operations\n    rotation_list = [(ops.Z, z_ht_before), (m_pauli, m_ht), (ops.Z, z_ht_after)]\n    return [(pauli, ht) for pauli, ht in rotation_list if not is_no_turn(ht)]\n\n\ndef single_qubit_matrix_to_gates(\n        mat: np.ndarray, tolerance: float = 0\n) -> List[ops.SingleQubitGate]:\n    \"\"\"Implements a single-qubit operation with few gates.\n\n    Args:\n        mat: The 2x2 unitary matrix of the operation to implement.\n        tolerance: A limit on the amount of error introduced by the\n            construction.\n\n    Returns:\n        A list of gates that, when applied in order, perform the desired\n            operation.\n    \"\"\"\n    rotations = single_qubit_matrix_to_pauli_rotations(mat, tolerance)\n    return [cast(ops.SingleQubitGate, pauli)**ht for pauli, ht in rotations]\n\n\ndef single_qubit_op_to_framed_phase_form(\n        mat: np.ndarray) -> Tuple[np.ndarray, complex, complex]:\n    \"\"\"Decomposes a 2x2 unitary M into U^-1 * diag(1, r) * U * diag(g, g).\n\n    U translates the rotation axis of M to the Z axis.\n    g fixes a global phase factor difference caused by the translation.\n    r's phase is the amount of rotation around M's rotation axis.\n\n    This decomposition can be used to decompose controlled single-qubit\n    rotations into controlled-Z operations bordered by single-qubit operations.\n\n    Args:\n      mat:  The qubit operation as a 2x2 unitary matrix.\n\n    Returns:\n        A 2x2 unitary U, the complex relative phase factor r, and the complex\n        global phase factor g. Applying M is equivalent (up to global phase) to\n        applying U, rotating around the Z axis to apply r, then un-applying U.\n        When M is controlled, the control must be rotated around the Z axis to\n        apply g.\n    \"\"\"\n    vals, vecs = linalg.unitary_eig(mat)\n    u = np.conj(vecs).T\n    r = vals[1] / vals[0]\n    g = vals[0]\n    return u, r, g\n\n\ndef _deconstruct_single_qubit_matrix_into_gate_turns(\n        mat: np.ndarray) -> Tuple[float, float, float]:\n    \"\"\"Breaks down a 2x2 unitary into gate parameters.\n\n    Args:\n        mat: The 2x2 unitary matrix to break down.\n\n    Returns:\n       A tuple containing the amount to rotate around an XY axis, the phase of\n       that axis, and the amount to phase around Z. All results will be in\n       fractions of a whole turn, with values canonicalized into the range\n       [-0.5, 0.5).\n    \"\"\"\n    pre_phase, rotation, post_phase = (\n        linalg.deconstruct_single_qubit_matrix_into_angles(mat))\n\n    # Figure out parameters of the actual gates we will do.\n    tau = 2 * np.pi\n    xy_turn = rotation / tau\n    xy_phase_turn = 0.25 - pre_phase / tau\n    total_z_turn = (post_phase + pre_phase) / tau\n\n    # Normalize turns into the range [-0.5, 0.5).\n    return (_signed_mod_1(xy_turn), _signed_mod_1(xy_phase_turn),\n            _signed_mod_1(total_z_turn))\n\n\ndef single_qubit_matrix_to_phased_x_z(\n        mat: np.ndarray,\n        atol: float = 0\n) -> List[ops.SingleQubitGate]:\n    \"\"\"Implements a single-qubit operation with a PhasedX and Z gate.\n\n    If one of the gates isn't needed, it will be omitted.\n\n    Args:\n        mat: The 2x2 unitary matrix of the operation to implement.\n        atol: A limit on the amount of error introduced by the\n            construction.\n\n    Returns:\n        A list of gates that, when applied in order, perform the desired\n            operation.\n    \"\"\"\n\n    xy_turn, xy_phase_turn, total_z_turn = (\n        _deconstruct_single_qubit_matrix_into_gate_turns(mat))\n\n    # Build the intended operation out of non-negligible XY and Z rotations.\n    result = [\n        ops.PhasedXPowGate(exponent=2 * xy_turn,\n                           phase_exponent=2 * xy_phase_turn),\n        ops.Z**(2 * total_z_turn)\n    ]\n    result = [\n        g for g in result\n        if protocols.trace_distance_bound(g) > atol\n    ]\n\n    # Special case: XY half-turns can absorb Z rotations.\n    if len(result) == 2 and math.isclose(abs(xy_turn), 0.5, abs_tol=atol):\n        return [\n            ops.PhasedXPowGate(phase_exponent=2 * xy_phase_turn + total_z_turn)\n        ]\n\n    return result\n\n\ndef single_qubit_matrix_to_phxz(\n        mat: np.ndarray,\n        atol: float = 0,\n) -> Optional[ops.PhasedXZGate]:\n    \"\"\"Implements a single-qubit operation with a PhasedXZ gate.\n\n    Under the hood, this uses deconstruct_single_qubit_matrix_into_angles which\n    converts the given matrix to a series of three rotations around the Z, Y, Z\n    axes. This is then converted to a phased X rotation followed by a Z, in the\n    form of a single PhasedXZ gate.\n\n    Args:\n        mat: The 2x2 unitary matrix of the operation to implement.\n        atol: A limit on the amount of error introduced by the\n            construction.\n\n    Returns:\n        A PhasedXZ gate that implements the given matrix, or None if it is\n        close to identity (trace distance <= atol).\n    \"\"\"\n\n    xy_turn, xy_phase_turn, total_z_turn = (\n        _deconstruct_single_qubit_matrix_into_gate_turns(mat))\n\n    # Build the intended operation out of non-negligible XY and Z rotations.\n    g = ops.PhasedXZGate(\n        axis_phase_exponent=2 * xy_phase_turn,\n        x_exponent=2 * xy_turn,\n        z_exponent=2 * total_z_turn,\n    )\n\n    if protocols.trace_distance_bound(g) <= atol:\n        return None\n\n    # Special case: XY half-turns can absorb Z rotations.\n    if math.isclose(abs(xy_turn), 0.5, abs_tol=atol):\n        g = ops.PhasedXZGate(\n            axis_phase_exponent=2 * xy_phase_turn + total_z_turn,\n            x_exponent=1,\n            z_exponent=0,\n        )\n\n    return g\n", "path": "cirq/optimizers/decompositions.py"}]}