cirq-core 1.6.0.dev20250416035400__py3-none-any.whl → 1.6.0.dev20250417204649__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cirq-core might be problematic. Click here for more details.
- cirq/_version.py +1 -1
- cirq/_version_test.py +1 -1
- cirq/devices/noise_model_test.py +3 -1
- cirq/devices/noise_properties.py +6 -4
- cirq/devices/noise_utils.py +8 -6
- cirq/devices/superconducting_qubits_noise_properties.py +10 -9
- cirq/devices/thermal_noise_model.py +12 -12
- cirq/devices/unconstrained_device.py +3 -1
- cirq/experiments/n_qubit_tomography.py +15 -12
- cirq/experiments/qubit_characterizations.py +34 -39
- cirq/experiments/random_quantum_circuit_generation.py +38 -38
- cirq/experiments/random_quantum_circuit_generation_test.py +7 -4
- cirq/experiments/readout_confusion_matrix.py +17 -15
- cirq/experiments/single_qubit_readout_calibration.py +9 -5
- cirq/experiments/single_qubit_readout_calibration_test.py +5 -2
- cirq/experiments/t1_decay_experiment.py +7 -5
- cirq/experiments/t2_decay_experiment.py +10 -7
- cirq/experiments/two_qubit_xeb.py +42 -43
- cirq/experiments/two_qubit_xeb_test.py +1 -1
- cirq/experiments/xeb_fitting.py +25 -21
- cirq/experiments/xeb_sampling.py +18 -14
- cirq/experiments/xeb_simulation.py +11 -7
- cirq/experiments/xeb_simulation_test.py +3 -3
- cirq/experiments/z_phase_calibration.py +27 -24
- cirq/experiments/z_phase_calibration_test.py +1 -4
- cirq/interop/quirk/cells/arithmetic_cells.py +11 -10
- cirq/interop/quirk/cells/cell.py +18 -15
- cirq/interop/quirk/cells/composite_cell.py +8 -8
- cirq/interop/quirk/cells/control_cells.py +14 -14
- cirq/interop/quirk/cells/frequency_space_cells.py +4 -3
- cirq/interop/quirk/cells/input_cells.py +6 -4
- cirq/interop/quirk/cells/input_rotation_cells.py +14 -12
- cirq/interop/quirk/cells/measurement_cells.py +4 -1
- cirq/interop/quirk/cells/qubit_permutation_cells.py +3 -1
- cirq/interop/quirk/cells/scalar_cells.py +4 -1
- cirq/interop/quirk/cells/single_qubit_rotation_cells.py +5 -2
- cirq/interop/quirk/cells/swap_cell.py +7 -5
- cirq/interop/quirk/cells/testing.py +1 -1
- cirq/interop/quirk/url_to_circuit.py +11 -8
- cirq/json_resolver_cache.py +5 -3
- cirq/linalg/decompositions.py +5 -4
- cirq/linalg/decompositions_test.py +1 -1
- cirq/linalg/operator_spaces.py +8 -8
- cirq/ops/arithmetic_operation.py +4 -2
- cirq/ops/boolean_hamiltonian.py +7 -6
- cirq/ops/classically_controlled_operation.py +23 -20
- cirq/ops/clifford_gate.py +43 -47
- cirq/ops/common_channels.py +16 -14
- cirq/ops/common_gates.py +49 -67
- cirq/ops/control_values.py +12 -15
- cirq/ops/controlled_gate.py +15 -17
- cirq/ops/controlled_operation.py +17 -15
- cirq/study/resolver.py +1 -1
- {cirq_core-1.6.0.dev20250416035400.dist-info → cirq_core-1.6.0.dev20250417204649.dist-info}/METADATA +1 -1
- {cirq_core-1.6.0.dev20250416035400.dist-info → cirq_core-1.6.0.dev20250417204649.dist-info}/RECORD +58 -58
- {cirq_core-1.6.0.dev20250416035400.dist-info → cirq_core-1.6.0.dev20250417204649.dist-info}/WHEEL +0 -0
- {cirq_core-1.6.0.dev20250416035400.dist-info → cirq_core-1.6.0.dev20250417204649.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.6.0.dev20250416035400.dist-info → cirq_core-1.6.0.dev20250417204649.dist-info}/top_level.txt +0 -0
cirq/ops/common_gates.py
CHANGED
|
@@ -25,19 +25,10 @@ Each of these are implemented as EigenGates, which means that they can be
|
|
|
25
25
|
raised to a power (i.e. cirq.H**0.5). See the definition in EigenGate.
|
|
26
26
|
"""
|
|
27
27
|
|
|
28
|
+
from __future__ import annotations
|
|
29
|
+
|
|
28
30
|
from types import NotImplementedType
|
|
29
|
-
from typing import
|
|
30
|
-
Any,
|
|
31
|
-
cast,
|
|
32
|
-
Collection,
|
|
33
|
-
Dict,
|
|
34
|
-
List,
|
|
35
|
-
Optional,
|
|
36
|
-
Sequence,
|
|
37
|
-
Tuple,
|
|
38
|
-
TYPE_CHECKING,
|
|
39
|
-
Union,
|
|
40
|
-
)
|
|
31
|
+
from typing import Any, cast, Collection, Dict, List, Optional, Sequence, Tuple, Union
|
|
41
32
|
|
|
42
33
|
import numpy as np
|
|
43
34
|
import sympy
|
|
@@ -50,9 +41,6 @@ from cirq.ops import control_values as cv, controlled_gate, eigen_gate, gate_fea
|
|
|
50
41
|
from cirq.ops.measurement_gate import MeasurementGate
|
|
51
42
|
from cirq.ops.swap_gates import ISWAP, ISwapPowGate, SWAP, SwapPowGate
|
|
52
43
|
|
|
53
|
-
if TYPE_CHECKING:
|
|
54
|
-
import cirq
|
|
55
|
-
|
|
56
44
|
assert all(
|
|
57
45
|
[ISWAP, SWAP, ISwapPowGate, SwapPowGate, MeasurementGate]
|
|
58
46
|
), """
|
|
@@ -126,7 +114,7 @@ class XPowGate(eigen_gate.EigenGate):
|
|
|
126
114
|
def _num_qubits_(self) -> int:
|
|
127
115
|
return 1
|
|
128
116
|
|
|
129
|
-
def _apply_unitary_(self, args:
|
|
117
|
+
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> Optional[np.ndarray]:
|
|
130
118
|
if self._exponent != 1 or self._dimension != 2:
|
|
131
119
|
return NotImplemented
|
|
132
120
|
zero = args.subspace_index(0)
|
|
@@ -138,11 +126,11 @@ class XPowGate(eigen_gate.EigenGate):
|
|
|
138
126
|
args.available_buffer *= p
|
|
139
127
|
return args.available_buffer
|
|
140
128
|
|
|
141
|
-
def in_su2(self) ->
|
|
129
|
+
def in_su2(self) -> Rx:
|
|
142
130
|
"""Returns an equal-up-global-phase gate from the group SU2."""
|
|
143
131
|
return Rx(rads=self._exponent * _pi(self._exponent))
|
|
144
132
|
|
|
145
|
-
def with_canonical_global_phase(self) ->
|
|
133
|
+
def with_canonical_global_phase(self) -> XPowGate:
|
|
146
134
|
"""Returns an equal-up-global-phase standardized form of the gate."""
|
|
147
135
|
return XPowGate(exponent=self._exponent, dimension=self._dimension)
|
|
148
136
|
|
|
@@ -161,7 +149,7 @@ class XPowGate(eigen_gate.EigenGate):
|
|
|
161
149
|
XPowGate._eigencomponents[self._dimension] = components
|
|
162
150
|
return XPowGate._eigencomponents[self._dimension]
|
|
163
151
|
|
|
164
|
-
def _with_exponent(self, exponent:
|
|
152
|
+
def _with_exponent(self, exponent: cirq.TParamVal) -> cirq.XPowGate:
|
|
165
153
|
return XPowGate(
|
|
166
154
|
exponent=exponent, global_shift=self._global_shift, dimension=self._dimension
|
|
167
155
|
)
|
|
@@ -266,13 +254,13 @@ class XPowGate(eigen_gate.EigenGate):
|
|
|
266
254
|
return value.LinearDict({'I': phase * lib.cos(angle), 'X': -1j * phase * lib.sin(angle)})
|
|
267
255
|
|
|
268
256
|
def _circuit_diagram_info_(
|
|
269
|
-
self, args:
|
|
270
|
-
) -> Union[str,
|
|
257
|
+
self, args: cirq.CircuitDiagramInfoArgs
|
|
258
|
+
) -> Union[str, protocols.CircuitDiagramInfo]:
|
|
271
259
|
return protocols.CircuitDiagramInfo(
|
|
272
260
|
wire_symbols=('X',), exponent=self._diagram_exponent(args)
|
|
273
261
|
)
|
|
274
262
|
|
|
275
|
-
def _qasm_(self, args:
|
|
263
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
|
|
276
264
|
args.validate_version('2.0', '3.0')
|
|
277
265
|
if self._global_shift == 0:
|
|
278
266
|
if self._exponent == 1:
|
|
@@ -349,12 +337,12 @@ class Rx(XPowGate):
|
|
|
349
337
|
self._rads = rads
|
|
350
338
|
super().__init__(exponent=rads / _pi(rads), global_shift=-0.5)
|
|
351
339
|
|
|
352
|
-
def _with_exponent(self, exponent: value.TParamVal) ->
|
|
340
|
+
def _with_exponent(self, exponent: value.TParamVal) -> Rx:
|
|
353
341
|
return Rx(rads=exponent * _pi(exponent))
|
|
354
342
|
|
|
355
343
|
def _circuit_diagram_info_(
|
|
356
|
-
self, args:
|
|
357
|
-
) -> Union[str,
|
|
344
|
+
self, args: cirq.CircuitDiagramInfoArgs
|
|
345
|
+
) -> Union[str, protocols.CircuitDiagramInfo]:
|
|
358
346
|
angle_str = self._format_exponent_as_angle(args)
|
|
359
347
|
return f'Rx({angle_str})'
|
|
360
348
|
|
|
@@ -366,7 +354,7 @@ class Rx(XPowGate):
|
|
|
366
354
|
def __repr__(self) -> str:
|
|
367
355
|
return f'cirq.Rx(rads={proper_repr(self._rads)})'
|
|
368
356
|
|
|
369
|
-
def _qasm_(self, args:
|
|
357
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
|
|
370
358
|
args.validate_version('2.0', '3.0')
|
|
371
359
|
return args.format('rx({0:half_turns}) {1};\n', self._exponent, qubits[0])
|
|
372
360
|
|
|
@@ -374,7 +362,7 @@ class Rx(XPowGate):
|
|
|
374
362
|
return {'rads': self._rads}
|
|
375
363
|
|
|
376
364
|
@classmethod
|
|
377
|
-
def _from_json_dict_(cls, rads, **kwargs) ->
|
|
365
|
+
def _from_json_dict_(cls, rads, **kwargs) -> Rx:
|
|
378
366
|
return cls(rads=rads)
|
|
379
367
|
|
|
380
368
|
|
|
@@ -412,7 +400,7 @@ class YPowGate(eigen_gate.EigenGate):
|
|
|
412
400
|
def _num_qubits_(self) -> int:
|
|
413
401
|
return 1
|
|
414
402
|
|
|
415
|
-
def _apply_unitary_(self, args:
|
|
403
|
+
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> Optional[np.ndarray]:
|
|
416
404
|
if self._exponent != 1:
|
|
417
405
|
return NotImplemented
|
|
418
406
|
zero = args.subspace_index(0)
|
|
@@ -424,11 +412,11 @@ class YPowGate(eigen_gate.EigenGate):
|
|
|
424
412
|
args.available_buffer *= p
|
|
425
413
|
return args.available_buffer
|
|
426
414
|
|
|
427
|
-
def in_su2(self) ->
|
|
415
|
+
def in_su2(self) -> Ry:
|
|
428
416
|
"""Returns an equal-up-global-phase gate from the group SU2."""
|
|
429
417
|
return Ry(rads=self._exponent * _pi(self._exponent))
|
|
430
418
|
|
|
431
|
-
def with_canonical_global_phase(self) ->
|
|
419
|
+
def with_canonical_global_phase(self) -> YPowGate:
|
|
432
420
|
"""Returns an equal-up-global-phase standardized form of the gate."""
|
|
433
421
|
return YPowGate(exponent=self._exponent)
|
|
434
422
|
|
|
@@ -463,13 +451,13 @@ class YPowGate(eigen_gate.EigenGate):
|
|
|
463
451
|
return value.LinearDict({'I': phase * lib.cos(angle), 'Y': -1j * phase * lib.sin(angle)})
|
|
464
452
|
|
|
465
453
|
def _circuit_diagram_info_(
|
|
466
|
-
self, args:
|
|
467
|
-
) -> Union[str,
|
|
454
|
+
self, args: cirq.CircuitDiagramInfoArgs
|
|
455
|
+
) -> Union[str, protocols.CircuitDiagramInfo]:
|
|
468
456
|
return protocols.CircuitDiagramInfo(
|
|
469
457
|
wire_symbols=('Y',), exponent=self._diagram_exponent(args)
|
|
470
458
|
)
|
|
471
459
|
|
|
472
|
-
def _qasm_(self, args:
|
|
460
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
|
|
473
461
|
args.validate_version('2.0', '3.0')
|
|
474
462
|
if self._exponent == 1 and self.global_shift != -0.5:
|
|
475
463
|
return args.format('y {0};\n', qubits[0])
|
|
@@ -534,12 +522,12 @@ class Ry(YPowGate):
|
|
|
534
522
|
self._rads = rads
|
|
535
523
|
super().__init__(exponent=rads / _pi(rads), global_shift=-0.5)
|
|
536
524
|
|
|
537
|
-
def _with_exponent(self, exponent: value.TParamVal) ->
|
|
525
|
+
def _with_exponent(self, exponent: value.TParamVal) -> Ry:
|
|
538
526
|
return Ry(rads=exponent * _pi(exponent))
|
|
539
527
|
|
|
540
528
|
def _circuit_diagram_info_(
|
|
541
|
-
self, args:
|
|
542
|
-
) -> Union[str,
|
|
529
|
+
self, args: cirq.CircuitDiagramInfoArgs
|
|
530
|
+
) -> Union[str, protocols.CircuitDiagramInfo]:
|
|
543
531
|
angle_str = self._format_exponent_as_angle(args)
|
|
544
532
|
return f'Ry({angle_str})'
|
|
545
533
|
|
|
@@ -551,7 +539,7 @@ class Ry(YPowGate):
|
|
|
551
539
|
def __repr__(self) -> str:
|
|
552
540
|
return f'cirq.Ry(rads={proper_repr(self._rads)})'
|
|
553
541
|
|
|
554
|
-
def _qasm_(self, args:
|
|
542
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
|
|
555
543
|
args.validate_version('2.0', '3.0')
|
|
556
544
|
return args.format('ry({0:half_turns}) {1};\n', self._exponent, qubits[0])
|
|
557
545
|
|
|
@@ -559,7 +547,7 @@ class Ry(YPowGate):
|
|
|
559
547
|
return {'rads': self._rads}
|
|
560
548
|
|
|
561
549
|
@classmethod
|
|
562
|
-
def _from_json_dict_(cls, rads, **kwargs) ->
|
|
550
|
+
def _from_json_dict_(cls, rads, **kwargs) -> Ry:
|
|
563
551
|
return cls(rads=rads)
|
|
564
552
|
|
|
565
553
|
|
|
@@ -624,7 +612,7 @@ class ZPowGate(eigen_gate.EigenGate):
|
|
|
624
612
|
def _num_qubits_(self) -> int:
|
|
625
613
|
return 1
|
|
626
614
|
|
|
627
|
-
def _apply_unitary_(self, args:
|
|
615
|
+
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> Optional[np.ndarray]:
|
|
628
616
|
if protocols.is_parameterized(self):
|
|
629
617
|
return None
|
|
630
618
|
|
|
@@ -650,11 +638,11 @@ class ZPowGate(eigen_gate.EigenGate):
|
|
|
650
638
|
return SingleQubitCliffordGate.Z_nsqrt.on(*qubits)
|
|
651
639
|
return NotImplemented # pragma: no cover
|
|
652
640
|
|
|
653
|
-
def in_su2(self) ->
|
|
641
|
+
def in_su2(self) -> Rz:
|
|
654
642
|
"""Returns an equal-up-global-phase gate from the group SU2."""
|
|
655
643
|
return Rz(rads=self._exponent * _pi(self._exponent))
|
|
656
644
|
|
|
657
|
-
def with_canonical_global_phase(self) ->
|
|
645
|
+
def with_canonical_global_phase(self) -> ZPowGate:
|
|
658
646
|
"""Returns an equal-up-global-phase standardized form of the gate."""
|
|
659
647
|
return ZPowGate(exponent=self._exponent, dimension=self._dimension)
|
|
660
648
|
|
|
@@ -745,7 +733,7 @@ class ZPowGate(eigen_gate.EigenGate):
|
|
|
745
733
|
ZPowGate._eigencomponents[self._dimension] = components
|
|
746
734
|
return ZPowGate._eigencomponents[self._dimension]
|
|
747
735
|
|
|
748
|
-
def _with_exponent(self, exponent:
|
|
736
|
+
def _with_exponent(self, exponent: cirq.TParamVal) -> cirq.ZPowGate:
|
|
749
737
|
return ZPowGate(
|
|
750
738
|
exponent=exponent, global_shift=self._global_shift, dimension=self._dimension
|
|
751
739
|
)
|
|
@@ -772,8 +760,8 @@ class ZPowGate(eigen_gate.EigenGate):
|
|
|
772
760
|
return self.exponent % 0.5 == 0
|
|
773
761
|
|
|
774
762
|
def _circuit_diagram_info_(
|
|
775
|
-
self, args:
|
|
776
|
-
) -> Union[str,
|
|
763
|
+
self, args: cirq.CircuitDiagramInfoArgs
|
|
764
|
+
) -> Union[str, protocols.CircuitDiagramInfo]:
|
|
777
765
|
e = self._diagram_exponent(args)
|
|
778
766
|
if e in [-0.25, 0.25]:
|
|
779
767
|
return protocols.CircuitDiagramInfo(wire_symbols=('T',), exponent=cast(float, e) * 4)
|
|
@@ -783,7 +771,7 @@ class ZPowGate(eigen_gate.EigenGate):
|
|
|
783
771
|
|
|
784
772
|
return protocols.CircuitDiagramInfo(wire_symbols=('Z',), exponent=e)
|
|
785
773
|
|
|
786
|
-
def _qasm_(self, args:
|
|
774
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
|
|
787
775
|
args.validate_version('2.0', '3.0')
|
|
788
776
|
|
|
789
777
|
if self.global_shift == 0:
|
|
@@ -838,7 +826,7 @@ class ZPowGate(eigen_gate.EigenGate):
|
|
|
838
826
|
return f'cirq.ZPowGate({all_args})'
|
|
839
827
|
|
|
840
828
|
def _commutes_on_qids_(
|
|
841
|
-
self, qids:
|
|
829
|
+
self, qids: Sequence[cirq.Qid], other: Any, *, atol: float = 1e-8
|
|
842
830
|
) -> Union[bool, NotImplementedType, None]:
|
|
843
831
|
from cirq.ops.parity_gates import ZZPowGate
|
|
844
832
|
|
|
@@ -879,12 +867,12 @@ class Rz(ZPowGate):
|
|
|
879
867
|
self._rads = rads
|
|
880
868
|
super().__init__(exponent=rads / _pi(rads), global_shift=-0.5)
|
|
881
869
|
|
|
882
|
-
def _with_exponent(self, exponent: value.TParamVal) ->
|
|
870
|
+
def _with_exponent(self, exponent: value.TParamVal) -> Rz:
|
|
883
871
|
return Rz(rads=exponent * _pi(exponent))
|
|
884
872
|
|
|
885
873
|
def _circuit_diagram_info_(
|
|
886
|
-
self, args:
|
|
887
|
-
) -> Union[str,
|
|
874
|
+
self, args: cirq.CircuitDiagramInfoArgs
|
|
875
|
+
) -> Union[str, protocols.CircuitDiagramInfo]:
|
|
888
876
|
angle_str = self._format_exponent_as_angle(args)
|
|
889
877
|
return f'Rz({angle_str})'
|
|
890
878
|
|
|
@@ -896,7 +884,7 @@ class Rz(ZPowGate):
|
|
|
896
884
|
def __repr__(self) -> str:
|
|
897
885
|
return f'cirq.Rz(rads={proper_repr(self._rads)})'
|
|
898
886
|
|
|
899
|
-
def _qasm_(self, args:
|
|
887
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
|
|
900
888
|
args.validate_version('2.0', '3.0')
|
|
901
889
|
return args.format('rz({0:half_turns}) {1};\n', self._exponent, qubits[0])
|
|
902
890
|
|
|
@@ -904,7 +892,7 @@ class Rz(ZPowGate):
|
|
|
904
892
|
return {'rads': self._rads}
|
|
905
893
|
|
|
906
894
|
@classmethod
|
|
907
|
-
def _from_json_dict_(cls, rads, **kwargs) ->
|
|
895
|
+
def _from_json_dict_(cls, rads, **kwargs) -> Rz:
|
|
908
896
|
return cls(rads=rads)
|
|
909
897
|
|
|
910
898
|
|
|
@@ -970,7 +958,7 @@ class HPowGate(eigen_gate.EigenGate):
|
|
|
970
958
|
return []
|
|
971
959
|
return NotImplemented # pragma: no cover
|
|
972
960
|
|
|
973
|
-
def _apply_unitary_(self, args:
|
|
961
|
+
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> Optional[np.ndarray]:
|
|
974
962
|
if self._exponent != 1:
|
|
975
963
|
return NotImplemented
|
|
976
964
|
|
|
@@ -995,14 +983,12 @@ class HPowGate(eigen_gate.EigenGate):
|
|
|
995
983
|
yield XPowGate(exponent=self._exponent, global_shift=self.global_shift).on(q)
|
|
996
984
|
yield YPowGate(exponent=-0.25).on(q)
|
|
997
985
|
|
|
998
|
-
def _circuit_diagram_info_(
|
|
999
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
1000
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
986
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
1001
987
|
return protocols.CircuitDiagramInfo(
|
|
1002
988
|
wire_symbols=('H',), exponent=self._diagram_exponent(args)
|
|
1003
989
|
)
|
|
1004
990
|
|
|
1005
|
-
def _qasm_(self, args:
|
|
991
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
|
|
1006
992
|
args.validate_version('2.0', '3.0')
|
|
1007
993
|
if self._exponent == 0:
|
|
1008
994
|
return args.format('id {0};\n', qubits[0])
|
|
@@ -1077,7 +1063,7 @@ class CZPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
1077
1063
|
return abs(np.sin(self._exponent * 0.5 * np.pi))
|
|
1078
1064
|
|
|
1079
1065
|
def _apply_unitary_(
|
|
1080
|
-
self, args:
|
|
1066
|
+
self, args: protocols.ApplyUnitaryArgs
|
|
1081
1067
|
) -> Union[np.ndarray, NotImplementedType]:
|
|
1082
1068
|
if protocols.is_parameterized(self):
|
|
1083
1069
|
return NotImplemented
|
|
@@ -1181,14 +1167,12 @@ class CZPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
1181
1167
|
)
|
|
1182
1168
|
return result
|
|
1183
1169
|
|
|
1184
|
-
def _circuit_diagram_info_(
|
|
1185
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
1186
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
1170
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
1187
1171
|
return protocols.CircuitDiagramInfo(
|
|
1188
1172
|
wire_symbols=('@', '@'), exponent=self._diagram_exponent(args)
|
|
1189
1173
|
)
|
|
1190
1174
|
|
|
1191
|
-
def _qasm_(self, args:
|
|
1175
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
|
|
1192
1176
|
if self._exponent != 1:
|
|
1193
1177
|
return None # Don't have an equivalent gate in QASM
|
|
1194
1178
|
args.validate_version('2.0', '3.0')
|
|
@@ -1280,14 +1264,12 @@ class CXPowGate(eigen_gate.EigenGate):
|
|
|
1280
1264
|
return None
|
|
1281
1265
|
return abs(np.sin(self._exponent * 0.5 * np.pi))
|
|
1282
1266
|
|
|
1283
|
-
def _circuit_diagram_info_(
|
|
1284
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
1285
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
1267
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
1286
1268
|
return protocols.CircuitDiagramInfo(
|
|
1287
1269
|
wire_symbols=('@', 'X'), exponent=self._diagram_exponent(args), exponent_qubit_index=1
|
|
1288
1270
|
)
|
|
1289
1271
|
|
|
1290
|
-
def _apply_unitary_(self, args:
|
|
1272
|
+
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> Optional[np.ndarray]:
|
|
1291
1273
|
if self._exponent != 1:
|
|
1292
1274
|
return NotImplemented
|
|
1293
1275
|
|
|
@@ -1389,7 +1371,7 @@ class CXPowGate(eigen_gate.EigenGate):
|
|
|
1389
1371
|
)
|
|
1390
1372
|
return result
|
|
1391
1373
|
|
|
1392
|
-
def _qasm_(self, args:
|
|
1374
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
|
|
1393
1375
|
if self._exponent != 1:
|
|
1394
1376
|
return None # Don't have an equivalent gate in QASM
|
|
1395
1377
|
args.validate_version('2.0', '3.0')
|
|
@@ -1544,7 +1526,7 @@ document(
|
|
|
1544
1526
|
|
|
1545
1527
|
def _phased_x_or_pauli_gate(
|
|
1546
1528
|
exponent: Union[float, sympy.Expr], phase_exponent: Union[float, sympy.Expr]
|
|
1547
|
-
) -> Union[
|
|
1529
|
+
) -> Union[cirq.PhasedXPowGate, cirq.XPowGate, cirq.YPowGate]:
|
|
1548
1530
|
"""Return PhasedXPowGate or X or Y gate if equivalent at the given phase_exponent."""
|
|
1549
1531
|
if not isinstance(phase_exponent, sympy.Expr) or phase_exponent.is_constant():
|
|
1550
1532
|
half_turns = value.canonicalize_half_turns(float(phase_exponent))
|
cirq/ops/control_values.py
CHANGED
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
14
17
|
import abc
|
|
15
18
|
import itertools
|
|
16
19
|
from functools import cached_property
|
|
@@ -47,7 +50,7 @@ class AbstractControlValues(abc.ABC):
|
|
|
47
50
|
"""Validates that all control values for ith qubit are in range [0, qid_shaped[i])"""
|
|
48
51
|
|
|
49
52
|
@abc.abstractmethod
|
|
50
|
-
def expand(self) ->
|
|
53
|
+
def expand(self) -> SumOfProducts:
|
|
51
54
|
"""Returns an expanded `cirq.SumOfProduct` representation of this control values."""
|
|
52
55
|
|
|
53
56
|
@property
|
|
@@ -68,9 +71,7 @@ class AbstractControlValues(abc.ABC):
|
|
|
68
71
|
"""Returns a dictionary used for serializing this object."""
|
|
69
72
|
|
|
70
73
|
@abc.abstractmethod
|
|
71
|
-
def _circuit_diagram_info_(
|
|
72
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
73
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
74
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
74
75
|
"""Returns information used to draw this object in circuit diagrams."""
|
|
75
76
|
|
|
76
77
|
@abc.abstractmethod
|
|
@@ -88,7 +89,7 @@ class AbstractControlValues(abc.ABC):
|
|
|
88
89
|
def _value_equality_values_(self) -> Any:
|
|
89
90
|
return tuple(v for v in self.expand())
|
|
90
91
|
|
|
91
|
-
def __and__(self, other:
|
|
92
|
+
def __and__(self, other: AbstractControlValues) -> AbstractControlValues:
|
|
92
93
|
"""Returns a cartesian product of all control values predicates in `self` x `other`.
|
|
93
94
|
|
|
94
95
|
The `and` of two control values `cv1` and `cv2` represents a control value object
|
|
@@ -109,7 +110,7 @@ class AbstractControlValues(abc.ABC):
|
|
|
109
110
|
tuple(x + y for (x, y) in itertools.product(self.expand(), other.expand()))
|
|
110
111
|
)
|
|
111
112
|
|
|
112
|
-
def __or__(self, other:
|
|
113
|
+
def __or__(self, other: AbstractControlValues) -> AbstractControlValues:
|
|
113
114
|
"""Returns a union of all control values predicates in `self` + `other`.
|
|
114
115
|
|
|
115
116
|
Both `self` and `other` must represent control values for the same set of qubits and
|
|
@@ -152,7 +153,7 @@ class ProductOfSums(AbstractControlValues):
|
|
|
152
153
|
def __iter__(self) -> Iterator[Tuple[int, ...]]:
|
|
153
154
|
return iter(self._qubit_sums)
|
|
154
155
|
|
|
155
|
-
def expand(self) ->
|
|
156
|
+
def expand(self) -> SumOfProducts:
|
|
156
157
|
return SumOfProducts(tuple(itertools.product(*self._qubit_sums)))
|
|
157
158
|
|
|
158
159
|
def __repr__(self) -> str:
|
|
@@ -161,7 +162,7 @@ class ProductOfSums(AbstractControlValues):
|
|
|
161
162
|
def _num_qubits_(self) -> int:
|
|
162
163
|
return len(self._qubit_sums)
|
|
163
164
|
|
|
164
|
-
def __getitem__(self, key: Union[int, slice]) -> Union[
|
|
165
|
+
def __getitem__(self, key: Union[int, slice]) -> Union[ProductOfSums, Tuple[int, ...]]:
|
|
165
166
|
if isinstance(key, slice):
|
|
166
167
|
return ProductOfSums(self._qubit_sums[key])
|
|
167
168
|
return self._qubit_sums[key]
|
|
@@ -175,9 +176,7 @@ class ProductOfSums(AbstractControlValues):
|
|
|
175
176
|
)
|
|
176
177
|
raise ValueError(message)
|
|
177
178
|
|
|
178
|
-
def _circuit_diagram_info_(
|
|
179
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
180
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
179
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
181
180
|
"""Returns a string representation to be used in circuit diagrams."""
|
|
182
181
|
|
|
183
182
|
def get_symbol(vals):
|
|
@@ -257,16 +256,14 @@ class SumOfProducts(AbstractControlValues):
|
|
|
257
256
|
def is_trivial(self) -> bool:
|
|
258
257
|
return self._conjunctions == ((1,) * self._num_qubits_(),)
|
|
259
258
|
|
|
260
|
-
def expand(self) ->
|
|
259
|
+
def expand(self) -> SumOfProducts:
|
|
261
260
|
return self
|
|
262
261
|
|
|
263
262
|
def __iter__(self) -> Iterator[Tuple[int, ...]]:
|
|
264
263
|
"""Returns the combinations tracked by the object."""
|
|
265
264
|
return iter(self._conjunctions)
|
|
266
265
|
|
|
267
|
-
def _circuit_diagram_info_(
|
|
268
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
269
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
266
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
270
267
|
"""Returns a string representation to be used in circuit diagrams."""
|
|
271
268
|
if self._name is not None:
|
|
272
269
|
wire_symbols = ['@'] * self._num_qubits_()
|
cirq/ops/controlled_gate.py
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
from types import NotImplementedType
|
|
16
18
|
from typing import (
|
|
17
19
|
AbstractSet,
|
|
@@ -57,7 +59,7 @@ class ControlledGate(raw_types.Gate):
|
|
|
57
59
|
|
|
58
60
|
def __init__(
|
|
59
61
|
self,
|
|
60
|
-
sub_gate:
|
|
62
|
+
sub_gate: cirq.Gate,
|
|
61
63
|
num_controls: Optional[int] = None,
|
|
62
64
|
control_values: Optional[
|
|
63
65
|
Union[cv.AbstractControlValues, Sequence[Union[int, Collection[int]]]]
|
|
@@ -141,7 +143,7 @@ class ControlledGate(raw_types.Gate):
|
|
|
141
143
|
return self._control_values
|
|
142
144
|
|
|
143
145
|
@property
|
|
144
|
-
def sub_gate(self) ->
|
|
146
|
+
def sub_gate(self) -> cirq.Gate:
|
|
145
147
|
return self._sub_gate
|
|
146
148
|
|
|
147
149
|
def num_controls(self) -> int:
|
|
@@ -151,13 +153,13 @@ class ControlledGate(raw_types.Gate):
|
|
|
151
153
|
return self.control_qid_shape + protocols.qid_shape(self.sub_gate)
|
|
152
154
|
|
|
153
155
|
def _decompose_(
|
|
154
|
-
self, qubits: Tuple[
|
|
155
|
-
) -> Union[None, NotImplementedType,
|
|
156
|
+
self, qubits: Tuple[cirq.Qid, ...]
|
|
157
|
+
) -> Union[None, NotImplementedType, cirq.OP_TREE]:
|
|
156
158
|
return self._decompose_with_context_(qubits)
|
|
157
159
|
|
|
158
160
|
def _decompose_with_context_(
|
|
159
|
-
self, qubits: Tuple[
|
|
160
|
-
) -> Union[None, NotImplementedType,
|
|
161
|
+
self, qubits: Tuple[cirq.Qid, ...], context: Optional[cirq.DecompositionContext] = None
|
|
162
|
+
) -> Union[None, NotImplementedType, cirq.OP_TREE]:
|
|
161
163
|
control_qubits = list(qubits[: self.num_controls()])
|
|
162
164
|
if (
|
|
163
165
|
protocols.has_unitary(self.sub_gate)
|
|
@@ -165,7 +167,7 @@ class ControlledGate(raw_types.Gate):
|
|
|
165
167
|
and self._qid_shape_() == (2,) * len(self._qid_shape_())
|
|
166
168
|
and isinstance(self.control_values, cv.ProductOfSums)
|
|
167
169
|
):
|
|
168
|
-
invert_ops: List[
|
|
170
|
+
invert_ops: List[cirq.Operation] = []
|
|
169
171
|
for cvals, cqbit in zip(self.control_values, qubits[: self.num_controls()]):
|
|
170
172
|
if set(cvals) == {0}:
|
|
171
173
|
invert_ops.append(common_gates.X(cqbit))
|
|
@@ -236,7 +238,7 @@ class ControlledGate(raw_types.Gate):
|
|
|
236
238
|
),
|
|
237
239
|
)
|
|
238
240
|
|
|
239
|
-
def on(self, *qubits:
|
|
241
|
+
def on(self, *qubits: cirq.Qid) -> cop.ControlledOperation:
|
|
240
242
|
if len(qubits) == 0:
|
|
241
243
|
raise ValueError(f"Applied a gate to an empty set of qubits. Gate: {self!r}")
|
|
242
244
|
self.validate_args(qubits)
|
|
@@ -249,7 +251,7 @@ class ControlledGate(raw_types.Gate):
|
|
|
249
251
|
def _value_equality_values_(self):
|
|
250
252
|
return (self.sub_gate, self.num_controls(), self.control_values, self.control_qid_shape)
|
|
251
253
|
|
|
252
|
-
def _apply_unitary_(self, args:
|
|
254
|
+
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> np.ndarray:
|
|
253
255
|
qubits = line_qubit.LineQid.for_gate(self)
|
|
254
256
|
op = self.sub_gate.on(*qubits[self.num_controls() :])
|
|
255
257
|
c_op = cop.ControlledOperation(qubits[: self.num_controls()], op, self.control_values)
|
|
@@ -274,7 +276,7 @@ class ControlledGate(raw_types.Gate):
|
|
|
274
276
|
c_op = cop.ControlledOperation(qubits[: self.num_controls()], op, self.control_values)
|
|
275
277
|
return protocols.mixture(c_op, default=NotImplemented)
|
|
276
278
|
|
|
277
|
-
def __pow__(self, exponent: Any) ->
|
|
279
|
+
def __pow__(self, exponent: Any) -> ControlledGate:
|
|
278
280
|
new_sub_gate = protocols.pow(self.sub_gate, exponent, NotImplemented)
|
|
279
281
|
if new_sub_gate is NotImplemented:
|
|
280
282
|
return NotImplemented
|
|
@@ -291,9 +293,7 @@ class ControlledGate(raw_types.Gate):
|
|
|
291
293
|
def _parameter_names_(self) -> AbstractSet[str]:
|
|
292
294
|
return protocols.parameter_names(self.sub_gate)
|
|
293
295
|
|
|
294
|
-
def _resolve_parameters_(
|
|
295
|
-
self, resolver: 'cirq.ParamResolver', recursive: bool
|
|
296
|
-
) -> 'ControlledGate':
|
|
296
|
+
def _resolve_parameters_(self, resolver: cirq.ParamResolver, recursive: bool) -> ControlledGate:
|
|
297
297
|
new_sub_gate = protocols.resolve_parameters(self.sub_gate, resolver, recursive)
|
|
298
298
|
return ControlledGate(
|
|
299
299
|
new_sub_gate,
|
|
@@ -311,9 +311,7 @@ class ControlledGate(raw_types.Gate):
|
|
|
311
311
|
angle_list = np.append(np.angle(np.linalg.eigvals(u)), 0)
|
|
312
312
|
return protocols.trace_distance_from_angle_list(angle_list)
|
|
313
313
|
|
|
314
|
-
def _circuit_diagram_info_(
|
|
315
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
316
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
314
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
317
315
|
sub_args = protocols.CircuitDiagramInfoArgs(
|
|
318
316
|
known_qubit_count=(
|
|
319
317
|
args.known_qubit_count - self.num_controls()
|
|
@@ -363,7 +361,7 @@ class ControlledGate(raw_types.Gate):
|
|
|
363
361
|
}
|
|
364
362
|
|
|
365
363
|
|
|
366
|
-
def _validate_sub_object(sub_object: Union[
|
|
364
|
+
def _validate_sub_object(sub_object: Union[cirq.Gate, cirq.Operation]):
|
|
367
365
|
if protocols.is_measurement(sub_object):
|
|
368
366
|
raise ValueError(f'Cannot control measurement {sub_object}')
|
|
369
367
|
if not protocols.has_mixture(sub_object) and not protocols.is_parameterized(sub_object):
|
cirq/ops/controlled_operation.py
CHANGED
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
from
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from types import EllipsisType, NotImplementedType
|
|
16
18
|
from typing import (
|
|
17
19
|
AbstractSet,
|
|
18
20
|
Any,
|
|
@@ -53,8 +55,8 @@ class ControlledOperation(raw_types.Operation):
|
|
|
53
55
|
|
|
54
56
|
def __init__(
|
|
55
57
|
self,
|
|
56
|
-
controls: Sequence[
|
|
57
|
-
sub_operation:
|
|
58
|
+
controls: Sequence[cirq.Qid],
|
|
59
|
+
sub_operation: cirq.Operation,
|
|
58
60
|
control_values: Optional[
|
|
59
61
|
Union[cv.AbstractControlValues, Sequence[Union[int, Collection[int]]]]
|
|
60
62
|
] = None,
|
|
@@ -114,7 +116,7 @@ class ControlledOperation(raw_types.Operation):
|
|
|
114
116
|
self._control_values = self._control_values & sub_operation.control_values
|
|
115
117
|
|
|
116
118
|
@property
|
|
117
|
-
def controls(self) -> Tuple[
|
|
119
|
+
def controls(self) -> Tuple[cirq.Qid, ...]:
|
|
118
120
|
return self._controls
|
|
119
121
|
|
|
120
122
|
@property
|
|
@@ -122,11 +124,11 @@ class ControlledOperation(raw_types.Operation):
|
|
|
122
124
|
return self._control_values
|
|
123
125
|
|
|
124
126
|
@property
|
|
125
|
-
def sub_operation(self) ->
|
|
127
|
+
def sub_operation(self) -> cirq.Operation:
|
|
126
128
|
return self._sub_operation
|
|
127
129
|
|
|
128
130
|
@property
|
|
129
|
-
def gate(self) -> Optional[
|
|
131
|
+
def gate(self) -> Optional[cirq.ControlledGate]:
|
|
130
132
|
if self.sub_operation.gate is None:
|
|
131
133
|
return None
|
|
132
134
|
return controlled_gate.ControlledGate(
|
|
@@ -148,7 +150,7 @@ class ControlledOperation(raw_types.Operation):
|
|
|
148
150
|
def _decompose_(self):
|
|
149
151
|
return self._decompose_with_context_()
|
|
150
152
|
|
|
151
|
-
def _decompose_with_context_(self, context: Optional[
|
|
153
|
+
def _decompose_with_context_(self, context: Optional[cirq.DecompositionContext] = None):
|
|
152
154
|
result = protocols.decompose_once_with_qubits(
|
|
153
155
|
self.gate, self.qubits, NotImplemented, flatten=False, context=context
|
|
154
156
|
)
|
|
@@ -176,12 +178,12 @@ class ControlledOperation(raw_types.Operation):
|
|
|
176
178
|
)
|
|
177
179
|
return sorted_controls, tuple(expanded_cvals), self.sub_operation
|
|
178
180
|
|
|
179
|
-
def _apply_unitary_(self, args:
|
|
181
|
+
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> np.ndarray:
|
|
180
182
|
n = len(self.controls)
|
|
181
183
|
sub_n = len(args.axes) - n
|
|
182
184
|
sub_axes = args.axes[n:]
|
|
183
185
|
for control_vals in self.control_values.expand():
|
|
184
|
-
active: Tuple[Union[
|
|
186
|
+
active: Tuple[Union[EllipsisType, slice], ...] = (
|
|
185
187
|
...,
|
|
186
188
|
*(slice(v, v + 1) for v in control_vals),
|
|
187
189
|
*(slice(None),) * sub_n,
|
|
@@ -207,7 +209,7 @@ class ControlledOperation(raw_types.Operation):
|
|
|
207
209
|
def _has_unitary_(self) -> bool:
|
|
208
210
|
return protocols.has_unitary(self.sub_operation)
|
|
209
211
|
|
|
210
|
-
def _qasm_(self, args:
|
|
212
|
+
def _qasm_(self, args: cirq.QasmArgs) -> Optional[str]:
|
|
211
213
|
if (
|
|
212
214
|
hasattr(self._sub_operation, "gate")
|
|
213
215
|
and len(self._controls) == 1
|
|
@@ -287,8 +289,8 @@ class ControlledOperation(raw_types.Operation):
|
|
|
287
289
|
return protocols.parameter_names(self.sub_operation)
|
|
288
290
|
|
|
289
291
|
def _resolve_parameters_(
|
|
290
|
-
self, resolver:
|
|
291
|
-
) ->
|
|
292
|
+
self, resolver: cirq.ParamResolver, recursive: bool
|
|
293
|
+
) -> ControlledOperation:
|
|
292
294
|
new_sub_op = protocols.resolve_parameters(self.sub_operation, resolver, recursive)
|
|
293
295
|
return ControlledOperation(self.controls, new_sub_op, self.control_values)
|
|
294
296
|
|
|
@@ -301,15 +303,15 @@ class ControlledOperation(raw_types.Operation):
|
|
|
301
303
|
angle_list = np.append(np.angle(np.linalg.eigvals(u)), 0)
|
|
302
304
|
return protocols.trace_distance_from_angle_list(angle_list)
|
|
303
305
|
|
|
304
|
-
def __pow__(self, exponent: Any) ->
|
|
306
|
+
def __pow__(self, exponent: Any) -> ControlledOperation:
|
|
305
307
|
new_sub_op = protocols.pow(self.sub_operation, exponent, NotImplemented)
|
|
306
308
|
if new_sub_op is NotImplemented:
|
|
307
309
|
return NotImplemented
|
|
308
310
|
return ControlledOperation(self.controls, new_sub_op, self.control_values)
|
|
309
311
|
|
|
310
312
|
def _circuit_diagram_info_(
|
|
311
|
-
self, args:
|
|
312
|
-
) -> Optional[
|
|
313
|
+
self, args: cirq.CircuitDiagramInfoArgs
|
|
314
|
+
) -> Optional[protocols.CircuitDiagramInfo]:
|
|
313
315
|
n = len(self.controls)
|
|
314
316
|
|
|
315
317
|
sub_args = protocols.CircuitDiagramInfoArgs(
|