def state_vector_has_stabilizer(state_vector: np.ndarray, stabilizer: DensePauliString) -> bool: """Checks that the state_vector is stabilized by the given stabilizer. The stabilizer should not modify the value of the state_vector, up to the global phase. Args: state_vector: An input state vector. Is not mutated by this function. stabilizer: A potential stabilizer of the above state_vector as a DensePauliString. Returns: Whether the stabilizer stabilizes the supplied state. """ args = act_on_state_vector_args.ActOnStateVectorArgs( target_tensor=state_vector.copy(), available_buffer=np.empty_like(state_vector), axes=range(protocols.num_qubits(stabilizer)), prng=np.random.RandomState(), log_of_measurement_results={}, ) protocols.act_on(stabilizer, args) return np.allclose(args.target_tensor, state_vector)
def _create_act_on_args( self, initial_state: Union['cirq.STATE_VECTOR_LIKE', 'cirq.ActOnStateVectorArgs'], qubits: Sequence['cirq.Qid'], ): """Creates the ActOnStateVectorArgs for a circuit. Args: initial_state: The initial state for the simulation in the computational basis. qubits: Determines the canonical ordering of the qubits. This is often used in specifying the initial state, i.e. the ordering of the computational basis states. Returns: ActOnStateVectorArgs for the circuit. """ if isinstance(initial_state, act_on_state_vector_args.ActOnStateVectorArgs): return initial_state num_qubits = len(qubits) qid_shape = protocols.qid_shape(qubits) state = qis.to_valid_state_vector( initial_state, num_qubits, qid_shape=qid_shape, dtype=self._dtype ) return act_on_state_vector_args.ActOnStateVectorArgs( target_tensor=np.reshape(state, qid_shape), available_buffer=np.empty(qid_shape, dtype=self._dtype), qubits=qubits, axes=[], prng=self._prng, log_of_measurement_results={}, )
def _create_partial_act_on_args( self, initial_state: Union['cirq.STATE_VECTOR_LIKE', 'cirq.ActOnStateVectorArgs'], qubits: Sequence['cirq.Qid'], classical_data: 'cirq.ClassicalDataStore', ): """Creates the ActOnStateVectorArgs for a circuit. Args: initial_state: The initial state for the simulation in the computational basis. qubits: Determines the canonical ordering of the qubits. This is often used in specifying the initial state, i.e. the ordering of the computational basis states. classical_data: The shared classical data container for this simulation. Returns: ActOnStateVectorArgs for the circuit. """ if isinstance(initial_state, act_on_state_vector_args.ActOnStateVectorArgs): return initial_state return act_on_state_vector_args.ActOnStateVectorArgs( qubits=qubits, prng=self._prng, classical_data=classical_data, initial_state=initial_state, dtype=self._dtype, )
def state_vector_has_stabilizer(state_vector: np.ndarray, stabilizer: DensePauliString) -> bool: """Checks that the stabilizer does not modify the value of the state_vector, including the global phase. Does not mutate the input state_vector.""" args = act_on_state_vector_args.ActOnStateVectorArgs( target_tensor=state_vector.copy(), available_buffer=np.empty_like(state_vector), axes=range(protocols.num_qubits(stabilizer)), prng=np.random.RandomState(), log_of_measurement_results={}) protocols.act_on(stabilizer, args) return np.allclose(args.target_tensor, state_vector)
def _base_iterator( self, circuit: circuits.Circuit, qubit_order: ops.QubitOrderOrList, initial_state: 'cirq.STATE_VECTOR_LIKE', perform_measurements: bool = True, ) -> Iterator['SparseSimulatorStep']: qubits = ops.QubitOrder.as_qubit_order(qubit_order).order_for( circuit.all_qubits()) num_qubits = len(qubits) qid_shape = protocols.qid_shape(qubits) qubit_map = {q: i for i, q in enumerate(qubits)} state = qis.to_valid_state_vector(initial_state, num_qubits, qid_shape=qid_shape, dtype=self._dtype) if len(circuit) == 0: yield SparseSimulatorStep(state, {}, qubit_map, self._dtype) sim_state = act_on_state_vector_args.ActOnStateVectorArgs( target_tensor=np.reshape(state, qid_shape), available_buffer=np.empty(qid_shape, dtype=self._dtype), axes=[], prng=self._prng, log_of_measurement_results={}, ) noisy_moments = self.noise.noisy_moments(circuit, sorted(circuit.all_qubits())) for op_tree in noisy_moments: for op in flatten_to_ops(op_tree): if perform_measurements or not isinstance( op.gate, ops.MeasurementGate): sim_state.axes = tuple(qubit_map[qubit] for qubit in op.qubits) protocols.act_on(op, sim_state) yield SparseSimulatorStep( state_vector=sim_state.target_tensor, measurements=dict(sim_state.log_of_measurement_results), qubit_map=qubit_map, dtype=self._dtype, ) sim_state.log_of_measurement_results.clear()