internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: quantumlib/Cirq

Issue:
Gate.controlled(0) should return self



Discussion:

Resolving patch:
diff --git a/cirq/ops/raw_types.py b/cirq/ops/raw_types.py
--- a/cirq/ops/raw_types.py
+++ b/cirq/ops/raw_types.py
@@ -285,6 +285,8 @@ def controlled(self,
         """
         # Avoids circular import.
         from cirq.ops import ControlledGate
+        if num_controls == 0:
+            return self
         return ControlledGate(self,
                               num_controls=num_controls,
                               control_values=control_values,


Test patch:
diff --git a/cirq/ops/raw_types_test.py b/cirq/ops/raw_types_test.py
--- a/cirq/ops/raw_types_test.py
+++ b/cirq/ops/raw_types_test.py
@@ -124,6 +124,8 @@ def test_gate():
     with pytest.raises(ValueError, match='Wrong shape'):
         _ = g(a, b.with_dimension(3))
 
+    assert g.controlled(0) is g
+
 
 def test_op():
     a, b, c = cirq.LineQubit.range(3)
Repository: quantumlib/Cirq

Issue:
ParamResolver does not have evaluatable repr
The reason is that values can be resolved into instances of sympy.Basic. For instance, `repr(cirq.ParamResolver({'a': sympy.Symbol('b') + 1}))` evaluates to `"cirq.ParamResolver({'a': b + 1})"` where the `b` is not a defined expression.

This is currently blocking JSON serialization of ParamResolver because the serialization test insists that the repr be evaluatable. Should we drop this requirement for ParamResolver? Or should we actually try to get an evaluatable repr for arbitrary sympy.Basic instances? As @mpharrigan mentioned in #2014 we could maybe use `sympy.srepr`.

@Strilanc 


Discussion:

Resolving patch:
diff --git a/cirq/study/resolver.py b/cirq/study/resolver.py
--- a/cirq/study/resolver.py
+++ b/cirq/study/resolver.py
@@ -16,6 +16,7 @@
 
 from typing import Dict, Union, TYPE_CHECKING, cast
 import sympy
+from cirq._compat import proper_repr
 from cirq._doc import document
 
 if TYPE_CHECKING:
@@ -151,4 +152,8 @@ def __ne__(self, other):
         return not self == other
 
     def __repr__(self):
-        return 'cirq.ParamResolver({})'.format(repr(self.param_dict))
+        param_dict_repr = ('{' + ', '.join([
+            f'{proper_repr(k)}: {proper_repr(v)}'
+            for k, v in self.param_dict.items()
+        ]) + '}')
+        return 'cirq.ParamResolver({})'.format(param_dict_repr)


Test patch:
diff --git a/cirq/study/resolver_test.py b/cirq/study/resolver_test.py
--- a/cirq/study/resolver_test.py
+++ b/cirq/study/resolver_test.py
@@ -95,3 +95,7 @@ def test_equals():
 def test_repr():
     cirq.testing.assert_equivalent_repr(cirq.ParamResolver())
     cirq.testing.assert_equivalent_repr(cirq.ParamResolver({'a': 2.0}))
+    cirq.testing.assert_equivalent_repr(
+        cirq.ParamResolver({'a': sympy.Symbol('a')}))
+    cirq.testing.assert_equivalent_repr(
+        cirq.ParamResolver({sympy.Symbol('a'): sympy.Symbol('b') + 1}))
Repository: quantumlib/Cirq

Issue:
Make cirq.GridQubit + cirq.GridQubit work
```cirq.GridQubit(a, b) + (c, d)``` works

```cirq.GridQubit(a, b) + cirq.GridQubit(c, d)``` does not work

The latter should act like the former.


Discussion:
Not sure how I feel about this. It seems odd to use GridQubit as a "delta" on another grid qubit.
The use case I ran into was defining a layout in grid qubits, and then passing in the center. It made sense for the function call to expose the center as a grid qubit, and for the internals to be defined on grid qubits, and then the offset operation is natural.

Resolving patch:
diff --git a/cirq/devices/grid_qubit.py b/cirq/devices/grid_qubit.py
--- a/cirq/devices/grid_qubit.py
+++ b/cirq/devices/grid_qubit.py
@@ -163,6 +163,8 @@ def _json_dict_(self):
         return protocols.obj_to_dict_helper(self, ['row', 'col'])
 
     def __add__(self, other: Tuple[int, int]) -> 'GridQubit':
+        if isinstance(other, GridQubit):
+            return GridQubit(row=self.row + other.row, col=self.col + other.col)
         if not (isinstance(other, tuple) and len(other) == 2 and
                 all(isinstance(x, int) for x in other)):
             raise TypeError(
@@ -171,6 +173,8 @@ def __add__(self, other: Tuple[int, int]) -> 'GridQubit':
         return GridQubit(row=self.row + other[0], col=self.col + other[1])
 
     def __sub__(self, other: Tuple[int, int]) -> 'GridQubit':
+        if isinstance(other, GridQubit):
+            return GridQubit(row=self.row - other.row, col=self.col - other.col)
         if not (isinstance(other, tuple) and len(other) == 2 and
                 all(isinstance(x, int) for x in other)):
             raise TypeError(


Test patch:
diff --git a/cirq/devices/grid_qubit_test.py b/cirq/devices/grid_qubit_test.py
--- a/cirq/devices/grid_qubit_test.py
+++ b/cirq/devices/grid_qubit_test.py
@@ -154,6 +154,10 @@ def test_grid_qubit_add_subtract():
     assert (2, 5) + cirq.GridQubit(1, 2) == cirq.GridQubit(3, 7)
     assert (2, 5) - cirq.GridQubit(1, 2) == cirq.GridQubit(1, 3)
 
+    assert cirq.GridQubit(1, 2) + cirq.GridQubit(3, 5) == cirq.GridQubit(4, 7)
+    assert cirq.GridQubit(3, 5) - cirq.GridQubit(2, 1) == cirq.GridQubit(1, 4)
+    assert cirq.GridQubit(1, -2) + cirq.GridQubit(3, 5) == cirq.GridQubit(4, 3)
+
 
 def test_grid_qubit_neg():
     assert -cirq.GridQubit(1, 2) == cirq.GridQubit(-1, -2)
Repository: quantumlib/Cirq

Issue:
Need a better compilation for swap_to_sqrt_iswap
Right now it uses 4 sqrtiswaps to support arbitrary angle. For a plain ol' `SWAP` (common for routing qubits around) you should be able to get away with 3

```python
        yield cirq.Y(a) ** 0.5
        yield cirq.Y(b) ** 0.5
        yield SQRT_ISWAP(a, b)
        yield cirq.Y(a) ** -0.5
        yield cirq.Y(b) ** -0.5
        yield SQRT_ISWAP(a, b)
        yield cirq.X(a) ** -0.5
        yield cirq.X(b) ** -0.5
        yield SQRT_ISWAP(a, b)
        yield cirq.X(a) ** 0.5
        yield cirq.X(b) ** 0.5
```

should do it.

cc @dstrain115 @john6060 @Strilanc 


Discussion:

Resolving patch:
diff --git a/cirq/google/optimizers/convert_to_sqrt_iswap.py b/cirq/google/optimizers/convert_to_sqrt_iswap.py
--- a/cirq/google/optimizers/convert_to_sqrt_iswap.py
+++ b/cirq/google/optimizers/convert_to_sqrt_iswap.py
@@ -262,6 +262,21 @@ def swap_to_sqrt_iswap(a, b, turns):
             theta: The rotational angle that specifies the gate, where
             c = cos(π·t/2), s = sin(π·t/2), g = exp(i·π·t/2).
     """
+    if not isinstance(turns, sympy.Basic) and _near_mod_n(turns, 1.0, 2):
+        # Decomposition for cirq.SWAP
+        yield ops.Y(a)**0.5
+        yield ops.Y(b)**0.5
+        yield SQRT_ISWAP(a, b)
+        yield ops.Y(a)**-0.5
+        yield ops.Y(b)**-0.5
+        yield SQRT_ISWAP(a, b)
+        yield ops.X(a)**-0.5
+        yield ops.X(b)**-0.5
+        yield SQRT_ISWAP(a, b)
+        yield ops.X(a)**0.5
+        yield ops.X(b)**0.5
+        return
+
     yield ops.Z(a)**1.25
     yield ops.Z(b)**-0.25
     yield ops.ISWAP(a, b)**-0.5


Test patch:
diff --git a/cirq/google/optimizers/convert_to_sqrt_iswap_test.py b/cirq/google/optimizers/convert_to_sqrt_iswap_test.py
--- a/cirq/google/optimizers/convert_to_sqrt_iswap_test.py
+++ b/cirq/google/optimizers/convert_to_sqrt_iswap_test.py
@@ -22,7 +22,7 @@ def _unitaries_allclose(circuit1, circuit2):
     [
         (cast(cirq.Gate, cirq.ISWAP), 7),  # cast is for fixing mypy confusion
         (cirq.CZ, 8),
-        (cirq.SWAP, 13),
+        (cirq.SWAP, 7),
         (cirq.CNOT, 9),
         (cirq.ISWAP**0.5, 1),
         (cirq.ISWAP**-0.5, 1),
Repository: quantumlib/Cirq

Issue:
Qubits shouldn't be mutable
```python
import cirq
q1 = cirq.LineQubit(1)
circuit = cirq.Circuit(cirq.X(q1))
print(circuit)
q1.x = 2
print(circuit)
```

```
1: ───X───
2: ───X───
```


Discussion:
Agreed.

LineQubit and GridQubit and NamedQubit should have their values hidden behind property methods.
A new way to remap qubits!  (j/k).  Yes to immutable.
We can also consider using dataclasses with `frozen=True`, which offers a stronger form of immutability 
Could you please assign this issue to me? (#2385)
Can you please assign this to me?
@vtomole @Strilanc 

Resolving patch:
diff --git a/cirq/devices/grid_qubit.py b/cirq/devices/grid_qubit.py
--- a/cirq/devices/grid_qubit.py
+++ b/cirq/devices/grid_qubit.py
@@ -38,12 +38,20 @@ class GridQubit(ops.Qid):
     """
 
     def __init__(self, row: int, col: int):
-        self.row = row
-        self.col = col
+        self._row = row
+        self._col = col
 
     def _comparison_key(self):
         return self.row, self.col
 
+    @property
+    def row(self) -> int:
+        return self._row
+
+    @property
+    def col(self) -> int:
+        return self._col
+
     @property
     def dimension(self) -> int:
         return 2
diff --git a/cirq/devices/line_qubit.py b/cirq/devices/line_qubit.py
--- a/cirq/devices/line_qubit.py
+++ b/cirq/devices/line_qubit.py
@@ -32,11 +32,15 @@ class _BaseLineQid(ops.Qid):
 
     def __init__(self, x: int) -> None:
         """Initializes a line qubit at the given x coordinate."""
-        self.x = x
+        self._x = x
 
     def _comparison_key(self):
         return self.x
 
+    @property
+    def x(self) -> int:
+        return self._x
+
     def with_dimension(self, dimension: int) -> 'LineQid':
         return LineQid(self.x, dimension)
 


Test patch:
diff --git a/cirq/devices/grid_qubit_test.py b/cirq/devices/grid_qubit_test.py
--- a/cirq/devices/grid_qubit_test.py
+++ b/cirq/devices/grid_qubit_test.py
@@ -185,3 +185,13 @@ def test_to_json():
         'row': 5,
         'col': 6,
     }
+
+
+def test_immutable():
+    with pytest.raises(AttributeError, match="can't set attribute"):
+        q = cirq.GridQubit(1, 2)
+        q.col = 3
+
+    with pytest.raises(AttributeError, match="can't set attribute"):
+        q = cirq.GridQubit(1, 2)
+        q.row = 3
diff --git a/cirq/devices/line_qubit_test.py b/cirq/devices/line_qubit_test.py
--- a/cirq/devices/line_qubit_test.py
+++ b/cirq/devices/line_qubit_test.py
@@ -258,3 +258,13 @@ def _qid_shape_(self):
         cirq.LineQid(3, 3),
         cirq.LineQid(2, 1),
     ]
+
+
+def test_immutable():
+    with pytest.raises(AttributeError, match="can't set attribute"):
+        q = cirq.LineQubit(5)
+        q.x = 6
+
+    with pytest.raises(AttributeError, match="can't set attribute"):
+        q = cirq.LineQid(5, dimension=4)
+        q.x = 6
Repository: quantumlib/Cirq

Issue:
Pauli operator deserialization, and commutation checking
When you serialize and then deserialize a Pauli operator, you get a different instance, which might not be too surprising
```python
cirq.read_json(json_text=cirq.to_json(cirq.Z)) is cirq.Z

False
```
This shouldn't be a problem, however Paulis are checking commutation using `is` instead of `==`, so commutation with deserialized Paulis is broken.


Discussion:
Can you give a code example of the commutation being broken?
```python
In [1]: import cirq                                                                                                                                                                                                

In [2]: z = cirq.Z                                                                                                                                                                                                 

In [3]: z2 = cirq.read_json(json_text=cirq.to_json(cirq.Z))                                                                                                                                                        

In [4]: cirq.commutes(z, z2)                                                                                                                                                                                       
Out[4]: False
```

Resolving patch:
diff --git a/cirq/ops/pauli_gates.py b/cirq/ops/pauli_gates.py
--- a/cirq/ops/pauli_gates.py
+++ b/cirq/ops/pauli_gates.py
@@ -117,7 +117,7 @@ def _with_exponent(self: '_PauliX',
     def _from_json_dict_(cls, exponent, global_shift, **kwargs):
         assert global_shift == 0
         assert exponent == 1
-        return cls()
+        return Pauli._XYZ[0]
 
 
 class _PauliY(Pauli, common_gates.YPowGate):
@@ -138,7 +138,7 @@ def _with_exponent(self: '_PauliY',
     def _from_json_dict_(cls, exponent, global_shift, **kwargs):
         assert global_shift == 0
         assert exponent == 1
-        return cls()
+        return Pauli._XYZ[1]
 
 
 class _PauliZ(Pauli, common_gates.ZPowGate):
@@ -159,7 +159,7 @@ def _with_exponent(self: '_PauliZ',
     def _from_json_dict_(cls, exponent, global_shift, **kwargs):
         assert global_shift == 0
         assert exponent == 1
-        return cls()
+        return Pauli._XYZ[2]
 
 
 X = _PauliX()


Test patch:
diff --git a/cirq/ops/pauli_gates_test.py b/cirq/ops/pauli_gates_test.py
--- a/cirq/ops/pauli_gates_test.py
+++ b/cirq/ops/pauli_gates_test.py
@@ -182,6 +182,7 @@ def test_commutes():
     with pytest.raises(TypeError):
         assert cirq.commutes(cirq.X, 'X')
     assert cirq.commutes(cirq.X, 'X', default='default') == 'default'
+    assert cirq.commutes(cirq.Z, cirq.read_json(json_text=cirq.to_json(cirq.Z)))
 
 
 def test_unitary():
Repository: quantumlib/Cirq

Issue:
Update cirq.google.Bristlecone/Foxtail with accurate duration numbers



Discussion:
What are the correct duration numbers?
I'll add these once we have concrete numbers.
@JulianSKelly for posterity what numbers would you recommend for xmon gate speeds (we currently have 50 ns CZ and 20 ns XY)?
I would use 45ns CZ and 15 ns XY

Resolving patch:
diff --git a/cirq/google/devices/known_devices.py b/cirq/google/devices/known_devices.py
--- a/cirq/google/devices/known_devices.py
+++ b/cirq/google/devices/known_devices.py
@@ -228,8 +228,8 @@ def _json_dict_(self) -> Dict[str, Any]:
 
 # Duration dict in picoseconds
 _DURATIONS_FOR_XMON = {
-    'cz': 50_000,
-    'xy': 20_000,
+    'cz': 45_000,
+    'xy': 15_000,
     'z': 0,
     'meas': 4_000_000,  # 1000ns for readout, 3000ns for "ring down"
 }


Test patch:
diff --git a/cirq/google/devices/known_devices_test.py b/cirq/google/devices/known_devices_test.py
--- a/cirq/google/devices/known_devices_test.py
+++ b/cirq/google/devices/known_devices_test.py
@@ -43,7 +43,7 @@ def test_foxtail_device_proto():
       name: "half_turns"
       type: FLOAT
     }
-    gate_duration_picos: 20000
+    gate_duration_picos: 15000
   }
   valid_gates {
     id: "z"
@@ -80,7 +80,7 @@ def test_foxtail_device_proto():
       name: "half_turns"
       type: FLOAT
     }
-    gate_duration_picos: 50000
+    gate_duration_picos: 45000
     valid_targets: "2_qubit_targets"
   }
   valid_gates {
diff --git a/cirq/google/devices/serializable_device_test.py b/cirq/google/devices/serializable_device_test.py
--- a/cirq/google/devices/serializable_device_test.py
+++ b/cirq/google/devices/serializable_device_test.py
@@ -148,7 +148,7 @@ def test_duration_of():
         proto=cg.devices.known_devices.FOXTAIL_PROTO,
         gate_sets=[cg.gate_sets.XMON])
 
-    assert foxtail.duration_of(cirq.X(valid_qubit1)) == cirq.Duration(nanos=20)
+    assert foxtail.duration_of(cirq.X(valid_qubit1)) == cirq.Duration(nanos=15)
 
     # Unsupported op
     with pytest.raises(ValueError):
Repository: quantumlib/Cirq

Issue:
Module wrapping makes module members invisible to inspection
https://github.com/quantumlib/Cirq/pull/2808 introduced `wrap_module` in `_compat.py` and used it to wrap the module `cirq.sim` in order to deprecate `cirq.sim.STATE_VECTOR`. It has the unfortunate side effect of making the module members invisible to inspection. For instance:
```python
import inspect
import cirq

for name, obj in inspect.getmembers(cirq.sim):
    print(name)
```
gives
```
__doc__
__loader__
__name__
__package__
__spec__
```
which is missing all the members of `cirq.sim`. One problem that this causes is that `docs/docs_coverage_test.py` fails to access members of `cirq.sim` that are not exposed in `cirq`.


Discussion:

Resolving patch:
diff --git a/cirq/_compat.py b/cirq/_compat.py
--- a/cirq/_compat.py
+++ b/cirq/_compat.py
@@ -200,6 +200,8 @@ def wrap_module(module: ModuleType,
 
     class Wrapped(ModuleType):
 
+        __dict__ = module.__dict__
+
         def __getattr__(self, name):
             if name in deprecated_attributes:
                 deadline, fix = deprecated_attributes[name]


Test patch:
Repository: quantumlib/Cirq

Issue:
Why is cirq.VirtualTag not at top level
Currently you have to say `cirq.ops.VirtualTag`.  Is there a reason it doesn't appear at the top level as `cirq.VirtualTag`?


Discussion:

Resolving patch:
diff --git a/cirq/__init__.py b/cirq/__init__.py
--- a/cirq/__init__.py
+++ b/cirq/__init__.py
@@ -262,6 +262,7 @@
     transform_op_tree,
     TwoQubitDiagonalGate,
     TwoQubitGate,
+    VirtualTag,
     WaitGate,
     X,
     XPowGate,
diff --git a/cirq/ops/tags.py b/cirq/ops/tags.py
--- a/cirq/ops/tags.py
+++ b/cirq/ops/tags.py
@@ -12,9 +12,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 """Canonical tags for the TaggedOperation class."""
+from typing import Dict
 
 
-class VirtualTag():
+class VirtualTag:
     """A TaggedOperation tag indicating that the operation is virtual.
 
     Operations marked with this tag are presumed to have zero duration of their
@@ -29,4 +30,7 @@ def __str__(self) -> str:
         return '<virtual>'
 
     def __repr__(self) -> str:
-        return str(self)
+        return 'cirq.VirtualTag()'
+
+    def _json_dict_(self) -> Dict[str, str]:
+        return {'cirq_type': self.__class__.__name__}
diff --git a/cirq/protocols/json_serialization.py b/cirq/protocols/json_serialization.py
--- a/cirq/protocols/json_serialization.py
+++ b/cirq/protocols/json_serialization.py
@@ -147,6 +147,7 @@ def two_qubit_matrix_gate(matrix):
                 'TwoQubitDiagonalGate': cirq.TwoQubitDiagonalGate,
                 '_UnconstrainedDevice':
                 cirq.devices.unconstrained_device._UnconstrainedDevice,
+                'VirtualTag': cirq.VirtualTag,
                 'WaitGate': cirq.WaitGate,
                 '_QubitAsQid': raw_types._QubitAsQid,
                 'XPowGate': cirq.XPowGate,


Test patch:
diff --git a/cirq/ops/tags_test.py b/cirq/ops/tags_test.py
--- a/cirq/ops/tags_test.py
+++ b/cirq/ops/tags_test.py
@@ -20,4 +20,7 @@ def test_virtual_tag():
     tag2 = cirq.ops.VirtualTag()
 
     assert tag1 == tag2
-    assert repr(tag1) == repr(tag2) == '<virtual>'
+    assert str(tag1) == str(tag2) == '<virtual>'
+
+    cirq.testing.assert_equivalent_repr(tag1)
+    cirq.testing.assert_equivalent_repr(tag2)
diff --git a/cirq/protocols/json_test_data/VirtualTag.json b/cirq/protocols/json_test_data/VirtualTag.json
new file mode 100644
--- /dev/null
+++ b/cirq/protocols/json_test_data/VirtualTag.json
@@ -0,0 +1,3 @@
+{
+  "cirq_type": "VirtualTag"
+}
\ No newline at end of file
diff --git a/cirq/protocols/json_test_data/VirtualTag.repr b/cirq/protocols/json_test_data/VirtualTag.repr
new file mode 100644
--- /dev/null
+++ b/cirq/protocols/json_test_data/VirtualTag.repr
@@ -0,0 +1 @@
+cirq.VirtualTag()
\ No newline at end of file
Repository: quantumlib/Cirq

Issue:
Missing documentation for some cirq.linalg.* functions
`cirq.linalg.deconstruct_single_qubit_matrix_into_angles` in particular.  It is not exported to the top-level `cirq.*` namespace so maybe the documentation script is missing them?

In this case, `deconstruct_single_qubit_matrix_into_angles` should probably be added to `cirq/__init__.py` since the rest of `cirq.linalg` is there.


Discussion:
Where are you looking at the docs?  Readthedocs?  The build docs script output?
Readthedocs: https://cirq.readthedocs.io/en/stable/api.html#algebra-and-representation

These are the URLs where I might expect it to be:
https://cirq.readthedocs.io/en/stable/generated/cirq.deconstruct_single_qubit_matrix_into_angles.html
https://cirq.readthedocs.io/en/stable/generated/cirq.linalg.deconstruct_single_qubit_matrix_into_angles.html

Latest:
https://cirq.readthedocs.io/en/latest/generated/cirq.deconstruct_single_qubit_matrix_into_angles.html
https://cirq.readthedocs.io/en/latest/generated/cirq.linalg.deconstruct_single_qubit_matrix_into_angles.html
Yeah the doc coverage test only looks at a few namespaces for methods (`cirq`,`cirq.experiments`, `cirq.testing`, and `cirq.google`), so it would not fail if this were not at top level.  It would get generated by inclusion into the api.rst.  

Resolving patch:
diff --git a/cirq/__init__.py b/cirq/__init__.py
--- a/cirq/__init__.py
+++ b/cirq/__init__.py
@@ -117,6 +117,7 @@
     bidiagonalize_unitary_with_special_orthogonals,
     block_diag,
     CONTROL_TAG,
+    deconstruct_single_qubit_matrix_into_angles,
     diagonalize_real_symmetric_and_sorted_diagonal_matrices,
     diagonalize_real_symmetric_matrix,
     dot,
@@ -139,6 +140,7 @@
     kron_with_controls,
     map_eigenvalues,
     match_global_phase,
+    matrix_commutes,
     matrix_from_basis_coefficients,
     partial_trace,
     partial_trace_of_state_vector_as_mixture,
@@ -315,6 +317,7 @@
     STATE_VECTOR_LIKE,
     to_valid_density_matrix,
     to_valid_state_vector,
+    validate_indices,
     validate_normalized_state,
     validate_normalized_state_vector,
     validate_qid_shape,
@@ -379,6 +382,7 @@
     Sweepable,
     to_resolvers,
     to_sweep,
+    to_sweeps,
     TrialResult,
     UnitSweep,
     Zip,
@@ -479,6 +483,7 @@
     to_json,
     obj_to_dict_helper,
     trace_distance_bound,
+    trace_distance_from_angle_list,
     unitary,
     validate_mixture,
 )


Test patch:
Repository: quantumlib/Cirq

Issue:
Add matrix documentation for `class YYPowGate`
Should be similar to `class XXPowGate` https://github.com/quantumlib/Cirq/blob/329765a96ec98e5856ba95ff41dec58f1e110452/cirq/ops/parity_gates.py#L37


Discussion:
@vtomole Hi! Can I work on this?
@ishanrai05 Sure!!

Resolving patch:
diff --git a/cirq/ops/parity_gates.py b/cirq/ops/parity_gates.py
--- a/cirq/ops/parity_gates.py
+++ b/cirq/ops/parity_gates.py
@@ -32,15 +32,21 @@ class XXPowGate(eigen_gate.EigenGate,
                 gate_features.InterchangeableQubitsGate):
     """The X-parity gate, possibly raised to a power.
 
-    At exponent=1, this gate implements the following unitary:
+    The XX**t gate implements the following unitary:
 
-        X⊗X = [0 0 0 1]
-              [0 0 1 0]
-              [0 1 0 0]
-              [1 0 0 0]
+        (X⊗X)^t = [c . . s]
+                  [. c s .]
+                  [. s c .]
+                  [s . . c]
+
+    where '.' means '0' and
+
+        c = f cos(πt / 2)
+        s = -i f sin(πt / 2)
+        f = e^{iπt / 2}.
 
     See also: `cirq.MSGate` (the Mølmer–Sørensen gate), which is implemented via
-        this class.
+    this class.
     """
 
     def _eigen_components(self):
@@ -114,7 +120,21 @@ def __repr__(self) -> str:
 class YYPowGate(eigen_gate.EigenGate,
                 gate_features.TwoQubitGate,
                 gate_features.InterchangeableQubitsGate):
-    """The Y-parity gate, possibly raised to a power."""
+    """The Y-parity gate, possibly raised to a power.
+
+    The YY**t gate implements the following unitary:
+
+        (Y⊗Y)^t = [ c . . -s]
+                  [ . c s  .]
+                  [ . s c  .]
+                  [-s . .  c]
+
+    where '.' means '0' and
+
+        c = f cos(πt / 2)
+        s = -i f sin(πt / 2)
+        f = e^{iπt / 2}.
+    """
 
     def _eigen_components(self):
         return [
@@ -197,7 +217,7 @@ class ZZPowGate(eigen_gate.EigenGate,
                   [. . w .]
                   [. . . 1]
 
-        where w = e^{i \pi t} and '.' means '0'.
+    where w = e^{iπt} and '.' means '0'.
     """
 
     def _decompose_(self, qubits):


Test patch: