Пример #1
0
    def _base_iterator(
        self,
        circuit: circuits.Circuit,
        qubit_order: ops.QubitOrderOrList,
        initial_state: Union[int, np.ndarray],
        perform_measurements: bool = True,
    ) -> Iterator[simulator.StepResult]:
        qubits = ops.QubitOrder.as_qubit_order(qubit_order).order_for(
            circuit.all_qubits())
        num_qubits = len(qubits)
        qubit_map = {q: i for i, q in enumerate(qubits)}
        state = wave_function.to_valid_state_vector(initial_state, num_qubits,
                                                    self._dtype)

        def on_stuck(bad_op: ops.Operation):
            return TypeError(
                "Can't simulate unknown operations that don't specify a "
                "_unitary_ method, a _decompose_ method, or "
                "(_has_unitary_ + _apply_unitary_) methods"
                ": {!r}".format(bad_op))

        def keep(potential_op: ops.Operation) -> bool:
            return (protocols.has_unitary(potential_op)
                    or ops.MeasurementGate.is_measurement(potential_op))

        state = np.reshape(state, (2, ) * num_qubits)
        buffer = np.empty((2, ) * num_qubits, dtype=self._dtype)
        for moment in circuit:
            measurements = collections.defaultdict(
                list)  # type: Dict[str, List[bool]]

            unitary_ops_and_measurements = protocols.decompose(
                moment.operations, keep=keep, on_stuck_raise=on_stuck)

            for op in unitary_ops_and_measurements:
                indices = [qubit_map[qubit] for qubit in op.qubits]
                if ops.MeasurementGate.is_measurement(op):
                    gate = cast(ops.MeasurementGate,
                                cast(ops.GateOperation, op).gate)
                    if perform_measurements:
                        invert_mask = gate.invert_mask or num_qubits * (
                            False, )
                        # Measure updates inline.
                        bits, _ = wave_function.measure_state_vector(
                            state, indices, state)
                        corrected = [
                            bit ^ mask for bit, mask in zip(bits, invert_mask)
                        ]
                        measurements[cast(str, gate.key)].extend(corrected)
                else:
                    result = protocols.apply_unitary(
                        op,
                        args=protocols.ApplyUnitaryArgs(
                            state, buffer, indices))
                    if result is buffer:
                        buffer = state
                    state = result
            yield SimulatorStep(state, measurements, qubit_map, self._dtype)
Пример #2
0
 def _simulate_reset(self, op: ops.Operation, data: _StateAndBuffer,
                     indices: List[int]) -> None:
     """Simulate an op that is a reset to the |0> state."""
     if isinstance(op.gate, ops.ResetChannel):
         reset = op.gate
         # Do a silent measurement.
         bits, _ = wave_function.measure_state_vector(
             data.state, indices, out=data.state, qid_shape=data.state.shape)
         # Apply bit flip(s) to change the reset the bits to 0.
         for b, i, d in zip(bits, indices, protocols.qid_shape(reset)):
             if b == 0:
                 continue  # Already zero, no reset needed
             reset_unitary = _FlipGate(d, reset_value=b)(*op.qubits)
             self._simulate_unitary(reset_unitary, data, [i])
Пример #3
0
 def _simulate_measurement(self, op: ops.Operation, data: _StateAndBuffer,
                           indices: List[int],
                           measurements: Dict[str, List[bool]],
                           num_qubits: int) -> None:
     """Simulate an op that is a measurement in the computataional basis."""
     meas = ops.op_gate_of_type(op, ops.MeasurementGate)
     # TODO: support measurement outside computational basis.
     if meas:
         invert_mask = meas.invert_mask or num_qubits * (False, )
         # Measure updates inline.
         bits, _ = wave_function.measure_state_vector(
             data.state, indices, data.state)
         corrected = [bit ^ mask for bit, mask in zip(bits, invert_mask)]
         key = protocols.measurement_key(meas)
         measurements[key].extend(corrected)
Пример #4
0
 def _simulate_measurement(self, op: ops.Operation, data: _StateAndBuffer,
                           indices: List[int],
                           measurements: Dict[str, List[int]],
                           num_qubits: int) -> None:
     """Simulate an op that is a measurement in the computational basis."""
     # TODO: support measurement outside computational basis.
     if isinstance(op.gate, ops.MeasurementGate):
         meas = op.gate
         invert_mask = meas.full_invert_mask()
         # Measure updates inline.
         bits, _ = wave_function.measure_state_vector(
             data.state,
             indices,
             out=data.state,
             qid_shape=data.state.shape,
             seed=self.prng)
         corrected = [
             bit ^ (bit < 2 and mask)
             for bit, mask in zip(bits, invert_mask)
         ]
         key = protocols.measurement_key(meas)
         measurements[key].extend(corrected)
Пример #5
0
    def _base_iterator(
        self,
        circuit: circuits.Circuit,
        qubit_order: ops.QubitOrderOrList,
        initial_state: Union[int, np.ndarray],
        perform_measurements: bool = True,
    ) -> Iterator:
        qubits = ops.QubitOrder.as_qubit_order(qubit_order).order_for(
            circuit.all_qubits())
        num_qubits = len(qubits)
        qubit_map = {q: i for i, q in enumerate(qubits)}
        state = wave_function.to_valid_state_vector(initial_state, num_qubits,
                                                    self._dtype)
        if len(circuit) == 0:
            yield SparseSimulatorStep(state, {}, qubit_map, self._dtype)

        def on_stuck(bad_op: ops.Operation):
            return TypeError(
                "Can't simulate unknown operations that don't specify a "
                "_unitary_ method, a _decompose_ method, or "
                "(_has_unitary_ + _apply_unitary_) methods"
                ": {!r}".format(bad_op))

        def keep(potential_op: ops.Operation) -> bool:
            return (protocols.has_unitary(potential_op)
                    or protocols.is_measurement(potential_op))

        state = np.reshape(state, (2, ) * num_qubits)
        buffer = np.empty((2, ) * num_qubits, dtype=self._dtype)
        for moment in circuit:
            measurements = collections.defaultdict(
                list)  # type: Dict[str, List[bool]]

            non_display_ops = (op for op in moment
                               if not isinstance(op, (
                                   ops.SamplesDisplay, ops.WaveFunctionDisplay,
                                   ops.DensityMatrixDisplay)))
            unitary_ops_and_measurements = protocols.decompose(
                non_display_ops, keep=keep, on_stuck_raise=on_stuck)

            for op in unitary_ops_and_measurements:
                indices = [qubit_map[qubit] for qubit in op.qubits]
                # TODO: Support measurements outside of computational basis.
                # TODO: Support mixtures.
                meas = ops.op_gate_of_type(op, ops.MeasurementGate)
                if meas:
                    if perform_measurements:
                        invert_mask = meas.invert_mask or num_qubits * (
                            False, )
                        # Measure updates inline.
                        bits, _ = wave_function.measure_state_vector(
                            state, indices, state)
                        corrected = [
                            bit ^ mask for bit, mask in zip(bits, invert_mask)
                        ]
                        key = protocols.measurement_key(meas)
                        measurements[key].extend(corrected)
                else:
                    result = protocols.apply_unitary(
                        op,
                        args=protocols.ApplyUnitaryArgs(
                            state, buffer, indices))
                    if result is buffer:
                        buffer = state
                    state = result
            yield SparseSimulatorStep(state_vector=state,
                                      measurements=measurements,
                                      qubit_map=qubit_map,
                                      dtype=self._dtype)