cirq-core 1.6.0.dev20250428201230__py3-none-any.whl → 1.6.0.dev20250429004516__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/protocols/measurement_key_protocol.py +8 -7
- cirq/protocols/pow_protocol.py +7 -7
- cirq/protocols/qasm.py +5 -3
- cirq/protocols/resolve_parameters.py +5 -3
- cirq/qis/clifford_tableau.py +11 -9
- cirq/qis/measures.py +7 -7
- cirq/qis/quantum_state_representation.py +4 -5
- cirq/qis/states.py +19 -17
- cirq/sim/classical_simulator.py +15 -14
- cirq/sim/clifford/clifford_simulator.py +19 -17
- cirq/sim/clifford/clifford_tableau_simulation_state.py +7 -4
- cirq/sim/clifford/stabilizer_ch_form_simulation_state.py +5 -3
- cirq/sim/clifford/stabilizer_sampler.py +6 -4
- cirq/sim/clifford/stabilizer_simulation_state.py +9 -9
- cirq/sim/clifford/stabilizer_state_ch_form.py +6 -4
- cirq/sim/density_matrix_simulation_state.py +17 -18
- cirq/sim/density_matrix_simulator.py +21 -19
- cirq/sim/density_matrix_utils.py +4 -2
- cirq/sim/mux.py +25 -23
- cirq/sim/simulation_product_state.py +12 -12
- cirq/sim/simulation_product_state_test.py +3 -3
- cirq/sim/simulation_state.py +23 -19
- cirq/sim/simulation_state_base.py +16 -12
- cirq/sim/simulation_state_test.py +1 -1
- cirq/sim/simulator.py +71 -72
- cirq/sim/simulator_base.py +22 -23
- cirq/sim/simulator_base_test.py +12 -9
- cirq/sim/simulator_test.py +12 -8
- cirq/sim/sparse_simulator.py +13 -11
- cirq/sim/state_vector.py +9 -6
- cirq/sim/state_vector_simulation_state.py +20 -20
- cirq/sim/state_vector_simulator.py +13 -10
- cirq/study/flatten_expressions.py +8 -5
- cirq/study/resolver.py +12 -9
- cirq/study/result.py +6 -3
- cirq/study/sweeps.py +17 -14
- cirq/testing/consistent_act_on_test.py +2 -2
- cirq/testing/consistent_controlled_gate_op_test.py +10 -6
- cirq/testing/lin_alg_utils.py +8 -7
- cirq/testing/random_circuit.py +17 -16
- cirq/testing/routing_devices.py +4 -1
- cirq/testing/sample_circuits.py +4 -1
- cirq/transformers/align.py +6 -4
- cirq/transformers/analytical_decompositions/clifford_decomposition.py +9 -7
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +15 -13
- cirq/transformers/analytical_decompositions/cphase_to_fsim.py +7 -5
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +10 -8
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +6 -3
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +8 -10
- {cirq_core-1.6.0.dev20250428201230.dist-info → cirq_core-1.6.0.dev20250429004516.dist-info}/METADATA +1 -1
- {cirq_core-1.6.0.dev20250428201230.dist-info → cirq_core-1.6.0.dev20250429004516.dist-info}/RECORD +56 -56
- {cirq_core-1.6.0.dev20250428201230.dist-info → cirq_core-1.6.0.dev20250429004516.dist-info}/WHEEL +0 -0
- {cirq_core-1.6.0.dev20250428201230.dist-info → cirq_core-1.6.0.dev20250429004516.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.6.0.dev20250428201230.dist-info → cirq_core-1.6.0.dev20250429004516.dist-info}/top_level.txt +0 -0
cirq/sim/sparse_simulator.py
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
"""A simulator that uses numpy's einsum for sparse matrix operations."""
|
|
16
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
17
19
|
from typing import Any, Iterator, List, Optional, Sequence, Type, TYPE_CHECKING, Union
|
|
18
20
|
|
|
19
21
|
import numpy as np
|
|
@@ -126,8 +128,8 @@ class Simulator(
|
|
|
126
128
|
self,
|
|
127
129
|
*,
|
|
128
130
|
dtype: Type[np.complexfloating] = np.complex64,
|
|
129
|
-
noise:
|
|
130
|
-
seed:
|
|
131
|
+
noise: cirq.NOISE_MODEL_LIKE = None,
|
|
132
|
+
seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
131
133
|
split_untangled_states: bool = True,
|
|
132
134
|
):
|
|
133
135
|
"""A sparse matrix simulator.
|
|
@@ -152,9 +154,9 @@ class Simulator(
|
|
|
152
154
|
|
|
153
155
|
def _create_partial_simulation_state(
|
|
154
156
|
self,
|
|
155
|
-
initial_state: Union[
|
|
156
|
-
qubits: Sequence[
|
|
157
|
-
classical_data:
|
|
157
|
+
initial_state: Union[cirq.STATE_VECTOR_LIKE, cirq.StateVectorSimulationState],
|
|
158
|
+
qubits: Sequence[cirq.Qid],
|
|
159
|
+
classical_data: cirq.ClassicalDataStore,
|
|
158
160
|
):
|
|
159
161
|
"""Creates the StateVectorSimulationState for a circuit.
|
|
160
162
|
|
|
@@ -183,16 +185,16 @@ class Simulator(
|
|
|
183
185
|
)
|
|
184
186
|
|
|
185
187
|
def _create_step_result(
|
|
186
|
-
self, sim_state:
|
|
188
|
+
self, sim_state: cirq.SimulationStateBase[cirq.StateVectorSimulationState]
|
|
187
189
|
):
|
|
188
190
|
return SparseSimulatorStep(sim_state=sim_state, dtype=self._dtype)
|
|
189
191
|
|
|
190
192
|
def simulate_expectation_values_sweep_iter(
|
|
191
193
|
self,
|
|
192
|
-
program:
|
|
193
|
-
observables: Union[
|
|
194
|
-
params:
|
|
195
|
-
qubit_order:
|
|
194
|
+
program: cirq.AbstractCircuit,
|
|
195
|
+
observables: Union[cirq.PauliSumLike, List[cirq.PauliSumLike]],
|
|
196
|
+
params: cirq.Sweepable,
|
|
197
|
+
qubit_order: cirq.QubitOrderOrList = ops.QubitOrder.DEFAULT,
|
|
196
198
|
initial_state: Any = None,
|
|
197
199
|
permit_terminal_measurements: bool = False,
|
|
198
200
|
) -> Iterator[List[float]]:
|
|
@@ -222,7 +224,7 @@ class SparseSimulatorStep(
|
|
|
222
224
|
|
|
223
225
|
def __init__(
|
|
224
226
|
self,
|
|
225
|
-
sim_state:
|
|
227
|
+
sim_state: cirq.SimulationStateBase[cirq.StateVectorSimulationState],
|
|
226
228
|
dtype: Type[np.complexfloating] = np.complex64,
|
|
227
229
|
):
|
|
228
230
|
"""Results of a step of the simulator.
|
cirq/sim/state_vector.py
CHANGED
|
@@ -11,8 +11,11 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
"""Helpers for handling quantum state vectors."""
|
|
15
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
16
19
|
import abc
|
|
17
20
|
from typing import List, Mapping, Optional, Sequence, Tuple, TYPE_CHECKING
|
|
18
21
|
|
|
@@ -31,7 +34,7 @@ if TYPE_CHECKING:
|
|
|
31
34
|
class StateVectorMixin:
|
|
32
35
|
"""A mixin that provide methods for objects that have a state vector."""
|
|
33
36
|
|
|
34
|
-
def __init__(self, qubit_map: Optional[Mapping[
|
|
37
|
+
def __init__(self, qubit_map: Optional[Mapping[cirq.Qid, int]] = None, *args, **kwargs):
|
|
35
38
|
"""Inits StateVectorMixin.
|
|
36
39
|
|
|
37
40
|
Args:
|
|
@@ -47,7 +50,7 @@ class StateVectorMixin:
|
|
|
47
50
|
self._qid_shape = None if qubit_map is None else qid_shape
|
|
48
51
|
|
|
49
52
|
@property
|
|
50
|
-
def qubit_map(self) -> Mapping[
|
|
53
|
+
def qubit_map(self) -> Mapping[cirq.Qid, int]:
|
|
51
54
|
return self._qubit_map
|
|
52
55
|
|
|
53
56
|
def _qid_shape_(self) -> Tuple[int, ...]:
|
|
@@ -102,7 +105,7 @@ class StateVectorMixin:
|
|
|
102
105
|
and non-zero floats of the specified accuracy."""
|
|
103
106
|
return qis.dirac_notation(self.state_vector(), decimals, qid_shape=self._qid_shape)
|
|
104
107
|
|
|
105
|
-
def density_matrix_of(self, qubits: Optional[List[
|
|
108
|
+
def density_matrix_of(self, qubits: Optional[List[cirq.Qid]] = None) -> np.ndarray:
|
|
106
109
|
r"""Returns the density matrix of the state.
|
|
107
110
|
|
|
108
111
|
Calculate the density matrix for the system on the qubits provided.
|
|
@@ -141,7 +144,7 @@ class StateVectorMixin:
|
|
|
141
144
|
qid_shape=self._qid_shape,
|
|
142
145
|
)
|
|
143
146
|
|
|
144
|
-
def bloch_vector_of(self, qubit:
|
|
147
|
+
def bloch_vector_of(self, qubit: cirq.Qid) -> np.ndarray:
|
|
145
148
|
"""Returns the bloch vector of a qubit in the state.
|
|
146
149
|
|
|
147
150
|
Calculates the bloch vector of the given qubit
|
|
@@ -171,7 +174,7 @@ def sample_state_vector(
|
|
|
171
174
|
*, # Force keyword args
|
|
172
175
|
qid_shape: Optional[Tuple[int, ...]] = None,
|
|
173
176
|
repetitions: int = 1,
|
|
174
|
-
seed:
|
|
177
|
+
seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
175
178
|
) -> np.ndarray:
|
|
176
179
|
"""Samples repeatedly from measurements in the computational basis.
|
|
177
180
|
|
|
@@ -236,7 +239,7 @@ def measure_state_vector(
|
|
|
236
239
|
*, # Force keyword args
|
|
237
240
|
qid_shape: Optional[Tuple[int, ...]] = None,
|
|
238
241
|
out: Optional[np.ndarray] = None,
|
|
239
|
-
seed:
|
|
242
|
+
seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
240
243
|
) -> Tuple[List[int], np.ndarray]:
|
|
241
244
|
"""Performs a measurement of the state in the computational basis.
|
|
242
245
|
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Objects and methods for acting efficiently on a state vector."""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
16
19
|
from typing import Any, Callable, List, Optional, Sequence, Tuple, Type, TYPE_CHECKING, Union
|
|
17
20
|
|
|
18
21
|
import numpy as np
|
|
@@ -50,7 +53,7 @@ class _BufferedStateVector(qis.QuantumStateRepresentation):
|
|
|
50
53
|
def create(
|
|
51
54
|
cls,
|
|
52
55
|
*,
|
|
53
|
-
initial_state: Union[np.ndarray,
|
|
56
|
+
initial_state: Union[np.ndarray, cirq.STATE_VECTOR_LIKE] = 0,
|
|
54
57
|
qid_shape: Optional[Tuple[int, ...]] = None,
|
|
55
58
|
dtype: Optional[Type[np.complexfloating]] = None,
|
|
56
59
|
buffer: Optional[np.ndarray] = None,
|
|
@@ -85,7 +88,7 @@ class _BufferedStateVector(qis.QuantumStateRepresentation):
|
|
|
85
88
|
state_vector = state_vector.astype(dtype, copy=False)
|
|
86
89
|
return cls(state_vector, buffer)
|
|
87
90
|
|
|
88
|
-
def copy(self, deep_copy_buffers: bool = True) ->
|
|
91
|
+
def copy(self, deep_copy_buffers: bool = True) -> _BufferedStateVector:
|
|
89
92
|
"""Copies the object.
|
|
90
93
|
|
|
91
94
|
Args:
|
|
@@ -98,7 +101,7 @@ class _BufferedStateVector(qis.QuantumStateRepresentation):
|
|
|
98
101
|
buffer=self._buffer.copy() if deep_copy_buffers else self._buffer,
|
|
99
102
|
)
|
|
100
103
|
|
|
101
|
-
def kron(self, other:
|
|
104
|
+
def kron(self, other: _BufferedStateVector) -> _BufferedStateVector:
|
|
102
105
|
"""Creates the Kronecker product with the other state vector.
|
|
103
106
|
|
|
104
107
|
Args:
|
|
@@ -113,7 +116,7 @@ class _BufferedStateVector(qis.QuantumStateRepresentation):
|
|
|
113
116
|
|
|
114
117
|
def factor(
|
|
115
118
|
self, axes: Sequence[int], *, validate=True, atol=1e-07
|
|
116
|
-
) -> Tuple[
|
|
119
|
+
) -> Tuple[_BufferedStateVector, _BufferedStateVector]:
|
|
117
120
|
"""Factors a state vector into two independent state vectors.
|
|
118
121
|
|
|
119
122
|
This function should only be called on state vectors that are known to be separable, such
|
|
@@ -143,7 +146,7 @@ class _BufferedStateVector(qis.QuantumStateRepresentation):
|
|
|
143
146
|
)
|
|
144
147
|
return extracted, remainder
|
|
145
148
|
|
|
146
|
-
def reindex(self, axes: Sequence[int]) ->
|
|
149
|
+
def reindex(self, axes: Sequence[int]) -> _BufferedStateVector:
|
|
147
150
|
"""Transposes the axes of a state vector to a specified order.
|
|
148
151
|
|
|
149
152
|
Args:
|
|
@@ -253,7 +256,7 @@ class _BufferedStateVector(qis.QuantumStateRepresentation):
|
|
|
253
256
|
return index
|
|
254
257
|
|
|
255
258
|
def measure(
|
|
256
|
-
self, axes: Sequence[int], seed:
|
|
259
|
+
self, axes: Sequence[int], seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None
|
|
257
260
|
) -> List[int]:
|
|
258
261
|
"""Measures the state vector.
|
|
259
262
|
|
|
@@ -269,10 +272,7 @@ class _BufferedStateVector(qis.QuantumStateRepresentation):
|
|
|
269
272
|
return bits
|
|
270
273
|
|
|
271
274
|
def sample(
|
|
272
|
-
self,
|
|
273
|
-
axes: Sequence[int],
|
|
274
|
-
repetitions: int = 1,
|
|
275
|
-
seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
|
|
275
|
+
self, axes: Sequence[int], repetitions: int = 1, seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None
|
|
276
276
|
) -> np.ndarray:
|
|
277
277
|
"""Samples the state vector.
|
|
278
278
|
|
|
@@ -322,10 +322,10 @@ class StateVectorSimulationState(SimulationState[_BufferedStateVector]):
|
|
|
322
322
|
*,
|
|
323
323
|
available_buffer: Optional[np.ndarray] = None,
|
|
324
324
|
prng: Optional[np.random.RandomState] = None,
|
|
325
|
-
qubits: Optional[Sequence[
|
|
326
|
-
initial_state: Union[np.ndarray,
|
|
325
|
+
qubits: Optional[Sequence[cirq.Qid]] = None,
|
|
326
|
+
initial_state: Union[np.ndarray, cirq.STATE_VECTOR_LIKE] = 0,
|
|
327
327
|
dtype: Type[np.complexfloating] = np.complex64,
|
|
328
|
-
classical_data: Optional[
|
|
328
|
+
classical_data: Optional[cirq.ClassicalDataStore] = None,
|
|
329
329
|
):
|
|
330
330
|
"""Inits StateVectorSimulationState.
|
|
331
331
|
|
|
@@ -356,7 +356,7 @@ class StateVectorSimulationState(SimulationState[_BufferedStateVector]):
|
|
|
356
356
|
)
|
|
357
357
|
super().__init__(state=state, prng=prng, qubits=qubits, classical_data=classical_data)
|
|
358
358
|
|
|
359
|
-
def add_qubits(self, qubits: Sequence[
|
|
359
|
+
def add_qubits(self, qubits: Sequence[cirq.Qid]):
|
|
360
360
|
ret = super().add_qubits(qubits)
|
|
361
361
|
return (
|
|
362
362
|
self.kronecker_product(type(self)(qubits=qubits), inplace=True)
|
|
@@ -364,7 +364,7 @@ class StateVectorSimulationState(SimulationState[_BufferedStateVector]):
|
|
|
364
364
|
else ret
|
|
365
365
|
)
|
|
366
366
|
|
|
367
|
-
def remove_qubits(self, qubits: Sequence[
|
|
367
|
+
def remove_qubits(self, qubits: Sequence[cirq.Qid]):
|
|
368
368
|
ret = super().remove_qubits(qubits)
|
|
369
369
|
if ret is not NotImplemented:
|
|
370
370
|
return ret
|
|
@@ -373,9 +373,9 @@ class StateVectorSimulationState(SimulationState[_BufferedStateVector]):
|
|
|
373
373
|
return remainder
|
|
374
374
|
|
|
375
375
|
def _act_on_fallback_(
|
|
376
|
-
self, action: Any, qubits: Sequence[
|
|
376
|
+
self, action: Any, qubits: Sequence[cirq.Qid], allow_decompose: bool = True
|
|
377
377
|
) -> bool:
|
|
378
|
-
strats: List[Callable[[Any, Any, Sequence[
|
|
378
|
+
strats: List[Callable[[Any, Any, Sequence[cirq.Qid]], bool]] = [
|
|
379
379
|
_strat_act_on_state_vector_from_apply_unitary,
|
|
380
380
|
_strat_act_on_state_vector_from_mixture,
|
|
381
381
|
_strat_act_on_state_vector_from_channel,
|
|
@@ -415,7 +415,7 @@ class StateVectorSimulationState(SimulationState[_BufferedStateVector]):
|
|
|
415
415
|
|
|
416
416
|
|
|
417
417
|
def _strat_act_on_state_vector_from_apply_unitary(
|
|
418
|
-
action: Any, args:
|
|
418
|
+
action: Any, args: cirq.StateVectorSimulationState, qubits: Sequence[cirq.Qid]
|
|
419
419
|
) -> bool:
|
|
420
420
|
if not args._state.apply_unitary(action, args.get_axes(qubits)):
|
|
421
421
|
return NotImplemented
|
|
@@ -423,7 +423,7 @@ def _strat_act_on_state_vector_from_apply_unitary(
|
|
|
423
423
|
|
|
424
424
|
|
|
425
425
|
def _strat_act_on_state_vector_from_mixture(
|
|
426
|
-
action: Any, args:
|
|
426
|
+
action: Any, args: cirq.StateVectorSimulationState, qubits: Sequence[cirq.Qid]
|
|
427
427
|
) -> bool:
|
|
428
428
|
index = args._state.apply_mixture(action, args.get_axes(qubits), args.prng)
|
|
429
429
|
if index is None:
|
|
@@ -435,7 +435,7 @@ def _strat_act_on_state_vector_from_mixture(
|
|
|
435
435
|
|
|
436
436
|
|
|
437
437
|
def _strat_act_on_state_vector_from_channel(
|
|
438
|
-
action: Any, args:
|
|
438
|
+
action: Any, args: cirq.StateVectorSimulationState, qubits: Sequence[cirq.Qid]
|
|
439
439
|
) -> bool:
|
|
440
440
|
index = args._state.apply_channel(action, args.get_axes(qubits), args.prng)
|
|
441
441
|
if index is None:
|
|
@@ -11,8 +11,11 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
"""Abstract classes for simulations which keep track of state vector."""
|
|
15
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
16
19
|
import abc
|
|
17
20
|
import warnings
|
|
18
21
|
from functools import cached_property
|
|
@@ -48,8 +51,8 @@ class SimulatesIntermediateStateVector(
|
|
|
48
51
|
self,
|
|
49
52
|
*,
|
|
50
53
|
dtype: Type[np.complexfloating] = np.complex64,
|
|
51
|
-
noise:
|
|
52
|
-
seed:
|
|
54
|
+
noise: cirq.NOISE_MODEL_LIKE = None,
|
|
55
|
+
seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
53
56
|
split_untangled_states: bool = False,
|
|
54
57
|
):
|
|
55
58
|
super().__init__(
|
|
@@ -58,20 +61,20 @@ class SimulatesIntermediateStateVector(
|
|
|
58
61
|
|
|
59
62
|
def _create_simulator_trial_result(
|
|
60
63
|
self,
|
|
61
|
-
params:
|
|
64
|
+
params: cirq.ParamResolver,
|
|
62
65
|
measurements: Dict[str, np.ndarray],
|
|
63
|
-
final_simulator_state:
|
|
64
|
-
) ->
|
|
66
|
+
final_simulator_state: cirq.SimulationStateBase[cirq.StateVectorSimulationState],
|
|
67
|
+
) -> cirq.StateVectorTrialResult:
|
|
65
68
|
return StateVectorTrialResult(
|
|
66
69
|
params=params, measurements=measurements, final_simulator_state=final_simulator_state
|
|
67
70
|
)
|
|
68
71
|
|
|
69
72
|
def compute_amplitudes_sweep_iter(
|
|
70
73
|
self,
|
|
71
|
-
program:
|
|
74
|
+
program: cirq.AbstractCircuit,
|
|
72
75
|
bitstrings: Sequence[int],
|
|
73
|
-
params:
|
|
74
|
-
qubit_order:
|
|
76
|
+
params: cirq.Sweepable,
|
|
77
|
+
qubit_order: cirq.QubitOrderOrList = ops.QubitOrder.DEFAULT,
|
|
75
78
|
) -> Iterator[Sequence[complex]]:
|
|
76
79
|
if isinstance(bitstrings, np.ndarray) and len(bitstrings.shape) > 1:
|
|
77
80
|
raise ValueError(
|
|
@@ -112,9 +115,9 @@ class StateVectorTrialResult(
|
|
|
112
115
|
|
|
113
116
|
def __init__(
|
|
114
117
|
self,
|
|
115
|
-
params:
|
|
118
|
+
params: cirq.ParamResolver,
|
|
116
119
|
measurements: Dict[str, np.ndarray],
|
|
117
|
-
final_simulator_state:
|
|
120
|
+
final_simulator_state: cirq.SimulationStateBase[cirq.StateVectorSimulationState],
|
|
118
121
|
) -> None:
|
|
119
122
|
super().__init__(
|
|
120
123
|
params=params,
|
|
@@ -11,8 +11,11 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
"""Resolves symbolic expressions to unique symbols."""
|
|
15
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
16
19
|
import numbers
|
|
17
20
|
from typing import Any, Callable, List, Optional, Tuple, TYPE_CHECKING, Union
|
|
18
21
|
|
|
@@ -25,7 +28,7 @@ if TYPE_CHECKING:
|
|
|
25
28
|
import cirq
|
|
26
29
|
|
|
27
30
|
|
|
28
|
-
def flatten(val: Any) -> Tuple[Any,
|
|
31
|
+
def flatten(val: Any) -> Tuple[Any, ExpressionMap]:
|
|
29
32
|
"""Creates a copy of `val` with any symbols or expressions replaced with
|
|
30
33
|
new symbols. `val` can be a `Circuit`, `Gate`, `Operation`, or other
|
|
31
34
|
type.
|
|
@@ -250,8 +253,8 @@ class _ParamFlattener(resolver.ParamResolver):
|
|
|
250
253
|
return symbol
|
|
251
254
|
|
|
252
255
|
def value_of(
|
|
253
|
-
self, value: Union[
|
|
254
|
-
) ->
|
|
256
|
+
self, value: Union[cirq.TParamKey, cirq.TParamValComplex], recursive: bool = False
|
|
257
|
+
) -> cirq.TParamValComplex:
|
|
255
258
|
"""Resolves a symbol or expression to a new symbol unique to that value.
|
|
256
259
|
|
|
257
260
|
- If value is a float, returns it.
|
|
@@ -380,8 +383,8 @@ class ExpressionMap(dict):
|
|
|
380
383
|
|
|
381
384
|
|
|
382
385
|
def _ensure_not_str(
|
|
383
|
-
param: Union[sympy.Expr,
|
|
384
|
-
) -> Union[sympy.Expr,
|
|
386
|
+
param: Union[sympy.Expr, cirq.TParamValComplex, str],
|
|
387
|
+
) -> Union[sympy.Expr, cirq.TParamValComplex]:
|
|
385
388
|
if isinstance(param, str):
|
|
386
389
|
return sympy.Symbol(param)
|
|
387
390
|
return param
|
cirq/study/resolver.py
CHANGED
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Resolves ParameterValues to assigned values."""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
16
19
|
import numbers
|
|
17
20
|
from typing import Any, cast, Dict, Iterator, Mapping, Optional, TYPE_CHECKING, Union
|
|
18
21
|
|
|
@@ -61,12 +64,12 @@ class ParamResolver:
|
|
|
61
64
|
TypeError if formulas are passed as keys.
|
|
62
65
|
"""
|
|
63
66
|
|
|
64
|
-
def __new__(cls, param_dict:
|
|
67
|
+
def __new__(cls, param_dict: cirq.ParamResolverOrSimilarType = None):
|
|
65
68
|
if isinstance(param_dict, ParamResolver):
|
|
66
69
|
return param_dict
|
|
67
70
|
return super().__new__(cls)
|
|
68
71
|
|
|
69
|
-
def __init__(self, param_dict:
|
|
72
|
+
def __init__(self, param_dict: cirq.ParamResolverOrSimilarType = None) -> None:
|
|
70
73
|
if hasattr(self, 'param_dict'):
|
|
71
74
|
return # Already initialized. Got wrapped as part of the __new__.
|
|
72
75
|
|
|
@@ -82,8 +85,8 @@ class ParamResolver:
|
|
|
82
85
|
return self._param_dict
|
|
83
86
|
|
|
84
87
|
def value_of(
|
|
85
|
-
self, value: Union[
|
|
86
|
-
) ->
|
|
88
|
+
self, value: Union[cirq.TParamKey, cirq.TParamValComplex], recursive: bool = True
|
|
89
|
+
) -> cirq.TParamValComplex:
|
|
87
90
|
"""Attempt to resolve a parameter to its assigned value.
|
|
88
91
|
|
|
89
92
|
Scalars are returned without modification. Strings are resolved via
|
|
@@ -193,7 +196,7 @@ class ParamResolver:
|
|
|
193
196
|
|
|
194
197
|
return self._value_of_recursive(value)
|
|
195
198
|
|
|
196
|
-
def _value_of_recursive(self, value:
|
|
199
|
+
def _value_of_recursive(self, value: cirq.TParamKey) -> cirq.TParamValComplex:
|
|
197
200
|
# Recursive parameter resolution. We can safely assume that value is a
|
|
198
201
|
# single symbol, since combinations are handled earlier in the method.
|
|
199
202
|
if value in self._deep_eval_map:
|
|
@@ -213,8 +216,8 @@ class ParamResolver:
|
|
|
213
216
|
self._deep_eval_map[value] = self.value_of(v, recursive=True)
|
|
214
217
|
return self._deep_eval_map[value]
|
|
215
218
|
|
|
216
|
-
def _resolve_parameters_(self, resolver:
|
|
217
|
-
new_dict: Dict[
|
|
219
|
+
def _resolve_parameters_(self, resolver: ParamResolver, recursive: bool) -> ParamResolver:
|
|
220
|
+
new_dict: Dict[cirq.TParamKey, Union[float, str, sympy.Symbol, sympy.Expr]] = {
|
|
218
221
|
k: k for k in resolver
|
|
219
222
|
}
|
|
220
223
|
new_dict.update({k: self.value_of(k, recursive) for k in self})
|
|
@@ -232,8 +235,8 @@ class ParamResolver:
|
|
|
232
235
|
return bool(self._param_dict)
|
|
233
236
|
|
|
234
237
|
def __getitem__(
|
|
235
|
-
self, key: Union[
|
|
236
|
-
) ->
|
|
238
|
+
self, key: Union[cirq.TParamKey, cirq.TParamValComplex]
|
|
239
|
+
) -> cirq.TParamValComplex:
|
|
237
240
|
return self.value_of(key)
|
|
238
241
|
|
|
239
242
|
def __hash__(self) -> int:
|
cirq/study/result.py
CHANGED
|
@@ -11,8 +11,11 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
"""Defines trial results."""
|
|
15
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
16
19
|
import abc
|
|
17
20
|
import collections
|
|
18
21
|
import io
|
|
@@ -99,7 +102,7 @@ class Result(abc.ABC):
|
|
|
99
102
|
|
|
100
103
|
@property
|
|
101
104
|
@abc.abstractmethod
|
|
102
|
-
def params(self) ->
|
|
105
|
+
def params(self) -> cirq.ParamResolver:
|
|
103
106
|
"""A ParamResolver of settings used for this result."""
|
|
104
107
|
|
|
105
108
|
@property
|
|
@@ -275,7 +278,7 @@ class Result(abc.ABC):
|
|
|
275
278
|
and self.params == other.params
|
|
276
279
|
)
|
|
277
280
|
|
|
278
|
-
def __add__(self, other:
|
|
281
|
+
def __add__(self, other: cirq.Result) -> cirq.Result:
|
|
279
282
|
if not isinstance(other, Result):
|
|
280
283
|
return NotImplemented
|
|
281
284
|
if self.params != other.params:
|
|
@@ -341,7 +344,7 @@ class ResultDict(Result):
|
|
|
341
344
|
self._data: Optional[pd.DataFrame] = None
|
|
342
345
|
|
|
343
346
|
@property
|
|
344
|
-
def params(self) ->
|
|
347
|
+
def params(self) -> cirq.ParamResolver:
|
|
345
348
|
return self._params
|
|
346
349
|
|
|
347
350
|
@property
|
cirq/study/sweeps.py
CHANGED
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
14
17
|
import abc
|
|
15
18
|
import collections
|
|
16
19
|
import itertools
|
|
@@ -71,7 +74,7 @@ class Sweep(metaclass=abc.ABCMeta):
|
|
|
71
74
|
see the Product and Zip documentation.
|
|
72
75
|
"""
|
|
73
76
|
|
|
74
|
-
def __mul__(self, other:
|
|
77
|
+
def __mul__(self, other: Sweep) -> Sweep:
|
|
75
78
|
factors: List[Sweep] = []
|
|
76
79
|
if isinstance(self, Product):
|
|
77
80
|
factors.extend(self.factors)
|
|
@@ -85,7 +88,7 @@ class Sweep(metaclass=abc.ABCMeta):
|
|
|
85
88
|
raise TypeError(f'cannot multiply sweep and {type(other)}')
|
|
86
89
|
return Product(*factors)
|
|
87
90
|
|
|
88
|
-
def __add__(self, other:
|
|
91
|
+
def __add__(self, other: Sweep) -> Sweep:
|
|
89
92
|
sweeps: List[Sweep] = []
|
|
90
93
|
if isinstance(self, Zip):
|
|
91
94
|
sweeps.extend(self.sweeps)
|
|
@@ -108,7 +111,7 @@ class Sweep(metaclass=abc.ABCMeta):
|
|
|
108
111
|
|
|
109
112
|
@property
|
|
110
113
|
@abc.abstractmethod
|
|
111
|
-
def keys(self) -> List[
|
|
114
|
+
def keys(self) -> List[cirq.TParamKey]:
|
|
112
115
|
"""The keys for the all of the sympy.Symbols that are resolved."""
|
|
113
116
|
|
|
114
117
|
@abc.abstractmethod
|
|
@@ -125,10 +128,10 @@ class Sweep(metaclass=abc.ABCMeta):
|
|
|
125
128
|
pass
|
|
126
129
|
|
|
127
130
|
@overload
|
|
128
|
-
def __getitem__(self, val: slice) ->
|
|
131
|
+
def __getitem__(self, val: slice) -> Sweep:
|
|
129
132
|
pass
|
|
130
133
|
|
|
131
|
-
def __getitem__(self, val: Union[int, slice]) -> Union[resolver.ParamResolver,
|
|
134
|
+
def __getitem__(self, val: Union[int, slice]) -> Union[resolver.ParamResolver, Sweep]:
|
|
132
135
|
n = len(self)
|
|
133
136
|
if isinstance(val, int):
|
|
134
137
|
if val < -n or val >= n:
|
|
@@ -186,7 +189,7 @@ class _Unit(Sweep):
|
|
|
186
189
|
return True
|
|
187
190
|
|
|
188
191
|
@property
|
|
189
|
-
def keys(self) -> List[
|
|
192
|
+
def keys(self) -> List[cirq.TParamKey]:
|
|
190
193
|
return []
|
|
191
194
|
|
|
192
195
|
def __len__(self) -> int:
|
|
@@ -233,7 +236,7 @@ class Product(Sweep):
|
|
|
233
236
|
return hash(tuple(self.factors))
|
|
234
237
|
|
|
235
238
|
@property
|
|
236
|
-
def keys(self) -> List[
|
|
239
|
+
def keys(self) -> List[cirq.TParamKey]:
|
|
237
240
|
return sum((factor.keys for factor in self.factors), [])
|
|
238
241
|
|
|
239
242
|
def __len__(self) -> int:
|
|
@@ -308,7 +311,7 @@ class Concat(Sweep):
|
|
|
308
311
|
return hash(tuple(self.sweeps))
|
|
309
312
|
|
|
310
313
|
@property
|
|
311
|
-
def keys(self) -> List[
|
|
314
|
+
def keys(self) -> List[cirq.TParamKey]:
|
|
312
315
|
return self.sweeps[0].keys
|
|
313
316
|
|
|
314
317
|
def __len__(self) -> int:
|
|
@@ -361,7 +364,7 @@ class Zip(Sweep):
|
|
|
361
364
|
return hash(tuple(self.sweeps))
|
|
362
365
|
|
|
363
366
|
@property
|
|
364
|
-
def keys(self) -> List[
|
|
367
|
+
def keys(self) -> List[cirq.TParamKey]:
|
|
365
368
|
return sum((sweep.keys for sweep in self.sweeps), [])
|
|
366
369
|
|
|
367
370
|
def __len__(self) -> int:
|
|
@@ -449,7 +452,7 @@ class ZipLongest(Zip):
|
|
|
449
452
|
class SingleSweep(Sweep):
|
|
450
453
|
"""A simple sweep over one parameter with values from an iterator."""
|
|
451
454
|
|
|
452
|
-
def __init__(self, key:
|
|
455
|
+
def __init__(self, key: cirq.TParamKey) -> None:
|
|
453
456
|
if isinstance(key, sympy.Symbol):
|
|
454
457
|
key = str(key)
|
|
455
458
|
self.key = key
|
|
@@ -467,7 +470,7 @@ class SingleSweep(Sweep):
|
|
|
467
470
|
pass
|
|
468
471
|
|
|
469
472
|
@property
|
|
470
|
-
def keys(self) -> List[
|
|
473
|
+
def keys(self) -> List[cirq.TParamKey]:
|
|
471
474
|
return [self.key]
|
|
472
475
|
|
|
473
476
|
def param_tuples(self) -> Iterator[Params]:
|
|
@@ -483,7 +486,7 @@ class Points(SingleSweep):
|
|
|
483
486
|
"""A simple sweep with explicitly supplied values."""
|
|
484
487
|
|
|
485
488
|
def __init__(
|
|
486
|
-
self, key:
|
|
489
|
+
self, key: cirq.TParamKey, points: Sequence[float], metadata: Optional[Any] = None
|
|
487
490
|
) -> None:
|
|
488
491
|
"""Creates a sweep on a variable with supplied values.
|
|
489
492
|
|
|
@@ -524,7 +527,7 @@ class Linspace(SingleSweep):
|
|
|
524
527
|
|
|
525
528
|
def __init__(
|
|
526
529
|
self,
|
|
527
|
-
key:
|
|
530
|
+
key: cirq.TParamKey,
|
|
528
531
|
start: float,
|
|
529
532
|
stop: float,
|
|
530
533
|
length: int,
|
|
@@ -607,7 +610,7 @@ class ListSweep(Sweep):
|
|
|
607
610
|
return not self == other
|
|
608
611
|
|
|
609
612
|
@property
|
|
610
|
-
def keys(self) -> List[
|
|
613
|
+
def keys(self) -> List[cirq.TParamKey]:
|
|
611
614
|
if not self.resolver_list:
|
|
612
615
|
return []
|
|
613
616
|
return list(map(str, self.resolver_list[0].param_dict))
|
|
@@ -24,7 +24,7 @@ class GoodGate(cirq.testing.SingleQubitGate):
|
|
|
24
24
|
def _unitary_(self):
|
|
25
25
|
return np.array([[0, 1], [1, 0]])
|
|
26
26
|
|
|
27
|
-
def _act_on_(self, sim_state:
|
|
27
|
+
def _act_on_(self, sim_state: cirq.SimulationStateBase, qubits: Sequence[cirq.Qid]):
|
|
28
28
|
if isinstance(sim_state, cirq.CliffordTableauSimulationState):
|
|
29
29
|
tableau = sim_state.tableau
|
|
30
30
|
q = sim_state.qubit_map[qubits[0]]
|
|
@@ -37,7 +37,7 @@ class BadGate(cirq.testing.SingleQubitGate):
|
|
|
37
37
|
def _unitary_(self):
|
|
38
38
|
return np.array([[0, 1j], [1, 0]])
|
|
39
39
|
|
|
40
|
-
def _act_on_(self, sim_state:
|
|
40
|
+
def _act_on_(self, sim_state: cirq.SimulationStateBase, qubits: Sequence[cirq.Qid]):
|
|
41
41
|
if isinstance(sim_state, cirq.CliffordTableauSimulationState):
|
|
42
42
|
tableau = sim_state.tableau
|
|
43
43
|
q = sim_state.qubit_map[qubits[0]]
|
|
@@ -12,13 +12,17 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
from
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from typing import Collection, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
|
|
16
18
|
|
|
17
19
|
import numpy as np
|
|
18
20
|
import pytest
|
|
19
21
|
|
|
20
22
|
import cirq
|
|
21
|
-
|
|
23
|
+
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
from cirq.ops import control_values as cv
|
|
22
26
|
|
|
23
27
|
|
|
24
28
|
class GoodGate(cirq.EigenGate, cirq.testing.SingleQubitGate):
|
|
@@ -29,11 +33,11 @@ class GoodGate(cirq.EigenGate, cirq.testing.SingleQubitGate):
|
|
|
29
33
|
class BadGateOperation(cirq.GateOperation):
|
|
30
34
|
def controlled_by(
|
|
31
35
|
self,
|
|
32
|
-
*control_qubits:
|
|
36
|
+
*control_qubits: cirq.Qid,
|
|
33
37
|
control_values: Optional[
|
|
34
38
|
Union[cv.AbstractControlValues, Sequence[Union[int, Collection[int]]]]
|
|
35
39
|
] = None,
|
|
36
|
-
) ->
|
|
40
|
+
) -> cirq.Operation:
|
|
37
41
|
return cirq.ControlledOperation(control_qubits, self, control_values)
|
|
38
42
|
|
|
39
43
|
|
|
@@ -41,7 +45,7 @@ class BadGate(cirq.EigenGate, cirq.testing.SingleQubitGate):
|
|
|
41
45
|
def _eigen_components(self) -> List[Tuple[float, np.ndarray]]:
|
|
42
46
|
return [(0, np.diag([1, 0])), (1, np.diag([0, 1]))]
|
|
43
47
|
|
|
44
|
-
def on(self, *qubits:
|
|
48
|
+
def on(self, *qubits: cirq.Qid) -> cirq.Operation:
|
|
45
49
|
return BadGateOperation(self, list(qubits))
|
|
46
50
|
|
|
47
51
|
def controlled(
|
|
@@ -51,7 +55,7 @@ class BadGate(cirq.EigenGate, cirq.testing.SingleQubitGate):
|
|
|
51
55
|
Union[cv.AbstractControlValues, Sequence[Union[int, Collection[int]]]]
|
|
52
56
|
] = None,
|
|
53
57
|
control_qid_shape: Optional[Tuple[int, ...]] = None,
|
|
54
|
-
) ->
|
|
58
|
+
) -> cirq.Gate:
|
|
55
59
|
ret = super().controlled(num_controls, control_values, control_qid_shape)
|
|
56
60
|
if num_controls == 1 and control_values is None:
|
|
57
61
|
return cirq.CZPowGate(exponent=self._exponent, global_shift=self._global_shift)
|