def _assert_meets_standards_helper( val: Any, *, ignoring_global_phase: bool, setup_code: str, global_vals: Optional[Dict[str, Any]], local_vals: Optional[Dict[str, Any]], ) -> None: __tracebackhide__ = True # pylint: disable=unused-variable assert_consistent_resolve_parameters(val) assert_specifies_has_unitary_if_unitary(val) assert_has_consistent_qid_shape(val) assert_has_consistent_apply_unitary(val) assert_all_implemented_act_on_effects_match_unitary(val) assert_qasm_is_consistent_with_unitary(val) assert_has_consistent_trace_distance_bound(val) assert_decompose_is_consistent_with_unitary(val, ignoring_global_phase=ignoring_global_phase) assert_phase_by_is_consistent_with_unitary(val) assert_pauli_expansion_is_consistent_with_unitary(val) assert_equivalent_repr( val, setup_code=setup_code, global_vals=global_vals, local_vals=local_vals ) assert protocols.measurement_key_objs(val) == protocols.measurement_key_names(val) if isinstance(val, ops.EigenGate): assert_eigen_shifts_is_consistent_with_eigen_components(val) if isinstance(val, ops.Gate): assert_controlled_and_controlled_by_identical(val)
def _measurement_key_names_(self) -> AbstractSet[str]: if self._measurement_key_names is None: self._measurement_key_names = { key for op in self.operations for key in protocols.measurement_key_names(op) } return self._measurement_key_names
def _verify_unique_measurement_keys(circuit: 'cirq.AbstractCircuit'): result = collections.Counter( key for op in ops.flatten_op_tree(iter(circuit)) for key in protocols.measurement_key_names(op)) if result: duplicates = [k for k, v in result.most_common() if v > 1] if duplicates: raise ValueError( f"Measurement key {','.join(duplicates)} repeated")
def _run(self, circuit: 'cirq.AbstractCircuit', repetitions: int) -> Dict[str, np.ndarray]: measurements: Dict[str, List[np.ndarray]] = { key: [] for key in protocols.measurement_key_names(circuit) } qubits = circuit.all_qubits() for _ in range(repetitions): state = CliffordTableauSimulationState( CliffordTableau(num_qubits=len(qubits)), qubits=list(qubits), prng=self._prng ) for op in circuit.all_operations(): protocols.act_on(op, state) for k, v in state.log_of_measurement_results.items(): measurements[k].append(np.array(v, dtype=np.uint8)) return {k: np.array(v) for k, v in measurements.items()}
def _run(self, circuit: circuits.AbstractCircuit, repetitions: int) -> Dict[str, np.ndarray]: measurements: Dict[str, List[int]] = { key: [] for key in protocols.measurement_key_names(circuit) } qubits = circuit.all_qubits() for _ in range(repetitions): state = ActOnCliffordTableauArgs( CliffordTableau(num_qubits=len(qubits)), qubits=list(qubits), prng=self._prng, log_of_measurement_results={}, ) for op in circuit.all_operations(): protocols.act_on(op, state) for k, v in state.log_of_measurement_results.items(): measurements[k].append(v) return {k: np.array(v) for k, v in measurements.items()}
def _measurement_key_names_(self) -> AbstractSet[str]: return protocols.measurement_key_names(self.sub_operation)
def sample_measurement_ops( self, measurement_ops: List['cirq.GateOperation'], repetitions: int = 1, seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None, *, _allow_repeated=False, ) -> Dict[str, np.ndarray]: """Samples from the system at this point in the computation. Note that this does not collapse the state vector. In contrast to `sample` which samples qubits, this takes a list of `cirq.GateOperation` instances whose gates are `cirq.MeasurementGate` instances and then returns a mapping from the key in the measurement gate to the resulting bit strings. Different measurement operations must not act on the same qubits. Args: measurement_ops: `GateOperation` instances whose gates are `MeasurementGate` instances to be sampled form. repetitions: The number of samples to take. seed: A seed for the pseudorandom number generator. _allow_repeated: If True, adds extra dimension to the result, corresponding to the number of times a key is repeated. Returns: A dictionary from measurement gate key to measurement results. Measurement results are stored in a 2-dimensional numpy array, the first dimension corresponding to the repetition and the second to the actual boolean measurement results (ordered by the qubits being measured.) Raises: ValueError: If the operation's gates are not `MeasurementGate` instances or a qubit is acted upon multiple times by different operations from `measurement_ops`. """ # Sanity checks. for op in measurement_ops: gate = op.gate if not isinstance(gate, ops.MeasurementGate): raise ValueError(f'{op.gate} was not a MeasurementGate') result = collections.Counter( key for op in measurement_ops for key in protocols.measurement_key_names(op)) if result and not _allow_repeated: duplicates = [k for k, v in result.most_common() if v > 1] if duplicates: raise ValueError( f"Measurement key {','.join(duplicates)} repeated") # Find measured qubits, ensuring a consistent ordering. measured_qubits = [] seen_qubits: Set[cirq.Qid] = set() for op in measurement_ops: for q in op.qubits: if q not in seen_qubits: seen_qubits.add(q) measured_qubits.append(q) # Perform whole-system sampling of the measured qubits. indexed_sample = self.sample(measured_qubits, repetitions, seed=seed) # Extract results for each measurement. results: Dict[str, Any] = {} qubits_to_index = {q: i for i, q in enumerate(measured_qubits)} for op in measurement_ops: gate = cast(ops.MeasurementGate, op.gate) key = gate.key out = np.zeros(shape=(repetitions, len(op.qubits)), dtype=np.int8) inv_mask = gate.full_invert_mask() cmap = gate.confusion_map for i, q in enumerate(op.qubits): out[:, i] = indexed_sample[:, qubits_to_index[q]] if inv_mask[i]: out[:, i] ^= out[:, i] < 2 self._confuse_results(out, op.qubits, cmap, seed) if _allow_repeated: if key not in results: results[key] = [] results[key].append(out) else: results[gate.key] = out return (results if not _allow_repeated else {k: np.array(v).swapaxes(0, 1) for k, v in results.items()})