cirq-core 1.4.0.dev20240509215225__py3-none-any.whl → 1.4.0.dev20240509224851__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/__init__.py CHANGED
@@ -336,6 +336,7 @@ from cirq.ops import (
336
336
 
337
337
  from cirq.transformers import (
338
338
  AbstractInitialMapper,
339
+ add_dynamical_decoupling,
339
340
  align_left,
340
341
  align_right,
341
342
  CompilationTargetGateset,
cirq/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "1.4.0.dev20240509215225"
1
+ __version__ = "1.4.0.dev20240509224851"
@@ -78,6 +78,8 @@ from cirq.transformers.drop_empty_moments import drop_empty_moments
78
78
 
79
79
  from cirq.transformers.drop_negligible_operations import drop_negligible_operations
80
80
 
81
+ from cirq.transformers.dynamical_decoupling import add_dynamical_decoupling
82
+
81
83
  from cirq.transformers.eject_z import eject_z
82
84
 
83
85
  from cirq.transformers.measurement_transformers import (
@@ -0,0 +1,122 @@
1
+ # Copyright 2024 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
+ """Transformer pass that adds dynamical decoupling operations to a circuit."""
16
+
17
+ from functools import reduce
18
+ from typing import Dict, Optional, Sequence, Tuple, Union
19
+
20
+ from cirq.transformers import transformer_api
21
+ import cirq
22
+ import numpy as np
23
+
24
+
25
+ def _repeat_sequence(
26
+ base_sequence: Sequence['cirq.Gate'], num_idle_moments: int
27
+ ) -> Sequence['cirq.Gate']:
28
+ """Returns the longest possible dynamical decoupling sequence."""
29
+ repeat_times = num_idle_moments // len(base_sequence)
30
+ return list(base_sequence) * repeat_times
31
+
32
+
33
+ def _get_dd_sequence_from_schema_name(schema: str) -> Sequence['cirq.Gate']:
34
+ """Gets dynamical decoupling sequence from a schema name."""
35
+ dd_sequence: Sequence['cirq.Gate']
36
+ match schema:
37
+ case 'XX_PAIR':
38
+ dd_sequence = (cirq.X, cirq.X)
39
+ case 'X_XINV':
40
+ dd_sequence = (cirq.X, cirq.X**-1)
41
+ case 'YY_PAIR':
42
+ dd_sequence = (cirq.Y, cirq.Y)
43
+ case 'Y_YINV':
44
+ dd_sequence = (cirq.Y, cirq.Y**-1)
45
+ case _:
46
+ raise ValueError('Invalid schema name.')
47
+ return dd_sequence
48
+
49
+
50
+ def _validate_dd_sequence(dd_sequence: Sequence['cirq.Gate']) -> None:
51
+ """Validates a given dynamical decoupling sequence.
52
+
53
+ Args:
54
+ dd_sequence: Input dynamical sequence to be validated.
55
+
56
+ Returns:
57
+ A tuple containing:
58
+ - is_valid (bool): True if the dd sequence is valid, False otherwise.
59
+ - error_message (str): An error message if the dd sequence is invalid, else None.
60
+
61
+ Raises:
62
+ ValueError: If dd_sequence is not valid.
63
+ """
64
+ if len(dd_sequence) < 2:
65
+ raise ValueError('Invalid dynamical decoupling sequence. Expect more than one gates.')
66
+ matrices = [cirq.unitary(gate) for gate in dd_sequence]
67
+ product = reduce(np.matmul, matrices)
68
+
69
+ if not cirq.equal_up_to_global_phase(product, np.eye(2)):
70
+ raise ValueError(
71
+ 'Invalid dynamical decoupling sequence. Expect sequence production equals'
72
+ f' identity up to a global phase, got {product}.'.replace('\n', ' ')
73
+ )
74
+
75
+
76
+ def _parse_dd_sequence(schema: Union[str, Sequence['cirq.Gate']]) -> Sequence['cirq.Gate']:
77
+ """Parses and returns dynamical decoupling sequence from schema."""
78
+ if isinstance(schema, str):
79
+ dd_sequence = _get_dd_sequence_from_schema_name(schema)
80
+ else:
81
+ _validate_dd_sequence(schema)
82
+ dd_sequence = schema
83
+ return dd_sequence
84
+
85
+
86
+ @transformer_api.transformer
87
+ def add_dynamical_decoupling(
88
+ circuit: 'cirq.AbstractCircuit',
89
+ *,
90
+ context: Optional['cirq.TransformerContext'] = None,
91
+ schema: Union[str, Sequence['cirq.Gate']] = 'X_XINV',
92
+ ) -> 'cirq.Circuit':
93
+ """Adds dynamical decoupling gate operations to idle moments of a given circuit.
94
+ This transformer preserves the moment structure of the circuit.
95
+
96
+ Args:
97
+ circuit: Input circuit to transform.
98
+ context: `cirq.TransformerContext` storing common configurable options for transformers.
99
+ schema: Dynamical decoupling schema name or a dynamical decoupling sequence.
100
+ If a schema is specified, provided dynamical decouping sequence will be used.
101
+ Otherwise, customized dynamical decoupling sequence will be applied.
102
+
103
+ Returns:
104
+ A copy of the input circuit with dynamical decoupling operations.
105
+ """
106
+ last_busy_moment_by_qubits: Dict['cirq.Qid', int] = {q: 0 for q in circuit.all_qubits()}
107
+ insert_into: list[Tuple[int, 'cirq.OP_TREE']] = []
108
+
109
+ base_dd_sequence = _parse_dd_sequence(schema)
110
+
111
+ for moment_id, moment in enumerate(circuit):
112
+ for q in moment.qubits:
113
+ insert_gates = _repeat_sequence(
114
+ base_dd_sequence, num_idle_moments=moment_id - last_busy_moment_by_qubits[q] - 1
115
+ )
116
+ for idx, gate in enumerate(insert_gates):
117
+ insert_into.append((last_busy_moment_by_qubits[q] + idx + 1, gate.on(q)))
118
+ last_busy_moment_by_qubits[q] = moment_id
119
+
120
+ updated_circuit = circuit.unfreeze(copy=True)
121
+ updated_circuit.batch_insert_into(insert_into)
122
+ return updated_circuit
@@ -0,0 +1,123 @@
1
+ # Copyright 2024 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
+ from typing import Sequence, Union
16
+ import cirq
17
+ from cirq import add_dynamical_decoupling
18
+ import pytest
19
+
20
+
21
+ def assert_dd(
22
+ input_circuit: cirq.Circuit,
23
+ expected_circuit: cirq.Circuit,
24
+ schema: Union[str, Sequence['cirq.Gate']],
25
+ ):
26
+ updated_circuit = add_dynamical_decoupling(input_circuit, schema=schema)
27
+ cirq.testing.assert_same_circuits(updated_circuit, expected_circuit)
28
+
29
+
30
+ def test_no_insert_due_to_no_consecutive_moments():
31
+ a = cirq.NamedQubit('a')
32
+ b = cirq.NamedQubit('b')
33
+
34
+ # No insertion as there is no room for a dd sequence.
35
+ assert_dd(
36
+ input_circuit=cirq.Circuit(
37
+ cirq.Moment(cirq.H(a)), cirq.Moment(cirq.CNOT(a, b)), cirq.Moment(cirq.H(b))
38
+ ),
39
+ expected_circuit=cirq.Circuit(
40
+ cirq.Moment(cirq.H(a)), cirq.Moment(cirq.CNOT(a, b)), cirq.Moment(cirq.H(b))
41
+ ),
42
+ schema='XX_PAIR',
43
+ )
44
+
45
+
46
+ @pytest.mark.parametrize(
47
+ 'schema,inserted_gates',
48
+ [
49
+ ('XX_PAIR', (cirq.X, cirq.X)),
50
+ ('X_XINV', (cirq.X, cirq.X**-1)),
51
+ ('YY_PAIR', (cirq.Y, cirq.Y)),
52
+ ('Y_YINV', (cirq.Y, cirq.Y**-1)),
53
+ ],
54
+ )
55
+ def test_insert_provided_schema(schema: str, inserted_gates: Sequence['cirq.Gate']):
56
+ a = cirq.NamedQubit('a')
57
+ b = cirq.NamedQubit('b')
58
+ c = cirq.NamedQubit('c')
59
+
60
+ input_circuit = cirq.Circuit(
61
+ cirq.Moment(cirq.H(a)),
62
+ cirq.Moment(cirq.CNOT(a, b)),
63
+ cirq.Moment(cirq.CNOT(b, c)),
64
+ cirq.Moment(cirq.CNOT(b, c)),
65
+ cirq.Moment(cirq.measure_each(a, b, c)),
66
+ )
67
+ expected_circuit = cirq.Circuit(
68
+ cirq.Moment(cirq.H(a)),
69
+ cirq.Moment(cirq.CNOT(a, b)),
70
+ cirq.Moment(cirq.CNOT(b, c), inserted_gates[0](a)),
71
+ cirq.Moment(cirq.CNOT(b, c), inserted_gates[1](a)),
72
+ cirq.Moment(cirq.measure_each(a, b, c)),
73
+ )
74
+
75
+ # Insert one dynamical decoupling sequence in idle moments.
76
+ assert_dd(input_circuit, expected_circuit, schema=schema)
77
+
78
+
79
+ def test_insert_by_customized_dd_sequence():
80
+ a = cirq.NamedQubit('a')
81
+ b = cirq.NamedQubit('b')
82
+ c = cirq.NamedQubit('c')
83
+
84
+ assert_dd(
85
+ input_circuit=cirq.Circuit(
86
+ cirq.Moment(cirq.H(a)),
87
+ cirq.Moment(cirq.CNOT(a, b)),
88
+ cirq.Moment(cirq.CNOT(b, c)),
89
+ cirq.Moment(cirq.CNOT(b, c)),
90
+ cirq.Moment(cirq.CNOT(b, c)),
91
+ cirq.Moment(cirq.CNOT(b, c)),
92
+ cirq.Moment(cirq.measure_each(a, b, c)),
93
+ ),
94
+ expected_circuit=cirq.Circuit(
95
+ cirq.Moment(cirq.H(a)),
96
+ cirq.Moment(cirq.CNOT(a, b)),
97
+ cirq.Moment(cirq.CNOT(b, c), cirq.X(a)),
98
+ cirq.Moment(cirq.CNOT(b, c), cirq.X(a)),
99
+ cirq.Moment(cirq.CNOT(b, c), cirq.Y(a)),
100
+ cirq.Moment(cirq.CNOT(b, c), cirq.Y(a)),
101
+ cirq.Moment(cirq.measure_each(a, b, c)),
102
+ ),
103
+ schema=[cirq.X, cirq.X, cirq.Y, cirq.Y],
104
+ )
105
+
106
+
107
+ @pytest.mark.parametrize(
108
+ 'schema,error_msg_regex',
109
+ [
110
+ ('INVALID_SCHEMA', 'Invalid schema name.'),
111
+ ([cirq.X], 'Invalid dynamical decoupling sequence. Expect more than one gates.'),
112
+ (
113
+ [cirq.X, cirq.H],
114
+ 'Invalid dynamical decoupling sequence. Expect sequence production equals identity'
115
+ ' up to a global phase, got',
116
+ ),
117
+ ],
118
+ )
119
+ def test_invalid_dd_schema(schema: Union[str, Sequence['cirq.Gate']], error_msg_regex):
120
+ a = cirq.NamedQubit('a')
121
+ input_circuit = cirq.Circuit(cirq.H(a))
122
+ with pytest.raises(ValueError, match=error_msg_regex):
123
+ add_dynamical_decoupling(input_circuit, schema=schema)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cirq-core
3
- Version: 1.4.0.dev20240509215225
3
+ Version: 1.4.0.dev20240509224851
4
4
  Summary: A framework for creating, editing, and invoking Noisy Intermediate Scale Quantum (NISQ) circuits.
5
5
  Home-page: http://github.com/quantumlib/cirq
6
6
  Author: The Cirq Developers
@@ -1,10 +1,10 @@
1
- cirq/__init__.py,sha256=Pisx61VoUhqDdggQ31ch0Mx3uMwVtZ0q7Z69Ib4C92s,15736
1
+ cirq/__init__.py,sha256=gQkxjgGyat-egE2jZlrLCVMofvpG_VA1021yh8Tv9j8,15766
2
2
  cirq/_compat.py,sha256=2tkJ50ID2PXzmMNuTfQrsZqqRSblTmfu3Y7g742gojs,29342
3
3
  cirq/_compat_test.py,sha256=Qq3ZcfgD-Nb81cEppQdJqhAyrVqXKtfXZYGXT0p-Wh0,34718
4
4
  cirq/_doc.py,sha256=yDyWUD_2JDS0gShfGRb-rdqRt9-WeL7DhkqX7np0Nko,2879
5
5
  cirq/_import.py,sha256=p9gMHJscbtDDkfHOaulvd3Aer0pwUF5AXpL89XR8dNw,8402
6
6
  cirq/_import_test.py,sha256=6K_v0riZJXOXUphHNkGA8MY-JcmGlezFaGmvrNhm3OQ,1015
7
- cirq/_version.py,sha256=XzUu-oSq5dDszma7gs7De3cNgBYMfb9_nx-2PuTDunI,40
7
+ cirq/_version.py,sha256=Oe2oO7fLniWMge5QU8jj7I7z689VwMkUcRfBX4DFRrU,40
8
8
  cirq/_version_test.py,sha256=yYS6xm5-nuBRQJa9R3n41WdvFtVyY7Lb5Q8bea3VgBI,133
9
9
  cirq/conftest.py,sha256=X7yLFL8GLhg2CjPw0hp5e_dGASfvHx1-QT03aUbhKJw,1168
10
10
  cirq/json_resolver_cache.py,sha256=9g_JQMmfBzTuV-3s2flUbXIgcLjs4K7LjAFFgngdG1U,13204
@@ -1013,13 +1013,15 @@ cirq/testing/test_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
1013
1013
  cirq/testing/test_data/test_module_missing_json_test_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1014
1014
  cirq/testing/test_data/test_module_missing_testspec/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1015
1015
  cirq/testing/test_data/test_module_missing_testspec/json_test_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1016
- cirq/transformers/__init__.py,sha256=Omi-8NLq9lMbMHV-eXxwrpX5_zw-ZyRJKPmIL_mIzMg,4145
1016
+ cirq/transformers/__init__.py,sha256=-buJqTF2c6rUM18JDGSb5aMKWtyT24jE_mMrHo6DsdM,4222
1017
1017
  cirq/transformers/align.py,sha256=B4DuX84DWd4tLfMH21JviMZSOFYu7KCOMSEMALYsQpw,2727
1018
1018
  cirq/transformers/align_test.py,sha256=M4etT2cgESv1RdkKASguiGxEuqY7kmI1IswjSi-1jjY,7174
1019
1019
  cirq/transformers/drop_empty_moments.py,sha256=Rtn_BrpwkLXyZBdLzwdnsnEGWTdYuf1xOPakzbpv7-w,1517
1020
1020
  cirq/transformers/drop_empty_moments_test.py,sha256=G8pZmTfi8NG2NpGz_K3LZu5NQoqa-xPMCuZjwEu07xk,1907
1021
1021
  cirq/transformers/drop_negligible_operations.py,sha256=8eyOMy7bra2wJAjORbk6QjwHiLdL5SfwRaz8D2Dazbw,2083
1022
1022
  cirq/transformers/drop_negligible_operations_test.py,sha256=gqL6RoDPm6Zf4RxtprBenFyIsZQPUxmPur9oRl0Yr3U,3823
1023
+ cirq/transformers/dynamical_decoupling.py,sha256=iALBcjaO3uwcAla-smjapp2z9YezGecGFo_OGgJkD_8,4704
1024
+ cirq/transformers/dynamical_decoupling_test.py,sha256=hGUzTDV1UL3VBIueri91j3_ycxGmr20mGfQSnRAjegM,4149
1023
1025
  cirq/transformers/eject_phased_paulis.py,sha256=mTgRT5aw5_c9ccTkP4Np_4YTWnLzxsMKRO8pOQ7CtYM,13955
1024
1026
  cirq/transformers/eject_phased_paulis_test.py,sha256=-mXsfbi3V0ojC_YqoQM5otzdW4kjGusCx6F-kCv8M98,15834
1025
1027
  cirq/transformers/eject_z.py,sha256=0kOyvh6FDfrCrrTCVfpHKNc_kNC_pBdEKoXv11kuqGA,5803
@@ -1169,8 +1171,8 @@ cirq/work/sampler.py,sha256=JEAeQQRF3bqlO9AkOf4XbrTATDI5f5JgyM_FAUCNxao,19751
1169
1171
  cirq/work/sampler_test.py,sha256=B2ZsuqGT854gQtBIAh8k0LiG9Vj5wSzcGvkxOUoTcW4,13217
1170
1172
  cirq/work/zeros_sampler.py,sha256=x1C7cup66a43n-3tm8QjhiqJa07qcJW10FxNp9jJ59Q,2356
1171
1173
  cirq/work/zeros_sampler_test.py,sha256=JIkpBBFPJe5Ba4142vzogyWyboG1Q1ZAm0UVGgOoZn8,3279
1172
- cirq_core-1.4.0.dev20240509215225.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
1173
- cirq_core-1.4.0.dev20240509215225.dist-info/METADATA,sha256=by0PSGyTPZ_yiM5_bg5AGvSYkHW_65ZFRb_hVjgTcHs,2000
1174
- cirq_core-1.4.0.dev20240509215225.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
1175
- cirq_core-1.4.0.dev20240509215225.dist-info/top_level.txt,sha256=Sz9iOxHU0IEMLSFGwiwOCaN2e9K-jFbBbtpPN1hB73g,5
1176
- cirq_core-1.4.0.dev20240509215225.dist-info/RECORD,,
1174
+ cirq_core-1.4.0.dev20240509224851.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
1175
+ cirq_core-1.4.0.dev20240509224851.dist-info/METADATA,sha256=VWh4JaX499yyPSZoAlVl2F0SUMTk6zuqukkKI7O7D3g,2000
1176
+ cirq_core-1.4.0.dev20240509224851.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
1177
+ cirq_core-1.4.0.dev20240509224851.dist-info/top_level.txt,sha256=Sz9iOxHU0IEMLSFGwiwOCaN2e9K-jFbBbtpPN1hB73g,5
1178
+ cirq_core-1.4.0.dev20240509224851.dist-info/RECORD,,