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 CHANGED
@@ -28,4 +28,4 @@ if sys.version_info < (3, 10, 0): # pragma: no cover
28
28
  'of cirq (e.g. "python -m pip install cirq==1.1.*")'
29
29
  )
30
30
 
31
- __version__ = "1.5.0.dev20241219205221"
31
+ __version__ = "1.5.0.dev20241220195200"
cirq/_version_test.py CHANGED
@@ -3,4 +3,4 @@ import cirq
3
3
 
4
4
 
5
5
  def test_version():
6
- assert cirq.__version__ == "1.5.0.dev20241219205221"
6
+ assert cirq.__version__ == "1.5.0.dev20241220195200"
@@ -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 ops
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."""
@@ -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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cirq-core
3
- Version: 1.5.0.dev20241219205221
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
@@ -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=LgYBHy4-TNt8aWBSL-jhQ7q-NeQUCK8I9jbPHuvcE2M,1206
8
- cirq/_version_test.py,sha256=iRVS_dYH5tfWJBzIJnvIXBfnhMrAk9rshfCOdmo5Bz0,147
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=6N83Ky3zkhT5LMKx0TqNe2UAQbb-rp4nzuTG31GFELg,11884
207
- cirq/experiments/z_phase_calibration_test.py,sha256=Hk6FR-mvlkwol1WQvc75gw6oC_adRW-0_JF5y0X598E,7592
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=eAQP2XPWW_1nItjzv__75eqhruCbKkFB1Y_eL1ov10c,18725
296
- cirq/ops/fsim_gate_test.py,sha256=owW1VpXntJqxlzhtppnyfaS9gQKFNA6UzCHksgPHaHU,25165
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.dev20241219205221.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
1193
- cirq_core-1.5.0.dev20241219205221.dist-info/METADATA,sha256=sUEl9aQuRY9clOGfxIhMygmHjCE89UTc7hGDjel2gHM,1992
1194
- cirq_core-1.5.0.dev20241219205221.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
1195
- cirq_core-1.5.0.dev20241219205221.dist-info/top_level.txt,sha256=Sz9iOxHU0IEMLSFGwiwOCaN2e9K-jFbBbtpPN1hB73g,5
1196
- cirq_core-1.5.0.dev20241219205221.dist-info/RECORD,,
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,,