def __init__(self, num_qubits: int, initial_state: int = 0) -> None: """Initializes StabilizerStateChForm Args: num_qubits: The number of qubits in the system. initial_state: The computational basis representation of the state as a big endian int. """ self.n = num_qubits # The state is represented by a set of binary matrices and vectors. # See Section IVa of Bravyi et al self.G = np.eye(self.n, dtype=bool) self.F = np.eye(self.n, dtype=bool) self.M = np.zeros((self.n, self.n), dtype=bool) self.gamma = np.zeros(self.n, dtype=int) self.v = np.zeros(self.n, dtype=bool) self.s = np.zeros(self.n, dtype=bool) self.omega = 1 # type: complex # Apply X for every non-zero element of initial_state for (i, val) in enumerate( big_endian_int_to_digits(initial_state, digit_count=num_qubits, base=2)): if val: protocols.act_on( pauli_gates.X, clifford.ActOnStabilizerCHFormArgs(self, [i], np.random.RandomState(), {}), )
def _create_partial_act_on_args( self, initial_state: Union[int, 'cirq.ActOnStabilizerCHFormArgs'], qubits: Sequence['cirq.Qid'], classical_data: 'cirq.ClassicalDataStore', ) -> 'cirq.ActOnStabilizerCHFormArgs': """Creates the ActOnStabilizerChFormArgs for a circuit. Args: initial_state: The initial state for the simulation in the computational basis. Represented as a big endian int. 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. logs: A log of the results of measurement that is added to. classical_data: The shared classical data container for this simulation. Returns: ActOnStabilizerChFormArgs for the circuit. """ if isinstance(initial_state, clifford.ActOnStabilizerCHFormArgs): return initial_state return clifford.ActOnStabilizerCHFormArgs( prng=self._prng, classical_data=classical_data, qubits=qubits, initial_state=initial_state, )
def _create_partial_act_on_args( self, initial_state: Union[int, clifford.ActOnStabilizerCHFormArgs], qubits: Sequence['cirq.Qid'], logs: Dict[str, Any], ) -> clifford.ActOnStabilizerCHFormArgs: """Creates the ActOnStabilizerChFormArgs for a circuit. Args: initial_state: The initial state for the simulation in the computational basis. Represented as a big endian int. 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. logs: A log of the results of measurement that is added to. Returns: ActOnStabilizerChFormArgs for the circuit. """ if isinstance(initial_state, clifford.ActOnStabilizerCHFormArgs): return initial_state qubit_map = {q: i for i, q in enumerate(qubits)} state = CliffordState(qubit_map, initial_state=initial_state) return clifford.ActOnStabilizerCHFormArgs( state=state.ch_form, prng=self._prng, log_of_measurement_results=logs, qubits=qubits, )
def apply_measurement( self, op: 'cirq.Operation', measurements: Dict[str, List[np.ndarray]], prng: np.random.RandomState, collapse_state_vector=True, ): if not isinstance(op.gate, cirq.MeasurementGate): raise TypeError( 'apply_measurement only supports cirq.MeasurementGate operations. Found %s instead.' % str(op.gate)) if collapse_state_vector: state = self else: state = self.copy() classical_data = value.ClassicalDataDictionaryStore() ch_form_args = clifford.ActOnStabilizerCHFormArgs( prng=prng, classical_data=classical_data, qubits=self.qubit_map.keys(), initial_state=state.ch_form, ) act_on(op, ch_form_args) measurements.update( {str(k): list(v[-1]) for k, v in classical_data.records.items()})
def apply_unitary(self, op: 'cirq.Operation'): ch_form_args = clifford.ActOnStabilizerCHFormArgs( self.ch_form, np.random.RandomState(), {}, self.qubit_map.keys()) try: act_on(op, ch_form_args) except TypeError: raise ValueError( f'{str(op.gate)} cannot be run with Clifford simulator.' ) # type: ignore return
def _base_iterator( self, circuit: circuits.Circuit, qubit_order: ops.QubitOrderOrList, initial_state: int ) -> Iterator['cirq.CliffordSimulatorStepResult']: """Iterator over CliffordSimulatorStepResult from Moments of a Circuit Args: circuit: The circuit to simulate. qubit_order: 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. initial_state: The initial state for the simulation in the computational basis. Represented as a big endian int. Yields: CliffordStepResult from simulating a Moment of the Circuit. """ qubits = ops.QubitOrder.as_qubit_order(qubit_order).order_for( circuit.all_qubits()) qubit_map = {q: i for i, q in enumerate(qubits)} if len(circuit) == 0: yield CliffordSimulatorStepResult(measurements={}, state=CliffordState( qubit_map, initial_state=initial_state)) return state = CliffordState(qubit_map, initial_state=initial_state) ch_form_args = clifford.ActOnStabilizerCHFormArgs( state.ch_form, [], self._prng, {}, ) for moment in circuit: ch_form_args.log_of_measurement_results = {} for op in moment: try: ch_form_args.axes = tuple(state.qubit_map[i] for i in op.qubits) act_on(op, ch_form_args) except TypeError: raise NotImplementedError( f"CliffordSimulator doesn't support {op!r}" ) # type: ignore yield CliffordSimulatorStepResult( measurements=ch_form_args.log_of_measurement_results, state=state)
def apply_unitary(self, op: 'cirq.Operation'): tableau_args = clifford.ActOnCliffordTableauArgs( self.tableau, [self.qubit_map[i] for i in op.qubits], np.random.RandomState(), {}) ch_form_args = clifford.ActOnStabilizerCHFormArgs( self.ch_form, [self.qubit_map[i] for i in op.qubits]) try: act_on(op, tableau_args) act_on(op, ch_form_args) except TypeError: raise ValueError('%s cannot be run with Clifford simulator.' % str(op.gate)) # type: ignore return
def apply_measurement( self, op: 'cirq.Operation', measurements: Dict[str, List[np.ndarray]], prng: np.random.RandomState, collapse_state_vector=True, ): if not isinstance(op.gate, cirq.MeasurementGate): raise TypeError( 'apply_measurement only supports cirq.MeasurementGate operations. Found %s instead.' % str(op.gate)) if collapse_state_vector: state = self else: state = self.copy() ch_form_args = clifford.ActOnStabilizerCHFormArgs( state.ch_form, prng, measurements, self.qubit_map.keys()) act_on(op, ch_form_args)