cirq-core 1.2.0.dev20230630133613__py3-none-any.whl → 1.2.0.dev20230705194247__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.
cirq/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "1.2.0.dev20230630133613"
1
+ __version__ = "1.2.0.dev20230705194247"
@@ -20,6 +20,7 @@ import numpy as np
20
20
 
21
21
  from cirq import _compat, ops, value, qis
22
22
  from cirq.sim import simulator, state_vector, simulator_base
23
+ from cirq.protocols import qid_shape
23
24
 
24
25
  if TYPE_CHECKING:
25
26
  import cirq
@@ -31,7 +32,7 @@ TStateVectorStepResult = TypeVar('TStateVectorStepResult', bound='StateVectorSte
31
32
  class SimulatesIntermediateStateVector(
32
33
  Generic[TStateVectorStepResult],
33
34
  simulator_base.SimulatorBase[
34
- TStateVectorStepResult, 'cirq.StateVectorTrialResult', 'cirq.StateVectorSimulationState',
35
+ TStateVectorStepResult, 'cirq.StateVectorTrialResult', 'cirq.StateVectorSimulationState'
35
36
  ],
36
37
  simulator.SimulatesAmplitudes,
37
38
  metaclass=abc.ABCMeta,
@@ -172,7 +173,7 @@ class StateVectorTrialResult(
172
173
  size = np.prod(shape, dtype=np.int64)
173
174
  final = final.reshape(size)
174
175
  if len([1 for e in final if abs(e) > 0.001]) < 16:
175
- state_vector = qis.dirac_notation(final, 3)
176
+ state_vector = qis.dirac_notation(final, 3, qid_shape(substate.qubits))
176
177
  else:
177
178
  state_vector = str(final)
178
179
  label = f'qubits: {substate.qubits}' if substate.qubits else 'phase:'
@@ -159,6 +159,28 @@ def test_str_big():
159
159
  assert 'output vector: [0.03125+0.j 0.03125+0.j 0.03125+0.j ..' in str(result)
160
160
 
161
161
 
162
+ def test_str_qudit():
163
+ qutrit = cirq.LineQid(0, dimension=3)
164
+ final_simulator_state = cirq.StateVectorSimulationState(
165
+ prng=np.random.RandomState(0),
166
+ qubits=[qutrit],
167
+ initial_state=np.array([0, 0, 1]),
168
+ dtype=np.complex64,
169
+ )
170
+ result = cirq.StateVectorTrialResult(cirq.ParamResolver(), {}, final_simulator_state)
171
+ assert "|2⟩" in str(result)
172
+
173
+ ququart = cirq.LineQid(0, dimension=4)
174
+ final_simulator_state = cirq.StateVectorSimulationState(
175
+ prng=np.random.RandomState(0),
176
+ qubits=[ququart],
177
+ initial_state=np.array([0, 1, 0, 0]),
178
+ dtype=np.complex64,
179
+ )
180
+ result = cirq.StateVectorTrialResult(cirq.ParamResolver(), {}, final_simulator_state)
181
+ assert "|1⟩" in str(result)
182
+
183
+
162
184
  def test_pretty_print():
163
185
  final_simulator_state = cirq.StateVectorSimulationState(
164
186
  available_buffer=np.array([1]),
@@ -37,6 +37,7 @@ from cirq.transformers.analytical_decompositions import (
37
37
  two_qubit_matrix_to_diagonal_and_cz_operations,
38
38
  two_qubit_matrix_to_ion_operations,
39
39
  two_qubit_matrix_to_sqrt_iswap_operations,
40
+ unitary_to_pauli_string,
40
41
  )
41
42
 
42
43
  from cirq.transformers.heuristic_decompositions import (
@@ -71,3 +71,7 @@ from cirq.transformers.analytical_decompositions.two_qubit_state_preparation imp
71
71
  from cirq.transformers.analytical_decompositions.single_to_two_qubit_isometry import (
72
72
  two_qubit_matrix_to_cz_isometry,
73
73
  )
74
+
75
+ from cirq.transformers.analytical_decompositions.pauli_string_decomposition import (
76
+ unitary_to_pauli_string,
77
+ )
@@ -0,0 +1,130 @@
1
+ # Copyright 2023 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 Optional, Tuple, cast
16
+
17
+ import numpy as np
18
+ import numpy.typing as npt
19
+
20
+ from cirq.ops import DensePauliString
21
+ from cirq import protocols
22
+
23
+
24
+ def _argmax(V: npt.NDArray) -> Tuple[int, float]:
25
+ """Returns a tuple (index of max number, max number)."""
26
+ V = (V * V.conj()).real
27
+ idx_max = np.argmax(V)
28
+ V[idx_max] = 0
29
+ return cast(int, idx_max), np.max(V)
30
+
31
+
32
+ def _validate_decomposition(decomposition: DensePauliString, U: npt.NDArray, eps: float) -> bool:
33
+ """Returns whether the max absolute value of the elementwise difference is less than eps."""
34
+ got = protocols.unitary(decomposition)
35
+ return np.abs(got - U).max() < eps
36
+
37
+
38
+ def _fast_walsh_hadamard_transform(V: npt.NDArray) -> None:
39
+ """Fast Walsh–Hadamard Transform of an array."""
40
+ m = len(V)
41
+ n = m.bit_length() - 1
42
+ for h in [2**i for i in range(n)]:
43
+ for i in range(0, m, h * 2):
44
+ for j in range(i, i + h):
45
+ x = V[j]
46
+ y = V[j + h]
47
+ V[j] = x + y
48
+ V[j + h] = x - y
49
+
50
+
51
+ def _conjugate_with_hadamard(U: npt.NDArray) -> npt.NDArray:
52
+ """Applies HcUH in O(n4^n) instead of O(8^n)."""
53
+
54
+ U = np.copy(U.T)
55
+ for i in range(U.shape[1]):
56
+ _fast_walsh_hadamard_transform(U[:, i])
57
+ U = U.T
58
+ for i in range(U.shape[1]):
59
+ _fast_walsh_hadamard_transform(U[:, i])
60
+ return U
61
+
62
+
63
+ def unitary_to_pauli_string(U: npt.NDArray, eps: float = 1e-15) -> Optional[DensePauliString]:
64
+ """Attempts to find a pauli string (with possible phase) equivalent to U up to eps.
65
+
66
+ Based on this answer https://shorturl.at/aA079.
67
+ Let x_mask be the index of the maximum number of the first column of U
68
+ and z_mask be the index of the maximum number of the first column of H†UH
69
+ each of these indicies is n-bits long where U is 2^n x 2^n.
70
+
71
+ These two indices/masks encode in binary the indices of the qubits that
72
+ have I, X, Y, Z acting on them as follows:
73
+ x_mask[i] == 1 and z_mask[i] == 0: X acts on the ith qubit
74
+ x_mask[i] == 0 and z_mask[i] == 1: Z acts on the ith qubit
75
+ x_mask[i] == 1 and z_mask[i] == 1: Y acts on the ith qubit
76
+ x_mask[i] == 0 and z_mask[i] == 0: I acts on the ith qubit
77
+
78
+ Args:
79
+ U: A square array whose dimension is a power of 2.
80
+ eps: numbers smaller than `eps` are considered zero.
81
+
82
+ Returns:
83
+ A DensePauliString of None.
84
+
85
+ Raises:
86
+ ValueError: if U is not square with a power of 2 dimension.
87
+ """
88
+
89
+ if len(U.shape) != 2 or U.shape[0] != U.shape[1]:
90
+ raise ValueError(f'Input has a non-square shape {U}')
91
+ n = U.shape[0].bit_length() - 1
92
+ if U.shape[0] != 2**n:
93
+ raise ValueError(f'Input dimension {U.shape[0]} isn\'t a power of 2')
94
+
95
+ x_msk, second_largest = _argmax(U[:, 0])
96
+ if second_largest > eps:
97
+ return None
98
+ U_z = _conjugate_with_hadamard(U)
99
+ z_msk, second_largest = _argmax(U_z[:, 0])
100
+ if second_largest > eps:
101
+ return None
102
+
103
+ def select(i):
104
+ """Returns the gate that acts on the ith qubit."""
105
+ has_x = (x_msk >> i) & 1
106
+ has_z = (z_msk >> i) & 1
107
+ # The mapping is:
108
+ # - has_x and not has_z => X
109
+ # - not has_x and has_z => Z
110
+ # - has_x and has_z => Y
111
+ # - not has_x and not has_z => I
112
+ gate_table = ['IX', 'ZY']
113
+ return gate_table[has_z][has_x]
114
+
115
+ decomposition = DensePauliString(''.join(select(i) for i in reversed(range(n))))
116
+
117
+ guess = protocols.unitary(decomposition)
118
+ if np.abs(guess[x_msk, 0]) < eps:
119
+ return None
120
+ phase = U[x_msk, 0] / guess[x_msk, 0]
121
+ phase /= np.abs(phase) # Make sure |phase| = 1 to avoid rounding issues.
122
+
123
+ decomposition = DensePauliString(
124
+ ''.join(select(i) for i in reversed(range(n))), coefficient=phase
125
+ )
126
+
127
+ if not _validate_decomposition(decomposition, U, eps):
128
+ return None
129
+
130
+ return decomposition
@@ -0,0 +1,58 @@
1
+ # Copyright 2023 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 cast
16
+ import itertools
17
+ import cmath
18
+ import pytest
19
+
20
+ import numpy as np
21
+
22
+ from cirq.ops import DensePauliString, T
23
+ from cirq import protocols
24
+ from cirq.transformers.analytical_decompositions import unitary_to_pauli_string
25
+
26
+
27
+ @pytest.mark.parametrize('phase', [cmath.exp(i * 2 * cmath.pi / 5 * 1j) for i in range(5)])
28
+ @pytest.mark.parametrize(
29
+ 'pauli_string', [''.join(p) for p in itertools.product(['', 'I', 'X', 'Y', 'Z'], repeat=4)]
30
+ )
31
+ def test_unitary_to_pauli_string(pauli_string: str, phase: complex):
32
+ want = DensePauliString(pauli_string, coefficient=phase)
33
+ got = unitary_to_pauli_string(protocols.unitary(want))
34
+ assert got is not None
35
+ assert np.all(want.pauli_mask == got.pauli_mask)
36
+ assert np.isclose(cast(np.complex128, want.coefficient), cast(np.complex128, got.coefficient))
37
+
38
+
39
+ def test_unitary_to_pauli_string_non_pauli_input():
40
+ got = unitary_to_pauli_string(protocols.unitary(T))
41
+ assert got is None
42
+
43
+ got = unitary_to_pauli_string(np.array([[1, 0], [1, 0]]))
44
+ assert got is None
45
+
46
+ got = unitary_to_pauli_string(np.array([[1, 1], [0, 2]]))
47
+ assert got is None
48
+
49
+ got = unitary_to_pauli_string(np.array([[0, 0.5], [1, -1]]), eps=1.1)
50
+ assert got is None
51
+
52
+
53
+ def test_invalid_input():
54
+ with pytest.raises(ValueError, match='Input has a non-square shape.*'):
55
+ _ = unitary_to_pauli_string(np.zeros((2, 3)))
56
+
57
+ with pytest.raises(ValueError, match='Input dimension [0-9]* isn\'t a power of 2'):
58
+ _ = unitary_to_pauli_string(np.zeros((3, 3)))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cirq-core
3
- Version: 1.2.0.dev20230630133613
3
+ Version: 1.2.0.dev20230705194247
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,7 +4,7 @@ cirq/_compat_test.py,sha256=yaTzjrXRFRHRZ5mom2NFrGP-1SeV7AlnH4fMmL5Jeps,33945
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=H_qyFa81Pjb3TyM5w-ZYVt0mu_CTA0e9Q0NDIa3qVXY,40
7
+ cirq/_version.py,sha256=7EpdLIjdUQ2IgIxJTP_baIEvsey7f3wXAogT8XmQInY,40
8
8
  cirq/_version_test.py,sha256=ZM9GLAiU02rzyJQ_HOT2o_tZixJ0lMXs4tCkOareqTA,133
9
9
  cirq/conftest.py,sha256=mHCDs5--u17oLFDAfIlkTS4TRGSc35eLnZ2CXuIuB7I,1175
10
10
  cirq/json_resolver_cache.py,sha256=JJiO1dhHsEqYClUv68eg-hiOzbb_C1QiQ-BCcvoe4Ck,13067
@@ -897,8 +897,8 @@ cirq/sim/sparse_simulator_test.py,sha256=3EAeCHUQeKllAAtdw14X592zBsGQY_vwfIYK-gE
897
897
  cirq/sim/state_vector.py,sha256=N6N9EELlW66UaLTBaq62ms0XkfIK7CzN9SBM7t52dXo,13428
898
898
  cirq/sim/state_vector_simulation_state.py,sha256=ZTmRdf9J--L3hISroWmW9vgqPvj13s99I2axIgV5x7o,17631
899
899
  cirq/sim/state_vector_simulation_state_test.py,sha256=UtGMIurlV6N74nX7qoVnGoRhwF35-ghDEIP7Mj5AXmI,9841
900
- cirq/sim/state_vector_simulator.py,sha256=d_6s5cBgUVCSCgx6yxzKYlbRp-e9BBfFmlZetN8MIS8,7465
901
- cirq/sim/state_vector_simulator_test.py,sha256=Xl6v_WghJGZtEEK7EHw_1QGoXCVbnvKhVu1K8OJ5D24,7098
900
+ cirq/sim/state_vector_simulator.py,sha256=L2S0xyUGqRcVgYdzYef0gVREVZVIDcCXPclVbIJEpPE,7529
901
+ cirq/sim/state_vector_simulator_test.py,sha256=wJq1OZRzKokeM9cJyaJXi6wHH2qi97h0HmJlYOEBDzU,7864
902
902
  cirq/sim/state_vector_test.py,sha256=OjhAL2tWqJWstHV8RvJYQVqg95zm0PcS9nQKrLOhMmQ,16934
903
903
  cirq/sim/clifford/__init__.py,sha256=lD7l6JuE5n0xwvOYNYH-giCH3qAEVH1SUwDrZM1jKKY,636
904
904
  cirq/sim/clifford/clifford_simulator.py,sha256=6M69sv6IbtJTOk5ZE8CGWiILf6Ee2sCEALiZaw9NmvQ,9735
@@ -999,7 +999,7 @@ cirq/testing/test_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
999
999
  cirq/testing/test_data/test_module_missing_json_test_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1000
1000
  cirq/testing/test_data/test_module_missing_testspec/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1001
1001
  cirq/testing/test_data/test_module_missing_testspec/json_test_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1002
- cirq/transformers/__init__.py,sha256=fMY29-7n94Wg8oaoRTrUyfMLiqd2QUsdZyxQ7Cw4aDM,3714
1002
+ cirq/transformers/__init__.py,sha256=FEYuMxJSn1mW_616HKdb5Ruf_JDNFIjZKPtHTNlJdQ0,3743
1003
1003
  cirq/transformers/align.py,sha256=B4DuX84DWd4tLfMH21JviMZSOFYu7KCOMSEMALYsQpw,2727
1004
1004
  cirq/transformers/align_test.py,sha256=M4etT2cgESv1RdkKASguiGxEuqY7kmI1IswjSi-1jjY,7174
1005
1005
  cirq/transformers/drop_empty_moments.py,sha256=Rtn_BrpwkLXyZBdLzwdnsnEGWTdYuf1xOPakzbpv7-w,1517
@@ -1028,13 +1028,15 @@ cirq/transformers/transformer_api.py,sha256=beDdouAulWeg4SQRwAjgc5H1jrKD0maYY32X
1028
1028
  cirq/transformers/transformer_api_test.py,sha256=f-Vup0VCUvTqJKm5kWHf6xet7sFTerLMGYzJHy8Rc5s,13045
1029
1029
  cirq/transformers/transformer_primitives.py,sha256=0QKiY2pEBzIfGsE4y5fGSfJlehOvHzIVaj10eNyHt8A,31574
1030
1030
  cirq/transformers/transformer_primitives_test.py,sha256=pJhCN28Tev7F04waYRtTlgJEY8fqtBcYJZDPSPUAWLw,41319
1031
- cirq/transformers/analytical_decompositions/__init__.py,sha256=irRBgRfMlIxOoZ6fPM3PM1rKrnLXDYJcp-HfpUlMGe0,2566
1031
+ cirq/transformers/analytical_decompositions/__init__.py,sha256=jUSQkbrFMGRi3ez_TXw8c487dJ_cTF-157JAQcIxUg4,2683
1032
1032
  cirq/transformers/analytical_decompositions/clifford_decomposition.py,sha256=DsuuP91pm2dX0CO4rWwmJAJyAfuXMcA1UJK0g8krp7k,6726
1033
1033
  cirq/transformers/analytical_decompositions/clifford_decomposition_test.py,sha256=AAZh_9vEb5f2E_EItPZTlMRNdv0d47AwqTn4BytX0UI,7102
1034
1034
  cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py,sha256=P-ge3093ayMAEiIf-X_Yv_UuEWkVBEEvJUKobhlXVuA,8554
1035
1035
  cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py,sha256=Pc1vNvRxcYJEERASHbCqPX1bqImGd7FzWnQcUcIo_YU,4950
1036
1036
  cirq/transformers/analytical_decompositions/cphase_to_fsim.py,sha256=RDg0wzYa_YXBJepCgloD_OIwTOwNco98dqGoe0UsnhI,9108
1037
1037
  cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py,sha256=bwZa0BDclAd1sX3bD-GdNF2MO5DtH7mw2YLppEK0LG0,5568
1038
+ cirq/transformers/analytical_decompositions/pauli_string_decomposition.py,sha256=bU9IoY0igVZTmF_wsTdTxAfqPKWyqZ14Gt2AJoK5D_4,4524
1039
+ cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py,sha256=qpFODpCJrE9piYLWR1FzweTn3v80EvLCV-PP2fbHcoE,2112
1038
1040
  cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py,sha256=-ovbhXHeuGcqu1XQd6ZNV3yDrO3JeAEoA_6z5IlPXxE,8326
1039
1041
  cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py,sha256=Q_CGIfaelZEvmTtmkbaPdBosGwqQQjjypAs2DNMCT54,4158
1040
1042
  cirq/transformers/analytical_decompositions/single_qubit_decompositions.py,sha256=iAPdMwHKM1B3mJtQWH-iNjR-VkzhkUDFC23f8kjXY6M,8436
@@ -1136,8 +1138,8 @@ cirq/work/sampler.py,sha256=JVv1vvfa6EgFiR3UeDk44U186dCrioH2NZXueCgsb9w,19828
1136
1138
  cirq/work/sampler_test.py,sha256=zo1Hj6sn6fLs_WZMxYRApBqgBsldmptn74NL0jhNukc,12325
1137
1139
  cirq/work/zeros_sampler.py,sha256=D3hbNZC-jXKuNAWg2OUiUuT8pmDV_WFnEfMank6In4o,2357
1138
1140
  cirq/work/zeros_sampler_test.py,sha256=JIkpBBFPJe5Ba4142vzogyWyboG1Q1ZAm0UVGgOoZn8,3279
1139
- cirq_core-1.2.0.dev20230630133613.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
1140
- cirq_core-1.2.0.dev20230630133613.dist-info/METADATA,sha256=7eaSnkJXjd5mFtGDtcXBV5AR1-YcoBzMG6mSzI242rE,2095
1141
- cirq_core-1.2.0.dev20230630133613.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
1142
- cirq_core-1.2.0.dev20230630133613.dist-info/top_level.txt,sha256=Sz9iOxHU0IEMLSFGwiwOCaN2e9K-jFbBbtpPN1hB73g,5
1143
- cirq_core-1.2.0.dev20230630133613.dist-info/RECORD,,
1141
+ cirq_core-1.2.0.dev20230705194247.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
1142
+ cirq_core-1.2.0.dev20230705194247.dist-info/METADATA,sha256=lJ79DZSV9U2TMMwvinF-uDKEfXlCVj0qxRBW6QbiPB8,2095
1143
+ cirq_core-1.2.0.dev20230705194247.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
1144
+ cirq_core-1.2.0.dev20230705194247.dist-info/top_level.txt,sha256=Sz9iOxHU0IEMLSFGwiwOCaN2e9K-jFbBbtpPN1hB73g,5
1145
+ cirq_core-1.2.0.dev20230705194247.dist-info/RECORD,,