Instruction:
Here you have a function in Python 3, explain what it does
def order_based_on_type(value1, value2):
        if isinstance(value1, int) and Layout.is_virtual(value2):
            physical = value1
            virtual = value2
        elif isinstance(value2, int) and Layout.is_virtual(value1):
            physical = value2
            virtual = value1
        else:
            raise LayoutError('The map (%s -> %s) has to be a ((Register, integer) -> integer)'
                              ' or the other way around.' % (type(value1), type(value2)))
        return virtual, physical

Response: decides which one is physical based on the type. Returns ( virtual physical )


Instruction:
Make a summary of the following Python 3 code
def is_virtual(value):
        return value is None or isinstance(value, tuple) and len(value) == 2 and isinstance(
            value[0], Register) and isinstance(value[1], int)

Response: Checks if the value is a valid virtual qubit


Instruction:
Create a Python 3 function to
return a copy of a Layout instance.

Response:
def copy(self):
        """Returns a copy of a Layout instance."""
        layout_copy = type(self)()

        layout_copy._p2v = self._p2v.copy()
        layout_copy._v2p = self._v2p.copy()

        return layout_copy


Instruction:
Write a Python 3 function for
adding a map element between bit and physical_bit.

Response:
def add(self, virtual_bit, physical_bit=None):
        """
        Adds a map element between `bit` and `physical_bit`. If `physical_bit` is not
        defined, `bit` will be mapped to a new physical bit (extending the length of the
        layout by one.)
        Args:
            virtual_bit (tuple): A (qu)bit. For example, (QuantumRegister(3, 'qr'), 2).
            physical_bit (int): A physical bit. For example, 3.
        """
        if physical_bit is None:
            physical_candidate = len(self)
            while physical_candidate in self._p2v:
                physical_candidate += 1
            physical_bit = physical_candidate
        self[virtual_bit] = physical_bit


Instruction:
Given the following Python 3 function, write the documentation
def swap(self, left, right):
        if type(left) is not type(right):
            raise LayoutError('The method swap only works with elements of the same type.')
        temp = self[left]
        self[left] = self[right]
        self[right] = temp

Response: Swaps the map between left and right.


Instruction:
Can you write a function in Python 3 where it
combines self and another_layout into an edge map.

Response:
def combine_into_edge_map(self, another_layout):
        """Combines self and another_layout into an "edge map".

        For example::

              self       another_layout  resulting edge map
           qr_1 -> 0        0 <- q_2         qr_1 -> q_2
           qr_2 -> 2        2 <- q_1         qr_2 -> q_1
           qr_3 -> 3        3 <- q_0         qr_3 -> q_0

        The edge map is used to compose dags via, for example, compose_back.

        Args:
            another_layout (Layout): The other layout to combine.
        Returns:
            dict: A "edge map".
        Raises:
            LayoutError: another_layout can be bigger than self, but not smaller. Otherwise, raises.
        """
        edge_map = dict()

        for virtual, physical in self.get_virtual_bits().items():
            if physical not in another_layout._p2v:
                raise LayoutError('The wire_map_from_layouts() method does not support when the'
                                  ' other layout (another_layout) is smaller.')
            edge_map[virtual] = another_layout[physical]

        return edge_map


Instruction:
Can you generate the documentation for the following Python 3 function
def generate_trivial_layout(*regs):
        layout = Layout()
        for reg in regs:
            layout.add_register(reg)
        return layout

Response: Generates a trivial layout with all the registers in regs.


Instruction:
Write a Python 3 script to
convert a list of integers to a Layout object mapping virtual qubits to physical qubits.

Response:
def from_intlist(int_list, *qregs):
        """Converts a list of integers to a Layout
        mapping virtual qubits (index of the list) to
        physical qubits (the list values).

        Args:
            int_list (list): A list of integers.
            *qregs (QuantumRegisters): The quantum registers to apply
                the layout to.
        Returns:
            Layout: The corresponding Layout object.
        Raises:
            LayoutError: Invalid input layout.
        """
        if not all((isinstance(i, int) for i in int_list)):
            raise LayoutError('Expected a list of ints')
        if len(int_list) != len(set(int_list)):
            raise LayoutError('Duplicate values not permitted; Layout is bijective.')
        n_qubits = sum(reg.size for reg in qregs)
        # Check if list is too short to cover all qubits
        if len(int_list) < n_qubits:
            err_msg = 'Integer list length must equal number of qubits in circuit.'
            raise LayoutError(err_msg)
        out = Layout()
        main_idx = 0
        for qreg in qregs:
            for idx in range(qreg.size):
                out[(qreg, idx)] = int_list[main_idx]
                main_idx += 1
        if main_idx != len(int_list):
            for int_item in int_list[main_idx:]:
                out[int_item] = None
        return out


Instruction:
Here you have a function in Python 3, explain what it does
def from_tuplelist(tuple_list):
        out = Layout()
        for physical, virtual in enumerate(tuple_list):
            if virtual is None:
                continue
            elif Layout.is_virtual(virtual):
                if virtual in out._v2p:
                    raise LayoutError('Duplicate values not permitted; Layout is bijective.')
                out[virtual] = physical
            else:
                raise LayoutError("The list should contain elements of the form"
                                  " (Register, integer) or None")
        return out

Response: Takes a list containing physical and virtual ones and returns a Layout object.


Instruction:
Can you tell what is the following Python 3 function doing
def ccx(self, ctl1, ctl2, tgt):
    return self.append(ToffoliGate(), [ctl1, ctl2, tgt], [])

Response: Apply Toffoli to from ctl1 and ctl2 to tgt.


Instruction:
Write a Python 3 script for
defining the class entry.

Response:
def _define(self):
        """
        gate ccx a,b,c
        {
        h c; cx b,c; tdg c; cx a,c;
        t c; cx b,c; tdg c; cx a,c;
        t b; t c; h c; cx a,b;
        t a; tdg b; cx a,b;}
        """
        definition = []
        q = QuantumRegister(3, "q")
        rule = [
            (HGate(), [q[2]], []),
            (CnotGate(), [q[1], q[2]], []),
            (TdgGate(), [q[2]], []),
            (CnotGate(), [q[0], q[2]], []),
            (TGate(), [q[2]], []),
            (CnotGate(), [q[1], q[2]], []),
            (TdgGate(), [q[2]], []),
            (CnotGate(), [q[0], q[2]], []),
            (TGate(), [q[1]], []),
            (TGate(), [q[2]], []),
            (HGate(), [q[2]], []),
            (CnotGate(), [q[0], q[1]], []),
            (TGate(), [q[0]], []),
            (TdgGate(), [q[1]], []),
            (CnotGate(), [q[0], q[1]], [])
        ]
        for inst in rule:
            definition.append(inst)
        self.definition = definition


Instruction:
Create a Python 3 function for
collecting blocks of adjacent gates acting on a pair of "cx" qubits. The blocks contain "op" nodes in topological sort order such that all gates in a block act on the same pair of qubits and are adjacent in the circuit. the blocks are built by examining predecessors and successors of "cx" gates in the circuit. u1, u2, u3, cx, id gates will be included. Return a list of tuples of "op" node labels.

Response:
def run(self, dag):
        """collect blocks of adjacent gates acting on a pair of "cx" qubits.

        The blocks contain "op" nodes in topological sort order
        such that all gates in a block act on the same pair of
        qubits and are adjacent in the circuit. the blocks are built
        by examining predecessors and successors of "cx" gates in
        the circuit. u1, u2, u3, cx, id gates will be included.

        Return a list of tuples of "op" node labels.
        """
        # Initiate the commutation set
        self.property_set['commutation_set'] = defaultdict(list)

        good_names = ["cx", "u1", "u2", "u3", "id"]
        block_list = []
        nodes = list(dag.topological_nodes())
        nodes_seen = dict(zip(nodes, [False] * len(nodes)))
        for nd in dag.topological_op_nodes():
            group = []
            # Explore predecessors and successors of cx gates
            if nd.name == "cx" and nd.condition is None and not nodes_seen[nd]:
                these_qubits = sorted(nd.qargs)
                # Explore predecessors of the "cx" node
                pred = list(dag.predecessors(nd))
                explore = True
                while explore:
                    pred_next = []
                    # If there is one predecessor, add it if it's on the right qubits
                    if len(pred) == 1 and not nodes_seen[pred[0]]:
                        pnd = pred[0]
                        if pnd.name in good_names:
                            if (pnd.name == "cx" and sorted(pnd.qargs) == these_qubits) or \
                                    pnd.name != "cx":
                                group.append(pnd)
                                nodes_seen[pnd] = True
                                pred_next.extend(dag.predecessors(pnd))
                    # If there are two, then we consider cases
                    elif len(pred) == 2:
                        # First, check if there is a relationship
                        if pred[0] in dag.predecessors(pred[1]):
                            sorted_pred = [pred[1]]   # was [pred[1], pred[0]]
                        elif pred[1] in dag.predecessors(pred[0]):
                            sorted_pred = [pred[0]]   # was [pred[0], pred[1]]
                        else:
                            # We need to avoid accidentally adding a cx on these_qubits
                            # since these must have a dependency through the other predecessor
                            # in this case
                            if pred[0].name == "cx" and sorted(pred[0].qargs) == these_qubits:
                                sorted_pred = [pred[1]]
                            elif pred[1].name == "cx" and sorted(pred[1].qargs) == these_qubits:
                                sorted_pred = [pred[0]]
                            else:
                                sorted_pred = pred
                        if len(sorted_pred) == 2 and sorted_pred[0].name == "cx" and \
                           sorted_pred[1].name == "cx":
                            break  # stop immediately if we hit a pair of cx
                        # Examine each predecessor
                        for pnd in sorted_pred:
                            if pnd.name not in good_names:
                                continue
                            # If a predecessor is a single qubit gate, add it
                            if pnd.name != "cx":
                                if not nodes_seen[pnd]:
                                    group.append(pnd)
                                    nodes_seen[pnd] = True
                                    pred_next.extend(dag.predecessors(pnd))
                            # If cx, check qubits
                            else:
                                pred_qubits = sorted(pnd.qargs)
                                if pred_qubits == these_qubits:
                                    # add if on same qubits
                                    if not nodes_seen[pnd]:
                                        group.append(pnd)
                                        nodes_seen[pnd] = True
                                        pred_next.extend(dag.predecessors(pnd))
                                else:
                                    # remove qubit from consideration if not
                                    these_qubits = list(set(these_qubits) -
                                                        set(pred_qubits))
                    # Update predecessors
                    # Stop if there aren't any more
                    pred = list(set(pred_next))
                    if not pred:
                        explore = False
                # Reverse the predecessor list and append the "cx" node
                group.reverse()
                group.append(nd)
                nodes_seen[nd] = True
                # Reset these_qubits
                these_qubits = sorted(nd.qargs)
                # Explore successors of the "cx" node
                succ = list(dag.successors(nd))
                explore = True
                while explore:
                    succ_next = []
                    # If there is one successor, add it if its on the right qubits
                    if len(succ) == 1 and not nodes_seen[succ[0]]:
                        snd = succ[0]
                        if snd.name in good_names:
                            if (snd.name == "cx" and sorted(snd.qargs) == these_qubits) or \
                                    snd.name != "cx":
                                group.append(snd)
                                nodes_seen[snd] = True
                                succ_next.extend(dag.successors(snd))
                    # If there are two, then we consider cases
                    elif len(succ) == 2:
                        # First, check if there is a relationship
                        if succ[0] in dag.successors(succ[1]):
                            sorted_succ = [succ[1]]  # was [succ[1], succ[0]]
                        elif succ[1] in dag.successors(succ[0]):
                            sorted_succ = [succ[0]]  # was [succ[0], succ[1]]
                        else:
                            # We need to avoid accidentally adding a cx on these_qubits
                            # since these must have a dependency through the other successor
                            # in this case
                            if succ[0].name == "cx" and sorted(succ[0].qargs) == these_qubits:
                                sorted_succ = [succ[1]]
                            elif succ[1].name == "cx" and sorted(succ[1].qargs) == these_qubits:
                                sorted_succ = [succ[0]]
                            else:
                                sorted_succ = succ
                        if len(sorted_succ) == 2 and \
                           sorted_succ[0].name == "cx" and \
                           sorted_succ[1].name == "cx":
                            break  # stop immediately if we hit a pair of cx
                        # Examine each successor
                        for snd in sorted_succ:
                            if snd.name not in good_names:
                                continue
                            # If a successor is a single qubit gate, add it
                            if snd.name != "cx":
                                if not nodes_seen[snd]:
                                    group.append(snd)
                                    nodes_seen[snd] = True
                                    succ_next.extend(dag.successors(snd))
                            else:
                                # If cx, check qubits
                                succ_qubits = sorted(snd.qargs)
                                if succ_qubits == these_qubits:
                                    # add if on same qubits
                                    if not nodes_seen[snd]:
                                        group.append(snd)
                                        nodes_seen[snd] = True
                                        succ_next.extend(dag.successors(snd))
                                else:
                                    # remove qubit from consideration if not
                                    these_qubits = list(set(these_qubits) -
                                                        set(succ_qubits))
                    # Update successors
                    # Stop if there aren't any more
                    succ = list(set(succ_next))
                    if not succ:
                        explore = False

                block_list.append(tuple(group))

        self.property_set['block_list'] = block_list

        return dag


Instruction:
Make a summary of the following Python 3 code
def u2(self, phi, lam, q):
    return self.append(U2Gate(phi, lam), [q], [])

Response: Apply u2 to q.


Instruction:
How would you code a function in Python 3 to
return a Numpy. array for the U3 gate.

Response:
def to_matrix(self):
        """Return a Numpy.array for the U3 gate."""
        isqrt2 = 1 / numpy.sqrt(2)
        phi, lam = self.params
        phi, lam = float(phi), float(lam)
        return numpy.array([[isqrt2, -numpy.exp(1j * lam) * isqrt2],
                            [
                                numpy.exp(1j * phi) * isqrt2,
                                numpy.exp(1j * (phi + lam)) * isqrt2
                            ]],
                           dtype=complex)


Instruction:
Can you generate the documentation for the following Python 3 function
def insert(self, start_time: int, schedule: ScheduleComponent) -> 'ScheduleComponent':
        return ops.insert(self, start_time, schedule)

Response: Insert a schedule into the cache at the specified start time.


Instruction:
Can you tell what is the following Python 3 function doing
def _check_if_fenced(self, name):
        if name in object.__getattribute__(self, '_attributes_to_fence'):
            raise TranspilerAccessError("The fenced %s has the property %s protected" %
                                        (type(object.__getattribute__(self, '_wrapped')), name))

Response: Checks if the attribute name is in the list of attributes to protect. If so raises a TranspilerAccessError.


Instruction:
Can you implement a function in Python 3 that
returns True if completely - positive trace - preserving.

Response:
def is_cptp(self, atol=None, rtol=None):
        """Return True if completely-positive trace-preserving."""
        if atol is None:
            atol = self._atol
        if rtol is None:
            rtol = self._rtol
        if self._data[1] is not None:
            return False
        check = np.dot(np.transpose(np.conj(self._data[0])), self._data[0])
        return is_identity_matrix(check, rtol=self._rtol, atol=self._atol)


Instruction:
How would you code a function in Python 3 to
return the conjugate of the QuantumChannel.

Response:
def conjugate(self):
        """Return the conjugate of the QuantumChannel."""
        # pylint: disable=assignment-from-no-return
        stine_l = np.conjugate(self._data[0])
        stine_r = None
        if self._data[1] is not None:
            stine_r = np.conjugate(self._data[1])
        return Stinespring((stine_l, stine_r), self.input_dims(),
                           self.output_dims())


Instruction:
Can you generate a brief explanation for the following Python 3 code
def transpose(self):
        din, dout = self.dim
        dtr = self._data[0].shape[0] // dout
        stine = [None, None]
        for i, mat in enumerate(self._data):
            if mat is not None:
                stine[i] = np.reshape(
                    np.transpose(np.reshape(mat, (dout, dtr, din)), (2, 1, 0)),
                    (din * dtr, dout))
        return Stinespring(
            tuple(stine),
            input_dims=self.output_dims(),
            output_dims=self.input_dims())

Response: Return the transpose of the QuantumChannel.


Instruction:
Here you have a function in Python 3, explain what it does
def compose(self, other, qargs=None, front=False):
        if qargs is not None:
            return Stinespring(
                SuperOp(self).compose(other, qargs=qargs, front=front))

        # Convert other to Kraus
        if not isinstance(other, Kraus):
            other = Kraus(other)
        # Check dimensions match up
        if front and self._input_dim != other._output_dim:
            raise QiskitError(
                'input_dim of self must match output_dim of other')
        if not front and self._output_dim != other._input_dim:
            raise QiskitError(
                'input_dim of other must match output_dim of self')
        # Since we cannot directly compose two channels in Stinespring
        # representation we convert to the Kraus representation
        return Stinespring(Kraus(self).compose(other, front=front))

Response: Return the composition of self and other.


Instruction:
How would you explain what the following Python 3 function does
def power(self, n):
        if n > 0:
            return super().power(n)
        return Stinespring(SuperOp(self).power(n))

Response: The matrix power of the superoperator matrix.


Instruction:
How would you explain what the following Python 3 function does
def multiply(self, other):
        if not isinstance(other, Number):
            raise QiskitError("other is not a number")
        # If the number is complex or negative we need to convert to
        # general Stinespring representation so we first convert to
        # the Choi representation
        if isinstance(other, complex) or other < 1:
            # Convert to Choi-matrix
            return Stinespring(Choi(self).multiply(other))
        # If the number is real we can update the Kraus operators
        # directly
        num = np.sqrt(other)
        stine_l, stine_r = self._data
        stine_l = num * self._data[0]
        stine_r = None
        if self._data[1] is not None:
            stine_r = num * self._data[1]
        return Stinespring((stine_l, stine_r), self.input_dims(),
                           self.output_dims())

Response: Returns the QuantumChannel self + other.


Instruction:
Explain what the following Python 3 code does
def _evolve(self, state, qargs=None):
        # If subsystem evolution we use the SuperOp representation
        if qargs is not None:
            return SuperOp(self)._evolve(state, qargs)

        # Otherwise we compute full evolution directly
        state = self._format_state(state)
        if state.shape[0] != self._input_dim:
            raise QiskitError(
                "QuantumChannel input dimension is not equal to state dimension."
            )
        if state.ndim == 1 and self._data[1] is None and \
           self._data[0].shape[0] // self._output_dim == 1:
            # If the shape of the stinespring operator is equal to the output_dim
            # evolution of a state vector psi -> stine.psi
            return np.dot(self._data[0], state)
        # Otherwise we always return a density matrix
        state = self._format_state(state, density_matrix=True)
        stine_l, stine_r = self._data
        if stine_r is None:
            stine_r = stine_l
        din, dout = self.dim
        dtr = stine_l.shape[0] // dout
        shape = (dout, dtr, din)
        return np.einsum('iAB,BC,jAC->ij', np.reshape(stine_l, shape), state,
                         np.reshape(np.conjugate(stine_r), shape))

Response: Evolve a state by the QuantumChannel.


Instruction:
Can you generate the documentation for the following Python 3 function
def _tensor_product(self, other, reverse=False):
        # Convert other to Stinespring
        if not isinstance(other, Stinespring):
            other = Stinespring(other)

        # Tensor stinespring ops
        sa_l, sa_r = self._data
        sb_l, sb_r = other._data

        # Reshuffle tensor dimensions
        din_a, dout_a = self.dim
        din_b, dout_b = other.dim
        dtr_a = sa_l.shape[0] // dout_a
        dtr_b = sb_l.shape[0] // dout_b
        if reverse:
            shape_in = (dout_b, dtr_b, dout_a, dtr_a, din_b * din_a)
            shape_out = (dout_b * dtr_b * dout_a * dtr_a, din_b * din_a)
        else:
            shape_in = (dout_a, dtr_a, dout_b, dtr_b, din_a * din_b)
            shape_out = (dout_a * dtr_a * dout_b * dtr_b, din_a * din_b)

        # Compute left stinepsring op
        if reverse:
            input_dims = self.input_dims() + other.input_dims()
            output_dims = self.output_dims() + other.output_dims()
            sab_l = np.kron(sb_l, sa_l)
        else:
            input_dims = other.input_dims() + self.input_dims()
            output_dims = other.output_dims() + self.output_dims()
            sab_l = np.kron(sa_l, sb_l)
        # Reravel indicies
        sab_l = np.reshape(
            np.transpose(np.reshape(sab_l, shape_in), (0, 2, 1, 3, 4)),
            shape_out)

        # Compute right stinespring op
        if sa_r is None and sb_r is None:
            sab_r = None
        else:
            if sa_r is None:
                sa_r = sa_l
            elif sb_r is None:
                sb_r = sb_l
            if reverse:
                sab_r = np.kron(sb_r, sa_r)
            else:
                sab_r = np.kron(sa_r, sb_r)
            # Reravel indicies
            sab_r = np.reshape(
                np.transpose(np.reshape(sab_r, shape_in), (0, 2, 1, 3, 4)),
                shape_out)
        return Stinespring((sab_l, sab_r), input_dims, output_dims)

Response: Return the tensor product of two quantum channels.


Instruction:
Write a Python 3 function that can
run the BasicSwap pass on the given DAG.

Response:
def run(self, dag):
        """
        Runs the BasicSwap 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
        """
        new_dag = DAGCircuit()

        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")

        current_layout = self.initial_layout.copy()

        for layer in dag.serial_layers():
            subdag = layer['graph']

            for gate in subdag.twoQ_gates():
                physical_q0 = current_layout[gate.qargs[0]]
                physical_q1 = current_layout[gate.qargs[1]]
                if self.coupling_map.distance(physical_q0, physical_q1) != 1:
                    # Insert a new layer with the SWAP(s).
                    swap_layer = DAGCircuit()

                    path = self.coupling_map.shortest_undirected_path(physical_q0, physical_q1)
                    for swap in range(len(path) - 2):
                        connected_wire_1 = path[swap]
                        connected_wire_2 = path[swap + 1]

                        qubit_1 = current_layout[connected_wire_1]
                        qubit_2 = current_layout[connected_wire_2]

                        # create qregs
                        for qreg in current_layout.get_registers():
                            if qreg not in swap_layer.qregs.values():
                                swap_layer.add_qreg(qreg)

                        # create the swap operation
                        swap_layer.apply_operation_back(SwapGate(),
                                                        qargs=[qubit_1, qubit_2],
                                                        cargs=[])

                    # layer insertion
                    edge_map = current_layout.combine_into_edge_map(self.initial_layout)
                    new_dag.compose_back(swap_layer, edge_map)

                    # update current_layout
                    for swap in range(len(path) - 2):
                        current_layout.swap(path[swap], path[swap + 1])

            edge_map = current_layout.combine_into_edge_map(self.initial_layout)
            new_dag.extend_back(subdag, edge_map)

        return new_dag


Instruction:
How would you implement a function in Python 3 that
finds a swap circuit that implements a permutation for this layer.

Response:
def _layer_permutation(layer_partition, initial_layout, layout, qubit_subset,
                       coupling, trials, qregs, rng):
    """Find a swap circuit that implements a permutation for this layer.

    Args:
        layer_partition (list): The layer_partition is a list of (qu)bit
            lists and each qubit is a tuple (qreg, index).
        initial_layout (Layout): The initial layout passed.
        layout (Layout): The layout is a Layout object mapping virtual
            qubits in the input circuit to physical qubits in the coupling
            graph. It reflects the current positions of the data.
        qubit_subset (list): The qubit_subset is the set of qubits in
            the coupling graph that we have chosen to map into, as tuples
            (Register, index).
        coupling (CouplingMap): Directed graph representing a coupling map.
            This coupling map should be one that was provided to the
            stochastic mapper.
        trials (int): Number of attempts the randomized algorithm makes.
        qregs (OrderedDict): Ordered dict of registers from input DAG.
        rng (RandomState): Random number generator.

    Returns:
        Tuple: success_flag, best_circuit, best_depth, best_layout, trivial_flag

    Raises:
        TranspilerError: if anything went wrong.
     """
    logger.debug("layer_permutation: layer_partition = %s",
                 pformat(layer_partition))
    logger.debug("layer_permutation: layout = %s",
                 pformat(layout.get_virtual_bits()))
    logger.debug("layer_permutation: qubit_subset = %s",
                 pformat(qubit_subset))
    logger.debug("layer_permutation: trials = %s", trials)

    gates = []  # list of lists of tuples [[(register, index), ...], ...]
    for gate_args in layer_partition:
        if len(gate_args) > 2:
            raise TranspilerError("Layer contains > 2-qubit gates")
        elif len(gate_args) == 2:
            gates.append(tuple(gate_args))
    logger.debug("layer_permutation: gates = %s", pformat(gates))

    # Can we already apply the gates? If so, there is no work to do.
    dist = sum([coupling.distance(layout[g[0]], layout[g[1]])
                for g in gates])
    logger.debug("layer_permutation: distance = %s", dist)
    if dist == len(gates):
        logger.debug("layer_permutation: nothing to do")
        circ = DAGCircuit()
        for register in layout.get_virtual_bits().keys():
            if register[0] not in circ.qregs.values():
                circ.add_qreg(register[0])
        return True, circ, 0, layout, (not bool(gates))

    # Begin loop over trials of randomized algorithm
    num_qubits = len(layout)
    best_depth = inf  # initialize best depth
    best_edges = None  # best edges found
    best_circuit = None  # initialize best swap circuit
    best_layout = None  # initialize best final layout

    cdist2 = coupling._dist_matrix**2
    # Scaling matrix
    scale = np.zeros((num_qubits, num_qubits))

    int_qubit_subset = regtuple_to_numeric(qubit_subset, qregs)
    int_gates = gates_to_idx(gates, qregs)
    int_layout = nlayout_from_layout(layout, qregs, coupling.size())

    trial_circuit = DAGCircuit()  # SWAP circuit for this trial
    for register in layout.get_virtual_bits().keys():
        if register[0] not in trial_circuit.qregs.values():
            trial_circuit.add_qreg(register[0])

    slice_circuit = DAGCircuit()  # circuit for this swap slice
    for register in layout.get_virtual_bits().keys():
        if register[0] not in slice_circuit.qregs.values():
            slice_circuit.add_qreg(register[0])
    edges = np.asarray(coupling.get_edges(), dtype=np.int32).ravel()
    cdist = coupling._dist_matrix
    for trial in range(trials):
        logger.debug("layer_permutation: trial %s", trial)
        # This is one Trial --------------------------------------
        dist, optim_edges, trial_layout, depth_step = swap_trial(num_qubits, int_layout,
                                                                 int_qubit_subset,
                                                                 int_gates, cdist2,
                                                                 cdist, edges, scale,
                                                                 rng)

        logger.debug("layer_permutation: final distance for this trial = %s", dist)
        if dist == len(gates) and depth_step < best_depth:
            logger.debug("layer_permutation: got circuit with improved depth %s",
                         depth_step)
            best_edges = optim_edges
            best_layout = trial_layout
            best_depth = min(best_depth, depth_step)

        # Break out of trial loop if we found a depth 1 circuit
        # since we can't improve it further
        if best_depth == 1:
            break

    # If we have no best circuit for this layer, all of the
    # trials have failed
    if best_layout is None:
        logger.debug("layer_permutation: failed!")
        return False, None, None, None, False

    edgs = best_edges.edges()
    for idx in range(best_edges.size//2):
        slice_circuit.apply_operation_back(
            SwapGate(), [initial_layout[edgs[2*idx]], initial_layout[edgs[2*idx+1]]], [])
    trial_circuit.extend_back(slice_circuit)
    best_circuit = trial_circuit

    # Otherwise, we return our result for this layer
    logger.debug("layer_permutation: success!")
    best_lay = best_layout.to_layout(qregs)
    return True, best_circuit, best_depth, best_lay, False


Instruction:
How would you code a function in Python 3 to
take a list of tuples and converts them into an integer array.

Response:
def regtuple_to_numeric(items, qregs):
    """Takes (QuantumRegister, int) tuples and converts
    them into an integer array.

    Args:
        items (list): List of tuples of (QuantumRegister, int)
                      to convert.
        qregs (dict): List of )QuantumRegister, int) tuples.
    Returns:
        ndarray: Array of integers.

    """
    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(len(items), dtype=np.int32)
    for idx, val in enumerate(items):
        out[idx] = reg_idx[regint[val[0]]]+val[1]
    return out


Instruction:
How would you code a function in Python 3 to
convert a list of gates into a nested list of integers.

Response:
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


Instruction:
Implement a function in Python 3 to
run the StochasticSwap pass on the given DAG.

Response:
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


Instruction:
Can you generate the documentation for the following Python 3 function
def _layer_permutation(self, layer_partition, layout, qubit_subset,
                           coupling, trials):
        """Find a swap circuit that implements a permutation for this layer.

        The goal is to swap qubits such that qubits in the same two-qubit gates
        are adjacent.

        Based on S. Bravyi's algorithm.

        layer_partition (list): The layer_partition is a list of (qu)bit
            lists and each qubit is a tuple (qreg, index).
        layout (Layout): The layout is a Layout object mapping virtual
            qubits in the input circuit to physical qubits in the coupling
            graph. It reflects the current positions of the data.
        qubit_subset (list): The qubit_subset is the set of qubits in
            the coupling graph that we have chosen to map into, as tuples
            (Register, index).
        coupling (CouplingMap): Directed graph representing a coupling map.
            This coupling map should be one that was provided to the
            stochastic mapper.
        trials (int): Number of attempts the randomized algorithm makes.

        Returns:
            Tuple: success_flag, best_circuit, best_depth, best_layout, trivial_flag

        If success_flag is True, then best_circuit contains a DAGCircuit with
        the swap circuit, best_depth contains the depth of the swap circuit,
        and best_layout contains the new positions of the data qubits after the
        swap circuit has been applied. The trivial_flag is set if the layer
        has no multi-qubit gates.

        Raises:
            TranspilerError: if anything went wrong.
     """
        return _layer_permutation(layer_partition, self.initial_layout,
                                  layout, qubit_subset,
                                  coupling, trials,
                                  self.qregs, self.rng)

Response: Find a swap circuit that implements a permutation for this layer.


Instruction:
Can you implement a function in Python 3 that
provides 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.

Response:
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


Instruction:
Create a Python 3 function to
map a DAGCircuit onto a CouplingMap using swap gates.

Response:
def _mapper(self, circuit_graph, coupling_graph,
                trials=20):
        """Map a DAGCircuit onto a CouplingMap using swap gates.

        Use self.initial_layout for the initial layout.

        Args:
            circuit_graph (DAGCircuit): input DAG circuit
            coupling_graph (CouplingMap): coupling graph to map onto
            trials (int): number of trials.

        Returns:
            DAGCircuit: object containing a circuit equivalent to
                circuit_graph that respects couplings in coupling_graph
            Layout: a layout object mapping qubits of circuit_graph into
                qubits of coupling_graph. The layout may differ from the
                initial_layout if the first layer of gates cannot be
                executed on the initial_layout, since in this case
                it is more efficient to modify the layout instead of swapping
            Dict: a final-layer qubit permutation

        Raises:
            TranspilerError: if there was any error during the mapping
                or with the parameters.
        """
        # Schedule the input circuit by calling layers()
        layerlist = list(circuit_graph.layers())
        logger.debug("schedule:")
        for i, v in enumerate(layerlist):
            logger.debug("    %d: %s", i, v["partition"])

        if self.initial_layout is not None:
            qubit_subset = self.initial_layout.get_virtual_bits().keys()
        else:
            # Supply a default layout for this dag
            self.initial_layout = Layout()
            physical_qubit = 0
            for qreg in circuit_graph.qregs.values():
                for index in range(qreg.size):
                    self.initial_layout[(qreg, index)] = physical_qubit
                    physical_qubit += 1
            qubit_subset = self.initial_layout.get_virtual_bits().keys()
            # Restrict the coupling map to the image of the layout
            coupling_graph = coupling_graph.subgraph(
                self.initial_layout.get_physical_bits().keys())
            if coupling_graph.size() < len(self.initial_layout):
                raise TranspilerError("Coupling map too small for default layout")
            self.input_layout = self.initial_layout.copy()

        # Find swap circuit to preceed to each layer of input circuit
        layout = self.initial_layout.copy()

        # Construct an empty DAGCircuit with the same set of
        # qregs and cregs as the input circuit
        dagcircuit_output = DAGCircuit()
        dagcircuit_output.name = circuit_graph.name
        for qreg in circuit_graph.qregs.values():
            dagcircuit_output.add_qreg(qreg)
        for creg in circuit_graph.cregs.values():
            dagcircuit_output.add_creg(creg)

        # Make a trivial wire mapping between the subcircuits
        # returned by _layer_update and the circuit we build
        identity_wire_map = {}
        for qubit in circuit_graph.qubits():
            identity_wire_map[qubit] = qubit
        for bit in circuit_graph.clbits():
            identity_wire_map[bit] = bit

        first_layer = True  # True until first layer is output
        logger.debug("initial_layout = %s", layout)

        # Iterate over layers
        for i, layer in enumerate(layerlist):

            # Attempt to find a permutation for this layer
            success_flag, best_circuit, best_depth, best_layout, trivial_flag \
                = self._layer_permutation(layer["partition"], layout,
                                          qubit_subset, coupling_graph,
                                          trials)
            logger.debug("mapper: layer %d", i)
            logger.debug("mapper: success_flag=%s,best_depth=%s,trivial_flag=%s",
                         success_flag, str(best_depth), trivial_flag)

            # If this fails, try one gate at a time in this layer
            if not success_flag:
                logger.debug("mapper: failed, layer %d, "
                             "retrying sequentially", i)
                serial_layerlist = list(layer["graph"].serial_layers())

                # Go through each gate in the layer
                for j, serial_layer in enumerate(serial_layerlist):

                    success_flag, best_circuit, best_depth, best_layout, trivial_flag = \
                        self._layer_permutation(
                            serial_layer["partition"],
                            layout, qubit_subset,
                            coupling_graph,
                            trials)
                    logger.debug("mapper: layer %d, sublayer %d", i, j)
                    logger.debug("mapper: success_flag=%s,best_depth=%s,"
                                 "trivial_flag=%s",
                                 success_flag, str(best_depth), trivial_flag)

                    # Give up if we fail again
                    if not success_flag:
                        raise TranspilerError("swap mapper failed: " +
                                              "layer %d, sublayer %d" % (i, j))

                    # If this layer is only single-qubit gates,
                    # and we have yet to see multi-qubit gates,
                    # continue to the next inner iteration
                    if trivial_flag and first_layer:
                        logger.debug("mapper: skip to next sublayer")
                        continue

                    if first_layer:
                        self.initial_layout = layout

                    # Update the record of qubit positions
                    # for each inner iteration
                    layout = best_layout
                    # Update the DAG
                    dagcircuit_output.extend_back(
                        self._layer_update(j,
                                           first_layer,
                                           best_layout,
                                           best_depth,
                                           best_circuit,
                                           serial_layerlist),
                        identity_wire_map)
                    if first_layer:
                        first_layer = False

            else:
                # Update the record of qubit positions for each iteration
                layout = best_layout

                if first_layer:
                    self.initial_layout = layout

                # Update the DAG
                dagcircuit_output.extend_back(
                    self._layer_update(i,
                                       first_layer,
                                       best_layout,
                                       best_depth,
                                       best_circuit,
                                       layerlist),
                    identity_wire_map)

                if first_layer:
                    first_layer = False

        # This is the final edgemap. We might use it to correctly replace
        # any measurements that needed to be removed earlier.
        logger.debug("mapper: self.initial_layout = %s", pformat(self.initial_layout))
        logger.debug("mapper: layout = %s", pformat(layout))
        last_edgemap = layout.combine_into_edge_map(self.initial_layout)
        logger.debug("mapper: last_edgemap = %s", pformat(last_edgemap))

        # If first_layer is still set, the circuit only has single-qubit gates
        # so we can use the initial layout to output the entire circuit
        # This code is dead due to changes to first_layer above.
        if first_layer:
            logger.debug("mapper: first_layer flag still set")
            layout = self.initial_layout
            for i, layer in enumerate(layerlist):
                edge_map = layout.combine_into_edge_map(self.initial_layout)
                dagcircuit_output.compose_back(layer["graph"], edge_map)

        return dagcircuit_output


Instruction:
How would you explain what the following Python 3 function does
def pauli_group(number_of_qubits, case='weight'):
    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")

Response: Returns the Pauli set with 4^n elements in order of the Pauli operator.


Instruction:
Given the following Python 3 function, write the documentation
def _init_from_bool(self, z, x):
        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

Response: Construct a pauli from boolean array.


Instruction:
Write a Python 3 script to
convert to Operator object.

Response:
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())


Instruction:
Can you generate the documentation for the following Python 3 function
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()

Response: Convert to Pauli circuit instruction.


Instruction:
Can you create a Python 3 function that
updates partial or entire z.

Response:
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


Instruction:
Can you implement a function in Python 3 that
updates partial or entire x.

Response:
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


Instruction:
Here you have a function in Python 3, explain what it does
def insert_paulis(self, indices=None, paulis=None, pauli_labels=None):
        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

Response: Insert or append paulis to the targeted indices.


Instruction:
Can you tell what is the following Python 3 function doing
def append_paulis(self, paulis=None, pauli_labels=None):
        return self.insert_paulis(None, paulis=paulis, pauli_labels=pauli_labels)

Response: Append paulis at the end of the list.


Instruction:
How would you explain what the following Python 3 function does
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

Response: Delete pauli at the indices.


Instruction:
Implement a Python 3 function for
returning a random Pauli on number of qubits.

Response:
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)


Instruction:
Can you create a Python 3 function that
generates a single qubit pauli at index with length num_qubits.

Response:
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)


Instruction:
Create a Python 3 function for
applying an arbitrary 1 - qubit unitary matrix.

Response:
def _add_unitary_single(self, gate, qubit):
        """Apply an arbitrary 1-qubit unitary matrix.

        Args:
            gate (matrix_like): a single qubit gate matrix
            qubit (int): the qubit to apply gate to
        """
        # Compute einsum index string for 1-qubit matrix multiplication
        indexes = einsum_vecmul_index([qubit], self._number_of_qubits)
        # Convert to complex rank-2 tensor
        gate_tensor = np.array(gate, dtype=complex)
        # Apply matrix multiplication
        self._statevector = np.einsum(indexes, gate_tensor,
                                      self._statevector,
                                      dtype=complex,
                                      casting='no')


Instruction:
Write a Python 3 function for
applying a two - qubit unitary matrix.

Response:
def _add_unitary_two(self, gate, qubit0, qubit1):
        """Apply a two-qubit unitary matrix.

        Args:
            gate (matrix_like): a the two-qubit gate matrix
            qubit0 (int): gate qubit-0
            qubit1 (int): gate qubit-1
        """
        # Compute einsum index string for 1-qubit matrix multiplication
        indexes = einsum_vecmul_index([qubit0, qubit1], self._number_of_qubits)
        # Convert to complex rank-4 tensor
        gate_tensor = np.reshape(np.array(gate, dtype=complex), 4 * [2])
        # Apply matrix multiplication
        self._statevector = np.einsum(indexes, gate_tensor,
                                      self._statevector,
                                      dtype=complex,
                                      casting='no')


Instruction:
Create a Python 3 function to
simulate the outcome of measurement of a qubit.

Response:
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]


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _add_sample_measure(self, measure_params, num_samples):
        # 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

Response: Generate memory samples from the current statevector.


Instruction:
How would you explain what the following Python 3 function does
def _add_qasm_measure(self, qubit, cmembit, cregbit=None):
        # 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)

Response: Apply a measure instruction to a qubit.


Instruction:
How would you code a function in Python 3 to
apply a reset instruction to a qubit.

Response:
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)


Instruction:
Implement a Python 3 function for
validating an initial statevector

Response:
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))


Instruction:
How would you code a function in Python 3 to
set the backend options for all experiments in a qobj

Response:
def _set_options(self, qobj_config=None, backend_options=None):
        """Set the backend options for all experiments in a qobj"""
        # Reset default options
        self._initial_statevector = self.DEFAULT_OPTIONS["initial_statevector"]
        self._chop_threshold = self.DEFAULT_OPTIONS["chop_threshold"]
        if backend_options is None:
            backend_options = {}

        # Check for custom initial statevector in backend_options first,
        # then config second
        if 'initial_statevector' in backend_options:
            self._initial_statevector = np.array(backend_options['initial_statevector'],
                                                 dtype=complex)
        elif hasattr(qobj_config, 'initial_statevector'):
            self._initial_statevector = np.array(qobj_config.initial_statevector,
                                                 dtype=complex)
        if self._initial_statevector is not None:
            # Check the initial statevector is normalized
            norm = np.linalg.norm(self._initial_statevector)
            if round(norm, 12) != 1:
                raise BasicAerError('initial statevector is not normalized: ' +
                                    'norm {} != 1'.format(norm))
        # Check for custom chop threshold
        # Replace with custom options
        if 'chop_threshold' in backend_options:
            self._chop_threshold = backend_options['chop_threshold']
        elif hasattr(qobj_config, 'chop_threshold'):
            self._chop_threshold = qobj_config.chop_threshold


Instruction:
Can you create a Python 3 function that
sets the initial statevector for simulation

Response:
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])


Instruction:
Create a Python 3 function to
return the current statevector in JSON Result spec format

Response:
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


Instruction:
How would you implement a function in Python 3 that
checks if measure sampling is allowed for an experiment. Returns True if measure sampling is allowed otherwise False.

Response:
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


Instruction:
Can you create a Python 3 function that
runs the entire experiment.

Response:
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


Instruction:
Create a Python 3 function to
run experiments in qobj

Response:
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)


Instruction:
Can you create a Python 3 function that
runs an experiment and return a single experiment result.

Response:
def run_experiment(self, experiment):
        """Run an experiment (circuit) and return a single experiment result.

        Args:
            experiment (QobjExperiment): experiment from qobj experiments list

        Returns:
             dict: A result dictionary which looks something like::

                {
                "name": name of this experiment (obtained from qobj.experiment header)
                "seed": random seed used for simulation
                "shots": number of shots used in the simulation
                "data":
                    {
                    "counts": {'0x9: 5, ...},
                    "memory": ['0x9', '0xF', '0x1D', ..., '0x9']
                    },
                "status": status string for the simulation
                "success": boolean
                "time_taken": simulation time of this single experiment
                }
        Raises:
            BasicAerError: if an error occurred.
        """
        start = time.time()
        self._number_of_qubits = experiment.config.n_qubits
        self._number_of_cmembits = experiment.config.memory_slots
        self._statevector = 0
        self._classical_memory = 0
        self._classical_register = 0
        self._sample_measure = False
        # Validate the dimension of initial statevector if set
        self._validate_initial_statevector()
        # Get the seed looking in circuit, qobj, and then random.
        if hasattr(experiment.config, 'seed'):
            seed = experiment.config.seed
        elif hasattr(self._qobj_config, 'seed'):
            seed = self._qobj_config.seed
        else:
            # For compatibility on Windows force dyte to be int32
            # and set the maximum value to be (2 ** 31) - 1
            seed = np.random.randint(2147483647, dtype='int32')

        self._local_random.seed(seed=seed)
        # Check if measure sampling is supported for current circuit
        self._validate_measure_sampling(experiment)

        # List of final counts for all shots
        memory = []
        # Check if we can sample measurements, if so we only perform 1 shot
        # and sample all outcomes from the final state vector
        if self._sample_measure:
            shots = 1
            # Store (qubit, cmembit) pairs for all measure ops in circuit to
            # be sampled
            measure_sample_ops = []
        else:
            shots = self._shots
        for _ in range(shots):
            self._initialize_statevector()
            # Initialize classical memory to all 0
            self._classical_memory = 0
            self._classical_register = 0
            for operation in experiment.instructions:
                conditional = getattr(operation, 'conditional', None)
                if isinstance(conditional, int):
                    conditional_bit_set = (self._classical_register >> conditional) & 1
                    if not conditional_bit_set:
                        continue
                elif conditional is not None:
                    mask = int(operation.conditional.mask, 16)
                    if mask > 0:
                        value = self._classical_memory & mask
                        while (mask & 0x1) == 0:
                            mask >>= 1
                            value >>= 1
                        if value != int(operation.conditional.val, 16):
                            continue

                # Check if single  gate
                if operation.name in ('U', 'u1', 'u2', 'u3'):
                    params = getattr(operation, 'params', None)
                    qubit = operation.qubits[0]
                    gate = single_gate_matrix(operation.name, params)
                    self._add_unitary_single(gate, qubit)
                # Check if CX gate
                elif operation.name in ('id', 'u0'):
                    pass
                elif operation.name in ('CX', 'cx'):
                    qubit0 = operation.qubits[0]
                    qubit1 = operation.qubits[1]
                    gate = cx_gate_matrix()
                    self._add_unitary_two(gate, qubit0, qubit1)
                # Check if reset
                elif operation.name == 'reset':
                    qubit = operation.qubits[0]
                    self._add_qasm_reset(qubit)
                # Check if barrier
                elif operation.name == 'barrier':
                    pass
                # Check if measure
                elif operation.name == 'measure':
                    qubit = operation.qubits[0]
                    cmembit = operation.memory[0]
                    cregbit = operation.register[0] if hasattr(operation, 'register') else None

                    if self._sample_measure:
                        # If sampling measurements record the qubit and cmembit
                        # for this measurement for later sampling
                        measure_sample_ops.append((qubit, cmembit))
                    else:
                        # If not sampling perform measurement as normal
                        self._add_qasm_measure(qubit, cmembit, cregbit)
                elif operation.name == 'bfunc':
                    mask = int(operation.mask, 16)
                    relation = operation.relation
                    val = int(operation.val, 16)

                    cregbit = operation.register
                    cmembit = operation.memory if hasattr(operation, 'memory') else None

                    compared = (self._classical_register & mask) - val

                    if relation == '==':
                        outcome = (compared == 0)
                    elif relation == '!=':
                        outcome = (compared != 0)
                    elif relation == '<':
                        outcome = (compared < 0)
                    elif relation == '<=':
                        outcome = (compared <= 0)
                    elif relation == '>':
                        outcome = (compared > 0)
                    elif relation == '>=':
                        outcome = (compared >= 0)
                    else:
                        raise BasicAerError('Invalid boolean function relation.')

                    # Store outcome in register and optionally memory slot
                    regbit = 1 << cregbit
                    self._classical_register = \
                        (self._classical_register & (~regbit)) | (int(outcome) << cregbit)
                    if cmembit is not None:
                        membit = 1 << cmembit
                        self._classical_memory = \
                            (self._classical_memory & (~membit)) | (int(outcome) << cmembit)
                else:
                    backend = self.name()
                    err_msg = '{0} encountered unrecognized operation "{1}"'
                    raise BasicAerError(err_msg.format(backend, operation.name))

            # Add final creg data to memory list
            if self._number_of_cmembits > 0:
                if self._sample_measure:
                    # If sampling we generate all shot samples from the final statevector
                    memory = self._add_sample_measure(measure_sample_ops, self._shots)
                else:
                    # Turn classical_memory (int) into bit string and pad zero for unused cmembits
                    outcome = bin(self._classical_memory)[2:]
                    memory.append(hex(int(outcome, 2)))

        # Add data
        data = {'counts': dict(Counter(memory))}
        # Optionally add memory list
        if self._memory:
            data['memory'] = memory
        # Optionally add final statevector
        if self.SHOW_FINAL_STATE:
            data['statevector'] = self._get_statevector()
            # Remove empty counts and memory for statevector simulator
            if not data['counts']:
                data.pop('counts')
            if 'memory' in data and not data['memory']:
                data.pop('memory')
        end = time.time()
        return {'name': experiment.header.name,
                'seed': seed,
                'shots': self._shots,
                'data': data,
                'status': 'DONE',
                'success': True,
                'time_taken': (end - start),
                'header': experiment.header.as_dict()}


Instruction:
Write a Python 3 function for
applying an arbitrary 1 - qubit unitary matrix.

Response:
def _add_unitary_single(self, gate, qubit):
        """Apply an arbitrary 1-qubit unitary matrix.

        Args:
            gate (matrix_like): a single qubit gate matrix
            qubit (int): the qubit to apply gate to
        """
        # Convert to complex rank-2 tensor
        gate_tensor = np.array(gate, dtype=complex)
        # Compute einsum index string for 1-qubit matrix multiplication
        indexes = einsum_matmul_index([qubit], self._number_of_qubits)
        # Apply matrix multiplication
        self._unitary = np.einsum(indexes, gate_tensor, self._unitary,
                                  dtype=complex, casting='no')


Instruction:
Create a Python 3 function to
apply a two - qubit unitary matrix.

Response:
def _add_unitary_two(self, gate, qubit0, qubit1):
        """Apply a two-qubit unitary matrix.

        Args:
            gate (matrix_like): a the two-qubit gate matrix
            qubit0 (int): gate qubit-0
            qubit1 (int): gate qubit-1
        """

        # Convert to complex rank-4 tensor
        gate_tensor = np.reshape(np.array(gate, dtype=complex), 4 * [2])

        # Compute einsum index string for 2-qubit matrix multiplication
        indexes = einsum_matmul_index([qubit0, qubit1], self._number_of_qubits)

        # Apply matrix multiplication
        self._unitary = np.einsum(indexes, gate_tensor, self._unitary,
                                  dtype=complex, casting='no')


Instruction:
How would you explain what the following Python 3 function does
def _validate_initial_unitary(self):
        # 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))

Response: Validate an initial unitary matrix


Instruction:
Can you generate the documentation for the following Python 3 function
def _set_options(self, qobj_config=None, backend_options=None):
        # Reset default options
        self._initial_unitary = self.DEFAULT_OPTIONS["initial_unitary"]
        self._chop_threshold = self.DEFAULT_OPTIONS["chop_threshold"]
        if backend_options is None:
            backend_options = {}

        # Check for custom initial statevector in backend_options first,
        # then config second
        if 'initial_unitary' in backend_options:
            self._initial_unitary = np.array(backend_options['initial_unitary'],
                                             dtype=complex)
        elif hasattr(qobj_config, 'initial_unitary'):
            self._initial_unitary = np.array(qobj_config.initial_unitary,
                                             dtype=complex)
        if self._initial_unitary is not None:
            # Check the initial unitary is actually unitary
            shape = np.shape(self._initial_unitary)
            if len(shape) != 2 or shape[0] != shape[1]:
                raise BasicAerError("initial unitary is not a square matrix")
            iden = np.eye(len(self._initial_unitary))
            u_dagger_u = np.dot(self._initial_unitary.T.conj(),
                                self._initial_unitary)
            norm = np.linalg.norm(u_dagger_u - iden)
            if round(norm, 10) != 0:
                raise BasicAerError("initial unitary is not unitary")
            # Check the initial statevector is normalized

        # Check for custom chop threshold
        # Replace with custom options
        if 'chop_threshold' in backend_options:
            self._chop_threshold = backend_options['chop_threshold']
        elif hasattr(qobj_config, 'chop_threshold'):
            self._chop_threshold = qobj_config.chop_threshold

Response: Set the backend options for all experiments in a qobj


Instruction:
Can you tell what is the following Python 3 function doing
def _initialize_unitary(self):
        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])

Response: Initialize the unitary for the current object


Instruction:
How would you code a function in Python 3 to
return the current unitary in JSON Result spec format

Response:
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


Instruction:
Can you write a function in Python 3 where it
runs experiments in qobj.

Response:
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)


Instruction:
Write a Python 3 script to
run an experiment and return a single experiment result.

Response:
def run_experiment(self, experiment):
        """Run an experiment (circuit) and return a single experiment result.

        Args:
            experiment (QobjExperiment): experiment from qobj experiments list

        Returns:
            dict: A result dictionary which looks something like::

                {
                "name": name of this experiment (obtained from qobj.experiment header)
                "seed": random seed used for simulation
                "shots": number of shots used in the simulation
                "data":
                    {
                    "unitary": [[[0.0, 0.0], [1.0, 0.0]],
                                [[1.0, 0.0], [0.0, 0.0]]]
                    },
                "status": status string for the simulation
                "success": boolean
                "time taken": simulation time of this single experiment
                }

        Raises:
            BasicAerError: if the number of qubits in the circuit is greater than 24.
            Note that the practical qubit limit is much lower than 24.
        """
        start = time.time()
        self._number_of_qubits = experiment.header.n_qubits

        # Validate the dimension of initial unitary if set
        self._validate_initial_unitary()
        self._initialize_unitary()

        for operation in experiment.instructions:
            # Check if single  gate
            if operation.name in ('U', 'u1', 'u2', 'u3'):
                params = getattr(operation, 'params', None)
                qubit = operation.qubits[0]
                gate = single_gate_matrix(operation.name, params)
                self._add_unitary_single(gate, qubit)
            elif operation.name in ('id', 'u0'):
                pass
            # Check if CX gate
            elif operation.name in ('CX', 'cx'):
                qubit0 = operation.qubits[0]
                qubit1 = operation.qubits[1]
                gate = cx_gate_matrix()
                self._add_unitary_two(gate, qubit0, qubit1)
            # Check if barrier
            elif operation.name == 'barrier':
                pass
            else:
                backend = self.name()
                err_msg = '{0} encountered unrecognized operation "{1}"'
                raise BasicAerError(err_msg.format(backend, operation.name))
        # Add final state to data
        data = {'unitary': self._get_unitary()}
        end = time.time()
        return {'name': experiment.header.name,
                'shots': 1,
                'data': data,
                'status': 'DONE',
                'success': True,
                'time_taken': (end - start),
                'header': experiment.header.as_dict()}


Instruction:
Make a summary of the following Python 3 code
def _validate(self, qobj):
        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)

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


Instruction:
How would you code a function in Python 3 to
determine if an object is a bit

Response:
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


Instruction:
Here you have a function in Python 3, explain what it does
def _convert_to_bits(a_list, bits):
    new_list = []
    for item in a_list:
        if isinstance(item, (int, slice)):
            # eg. circuit.h(2)
            # eg. circuit.h(slice(0, 2))
            try:
                new_list.append(bits[item])
            except IndexError:
                raise QiskitError("The integer param is out of range")
        elif isinstance(item, list):
            # eg. circuit.h([0, 2])
            new_list.append(_convert_to_bits(item, bits))
        elif isinstance(item, range):
            # eg. circuit.h(range(0, 2))
            new_list.append(_convert_to_bits([index for index in item], bits))
        else:
            new_list.append(item)
    return new_list

Response: Recursively converts integers tuples and ranges in a_list to bits.


Instruction:
Implement a function in Python 3 to
convert gate arguments to [ qu|cl bits ] from integers slices ranges etc.

Response:
def _to_bits(nqbits, ncbits=0, func=None):
    """Convert gate arguments to [qu|cl]bits from integers, slices, ranges, etc.
    For example circuit.h(0) -> circuit.h(QuantumRegister(2)[0]) """
    if func is None:
        return functools.partial(_to_bits, nqbits, ncbits)

    @functools.wraps(func)
    def wrapper(self, *args):
        qbits = self.qubits()
        cbits = self.clbits()

        nparams = len(args) - nqbits - ncbits
        params = args[:nparams]
        qb_args = args[nparams:nparams + nqbits]
        cl_args = args[nparams + nqbits:]

        args = list(params) + _convert_to_bits(qb_args, qbits) + _convert_to_bits(cl_args, cbits)

        return func(self, *args)

    return wrapper


Instruction:
Can you tell what is the following Python 3 function doing
def to_matrix(self):
        lam = self.params[0]
        lam = float(lam)
        return numpy.array([[1, 0], [0, numpy.exp(1j * lam)]], dtype=complex)

Response: Return a Numpy. array for the U3 gate.


Instruction:
Can you tell what is the following Python 3 function doing
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())

Response: Run the layout algorithm.


Instruction:
Can you implement a function in Python 3 that
checks if self has overlap with interval.

Response:
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


Instruction:
Can you generate a brief explanation for the following Python 3 code
def shift(self, time: int) -> 'Interval':
        return Interval(self._begin + time, self._end + time)

Response: Return a new interval shifted by time from self.


Instruction:
Can you write a function in Python 3 where it
returns a new Timeslot shifted by time.

Response:
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)


Instruction:
Can you create a Python 3 function that
returns the earliest start time in this collection.

Response:
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


Instruction:
Make a summary of the following Python 3 code
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

Response: Return the maximum time of timeslots over all channels.


Instruction:
Explain what the following Python 3 code does
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

Response: Return if self is mergeable with timeslots.


Instruction:
Can you generate a brief explanation for the following Python 3 code
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)

Response: Returns a new TimeslotCollection merged with a specified timeslots


Instruction:
Explain what the following Python 3 code does
def shift(self, time: int) -> 'TimeslotCollection':
        slots = [Timeslot(slot.interval.shift(time), slot.channel) for slot in self.timeslots]
        return TimeslotCollection(*slots)

Response: Return a new TimeslotCollection shifted by time.


Instruction:
Given the following Python 3 function, write the documentation
def real(self, nested_scope=None):
        op = self.children[0].name
        expr = self.children[1]
        dispatch = {
            'sin': sympy.sin,
            'cos': sympy.cos,
            'tan': sympy.tan,
            'asin': sympy.asin,
            'acos': sympy.acos,
            'atan': sympy.atan,
            'exp': sympy.exp,
            'ln': sympy.log,
            'sqrt': sympy.sqrt
        }
        if op in dispatch:
            arg = expr.real(nested_scope)
            return dispatch[op](arg)
        else:
            raise NodeException("internal error: undefined external")

Response: Return the correspond floating point number.