cirq-core 1.5.0.dev20241219205221__py3-none-any.whl → 1.5.0.dev20241220195200__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/z_phase_calibration.py +84 -2
- cirq/experiments/z_phase_calibration_test.py +31 -0
- cirq/ops/fsim_gate.py +39 -0
- cirq/ops/fsim_gate_test.py +21 -0
- {cirq_core-1.5.0.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241220195200.dist-info}/METADATA +1 -1
- {cirq_core-1.5.0.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241220195200.dist-info}/RECORD +11 -11
- {cirq_core-1.5.0.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241220195200.dist-info}/LICENSE +0 -0
- {cirq_core-1.5.0.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241220195200.dist-info}/WHEEL +0 -0
- {cirq_core-1.5.0.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241220195200.dist-info}/top_level.txt +0 -0
cirq/_version.py
CHANGED
cirq/_version_test.py
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Provides a method to do z-phase calibration for excitation-preserving gates."""
|
|
16
|
-
from typing import Union, Optional, Sequence, Tuple, Dict, TYPE_CHECKING, Any
|
|
16
|
+
from typing import Union, Optional, Sequence, Tuple, Dict, TYPE_CHECKING, Any, List
|
|
17
17
|
import multiprocessing
|
|
18
18
|
import multiprocessing.pool
|
|
19
19
|
|
|
@@ -22,7 +22,8 @@ import numpy as np
|
|
|
22
22
|
|
|
23
23
|
from cirq.experiments import xeb_fitting
|
|
24
24
|
from cirq.experiments.two_qubit_xeb import parallel_xeb_workflow
|
|
25
|
-
from cirq import
|
|
25
|
+
from cirq.transformers import transformer_api
|
|
26
|
+
from cirq import ops, circuits, protocols
|
|
26
27
|
|
|
27
28
|
if TYPE_CHECKING:
|
|
28
29
|
import cirq
|
|
@@ -283,3 +284,84 @@ def plot_z_phase_calibration_result(
|
|
|
283
284
|
ax.set_title('-'.join(str(q) for q in pair))
|
|
284
285
|
ax.legend()
|
|
285
286
|
return axes
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def _z_angles(old: ops.PhasedFSimGate, new: ops.PhasedFSimGate) -> Tuple[float, float, float]:
|
|
290
|
+
"""Computes a set of possible 3 z-phases that result in the change in gamma, zeta, and chi."""
|
|
291
|
+
# This procedure is the inverse of PhasedFSimGate.from_fsim_rz
|
|
292
|
+
delta_gamma = new.gamma - old.gamma
|
|
293
|
+
delta_zeta = new.zeta - old.zeta
|
|
294
|
+
delta_chi = new.chi - old.chi
|
|
295
|
+
return (-delta_gamma + delta_chi, -delta_gamma - delta_zeta, delta_zeta - delta_chi)
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
@transformer_api.transformer
|
|
299
|
+
class CalibrationTransformer:
|
|
300
|
+
|
|
301
|
+
def __init__(
|
|
302
|
+
self,
|
|
303
|
+
target: 'cirq.Gate',
|
|
304
|
+
calibration_map: Dict[Tuple['cirq.Qid', 'cirq.Qid'], 'cirq.PhasedFSimGate'],
|
|
305
|
+
):
|
|
306
|
+
"""Create a CalibrationTransformer.
|
|
307
|
+
|
|
308
|
+
The transformer adds 3 ZPowGates around each calibrated gate to cancel the
|
|
309
|
+
effect of z-phases.
|
|
310
|
+
|
|
311
|
+
Args:
|
|
312
|
+
target: The target gate. Any gate matching this
|
|
313
|
+
will be replaced based on the content of `calibration_map`.
|
|
314
|
+
calibration_map:
|
|
315
|
+
A map mapping qubit pairs to calibrated gates. This is the output of
|
|
316
|
+
calling `calibrate_z_phases`.
|
|
317
|
+
"""
|
|
318
|
+
self.target = target
|
|
319
|
+
if isinstance(target, ops.PhasedFSimGate):
|
|
320
|
+
self.target_as_fsim = target
|
|
321
|
+
elif (gate := ops.PhasedFSimGate.from_matrix(protocols.unitary(target))) is not None:
|
|
322
|
+
self.target_as_fsim = gate
|
|
323
|
+
else:
|
|
324
|
+
raise ValueError(f"{target} is not equivalent to a PhasedFSimGate")
|
|
325
|
+
self.calibration_map = calibration_map
|
|
326
|
+
|
|
327
|
+
def __call__(
|
|
328
|
+
self,
|
|
329
|
+
circuit: 'cirq.AbstractCircuit',
|
|
330
|
+
*,
|
|
331
|
+
context: Optional[transformer_api.TransformerContext] = None,
|
|
332
|
+
) -> 'cirq.Circuit':
|
|
333
|
+
"""Adds 3 ZPowGates around each calibrated gate to cancel the effect of Z phases.
|
|
334
|
+
|
|
335
|
+
Args:
|
|
336
|
+
circuit: Circuit to transform.
|
|
337
|
+
context: Optional transformer context (not used).
|
|
338
|
+
|
|
339
|
+
Returns:
|
|
340
|
+
New circuit with the extra ZPowGates.
|
|
341
|
+
"""
|
|
342
|
+
new_moments: List[Union[List[cirq.Operation], 'cirq.Moment']] = []
|
|
343
|
+
for moment in circuit:
|
|
344
|
+
before = []
|
|
345
|
+
after = []
|
|
346
|
+
for op in moment:
|
|
347
|
+
if op.gate != self.target:
|
|
348
|
+
# not a target.
|
|
349
|
+
continue
|
|
350
|
+
assert len(op.qubits) == 2
|
|
351
|
+
gate = self.calibration_map.get(op.qubits, None) or self.calibration_map.get(
|
|
352
|
+
op.qubits[::-1], None
|
|
353
|
+
)
|
|
354
|
+
if gate is None:
|
|
355
|
+
# no calibration available.
|
|
356
|
+
continue
|
|
357
|
+
angles = np.array(_z_angles(self.target_as_fsim, gate)) / np.pi
|
|
358
|
+
angles = -angles # Take the negative to cancel the effect.
|
|
359
|
+
before.append(ops.Z(op.qubits[0]) ** angles[0])
|
|
360
|
+
before.append(ops.Z(op.qubits[1]) ** angles[1])
|
|
361
|
+
after.append(ops.Z(op.qubits[0]) ** angles[2])
|
|
362
|
+
if before:
|
|
363
|
+
new_moments.append(before)
|
|
364
|
+
new_moments.append(moment)
|
|
365
|
+
if after:
|
|
366
|
+
new_moments.append(after)
|
|
367
|
+
return circuits.Circuit.from_moments(*new_moments)
|
|
@@ -22,6 +22,7 @@ from cirq.experiments.z_phase_calibration import (
|
|
|
22
22
|
calibrate_z_phases,
|
|
23
23
|
z_phase_calibration_workflow,
|
|
24
24
|
plot_z_phase_calibration_result,
|
|
25
|
+
CalibrationTransformer,
|
|
25
26
|
)
|
|
26
27
|
from cirq.experiments.xeb_fitting import XEBPhasedFSimCharacterizationOptions
|
|
27
28
|
|
|
@@ -205,3 +206,33 @@ def test_plot_z_phase_calibration_result():
|
|
|
205
206
|
np.testing.assert_allclose(axes[1].lines[0].get_xdata().astype(float), [1, 2, 3])
|
|
206
207
|
np.testing.assert_allclose(axes[1].lines[0].get_ydata().astype(float), [0.6, 0.4, 0.1])
|
|
207
208
|
np.testing.assert_allclose(axes[1].lines[1].get_ydata().astype(float), [0.7, 0.77, 0.8])
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
@pytest.mark.parametrize('angles', 2 * np.pi * np.random.random((10, 10)))
|
|
212
|
+
def test_transform_circuit(angles):
|
|
213
|
+
theta, phi = angles[:2]
|
|
214
|
+
old_zs = angles[2:6]
|
|
215
|
+
new_zs = angles[6:]
|
|
216
|
+
gate = cirq.PhasedFSimGate.from_fsim_rz(theta, phi, old_zs[:2], old_zs[2:])
|
|
217
|
+
fsim = cirq.PhasedFSimGate.from_fsim_rz(theta, phi, new_zs[:2], new_zs[2:])
|
|
218
|
+
c = cirq.Circuit(gate(cirq.q(0), cirq.q(1)))
|
|
219
|
+
replacement_map = {(cirq.q(1), cirq.q(0)): fsim}
|
|
220
|
+
|
|
221
|
+
new_circuit = CalibrationTransformer(gate, replacement_map)(c)
|
|
222
|
+
|
|
223
|
+
# we replace the old gate with the `fsim` gate the result should be that the overall
|
|
224
|
+
# unitary equals the unitary of the original (ideal) gate.
|
|
225
|
+
circuit_with_replacement_gate = cirq.Circuit(
|
|
226
|
+
op if op.gate != gate else fsim(*op.qubits) for op in new_circuit.all_operations()
|
|
227
|
+
)
|
|
228
|
+
np.testing.assert_allclose(cirq.unitary(circuit_with_replacement_gate), cirq.unitary(c))
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def test_transform_circuit_invalid_gate_raises():
|
|
232
|
+
with pytest.raises(ValueError, match="is not equivalent to a PhasedFSimGate"):
|
|
233
|
+
_ = CalibrationTransformer(cirq.XX, {})
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def test_transform_circuit_uncalibrated_gates_pass():
|
|
237
|
+
c = cirq.Circuit(cirq.CZ(cirq.q(0), cirq.q(1)), cirq.measure(cirq.q(0)))
|
|
238
|
+
assert c == CalibrationTransformer(cirq.CZ, {})(c)
|
cirq/ops/fsim_gate.py
CHANGED
|
@@ -347,6 +347,45 @@ class PhasedFSimGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
|
|
|
347
347
|
chi = (b0 - b1 - a0 + a1) / 2.0
|
|
348
348
|
return PhasedFSimGate(theta, zeta, chi, gamma, phi)
|
|
349
349
|
|
|
350
|
+
@staticmethod
|
|
351
|
+
def from_matrix(u: np.ndarray) -> Optional['PhasedFSimGate']:
|
|
352
|
+
"""Contruct a PhasedFSimGate from unitary.
|
|
353
|
+
|
|
354
|
+
Args:
|
|
355
|
+
u: A unitary matrix representing a PhasedFSimGate.
|
|
356
|
+
|
|
357
|
+
Returns:
|
|
358
|
+
- Either PhasedFSimGate with the given unitary or None if
|
|
359
|
+
the matrix is not unitary or if doesn't represent a PhasedFSimGate.
|
|
360
|
+
"""
|
|
361
|
+
|
|
362
|
+
gamma = np.angle(u[1, 1] * u[2, 2] - u[1, 2] * u[2, 1]) / -2
|
|
363
|
+
phi = -np.angle(u[3, 3]) - 2 * gamma
|
|
364
|
+
phased_cos_theta_2 = u[1, 1] * u[2, 2]
|
|
365
|
+
if phased_cos_theta_2 == 0:
|
|
366
|
+
# The zeta phase is multiplied with cos(theta),
|
|
367
|
+
# so if cos(theta) is zero then any value is possible.
|
|
368
|
+
zeta = 0
|
|
369
|
+
else:
|
|
370
|
+
zeta = np.angle(u[2, 2] / u[1, 1]) / 2
|
|
371
|
+
|
|
372
|
+
phased_sin_theta_2 = u[1, 2] * u[2, 1]
|
|
373
|
+
if phased_sin_theta_2 == 0:
|
|
374
|
+
# The chi phase is multiplied with sin(theta),
|
|
375
|
+
# so if sin(theta) is zero then any value is possible.
|
|
376
|
+
chi = 0
|
|
377
|
+
else:
|
|
378
|
+
chi = np.angle(u[1, 2] / u[2, 1]) / 2
|
|
379
|
+
|
|
380
|
+
theta = np.angle(
|
|
381
|
+
np.exp(1j * (gamma + zeta)) * u[1, 1] - np.exp(1j * (gamma - chi)) * u[1, 2]
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
gate = PhasedFSimGate(theta=theta, phi=phi, chi=chi, zeta=zeta, gamma=gamma)
|
|
385
|
+
if np.allclose(u, protocols.unitary(gate)):
|
|
386
|
+
return gate
|
|
387
|
+
return None
|
|
388
|
+
|
|
350
389
|
@property
|
|
351
390
|
def rz_angles_before(self) -> Tuple['cirq.TParamVal', 'cirq.TParamVal']:
|
|
352
391
|
"""Returns 2-tuple of phase angles applied to qubits before FSimGate."""
|
cirq/ops/fsim_gate_test.py
CHANGED
|
@@ -797,3 +797,24 @@ def test_phased_fsim_json_dict():
|
|
|
797
797
|
assert cirq.PhasedFSimGate(
|
|
798
798
|
theta=0.12, zeta=0.34, chi=0.56, gamma=0.78, phi=0.9
|
|
799
799
|
)._json_dict_() == {'theta': 0.12, 'zeta': 0.34, 'chi': 0.56, 'gamma': 0.78, 'phi': 0.9}
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
@pytest.mark.parametrize(
|
|
803
|
+
'gate',
|
|
804
|
+
[
|
|
805
|
+
cirq.CZ,
|
|
806
|
+
cirq.SQRT_ISWAP,
|
|
807
|
+
cirq.SQRT_ISWAP_INV,
|
|
808
|
+
cirq.ISWAP,
|
|
809
|
+
cirq.ISWAP_INV,
|
|
810
|
+
cirq.cphase(0.1),
|
|
811
|
+
cirq.CZ**0.2,
|
|
812
|
+
],
|
|
813
|
+
)
|
|
814
|
+
def test_phase_fsim_from_matrix(gate):
|
|
815
|
+
u = cirq.unitary(gate)
|
|
816
|
+
np.testing.assert_allclose(cirq.unitary(cirq.PhasedFSimGate.from_matrix(u)), u, atol=1e-8)
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
def test_phase_fsim_from_matrix_not_fsim_returns_none():
|
|
820
|
+
assert cirq.PhasedFSimGate.from_matrix(np.ones((4, 4))) is None
|
{cirq_core-1.5.0.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241220195200.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.dev20241220195200
|
|
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.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241220195200.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=dPaa8yrdK5buJFr5S5fOt0KpPJ-F-HoYxSDqDBco1_w,1206
|
|
8
|
+
cirq/_version_test.py,sha256=j8wRMiv7LlOfF9JlQcW5gYoN0x3c1fws-8ub4E-LOFU,147
|
|
9
9
|
cirq/conftest.py,sha256=X7yLFL8GLhg2CjPw0hp5e_dGASfvHx1-QT03aUbhKJw,1168
|
|
10
10
|
cirq/json_resolver_cache.py,sha256=03MVo6Y-UYrzt9CKHmwpiBLN2ixL6uSU-OWnKZXfG7k,13302
|
|
11
11
|
cirq/py.typed,sha256=VFSlmh_lNwnaXzwY-ZuW-C2Ws5PkuDoVgBdNCs0jXJE,63
|
|
@@ -203,8 +203,8 @@ cirq/experiments/xeb_sampling.py,sha256=6ZOidGi7Kt6p4cMQCjK7qQuIUXVHCYl47B2GnL8M
|
|
|
203
203
|
cirq/experiments/xeb_sampling_test.py,sha256=0XkQGvcURsug3IblE_wZrHVDoOQV3WuQilrqCJbDHjI,6784
|
|
204
204
|
cirq/experiments/xeb_simulation.py,sha256=yML2NAnYTRFG1wsQHvxtNEGEMXuExbWjrE2JYuCqnrk,5076
|
|
205
205
|
cirq/experiments/xeb_simulation_test.py,sha256=YWFKXPdtBFuZNhQoG06W1EetVhXighc3zyXwhKfGAeo,5652
|
|
206
|
-
cirq/experiments/z_phase_calibration.py,sha256=
|
|
207
|
-
cirq/experiments/z_phase_calibration_test.py,sha256=
|
|
206
|
+
cirq/experiments/z_phase_calibration.py,sha256=2mkpmtY60hQuaB91If6eAL_q_nW88hwJ2Pqdq9R_iTE,15152
|
|
207
|
+
cirq/experiments/z_phase_calibration_test.py,sha256=BJ88waxTxRUsKSoFnkYkvhKxKwBNSmYCuZII6X-R36g,8904
|
|
208
208
|
cirq/interop/__init__.py,sha256=Xt1xU9UegP_jBNa9xaeOFSgtC0lYb_HNHq4hQQ0J20k,784
|
|
209
209
|
cirq/interop/quirk/__init__.py,sha256=W11jqaExSgvoUkjM_d0Kik4R8bqETF9Ezo27CDEB3iw,1237
|
|
210
210
|
cirq/interop/quirk/url_to_circuit.py,sha256=1ToWnFJdJIhCko9q62BEvOoCGxCpOUl8891IdCa52MM,14211
|
|
@@ -292,8 +292,8 @@ cirq/ops/eigen_gate.py,sha256=eQ6-MOknop7CrejsTuQ0KZWf4mZnQBi8wEaTQXw4KSQ,18334
|
|
|
292
292
|
cirq/ops/eigen_gate_test.py,sha256=-7l6GmAd1EYzHoGREQN1n7J1VOQKbThH2mA88TRODs8,13928
|
|
293
293
|
cirq/ops/fourier_transform.py,sha256=pynO07OcZSVCeL8L0pNQ9m_y5_wrpTWOMf99BHpjXdU,7579
|
|
294
294
|
cirq/ops/fourier_transform_test.py,sha256=PIK4bWnCIy2TuX0fgclHeU1CBDT6zRVoQpv1v1jt62c,6220
|
|
295
|
-
cirq/ops/fsim_gate.py,sha256=
|
|
296
|
-
cirq/ops/fsim_gate_test.py,sha256=
|
|
295
|
+
cirq/ops/fsim_gate.py,sha256=Avzlcb_O201K0_tBmNR5m9fWkpBM7Nby0MfJjNJ9g_8,20136
|
|
296
|
+
cirq/ops/fsim_gate_test.py,sha256=4kFk0ALzTmaskQURHPl6JerNvw8gbZn49nt1_WAjpdY,25671
|
|
297
297
|
cirq/ops/gate_features.py,sha256=414mSi3kgKSwLOeAG_WEZKn8ZMaLtOowed7os1qSnM4,1049
|
|
298
298
|
cirq/ops/gate_features_test.py,sha256=mnlqJnSpllcOnTUdvmUs_ssnPRhAIgHhKIAK2Z86Dfg,2347
|
|
299
299
|
cirq/ops/gate_operation.py,sha256=IGCyqe9YguIlajnQ3EV61Y0vUxOT_SrRxvNEFwKtUak,13720
|
|
@@ -1189,8 +1189,8 @@ cirq/work/sampler.py,sha256=bE5tmVkcR6cZZMLETxDfHehdsYUMbx2RvBeIBetehI4,19187
|
|
|
1189
1189
|
cirq/work/sampler_test.py,sha256=hL2UWx3dz2ukZVNxWftiKVvJcQoLplLZdQm-k1QcA40,13282
|
|
1190
1190
|
cirq/work/zeros_sampler.py,sha256=x1C7cup66a43n-3tm8QjhiqJa07qcJW10FxNp9jJ59Q,2356
|
|
1191
1191
|
cirq/work/zeros_sampler_test.py,sha256=JIkpBBFPJe5Ba4142vzogyWyboG1Q1ZAm0UVGgOoZn8,3279
|
|
1192
|
-
cirq_core-1.5.0.
|
|
1193
|
-
cirq_core-1.5.0.
|
|
1194
|
-
cirq_core-1.5.0.
|
|
1195
|
-
cirq_core-1.5.0.
|
|
1196
|
-
cirq_core-1.5.0.
|
|
1192
|
+
cirq_core-1.5.0.dev20241220195200.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
|
|
1193
|
+
cirq_core-1.5.0.dev20241220195200.dist-info/METADATA,sha256=yAQPpmLOdT_gJeAKrLe6S17oCv5xxFWM8SGAm1oDpOI,1992
|
|
1194
|
+
cirq_core-1.5.0.dev20241220195200.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
|
1195
|
+
cirq_core-1.5.0.dev20241220195200.dist-info/top_level.txt,sha256=Sz9iOxHU0IEMLSFGwiwOCaN2e9K-jFbBbtpPN1hB73g,5
|
|
1196
|
+
cirq_core-1.5.0.dev20241220195200.dist-info/RECORD,,
|
{cirq_core-1.5.0.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241220195200.dist-info}/LICENSE
RENAMED
|
File without changes
|
{cirq_core-1.5.0.dev20241219205221.dist-info → cirq_core-1.5.0.dev20241220195200.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|