cirq-core 1.5.0.dev20240710182542__py3-none-any.whl → 1.5.0.dev20240712174048__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/experiments/two_qubit_xeb.py +55 -4
- cirq/experiments/xeb_fitting.py +68 -9
- cirq/experiments/xeb_fitting_test.py +33 -1
- cirq/transformers/noise_adding.py +114 -0
- cirq/transformers/noise_adding_test.py +53 -0
- {cirq_core-1.5.0.dev20240710182542.dist-info → cirq_core-1.5.0.dev20240712174048.dist-info}/METADATA +1 -1
- {cirq_core-1.5.0.dev20240710182542.dist-info → cirq_core-1.5.0.dev20240712174048.dist-info}/RECORD +12 -10
- {cirq_core-1.5.0.dev20240710182542.dist-info → cirq_core-1.5.0.dev20240712174048.dist-info}/LICENSE +0 -0
- {cirq_core-1.5.0.dev20240710182542.dist-info → cirq_core-1.5.0.dev20240712174048.dist-info}/WHEEL +0 -0
- {cirq_core-1.5.0.dev20240710182542.dist-info → cirq_core-1.5.0.dev20240712174048.dist-info}/top_level.txt +0 -0
cirq/_version.py
CHANGED
cirq/_version_test.py
CHANGED
|
@@ -347,7 +347,7 @@ class InferredXEBResult:
|
|
|
347
347
|
return ax
|
|
348
348
|
|
|
349
349
|
|
|
350
|
-
def
|
|
350
|
+
def parallel_xeb_workflow(
|
|
351
351
|
sampler: 'cirq.Sampler',
|
|
352
352
|
qubits: Optional[Sequence['cirq.GridQubit']] = None,
|
|
353
353
|
entangling_gate: 'cirq.Gate' = ops.CZ,
|
|
@@ -358,8 +358,8 @@ def parallel_two_qubit_xeb(
|
|
|
358
358
|
random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
|
|
359
359
|
ax: Optional[plt.Axes] = None,
|
|
360
360
|
**plot_kwargs,
|
|
361
|
-
) ->
|
|
362
|
-
"""A
|
|
361
|
+
) -> Tuple[pd.DataFrame, Sequence['cirq.Circuit'], pd.DataFrame]:
|
|
362
|
+
"""A utility method that runs the full XEB workflow.
|
|
363
363
|
|
|
364
364
|
Args:
|
|
365
365
|
sampler: The quantum engine or simulator to run the circuits.
|
|
@@ -375,7 +375,12 @@ def parallel_two_qubit_xeb(
|
|
|
375
375
|
**plot_kwargs: Arguments to be passed to 'plt.Axes.plot'.
|
|
376
376
|
|
|
377
377
|
Returns:
|
|
378
|
-
A
|
|
378
|
+
- A DataFrame with columns 'cycle_depth' and 'fidelity'.
|
|
379
|
+
- The circuits used to perform XEB.
|
|
380
|
+
- A pandas dataframe with index given by ['circuit_i', 'cycle_depth'].
|
|
381
|
+
Columns always include "sampled_probs". If `combinations_by_layer` is
|
|
382
|
+
not `None` and you are doing parallel XEB, additional metadata columns
|
|
383
|
+
will be attached to the returned DataFrame.
|
|
379
384
|
|
|
380
385
|
Raises:
|
|
381
386
|
ValueError: If qubits are not specified and the sampler has no device.
|
|
@@ -420,6 +425,52 @@ def parallel_two_qubit_xeb(
|
|
|
420
425
|
sampled_df=sampled_df, circuits=circuit_library, cycle_depths=cycle_depths
|
|
421
426
|
)
|
|
422
427
|
|
|
428
|
+
return fids, circuit_library, sampled_df
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def parallel_two_qubit_xeb(
|
|
432
|
+
sampler: 'cirq.Sampler',
|
|
433
|
+
qubits: Optional[Sequence['cirq.GridQubit']] = None,
|
|
434
|
+
entangling_gate: 'cirq.Gate' = ops.CZ,
|
|
435
|
+
n_repetitions: int = 10**4,
|
|
436
|
+
n_combinations: int = 10,
|
|
437
|
+
n_circuits: int = 20,
|
|
438
|
+
cycle_depths: Sequence[int] = tuple(np.arange(3, 100, 20)),
|
|
439
|
+
random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
|
|
440
|
+
ax: Optional[plt.Axes] = None,
|
|
441
|
+
**plot_kwargs,
|
|
442
|
+
) -> TwoQubitXEBResult:
|
|
443
|
+
"""A convenience method that runs the full XEB workflow.
|
|
444
|
+
|
|
445
|
+
Args:
|
|
446
|
+
sampler: The quantum engine or simulator to run the circuits.
|
|
447
|
+
qubits: Qubits under test. If none, uses all qubits on the sampler's device.
|
|
448
|
+
entangling_gate: The entangling gate to use.
|
|
449
|
+
n_repetitions: The number of repetitions to use.
|
|
450
|
+
n_combinations: The number of combinations to generate.
|
|
451
|
+
n_circuits: The number of circuits to generate.
|
|
452
|
+
cycle_depths: The cycle depths to use.
|
|
453
|
+
random_state: The random state to use.
|
|
454
|
+
ax: the plt.Axes to plot the device layout on. If not given,
|
|
455
|
+
no plot is created.
|
|
456
|
+
**plot_kwargs: Arguments to be passed to 'plt.Axes.plot'.
|
|
457
|
+
Returns:
|
|
458
|
+
A TwoQubitXEBResult object representing the results of the experiment.
|
|
459
|
+
Raises:
|
|
460
|
+
ValueError: If qubits are not specified and the sampler has no device.
|
|
461
|
+
"""
|
|
462
|
+
fids, *_ = parallel_xeb_workflow(
|
|
463
|
+
sampler=sampler,
|
|
464
|
+
qubits=qubits,
|
|
465
|
+
entangling_gate=entangling_gate,
|
|
466
|
+
n_repetitions=n_repetitions,
|
|
467
|
+
n_combinations=n_combinations,
|
|
468
|
+
n_circuits=n_circuits,
|
|
469
|
+
cycle_depths=cycle_depths,
|
|
470
|
+
random_state=random_state,
|
|
471
|
+
ax=ax,
|
|
472
|
+
**plot_kwargs,
|
|
473
|
+
)
|
|
423
474
|
return TwoQubitXEBResult(fit_exponential_decays(fids))
|
|
424
475
|
|
|
425
476
|
|
cirq/experiments/xeb_fitting.py
CHANGED
|
@@ -146,6 +146,69 @@ class XEBCharacterizationOptions(ABC):
|
|
|
146
146
|
"""Return an initial Nelder-Mead simplex and the names for each parameter."""
|
|
147
147
|
|
|
148
148
|
|
|
149
|
+
def _try_defaults_from_unitary(gate: 'cirq.Gate') -> Optional[Dict[str, 'cirq.TParamVal']]:
|
|
150
|
+
r"""Try to figure out the PhasedFSim angles from the unitary of the gate.
|
|
151
|
+
|
|
152
|
+
The unitary of a PhasedFSimGate has the form:
|
|
153
|
+
$$
|
|
154
|
+
\begin{bmatrix}
|
|
155
|
+
1 & 0 & 0 & 0 \\
|
|
156
|
+
0 & e^{-i \gamma - i \zeta} \cos(\theta) & -i e^{-i \gamma + i\chi} \sin(\theta) & 0 \\
|
|
157
|
+
0 & -i e^{-i \gamma - i \chi} \sin(\theta) & e^{-i \gamma + i \zeta} \cos(\theta) & 0 \\
|
|
158
|
+
0 & 0 & 0 & e^{-2i \gamma - i \phi}
|
|
159
|
+
\end{bmatrix}
|
|
160
|
+
$$
|
|
161
|
+
That's the information about the five angles $\theta, \phi, \gamma, \zeta, \chi$ is encoded in
|
|
162
|
+
the submatrix unitary[1:3, 1:3] and the element u[3][3]. With some algebra, we can isolate each
|
|
163
|
+
of the angles as an argument of a combination of those elements (and potentially other angles).
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
A cirq gate.
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
A dictionary mapping angles to values or None if the gate doesn't have a unitary or if it
|
|
170
|
+
can't be represented by a PhasedFSimGate.
|
|
171
|
+
"""
|
|
172
|
+
u = protocols.unitary(gate, default=None)
|
|
173
|
+
if u is None:
|
|
174
|
+
return None
|
|
175
|
+
|
|
176
|
+
gamma = np.angle(u[1, 1] * u[2, 2] - u[1, 2] * u[2, 1]) / -2
|
|
177
|
+
phi = -np.angle(u[3, 3]) - 2 * gamma
|
|
178
|
+
phased_cos_theta_2 = u[1, 1] * u[2, 2]
|
|
179
|
+
if phased_cos_theta_2 == 0:
|
|
180
|
+
# The zeta phase is multiplied with cos(theta),
|
|
181
|
+
# so if cos(theta) is zero then any value is possible.
|
|
182
|
+
zeta = 0
|
|
183
|
+
else:
|
|
184
|
+
zeta = np.angle(u[2, 2] / u[1, 1]) / 2
|
|
185
|
+
|
|
186
|
+
phased_sin_theta_2 = u[1, 2] * u[2, 1]
|
|
187
|
+
if phased_sin_theta_2 == 0:
|
|
188
|
+
# The chi phase is multiplied with sin(theta),
|
|
189
|
+
# so if sin(theta) is zero then any value is possible.
|
|
190
|
+
chi = 0
|
|
191
|
+
else:
|
|
192
|
+
chi = np.angle(u[1, 2] / u[2, 1]) / 2
|
|
193
|
+
|
|
194
|
+
theta = np.angle(np.exp(1j * (gamma + zeta)) * u[1, 1] - np.exp(1j * (gamma - chi)) * u[1, 2])
|
|
195
|
+
|
|
196
|
+
if np.allclose(
|
|
197
|
+
u,
|
|
198
|
+
protocols.unitary(
|
|
199
|
+
ops.PhasedFSimGate(theta=theta, phi=phi, chi=chi, zeta=zeta, gamma=gamma)
|
|
200
|
+
),
|
|
201
|
+
):
|
|
202
|
+
return {
|
|
203
|
+
'theta_default': theta,
|
|
204
|
+
'phi_default': phi,
|
|
205
|
+
'gamma_default': gamma,
|
|
206
|
+
'zeta_default': zeta,
|
|
207
|
+
'chi_default': chi,
|
|
208
|
+
}
|
|
209
|
+
return None
|
|
210
|
+
|
|
211
|
+
|
|
149
212
|
def phased_fsim_angles_from_gate(gate: 'cirq.Gate') -> Dict[str, 'cirq.TParamVal']:
|
|
150
213
|
"""For a given gate, return a dictionary mapping '{angle}_default' to its noiseless value
|
|
151
214
|
for the five PhasedFSim angles."""
|
|
@@ -175,6 +238,11 @@ def phased_fsim_angles_from_gate(gate: 'cirq.Gate') -> Dict[str, 'cirq.TParamVal
|
|
|
175
238
|
'phi_default': gate.phi,
|
|
176
239
|
}
|
|
177
240
|
|
|
241
|
+
# Handle all gates that can be represented using an FSimGate.
|
|
242
|
+
from_unitary = _try_defaults_from_unitary(gate)
|
|
243
|
+
if from_unitary is not None:
|
|
244
|
+
return from_unitary
|
|
245
|
+
|
|
178
246
|
raise ValueError(f"Unknown default angles for {gate}.")
|
|
179
247
|
|
|
180
248
|
|
|
@@ -580,15 +648,6 @@ def _fit_exponential_decay(
|
|
|
580
648
|
return a, layer_fid, a_std, layer_fid_std
|
|
581
649
|
|
|
582
650
|
|
|
583
|
-
def _one_unique(df, name, default):
|
|
584
|
-
"""Helper function to assert that there's one unique value in a column and return it."""
|
|
585
|
-
if name not in df.columns:
|
|
586
|
-
return default
|
|
587
|
-
vals = df[name].unique()
|
|
588
|
-
assert len(vals) == 1, name
|
|
589
|
-
return vals[0]
|
|
590
|
-
|
|
591
|
-
|
|
592
651
|
def fit_exponential_decays(fidelities_df: pd.DataFrame) -> pd.DataFrame:
|
|
593
652
|
"""Fit exponential decay curves to a fidelities DataFrame.
|
|
594
653
|
|
|
@@ -32,6 +32,7 @@ from cirq.experiments.xeb_fitting import (
|
|
|
32
32
|
fit_exponential_decays,
|
|
33
33
|
before_and_after_characterization,
|
|
34
34
|
XEBPhasedFSimCharacterizationOptions,
|
|
35
|
+
phased_fsim_angles_from_gate,
|
|
35
36
|
)
|
|
36
37
|
from cirq.experiments.xeb_sampling import sample_2q_xeb_circuits
|
|
37
38
|
|
|
@@ -354,7 +355,7 @@ def test_options_with_defaults_from_gate():
|
|
|
354
355
|
assert options.zeta_default == 0.0
|
|
355
356
|
|
|
356
357
|
with pytest.raises(ValueError):
|
|
357
|
-
_ = XEBPhasedFSimCharacterizationOptions().with_defaults_from_gate(cirq.
|
|
358
|
+
_ = XEBPhasedFSimCharacterizationOptions().with_defaults_from_gate(cirq.XX)
|
|
358
359
|
|
|
359
360
|
|
|
360
361
|
def test_options_defaults_set():
|
|
@@ -395,3 +396,34 @@ def test_options_defaults_set():
|
|
|
395
396
|
phi_default=0.0,
|
|
396
397
|
)
|
|
397
398
|
assert o3.defaults_set() is True
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
def _random_angles(n, seed):
|
|
402
|
+
rng = np.random.default_rng(seed)
|
|
403
|
+
r = 2 * rng.random((n, 5)) - 1
|
|
404
|
+
return np.pi * r
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
@pytest.mark.parametrize(
|
|
408
|
+
'gate',
|
|
409
|
+
[
|
|
410
|
+
cirq.CZ,
|
|
411
|
+
cirq.SQRT_ISWAP,
|
|
412
|
+
cirq.SQRT_ISWAP_INV,
|
|
413
|
+
cirq.ISWAP,
|
|
414
|
+
cirq.ISWAP_INV,
|
|
415
|
+
cirq.cphase(0.1),
|
|
416
|
+
cirq.CZ**0.2,
|
|
417
|
+
]
|
|
418
|
+
+ [cirq.PhasedFSimGate(*r) for r in _random_angles(10, 0)],
|
|
419
|
+
)
|
|
420
|
+
def test_phased_fsim_angles_from_gate(gate):
|
|
421
|
+
angles = phased_fsim_angles_from_gate(gate)
|
|
422
|
+
angles = {k.removesuffix('_default'): v for k, v in angles.items()}
|
|
423
|
+
phasedfsim = cirq.PhasedFSimGate(**angles)
|
|
424
|
+
np.testing.assert_allclose(cirq.unitary(phasedfsim), cirq.unitary(gate), atol=1e-9)
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
def test_phased_fsim_angles_from_gate_unsupporet_gate():
|
|
428
|
+
with pytest.raises(ValueError, match='Unknown default angles'):
|
|
429
|
+
_ = phased_fsim_angles_from_gate(cirq.testing.TwoQubitGate())
|
|
@@ -0,0 +1,114 @@
|
|
|
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 collections.abc import Mapping
|
|
16
|
+
|
|
17
|
+
from typing import cast
|
|
18
|
+
from cirq import ops, circuits
|
|
19
|
+
from cirq.transformers import transformer_api
|
|
20
|
+
import numpy as np
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _gate_in_moment(gate: ops.Gate, moment: circuits.Moment) -> bool:
|
|
24
|
+
"""Check whether `gate` is in `moment`."""
|
|
25
|
+
return any(op.gate == gate for op in moment)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@transformer_api.transformer
|
|
29
|
+
class DepolerizingNoiseTransformer:
|
|
30
|
+
"""Add local depolarizing noise after two-qubit gates in a specified circuit. More specifically,
|
|
31
|
+
with probability p, append a random non-identity two-qubit Pauli operator after each specified
|
|
32
|
+
two-qubit gate.
|
|
33
|
+
|
|
34
|
+
Attrs:
|
|
35
|
+
p: The probability with which to add noise.
|
|
36
|
+
target_gate: Add depolarizing nose after this type of gate
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(
|
|
40
|
+
self, p: float | Mapping[tuple[ops.Qid, ops.Qid], float], target_gate: ops.Gate = ops.CZ
|
|
41
|
+
):
|
|
42
|
+
"""Initialize the depolarizing noise transformer with some depolarizing probability and
|
|
43
|
+
target gate.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
p: The depolarizing probability, either a single float or a mapping from pairs of qubits
|
|
47
|
+
to floats.
|
|
48
|
+
target_gate: The gate after which to add depolarizing noise.
|
|
49
|
+
|
|
50
|
+
Raises:
|
|
51
|
+
TypeError: If `p` is not either be a float or a mapping from sorted qubit pairs to
|
|
52
|
+
floats.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
if not isinstance(p, (Mapping, float)):
|
|
56
|
+
raise TypeError( # pragma: no cover
|
|
57
|
+
"p must either be a float or a mapping from" # pragma: no cover
|
|
58
|
+
+ "sorted qubit pairs to floats" # pragma: no cover
|
|
59
|
+
) # pragma: no cover
|
|
60
|
+
self.p = p
|
|
61
|
+
self.p_func = (
|
|
62
|
+
(lambda _: p)
|
|
63
|
+
if isinstance(p, (int, float))
|
|
64
|
+
else (lambda pair: cast(Mapping, p).get(pair, 0.0))
|
|
65
|
+
)
|
|
66
|
+
self.target_gate = target_gate
|
|
67
|
+
|
|
68
|
+
def __call__(
|
|
69
|
+
self,
|
|
70
|
+
circuit: circuits.AbstractCircuit,
|
|
71
|
+
rng: np.random.Generator | None = None,
|
|
72
|
+
*,
|
|
73
|
+
context: transformer_api.TransformerContext | None = None,
|
|
74
|
+
):
|
|
75
|
+
"""Apply the transformer to the given circuit.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
circuit: The circuit to add noise to.
|
|
79
|
+
context: Not used; to satisfy transformer API.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
The transformed circuit.
|
|
83
|
+
"""
|
|
84
|
+
if rng is None:
|
|
85
|
+
rng = np.random.default_rng()
|
|
86
|
+
target_gate = self.target_gate
|
|
87
|
+
|
|
88
|
+
# add random Pauli gates with probability p after each of the specified gate
|
|
89
|
+
assert target_gate.num_qubits() == 2, "`target_gate` must be a two-qubit gate."
|
|
90
|
+
paulis = [ops.I, ops.X, ops.Y, ops.Z]
|
|
91
|
+
new_moments = []
|
|
92
|
+
for moment in circuit:
|
|
93
|
+
new_moments.append(moment)
|
|
94
|
+
if _gate_in_moment(target_gate, moment):
|
|
95
|
+
# add a new moment with the Paulis
|
|
96
|
+
target_pairs = {
|
|
97
|
+
tuple(sorted(op.qubits)) for op in moment.operations if op.gate == target_gate
|
|
98
|
+
}
|
|
99
|
+
added_moment_ops = []
|
|
100
|
+
for pair in target_pairs:
|
|
101
|
+
pair_sorted_tuple = (pair[0], pair[1])
|
|
102
|
+
p_i = self.p_func(pair_sorted_tuple)
|
|
103
|
+
apply = rng.choice([True, False], p=[p_i, 1 - p_i])
|
|
104
|
+
if apply:
|
|
105
|
+
choices = [
|
|
106
|
+
(pauli_a(pair[0]), pauli_b(pair[1]))
|
|
107
|
+
for pauli_a in paulis
|
|
108
|
+
for pauli_b in paulis
|
|
109
|
+
][1:]
|
|
110
|
+
pauli_to_apply = rng.choice(np.array(choices, dtype=object))
|
|
111
|
+
added_moment_ops.append(pauli_to_apply)
|
|
112
|
+
if len(added_moment_ops) > 0:
|
|
113
|
+
new_moments.append(circuits.Moment(*added_moment_ops))
|
|
114
|
+
return circuits.Circuit.from_moments(*new_moments)
|
|
@@ -0,0 +1,53 @@
|
|
|
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 cirq import ops, circuits, devices
|
|
16
|
+
import cirq.transformers.noise_adding as na
|
|
17
|
+
import numpy as np
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_noise_adding():
|
|
21
|
+
qubits = devices.LineQubit.range(4)
|
|
22
|
+
one_layer = circuits.Circuit(ops.CZ(*qubits[:2]), ops.CZ(*qubits[2:]))
|
|
23
|
+
circuit = one_layer * 10
|
|
24
|
+
|
|
25
|
+
# test that p=0 does nothing
|
|
26
|
+
transformed_circuit_p0 = na.DepolerizingNoiseTransformer(0.0)(circuit)
|
|
27
|
+
assert transformed_circuit_p0 == circuit
|
|
28
|
+
|
|
29
|
+
# test that p=1 doubles the circuit depth
|
|
30
|
+
transformed_circuit_p1 = na.DepolerizingNoiseTransformer(1.0)(circuit)
|
|
31
|
+
assert len(transformed_circuit_p1) == 20
|
|
32
|
+
|
|
33
|
+
# test that we get a deterministic result when using a specific rng
|
|
34
|
+
rng = np.random.default_rng(0)
|
|
35
|
+
transformed_circuit_p0_03 = na.DepolerizingNoiseTransformer(0.03)(circuit, rng=rng)
|
|
36
|
+
expected_circuit = (
|
|
37
|
+
one_layer * 2
|
|
38
|
+
+ circuits.Circuit(ops.I(qubits[2]), ops.Z(qubits[3]))
|
|
39
|
+
+ one_layer * 4
|
|
40
|
+
+ circuits.Circuit(ops.Z(qubits[0]), ops.X(qubits[1]))
|
|
41
|
+
+ one_layer * 4
|
|
42
|
+
+ circuits.Circuit(ops.I(qubits[2]), ops.X(qubits[3]))
|
|
43
|
+
)
|
|
44
|
+
assert transformed_circuit_p0_03 == expected_circuit
|
|
45
|
+
|
|
46
|
+
# test that supplying a dictionary for p works
|
|
47
|
+
transformed_circuit_p_dict = na.DepolerizingNoiseTransformer(
|
|
48
|
+
{tuple(qubits[:2]): 1.0, tuple(qubits[2:]): 0.0}
|
|
49
|
+
)(circuit)
|
|
50
|
+
assert len(transformed_circuit_p_dict) == 20 # depth should be doubled
|
|
51
|
+
assert transformed_circuit_p_dict[1::2].all_qubits() == frozenset(
|
|
52
|
+
qubits[:2]
|
|
53
|
+
) # no single-qubit gates get added to qubits[2:]
|
{cirq_core-1.5.0.dev20240710182542.dist-info → cirq_core-1.5.0.dev20240712174048.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cirq-core
|
|
3
|
-
Version: 1.5.0.
|
|
3
|
+
Version: 1.5.0.dev20240712174048
|
|
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
|
{cirq_core-1.5.0.dev20240710182542.dist-info → cirq_core-1.5.0.dev20240712174048.dist-info}/RECORD
RENAMED
|
@@ -4,8 +4,8 @@ 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=
|
|
8
|
-
cirq/_version_test.py,sha256=
|
|
7
|
+
cirq/_version.py,sha256=iUhBnaAkxANMTntlE0vtUUwIfs0DksnHzH_qxhgat2s,1206
|
|
8
|
+
cirq/_version_test.py,sha256=jsZSypKTqjpgtoUqQ_xhXrNpPwx3PqF0JcOJqT0-2pk,147
|
|
9
9
|
cirq/conftest.py,sha256=X7yLFL8GLhg2CjPw0hp5e_dGASfvHx1-QT03aUbhKJw,1168
|
|
10
10
|
cirq/json_resolver_cache.py,sha256=ytePZtNZgKjOF2NiVpUTuotB-JKZmQNOFIFdvXqsxHw,13271
|
|
11
11
|
cirq/py.typed,sha256=VFSlmh_lNwnaXzwY-ZuW-C2Ws5PkuDoVgBdNCs0jXJE,63
|
|
@@ -196,10 +196,10 @@ cirq/experiments/t1_decay_experiment.py,sha256=ealdmc_RTE__z1YUcaDEncDzQOaiT0K6I
|
|
|
196
196
|
cirq/experiments/t1_decay_experiment_test.py,sha256=Pgbm-37JiCdw9iQg2OaXVvs72xGWV2629CgsTQlLQnw,9139
|
|
197
197
|
cirq/experiments/t2_decay_experiment.py,sha256=lTgZ9yJ7Fk9_ozUCHysQn1qKrMQwTpsgEv-QnvsEif0,19158
|
|
198
198
|
cirq/experiments/t2_decay_experiment_test.py,sha256=DFR0BGn0Id4qNPfqIExj70TEAqf7Vrc8eK91Wj0YKTc,15031
|
|
199
|
-
cirq/experiments/two_qubit_xeb.py,sha256=
|
|
199
|
+
cirq/experiments/two_qubit_xeb.py,sha256=NU8JsM6yqpTfWQCPf6dCAlD89MmYpprI5kVz2bxAJhI,19879
|
|
200
200
|
cirq/experiments/two_qubit_xeb_test.py,sha256=Tlr32vuJpyepkMBVVkN6ipjRyDr8DIixfBumEeGXzDM,10073
|
|
201
|
-
cirq/experiments/xeb_fitting.py,sha256=
|
|
202
|
-
cirq/experiments/xeb_fitting_test.py,sha256=
|
|
201
|
+
cirq/experiments/xeb_fitting.py,sha256=tD678gTY495cDA6b55YIPdwq22VQFbB2AlnkeX_X9P0,29332
|
|
202
|
+
cirq/experiments/xeb_fitting_test.py,sha256=LEgC76mYFwsX-ZqRqg2j85EiHACq8nK9ITrcl-TgeiA,15286
|
|
203
203
|
cirq/experiments/xeb_sampling.py,sha256=6ZOidGi7Kt6p4cMQCjK7qQuIUXVHCYl47B2GnL8M-Bw,14987
|
|
204
204
|
cirq/experiments/xeb_sampling_test.py,sha256=0XkQGvcURsug3IblE_wZrHVDoOQV3WuQilrqCJbDHjI,6784
|
|
205
205
|
cirq/experiments/xeb_simulation.py,sha256=DpCWVxzWnZvjrdfgIbwR9rWenehqz7Su3LPIVHoK7gI,5055
|
|
@@ -1038,6 +1038,8 @@ cirq/transformers/merge_k_qubit_gates.py,sha256=dUsswQOIHfbb6Lu37fecgrpT6_45zmDE
|
|
|
1038
1038
|
cirq/transformers/merge_k_qubit_gates_test.py,sha256=k_ROZvUebHgPy5vsNnWNMBYU4kfIkrunPsw39ZngMwo,13920
|
|
1039
1039
|
cirq/transformers/merge_single_qubit_gates.py,sha256=NRREV4Z6Ptc3mZnOUgzQePdj4H0aix17WOUwZUB7iQ8,5826
|
|
1040
1040
|
cirq/transformers/merge_single_qubit_gates_test.py,sha256=SWf1Il7Bz0iUCDM7JoDG2Yxe4p2yYr2PgViQpjByFm0,9914
|
|
1041
|
+
cirq/transformers/noise_adding.py,sha256=Ng1JoGzSJdrA7WBAOLmM5kSGWP4bqEnQc-g9kYxePNQ,4439
|
|
1042
|
+
cirq/transformers/noise_adding_test.py,sha256=C0G16cj_hGWgpAYV0L7p3_p4LkD7SR99p0DJJq1fUwk,2134
|
|
1041
1043
|
cirq/transformers/optimize_for_target_gateset.py,sha256=MxhFsCm2XgW3gdpNW4NGVmz1VdQvzKdNNCtVZDuZiVE,7229
|
|
1042
1044
|
cirq/transformers/optimize_for_target_gateset_test.py,sha256=MgAHjsPbVtd0fl2ytRz2R-LQuhSqImtrFK5F45QXkA8,19523
|
|
1043
1045
|
cirq/transformers/qubit_management_transformers.py,sha256=A7Mweu9ElLSCsy_atmgFbYlzOFXKhct5gQ5YNTjjaVU,9430
|
|
@@ -1175,8 +1177,8 @@ cirq/work/sampler.py,sha256=JEAeQQRF3bqlO9AkOf4XbrTATDI5f5JgyM_FAUCNxao,19751
|
|
|
1175
1177
|
cirq/work/sampler_test.py,sha256=B2ZsuqGT854gQtBIAh8k0LiG9Vj5wSzcGvkxOUoTcW4,13217
|
|
1176
1178
|
cirq/work/zeros_sampler.py,sha256=x1C7cup66a43n-3tm8QjhiqJa07qcJW10FxNp9jJ59Q,2356
|
|
1177
1179
|
cirq/work/zeros_sampler_test.py,sha256=JIkpBBFPJe5Ba4142vzogyWyboG1Q1ZAm0UVGgOoZn8,3279
|
|
1178
|
-
cirq_core-1.5.0.
|
|
1179
|
-
cirq_core-1.5.0.
|
|
1180
|
-
cirq_core-1.5.0.
|
|
1181
|
-
cirq_core-1.5.0.
|
|
1182
|
-
cirq_core-1.5.0.
|
|
1180
|
+
cirq_core-1.5.0.dev20240712174048.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
|
|
1181
|
+
cirq_core-1.5.0.dev20240712174048.dist-info/METADATA,sha256=NlXO10cYbogOnPAE1Ey5161fy8CcORzhbrcdiEYYDl8,2007
|
|
1182
|
+
cirq_core-1.5.0.dev20240712174048.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
1183
|
+
cirq_core-1.5.0.dev20240712174048.dist-info/top_level.txt,sha256=Sz9iOxHU0IEMLSFGwiwOCaN2e9K-jFbBbtpPN1hB73g,5
|
|
1184
|
+
cirq_core-1.5.0.dev20240712174048.dist-info/RECORD,,
|
{cirq_core-1.5.0.dev20240710182542.dist-info → cirq_core-1.5.0.dev20240712174048.dist-info}/LICENSE
RENAMED
|
File without changes
|
{cirq_core-1.5.0.dev20240710182542.dist-info → cirq_core-1.5.0.dev20240712174048.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|