def gates_to_idx(gates, qregs):
    """Converts gate tuples into a nested list of integers.

    Args:
        gates (list): List of (QuantumRegister, int) pairs
                      representing gates.
        qregs (dict): List of )QuantumRegister, int) tuples.

    Returns:
        list: Nested list of integers for gates.
    """
    sizes = [qr.size for qr in qregs.values()]
    reg_idx = np.cumsum([0]+sizes)
    regint = {}
    for ind, qreg in enumerate(qregs.values()):
        regint[qreg] = ind
    out = np.zeros(2*len(gates), dtype=np.int32)
    for idx, gate in enumerate(gates):
        out[2*idx] = reg_idx[regint[gate[0][0]]]+gate[0][1]
        out[2*idx+1] = reg_idx[regint[gate[1][0]]]+gate[1][1]
    return out

def gates_to_idx ( gates , qregs ) : sizes = [ qr . size for qr in qregs . values ( ) ] reg_idx = np . cumsum ( [ 0 ] + sizes ) regint = { } for ind , qreg in enumerate ( qregs . values ( ) ) : regint [ qreg ] = ind out = np . zeros ( 2 * len ( gates ) , dtype = np . int32 ) for idx , gate in enumerate ( gates ) : out [ 2 * idx ] = reg_idx [ regint [ gate [ 0 ] [ 0 ] ] ] + gate [ 0 ] [ 1 ] out [ 2 * idx + 1 ] = reg_idx [ regint [ gate [ 1 ] [ 0 ] ] ] + gate [ 1 ] [ 1 ] return out

Converts gate tuples into a nested list of integers .


def run(self, dag):
        """
        Run the StochasticSwap pass on `dag`.

        Args:
            dag (DAGCircuit): DAG to map.

        Returns:
            DAGCircuit: A mapped DAG.

        Raises:
            TranspilerError: if the coupling map or the layout are not
            compatible with the DAG
        """

        if self.initial_layout is None:
            if self.property_set["layout"]:
                self.initial_layout = self.property_set["layout"]
            else:
                self.initial_layout = Layout.generate_trivial_layout(*dag.qregs.values())

        if len(dag.qubits()) != len(self.initial_layout):
            raise TranspilerError('The layout does not match the amount of qubits in the DAG')

        if len(self.coupling_map.physical_qubits) != len(self.initial_layout):
            raise TranspilerError(
                "Mappers require to have the layout to be the same size as the coupling map")

        self.input_layout = self.initial_layout.copy()

        self.qregs = dag.qregs
        if self.seed is None:
            self.seed = np.random.randint(0, np.iinfo(np.int32).max)
        self.rng = np.random.RandomState(self.seed)
        logger.debug("StochasticSwap RandomState seeded with seed=%s", self.seed)

        new_dag = self._mapper(dag, self.coupling_map, trials=self.trials)
        # self.property_set["layout"] = self.initial_layout
        return new_dag


def _layer_update(self, i, first_layer, best_layout, best_depth,
                      best_circuit, layer_list):
        """Provide a DAGCircuit for a new mapped layer.

        i (int) = layer number
        first_layer (bool) = True if this is the first layer in the
            circuit with any multi-qubit gates
        best_layout (Layout) = layout returned from _layer_permutation
        best_depth (int) = depth returned from _layer_permutation
        best_circuit (DAGCircuit) = swap circuit returned
            from _layer_permutation
        layer_list (list) = list of DAGCircuit objects for each layer,
            output of DAGCircuit layers() method

        Return a DAGCircuit object to append to the output DAGCircuit
        that the _mapper method is building.
        """
        layout = best_layout
        logger.debug("layer_update: layout = %s", pformat(layout))
        logger.debug("layer_update: self.initial_layout = %s", pformat(self.initial_layout))
        dagcircuit_output = DAGCircuit()
        for register in layout.get_virtual_bits().keys():
            if register[0] not in dagcircuit_output.qregs.values():
                dagcircuit_output.add_qreg(register[0])

        # If this is the first layer with multi-qubit gates,
        # output all layers up to this point and ignore any
        # swap gates. Set the initial layout.
        if first_layer:
            logger.debug("layer_update: first multi-qubit gate layer")
            # Output all layers up to this point
            for j in range(i + 1):
                # Make qubit edge map and extend by classical bits
                edge_map = layout.combine_into_edge_map(self.initial_layout)
                for bit in dagcircuit_output.clbits():
                    edge_map[bit] = bit
                dagcircuit_output.compose_back(layer_list[j]["graph"], edge_map)
        # Otherwise, we output the current layer and the associated swap gates.
        else:
            # Output any swaps
            if best_depth > 0:
                logger.debug("layer_update: there are swaps in this layer, "
                             "depth %d", best_depth)
                dagcircuit_output.extend_back(best_circuit)
            else:
                logger.debug("layer_update: there are no swaps in this layer")
            # Make qubit edge map and extend by classical bits
            edge_map = layout.combine_into_edge_map(self.initial_layout)
            for bit in dagcircuit_output.clbits():
                edge_map[bit] = bit
            # Output this layer
            dagcircuit_output.compose_back(layer_list[i]["graph"], edge_map)

        return dagcircuit_output

Provide a DAGCircuit for a new mapped layer .


def pauli_group(number_of_qubits, case='weight'):
    """Return the Pauli group with 4^n elements.

    The phases have been removed.
    case 'weight' is ordered by Pauli weights and
    case 'tensor' is ordered by I,X,Y,Z counting lowest qubit fastest.

    Args:
        number_of_qubits (int): number of qubits
        case (str): determines ordering of group elements ('weight' or 'tensor')

    Returns:
        list: list of Pauli objects

    Raises:
        QiskitError: case is not 'weight' or 'tensor'
        QiskitError: number_of_qubits is larger than 4
    """
    if number_of_qubits < 5:
        temp_set = []

        if case == 'weight':
            tmp = pauli_group(number_of_qubits, case='tensor')
            # sort on the weight of the Pauli operator
            return sorted(tmp, key=lambda x: -np.count_nonzero(
                np.array(x.to_label(), 'c') == b'I'))
        elif case == 'tensor':
            # the Pauli set is in tensor order II IX IY IZ XI ...
            for k in range(4 ** number_of_qubits):
                z = np.zeros(number_of_qubits, dtype=np.bool)
                x = np.zeros(number_of_qubits, dtype=np.bool)
                # looping over all the qubits
                for j in range(number_of_qubits):
                    # making the Pauli for each j fill it in from the
                    # end first
                    element = (k // (4 ** j)) % 4
                    if element == 1:
                        x[j] = True
                    elif element == 2:
                        z[j] = True
                        x[j] = True
                    elif element == 3:
                        z[j] = True
                temp_set.append(Pauli(z, x))
            return temp_set
        else:
            raise QiskitError("Only support 'weight' or 'tensor' cases "
                              "but you have {}.".format(case))

    raise QiskitError("Only support number of qubits is less than 5")

Return the Pauli group with 4^n elements .


def from_label(cls, label):
        r"""Take pauli string to construct pauli.

        The qubit index of pauli label is q_{n-1} ... q_0.
        E.g., a pauli is $P_{n-1} \otimes ... \otimes P_0$

        Args:
            label (str): pauli label

        Returns:
            Pauli: the constructed pauli

        Raises:
            QiskitError: invalid character in the label
        """
        z = np.zeros(len(label), dtype=np.bool)
        x = np.zeros(len(label), dtype=np.bool)
        for i, char in enumerate(label):
            if char == 'X':
                x[-i - 1] = True
            elif char == 'Z':
                z[-i - 1] = True
            elif char == 'Y':
                z[-i - 1] = True
                x[-i - 1] = True
            elif char != 'I':
                raise QiskitError("Pauli string must be only consisted of 'I', 'X', "
                                  "'Y' or 'Z' but you have {}.".format(char))
        return cls(z=z, x=x)

r Take pauli string to construct pauli .


def _init_from_bool(self, z, x):
        """Construct pauli from boolean array.

        Args:
            z (numpy.ndarray): boolean, z vector
            x (numpy.ndarray): boolean, x vector

        Returns:
            Pauli: self

        Raises:
            QiskitError: if z or x are None or the length of z and x are different.
        """
        if z is None:
            raise QiskitError("z vector must not be None.")
        if x is None:
            raise QiskitError("x vector must not be None.")
        if len(z) != len(x):
            raise QiskitError("length of z and x vectors must be "
                              "the same. (z: {} vs x: {})".format(len(z), len(x)))

        z = _make_np_bool(z)
        x = _make_np_bool(x)
        self._z = z
        self._x = x

        return self

def
_init_from_bool
(
self
,
z
,
x
)
:
if
z
is
:
raise
QiskitError
(
"z vector must not be None."
)
if
x
is
:
raise
QiskitError
(
"x vector must not be None."
)
if
len
(
z
)
!=
len
(
x
)
:
raise
QiskitError
(
"length of z and x vectors must be "
"the same. (z: {} vs x: {})"
.
format
(
len
(
z
)
,
len
(
x
)
)
)
z
=
_make_np_bool
(
z
)
x
=
_make_np_bool
(
x
)
self
.
_z
=
z
self
.
_x
=
x
return
self


def sgn_prod(p1, p2):
        r"""
        Multiply two Paulis and track the phase.

        $P_3 = P_1 \otimes P_2$: X*Y

        Args:
            p1 (Pauli): pauli 1
            p2 (Pauli): pauli 2

        Returns:
            Pauli: the multiplied pauli
            complex: the sign of the multiplication, 1, -1, 1j or -1j
        """
        phase = Pauli._prod_phase(p1, p2)
        new_pauli = p1 * p2
        return new_pauli, phase

r Multiply two Paulis and track the phase .


def to_operator(self):
        """Convert to Operator object."""
        # Place import here to avoid cyclic import from circuit visualization
        from qiskit.quantum_info.operators.operator import Operator
        return Operator(self.to_matrix())

def to_operator ( self ) : from qiskit . quantum_info . operators . operator import Operator return Operator ( self . to_matrix ( ) )


def to_instruction(self):
        """Convert to Pauli circuit instruction."""
        from qiskit.circuit import QuantumCircuit, QuantumRegister
        from qiskit.extensions.standard import IdGate, XGate, YGate, ZGate
        gates = {'I': IdGate(), 'X': XGate(), 'Y': YGate(), 'Z': ZGate()}
        label = self.to_label()
        n_qubits = self.numberofqubits
        qreg = QuantumRegister(n_qubits)
        circuit = QuantumCircuit(qreg, name='Pauli:{}'.format(label))
        for i, pauli in enumerate(reversed(label)):
            circuit.append(gates[pauli], [qreg[i]])
        return circuit.to_instruction()

def to_instruction ( self ) : from qiskit . circuit import QuantumCircuit , QuantumRegister from qiskit . extensions . standard import IdGate , XGate , YGate , ZGate gates = { 'I' : IdGate ( ) , 'X' : XGate ( ) , 'Y' : YGate ( ) , 'Z' : ZGate ( ) } label = self . to_label ( ) n_qubits = self . numberofqubits qreg = QuantumRegister ( n_qubits ) circuit = QuantumCircuit ( qreg , name = 'Pauli:{}' . format ( label ) ) for i , pauli in enumerate ( reversed ( label ) ) : circuit . append ( gates [ pauli ] , [ qreg [ i ] ] ) return circuit . to_instruction ( )


def update_z(self, z, indices=None):
        """
        Update partial or entire z.

        Args:
            z (numpy.ndarray or list): to-be-updated z
            indices (numpy.ndarray or list or optional): to-be-updated qubit indices

        Returns:
            Pauli: self

        Raises:
            QiskitError: when updating whole z, the number of qubits must be the same.
        """
        z = _make_np_bool(z)
        if indices is None:
            if len(self._z) != len(z):
                raise QiskitError("During updating whole z, you can not "
                                  "change the number of qubits.")
            self._z = z
        else:
            if not isinstance(indices, list) and not isinstance(indices, np.ndarray):
                indices = [indices]
            for p, idx in enumerate(indices):
                self._z[idx] = z[p]

        return self

def
update_z
(
self
,
z
,
indices
=
)
:
z
=
_make_np_bool
(
z
)
if
indices
is
:
if
len
(
self
.
_z
)
!=
len
(
z
)
:
raise
QiskitError
(
"During updating whole z, you can not "
"change the number of qubits."
)
self
.
_z
=
z
else
:
if
not
isinstance
(
indices
,
list
)
and
not
isinstance
(
indices
,
np
.
ndarray
)
:
indices
=
[
indices
]
for
p
,
idx
in
enumerate
(
indices
)
:
self
.
_z
[
idx
]
=
z
[
p
]
return
self


def update_x(self, x, indices=None):
        """
        Update partial or entire x.

        Args:
            x (numpy.ndarray or list): to-be-updated x
            indices (numpy.ndarray or list or optional): to-be-updated qubit indices

        Returns:
            Pauli: self

        Raises:
            QiskitError: when updating whole x, the number of qubits must be the same.
        """
        x = _make_np_bool(x)
        if indices is None:
            if len(self._x) != len(x):
                raise QiskitError("During updating whole x, you can not change "
                                  "the number of qubits.")
            self._x = x
        else:
            if not isinstance(indices, list) and not isinstance(indices, np.ndarray):
                indices = [indices]
            for p, idx in enumerate(indices):
                self._x[idx] = x[p]

        return self


def insert_paulis(self, indices=None, paulis=None, pauli_labels=None):
        """
        Insert or append pauli to the targeted indices.

        If indices is None, it means append at the end.

        Args:
            indices (list[int]): the qubit indices to be inserted
            paulis (Pauli): the to-be-inserted or appended pauli
            pauli_labels (list[str]): the to-be-inserted or appended pauli label

        Note:
            the indices refers to the localion of original paulis,
            e.g. if indices = [0, 2], pauli_labels = ['Z', 'I'] and original pauli = 'ZYXI'
            the pauli will be updated to ZY'I'XI'Z'
            'Z' and 'I' are inserted before the qubit at 0 and 2.

        Returns:
            Pauli: self

        Raises:
            QiskitError: provide both `paulis` and `pauli_labels` at the same time
        """
        if pauli_labels is not None:
            if paulis is not None:
                raise QiskitError("Please only provide either `paulis` or `pauli_labels`")
            if isinstance(pauli_labels, str):
                pauli_labels = list(pauli_labels)
            # since pauli label is in reversed order.
            paulis = Pauli.from_label(pauli_labels[::-1])

        if indices is None:  # append
            self._z = np.concatenate((self._z, paulis.z))
            self._x = np.concatenate((self._x, paulis.x))
        else:
            if not isinstance(indices, list):
                indices = [indices]
            self._z = np.insert(self._z, indices, paulis.z)
            self._x = np.insert(self._x, indices, paulis.x)

        return self

Insert or append pauli to the targeted indices .


def append_paulis(self, paulis=None, pauli_labels=None):
        """
        Append pauli at the end.

        Args:
            paulis (Pauli): the to-be-inserted or appended pauli
            pauli_labels (list[str]): the to-be-inserted or appended pauli label

        Returns:
            Pauli: self
        """
        return self.insert_paulis(None, paulis=paulis, pauli_labels=pauli_labels)

def append_paulis ( self , paulis = None , pauli_labels = None ) : return self . insert_paulis ( None , paulis = paulis , pauli_labels = pauli_labels )


def delete_qubits(self, indices):
        """
        Delete pauli at the indices.

        Args:
            indices(list[int]): the indices of to-be-deleted paulis

        Returns:
            Pauli: self
        """
        if not isinstance(indices, list):
            indices = [indices]

        self._z = np.delete(self._z, indices)
        self._x = np.delete(self._x, indices)

        return self

def delete_qubits ( self , indices ) : if not isinstance ( indices , list ) : indices = [ indices ] self . _z = np . delete ( self . _z , indices ) self . _x = np . delete ( self . _x , indices ) return self


def random(cls, num_qubits, seed=None):
        """Return a random Pauli on number of qubits.

        Args:
            num_qubits (int): the number of qubits
            seed (int): Optional. To set a random seed.
        Returns:
            Pauli: the random pauli
        """
        if seed is not None:
            np.random.seed(seed)
        z = np.random.randint(2, size=num_qubits).astype(np.bool)
        x = np.random.randint(2, size=num_qubits).astype(np.bool)
        return cls(z, x)

def random ( cls , num_qubits , seed = None ) : if seed is not None : np . random . seed ( seed ) z = np . random . randint ( 2 , size = num_qubits ) . astype ( np . bool ) x = np . random . randint ( 2 , size = num_qubits ) . astype ( np . bool ) return cls ( z , x )

Return a random Pauli on number of qubits .


def pauli_single(cls, num_qubits, index, pauli_label):
        """
        Generate single qubit pauli at index with pauli_label with length num_qubits.

        Args:
            num_qubits (int): the length of pauli
            index (int): the qubit index to insert the single qubii
            pauli_label (str): pauli

        Returns:
            Pauli: single qubit pauli
        """
        tmp = Pauli.from_label(pauli_label)
        z = np.zeros(num_qubits, dtype=np.bool)
        x = np.zeros(num_qubits, dtype=np.bool)

        z[index] = tmp.z[0]
        x[index] = tmp.x[0]

        return cls(z, x)

def pauli_single ( cls , num_qubits , index , pauli_label ) : tmp = Pauli . from_label ( pauli_label ) z = np . zeros ( num_qubits , dtype = np . bool ) x = np . zeros ( num_qubits , dtype = np . bool ) z [ index ] = tmp . z [ 0 ] x [ index ] = tmp . x [ 0 ] return cls ( z , x )

Generate single qubit pauli at index with pauli_label with length num_qubits .


def _get_measure_outcome(self, qubit):
        """Simulate the outcome of measurement of a qubit.

        Args:
            qubit (int): the qubit to measure

        Return:
            tuple: pair (outcome, probability) where outcome is '0' or '1' and
            probability is the probability of the returned outcome.
        """
        # Axis for numpy.sum to compute probabilities
        axis = list(range(self._number_of_qubits))
        axis.remove(self._number_of_qubits - 1 - qubit)
        probabilities = np.sum(np.abs(self._statevector) ** 2, axis=tuple(axis))
        # Compute einsum index string for 1-qubit matrix multiplication
        random_number = self._local_random.rand()
        if random_number < probabilities[0]:
            return '0', probabilities[0]
        # Else outcome was '1'
        return '1', probabilities[1]

def _get_measure_outcome ( self , qubit ) : axis = list ( range ( self . _number_of_qubits ) ) axis . remove ( self . _number_of_qubits - 1 - qubit ) probabilities = np . sum ( np . abs ( self . _statevector ) ** 2 , axis = tuple ( axis ) ) random_number = self . _local_random . rand ( ) if random_number < probabilities [ 0 ] : return '0' , probabilities [ 0 ] return '1' , probabilities [ 1 ]

Simulate the outcome of measurement of a qubit .


def _add_sample_measure(self, measure_params, num_samples):
        """Generate memory samples from current statevector.

        Args:
            measure_params (list): List of (qubit, cmembit) values for
                                   measure instructions to sample.
            num_samples (int): The number of memory samples to generate.

        Returns:
            list: A list of memory values in hex format.
        """
        # Get unique qubits that are actually measured
        measured_qubits = list({qubit for qubit, cmembit in measure_params})
        num_measured = len(measured_qubits)
        # Axis for numpy.sum to compute probabilities
        axis = list(range(self._number_of_qubits))
        for qubit in reversed(measured_qubits):
            # Remove from largest qubit to smallest so list position is correct
            # with respect to position from end of the list
            axis.remove(self._number_of_qubits - 1 - qubit)
        probabilities = np.reshape(np.sum(np.abs(self._statevector) ** 2,
                                          axis=tuple(axis)),
                                   2 ** num_measured)
        # Generate samples on measured qubits
        samples = self._local_random.choice(range(2 ** num_measured),
                                            num_samples, p=probabilities)
        # Convert to bit-strings
        memory = []
        for sample in samples:
            classical_memory = self._classical_memory
            for count, (qubit, cmembit) in enumerate(sorted(measure_params)):
                qubit_outcome = int((sample & (1 << count)) >> count)
                membit = 1 << cmembit
                classical_memory = (classical_memory & (~membit)) | (qubit_outcome << cmembit)
            value = bin(classical_memory)[2:]
            memory.append(hex(int(value, 2)))
        return memory

def _add_sample_measure ( self , measure_params , num_samples ) : measured_qubits = list ( { qubit for qubit , cmembit in measure_params } ) num_measured = len ( measured_qubits ) axis = list ( range ( self . _number_of_qubits ) ) for qubit in reversed ( measured_qubits ) : axis . remove ( self . _number_of_qubits - 1 - qubit ) probabilities = np . reshape ( np . sum ( np . abs ( self . _statevector ) ** 2 , axis = tuple ( axis ) ) , 2 ** num_measured ) samples = self . _local_random . choice ( range ( 2 ** num_measured ) , num_samples , p = probabilities ) memory = [ ] for sample in samples : classical_memory = self . _classical_memory for count , ( qubit , cmembit ) in enumerate ( sorted ( measure_params ) ) : qubit_outcome = int ( ( sample & ( 1 << count ) ) >> count ) membit = 1 << cmembit classical_memory = ( classical_memory & ( ~ membit ) ) | ( qubit_outcome << cmembit ) value = bin ( classical_memory ) [ 2 : ] memory . append ( hex ( int ( value , 2 ) ) ) return memory

Generate memory samples from current statevector .


def _add_qasm_measure(self, qubit, cmembit, cregbit=None):
        """Apply a measure instruction to a qubit.

        Args:
            qubit (int): qubit is the qubit measured.
            cmembit (int): is the classical memory bit to store outcome in.
            cregbit (int, optional): is the classical register bit to store outcome in.
        """
        # get measure outcome
        outcome, probability = self._get_measure_outcome(qubit)
        # update classical state
        membit = 1 << cmembit
        self._classical_memory = (self._classical_memory & (~membit)) | (int(outcome) << cmembit)

        if cregbit is not None:
            regbit = 1 << cregbit
            self._classical_register = \
                (self._classical_register & (~regbit)) | (int(outcome) << cregbit)

        # update quantum state
        if outcome == '0':
            update_diag = [[1 / np.sqrt(probability), 0], [0, 0]]
        else:
            update_diag = [[0, 0], [0, 1 / np.sqrt(probability)]]
        # update classical state
        self._add_unitary_single(update_diag, qubit)

def _add_qasm_measure ( self , qubit , cmembit , cregbit = None ) : outcome , probability = self . _get_measure_outcome ( qubit ) membit = 1 << cmembit self . _classical_memory = ( self . _classical_memory & ( ~ membit ) ) | ( int ( outcome ) << cmembit ) if cregbit is not None : regbit = 1 << cregbit self . _classical_register = ( self . _classical_register & ( ~ regbit ) ) | ( int ( outcome ) << cregbit ) if outcome == '0' : update_diag = [ [ 1 / np . sqrt ( probability ) , 0 ] , [ 0 , 0 ] ] else : update_diag = [ [ 0 , 0 ] , [ 0 , 1 / np . sqrt ( probability ) ] ] self . _add_unitary_single ( update_diag , qubit )

Apply a measure instruction to a qubit .


def _add_qasm_reset(self, qubit):
        """Apply a reset instruction to a qubit.

        Args:
            qubit (int): the qubit being rest

        This is done by doing a simulating a measurement
        outcome and projecting onto the outcome state while
        renormalizing.
        """
        # get measure outcome
        outcome, probability = self._get_measure_outcome(qubit)
        # update quantum state
        if outcome == '0':
            update = [[1 / np.sqrt(probability), 0], [0, 0]]
            self._add_unitary_single(update, qubit)
        else:
            update = [[0, 1 / np.sqrt(probability)], [0, 0]]
            self._add_unitary_single(update, qubit)

def _add_qasm_reset ( self , qubit ) : outcome , probability = self . _get_measure_outcome ( qubit ) if outcome == '0' : update = [ [ 1 / np . sqrt ( probability ) , 0 ] , [ 0 , 0 ] ] self . _add_unitary_single ( update , qubit ) else : update = [ [ 0 , 1 / np . sqrt ( probability ) ] , [ 0 , 0 ] ] self . _add_unitary_single ( update , qubit )


def _validate_initial_statevector(self):
        """Validate an initial statevector"""
        # If initial statevector isn't set we don't need to validate
        if self._initial_statevector is None:
            return
        # Check statevector is correct length for number of qubits
        length = len(self._initial_statevector)
        required_dim = 2 ** self._number_of_qubits
        if length != required_dim:
            raise BasicAerError('initial statevector is incorrect length: ' +
                                '{} != {}'.format(length, required_dim))


def _initialize_statevector(self):
        """Set the initial statevector for simulation"""
        if self._initial_statevector is None:
            # Set to default state of all qubits in |0>
            self._statevector = np.zeros(2 ** self._number_of_qubits,
                                         dtype=complex)
            self._statevector[0] = 1
        else:
            self._statevector = self._initial_statevector.copy()
        # Reshape to rank-N tensor
        self._statevector = np.reshape(self._statevector,
                                       self._number_of_qubits * [2])

def _initialize_statevector ( self ) : if self . _initial_statevector is None : self . _statevector = np . zeros ( 2 ** self . _number_of_qubits , dtype = complex ) self . _statevector [ 0 ] = 1 else : self . _statevector = self . _initial_statevector . copy ( ) self . _statevector = np . reshape ( self . _statevector , self . _number_of_qubits * [ 2 ] )


def _get_statevector(self):
        """Return the current statevector in JSON Result spec format"""
        vec = np.reshape(self._statevector, 2 ** self._number_of_qubits)
        # Expand complex numbers
        vec = np.stack([vec.real, vec.imag], axis=1)
        # Truncate small values
        vec[abs(vec) < self._chop_threshold] = 0.0
        return vec

def _get_statevector ( self ) : vec = np . reshape ( self . _statevector , 2 ** self . _number_of_qubits ) vec = np . stack ( [ vec . real , vec . imag ] , axis = 1 ) vec [ abs ( vec ) < self . _chop_threshold ] = 0.0 return vec


def _validate_measure_sampling(self, experiment):
        """Determine if measure sampling is allowed for an experiment

        Args:
            experiment (QobjExperiment): a qobj experiment.
        """
        # If shots=1 we should disable measure sampling.
        # This is also required for statevector simulator to return the
        # correct final statevector without silently dropping final measurements.
        if self._shots <= 1:
            self._sample_measure = False
            return

        # Check for config flag
        if hasattr(experiment.config, 'allows_measure_sampling'):
            self._sample_measure = experiment.config.allows_measure_sampling
        # If flag isn't found do a simple test to see if a circuit contains
        # no reset instructions, and no gates instructions after
        # the first measure.
        else:
            measure_flag = False
            for instruction in experiment.instructions:
                # If circuit contains reset operations we cannot sample
                if instruction.name == "reset":
                    self._sample_measure = False
                    return
                # If circuit contains a measure option then we can
                # sample only if all following operations are measures
                if measure_flag:
                    # If we find a non-measure instruction
                    # we cannot do measure sampling
                    if instruction.name not in ["measure", "barrier", "id", "u0"]:
                        self._sample_measure = False
                        return
                elif instruction.name == "measure":
                    measure_flag = True
            # If we made it to the end of the circuit without returning
            # measure sampling is allowed
            self._sample_measure = True

def _validate_measure_sampling ( self , experiment ) : if self . _shots <= 1 : self . _sample_measure = False return if hasattr ( experiment . config , 'allows_measure_sampling' ) : self . _sample_measure = experiment . config . allows_measure_sampling else : measure_flag = False for instruction in experiment . instructions : if instruction . name == "reset" : self . _sample_measure = False return if measure_flag : if instruction . name not in [ "measure" , "barrier" , "id" , "u0" ] : self . _sample_measure = False return elif instruction . name == "measure" : measure_flag = True self . _sample_measure = True


def run(self, qobj, backend_options=None):
        """Run qobj asynchronously.

        Args:
            qobj (Qobj): payload of the experiment
            backend_options (dict): backend options

        Returns:
            BasicAerJob: derived from BaseJob

        Additional Information:
            backend_options: Is a dict of options for the backend. It may contain
                * "initial_statevector": vector_like

            The "initial_statevector" option specifies a custom initial
            initial statevector for the simulator to be used instead of the all
            zero state. This size of this vector must be correct for the number
            of qubits in all experiments in the qobj.

            Example::

                backend_options = {
                    "initial_statevector": np.array([1, 0, 0, 1j]) / np.sqrt(2),
                }
        """
        self._set_options(qobj_config=qobj.config,
                          backend_options=backend_options)
        job_id = str(uuid.uuid4())
        job = BasicAerJob(self, job_id, self._run_job, qobj)
        job.submit()
        return job

def run ( self , qobj , backend_options = None ) : self . _set_options ( qobj_config = qobj . config , backend_options = backend_options ) job_id = str ( uuid . uuid4 ( ) ) job = BasicAerJob ( self , job_id , self . _run_job , qobj ) job . submit ( ) return job


def _run_job(self, job_id, qobj):
        """Run experiments in qobj

        Args:
            job_id (str): unique id for the job.
            qobj (Qobj): job description

        Returns:
            Result: Result object
        """
        self._validate(qobj)
        result_list = []
        self._shots = qobj.config.shots
        self._memory = getattr(qobj.config, 'memory', False)
        self._qobj_config = qobj.config
        start = time.time()
        for experiment in qobj.experiments:
            result_list.append(self.run_experiment(experiment))
        end = time.time()
        result = {'backend_name': self.name(),
                  'backend_version': self._configuration.backend_version,
                  'qobj_id': qobj.qobj_id,
                  'job_id': job_id,
                  'results': result_list,
                  'status': 'COMPLETED',
                  'success': True,
                  'time_taken': (end - start),
                  'header': qobj.header.as_dict()}

        return Result.from_dict(result)

def _run_job ( self , job_id , qobj ) : self . _validate ( qobj ) result_list = [ ] self . _shots = qobj . config . shots self . _memory = getattr ( qobj . config , 'memory' , False ) self . _qobj_config = qobj . config start = time . time ( ) for experiment in qobj . experiments : result_list . append ( self . run_experiment ( experiment ) ) end = time . time ( ) result = { 'backend_name' : self . name ( ) , 'backend_version' : self . _configuration . backend_version , 'qobj_id' : qobj . qobj_id , 'job_id' : job_id , 'results' : result_list , 'status' : 'COMPLETED' , 'success' : True , 'time_taken' : ( end - start ) , 'header' : qobj . header . as_dict ( ) } return Result . from_dict ( result )


def _validate(self, qobj):
        """Semantic validations of the qobj which cannot be done via schemas."""
        n_qubits = qobj.config.n_qubits
        max_qubits = self.configuration().n_qubits
        if n_qubits > max_qubits:
            raise BasicAerError('Number of qubits {} '.format(n_qubits) +
                                'is greater than maximum ({}) '.format(max_qubits) +
                                'for "{}".'.format(self.name()))
        for experiment in qobj.experiments:
            name = experiment.header.name
            if experiment.config.memory_slots == 0:
                logger.warning('No classical registers in circuit "%s", '
                               'counts will be empty.', name)
            elif 'measure' not in [op.name for op in experiment.instructions]:
                logger.warning('No measurements in circuit "%s", '
                               'classical register will remain all zeros.', name)

Semantic validations of the qobj which cannot be done via schemas .


def _validate_initial_unitary(self):
        """Validate an initial unitary matrix"""
        # If initial unitary isn't set we don't need to validate
        if self._initial_unitary is None:
            return
        # Check unitary is correct length for number of qubits
        shape = np.shape(self._initial_unitary)
        required_shape = (2 ** self._number_of_qubits,
                          2 ** self._number_of_qubits)
        if shape != required_shape:
            raise BasicAerError('initial unitary is incorrect shape: ' +
                                '{} != 2 ** {}'.format(shape, required_shape))

def
_validate_initial_unitary
(
self
)
:
if
self
.
_initial_unitary
is
:
return
shape
=
np
.
shape
(
self
.
_initial_unitary
)
required_shape
=
(
2
**
self
.
_number_of_qubits
,
2
**
self
.
_number_of_qubits
)
if
shape
!=
required_shape
:
raise
BasicAerError
(
'initial unitary is incorrect shape: '
+
'{} != 2 ** {}'
.
format
(
shape
,
required_shape
)
)


def _initialize_unitary(self):
        """Set the initial unitary for simulation"""
        self._validate_initial_unitary()
        if self._initial_unitary is None:
            # Set to identity matrix
            self._unitary = np.eye(2 ** self._number_of_qubits,
                                   dtype=complex)
        else:
            self._unitary = self._initial_unitary.copy()
        # Reshape to rank-N tensor
        self._unitary = np.reshape(self._unitary,
                                   self._number_of_qubits * [2, 2])

def _initialize_unitary ( self ) : self . _validate_initial_unitary ( ) if self . _initial_unitary is None : self . _unitary = np . eye ( 2 ** self . _number_of_qubits , dtype = complex ) else : self . _unitary = self . _initial_unitary . copy ( ) self . _unitary = np . reshape ( self . _unitary , self . _number_of_qubits * [ 2 , 2 ] )


def _get_unitary(self):
        """Return the current unitary in JSON Result spec format"""
        unitary = np.reshape(self._unitary, 2 * [2 ** self._number_of_qubits])
        # Expand complex numbers
        unitary = np.stack((unitary.real, unitary.imag), axis=-1)
        # Truncate small values
        unitary[abs(unitary) < self._chop_threshold] = 0.0
        return unitary

def _get_unitary ( self ) : unitary = np . reshape ( self . _unitary , 2 * [ 2 ** self . _number_of_qubits ] ) unitary = np . stack ( ( unitary . real , unitary . imag ) , axis = - 1 ) unitary [ abs ( unitary ) < self . _chop_threshold ] = 0.0 return unitary


def _run_job(self, job_id, qobj):
        """Run experiments in qobj.

        Args:
            job_id (str): unique id for the job.
            qobj (Qobj): job description

        Returns:
            Result: Result object
        """
        self._validate(qobj)
        result_list = []
        start = time.time()
        for experiment in qobj.experiments:
            result_list.append(self.run_experiment(experiment))
        end = time.time()
        result = {'backend_name': self.name(),
                  'backend_version': self._configuration.backend_version,
                  'qobj_id': qobj.qobj_id,
                  'job_id': job_id,
                  'results': result_list,
                  'status': 'COMPLETED',
                  'success': True,
                  'time_taken': (end - start),
                  'header': qobj.header.as_dict()}

        return Result.from_dict(result)

def _run_job ( self , job_id , qobj ) : self . _validate ( qobj ) result_list = [ ] start = time . time ( ) for experiment in qobj . experiments : result_list . append ( self . run_experiment ( experiment ) ) end = time . time ( ) result = { 'backend_name' : self . name ( ) , 'backend_version' : self . _configuration . backend_version , 'qobj_id' : qobj . qobj_id , 'job_id' : job_id , 'results' : result_list , 'status' : 'COMPLETED' , 'success' : True , 'time_taken' : ( end - start ) , 'header' : qobj . header . as_dict ( ) } return Result . from_dict ( result )


def _validate(self, qobj):
        """Semantic validations of the qobj which cannot be done via schemas.
        Some of these may later move to backend schemas.
        1. No shots
        2. No measurements in the middle
        """
        n_qubits = qobj.config.n_qubits
        max_qubits = self.configuration().n_qubits
        if n_qubits > max_qubits:
            raise BasicAerError('Number of qubits {} '.format(n_qubits) +
                                'is greater than maximum ({}) '.format(max_qubits) +
                                'for "{}".'.format(self.name()))
        if hasattr(qobj.config, 'shots') and qobj.config.shots != 1:
            logger.info('"%s" only supports 1 shot. Setting shots=1.',
                        self.name())
            qobj.config.shots = 1
        for experiment in qobj.experiments:
            name = experiment.header.name
            if getattr(experiment.config, 'shots', 1) != 1:
                logger.info('"%s" only supports 1 shot. '
                            'Setting shots=1 for circuit "%s".',
                            self.name(), name)
                experiment.config.shots = 1
            for operation in experiment.instructions:
                if operation.name in ['measure', 'reset']:
                    raise BasicAerError('Unsupported "%s" instruction "%s" ' +
                                        'in circuit "%s" ', self.name(),
                                        operation.name, name)

Semantic validations of the qobj which cannot be done via schemas . Some of these may later move to backend schemas . 1 . No shots 2 . No measurements in the middle


def _is_bit(obj):
    """Determine if obj is a bit"""
    # If there is a bit type this could be replaced by isinstance.
    if isinstance(obj, tuple) and len(obj) == 2:
        if isinstance(obj[0], Register) and isinstance(obj[1], int) and obj[1] < len(obj[0]):
            return True
    return False

def _is_bit ( obj ) : if isinstance ( obj , tuple ) and len ( obj ) == 2 : if isinstance ( obj [ 0 ] , Register ) and isinstance ( obj [ 1 ] , int ) and obj [ 1 ] < len ( obj [ 0 ] ) : return True return False


def run(self, dag):
        """
        Pick a layout by assigning n circuit qubits to device qubits 0, .., n-1.

        Args:
            dag (DAGCircuit): DAG to find layout for.

        Raises:
            TranspilerError: if dag wider than self.coupling_map
        """
        num_dag_qubits = sum([qreg.size for qreg in dag.qregs.values()])
        if num_dag_qubits > self.coupling_map.size():
            raise TranspilerError('Number of qubits greater than device.')
        self.property_set['layout'] = Layout.generate_trivial_layout(*dag.qregs.values())

def
run
(
self
,
dag
)
:
num_dag_qubits
=
sum
(
[
qreg
.
size
for
qreg
in
dag
.
qregs
.
values
(
)
]
)
if
num_dag_qubits
>
self
.
coupling_map
.
size
(
)
:
raise
TranspilerError
(
'Number of qubits greater than device.'
)
self
.
property_set
[
'layout'
]
=
Layout
.
generate_trivial_layout
(
*
dag
.
qregs
.
values
(
)
)

Pick a layout by assigning n circuit qubits to device qubits 0 .. n - 1 .


def has_overlap(self, interval: 'Interval') -> bool:
        """Check if self has overlap with `interval`.

        Args:
            interval: interval to be examined

        Returns:
            bool: True if self has overlap with `interval` otherwise False
        """
        if self.begin < interval.end and interval.begin < self.end:
            return True
        return False

def has_overlap ( self , interval : 'Interval' ) -> bool : if self . begin < interval . end and interval . begin < self . end : return True return False

Check if self has overlap with interval .


def shift(self, time: int) -> 'Interval':
        """Return a new interval shifted by `time` from self

        Args:
            time: time to be shifted

        Returns:
            Interval: interval shifted by `time`
        """
        return Interval(self._begin + time, self._end + time)

def shift ( self , time : int ) -> 'Interval' : return Interval ( self . _begin + time , self . _end + time )

Return a new interval shifted by time from self


def shift(self, time: int) -> 'Timeslot':
        """Return a new Timeslot shifted by `time`.

        Args:
            time: time to be shifted
        """
        return Timeslot(self.interval.shift(time), self.channel)

def shift ( self , time : int ) -> 'Timeslot' : return Timeslot ( self . interval . shift ( time ) , self . channel )


def ch_start_time(self, *channels: List[Channel]) -> int:
        """Return earliest start time in this collection.

        Args:
            *channels: Channels over which to obtain start_time.
        """
        intervals = list(itertools.chain(*(self._table[chan] for chan in channels
                                           if chan in self._table)))
        if intervals:
            return min((interval.begin for interval in intervals))
        return 0

def ch_start_time ( self , * channels : List [ Channel ] ) -> int : intervals = list ( itertools . chain ( * ( self . _table [ chan ] for chan in channels if chan in self . _table ) ) ) if intervals : return min ( ( interval . begin for interval in intervals ) ) return 0

Return earliest start time in this collection .


def ch_stop_time(self, *channels: List[Channel]) -> int:
        """Return maximum time of timeslots over all channels.

        Args:
            *channels: Channels over which to obtain stop time.
        """
        intervals = list(itertools.chain(*(self._table[chan] for chan in channels
                                           if chan in self._table)))
        if intervals:
            return max((interval.end for interval in intervals))
        return 0

def ch_stop_time ( self , * channels : List [ Channel ] ) -> int : intervals = list ( itertools . chain ( * ( self . _table [ chan ] for chan in channels if chan in self . _table ) ) ) if intervals : return max ( ( interval . end for interval in intervals ) ) return 0

Return maximum time of timeslots over all channels .


def is_mergeable_with(self, timeslots: 'TimeslotCollection') -> bool:
        """Return if self is mergeable with `timeslots`.

        Args:
            timeslots: TimeslotCollection to be checked
        """
        for slot in timeslots.timeslots:
            for interval in self._table[slot.channel]:
                if slot.interval.has_overlap(interval):
                    return False
        return True

def is_mergeable_with ( self , timeslots : 'TimeslotCollection' ) -> bool : for slot in timeslots . timeslots : for interval in self . _table [ slot . channel ] : if slot . interval . has_overlap ( interval ) : return False return True

Return if self is mergeable with timeslots .


def merged(self, timeslots: 'TimeslotCollection') -> 'TimeslotCollection':
        """Return a new TimeslotCollection merged with a specified `timeslots`

        Args:
            timeslots: TimeslotCollection to be merged
        """
        slots = [Timeslot(slot.interval, slot.channel) for slot in self.timeslots]
        slots.extend([Timeslot(slot.interval, slot.channel) for slot in timeslots.timeslots])
        return TimeslotCollection(*slots)

def merged ( self , timeslots : 'TimeslotCollection' ) -> 'TimeslotCollection' : slots = [ Timeslot ( slot . interval , slot . channel ) for slot in self . timeslots ] slots . extend ( [ Timeslot ( slot . interval , slot . channel ) for slot in timeslots . timeslots ] ) return TimeslotCollection ( * slots )

Return a new TimeslotCollection merged with a specified timeslots


def shift(self, time: int) -> 'TimeslotCollection':
        """Return a new TimeslotCollection shifted by `time`.

        Args:
            time: time to be shifted by
        """
        slots = [Timeslot(slot.interval.shift(time), slot.channel) for slot in self.timeslots]
        return TimeslotCollection(*slots)

def shift ( self , time : int ) -> 'TimeslotCollection' : slots = [ Timeslot ( slot . interval . shift ( time ) , slot . channel ) for slot in self . timeslots ] return TimeslotCollection ( * slots )

Return a new TimeslotCollection shifted by time .


def report(self, branch, commit, infourl=None):
        """Report on GitHub that the specified branch is failing to build at
        the specified commit. The method will open an issue indicating that
        the branch is failing. If there is an issue already open, it will add a
        comment avoiding to report twice about the same failure.

        Args:
            branch (str): branch name to report about.
            commit (str): commit hash at which the build fails.
            infourl (str): URL with extra info about the failure such as the
                build logs.
        """
        issue_number = self._get_report_issue_number()
        if issue_number:
            self._report_as_comment(issue_number, branch, commit, infourl)
        else:
            self._report_as_issue(branch, commit, infourl)

def report ( self , branch , commit , infourl = None ) : issue_number = self . _get_report_issue_number ( ) if issue_number : self . _report_as_comment ( issue_number , branch , commit , infourl ) else : self . _report_as_issue ( branch , commit , infourl )

Report on GitHub that the specified branch is failing to build at the specified commit . The method will open an issue indicating that the branch is failing . If there is an issue already open it will add a comment avoiding to report twice about the same failure .


def process_data(rho):
    """ Sort rho data """
    result = dict()

    num = int(np.log2(len(rho)))
    labels = list(map(lambda x: x.to_label(), pauli_group(num)))
    values = list(map(lambda x: np.real(np.trace(np.dot(x.to_matrix(), rho))),
                      pauli_group(num)))

    for position, label in enumerate(labels):
        result[label] = values[position]
    return result

def process_data ( rho ) : result = dict ( ) num = int ( np . log2 ( len ( rho ) ) ) labels = list ( map ( lambda x : x . to_label ( ) , pauli_group ( num ) ) ) values = list ( map ( lambda x : np . real ( np . trace ( np . dot ( x . to_matrix ( ) , rho ) ) ) , pauli_group ( num ) ) ) for position , label in enumerate ( labels ) : result [ label ] = values [ position ] return result


def iplot_state_paulivec(rho, figsize=None, slider=False, show_legend=False):
    """ Create a paulivec representation.

        Graphical representation of the input array.

        Args:
            rho (array): State vector or density matrix.
            figsize (tuple): Figure size in pixels.
            slider (bool): activate slider
            show_legend (bool): show legend of graph content
    """

    # HTML
    html_template = Template("""

    """)

    # JavaScript
    javascript_template = Template("""

    """)
    rho = _validate_input_state(rho)
    # set default figure size if none given
    if figsize is None:
        figsize = (7, 5)

    options = {'width': figsize[0], 'height': figsize[1],
               'slider': int(slider), 'show_legend': int(show_legend)}

    # Process data and execute
    div_number = str(time.time())
    div_number = re.sub('[.]', '', div_number)

    data_to_plot = []
    rho_data = process_data(rho)
    data_to_plot.append(dict(
        data=rho_data
    ))

    html = html_template.substitute({
        'divNumber': div_number
    })

    javascript = javascript_template.substitute({
        'divNumber': div_number,
        'executions': data_to_plot,
        'options': options
    })

    display(HTML(html + javascript))

def iplot_state_paulivec ( rho , figsize = None , slider = False , show_legend = False ) : html_template = Template ( ) javascript_template = Template ( ) rho = _validate_input_state ( rho ) if figsize is None : figsize = ( 7 , 5 ) options = { 'width' : figsize [ 0 ] , 'height' : figsize [ 1 ] , 'slider' : int ( slider ) , 'show_legend' : int ( show_legend ) } div_number = str ( time . time ( ) ) div_number = re . sub ( '[.]' , '' , div_number ) data_to_plot = [ ] rho_data = process_data ( rho ) data_to_plot . append ( dict ( data = rho_data ) ) html = html_template . substitute ( { 'divNumber' : div_number } ) javascript = javascript_template . substitute ( { 'divNumber' : div_number , 'executions' : data_to_plot , 'options' : options } ) display ( HTML ( html + javascript ) )


def rzz(self, theta, qubit1, qubit2):
    """Apply RZZ to circuit."""
    return self.append(RZZGate(theta), [qubit1, qubit2], [])

def rzz ( self , theta , qubit1 , qubit2 ) : return self . append ( RZZGate ( theta ) , [ qubit1 , qubit2 ] , [ ] )


def cswap(self, ctl, tgt1, tgt2):
    """Apply Fredkin to circuit."""
    return self.append(FredkinGate(), [ctl, tgt1, tgt2], [])

def cswap ( self , ctl , tgt1 , tgt2 ) : return self . append ( FredkinGate ( ) , [ ctl , tgt1 , tgt2 ] , [ ] )


def _initialize_backend_prop(self):
        """
        Extract readout and CNOT errors and compute swap costs.
        """
        backend_prop = self.backend_prop
        for ginfo in backend_prop.gates:
            if ginfo.gate == 'cx':
                for item in ginfo.parameters:
                    if item.name == 'gate_error':
                        g_reliab = 1.0 - item.value
                        break
                    else:
                        g_reliab = 1.0
                swap_reliab = -math.log(pow(g_reliab, 3))
                self.swap_graph.add_edge(ginfo.qubits[0], ginfo.qubits[1], weight=swap_reliab)
                self.swap_graph.add_edge(ginfo.qubits[1], ginfo.qubits[0], weight=swap_reliab)
                self.cx_errors[(ginfo.qubits[0], ginfo.qubits[1])] = g_reliab
                self.gate_list.append((ginfo.qubits[0], ginfo.qubits[1]))
        idx = 0
        for q in backend_prop.qubits:
            for nduv in q:
                if nduv.name == 'readout_error':
                    self.readout_errors[idx] = 1.0 - nduv.value
                    self.available_hw_qubits.append(idx)
            idx += 1
        for edge in self.cx_errors:
            self.gate_cost[edge] = self.cx_errors[edge] * self.readout_errors[edge[0]] *\
                self.readout_errors[edge[1]]
        self.swap_paths, swap_costs_temp = nx.algorithms.shortest_paths.dense.\
            floyd_warshall_predecessor_and_distance(self.swap_graph, weight='weight')
        for i in swap_costs_temp:
            self.swap_costs[i] = {}
            for j in swap_costs_temp[i]:
                if (i, j) in self.cx_errors:
                    self.swap_costs[i][j] = self.cx_errors[(i, j)]
                elif (j, i) in self.cx_errors:
                    self.swap_costs[i][j] = self.cx_errors[(j, i)]
                else:
                    best_reliab = 0.0
                    for n in self.swap_graph.neighbors(j):
                        if (n, j) in self.cx_errors:
                            reliab = math.exp(-swap_costs_temp[i][n])*self.cx_errors[(n, j)]
                        else:
                            reliab = math.exp(-swap_costs_temp[i][n])*self.cx_errors[(j, n)]
                        if reliab > best_reliab:
                            best_reliab = reliab
                    self.swap_costs[i][j] = best_reliab

def _initialize_backend_prop ( self ) : backend_prop = self . backend_prop for ginfo in backend_prop . gates : if ginfo . gate == 'cx' : for item in ginfo . parameters : if item . name == 'gate_error' : g_reliab = 1.0 - item . value break else : g_reliab = 1.0 swap_reliab = - math . log ( pow ( g_reliab , 3 ) ) self . swap_graph . add_edge ( ginfo . qubits [ 0 ] , ginfo . qubits [ 1 ] , weight = swap_reliab ) self . swap_graph . add_edge ( ginfo . qubits [ 1 ] , ginfo . qubits [ 0 ] , weight = swap_reliab ) self . cx_errors [ ( ginfo . qubits [ 0 ] , ginfo . qubits [ 1 ] ) ] = g_reliab self . gate_list . append ( ( ginfo . qubits [ 0 ] , ginfo . qubits [ 1 ] ) ) idx = 0 for q in backend_prop . qubits : for nduv in q : if nduv . name == 'readout_error' : self . readout_errors [ idx ] = 1.0 - nduv . value self . available_hw_qubits . append ( idx ) idx += 1 for edge in self . cx_errors : self . gate_cost [ edge ] = self . cx_errors [ edge ] * self . readout_errors [ edge [ 0 ] ] * self . readout_errors [ edge [ 1 ] ] self . swap_paths , swap_costs_temp = nx . algorithms . shortest_paths . dense . floyd_warshall_predecessor_and_distance ( self . swap_graph , weight = 'weight' ) for i in swap_costs_temp : self . swap_costs [ i ] = { } for j in swap_costs_temp [ i ] : if ( i , j ) in self . cx_errors : self . swap_costs [ i ] [ j ] = self . cx_errors [ ( i , j ) ] elif ( j , i ) in self . cx_errors : self . swap_costs [ i ] [ j ] = self . cx_errors [ ( j , i ) ] else : best_reliab = 0.0 for n in self . swap_graph . neighbors ( j ) : if ( n , j ) in self . cx_errors : reliab = math . exp ( - swap_costs_temp [ i ] [ n ] ) * self . cx_errors [ ( n , j ) ] else : reliab = math . exp ( - swap_costs_temp [ i ] [ n ] ) * self . cx_errors [ ( j , n ) ] if reliab > best_reliab : best_reliab = reliab self . swap_costs [ i ] [ j ] = best_reliab

Extract readout and CNOT errors and compute swap costs .


def _create_program_graph(self, dag):
        """
        Program graph has virtual qubits as nodes.
        Two nodes have an edge if the corresponding virtual qubits
        participate in a 2-qubit gate. The edge is weighted by the
        number of CNOTs between the pair.
        """
        idx = 0
        for q in dag.qubits():
            self.qarg_to_id[q[0].name + str(q[1])] = idx
            idx += 1
        for gate in dag.twoQ_gates():
            qid1 = self._qarg_to_id(gate.qargs[0])
            qid2 = self._qarg_to_id(gate.qargs[1])
            min_q = min(qid1, qid2)
            max_q = max(qid1, qid2)
            edge_weight = 1
            if self.prog_graph.has_edge(min_q, max_q):
                edge_weight = self.prog_graph[min_q][max_q]['weight'] + 1
            self.prog_graph.add_edge(min_q, max_q, weight=edge_weight)
        return idx

def _create_program_graph ( self , dag ) : idx = 0 for q in dag . qubits ( ) : self . qarg_to_id [ q [ 0 ] . name + str ( q [ 1 ] ) ] = idx idx += 1 for gate in dag . twoQ_gates ( ) : qid1 = self . _qarg_to_id ( gate . qargs [ 0 ] ) qid2 = self . _qarg_to_id ( gate . qargs [ 1 ] ) min_q = min ( qid1 , qid2 ) max_q = max ( qid1 , qid2 ) edge_weight = 1 if self . prog_graph . has_edge ( min_q , max_q ) : edge_weight = self . prog_graph [ min_q ] [ max_q ] [ 'weight' ] + 1 self . prog_graph . add_edge ( min_q , max_q , weight = edge_weight ) return idx

Program graph has virtual qubits as nodes . Two nodes have an edge if the corresponding virtual qubits participate in a 2 - qubit gate . The edge is weighted by the number of CNOTs between the pair .


def _select_next_edge(self):
        """
        If there is an edge with one endpoint mapped, return it.
        Else return in the first edge
        """
        for edge in self.pending_program_edges:
            q1_mapped = edge[0] in self.prog2hw
            q2_mapped = edge[1] in self.prog2hw
            assert not (q1_mapped and q2_mapped)
            if q1_mapped or q2_mapped:
                return edge
        return self.pending_program_edges[0]

def _select_next_edge ( self ) : for edge in self . pending_program_edges : q1_mapped = edge [ 0 ] in self . prog2hw q2_mapped = edge [ 1 ] in self . prog2hw assert not ( q1_mapped and q2_mapped ) if q1_mapped or q2_mapped : return edge return self . pending_program_edges [ 0 ]

If there is an edge with one endpoint mapped return it . Else return in the first edge


def _select_best_remaining_cx(self):
        """
        Select best remaining CNOT in the hardware for the next program edge.
        """
        candidates = []
        for gate in self.gate_list:
            chk1 = gate[0] in self.available_hw_qubits
            chk2 = gate[1] in self.available_hw_qubits
            if chk1 and chk2:
                candidates.append(gate)
        best_reliab = 0
        best_item = None
        for item in candidates:
            if self.gate_cost[item] > best_reliab:
                best_reliab = self.gate_cost[item]
                best_item = item
        return best_item

def _select_best_remaining_cx ( self ) : candidates = [ ] for gate in self . gate_list : chk1 = gate [ 0 ] in self . available_hw_qubits chk2 = gate [ 1 ] in self . available_hw_qubits if chk1 and chk2 : candidates . append ( gate ) best_reliab = 0 best_item = None for item in candidates : if self . gate_cost [ item ] > best_reliab : best_reliab = self . gate_cost [ item ] best_item = item return best_item

Select best remaining CNOT in the hardware for the next program edge .


def _select_best_remaining_qubit(self, prog_qubit):
        """
        Select the best remaining hardware qubit for the next program qubit.
        """
        reliab_store = {}
        for hw_qubit in self.available_hw_qubits:
            reliab = 1
            for n in self.prog_graph.neighbors(prog_qubit):
                if n in self.prog2hw:
                    reliab *= self.swap_costs[self.prog2hw[n]][hw_qubit]
            reliab *= self.readout_errors[hw_qubit]
            reliab_store[hw_qubit] = reliab
        max_reliab = 0
        best_hw_qubit = None
        for hw_qubit in reliab_store:
            if reliab_store[hw_qubit] > max_reliab:
                max_reliab = reliab_store[hw_qubit]
                best_hw_qubit = hw_qubit
        return best_hw_qubit

def _select_best_remaining_qubit ( self , prog_qubit ) : reliab_store = { } for hw_qubit in self . available_hw_qubits : reliab = 1 for n in self . prog_graph . neighbors ( prog_qubit ) : if n in self . prog2hw : reliab *= self . swap_costs [ self . prog2hw [ n ] ] [ hw_qubit ] reliab *= self . readout_errors [ hw_qubit ] reliab_store [ hw_qubit ] = reliab max_reliab = 0 best_hw_qubit = None for hw_qubit in reliab_store : if reliab_store [ hw_qubit ] > max_reliab : max_reliab = reliab_store [ hw_qubit ] best_hw_qubit = hw_qubit return best_hw_qubit

Select the best remaining hardware qubit for the next program qubit .


def run(self, dag):
        """Main run method for the noise adaptive layout."""
        self._initialize_backend_prop()
        num_qubits = self._create_program_graph(dag)
        if num_qubits > len(self.swap_graph):
            raise TranspilerError('Number of qubits greater than device.')
        for end1, end2, _ in sorted(self.prog_graph.edges(data=True),
                                    key=lambda x: x[2]['weight'], reverse=True):
            self.pending_program_edges.append((end1, end2))
        while self.pending_program_edges:
            edge = self._select_next_edge()
            q1_mapped = edge[0] in self.prog2hw
            q2_mapped = edge[1] in self.prog2hw
            if (not q1_mapped) and (not q2_mapped):
                best_hw_edge = self._select_best_remaining_cx()
                self.prog2hw[edge[0]] = best_hw_edge[0]
                self.prog2hw[edge[1]] = best_hw_edge[1]
                self.available_hw_qubits.remove(best_hw_edge[0])
                self.available_hw_qubits.remove(best_hw_edge[1])
            elif not q1_mapped:
                best_hw_qubit = self._select_best_remaining_qubit(edge[0])
                self.prog2hw[edge[0]] = best_hw_qubit
                self.available_hw_qubits.remove(best_hw_qubit)
            else:
                best_hw_qubit = self._select_best_remaining_qubit(edge[1])
                self.prog2hw[edge[1]] = best_hw_qubit
                self.available_hw_qubits.remove(best_hw_qubit)
            new_edges = [x for x in self.pending_program_edges
                         if not (x[0] in self.prog2hw and x[1] in self.prog2hw)]
            self.pending_program_edges = new_edges
        for qid in self.qarg_to_id.values():
            if qid not in self.prog2hw:
                self.prog2hw[qid] = self.available_hw_qubits[0]
                self.available_hw_qubits.remove(self.prog2hw[qid])
        layout = Layout()
        for q in dag.qubits():
            pid = self._qarg_to_id(q)
            hwid = self.prog2hw[pid]
            layout[(q[0], q[1])] = hwid
        self.property_set['layout'] = layout

def
run
(
self
,
dag
)
:
self
.
_initialize_backend_prop
(
)
num_qubits
=
self
.
_create_program_graph
(
dag
)
if
num_qubits
>
len
(
self
.
swap_graph
)
:
raise
TranspilerError
(
'Number of qubits greater than device.'
)
for
end1
,
end2
,
_
in
sorted
(
self
.
prog_graph
.
edges
(
data
=
True
)
,
key
=
lambda
x
:
x
[
2
]
[
'weight'
]
,
reverse
=
True
)
:
self
.
pending_program_edges
.
append
(
(
end1
,
end2
)
)
while
self
.
pending_program_edges
:
edge
=
self
.
_select_next_edge
(
)
q1_mapped
=
edge
[
0
]
in
self
.
prog2hw
q2_mapped
=
edge
[
1
]
in
self
.
prog2hw
if
(
not
q1_mapped
)
and
(
not
q2_mapped
)
:
best_hw_edge
=
self
.
_select_best_remaining_cx
(
)
self
.
prog2hw
[
edge
[
0
]
]
=
best_hw_edge
[
0
]
self
.
prog2hw
[
edge
[
1
]
]
=
best_hw_edge
[
1
]
self
.
available_hw_qubits
.
remove
(
best_hw_edge
[
0
]
)
self
.
available_hw_qubits
.
remove
(
best_hw_edge
[
1
]
)
elif
not
q1_mapped
:
best_hw_qubit
=
self
.
_select_best_remaining_qubit
(
edge
[
0
]
)
self
.
prog2hw
[
edge
[
0
]
]
=
best_hw_qubit
self
.
available_hw_qubits
.
remove
(
best_hw_qubit
)
else
:
best_hw_qubit
=
self
.
_select_best_remaining_qubit
(
edge
[
1
]
)
self
.
prog2hw
[
edge
[
1
]
]
=
best_hw_qubit
self
.
available_hw_qubits
.
remove
(
best_hw_qubit
)
new_edges
=
[
x
for
x
in
self
.
pending_program_edges
if
not
(
x
[
0
]
in
self
.
prog2hw
and
x
[
1
]
in
self
.
prog2hw
)
]
self
.
pending_program_edges
=
new_edges
for
qid
in
self
.
qarg_to_id
.
values
(
)
:
if
qid
not
in
self
.
prog2hw
:
self
.
prog2hw
[
qid
]
=
self
.
available_hw_qubits
[
0
]
self
.
available_hw_qubits
.
remove
(
self
.
prog2hw
[
qid
]
)
layout
=
Layout
(
)
for
q
in
dag
.
qubits
(
)
:
pid
=
self
.
_qarg_to_id
(
q
)
hwid
=
self
.
prog2hw
[
pid
]
layout
[
(
q
[
0
]
,
q
[
1
]
)
]
=
hwid
self
.
property_set
[
'layout'
]
=
layout

Main run method for the noise adaptive layout .


def instruction_list(self):
        """Return a list of instructions for this CompositeGate.

        If the CompositeGate itself contains composites, call
        this method recursively.
        """
        instruction_list = []
        for instruction in self.data:
            if isinstance(instruction, CompositeGate):
                instruction_list.extend(instruction.instruction_list())
            else:
                instruction_list.append(instruction)
        return instruction_list

def instruction_list ( self ) : instruction_list = [ ] for instruction in self . data : if isinstance ( instruction , CompositeGate ) : instruction_list . extend ( instruction . instruction_list ( ) ) else : instruction_list . append ( instruction ) return instruction_list

Return a list of instructions for this CompositeGate .


def inverse(self):
        """Invert this gate."""
        self.data = [gate.inverse() for gate in reversed(self.data)]
        self.inverse_flag = not self.inverse_flag
        return self

def inverse ( self ) : self . data = [ gate . inverse ( ) for gate in reversed ( self . data ) ] self . inverse_flag = not self . inverse_flag return self


def q_if(self, *qregs):
        """Add controls to this gate."""
        self.data = [gate.q_if(qregs) for gate in self.data]
        return self

def q_if ( self , * qregs ) : self . data = [ gate . q_if ( qregs ) for gate in self . data ] return self


def c_if(self, classical, val):
        """Add classical control register."""
        self.data = [gate.c_if(classical, val) for gate in self.data]
        return self

def c_if ( self , classical , val ) : self . data = [ gate . c_if ( classical , val ) for gate in self . data ] return self


def is_unitary(self, atol=None, rtol=None):
        """Return True if operator is a unitary matrix."""
        if atol is None:
            atol = self._atol
        if rtol is None:
            rtol = self._rtol
        return is_unitary_matrix(self._data, rtol=rtol, atol=atol)

def is_unitary ( self , atol = None , rtol = None ) : if atol is None : atol = self . _atol if rtol is None : rtol = self . _rtol return is_unitary_matrix ( self . _data , rtol = rtol , atol = atol )

Return True if operator is a unitary matrix .


def conjugate(self):
        """Return the conjugate of the operator."""
        return Operator(
            np.conj(self.data), self.input_dims(), self.output_dims())

def conjugate ( self ) : return Operator ( np . conj ( self . data ) , self . input_dims ( ) , self . output_dims ( ) )


def transpose(self):
        """Return the transpose of the operator."""
        return Operator(
            np.transpose(self.data), self.input_dims(), self.output_dims())

def transpose ( self ) : return Operator ( np . transpose ( self . data ) , self . input_dims ( ) , self . output_dims ( ) )


def power(self, n):
        """Return the matrix power of the operator.

        Args:
            n (int): the power to raise the matrix to.

        Returns:
            BaseOperator: the n-times composed operator.

        Raises:
            QiskitError: if the input and output dimensions of the operator
            are not equal, or the power is not a positive integer.
        """
        if not isinstance(n, int):
            raise QiskitError("Can only take integer powers of Operator.")
        if self.input_dims() != self.output_dims():
            raise QiskitError("Can only power with input_dims = output_dims.")
        # Override base class power so we can implement more efficiently
        # using Numpy.matrix_power
        return Operator(
            np.linalg.matrix_power(self.data, n), self.input_dims(),
            self.output_dims())

Return the matrix power of the operator .


def _shape(self):
        """Return the tensor shape of the matrix operator"""
        return tuple(reversed(self.output_dims())) + tuple(
            reversed(self.input_dims()))

def _shape ( self ) : return tuple ( reversed ( self . output_dims ( ) ) ) + tuple ( reversed ( self . input_dims ( ) ) )


def _instruction_to_operator(cls, instruction):
        """Convert a QuantumCircuit or Instruction to an Operator."""
        # Convert circuit to an instruction
        if isinstance(instruction, QuantumCircuit):
            instruction = instruction.to_instruction()
        # Initialize an identity operator of the correct size of the circuit
        op = Operator(np.eye(2 ** instruction.num_qubits))
        op._append_instruction(instruction)
        return op

def _instruction_to_operator ( cls , instruction ) : if isinstance ( instruction , QuantumCircuit ) : instruction = instruction . to_instruction ( ) op = Operator ( np . eye ( 2 ** instruction . num_qubits ) ) op . _append_instruction ( instruction ) return op

Convert a QuantumCircuit or Instruction to an Operator .


def swap_mapper_layer_update(self, i, first_layer, best_layout, best_d,
                                 best_circ, layer_list):
        """Update the QASM string for an iteration of swap_mapper.

        i = layer number
        first_layer = True if this is the first layer with multi-qubit gates
        best_layout = layout returned from swap algorithm
        best_d = depth returned from swap algorithm
        best_circ = swap circuit returned from swap algorithm
        layer_list = list of circuit objects for each layer

        Return DAGCircuit object to append to the output DAGCircuit.
        """
        layout = best_layout
        dagcircuit_output = DAGCircuit()
        QR = QuantumRegister(self.coupling_map.size(), 'q')
        dagcircuit_output.add_qreg(QR)
        # Identity wire-map for composing the circuits
        identity_wire_map = {(QR, j): (QR, j) for j in range(self.coupling_map.size())}

        # If this is the first layer with multi-qubit gates,
        # output all layers up to this point and ignore any
        # swap gates. Set the initial layout.
        if first_layer:
            # Output all layers up to this point
            for j in range(i + 1):
                dagcircuit_output.compose_back(layer_list[j]["graph"], layout)
        # Otherwise, we output the current layer and the associated swap gates.
        else:
            # Output any swaps
            if best_d > 0:
                dagcircuit_output.compose_back(best_circ, identity_wire_map)

            # Output this layer
            dagcircuit_output.compose_back(layer_list[i]["graph"], layout)
        return dagcircuit_output

def swap_mapper_layer_update ( self , i , first_layer , best_layout , best_d , best_circ , layer_list ) : layout = best_layout dagcircuit_output = DAGCircuit ( ) QR = QuantumRegister ( self . coupling_map . size ( ) , 'q' ) dagcircuit_output . add_qreg ( QR ) identity_wire_map = { ( QR , j ) : ( QR , j ) for j in range ( self . coupling_map . size ( ) ) } if first_layer : for j in range ( i + 1 ) : dagcircuit_output . compose_back ( layer_list [ j ] [ "graph" ] , layout ) else : if best_d > 0 : dagcircuit_output . compose_back ( best_circ , identity_wire_map ) dagcircuit_output . compose_back ( layer_list [ i ] [ "graph" ] , layout ) return dagcircuit_output

Update the QASM string for an iteration of swap_mapper .


def _separate_bitstring(bitstring, creg_sizes):
    """Separate a bitstring according to the registers defined in the result header."""
    substrings = []
    running_index = 0
    for _, size in reversed(creg_sizes):
        substrings.append(bitstring[running_index: running_index + size])
        running_index += size
    return ' '.join(substrings)

def
_separate_bitstring
(
bitstring
,
creg_sizes
)
:
substrings
=
[
]
running_index
=
0
for
_
,
size
in
reversed
(
creg_sizes
)
:
substrings
.
append
(
bitstring
[
running_index
:
running_index
+
size
]
)
running_index
+=
size
return
' '
.
join
(
substrings
)

Separate a bitstring according to the registers defined in the result header .


def format_level_0_memory(memory):
    """ Format an experiment result memory object for measurement level 0.

    Args:
        memory (list): Memory from experiment with `meas_level==1`. `avg` or
            `single` will be inferred from shape of result memory.

    Returns:
        np.ndarray: Measurement level 0 complex numpy array

    Raises:
        QiskitError: If the returned numpy array does not have 2 (avg) or 3 (single)
            indicies.
    """
    formatted_memory = _list_to_complex_array(memory)
    # infer meas_return from shape of returned data.
    if not 2 <= len(formatted_memory.shape) <= 3:
        raise QiskitError('Level zero memory is not of correct shape.')
    return formatted_memory

Format an experiment result memory object for measurement level 0 .


def format_level_1_memory(memory):
    """ Format an experiment result memory object for measurement level 1.

    Args:
        memory (list): Memory from experiment with `meas_level==1`. `avg` or
            `single` will be inferred from shape of result memory.

    Returns:
        np.ndarray: Measurement level 1 complex numpy array

    Raises:
        QiskitError: If the returned numpy array does not have 1 (avg) or 2 (single)
            indicies.
    """
    formatted_memory = _list_to_complex_array(memory)
    # infer meas_return from shape of returned data.
    if not 1 <= len(formatted_memory.shape) <= 2:
        raise QiskitError('Level one memory is not of correct shape.')
    return formatted_memory

Format an experiment result memory object for measurement level 1 .


def format_level_2_memory(memory, header=None):
    """ Format an experiment result memory object for measurement level 2.

    Args:
        memory (list): Memory from experiment with `meas_level==2` and `memory==True`.
        header (dict): the experiment header dictionary containing
            useful information for postprocessing.

    Returns:
        list[str]: List of bitstrings
    """
    memory_list = []
    for shot_memory in memory:
        memory_list.append(format_counts_memory(shot_memory, header))
    return memory_list

def format_level_2_memory ( memory , header = None ) : memory_list = [ ] for shot_memory in memory : memory_list . append ( format_counts_memory ( shot_memory , header ) ) return memory_list

Format an experiment result memory object for measurement level 2 .


def format_counts(counts, header=None):
    """Format a single experiment result coming from backend to present
    to the Qiskit user.

    Args:
        counts (dict): counts histogram of multiple shots
        header (dict): the experiment header dictionary containing
            useful information for postprocessing.

    Returns:
        dict: a formatted counts
    """
    counts_dict = {}
    for key, val in counts.items():
        key = format_counts_memory(key, header)
        counts_dict[key] = val
    return counts_dict

def format_counts ( counts , header = None ) : counts_dict = { } for key , val in counts . items ( ) : key = format_counts_memory ( key , header ) counts_dict [ key ] = val return counts_dict

Format a single experiment result coming from backend to present to the Qiskit user .


def format_statevector(vec, decimals=None):
    """Format statevector coming from the backend to present to the Qiskit user.

    Args:
        vec (list): a list of [re, im] complex numbers.
        decimals (int): the number of decimals in the statevector.
            If None, no rounding is done.

    Returns:
        list[complex]: a list of python complex numbers.
    """
    num_basis = len(vec)
    vec_complex = np.zeros(num_basis, dtype=complex)
    for i in range(num_basis):
        vec_complex[i] = vec[i][0] + 1j * vec[i][1]
    if decimals:
        vec_complex = np.around(vec_complex, decimals=decimals)
    return vec_complex

def format_statevector ( vec , decimals = None ) : num_basis = len ( vec ) vec_complex = np . zeros ( num_basis , dtype = complex ) for i in range ( num_basis ) : vec_complex [ i ] = vec [ i ] [ 0 ] + 1j * vec [ i ] [ 1 ] if decimals : vec_complex = np . around ( vec_complex , decimals = decimals ) return vec_complex

Format statevector coming from the backend to present to the Qiskit user .


def format_unitary(mat, decimals=None):
    """Format unitary coming from the backend to present to the Qiskit user.

    Args:
        mat (list[list]): a list of list of [re, im] complex numbers
        decimals (int): the number of decimals in the statevector.
            If None, no rounding is done.

    Returns:
        list[list[complex]]: a matrix of complex numbers
    """
    num_basis = len(mat)
    mat_complex = np.zeros((num_basis, num_basis), dtype=complex)
    for i, vec in enumerate(mat):
        mat_complex[i] = format_statevector(vec, decimals)
    return mat_complex

def format_unitary ( mat , decimals = None ) : num_basis = len ( mat ) mat_complex = np . zeros ( ( num_basis , num_basis ) , dtype = complex ) for i , vec in enumerate ( mat ) : mat_complex [ i ] = format_statevector ( vec , decimals ) return mat_complex

Format unitary coming from the backend to present to the Qiskit user .


def requires_submit(func):
    """
    Decorator to ensure that a submit has been performed before
    calling the method.

    Args:
        func (callable): test function to be decorated.

    Returns:
        callable: the decorated function.
    """
    @functools.wraps(func)
    def _wrapper(self, *args, **kwargs):
        if self._future is None:
            raise JobError("Job not submitted yet!. You have to .submit() first!")
        return func(self, *args, **kwargs)
    return _wrapper

Decorator to ensure that a submit has been performed before calling the method .


def submit(self):
        """Submit the job to the backend for execution.

        Raises:
            QobjValidationError: if the JSON serialization of the Qobj passed
            during construction does not validate against the Qobj schema.

            JobError: if trying to re-submit the job.
        """
        if self._future is not None:
            raise JobError("We have already submitted the job!")

        validate_qobj_against_schema(self._qobj)
        self._future = self._executor.submit(self._fn, self._job_id, self._qobj)

def
submit
(
self
)
:
if
self
.
_future
is
not
:
raise
JobError
(
"We have already submitted the job!"
)
validate_qobj_against_schema
(
self
.
_qobj
)
self
.
_future
=
self
.
_executor
.
submit
(
self
.
_fn
,
self
.
_job_id
,
self
.
_qobj
)

Submit the job to the backend for execution .


def status(self):
        """Gets the status of the job by querying the Python's future

        Returns:
            qiskit.providers.JobStatus: The current JobStatus

        Raises:
            JobError: If the future is in unexpected state
            concurrent.futures.TimeoutError: if timeout occurred.
        """
        # The order is important here
        if self._future.running():
            _status = JobStatus.RUNNING
        elif self._future.cancelled():
            _status = JobStatus.CANCELLED
        elif self._future.done():
            _status = JobStatus.DONE if self._future.exception() is None else JobStatus.ERROR
        else:
            # Note: There is an undocumented Future state: PENDING, that seems to show up when
            # the job is enqueued, waiting for someone to pick it up. We need to deal with this
            # state but there's no public API for it, so we are assuming that if the job is not
            # in any of the previous states, is PENDING, ergo INITIALIZING for us.
            _status = JobStatus.INITIALIZING

        return _status

def status ( self ) : if self . _future . running ( ) : _status = JobStatus . RUNNING elif self . _future . cancelled ( ) : _status = JobStatus . CANCELLED elif self . _future . done ( ) : _status = JobStatus . DONE if self . _future . exception ( ) is None else JobStatus . ERROR else : _status = JobStatus . INITIALIZING return _status

Gets the status of the job by querying the Python s future


def includes(self, lo_freq: float) -> bool:
        """Whether `lo_freq` is within the `LoRange`.

        Args:
            lo_freq: LO frequency to be checked

        Returns:
            bool: True if lo_freq is included in this range, otherwise False
        """
        if self._lb <= lo_freq <= self._ub:
            return True
        return False

def includes ( self , lo_freq : float ) -> bool : if self . _lb <= lo_freq <= self . _ub : return True return False


def iplot_bloch_multivector(rho, figsize=None):
    """ Create a bloch sphere representation.

        Graphical representation of the input array, using as much bloch
        spheres as qubit are required.

        Args:
            rho (array): State vector or density matrix
            figsize (tuple): Figure size in pixels.
    """

    # HTML
    html_template = Template("""

    """)

    # JavaScript
    javascript_template = Template("""

    """)
    rho = _validate_input_state(rho)
    if figsize is None:
        options = {}
    else:
        options = {'width': figsize[0], 'height': figsize[1]}

    # Process data and execute
    num = int(np.log2(len(rho)))

    bloch_data = []
    for i in range(num):
        pauli_singles = [Pauli.pauli_single(num, i, 'X'), Pauli.pauli_single(num, i, 'Y'),
                         Pauli.pauli_single(num, i, 'Z')]
        bloch_state = list(map(lambda x: np.real(np.trace(np.dot(x.to_matrix(), rho))),
                               pauli_singles))
        bloch_data.append(bloch_state)

    div_number = str(time.time())
    div_number = re.sub('[.]', '', div_number)

    html = html_template.substitute({
        'divNumber': div_number
    })

    javascript = javascript_template.substitute({
        'data': bloch_data,
        'divNumber': div_number,
        'options': options
    })

    display(HTML(html + javascript))

def iplot_bloch_multivector ( rho , figsize = None ) : html_template = Template ( ) javascript_template = Template ( ) rho = _validate_input_state ( rho ) if figsize is None : options = { } else : options = { 'width' : figsize [ 0 ] , 'height' : figsize [ 1 ] } num = int ( np . log2 ( len ( rho ) ) ) bloch_data = [ ] for i in range ( num ) : pauli_singles = [ Pauli . pauli_single ( num , i , 'X' ) , Pauli . pauli_single ( num , i , 'Y' ) , Pauli . pauli_single ( num , i , 'Z' ) ] bloch_state = list ( map ( lambda x : np . real ( np . trace ( np . dot ( x . to_matrix ( ) , rho ) ) ) , pauli_singles ) ) bloch_data . append ( bloch_state ) div_number = str ( time . time ( ) ) div_number = re . sub ( '[.]' , '' , div_number ) html = html_template . substitute ( { 'divNumber' : div_number } ) javascript = javascript_template . substitute ( { 'data' : bloch_data , 'divNumber' : div_number , 'options' : options } ) display ( HTML ( html + javascript ) )


def get_qubit_los(self, user_lo_config):
        """Embed default qubit LO frequencies from backend and format them to list object.
        If configured lo frequency is the same as default, this method returns `None`.

        Args:
            user_lo_config (LoConfig): A dictionary of LOs to format.

        Returns:
            list: A list of qubit LOs.

        Raises:
            PulseError: when LO frequencies are missing.
        """
        try:
            _q_los = self.default_qubit_los.copy()
        except KeyError:
            raise PulseError('Qubit default frequencies not exist.')

        for channel, lo_freq in user_lo_config.qubit_lo_dict().items():
            _q_los[channel.index] = lo_freq

        if _q_los == self.default_qubit_los:
            return None
        return _q_los

def
get_qubit_los
(
self
,
user_lo_config
)
:
try
:
_q_los
=
self
.
default_qubit_los
.
copy
(
)
except
KeyError
:
raise
PulseError
(
'Qubit default frequencies not exist.'
)
for
channel
,
lo_freq
in
user_lo_config
.
qubit_lo_dict
(
)
.
items
(
)
:
_q_los
[
channel
.
index
]
=
lo_freq
if
_q_los
==
self
.
default_qubit_los
:
return
return
_q_los

Embed default qubit LO frequencies from backend and format them to list object . If configured lo frequency is the same as default this method returns None .


def get_meas_los(self, user_lo_config):
        """Embed default meas LO frequencies from backend and format them to list object.
        If configured lo frequency is the same as default, this method returns `None`.

        Args:
            user_lo_config (LoConfig): A dictionary of LOs to format.

        Returns:
            list: A list of meas LOs.

        Raises:
            PulseError: when LO frequencies are missing.
        """
        try:
            _m_los = self.default_meas_los.copy()
        except KeyError:
            raise PulseError('Default measurement frequencies not exist.')

        for channel, lo_freq in user_lo_config.meas_lo_dict().items():
            _m_los[channel.index] = lo_freq

        if _m_los == self.default_meas_los:
            return None
        return _m_los

Embed default meas LO frequencies from backend and format them to list object . If configured lo frequency is the same as default this method returns None .


def run(self, dag):
        """Expand all op nodes to the given basis.

        Args:
            dag(DAGCircuit): input dag

        Raises:
            QiskitError: if unable to unroll given the basis due to undefined
            decomposition rules (such as a bad basis) or excessive recursion.

        Returns:
            DAGCircuit: output unrolled dag
        """
        # Walk through the DAG and expand each non-basis node
        for node in dag.op_nodes():
            basic_insts = ['measure', 'reset', 'barrier', 'snapshot']
            if node.name in basic_insts:
                # TODO: this is legacy behavior.Basis_insts should be removed that these
                #  instructions should be part of the device-reported basis. Currently, no
                #  backend reports "measure", for example.
                continue
            if node.name in self.basis:  # If already a base, ignore.
                continue

            # TODO: allow choosing other possible decompositions
            rule = node.op.definition
            if not rule:
                raise QiskitError("Cannot unroll the circuit to the given basis, %s. "
                                  "No rule to expand instruction %s." %
                                  (str(self.basis), node.op.name))

            # hacky way to build a dag on the same register as the rule is defined
            # TODO: need anonymous rules to address wires by index
            decomposition = DAGCircuit()
            decomposition.add_qreg(rule[0][1][0][0])
            for inst in rule:
                decomposition.apply_operation_back(*inst)

            unrolled_dag = self.run(decomposition)  # recursively unroll ops
            dag.substitute_node_with_dag(node, unrolled_dag)
        return dag

Expand all op nodes to the given basis .


def iplot_state_qsphere(rho, figsize=None):
    """ Create a Q sphere representation.

        Graphical representation of the input array, using a Q sphere for each
        eigenvalue.

        Args:
            rho (array): State vector or density matrix.
            figsize (tuple): Figure size in pixels.
    """

    # HTML
    html_template = Template("""

    """)

    # JavaScript
    javascript_template = Template("""

    """)
    rho = _validate_input_state(rho)
    if figsize is None:
        options = {}
    else:
        options = {'width': figsize[0], 'height': figsize[1]}

    qspheres_data = []
    # Process data and execute
    num = int(np.log2(len(rho)))

    # get the eigenvectors and eigenvalues
    weig, stateall = linalg.eigh(rho)

    for _ in range(2**num):
        # start with the max
        probmix = weig.max()
        prob_location = weig.argmax()
        if probmix > 0.001:
            # print("The " + str(k) + "th eigenvalue = " + str(probmix))
            # get the max eigenvalue
            state = stateall[:, prob_location]
            loc = np.absolute(state).argmax()
            # get the element location closes to lowest bin representation.
            for j in range(2**num):
                test = np.absolute(np.absolute(state[j]) -
                                   np.absolute(state[loc]))
                if test < 0.001:
                    loc = j
                    break
            # remove the global phase
            angles = (np.angle(state[loc]) + 2 * np.pi) % (2 * np.pi)
            angleset = np.exp(-1j*angles)
            state = angleset*state
            state.flatten()

            spherepoints = []
            for i in range(2**num):
                # get x,y,z points

                element = bin(i)[2:].zfill(num)
                weight = element.count("1")

                number_of_divisions = n_choose_k(num, weight)
                weight_order = bit_string_index(element)

                angle = weight_order * 2 * np.pi / number_of_divisions

                zvalue = -2 * weight / num + 1
                xvalue = np.sqrt(1 - zvalue**2) * np.cos(angle)
                yvalue = np.sqrt(1 - zvalue**2) * np.sin(angle)

                # get prob and angle - prob will be shade and angle color
                prob = np.real(np.dot(state[i], state[i].conj()))
                angles = (np.angle(state[i]) + 2 * np.pi) % (2 * np.pi)
                qpoint = {
                    'x': xvalue,
                    'y': yvalue,
                    'z': zvalue,
                    'prob': prob,
                    'phase': angles
                }
                spherepoints.append(qpoint)

            # Associate all points to one sphere
            sphere = {
                'points': spherepoints,
                'eigenvalue': probmix
            }

            # Add sphere to the spheres array
            qspheres_data.append(sphere)
            weig[prob_location] = 0

    div_number = str(time.time())
    div_number = re.sub('[.]', '', div_number)

    html = html_template.substitute({
        'divNumber': div_number
    })

    javascript = javascript_template.substitute({
        'data': qspheres_data,
        'divNumber': div_number,
        'options': options
    })

    display(HTML(html + javascript))

def iplot_state_qsphere ( rho , figsize = None ) : html_template = Template ( ) javascript_template = Template ( ) rho = _validate_input_state ( rho ) if figsize is None : options = { } else : options = { 'width' : figsize [ 0 ] , 'height' : figsize [ 1 ] } qspheres_data = [ ] num = int ( np . log2 ( len ( rho ) ) ) weig , stateall = linalg . eigh ( rho ) for _ in range ( 2 ** num ) : probmix = weig . max ( ) prob_location = weig . argmax ( ) if probmix > 0.001 : state = stateall [ : , prob_location ] loc = np . absolute ( state ) . argmax ( ) for j in range ( 2 ** num ) : test = np . absolute ( np . absolute ( state [ j ] ) - np . absolute ( state [ loc ] ) ) if test < 0.001 : loc = j break angles = ( np . angle ( state [ loc ] ) + 2 * np . pi ) % ( 2 * np . pi ) angleset = np . exp ( - 1j * angles ) state = angleset * state state . flatten ( ) spherepoints = [ ] for i in range ( 2 ** num ) : element = bin ( i ) [ 2 : ] . zfill ( num ) weight = element . count ( "1" ) number_of_divisions = n_choose_k ( num , weight ) weight_order = bit_string_index ( element ) angle = weight_order * 2 * np . pi / number_of_divisions zvalue = - 2 * weight / num + 1 xvalue = np . sqrt ( 1 - zvalue ** 2 ) * np . cos ( angle ) yvalue = np . sqrt ( 1 - zvalue ** 2 ) * np . sin ( angle ) prob = np . real ( np . dot ( state [ i ] , state [ i ] . conj ( ) ) ) angles = ( np . angle ( state [ i ] ) + 2 * np . pi ) % ( 2 * np . pi ) qpoint = { 'x' : xvalue , 'y' : yvalue , 'z' : zvalue , 'prob' : prob , 'phase' : angles } spherepoints . append ( qpoint ) sphere = { 'points' : spherepoints , 'eigenvalue' : probmix } qspheres_data . append ( sphere ) weig [ prob_location ] = 0 div_number = str ( time . time ( ) ) div_number = re . sub ( '[.]' , '' , div_number ) html = html_template . substitute ( { 'divNumber' : div_number } ) javascript = javascript_template . substitute ( { 'data' : qspheres_data , 'divNumber' : div_number , 'options' : options } ) display ( HTML ( html + javascript ) )


def n_choose_k(n, k):
    """Return the number of combinations for n choose k.

    Args:
        n (int): the total number of options .
        k (int): The number of elements.

    Returns:
        int: returns the binomial coefficient
    """
    if n == 0:
        return 0
    return reduce(lambda x, y: x * y[0] / y[1],
                  zip(range(n - k + 1, n + 1),
                      range(1, k + 1)), 1)

def n_choose_k ( n , k ) : if n == 0 : return 0 return reduce ( lambda x , y : x * y [ 0 ] / y [ 1 ] , zip ( range ( n - k + 1 , n + 1 ) , range ( 1 , k + 1 ) ) , 1 )

Return the number of combinations for n choose k .


def lex_index(n, k, lst):
    """Return  the lex index of a combination..

    Args:
        n (int): the total number of options .
        k (int): The number of elements.
        lst (list): list

    Returns:
        int: returns int index for lex order

    Raises:
        VisualizationError: if length of list is not equal to k
    """
    if len(lst) != k:
        raise VisualizationError("list should have length k")
    comb = list(map(lambda x: n - 1 - x, lst))
    dualm = sum([n_choose_k(comb[k - 1 - i], i + 1) for i in range(k)])
    return int(dualm)

def
lex_index
(
n
,
k
,
lst
)
:
if
len
(
lst
)
!=
k
:
raise
VisualizationError
(
"list should have length k"
)
comb
=
list
(
map
(
lambda
x
:
n
1
x
,
lst
)
)
dualm
=
sum
(
[
n_choose_k
(
comb
[
k
1
i
]
,
i
+
1
)
for
i
in
range
(
k
)
]
)
return
int
(
dualm
)

Return the lex index of a combination ..


def plot_state_paulivec(rho, title="", figsize=None, color=None):
    """Plot the paulivec representation of a quantum state.

    Plot a bargraph of the mixed state rho over the pauli matrices

    Args:
        rho (ndarray): Numpy array for state vector or density matrix
        title (str): a string that represents the plot title
        figsize (tuple): Figure size in inches.
        color (list or str): Color of the expectation value bars.
    Returns:
         matplotlib.Figure: The matplotlib.Figure of the visualization
    Raises:
        ImportError: Requires matplotlib.
    """
    if not HAS_MATPLOTLIB:
        raise ImportError('Must have Matplotlib installed.')
    rho = _validate_input_state(rho)
    if figsize is None:
        figsize = (7, 5)
    num = int(np.log2(len(rho)))
    labels = list(map(lambda x: x.to_label(), pauli_group(num)))
    values = list(map(lambda x: np.real(np.trace(np.dot(x.to_matrix(), rho))),
                      pauli_group(num)))
    numelem = len(values)
    if color is None:
        color = "#648fff"

    ind = np.arange(numelem)  # the x locations for the groups
    width = 0.5  # the width of the bars
    fig, ax = plt.subplots(figsize=figsize)
    ax.grid(zorder=0, linewidth=1, linestyle='--')
    ax.bar(ind, values, width, color=color, zorder=2)
    ax.axhline(linewidth=1, color='k')
    # add some text for labels, title, and axes ticks
    ax.set_ylabel('Expectation value', fontsize=14)
    ax.set_xticks(ind)
    ax.set_yticks([-1, -0.5, 0, 0.5, 1])
    ax.set_xticklabels(labels, fontsize=14, rotation=70)
    ax.set_xlabel('Pauli', fontsize=14)
    ax.set_ylim([-1, 1])
    ax.set_facecolor('#eeeeee')
    for tick in ax.xaxis.get_major_ticks()+ax.yaxis.get_major_ticks():
        tick.label.set_fontsize(14)
    ax.set_title(title, fontsize=16)
    plt.close(fig)
    return fig

def
plot_state_paulivec
(
rho
,
title
=
""
,
figsize
=
,
color
=
)
:
if
not
HAS_MATPLOTLIB
:
raise
ImportError
(
'Must have Matplotlib installed.'
)
rho
=
_validate_input_state
(
rho
)
if
figsize
is
:
figsize
=
(
7
,
5
)
num
=
int
(
np
.
log2
(
len
(
rho
)
)
)
labels
=
list
(
map
(
lambda
x
:
x
.
to_label
(
)
,
pauli_group
(
num
)
)
)
values
=
list
(
map
(
lambda
x
:
np
.
real
(
np
.
trace
(
np
.
dot
(
x
.
to_matrix
(
)
,
rho
)
)
)
,
pauli_group
(
num
)
)
)
numelem
=
len
(
values
)
if
color
is
:
color
=
"#648fff"
ind
=
np
.
arange
(
numelem
)
width
=
0.5
fig
,
ax
=
plt
.
subplots
(
figsize
=
figsize
)
ax
.
grid
(
zorder
=
0
,
linewidth
=
1
,
linestyle
=
'--'
)
ax
.
bar
(
ind
,
values
,
width
,
color
=
color
,
zorder
=
2
)
ax
.
axhline
(
linewidth
=
1
,
color
=
'k'
)
ax
.
set_ylabel
(
'Expectation value'
,
fontsize
=
14
)
ax
.
set_xticks
(
ind
)
ax
.
set_yticks
(
[
1
,
0.5
,
0
,
0.5
,
1
]
)
ax
.
set_xticklabels
(
labels
,
fontsize
=
14
,
rotation
=
70
)
ax
.
set_xlabel
(
'Pauli'
,
fontsize
=
14
)
ax
.
set_ylim
(
[
1
,
1
]
)
ax
.
set_facecolor
(
'#eeeeee'
)
for
tick
in
ax
.
xaxis
.
get_major_ticks
(
)
+
ax
.
yaxis
.
get_major_ticks
(
)
:
tick
.
label
.
set_fontsize
(
14
)
ax
.
set_title
(
title
,
fontsize
=
16
)
plt
.
close
(
fig
)
return
fig

Plot the paulivec representation of a quantum state .


def get_unique_backends():
    """Gets the unique backends that are available.

    Returns:
        list: Unique available backends.

    Raises:
        QiskitError: No backends available.
    """
    backends = IBMQ.backends()
    unique_hardware_backends = []
    unique_names = []
    for back in backends:
        if back.name() not in unique_names and not back.configuration().simulator:
            unique_hardware_backends.append(back)
            unique_names.append(back.name())
    if not unique_hardware_backends:
        raise QiskitError('No backends available.')
    return unique_hardware_backends

def
get_unique_backends
(
)
:
backends
=
IBMQ
.
backends
(
)
unique_hardware_backends
=
[
]
unique_names
=
[
]
for
back
in
backends
:
if
back
.
name
(
)
not
in
unique_names
and
not
back
.
configuration
(
)
.
simulator
:
unique_hardware_backends
.
append
(
back
)
unique_names
.
append
(
back
.
name
(
)
)
if
not
unique_hardware_backends
:
raise
QiskitError
(
'No backends available.'
)
return
unique_hardware_backends

Gets the unique backends that are available .


def op(self):
        """Returns the Instruction object corresponding to the op for the node else None"""
        if 'type' not in self.data_dict or self.data_dict['type'] != 'op':
            raise QiskitError("The node %s is not an op node" % (str(self)))
        return self.data_dict.get('op')

def
op
(
self
)
:
if
'type'
not
in
self
.
data_dict
or
self
.
data_dict
[
'type'
]
!=
'op'
:
raise
QiskitError
(
"The node %s is not an op node"
%
(
str
(
self
)
)
)
return
self
.
data_dict
.
get
(
'op'
)


def constant(duration: int, amp: complex, name: str = None) -> SamplePulse:
    """Generates constant-sampled `SamplePulse`.

    Applies `left` sampling strategy to generate discrete pulse from continuous function.

    Args:
        duration: Duration of pulse. Must be greater than zero.
        amp: Complex pulse amplitude.
        name: Name of pulse.
    """
    return _sampled_constant_pulse(duration, amp, name=name)

def constant ( duration : int , amp : complex , name : str = None ) -> SamplePulse : return _sampled_constant_pulse ( duration , amp , name = name )

Generates constant - sampled SamplePulse .