Beispiel #1
0
    def __init__(self, data, time, label=None):
        """Create a gate from a hamiltonian operator and evolution time parameter t

        Args:
            data (matrix or Operator): a hermitian operator.
            time (float): time evolution parameter.
            label (str): unitary name for backend [Default: None].

        Raises:
            ExtensionError: if input data is not an N-qubit unitary operator.
        """
        if hasattr(data, 'to_matrix'):
            # If input is Gate subclass or some other class object that has
            # a to_matrix method this will call that method.
            data = data.to_matrix()
        elif hasattr(data, 'to_operator'):
            # If input is a BaseOperator subclass this attempts to convert
            # the object to an Operator so that we can extract the underlying
            # numpy matrix from `Operator.data`.
            data = data.to_operator().data
        # Convert to numpy array in case not already an array
        data = numpy.array(data, dtype=complex)
        # Check input is unitary
        if not is_hermitian_matrix(data):
            raise ExtensionError("Input matrix is not Hermitian.")
        if isinstance(time, Number) and time != numpy.real(time):
            raise ExtensionError("Evolution time is not real.")
        # Check input is N-qubit matrix
        input_dim, output_dim = data.shape
        num_qubits = int(numpy.log2(input_dim))
        if input_dim != output_dim or 2**num_qubits != input_dim:
            raise ExtensionError("Input matrix is not an N-qubit operator.")

        # Store instruction params
        super().__init__('hamiltonian', num_qubits, [data, time], label=label)
Beispiel #2
0
    def __init__(self, data, label=None):
        """Create a gate from a numeric unitary matrix.

        Args:
            data (matrix or Operator): unitary operator.
            label (str): unitary name for backend [Default: None].

        Raises:
            ExtensionError: if input data is not an N-qubit unitary operator.
        """
        if hasattr(data, 'to_matrix'):
            # If input is Gate subclass or some other class object that has
            # a to_matrix method this will call that method.
            data = data.to_matrix()
        elif hasattr(data, 'to_operator'):
            # If input is a BaseOperator subclass this attempts to convert
            # the object to an Operator so that we can extract the underlying
            # numpy matrix from `Operator.data`.
            data = data.to_operator().data
        # Convert to numpy array in case not already an array
        data = numpy.array(data, dtype=complex)
        # Check input is unitary
        if not is_unitary_matrix(data):
            raise ExtensionError("Input matrix is not unitary.")
        # Check input is N-qubit matrix
        input_dim, output_dim = data.shape
        num_qubits = int(numpy.log2(input_dim))
        if input_dim != output_dim or 2**num_qubits != input_dim:
            raise ExtensionError("Input matrix is not an N-qubit operator.")

        self._qasm_name = None
        self._qasm_definition = None
        self._qasm_def_written = False
        # Store instruction params
        super().__init__('unitary', num_qubits, [data], label=label)
Beispiel #3
0
def snapshot(self, label, snap_type='statevector'):
    """Take a snapshot of the internal simulator representation (statevector)
    Works on all qubits, and prevents reordering (like barrier).

    Args:
        label (str): a snapshot label to report the result
        snap_type (str): a snapshot type (only supports statevector)

    Returns:
        QuantumCircuit: with attached command

    Raises:
        ExtensionError: malformed command
    """
    tuples = []
    if isinstance(self, QuantumCircuit):
        for register in self.qregs:
            tuples.append(register)
    if not tuples:
        raise ExtensionError("no qubits for snapshot")
    if label is None:
        raise ExtensionError("no snapshot label passed")
    qubits = []
    for tuple_element in tuples:
        if isinstance(tuple_element, QuantumRegister):
            for j in range(tuple_element.size):
                self._check_qubit((tuple_element, j))
                qubits.append((tuple_element, j))
        else:
            self._check_qubit(tuple_element)
            qubits.append(tuple_element)
    self._check_dups(qubits)
    return self._attach(Snapshot(label, snap_type, qubits, self))
Beispiel #4
0
    def __init__(self, name, num_qubits, label, subtype='single', params=None):
        """Create new save data instruction.

        Args:
            name (str): the name of hte save instruction.
            num_qubits (int): the number of qubits for the snapshot type.
            label (str): the key for retrieving saved data from results.
            subtype (str): the data subtype for the instruction [Default: 'single'].
            params (list or None): Optional, the parameters for instruction
                                   [Default: None].

        Raises:
            ExtensionError: if the subtype string is invalid.

        Additional Information:
            The supported subtypes are 'single', 'list', 'c_list', 'average',
            'c_average', 'accum', 'c_accum'.
        """
        if params is None:
            params = {}

        if subtype not in self._allowed_subtypes:
            raise ExtensionError(
                "Invalid data subtype for SaveData instruction.")

        if not isinstance(label, str):
            raise ExtensionError(
                f"Invalid label for save data instruction, {label} must be a string."
            )

        self._label = label
        self._subtype = subtype
        super().__init__(name, num_qubits, 0, params)
Beispiel #5
0
def set_superop(self, state):
    """Set the superop state of the simulator.

    Args:
        state (QuantumChannel): A CPTP quantum channel.

    Returns:
        QuantumCircuit: with attached instruction.

    Raises:
        ExtensionError: If the state is the incorrect size for the
                        current circuit.
        ExtensionError: if the input QuantumChannel is not CPTP.

    .. note:

        This instruction is always defined across all qubits in a circuit.
    """
    qubits = default_qubits(self)
    if not isinstance(state, SuperOp):
        state = SuperOp(state)
    if not state.num_qubits or state.num_qubits != len(qubits):
        raise ExtensionError(
            "The size of the quantum channel for the set_superop"
            " instruction must be equal to the number of qubits"
            f" in the circuit (state.num_qubits ({state.num_qubits})"
            f" != QuantumCircuit.num_qubits ({self.num_qubits})).")
    return self.append(SetSuperOp(state), qubits)
def set_density_matrix(self, state):
    """Set the density matrix state of the simulator.

    Args:
        state (DensityMatrix): a density matrix.

    Returns:
        QuantumCircuit: with attached instruction.

    Raises:
        ExtensionError: If the density matrix is the incorrect size for the
                        current circuit.

    .. note:

        This instruction is always defined across all qubits in a circuit.
    """
    qubits = default_qubits(self)
    if not isinstance(state, DensityMatrix):
        state = DensityMatrix(state)
    if not state.num_qubits or state.num_qubits != len(qubits):
        raise ExtensionError(
            "The size of the density matrix for the set state"
            " instruction must be equal to the number of qubits"
            f" in the circuit (state.num_qubits ({state.num_qubits})"
            f" != QuantumCircuit.num_qubits ({self.num_qubits})).")
    return self.append(SetDensityMatrix(state), qubits)
Beispiel #7
0
def _expval_params(operator, variance=False):

    # Convert O to SparsePauliOp representation
    if isinstance(operator, Pauli):
        operator = SparsePauliOp(operator)
    elif not isinstance(operator, SparsePauliOp):
        operator = SparsePauliOp.from_operator(Operator(operator))
    if not isinstance(operator, SparsePauliOp):
        raise ExtensionError("Invalid input operator")

    params = {}

    # Add Pauli basis components of O
    for pauli, coeff in operator.label_iter():
        if pauli in params:
            coeff1 = params[pauli][0]
            params[pauli] = (coeff1 + coeff.real, 0)
        else:
            params[pauli] = (coeff.real, 0)

    # Add Pauli basis components of O^2
    if variance:
        for pauli, coeff in operator.dot(operator).label_iter():
            if pauli in params:
                coeff1, coeff2 = params[pauli]
                params[pauli] = (coeff1, coeff2 + coeff.real)
            else:
                params[pauli] = (0, coeff.real)

    # Convert to list
    return list(params.items())
    def define_snapshot_register(circuit,
                                 label,
                                 qubits=None):
        """Defines qubits to snapshot for all snapshot methods"""
        # Convert label to string for backwards compatibility
        if not isinstance(label, str):
            warnings.warn(
                "Snapshot label should be a string, "
                "implicit conversion is deprecated.", DeprecationWarning)
            label = str(label)
        # If no qubits are specified we add all qubits so it acts as a barrier
        # This is needed for full register snapshots like statevector
        if isinstance(qubits, QuantumRegister):
            qubits = qubits[:]
        if not qubits:
            tuples = []
            if isinstance(circuit, QuantumCircuit):
                for register in circuit.qregs:
                    tuples.append(register)
            if not tuples:
                raise ExtensionError('no qubits for snapshot')
            qubits = []
            for tuple_element in tuples:
                if isinstance(tuple_element, QuantumRegister):
                    for j in range(tuple_element.size):
                        qubits.append(tuple_element[j])
                else:
                    qubits.append(tuple_element)

        return qubits
Beispiel #9
0
def set_stabilizer(self, state):
    """Set the Clifford stabilizer state of the simulator.

    Args:
        state (Clifford): A clifford operator.

    Returns:
        QuantumCircuit: with attached instruction.

    Raises:
        ExtensionError: If the state is the incorrect size for the
                        current circuit.

    .. note:

        This instruction is always defined across all qubits in a circuit.
    """
    qubits = default_qubits(self)
    if not isinstance(state, Clifford):
        state = Clifford(state)
    if state.num_qubits != len(qubits):
        raise ExtensionError(
            "The size of the Clifford for the set_stabilizer"
            " instruction must be equal to the number of qubits"
            f" in the circuit (state.num_qubits ({state.num_qubits})"
            f" != QuantumCircuit.num_qubits ({self.num_qubits})).")
    return self.append(SetStabilizer(state), qubits)
Beispiel #10
0
def set_unitary(self, state):
    """Set the state state of the simulator.

    Args:
        state (Operator): A state matrix.

    Returns:
        QuantumCircuit: with attached instruction.

    Raises:
        ExtensionError: If the state is the incorrect size for the
                        current circuit.
        ExtensionError: if the input matrix is not unitary.

    .. note:

        This instruction is always defined across all qubits in a circuit.
    """
    qubits = default_qubits(self)
    if not isinstance(state, Operator):
        state = Operator(state)
    if not state.num_qubits or state.num_qubits != len(qubits):
        raise ExtensionError(
            "The size of the unitary matrix for the set_unitary"
            " instruction must be equal to the number of qubits"
            f" in the circuit (state.num_qubits ({state.num_qubits})"
            f" != QuantumCircuit.num_qubits ({self.num_qubits})).")
    return self.append(SetUnitary(state), qubits)
Beispiel #11
0
    def define_snapshot_register(circuit, label=None, qubits=None):
        """Defines qubits to snapshot for all snapshot methods"""
        # Convert label to string for backwards compatibility
        if label is not None:
            warnings.warn(
                "The 'label' arg of `define_snapshot_register` has been deprecated"
                "as of qiskit-aer 0.7.0.", DeprecationWarning)
        # If no qubits are specified we add all qubits so it acts as a barrier
        # This is needed for full register snapshots like statevector
        if isinstance(qubits, QuantumRegister):
            qubits = qubits[:]
        if not qubits:
            tuples = []
            if isinstance(circuit, QuantumCircuit):
                for register in circuit.qregs:
                    tuples.append(register)
            if not tuples:
                raise ExtensionError('no qubits for snapshot')
            qubits = []
            for tuple_element in tuples:
                if isinstance(tuple_element, QuantumRegister):
                    for j in range(tuple_element.size):
                        qubits.append(tuple_element[j])
                else:
                    qubits.append(tuple_element)

        return qubits
    def __init__(self,
                 label,
                 snapshot_type='statevector',
                 num_qubits=0,
                 num_clbits=0,
                 params=None):
        """Create new snapshot instruction.

        Args:
            label (str): the snapshot label for result data.
            snapshot_type (str): the type of the snapshot.
            num_qubits (int): the number of qubits for the snapshot type [Default: 0].
            num_clbits (int): the number of classical bits for the snapshot type [Default: 0].
            params (list or None): the parameters for snapshot_type [Default: None].

        Raises:
            ExtensionError: if snapshot label is invalid.
        """
        if not isinstance(label, str):
            raise ExtensionError('Snapshot label must be a string.')
        self._label = label
        self._snapshot_type = snapshot_type
        if params is None:
            params = []
        super().__init__('snapshot', num_qubits, num_clbits, params)
Beispiel #13
0
def _format_amplitude_params(params, num_qubits=None):
    """Format amplitude params as a interger list."""
    if isinstance(params[0], str):
        if params[0].find('0x') == 0:
            params = [int(i, 16) for i in params]
        else:
            params = [int(i, 2) for i in params]
    if num_qubits and max(params) >= 2 ** num_qubits:
        raise ExtensionError(
            "Param values contain a state larger than the number of qubits")
    return params
Beispiel #14
0
    def __init__(self, label, op, single_shot=False, variance=False):
        """Create an expectation value snapshot instruction.

        Args:
            label (str): the snapshot label.
            op (Operator): operator to snapshot.
            single_shot (bool): return list for each shot rather than average [Default: False]
            variance (bool): compute variance of values [Default: False]

        Raises:
            ExtensionError: if snapshot is invalid.
        """
        if variance:
            warn(
                'The snapshot `variance` kwarg has been deprecated and will'
                ' be removed in qiskit-aer 0.8. To compute variance use'
                ' `single_shot=True` and compute manually in post-processing',
                DeprecationWarning)
        pauli_op = self._format_pauli_op(op)
        if pauli_op:
            # Pauli expectation value
            snapshot_type = 'expectation_value_pauli'
            params = pauli_op
            num_qubits = len(params[0][1])
        else:
            snapshot_type = 'expectation_value_matrix'
            mat = self._format_single_matrix(op)
            if mat is not None:
                num_qubits = int(math.log2(len(mat)))
                if mat.shape != (2**num_qubits, 2**num_qubits):
                    raise ExtensionError("Snapshot Operator is invalid.")
                qubits = list(range(num_qubits))
                params = [[1., [[qubits, mat]]]]
            else:
                # If op doesn't match the previous cases we try passing
                # in the op as raw params
                params = op
                num_qubits = 0
                for _, pair in params:
                    num_qubits = max(num_qubits, *pair[0])

        # HACK: we wrap param list in numpy array to make it validate
        # in terra
        params = [numpy.array(elt, dtype=object) for elt in params]

        if single_shot:
            snapshot_type += '_single_shot'
        elif variance:
            snapshot_type += '_with_variance'
        super().__init__(label,
                         snapshot_type=snapshot_type,
                         num_qubits=num_qubits,
                         params=params)
def snapshot(self,
             label,
             snapshot_type='statevector',
             qubits=None,
             params=None):
    """Take a statevector snapshot of the internal simulator representation.
    Works on all qubits, and prevents reordering (like barrier).

    For other types of snapshots use the Snapshot extension directly.

    Args:
        label (str): a snapshot label to report the result
        snapshot_type (str): the type of the snapshot.
        qubits (list or None): the qubits to apply snapshot to [Default: None].
        params (list or None): the parameters for snapshot_type [Default: None].

    Returns:
        QuantumCircuit: with attached command

    Raises:
        ExtensionError: malformed command
    """
    # Convert label to string for backwards compatibility
    if not isinstance(label, str):
        warnings.warn(
            "Snapshot label should be a string, "
            "implicit conversion is depreciated.", DeprecationWarning)
        label = str(label)
    # If no qubits are specified we add all qubits so it acts as a barrier
    # This is needed for full register snapshots like statevector
    if isinstance(qubits, QuantumRegister):
        qubits = qubits[:]
    if not qubits:
        tuples = []
        if isinstance(self, QuantumCircuit):
            for register in self.qregs:
                tuples.append(register)
        if not tuples:
            raise ExtensionError('no qubits for snapshot')
        qubits = []
        for tuple_element in tuples:
            if isinstance(tuple_element, QuantumRegister):
                for j in range(tuple_element.size):
                    qubits.append(tuple_element[j])
            else:
                qubits.append(tuple_element)
    return self.append(
        Snapshot(
            label,
            snapshot_type=snapshot_type,
            num_qubits=len(qubits),
            params=params), qubits)
Beispiel #16
0
def set_matrix_product_state(self, state):
    """Set the matrix product state of the simulator.

    Args:
        state (Tuple[List[Tuple[np.array[complex_t]]]], List[List[float]]):
              A matrix_product_state.

    Returns:
        QuantumCircuit: with attached instruction.

    Raises:
        ExtensionError: If the structure of the state is incorrect

    .. note:

        This instruction is always defined across all qubits in a circuit.
    """
    qubits = default_qubits(self)
    if not isinstance(state, tuple) or len(state) != 2:
        raise ExtensionError(
            "The input matrix product state is not valid.  Should be a list of 2 elements"
        )
    if not isinstance(state[0], list) or not isinstance(state[1], list):
        raise ExtensionError(
            "The first element of the input matrix product state is not valid. Should be a list."
        )
    if len(state[0]) != len(state[1]) + 1:
        raise ExtensionError(
            "The input matrix product state is not valid. "
            "Length of q_reg vector should be 1 more than length of lambda_reg"
        )
    for elem in state[0]:
        if not isinstance(elem, tuple) or len(elem) != 2:
            raise ExtensionError(
                "The input matrix product state is not valid."
                "The first element should be a list of length 2")
    return self.append(SetMatrixProductState(state), qubits)
Beispiel #17
0
    def __init__(self,
                 operator,
                 label="expectation_value_variance",
                 unnormalized=False,
                 pershot=False,
                 conditional=False):
        r"""Instruction to save the expectation value and variance of a Hermitian operator.

        The expectation value of a Hermitian operator :math:`H` for a
        simulator in quantum state :math`\rho`is given by
        :math:`\langle H\rangle = \mbox{Tr}[H.\rho]`. The variance is given by
        :math:`\sigma^2 = \langle H^2 \rangle - \langle H \rangle>^2`.

        Args:
            operator (Pauli or SparsePauliOp or Operator): a Hermitian operator.
            label (str): the key for retrieving saved data from results.
            unnormalized (bool): If True return save the unnormalized accumulated
                                 or conditional accumulated expectation value
                                 over all shot [Default: False].
            pershot (bool): if True save a list of expectation values for each shot
                            of the simulation rather than the average over
                            all shots [Default: False].
            conditional (bool): if True save the average or pershot data
                                conditional on the current classical register
                                values [Default: False].

        Raises:
            ExtensionError: if the input operator is invalid or not Hermitian.

        .. note::

            This instruction can be directly appended to a circuit using
            the :func:`save_expectation_value` circuit method.
        """
        # Convert O to SparsePauliOp representation
        if isinstance(operator, Pauli):
            operator = SparsePauliOp(operator)
        elif not isinstance(operator, SparsePauliOp):
            operator = SparsePauliOp.from_operator(Operator(operator))
        if not allclose(operator.coeffs.imag, 0):
            raise ExtensionError("Input operator is not Hermitian.")
        params = _expval_params(operator, variance=True)
        super().__init__('save_expval_var',
                         operator.num_qubits,
                         label,
                         unnormalized=unnormalized,
                         pershot=pershot,
                         conditional=conditional,
                         params=params)
Beispiel #18
0
    def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None):
        r"""Return controlled version of gate

        Args:
            num_ctrl_qubits (int): number of controls to add to gate (default=1)
            label (str): optional gate label
            ctrl_state (int or str or None): The control state in decimal or as a
                bit string (e.g. '1011'). If None, use 2**num_ctrl_qubits-1.

        Returns:
            UnitaryGate: controlled version of gate.

        Raises:
            QiskitError: Invalid ctrl_state.
            ExtensionError: Non-unitary controlled unitary.
        """
        cmat = _compute_control_matrix(self.to_matrix(),
                                       num_ctrl_qubits,
                                       ctrl_state=ctrl_state)
        iso = isometry.Isometry(cmat, 0, 0)
        cunitary = ControlledGate('c-unitary',
                                  num_qubits=self.num_qubits + num_ctrl_qubits,
                                  params=[cmat],
                                  label=label,
                                  num_ctrl_qubits=num_ctrl_qubits,
                                  definition=iso.definition,
                                  ctrl_state=ctrl_state)

        from qiskit.quantum_info import Operator
        # hack to correct global phase; should fix to prevent need for correction here
        pmat = (Operator(iso.inverse()).data @ cmat)
        diag = numpy.diag(pmat)
        if not numpy.allclose(diag, diag[0]):
            raise ExtensionError('controlled unitary generation failed')
        phase = numpy.angle(diag[0])
        if phase:
            qreg = cunitary.definition.qregs[0]
            cunitary.definition.u3(numpy.pi, phase, phase - numpy.pi, qreg[0])
            cunitary.definition.u3(numpy.pi, 0, numpy.pi, qreg[0])
        cunitary.base_gate = self.copy()
        cunitary.base_gate.label = self.label
        return cunitary
Beispiel #19
0
    def __init__(self, state):
        """Create new instruction to set the unitary simulator state.

        Args:
            state (Operator): A unitary matrix.

        Raises:
            ExtensionError: if the input matrix is not state.

        .. note::

            This set instruction must always be performed on the full width of
            qubits in a circuit, otherwise an exception will be raised during
            simulation.
        """
        if not isinstance(state, Operator):
            state = Operator(state)
        if not state.num_qubits or not state.is_unitary():
            raise ExtensionError("The input matrix is not unitary")
        super().__init__('set_unitary', state.num_qubits, 0, [state.data])
Beispiel #20
0
    def __init__(self, state):
        """Create new instruction to set the superop simulator state.

        Args:
            state (QuantumChannel): A CPTP quantum channel.

        Raises:
            ExtensionError: if the input QuantumChannel is not CPTP.

        .. note::

            This set instruction must always be performed on the full width of
            qubits in a circuit, otherwise an exception will be raised during
            simulation.
        """
        if not isinstance(state, SuperOp):
            state = SuperOp(state)
        if not state.num_qubits or not state.is_cptp():
            raise ExtensionError("The input quantum channel is not CPTP")
        super().__init__('set_superop', state.num_qubits, 0, [state.data])
Beispiel #21
0
    def __init__(self, state):
        """Create new instruction to set the statevector state of the simulator.

        Args:
            state (Statevector): a statevector.

        Raises:
            ExtensionError: if the input is not a valid state.

        .. note::

            This set instruction must always be performed on the full width of
            qubits in a circuit, otherwise an exception will be raised during
            simulation.
        """
        if not isinstance(state, Statevector):
            state = Statevector(state)
        if not state.num_qubits or not state.is_valid():
            raise ExtensionError("The input statevector is not valid")
        super().__init__('set_statevector', state.num_qubits, 0, [state.data])
Beispiel #22
0
    def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None):
        """Return controlled version of gate

        Args:
            num_ctrl_qubits (int): number of controls to add to gate (default=1)
            label (str): optional gate label
            ctrl_state (int or str or None): The control state in decimal or as a
                bit string (e.g. '1011'). If None, use 2**num_ctrl_qubits-1.

        Returns:
            UnitaryGate: controlled version of gate.

        Raises:
            QiskitError: Invalid ctrl_state.
            ExtensionError: Non-unitary controlled unitary.
        """
        mat = self.to_matrix()
        cmat = _compute_control_matrix(mat, num_ctrl_qubits, ctrl_state=None)
        iso = isometry.Isometry(cmat, 0, 0)
        cunitary = ControlledGate(
            "c-unitary",
            num_qubits=self.num_qubits + num_ctrl_qubits,
            params=[mat],
            label=label,
            num_ctrl_qubits=num_ctrl_qubits,
            definition=iso.definition,
            ctrl_state=ctrl_state,
            base_gate=self.copy(),
        )
        from qiskit.quantum_info import Operator

        # hack to correct global phase; should fix to prevent need for correction here
        pmat = Operator(iso.inverse()).data @ cmat
        diag = numpy.diag(pmat)
        if not numpy.allclose(diag, diag[0]):
            raise ExtensionError("controlled unitary generation failed")
        phase = numpy.angle(diag[0])
        if phase:
            # need to apply to _definition since open controls creates temporary definition
            cunitary._definition.global_phase = phase
        return cunitary
Beispiel #23
0
    def __init__(self, state):
        """Create new instruction to set the density matrix state of the simulator.

        Args:
            state (DensityMatrix): a density matrix.

        Raises:
            ExtensionError: if the input density matrix is not valid.

        .. note::

            This set instruction must always be performed on the full width of
            qubits in a circuit, otherwise an exception will be raised during
            simulation.
        """
        if not isinstance(state, DensityMatrix):
            state = DensityMatrix(state)
        if not state.num_qubits or not state.is_valid():
            raise ExtensionError("The input state is not valid")
        super().__init__('set_density_matrix', state.num_qubits, 0,
                         [state.data])
    def __init__(self,
                 label,
                 snapshot_type='statevector',
                 num_qubits=0,
                 num_clbits=0,
                 params=None):
        """Create new snapshot instruction.

        Args:
            label (str): the snapshot label for result data.
            snapshot_type (str): the type of the snapshot.
            num_qubits (int): the number of qubits for the snapshot type [Default: 0].
            num_clbits (int): the number of classical bits for the snapshot type [Default: 0].
            params (list or None): the parameters for snapshot_type [Default: None].

        Raises:
            ExtensionError: if snapshot label is invalid.

        .. deprecated:: 0.9.0

            This instruction has been deprecated and will be removed no earlier
            than 3 months from the 0.9.0 release date. It has been superseded by
            the save instructions in
            :mod:`qiskit.providers.aer.library` module.
        """
        warn(
            'The `Snapshot` instruction will be deprecated in the'
            ' future. It has been superseded by the `SaveStatevector`'
            ' instructions.',
            DeprecationWarning,
            stacklevel=2)
        if not isinstance(label, str):
            raise ExtensionError('Snapshot label must be a string.')
        if params is None:
            params = []

        super().__init__('snapshot', num_qubits, num_clbits, params)

        self._label = label
        self._snapshot_type = snapshot_type
Beispiel #25
0
def default_qubits(circuit, qubits=None):
    """Helper method to return list of qubits.

    Args:
        circuit (QuantumCircuit): a quantum circuit.
        qubits (list or QuantumRegister): Optional, qubits argument,
            If None the returned list will be all qubits in the circuit.
            [Default: None]

    Raises:
            ExtensionError: if default qubits fails.

    Returns:
        list: qubits list.
    """
    # Convert label to string for backwards compatibility
    # If no qubits are specified we add all qubits so it acts as a barrier
    # This is needed for full register snapshots like statevector
    if isinstance(qubits, QuantumRegister):
        qubits = qubits[:]
    if not qubits:
        tuples = []
        if isinstance(circuit, QuantumCircuit):
            for register in circuit.qregs:
                tuples.append(register)
        if not tuples:
            raise ExtensionError('no qubits for snapshot')
        qubits = []
        for tuple_element in tuples:
            if isinstance(tuple_element, QuantumRegister):
                for j in range(tuple_element.size):
                    qubits.append(tuple_element[j])
            else:
                qubits.append(tuple_element)

    return qubits
    def __init__(self, label, op, single_shot=False, variance=False):
        """Create an expectation value snapshot instruction.

        Args:
            label (str): the snapshot label.
            op (Operator): operator to snapshot.
            single_shot (bool): return list for each shot rather than average [Default: False]
            variance (bool): compute variance of values [Default: False]

        Raises:
            ExtensionError: if snapshot is invalid.

        .. deprecated:: 0.9.0

            This instruction has been deprecated and will be removed no earlier
            than 3 months from the 0.9.0 release date. It has been superseded by the
            :class:`qiskit.providers.aer.library.SaveExpectationValue` and
            :class:`qiskit.providers.aer.library.SaveExpectationValueVariance`
            instructions.
        """
        warn(
            'The `SnapshotExpectationValue` instruction has been deprecated as of'
            ' qiskit-aer 0.9. It has been superseded by the `SaveExpectationValue` and'
            ' `SaveExpectationValueVariance` instructions.',
            DeprecationWarning,
            stacklevel=2)
        pauli_op = self._format_pauli_op(op)
        if pauli_op:
            # Pauli expectation value
            snapshot_type = 'expectation_value_pauli'
            params = pauli_op
            num_qubits = len(params[0][1])
        else:
            snapshot_type = 'expectation_value_matrix'
            mat = self._format_single_matrix(op)
            if mat is not None:
                num_qubits = int(math.log2(len(mat)))
                if mat.shape != (2**num_qubits, 2**num_qubits):
                    raise ExtensionError("Snapshot Operator is invalid.")
                qubits = list(range(num_qubits))
                params = [[1., [[qubits, mat]]]]
            else:
                # If op doesn't match the previous cases we try passing
                # in the op as raw params
                params = op
                num_qubits = 0
                for _, pair in params:
                    num_qubits = max(num_qubits, *pair[0])

        # HACK: we wrap param list in numpy array to make it validate
        # in terra
        params = [numpy.array(elt, dtype=object) for elt in params]

        if single_shot:
            snapshot_type += '_single_shot'
        elif variance:
            snapshot_type += '_with_variance'
        super().__init__(label,
                         snapshot_type=snapshot_type,
                         num_qubits=num_qubits,
                         params=params)
Beispiel #27
0
 def qasm(self):
     """Raise an error, as QASM is not defined for the HamiltonianGate."""
     raise ExtensionError("HamiltonianGate as no QASM definition.")