def reset(self, qargs=None): """Reset state or subsystems to the 0-state. Args: qargs (list or None): subsystems to reset, if None all subsystems will be reset to their 0-state (Default: None). Returns: DensityMatrix: the reset state. Additional Information: If all subsystems are reset this will return the ground state on all subsystems. If only a some subsystems are reset this function will perform evolution by the reset :class:`~qiskit.quantum_info.SuperOp` of the reset subsystems. """ if qargs is None: # Resetting all qubits does not require sampling or RNG ret = copy.copy(self) state = np.zeros(self._op_shape.shape, dtype=complex) state[0, 0] = 1 ret._data = state return ret # Reset by evolving by reset SuperOp dims = self.dims(qargs) reset_superop = SuperOp(ScalarOp(dims, coeff=0)) reset_superop.data[0] = Operator(ScalarOp(dims)).data.ravel() return self.evolve(reset_superop, qargs=qargs)
def _add(self, other, qargs=None): """Return the operator self + other. If ``qargs`` are specified the other operator will be added assuming it is identity on all other subsystems. Args: other (Operator): an operator object. qargs (None or list): optional subsystems to add on (Default: None) Returns: Operator: the operator self + other. Raises: QiskitError: if other is not an operator, or has incompatible dimensions. """ # pylint: disable=cyclic-import from qiskit.quantum_info.operators.scalar_op import ScalarOp if qargs is None: qargs = getattr(other, 'qargs', None) if not isinstance(other, Operator): other = Operator(other) self._op_shape._validate_add(other._op_shape, qargs) other = ScalarOp._pad_with_identity(self, other, qargs) ret = copy.copy(self) ret._data = self.data + other.data return ret
def _add(self, other, qargs=None): """Return the QuantumChannel self + other. If ``qargs`` are specified the other channel will be added assuming it is the identity channel on all other subsystems. Args: other (QuantumChannel): a quantum channel. qargs (None or list): optional subsystems to add on (Default: None) Returns: QuantumChannel: the linear addition self + other as a SuperOp object. Raises: QiskitError: if other cannot be converted to a channel or has incompatible dimensions. """ # NOTE: this method must be overriden for subclasses # that don't have a linear matrix representation # ie Kraus and Stinespring if qargs is None: qargs = getattr(other, 'qargs', None) if not isinstance(other, self.__class__): other = self.__class__(other) self._validate_add_dims(other, qargs) other = ScalarOp._pad_with_identity(self, other, qargs) ret = copy.copy(self) ret._data = self._data + other._data return ret
def _append_instruction(self, obj, qargs=None): """Update the current Operator by apply an instruction.""" from qiskit.circuit.barrier import Barrier from .scalar_op import ScalarOp mat = self._instruction_to_matrix(obj) if mat is not None: # Perform the composition and inplace update the current state # of the operator op = self.compose(mat, qargs=qargs) self._data = op.data elif isinstance(obj, Barrier): return else: # If the instruction doesn't have a matrix defined we use its # circuit decomposition definition if it exists, otherwise we # cannot compose this gate and raise an error. if obj.definition is None: raise QiskitError(f"Cannot apply Operation: {obj.name}") if not isinstance(obj.definition, QuantumCircuit): raise QiskitError( 'Operation "{}" ' "definition is {} but expected QuantumCircuit.".format( obj.name, type(obj.definition))) if obj.definition.global_phase: dimension = 2**obj.num_qubits op = self.compose( ScalarOp(dimension, np.exp(1j * float(obj.definition.global_phase))), qargs=qargs, ) self._data = op.data flat_instr = obj.definition bit_indices = { bit: index for bits in [flat_instr.qubits, flat_instr.clbits] for index, bit in enumerate(bits) } for instruction in flat_instr: if instruction.clbits: raise QiskitError( "Cannot apply operation with classical bits:" f" {instruction.operation.name}") # Get the integer position of the flat register if qargs is None: new_qargs = [ bit_indices[tup] for tup in instruction.qubits ] else: new_qargs = [ qargs[bit_indices[tup]] for tup in instruction.qubits ] self._append_instruction(instruction.operation, qargs=new_qargs)
def _add(self, other, qargs=None): # NOTE: this method must be overridden for subclasses # that don't have a linear matrix representation # ie Kraus and Stinespring if not isinstance(other, type(self)): other = type(self)(other) self._op_shape._validate_add(other._op_shape, qargs) other = ScalarOp._pad_with_identity(self, other, qargs) ret = copy.copy(self) ret._data = self._data + other._data return ret
def _append_instruction(self, obj, qargs=None): """Update the current Operator by apply an instruction.""" from qiskit.circuit.barrier import Barrier from .scalar_op import ScalarOp mat = self._instruction_to_matrix(obj) if mat is not None: # Perform the composition and inplace update the current state # of the operator op = self.compose(mat, qargs=qargs) self._data = op.data elif isinstance(obj, Barrier): return else: # If the instruction doesn't have a matrix defined we use its # circuit decomposition definition if it exists, otherwise we # cannot compose this gate and raise an error. if obj.definition is None: raise QiskitError('Cannot apply Instruction: {}'.format( obj.name)) if not isinstance(obj.definition, QuantumCircuit): raise QiskitError( 'Instruction "{}" ' 'definition is {} but expected QuantumCircuit.'.format( obj.name, type(obj.definition))) if obj.definition.global_phase: dimension = 2**self.num_qubits op = self.compose(ScalarOp( dimension, np.exp(1j * float(obj.definition.global_phase))), qargs=qargs) self._data = op.data flat_instr = obj.definition.to_instruction() for instr, qregs, cregs in flat_instr.definition.data: if cregs: raise QiskitError( 'Cannot apply instruction with classical registers: {}' .format(instr.name)) # Get the integer position of the flat register if qargs is None: new_qargs = [tup.index for tup in qregs] else: new_qargs = [qargs[tup.index] for tup in qregs] self._append_instruction(instr, qargs=new_qargs)