cirq-core 1.2.0.dev20230717232332__py3-none-any.whl → 1.3.0__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/__init__.py +5 -0
- cirq/_compat.py +26 -11
- cirq/_compat_test.py +37 -3
- cirq/_version.py +31 -1
- cirq/_version_test.py +1 -1
- cirq/circuits/circuit.py +106 -32
- cirq/circuits/circuit_operation.py +2 -2
- cirq/circuits/circuit_operation_test.py +1 -1
- cirq/circuits/circuit_test.py +109 -3
- cirq/circuits/frozen_circuit.py +80 -5
- cirq/circuits/frozen_circuit_test.py +47 -2
- cirq/circuits/qasm_output_test.py +9 -9
- cirq/conftest.py +1 -2
- cirq/contrib/acquaintance/devices.py +1 -1
- cirq/contrib/hacks/disable_validation_test.py +1 -1
- cirq/contrib/noise_models/noise_models.py +1 -2
- cirq/contrib/paulistring/clifford_optimize.py +1 -1
- cirq/contrib/paulistring/clifford_target_gateset_test.py +4 -4
- cirq/contrib/qcircuit/qcircuit_pdf.py +1 -1
- cirq/contrib/quimb/density_matrix.py +2 -3
- cirq/contrib/quimb/grid_circuits.py +3 -3
- cirq/contrib/quimb/state_vector.py +3 -5
- cirq/contrib/routing/utils.py +1 -2
- cirq/contrib/svg/svg.py +4 -6
- cirq/devices/grid_qubit.py +49 -38
- cirq/devices/grid_qubit_test.py +1 -3
- cirq/devices/insertion_noise_model.py +21 -1
- cirq/devices/insertion_noise_model_test.py +6 -0
- cirq/devices/line_qubit.py +67 -40
- cirq/devices/named_topologies.py +8 -14
- cirq/devices/noise_properties.py +1 -1
- cirq/devices/noise_utils.py +7 -5
- cirq/devices/noise_utils_test.py +7 -0
- cirq/experiments/fidelity_estimation_test.py +1 -1
- cirq/experiments/qubit_characterizations.py +6 -5
- cirq/experiments/random_quantum_circuit_generation.py +1 -1
- cirq/experiments/random_quantum_circuit_generation_test.py +28 -1
- cirq/experiments/readout_confusion_matrix.py +6 -6
- cirq/experiments/xeb_fitting.py +3 -5
- cirq/experiments/xeb_fitting_test.py +2 -2
- cirq/experiments/xeb_sampling.py +1 -1
- cirq/interop/quirk/url_to_circuit.py +40 -38
- cirq/json_resolver_cache.py +2 -0
- cirq/linalg/decompositions.py +6 -5
- cirq/ops/__init__.py +2 -0
- cirq/ops/classically_controlled_operation.py +1 -1
- cirq/ops/clifford_gate.py +9 -9
- cirq/ops/clifford_gate_test.py +3 -4
- cirq/ops/common_channels.py +2 -5
- cirq/ops/common_channels_test.py +3 -5
- cirq/ops/common_gates_test.py +7 -7
- cirq/ops/controlled_operation_test.py +2 -2
- cirq/ops/dense_pauli_string.py +3 -0
- cirq/ops/eigen_gate_test.py +1 -3
- cirq/ops/fourier_transform.py +1 -2
- cirq/ops/fsim_gate.py +1 -1
- cirq/ops/gate_features_test.py +2 -2
- cirq/ops/gate_operation_test.py +1 -2
- cirq/ops/greedy_qubit_manager.py +86 -0
- cirq/ops/greedy_qubit_manager_test.py +98 -0
- cirq/ops/linear_combinations.py +1 -1
- cirq/ops/named_qubit.py +55 -18
- cirq/ops/parity_gates.py +65 -18
- cirq/ops/parity_gates_test.py +41 -2
- cirq/ops/pauli_gates.py +2 -2
- cirq/ops/pauli_string.py +3 -4
- cirq/ops/pauli_string_raw_types_test.py +3 -3
- cirq/ops/pauli_string_test.py +3 -4
- cirq/ops/random_gate_channel_test.py +3 -3
- cirq/ops/raw_types.py +1 -1
- cirq/ops/raw_types_test.py +5 -5
- cirq/ops/three_qubit_gates.py +12 -8
- cirq/protocols/act_on_protocol_test.py +9 -9
- cirq/protocols/apply_channel_protocol.py +9 -6
- cirq/protocols/apply_unitary_protocol_test.py +1 -1
- cirq/protocols/equal_up_to_global_phase_protocol_test.py +2 -2
- cirq/protocols/has_stabilizer_effect_protocol.py +52 -6
- cirq/protocols/has_stabilizer_effect_protocol_test.py +21 -8
- cirq/protocols/has_unitary_protocol_test.py +1 -3
- cirq/protocols/json_serialization.py +6 -6
- cirq/protocols/json_serialization_test.py +7 -14
- cirq/protocols/json_test_data/InsertionNoiseModel.json +91 -0
- cirq/protocols/json_test_data/InsertionNoiseModel.repr +4 -0
- cirq/protocols/json_test_data/OpIdentifier.json +45 -10
- cirq/protocols/json_test_data/OpIdentifier.repr +7 -1
- cirq/protocols/json_test_data/spec.py +4 -0
- cirq/protocols/measurement_key_protocol_test.py +1 -1
- cirq/protocols/unitary_protocol_test.py +13 -16
- cirq/qis/clifford_tableau.py +7 -8
- cirq/qis/measures.py +1 -1
- cirq/qis/states.py +2 -3
- cirq/sim/__init__.py +2 -0
- cirq/sim/classical_simulator.py +107 -0
- cirq/sim/classical_simulator_test.py +207 -0
- cirq/sim/clifford/clifford_simulator_test.py +7 -7
- cirq/sim/clifford/stabilizer_simulation_state.py +2 -2
- cirq/sim/clifford/stabilizer_state_ch_form.py +7 -7
- cirq/sim/density_matrix_simulation_state.py +19 -4
- cirq/sim/density_matrix_simulator_test.py +5 -13
- cirq/sim/simulation_state_test.py +13 -14
- cirq/sim/simulator_test.py +6 -9
- cirq/sim/state_vector_simulation_state.py +1 -1
- cirq/study/resolver.py +41 -41
- cirq/study/resolver_test.py +13 -12
- cirq/testing/__init__.py +4 -1
- cirq/testing/circuit_compare.py +1 -1
- cirq/testing/circuit_compare_test.py +11 -11
- cirq/testing/consistent_controlled_gate_op.py +15 -1
- cirq/testing/consistent_controlled_gate_op_test.py +12 -3
- cirq/testing/consistent_decomposition.py +0 -1
- cirq/testing/consistent_protocols.py +6 -1
- cirq/testing/consistent_protocols_test.py +5 -10
- cirq/testing/consistent_qasm.py +2 -4
- cirq/testing/consistent_qasm_test.py +2 -3
- cirq/testing/consistent_specified_has_unitary_test.py +1 -3
- cirq/testing/equals_tester.py +1 -1
- cirq/testing/equals_tester_test.py +5 -5
- cirq/testing/equivalent_repr_eval_test.py +1 -3
- cirq/testing/gate_features_test.py +6 -6
- cirq/testing/order_tester_test.py +1 -3
- cirq/testing/random_circuit_test.py +1 -3
- cirq/transformers/__init__.py +3 -0
- cirq/transformers/analytical_decompositions/__init__.py +1 -0
- cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +1 -2
- cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +2 -5
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +38 -0
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +18 -0
- cirq/transformers/expand_composite_test.py +4 -4
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +1 -1
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +1 -2
- cirq/transformers/merge_k_qubit_gates_test.py +2 -2
- cirq/transformers/qubit_management_transformers.py +177 -0
- cirq/transformers/qubit_management_transformers_test.py +250 -0
- cirq/transformers/routing/route_circuit_cqc.py +23 -4
- cirq/transformers/routing/route_circuit_cqc_test.py +42 -0
- cirq/transformers/stratify.py +10 -11
- cirq/transformers/target_gatesets/compilation_target_gateset_test.py +10 -10
- cirq/transformers/target_gatesets/cz_gateset_test.py +8 -10
- cirq/transformers/transformer_primitives.py +138 -28
- cirq/value/abc_alt_test.py +4 -4
- cirq/value/duration.py +68 -37
- cirq/value/duration_test.py +2 -0
- cirq/value/measurement_key_test.py +1 -1
- cirq/value/product_state.py +4 -8
- cirq/value/value_equality_attr.py +12 -5
- cirq/vis/heatmap.py +7 -4
- cirq/vis/heatmap_test.py +14 -4
- cirq/vis/histogram.py +4 -4
- cirq/vis/state_histogram.py +10 -6
- cirq/vis/state_histogram_test.py +2 -0
- cirq/work/observable_measurement_data_test.py +1 -1
- cirq/work/observable_measurement_test.py +2 -2
- cirq/work/zeros_sampler.py +1 -1
- {cirq_core-1.2.0.dev20230717232332.dist-info → cirq_core-1.3.0.dist-info}/METADATA +11 -19
- {cirq_core-1.2.0.dev20230717232332.dist-info → cirq_core-1.3.0.dist-info}/RECORD +158 -150
- {cirq_core-1.2.0.dev20230717232332.dist-info → cirq_core-1.3.0.dist-info}/WHEEL +1 -1
- {cirq_core-1.2.0.dev20230717232332.dist-info → cirq_core-1.3.0.dist-info}/LICENSE +0 -0
- {cirq_core-1.2.0.dev20230717232332.dist-info → cirq_core-1.3.0.dist-info}/top_level.txt +0 -0
cirq/qis/clifford_tableau.py
CHANGED
|
@@ -275,8 +275,7 @@ class CliffordTableau(StabilizerState):
|
|
|
275
275
|
|
|
276
276
|
def __eq__(self, other):
|
|
277
277
|
if not isinstance(other, type(self)):
|
|
278
|
-
#
|
|
279
|
-
return NotImplemented
|
|
278
|
+
return NotImplemented # pragma: no cover
|
|
280
279
|
return (
|
|
281
280
|
self.n == other.n
|
|
282
281
|
and np.array_equal(self.rs, other.rs)
|
|
@@ -551,7 +550,7 @@ class CliffordTableau(StabilizerState):
|
|
|
551
550
|
if exponent % 2 == 0:
|
|
552
551
|
return
|
|
553
552
|
if exponent % 0.5 != 0.0:
|
|
554
|
-
raise ValueError('X exponent must be half integer') #
|
|
553
|
+
raise ValueError('X exponent must be half integer') # pragma: no cover
|
|
555
554
|
effective_exponent = exponent % 2
|
|
556
555
|
if effective_exponent == 0.5:
|
|
557
556
|
self.xs[:, axis] ^= self.zs[:, axis]
|
|
@@ -566,7 +565,7 @@ class CliffordTableau(StabilizerState):
|
|
|
566
565
|
if exponent % 2 == 0:
|
|
567
566
|
return
|
|
568
567
|
if exponent % 0.5 != 0.0:
|
|
569
|
-
raise ValueError('Y exponent must be half integer') #
|
|
568
|
+
raise ValueError('Y exponent must be half integer') # pragma: no cover
|
|
570
569
|
effective_exponent = exponent % 2
|
|
571
570
|
if effective_exponent == 0.5:
|
|
572
571
|
self.rs[:] ^= self.xs[:, axis] & (~self.zs[:, axis])
|
|
@@ -587,7 +586,7 @@ class CliffordTableau(StabilizerState):
|
|
|
587
586
|
if exponent % 2 == 0:
|
|
588
587
|
return
|
|
589
588
|
if exponent % 0.5 != 0.0:
|
|
590
|
-
raise ValueError('Z exponent must be half integer') #
|
|
589
|
+
raise ValueError('Z exponent must be half integer') # pragma: no cover
|
|
591
590
|
effective_exponent = exponent % 2
|
|
592
591
|
if effective_exponent == 0.5:
|
|
593
592
|
self.rs[:] ^= self.xs[:, axis] & self.zs[:, axis]
|
|
@@ -602,7 +601,7 @@ class CliffordTableau(StabilizerState):
|
|
|
602
601
|
if exponent % 2 == 0:
|
|
603
602
|
return
|
|
604
603
|
if exponent % 1 != 0:
|
|
605
|
-
raise ValueError('H exponent must be integer') #
|
|
604
|
+
raise ValueError('H exponent must be integer') # pragma: no cover
|
|
606
605
|
self.apply_y(axis, 0.5)
|
|
607
606
|
self.apply_x(axis)
|
|
608
607
|
|
|
@@ -612,7 +611,7 @@ class CliffordTableau(StabilizerState):
|
|
|
612
611
|
if exponent % 2 == 0:
|
|
613
612
|
return
|
|
614
613
|
if exponent % 1 != 0:
|
|
615
|
-
raise ValueError('CZ exponent must be integer') #
|
|
614
|
+
raise ValueError('CZ exponent must be integer') # pragma: no cover
|
|
616
615
|
(self.xs[:, target_axis], self.zs[:, target_axis]) = (
|
|
617
616
|
self.zs[:, target_axis].copy(),
|
|
618
617
|
self.xs[:, target_axis].copy(),
|
|
@@ -637,7 +636,7 @@ class CliffordTableau(StabilizerState):
|
|
|
637
636
|
if exponent % 2 == 0:
|
|
638
637
|
return
|
|
639
638
|
if exponent % 1 != 0:
|
|
640
|
-
raise ValueError('CX exponent must be integer') #
|
|
639
|
+
raise ValueError('CX exponent must be integer') # pragma: no cover
|
|
641
640
|
self.rs[:] ^= (
|
|
642
641
|
self.xs[:, control_axis]
|
|
643
642
|
& self.zs[:, target_axis]
|
cirq/qis/measures.py
CHANGED
|
@@ -211,7 +211,7 @@ def _numpy_arrays_to_state_vectors_or_density_matrices(
|
|
|
211
211
|
state2.shape[0] if state2.ndim == 2 else np.prod(state2.shape, dtype=np.int64).item()
|
|
212
212
|
)
|
|
213
213
|
if dim1 != dim2:
|
|
214
|
-
raise ValueError('Mismatched dimensions in given states:
|
|
214
|
+
raise ValueError(f'Mismatched dimensions in given states: {dim1} and {dim2}.')
|
|
215
215
|
if qid_shape is None:
|
|
216
216
|
qid_shape = (dim1,)
|
|
217
217
|
else:
|
cirq/qis/states.py
CHANGED
|
@@ -314,7 +314,7 @@ def density_matrix(
|
|
|
314
314
|
ValueError: Invalid density matrix.
|
|
315
315
|
"""
|
|
316
316
|
if state.ndim != 2 or state.shape[0] != state.shape[1]:
|
|
317
|
-
raise ValueError('A density matrix must be a square matrix.
|
|
317
|
+
raise ValueError(f'A density matrix must be a square matrix. Got shape {state.shape}.')
|
|
318
318
|
dim, _ = state.shape
|
|
319
319
|
if qid_shape is None:
|
|
320
320
|
qid_shape = _infer_qid_shape_from_dimension(dim)
|
|
@@ -524,8 +524,7 @@ class _QidShapeSet:
|
|
|
524
524
|
'with the corresponding qudit dimensions being at least '
|
|
525
525
|
f'{self.min_qudit_dimensions}.'
|
|
526
526
|
)
|
|
527
|
-
if len(self.explicit_qid_shapes) > 1:
|
|
528
|
-
# coverage: ignore
|
|
527
|
+
if len(self.explicit_qid_shapes) > 1: # pragma: no cover
|
|
529
528
|
raise ValueError(
|
|
530
529
|
f'Qid shape is ambiguous: Could be any one of {self.explicit_qid_shapes}.'
|
|
531
530
|
)
|
cirq/sim/__init__.py
CHANGED
|
@@ -68,6 +68,8 @@ from cirq.sim.state_vector import measure_state_vector, sample_state_vector, Sta
|
|
|
68
68
|
|
|
69
69
|
from cirq.sim.state_vector_simulation_state import StateVectorSimulationState
|
|
70
70
|
|
|
71
|
+
from cirq.sim.classical_simulator import ClassicalStateSimulator
|
|
72
|
+
|
|
71
73
|
from cirq.sim.state_vector_simulator import (
|
|
72
74
|
SimulatesIntermediateStateVector,
|
|
73
75
|
StateVectorStepResult,
|
|
@@ -0,0 +1,107 @@
|
|
|
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 Dict
|
|
16
|
+
from collections import defaultdict
|
|
17
|
+
from cirq.sim.simulator import SimulatesSamples
|
|
18
|
+
from cirq import ops, protocols
|
|
19
|
+
from cirq.study.resolver import ParamResolver
|
|
20
|
+
from cirq.circuits.circuit import AbstractCircuit
|
|
21
|
+
from cirq.ops.raw_types import Qid
|
|
22
|
+
import numpy as np
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _is_identity(op: ops.Operation) -> bool:
|
|
26
|
+
if isinstance(op.gate, (ops.XPowGate, ops.CXPowGate, ops.CCXPowGate, ops.SwapPowGate)):
|
|
27
|
+
return op.gate.exponent % 2 == 0
|
|
28
|
+
return False
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ClassicalStateSimulator(SimulatesSamples):
|
|
32
|
+
"""A simulator that accepts only gates with classical counterparts.
|
|
33
|
+
|
|
34
|
+
This simulator evolves a single state, using only gates that output a single state for each
|
|
35
|
+
input state. The simulator runs in linear time, at the cost of not supporting superposition.
|
|
36
|
+
It can be used to estimate costs and simulate circuits for simple non-quantum algorithms using
|
|
37
|
+
many more qubits than fully capable quantum simulators.
|
|
38
|
+
|
|
39
|
+
The supported gates are:
|
|
40
|
+
- cirq.X
|
|
41
|
+
- cirq.CNOT
|
|
42
|
+
- cirq.SWAP
|
|
43
|
+
- cirq.TOFFOLI
|
|
44
|
+
- cirq.measure
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
circuit: The circuit to simulate.
|
|
48
|
+
param_resolver: Parameters to run with the program.
|
|
49
|
+
repetitions: Number of times to repeat the run. It is expected that
|
|
50
|
+
this is validated greater than zero before calling this method.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
A dictionary mapping measurement keys to measurement results.
|
|
54
|
+
|
|
55
|
+
Raises:
|
|
56
|
+
ValueError: If
|
|
57
|
+
- one of the gates is not an X, CNOT, SWAP, TOFFOLI or a measurement.
|
|
58
|
+
- A measurement key is used for measurements on different numbers of qubits.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
def _run(
|
|
62
|
+
self, circuit: AbstractCircuit, param_resolver: ParamResolver, repetitions: int
|
|
63
|
+
) -> Dict[str, np.ndarray]:
|
|
64
|
+
results_dict: Dict[str, np.ndarray] = {}
|
|
65
|
+
values_dict: Dict[Qid, int] = defaultdict(int)
|
|
66
|
+
param_resolver = param_resolver or ParamResolver({})
|
|
67
|
+
resolved_circuit = protocols.resolve_parameters(circuit, param_resolver)
|
|
68
|
+
|
|
69
|
+
for moment in resolved_circuit:
|
|
70
|
+
for op in moment:
|
|
71
|
+
if _is_identity(op):
|
|
72
|
+
continue
|
|
73
|
+
if op.gate == ops.X:
|
|
74
|
+
(q,) = op.qubits
|
|
75
|
+
values_dict[q] ^= 1
|
|
76
|
+
elif op.gate == ops.CNOT:
|
|
77
|
+
c, q = op.qubits
|
|
78
|
+
values_dict[q] ^= values_dict[c]
|
|
79
|
+
elif op.gate == ops.SWAP:
|
|
80
|
+
a, b = op.qubits
|
|
81
|
+
values_dict[a], values_dict[b] = values_dict[b], values_dict[a]
|
|
82
|
+
elif op.gate == ops.TOFFOLI:
|
|
83
|
+
c1, c2, q = op.qubits
|
|
84
|
+
values_dict[q] ^= values_dict[c1] & values_dict[c2]
|
|
85
|
+
elif protocols.is_measurement(op):
|
|
86
|
+
measurement_values = np.array(
|
|
87
|
+
[[[values_dict[q] for q in op.qubits]]] * repetitions, dtype=np.uint8
|
|
88
|
+
)
|
|
89
|
+
key = op.gate.key # type: ignore
|
|
90
|
+
if key in results_dict:
|
|
91
|
+
if op._num_qubits_() != results_dict[key].shape[-1]:
|
|
92
|
+
raise ValueError(
|
|
93
|
+
f'Measurement shape {len(measurement_values)} does not match '
|
|
94
|
+
f'{results_dict[key].shape[-1]} in {key}.'
|
|
95
|
+
)
|
|
96
|
+
results_dict[key] = np.concatenate(
|
|
97
|
+
(results_dict[key], measurement_values), axis=1
|
|
98
|
+
)
|
|
99
|
+
else:
|
|
100
|
+
results_dict[key] = measurement_values
|
|
101
|
+
else:
|
|
102
|
+
raise ValueError(
|
|
103
|
+
f'{op} is not one of cirq.X, cirq.CNOT, cirq.SWAP, '
|
|
104
|
+
'cirq.CCNOT, or a measurement'
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
return results_dict
|
|
@@ -0,0 +1,207 @@
|
|
|
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
|
+
import numpy as np
|
|
15
|
+
import pytest
|
|
16
|
+
import cirq
|
|
17
|
+
import sympy
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_x_gate():
|
|
21
|
+
q0, q1 = cirq.LineQubit.range(2)
|
|
22
|
+
circuit = cirq.Circuit()
|
|
23
|
+
circuit.append(cirq.X(q0))
|
|
24
|
+
circuit.append(cirq.X(q1))
|
|
25
|
+
circuit.append(cirq.X(q1))
|
|
26
|
+
circuit.append(cirq.measure((q0, q1), key='key'))
|
|
27
|
+
expected_results = {'key': np.array([[[1, 0]]], dtype=np.uint8)}
|
|
28
|
+
sim = cirq.ClassicalStateSimulator()
|
|
29
|
+
results = sim.run(circuit, param_resolver=None, repetitions=1).records
|
|
30
|
+
np.testing.assert_equal(results, expected_results)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_CNOT():
|
|
34
|
+
q0, q1 = cirq.LineQubit.range(2)
|
|
35
|
+
circuit = cirq.Circuit()
|
|
36
|
+
circuit.append(cirq.X(q0))
|
|
37
|
+
circuit.append(cirq.CNOT(q0, q1))
|
|
38
|
+
circuit.append(cirq.measure(q1, key='key'))
|
|
39
|
+
expected_results = {'key': np.array([[[1]]], dtype=np.uint8)}
|
|
40
|
+
sim = cirq.ClassicalStateSimulator()
|
|
41
|
+
results = sim.run(circuit, param_resolver=None, repetitions=1).records
|
|
42
|
+
np.testing.assert_equal(results, expected_results)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_Swap():
|
|
46
|
+
q0, q1 = cirq.LineQubit.range(2)
|
|
47
|
+
circuit = cirq.Circuit()
|
|
48
|
+
circuit.append(cirq.X(q0))
|
|
49
|
+
circuit.append(cirq.SWAP(q0, q1))
|
|
50
|
+
circuit.append(cirq.measure((q0, q1), key='key'))
|
|
51
|
+
expected_results = {'key': np.array([[[0, 1]]], dtype=np.uint8)}
|
|
52
|
+
sim = cirq.ClassicalStateSimulator()
|
|
53
|
+
results = sim.run(circuit, param_resolver=None, repetitions=1).records
|
|
54
|
+
np.testing.assert_equal(results, expected_results)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_CCNOT():
|
|
58
|
+
q0, q1, q2 = cirq.LineQubit.range(3)
|
|
59
|
+
circuit = cirq.Circuit()
|
|
60
|
+
circuit.append(cirq.CCNOT(q0, q1, q2))
|
|
61
|
+
circuit.append(cirq.measure((q0, q1, q2), key='key'))
|
|
62
|
+
circuit.append(cirq.X(q0))
|
|
63
|
+
circuit.append(cirq.CCNOT(q0, q1, q2))
|
|
64
|
+
circuit.append(cirq.measure((q0, q1, q2), key='key'))
|
|
65
|
+
circuit.append(cirq.X(q1))
|
|
66
|
+
circuit.append(cirq.X(q0))
|
|
67
|
+
circuit.append(cirq.CCNOT(q0, q1, q2))
|
|
68
|
+
circuit.append(cirq.measure((q0, q1, q2), key='key'))
|
|
69
|
+
circuit.append(cirq.X(q0))
|
|
70
|
+
circuit.append(cirq.CCNOT(q0, q1, q2))
|
|
71
|
+
circuit.append(cirq.measure((q0, q1, q2), key='key'))
|
|
72
|
+
expected_results = {
|
|
73
|
+
'key': np.array([[[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 1]]], dtype=np.uint8)
|
|
74
|
+
}
|
|
75
|
+
sim = cirq.ClassicalStateSimulator()
|
|
76
|
+
results = sim.run(circuit, param_resolver=None, repetitions=1).records
|
|
77
|
+
np.testing.assert_equal(results, expected_results)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_measurement_gate():
|
|
81
|
+
q0, q1 = cirq.LineQubit.range(2)
|
|
82
|
+
circuit = cirq.Circuit()
|
|
83
|
+
circuit.append(cirq.measure((q0, q1), key='key'))
|
|
84
|
+
expected_results = {'key': np.array([[[0, 0]]], dtype=np.uint8)}
|
|
85
|
+
sim = cirq.ClassicalStateSimulator()
|
|
86
|
+
results = sim.run(circuit, param_resolver=None, repetitions=1).records
|
|
87
|
+
np.testing.assert_equal(results, expected_results)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_qubit_order():
|
|
91
|
+
q0, q1 = cirq.LineQubit.range(2)
|
|
92
|
+
circuit = cirq.Circuit()
|
|
93
|
+
circuit.append(cirq.CNOT(q0, q1))
|
|
94
|
+
circuit.append(cirq.X(q0))
|
|
95
|
+
circuit.append(cirq.measure((q0, q1), key='key'))
|
|
96
|
+
expected_results = {'key': np.array([[[1, 0]]], dtype=np.uint8)}
|
|
97
|
+
sim = cirq.ClassicalStateSimulator()
|
|
98
|
+
results = sim.run(circuit, param_resolver=None, repetitions=1).records
|
|
99
|
+
np.testing.assert_equal(results, expected_results)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def test_same_key_instances():
|
|
103
|
+
q0, q1 = cirq.LineQubit.range(2)
|
|
104
|
+
circuit = cirq.Circuit()
|
|
105
|
+
circuit.append(cirq.measure((q0, q1), key='key'))
|
|
106
|
+
circuit.append(cirq.X(q0))
|
|
107
|
+
circuit.append(cirq.measure((q0, q1), key='key'))
|
|
108
|
+
expected_results = {'key': np.array([[[0, 0], [1, 0]]], dtype=np.uint8)}
|
|
109
|
+
sim = cirq.ClassicalStateSimulator()
|
|
110
|
+
results = sim.run(circuit, param_resolver=None, repetitions=1).records
|
|
111
|
+
np.testing.assert_equal(results, expected_results)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def test_same_key_instances_order():
|
|
115
|
+
q0, q1 = cirq.LineQubit.range(2)
|
|
116
|
+
circuit = cirq.Circuit()
|
|
117
|
+
circuit.append(cirq.X(q0))
|
|
118
|
+
circuit.append(cirq.measure((q0, q1), key='key'))
|
|
119
|
+
circuit.append(cirq.X(q0))
|
|
120
|
+
circuit.append(cirq.measure((q1, q0), key='key'))
|
|
121
|
+
expected_results = {'key': np.array([[[1, 0], [0, 0]]], dtype=np.uint8)}
|
|
122
|
+
sim = cirq.ClassicalStateSimulator()
|
|
123
|
+
results = sim.run(circuit, param_resolver=None, repetitions=1).records
|
|
124
|
+
np.testing.assert_equal(results, expected_results)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def test_repetitions():
|
|
128
|
+
q0 = cirq.LineQubit.range(1)
|
|
129
|
+
circuit = cirq.Circuit()
|
|
130
|
+
circuit.append(cirq.measure(q0, key='key'))
|
|
131
|
+
expected_results = {
|
|
132
|
+
'key': np.array(
|
|
133
|
+
[[[0]], [[0]], [[0]], [[0]], [[0]], [[0]], [[0]], [[0]], [[0]], [[0]]], dtype=np.uint8
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
sim = cirq.ClassicalStateSimulator()
|
|
137
|
+
results = sim.run(circuit, param_resolver=None, repetitions=10).records
|
|
138
|
+
np.testing.assert_equal(results, expected_results)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def test_multiple_gates():
|
|
142
|
+
q0, q1 = cirq.LineQubit.range(2)
|
|
143
|
+
circuit = cirq.Circuit()
|
|
144
|
+
circuit.append(cirq.X(q0))
|
|
145
|
+
circuit.append(cirq.CNOT(q0, q1))
|
|
146
|
+
circuit.append(cirq.CNOT(q0, q1))
|
|
147
|
+
circuit.append(cirq.CNOT(q0, q1))
|
|
148
|
+
circuit.append(cirq.X(q1))
|
|
149
|
+
circuit.append(cirq.measure((q0, q1), key='key'))
|
|
150
|
+
expected_results = {'key': np.array([[[1, 0]]], dtype=np.uint8)}
|
|
151
|
+
sim = cirq.ClassicalStateSimulator()
|
|
152
|
+
results = sim.run(circuit, param_resolver=None, repetitions=1).records
|
|
153
|
+
np.testing.assert_equal(results, expected_results)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def test_multiple_gates_order():
|
|
157
|
+
q0, q1 = cirq.LineQubit.range(2)
|
|
158
|
+
circuit = cirq.Circuit()
|
|
159
|
+
circuit.append(cirq.X(q0))
|
|
160
|
+
circuit.append(cirq.CNOT(q0, q1))
|
|
161
|
+
circuit.append(cirq.CNOT(q1, q0))
|
|
162
|
+
circuit.append(cirq.measure((q0, q1), key='key'))
|
|
163
|
+
expected_results = {'key': np.array([[[0, 1]]], dtype=np.uint8)}
|
|
164
|
+
sim = cirq.ClassicalStateSimulator()
|
|
165
|
+
results = sim.run(circuit, param_resolver=None, repetitions=1).records
|
|
166
|
+
np.testing.assert_equal(results, expected_results)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def test_param_resolver():
|
|
170
|
+
gate = cirq.CNOT ** sympy.Symbol('t')
|
|
171
|
+
q0, q1 = cirq.LineQubit.range(2)
|
|
172
|
+
circuit = cirq.Circuit()
|
|
173
|
+
circuit.append(cirq.X(q0))
|
|
174
|
+
circuit.append(gate(q0, q1))
|
|
175
|
+
circuit.append(cirq.measure((q1), key='key'))
|
|
176
|
+
resolver = cirq.ParamResolver({'t': 0})
|
|
177
|
+
sim = cirq.ClassicalStateSimulator()
|
|
178
|
+
results_with_parameter_zero = sim.run(circuit, param_resolver=resolver, repetitions=1).records
|
|
179
|
+
resolver = cirq.ParamResolver({'t': 1})
|
|
180
|
+
results_with_parameter_one = sim.run(circuit, param_resolver=resolver, repetitions=1).records
|
|
181
|
+
np.testing.assert_equal(results_with_parameter_zero, {'key': np.array([[[0]]], dtype=np.uint8)})
|
|
182
|
+
np.testing.assert_equal(results_with_parameter_one, {'key': np.array([[[1]]], dtype=np.uint8)})
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def test_unknown_gates():
|
|
186
|
+
gate = cirq.Y
|
|
187
|
+
q = cirq.LineQubit(0)
|
|
188
|
+
circuit = cirq.Circuit(gate(q), cirq.measure((q), key='key'))
|
|
189
|
+
sim = cirq.ClassicalStateSimulator()
|
|
190
|
+
with pytest.raises(ValueError):
|
|
191
|
+
_ = sim.run(circuit).records
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def test_incompatible_measurements():
|
|
195
|
+
qs = cirq.LineQubit.range(2)
|
|
196
|
+
c = cirq.Circuit(cirq.measure(qs, key='key'), cirq.measure(qs[0], key='key'))
|
|
197
|
+
sim = cirq.ClassicalStateSimulator()
|
|
198
|
+
with pytest.raises(ValueError):
|
|
199
|
+
_ = sim.run(c)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def test_compatible_measurement():
|
|
203
|
+
qs = cirq.LineQubit.range(2)
|
|
204
|
+
c = cirq.Circuit(cirq.measure(qs, key='key'), cirq.X.on_each(qs), cirq.measure(qs, key='key'))
|
|
205
|
+
sim = cirq.ClassicalStateSimulator()
|
|
206
|
+
res = sim.run(c, repetitions=3).records
|
|
207
|
+
np.testing.assert_equal(res['key'], np.array([[[0, 0], [1, 1]]] * 3, dtype=np.uint8))
|
|
@@ -373,19 +373,19 @@ def test_clifford_circuit_2(qubits, split):
|
|
|
373
373
|
x = np.random.randint(7)
|
|
374
374
|
|
|
375
375
|
if x == 0:
|
|
376
|
-
circuit.append(cirq.X(np.random.choice(qubits))) #
|
|
376
|
+
circuit.append(cirq.X(np.random.choice(qubits))) # pragma: no cover
|
|
377
377
|
elif x == 1:
|
|
378
|
-
circuit.append(cirq.Z(np.random.choice(qubits))) #
|
|
378
|
+
circuit.append(cirq.Z(np.random.choice(qubits))) # pragma: no cover
|
|
379
379
|
elif x == 2:
|
|
380
|
-
circuit.append(cirq.Y(np.random.choice(qubits))) #
|
|
380
|
+
circuit.append(cirq.Y(np.random.choice(qubits))) # pragma: no cover
|
|
381
381
|
elif x == 3:
|
|
382
|
-
circuit.append(cirq.S(np.random.choice(qubits))) #
|
|
382
|
+
circuit.append(cirq.S(np.random.choice(qubits))) # pragma: no cover
|
|
383
383
|
elif x == 4:
|
|
384
|
-
circuit.append(cirq.H(np.random.choice(qubits))) #
|
|
384
|
+
circuit.append(cirq.H(np.random.choice(qubits))) # pragma: no cover
|
|
385
385
|
elif x == 5:
|
|
386
|
-
circuit.append(cirq.CNOT(qubits[0], qubits[1])) #
|
|
386
|
+
circuit.append(cirq.CNOT(qubits[0], qubits[1])) # pragma: no cover
|
|
387
387
|
elif x == 6:
|
|
388
|
-
circuit.append(cirq.CZ(qubits[0], qubits[1])) #
|
|
388
|
+
circuit.append(cirq.CZ(qubits[0], qubits[1])) # pragma: no cover
|
|
389
389
|
|
|
390
390
|
circuit.append(cirq.measure(qubits[0]))
|
|
391
391
|
result = cirq.CliffordSimulator(split_untangled_states=split).run(circuit, repetitions=100)
|
|
@@ -84,7 +84,7 @@ class StabilizerSimulationState(
|
|
|
84
84
|
):
|
|
85
85
|
"""Apply a SWAP gate"""
|
|
86
86
|
if exponent % 1 != 0:
|
|
87
|
-
raise ValueError('Swap exponent must be integer') #
|
|
87
|
+
raise ValueError('Swap exponent must be integer') # pragma: no cover
|
|
88
88
|
self._state.apply_cx(control_axis, target_axis)
|
|
89
89
|
self._state.apply_cx(target_axis, control_axis, exponent, global_shift)
|
|
90
90
|
self._state.apply_cx(control_axis, target_axis)
|
|
@@ -122,7 +122,7 @@ class StabilizerSimulationState(
|
|
|
122
122
|
if mixture is None:
|
|
123
123
|
return NotImplemented
|
|
124
124
|
if not all(linalg.is_unitary(m) for _, m in mixture):
|
|
125
|
-
return NotImplemented #
|
|
125
|
+
return NotImplemented # pragma: no cover
|
|
126
126
|
probabilities, unitaries = zip(*mixture)
|
|
127
127
|
index = self.prng.choice(len(unitaries), p=probabilities)
|
|
128
128
|
return self._strat_act_from_single_qubit_decompose(
|
|
@@ -54,7 +54,7 @@ class StabilizerStateChForm(qis.StabilizerState):
|
|
|
54
54
|
self.omega: complex = 1
|
|
55
55
|
|
|
56
56
|
# Apply X for every non-zero element of initial_state
|
|
57
|
-
for
|
|
57
|
+
for i, val in enumerate(
|
|
58
58
|
big_endian_int_to_digits(initial_state, digit_count=num_qubits, base=2)
|
|
59
59
|
):
|
|
60
60
|
if val:
|
|
@@ -295,7 +295,7 @@ class StabilizerStateChForm(qis.StabilizerState):
|
|
|
295
295
|
def apply_x(self, axis: int, exponent: float = 1, global_shift: float = 0):
|
|
296
296
|
if exponent % 2 != 0:
|
|
297
297
|
if exponent % 0.5 != 0.0:
|
|
298
|
-
raise ValueError('X exponent must be half integer') #
|
|
298
|
+
raise ValueError('X exponent must be half integer') # pragma: no cover
|
|
299
299
|
self.apply_h(axis)
|
|
300
300
|
self.apply_z(axis, exponent)
|
|
301
301
|
self.apply_h(axis)
|
|
@@ -303,7 +303,7 @@ class StabilizerStateChForm(qis.StabilizerState):
|
|
|
303
303
|
|
|
304
304
|
def apply_y(self, axis: int, exponent: float = 1, global_shift: float = 0):
|
|
305
305
|
if exponent % 0.5 != 0.0:
|
|
306
|
-
raise ValueError('Y exponent must be half integer') #
|
|
306
|
+
raise ValueError('Y exponent must be half integer') # pragma: no cover
|
|
307
307
|
shift = _phase(exponent, global_shift)
|
|
308
308
|
if exponent % 2 == 0:
|
|
309
309
|
self.omega *= shift
|
|
@@ -325,7 +325,7 @@ class StabilizerStateChForm(qis.StabilizerState):
|
|
|
325
325
|
def apply_z(self, axis: int, exponent: float = 1, global_shift: float = 0):
|
|
326
326
|
if exponent % 2 != 0:
|
|
327
327
|
if exponent % 0.5 != 0.0:
|
|
328
|
-
raise ValueError('Z exponent must be half integer') #
|
|
328
|
+
raise ValueError('Z exponent must be half integer') # pragma: no cover
|
|
329
329
|
effective_exponent = exponent % 2
|
|
330
330
|
for _ in range(int(effective_exponent * 2)):
|
|
331
331
|
# Prescription for S left multiplication.
|
|
@@ -337,7 +337,7 @@ class StabilizerStateChForm(qis.StabilizerState):
|
|
|
337
337
|
def apply_h(self, axis: int, exponent: float = 1, global_shift: float = 0):
|
|
338
338
|
if exponent % 2 != 0:
|
|
339
339
|
if exponent % 1 != 0:
|
|
340
|
-
raise ValueError('H exponent must be integer') #
|
|
340
|
+
raise ValueError('H exponent must be integer') # pragma: no cover
|
|
341
341
|
# Prescription for H left multiplication
|
|
342
342
|
# Reference: https://arxiv.org/abs/1808.00128
|
|
343
343
|
# Equations 48, 49 and Proposition 4
|
|
@@ -357,7 +357,7 @@ class StabilizerStateChForm(qis.StabilizerState):
|
|
|
357
357
|
):
|
|
358
358
|
if exponent % 2 != 0:
|
|
359
359
|
if exponent % 1 != 0:
|
|
360
|
-
raise ValueError('CZ exponent must be integer') #
|
|
360
|
+
raise ValueError('CZ exponent must be integer') # pragma: no cover
|
|
361
361
|
# Prescription for CZ left multiplication.
|
|
362
362
|
# Reference: https://arxiv.org/abs/1808.00128 Proposition 4 end
|
|
363
363
|
self.M[control_axis, :] ^= self.G[target_axis, :]
|
|
@@ -369,7 +369,7 @@ class StabilizerStateChForm(qis.StabilizerState):
|
|
|
369
369
|
):
|
|
370
370
|
if exponent % 2 != 0:
|
|
371
371
|
if exponent % 1 != 0:
|
|
372
|
-
raise ValueError('CX exponent must be integer') #
|
|
372
|
+
raise ValueError('CX exponent must be integer') # pragma: no cover
|
|
373
373
|
# Prescription for CX left multiplication.
|
|
374
374
|
# Reference: https://arxiv.org/abs/1808.00128 Proposition 4 end
|
|
375
375
|
self.gamma[control_axis] = (
|
|
@@ -47,8 +47,7 @@ class _BufferedDensityMatrix(qis.QuantumStateRepresentation):
|
|
|
47
47
|
if buffer is None:
|
|
48
48
|
buffer = [np.empty_like(density_matrix) for _ in range(3)]
|
|
49
49
|
self._buffer = buffer
|
|
50
|
-
if len(density_matrix.shape) % 2 != 0:
|
|
51
|
-
# coverage: ignore
|
|
50
|
+
if len(density_matrix.shape) % 2 != 0: # pragma: no cover
|
|
52
51
|
raise ValueError('The dimension of target_tensor is not divisible by 2.')
|
|
53
52
|
self._qid_shape = density_matrix.shape[: len(density_matrix.shape) // 2]
|
|
54
53
|
|
|
@@ -86,7 +85,7 @@ class _BufferedDensityMatrix(qis.QuantumStateRepresentation):
|
|
|
86
85
|
initial_state, len(qid_shape), qid_shape=qid_shape, dtype=dtype
|
|
87
86
|
).reshape(qid_shape * 2)
|
|
88
87
|
else:
|
|
89
|
-
density_matrix = initial_state #
|
|
88
|
+
density_matrix = initial_state # pragma: no cover
|
|
90
89
|
if np.may_share_memory(density_matrix, initial_state):
|
|
91
90
|
density_matrix = density_matrix.copy()
|
|
92
91
|
density_matrix = density_matrix.astype(dtype, copy=False)
|
|
@@ -286,6 +285,22 @@ class DensityMatrixSimulationState(SimulationState[_BufferedDensityMatrix]):
|
|
|
286
285
|
)
|
|
287
286
|
super().__init__(state=state, prng=prng, qubits=qubits, classical_data=classical_data)
|
|
288
287
|
|
|
288
|
+
def add_qubits(self, qubits: Sequence['cirq.Qid']):
|
|
289
|
+
ret = super().add_qubits(qubits)
|
|
290
|
+
return (
|
|
291
|
+
self.kronecker_product(type(self)(qubits=qubits), inplace=True)
|
|
292
|
+
if ret is NotImplemented
|
|
293
|
+
else ret
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
def remove_qubits(self, qubits: Sequence['cirq.Qid']):
|
|
297
|
+
ret = super().remove_qubits(qubits)
|
|
298
|
+
if ret is not NotImplemented:
|
|
299
|
+
return ret
|
|
300
|
+
extracted, remainder = self.factor(qubits, inplace=True)
|
|
301
|
+
remainder._state._density_matrix *= extracted._state._density_matrix.reshape(-1)[0]
|
|
302
|
+
return remainder
|
|
303
|
+
|
|
289
304
|
def _act_on_fallback_(
|
|
290
305
|
self, action: Any, qubits: Sequence['cirq.Qid'], allow_decompose: bool = True
|
|
291
306
|
) -> bool:
|
|
@@ -299,7 +314,7 @@ class DensityMatrixSimulationState(SimulationState[_BufferedDensityMatrix]):
|
|
|
299
314
|
for strat in strats:
|
|
300
315
|
result = strat(action, self, qubits)
|
|
301
316
|
if result is False:
|
|
302
|
-
break #
|
|
317
|
+
break # pragma: no cover
|
|
303
318
|
if result is True:
|
|
304
319
|
return True
|
|
305
320
|
assert result is NotImplemented, str(result)
|
|
@@ -139,8 +139,7 @@ def test_run_not_channel_op(dtype: Type[np.complexfloating], split: bool):
|
|
|
139
139
|
def qubits(self):
|
|
140
140
|
return self._qubits
|
|
141
141
|
|
|
142
|
-
def with_qubits(self, *new_qubits):
|
|
143
|
-
# coverage: ignore
|
|
142
|
+
def with_qubits(self, *new_qubits): # pragma: no cover
|
|
144
143
|
return BadOp(self._qubits)
|
|
145
144
|
|
|
146
145
|
q0 = cirq.LineQubit(0)
|
|
@@ -1050,39 +1049,32 @@ def test_density_matrix_trial_result_repr():
|
|
|
1050
1049
|
|
|
1051
1050
|
class XAsOp(cirq.Operation):
|
|
1052
1051
|
def __init__(self, q):
|
|
1053
|
-
#
|
|
1054
|
-
self.q = q
|
|
1052
|
+
self.q = q # pragma: no cover
|
|
1055
1053
|
|
|
1056
1054
|
@property
|
|
1057
1055
|
def qubits(self):
|
|
1058
|
-
#
|
|
1059
|
-
return (self.q,)
|
|
1056
|
+
return (self.q,) # pragma: no cover
|
|
1060
1057
|
|
|
1061
1058
|
def with_qubits(self, *new_qubits):
|
|
1062
|
-
#
|
|
1063
|
-
return XAsOp(new_qubits[0])
|
|
1059
|
+
return XAsOp(new_qubits[0]) # pragma: no cover
|
|
1064
1060
|
|
|
1065
1061
|
def _kraus_(self):
|
|
1066
|
-
#
|
|
1067
|
-
return cirq.kraus(cirq.X)
|
|
1062
|
+
return cirq.kraus(cirq.X) # pragma: no cover
|
|
1068
1063
|
|
|
1069
1064
|
|
|
1070
1065
|
def test_works_on_operation():
|
|
1071
1066
|
class XAsOp(cirq.Operation):
|
|
1072
1067
|
def __init__(self, q):
|
|
1073
|
-
# coverage: ignore
|
|
1074
1068
|
self.q = q
|
|
1075
1069
|
|
|
1076
1070
|
@property
|
|
1077
1071
|
def qubits(self):
|
|
1078
|
-
# coverage: ignore
|
|
1079
1072
|
return (self.q,)
|
|
1080
1073
|
|
|
1081
1074
|
def with_qubits(self, *new_qubits):
|
|
1082
1075
|
raise NotImplementedError()
|
|
1083
1076
|
|
|
1084
1077
|
def _kraus_(self):
|
|
1085
|
-
# coverage: ignore
|
|
1086
1078
|
return cirq.kraus(cirq.X)
|
|
1087
1079
|
|
|
1088
1080
|
s = cirq.DensityMatrixSimulator()
|