Пример #1
0
    def repeat(self, n):
        """Creates an instruction with `gate` repeated `n` amount of times.

        Args:
            n (int): Number of times to repeat the instruction

        Returns:
            Instruction: Containing the definition.

        Raises:
            CircuitError: If n < 1.
        """
        if int(n) != n or n < 1:
            raise CircuitError(
                "Repeat can only be called with strictly positive integer.")

        n = int(n)

        instruction = self._return_repeat(n)
        qargs = [] if self.num_qubits == 0 else QuantumRegister(
            self.num_qubits, 'q')
        cargs = [] if self.num_clbits == 0 else ClassicalRegister(
            self.num_clbits, 'c')

        instruction.definition = [(self, qargs[:], cargs[:])] * n
        return instruction
Пример #2
0
    def repeat(self, n):
        """Creates an instruction with `gate` repeated `n` amount of times.

        Args:
            n (int): Number of times to repeat the instruction

        Returns:
            qiskit.circuit.Instruction: Containing the definition.

        Raises:
            CircuitError: If n < 1.
        """
        if int(n) != n or n < 1:
            raise CircuitError(
                "Repeat can only be called with strictly positive integer.")

        n = int(n)

        instruction = self._return_repeat(n)
        qargs = [] if self.num_qubits == 0 else QuantumRegister(
            self.num_qubits, 'q')
        cargs = [] if self.num_clbits == 0 else ClassicalRegister(
            self.num_clbits, 'c')

        if instruction.definition is None:
            # pylint: disable=cyclic-import
            from qiskit import QuantumCircuit
            qc = QuantumCircuit()
            if qargs:
                qc.add_register(qargs)
            if cargs:
                qc.add_register(cargs)
            qc.data = [(self, qargs[:], cargs[:])] * n
        instruction.definition = qc
        return instruction
Пример #3
0
def _experiments_to_circuits(qobj):
    """Return a list of QuantumCircuit object(s) from a qobj

    Args:
        qobj (Qobj): The Qobj object to convert to QuantumCircuits
    Returns:
        list: A list of QuantumCircuit objects from the qobj

    """
    if qobj.experiments:
        circuits = []
        for x in qobj.experiments:
            quantum_registers = [
                QuantumRegister(i[1], name=i[0]) for i in x.header.qreg_sizes
            ]
            classical_registers = [
                ClassicalRegister(i[1], name=i[0]) for i in x.header.creg_sizes
            ]
            circuit = QuantumCircuit(*quantum_registers,
                                     *classical_registers,
                                     name=x.header.name)
            qreg_dict = {}
            creg_dict = {}
            for reg in quantum_registers:
                qreg_dict[reg.name] = reg
            for reg in classical_registers:
                creg_dict[reg.name] = reg
            for i in x.instructions:
                instr_method = getattr(circuit, i.name)
                qubits = []
                try:
                    for qubit in i.qubits:
                        qubit_label = x.header.qubit_labels[qubit]
                        qubits.append(
                            qreg_dict[qubit_label[0]][qubit_label[1]])
                except Exception:  # pylint: disable=broad-except
                    pass
                clbits = []
                try:
                    for clbit in i.memory:
                        clbit_label = x.header.clbit_labels[clbit]
                        clbits.append(
                            creg_dict[clbit_label[0]][clbit_label[1]])
                except Exception:  # pylint: disable=broad-except
                    pass
                params = []
                try:
                    params = i.params
                except Exception:  # pylint: disable=broad-except
                    pass
                if i.name in ['snapshot']:
                    instr_method(*params)
                elif i.name == 'initialize':
                    instr_method(params, qubits)
                else:
                    instr_method(*params, *qubits, *clbits)
            circuits.append(circuit)
        return circuits
    return None
Пример #4
0
    def construct_circuit(
        self,
        unitary: QuantumCircuit,
        state_preparation: QuantumCircuit,
        k: int,
        omega: float = 0,
        measurement: bool = False,
    ) -> QuantumCircuit:
        """Construct the kth iteration Quantum Phase Estimation circuit.

        For details of parameters, see Fig. 2 in https://arxiv.org/pdf/quant-ph/0610214.pdf.

        Args:
            unitary: The circuit representing the unitary operator whose eigenvalue (via phase)
                     will be measured.
            state_preparation: The circuit that prepares the state whose eigenphase will be
                     measured.  If this parameter is omitted, no preparation circuit
                     will be run and input state will be the all-zero state in the
                     computational basis.
            k: the iteration idx.
            omega: the feedback angle.
            measurement: Boolean flag to indicate if measurement should
                    be included in the circuit.

        Returns:
            QuantumCircuit: the quantum circuit per iteration
        """
        k = self._num_iterations if k is None else k
        # The auxiliary (phase measurement) qubit
        phase_register = QuantumRegister(1, name="a")
        eigenstate_register = QuantumRegister(unitary.num_qubits, name="q")
        qc = QuantumCircuit(eigenstate_register)
        qc.add_register(phase_register)
        if isinstance(state_preparation, QuantumCircuit):
            qc.append(state_preparation, eigenstate_register)
        elif state_preparation is not None:
            qc += state_preparation.construct_circuit("circuit",
                                                      eigenstate_register)
        # hadamard on phase_register[0]
        qc.h(phase_register[0])
        # controlled-U
        # TODO: We may want to allow flexibility in how the power is computed
        # For example, it may be desirable to compute the power via Trotterization, if
        # we are doing Trotterization anyway.
        unitary_power = unitary.power(2**(k - 1)).control()
        qc = qc.compose(unitary_power,
                        list(range(1, unitary.num_qubits + 1)) + [0])
        qc.p(omega, phase_register[0])
        # hadamard on phase_register[0]
        qc.h(phase_register[0])
        if measurement:
            c = ClassicalRegister(1, name="c")
            qc.add_register(c)
            qc.measure(phase_register, c)
        return qc
Пример #5
0
    def _add_measurement_if_required(self, pe_circuit):
        if not self._quantum_instance.is_statevector:
            # Measure only the evaluation qubits.
            regname = "meas"
            creg = ClassicalRegister(self._num_evaluation_qubits, regname)
            pe_circuit.add_register(creg)
            pe_circuit.barrier()
            pe_circuit.measure(range(self._num_evaluation_qubits),
                               range(self._num_evaluation_qubits))

        return circuit
Пример #6
0
def circuit_to_instruction(circuit):
    """Build an ``Instruction`` object from a ``QuantumCircuit``.

    The instruction is anonymous (not tied to a named quantum register),
    and so can be inserted into another circuit. The instruction will
    have the same string name as the circuit.

    Args:
        circuit (QuantumCircuit): the input circuit.

    Return:
        Instruction: an instruction equivalent to the action of the
            input circuit. Upon decomposition, this instruction will
            yield the components comprising the original circuit.
    """
    instruction = Instruction(
        name=circuit.name,
        num_qubits=sum([qreg.size for qreg in circuit.qregs]),
        num_clbits=sum([creg.size for creg in circuit.cregs]),
        params=[])
    instruction.control = None

    def find_bit_position(bit):
        """find the index of a given bit (Register, int) within
        a flat ordered list of bits of the circuit
        """
        if isinstance(bit[0], QuantumRegister):
            ordered_regs = circuit.qregs
        else:
            ordered_regs = circuit.cregs
        reg_index = ordered_regs.index(bit[0])
        return sum([reg.size for reg in ordered_regs[:reg_index]]) + bit[1]

    definition = circuit.data.copy()

    if instruction.num_qubits > 0:
        q = QuantumRegister(instruction.num_qubits, 'q')
    if instruction.num_clbits > 0:
        c = ClassicalRegister(instruction.num_clbits, 'c')

    definition = list(
        map(
            lambda x:
            (x[0], list(map(lambda y: (q, find_bit_position(y)), x[1])),
             list(map(lambda y:
                      (c, find_bit_position(y)), x[2]))), definition))
    instruction.definition = definition

    return instruction
Пример #7
0
    def extend_back(self, dag, edge_map=None):
        """Add `dag` at the end of `self`, using `edge_map`.
        """
        edge_map = edge_map or {}
        for qreg in dag.qregs.values():
            if qreg.name not in self.qregs:
                self.add_qreg(QuantumRegister(qreg.size, qreg.name))
            edge_map.update([(qbit, qbit) for qbit in qreg if qbit not in edge_map])

        for creg in dag.cregs.values():
            if creg.name not in self.cregs:
                self.add_creg(ClassicalRegister(creg.size, creg.name))
            edge_map.update([(cbit, cbit) for cbit in creg if cbit not in edge_map])

        self.compose_back(dag, edge_map)
Пример #8
0
 def __init__(self, graph):
     super().__init__()
     assert isinstance(graph, nx.Graph) or isinstance(graph, nx.DiGraph), \
         ValueError("Graphs have to be networkx.Graph() or networkx.DiGraph()")
     self.graph = graph
     # Create a quantum register based on the number of nodes in G
     self.qreg = QuantumRegister(len(self.graph.nodes))
     self.creg = ClassicalRegister(len(self.graph.nodes))
     # Create a circuit using the quantum register
     self.circuit = QuantumCircuit(self.qreg, self.creg)
     # For each vertex, apply a Hadamard gate
     for vertex in self.graph.nodes:
         self.circuit.h(vertex)
     # For each edge e={x,y} apply a controlled-Z gate on its vertices
     for x, y in self.graph.edges:
         self.circuit.cz(x, y)
     #         create a node dictionary from node to integer index of a qubit
     #         in a Qiskit circuit
     self.node_dict = dict()
     for count, node in enumerate(self.graph.nodes):
         self.node_dict[node] = count
Пример #9
0
def power(circ, a, b, finalOut): #Because this is reversible/gate friendly memory blooms to say the least
    # Track Number of Qubits
    n = len(a)
    v = len(b)

    # Left 0 pad a, to satisfy multiplication function arguments
    aPad = AncillaRegister(2)
    circ.add_register(aPad)
    padAList = full_qr(aPad)
    aList = full_qr(a)
    a = aList + padAList
    
    # Create zero bits
    num_recycle = 2
    permaZeros = []
    if num_recycle > 0:
        permaZeros = AncillaRegister(num_recycle) #8
        circ.add_register(permaZeros)
        permaZeros = full_qr(permaZeros)
        finalOut = full_qr(finalOut) + permaZeros
    
    # Create a register d for mults and init with state 1
    d = AncillaRegister(len(finalOut)) # Unsure of where to Anciallas these
    circ.add_register(d)
    circ.x(d[0])

    r = 2
    # iterate through every qubit of b
    for i in range(0,v): # for every bit of b 
        cmult(circ, [b[i]], a[:r], d[:r], finalOut[:r * 2], r)
        for swap_target in range(0, r*2):
            circ.cswap(b[i], d[swap_target], finalOut[swap_target])
        circ.cx(b[i], finalOut[0])

        r *= 2
    
    cd = ClassicalRegister(len(d))
    circ.add_register(cd)
    circ.measure(d, cd)
Пример #10
0
def _read_registers(file_obj, num_registers):
    registers = {"q": {}, "c": {}}
    for _reg in range(num_registers):
        register_raw = file_obj.read(REGISTER_SIZE)
        register = struct.unpack(REGISTER_PACK, register_raw)
        name = file_obj.read(register[2]).decode("utf8")
        REGISTER_ARRAY_PACK = "%sI" % register[1]
        bit_indices_raw = file_obj.read(struct.calcsize(REGISTER_ARRAY_PACK))
        bit_indices = struct.unpack(REGISTER_ARRAY_PACK, bit_indices_raw)
        if register[0].decode("utf8") == "q":
            registers["q"][name] = {}
            registers["q"][name]["register"] = QuantumRegister(
                register[1], name)
            registers["q"][name]["index_map"] = dict(
                zip(bit_indices, registers["q"][name]["register"]))
        else:
            registers["c"][name] = {}
            registers["c"][name]["register"] = ClassicalRegister(
                register[1], name)
            registers["c"][name]["index_map"] = dict(
                zip(bit_indices, registers["c"][name]["register"]))
    return registers
def circuit_to_instruction(circuit, parameter_map=None, equivalence_library=None, label=None):
    """Build an ``Instruction`` object from a ``QuantumCircuit``.

    The instruction is anonymous (not tied to a named quantum register),
    and so can be inserted into another circuit. The instruction will
    have the same string name as the circuit.

    Args:
        circuit (QuantumCircuit): the input circuit.
        parameter_map (dict): For parameterized circuits, a mapping from
           parameters in the circuit to parameters to be used in the instruction.
           If None, existing circuit parameters will also parameterize the
           instruction.
        equivalence_library (EquivalenceLibrary): Optional equivalence library
           where the converted instruction will be registered.
        label (str): Optional instruction label.

    Raises:
        QiskitError: if parameter_map is not compatible with circuit

    Return:
        qiskit.circuit.Instruction: an instruction equivalent to the action of the
        input circuit. Upon decomposition, this instruction will
        yield the components comprising the original circuit.

    Example:
        .. jupyter-execute::

            from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
            from qiskit.converters import circuit_to_instruction
            %matplotlib inline

            q = QuantumRegister(3, 'q')
            c = ClassicalRegister(3, 'c')
            circ = QuantumCircuit(q, c)
            circ.h(q[0])
            circ.cx(q[0], q[1])
            circ.measure(q[0], c[0])
            circ.rz(0.5, q[1]).c_if(c, 2)
            circuit_to_instruction(circ)
    """
    # pylint: disable=cyclic-import
    from qiskit.circuit.quantumcircuit import QuantumCircuit

    if parameter_map is None:
        parameter_dict = {p: p for p in circuit.parameters}
    else:
        parameter_dict = circuit._unroll_param_dict(parameter_map)

    if parameter_dict.keys() != circuit.parameters:
        raise QiskitError(
            (
                "parameter_map should map all circuit parameters. "
                "Circuit parameters: {}, parameter_map: {}"
            ).format(circuit.parameters, parameter_dict)
        )

    instruction = Instruction(
        name=circuit.name,
        num_qubits=sum(qreg.size for qreg in circuit.qregs),
        num_clbits=sum(creg.size for creg in circuit.cregs),
        params=[*parameter_dict.values()],
        label=label,
    )
    instruction.condition = None

    target = circuit.assign_parameters(parameter_dict, inplace=False)

    if equivalence_library is not None:
        equivalence_library.add_equivalence(instruction, target)

    definition = target.data

    regs = []
    if instruction.num_qubits > 0:
        q = QuantumRegister(instruction.num_qubits, "q")
        regs.append(q)

    if instruction.num_clbits > 0:
        c = ClassicalRegister(instruction.num_clbits, "c")
        regs.append(c)

    qubit_map = {bit: q[idx] for idx, bit in enumerate(circuit.qubits)}
    clbit_map = {bit: c[idx] for idx, bit in enumerate(circuit.clbits)}

    definition = [
        (inst, [qubit_map[y] for y in qargs], [clbit_map[y] for y in cargs])
        for inst, qargs, cargs in definition
    ]

    # fix condition
    for rule in definition:
        condition = rule[0].condition
        if condition:
            reg, val = condition
            if isinstance(reg, Clbit):
                idx = 0
                for creg in circuit.cregs:
                    if reg not in creg:
                        idx += creg.size
                    else:
                        cond_reg = creg
                        break
                rule[0].condition = (c[idx + list(cond_reg).index(reg)], val)
            elif reg.size == c.size:
                rule[0].condition = (c, val)
            else:
                raise QiskitError(
                    "Cannot convert condition in circuit with "
                    "multiple classical registers to instruction"
                )

    qc = QuantumCircuit(*regs, name=instruction.name)
    for instr, qargs, cargs in definition:
        qc._append(instr, qargs, cargs)
    if circuit.global_phase:
        qc.global_phase = circuit.global_phase

    instruction.definition = qc

    return instruction
Пример #12
0
def _experiments_to_circuits(qobj):
    """Return a list of QuantumCircuit object(s) from a qobj.

    Args:
        qobj (Qobj): The Qobj object to convert to QuantumCircuits

    Returns:
        list: A list of QuantumCircuit objects from the qobj
    """
    if not qobj.experiments:
        return None

    circuits = []
    for exp in qobj.experiments:
        quantum_registers = [QuantumRegister(i[1], name=i[0]) for i in exp.header.qreg_sizes]
        classical_registers = [ClassicalRegister(i[1], name=i[0]) for i in exp.header.creg_sizes]
        circuit = QuantumCircuit(*quantum_registers, *classical_registers, name=exp.header.name)
        qreg_dict = collections.OrderedDict()
        creg_dict = collections.OrderedDict()
        for reg in quantum_registers:
            qreg_dict[reg.name] = reg
        for reg in classical_registers:
            creg_dict[reg.name] = reg
        conditional = {}
        for i in exp.instructions:
            name = i.name
            qubits = []
            params = getattr(i, "params", [])
            try:
                for qubit in i.qubits:
                    qubit_label = exp.header.qubit_labels[qubit]
                    qubits.append(qreg_dict[qubit_label[0]][qubit_label[1]])
            except Exception:  # pylint: disable=broad-except
                pass
            clbits = []
            try:
                for clbit in i.memory:
                    clbit_label = exp.header.clbit_labels[clbit]
                    clbits.append(creg_dict[clbit_label[0]][clbit_label[1]])
            except Exception:  # pylint: disable=broad-except
                pass
            if hasattr(circuit, name):
                instr_method = getattr(circuit, name)
                if i.name in ["snapshot"]:
                    _inst = instr_method(
                        i.label, snapshot_type=i.snapshot_type, qubits=qubits, params=params
                    )
                elif i.name == "initialize":
                    _inst = instr_method(params, qubits)
                elif i.name == "isometry":
                    _inst = instr_method(*params, qubits, clbits)
                elif i.name in ["mcx", "mcu1", "mcp"]:
                    _inst = instr_method(*params, qubits[:-1], qubits[-1], *clbits)
                else:
                    _inst = instr_method(*params, *qubits, *clbits)
            elif name == "bfunc":
                conditional["value"] = int(i.val, 16)
                full_bit_size = sum(creg_dict[x].size for x in creg_dict)
                mask_map = {}
                raw_map = {}
                raw = []

                for creg in creg_dict:
                    size = creg_dict[creg].size
                    reg_raw = [1] * size
                    if not raw:
                        raw = reg_raw
                    else:
                        for pos, val in enumerate(raw):
                            if val == 1:
                                raw[pos] = 0
                        raw = reg_raw + raw
                    mask = [0] * (full_bit_size - len(raw)) + raw
                    raw_map[creg] = mask
                    mask_map[int("".join(str(x) for x in mask), 2)] = creg
                creg = mask_map[int(i.mask, 16)]
                conditional["register"] = creg_dict[creg]
                val = int(i.val, 16)
                mask = raw_map[creg]
                for j in reversed(mask):
                    if j == 0:
                        val = val >> 1
                    else:
                        conditional["value"] = val
                        break
            else:
                _inst = temp_opaque_instruction = Instruction(
                    name=name, num_qubits=len(qubits), num_clbits=len(clbits), params=params
                )
                circuit.append(temp_opaque_instruction, qubits, clbits)
            if conditional and name != "bfunc":
                _inst.c_if(conditional["register"], conditional["value"])
                conditional = {}
        pulse_lib = qobj.config.pulse_library if hasattr(qobj.config, "pulse_library") else []
        parametric_pulses = (
            qobj.config.parametric_pulses if hasattr(qobj.config, "parametric_pulses") else []
        )
        # The dict update method did not work here; could investigate in the future
        if hasattr(qobj.config, "calibrations"):
            circuit.calibrations = dict(
                **circuit.calibrations, **_qobj_to_circuit_cals(qobj, pulse_lib, parametric_pulses)
            )
        if hasattr(exp.config, "calibrations"):
            circuit.calibrations = dict(
                **circuit.calibrations, **_qobj_to_circuit_cals(exp, pulse_lib, parametric_pulses)
            )
        circuits.append(circuit)
    return circuits
Пример #13
0
    def run(self, dag):
        """Run the ConsolidateBlocks pass on `dag`.

        Iterate over each block and replace it with an equivalent Unitary
        on the same wires.
        """
        if self.decomposer is None:
            return dag

        # compute ordered indices for the global circuit wires
        global_index_map = {wire: idx for idx, wire in enumerate(dag.qubits)}
        blocks = self.property_set["block_list"]
        basis_gate_name = self.decomposer.gate.name
        all_block_gates = set()
        for block in blocks:
            if len(block) == 1 and (self.basis_gates and block[0].name not in self.basis_gates):
                all_block_gates.add(block[0])
                dag.substitute_node(block[0], UnitaryGate(block[0].op.to_matrix()))
            else:
                basis_count = 0
                outside_basis = False
                block_qargs = set()
                block_cargs = set()
                for nd in block:
                    block_qargs |= set(nd.qargs)
                    if isinstance(nd, DAGOpNode) and nd.op.condition:
                        block_cargs |= set(nd.op.condition[0])
                    all_block_gates.add(nd)
                q = QuantumRegister(len(block_qargs))
                qc = QuantumCircuit(q)
                if block_cargs:
                    c = ClassicalRegister(len(block_cargs))
                    qc.add_register(c)
                block_index_map = self._block_qargs_to_indices(block_qargs, global_index_map)
                for nd in block:
                    if nd.op.name == basis_gate_name:
                        basis_count += 1
                    if self.basis_gates and nd.op.name not in self.basis_gates:
                        outside_basis = True
                    qc.append(nd.op, [q[block_index_map[i]] for i in nd.qargs])
                unitary = UnitaryGate(Operator(qc))

                max_2q_depth = 20  # If depth > 20, there will be 1q gates to consolidate.
                if (  # pylint: disable=too-many-boolean-expressions
                    self.force_consolidate
                    or unitary.num_qubits > 2
                    or self.decomposer.num_basis_gates(unitary) < basis_count
                    or len(block) > max_2q_depth
                    or (self.basis_gates is not None and outside_basis)
                ):
                    dag.replace_block_with_op(block, unitary, block_index_map, cycle_check=False)
        # If 1q runs are collected before consolidate those too
        runs = self.property_set["run_list"] or []
        for run in runs:
            if run[0] in all_block_gates:
                continue
            if len(run) == 1 and self.basis_gates and run[0].name not in self.basis_gates:
                dag.substitute_node(run[0], UnitaryGate(run[0].op.to_matrix()))
            else:
                qubit = run[0].qargs[0]
                operator = run[0].op.to_matrix()
                already_in_block = False
                for gate in run[1:]:
                    if gate in all_block_gates:
                        already_in_block = True
                    operator = gate.op.to_matrix().dot(operator)
                if already_in_block:
                    continue
                unitary = UnitaryGate(operator)
                dag.replace_block_with_op(run, unitary, {qubit: 0}, cycle_check=False)
        return dag
Пример #14
0
def complete_meas_cal(
    qubit_list: List[int] = None,
    qr: Union[int, List["QuantumRegister"]] = None,
    cr: Union[int, List["ClassicalRegister"]] = None,
    circlabel: str = "",
) -> Tuple[List["QuantumCircuit"], List[str]]:
    """
    Return a list of measurement calibration circuits for the full
    Hilbert space.

    If the circuit contains :math:`n` qubits, then :math:`2^n` calibration circuits
    are created, each of which creates a basis state.

    Args:
        qubit_list: A list of qubits to perform the measurement correction on.
           If `None`, and qr is given then assumed to be performed over the entire
           qr. The calibration states will be labelled according to this ordering (default `None`).

        qr: Quantum registers (or their size).
            If ``None``, one is created (default ``None``).

        cr: Classical registers (or their size).
            If ``None``, one is created(default ``None``).

        circlabel: A string to add to the front of circuit names for
            unique identification(default ' ').

    Returns:
        A list of QuantumCircuit objects containing the calibration circuits.

        A list of calibration state labels.

    Additional Information:
        The returned circuits are named circlabel+cal_XXX
        where XXX is the basis state,
        e.g., cal_1001.

        Pass the results of these circuits to the CompleteMeasurementFitter
        constructor.

    Raises:
        QiskitError: if both `qubit_list` and `qr` are `None`.

    """
    # Runtime imports to avoid circular imports causeed by QuantumInstance
    # getting initialized by imported utils/__init__ which is imported
    # by qiskit.circuit
    from qiskit.circuit.quantumregister import QuantumRegister
    from qiskit.circuit.classicalregister import ClassicalRegister
    from qiskit.circuit.exceptions import QiskitError

    if qubit_list is None and qr is None:
        raise QiskitError("Must give one of a qubit_list or a qr")

    # Create the registers if not already done
    if qr is None:
        qr = QuantumRegister(max(qubit_list) + 1)

    if isinstance(qr, int):
        qr = QuantumRegister(qr)

    if qubit_list is None:
        qubit_list = range(len(qr))

    if isinstance(cr, int):
        cr = ClassicalRegister(cr)

    nqubits = len(qubit_list)

    # labels for 2**n qubit states
    state_labels = count_keys(nqubits)

    cal_circuits, _ = tensored_meas_cal([qubit_list], qr, cr, circlabel)

    return cal_circuits, state_labels
Пример #15
0
def circuit_to_instruction(circuit, parameter_map=None):
    """Build an ``Instruction`` object from a ``QuantumCircuit``.

    The instruction is anonymous (not tied to a named quantum register),
    and so can be inserted into another circuit. The instruction will
    have the same string name as the circuit.

    Args:
        circuit (QuantumCircuit): the input circuit.
        parameter_map (dict): For parameterized circuits, a mapping from
           parameters in the circuit to parameters to be used in the instruction.
           If None, existing circuit parameters will also parameterize the
           instruction.

    Raises:
        QiskitError: if parameter_map is not compatible with circuit

    Return:
        Instruction: an instruction equivalent to the action of the
            input circuit. Upon decomposition, this instruction will
            yield the components comprising the original circuit.
    """

    if parameter_map is None:
        parameter_map = {p: p for p in circuit.parameters}

    if parameter_map.keys() != circuit.parameters:
        raise QiskitError(('parameter_map should map all circuit parameters. '
                           'Circuit parameters: {}, parameter_map: {}').format(
                               circuit.parameters, parameter_map))

    instruction = Instruction(name=circuit.name,
                              num_qubits=sum([qreg.size for qreg in circuit.qregs]),
                              num_clbits=sum([creg.size for creg in circuit.cregs]),
                              params=sorted(parameter_map.values(), key=lambda p: p.name))
    instruction.control = None

    def find_bit_position(bit):
        """find the index of a given bit (Register, int) within
        a flat ordered list of bits of the circuit
        """
        if isinstance(bit[0], QuantumRegister):
            ordered_regs = circuit.qregs
        else:
            ordered_regs = circuit.cregs
        reg_index = ordered_regs.index(bit[0])
        return sum([reg.size for reg in ordered_regs[:reg_index]]) + bit[1]

    target = circuit.copy()
    target._substitute_parameters(parameter_map)

    definition = target.data

    if instruction.num_qubits > 0:
        q = QuantumRegister(instruction.num_qubits, 'q')
    if instruction.num_clbits > 0:
        c = ClassicalRegister(instruction.num_clbits, 'c')

    definition = list(map(lambda x:
                          (x[0],
                           list(map(lambda y: (q, find_bit_position(y)), x[1])),
                           list(map(lambda y: (c, find_bit_position(y)), x[2]))), definition))
    instruction.definition = definition

    return instruction
 def test_x_measurement(self):
     """this will give you something different every time,
      so don't try to test the exact answer"""
     a = GraphState(self.G)
     a.x_measurement(a.qreg[0], a.creg[0])
     assert isinstance(a.creg[0], type(Clbit(ClassicalRegister(3, 'c2'), 0)))
Пример #17
0
def tensored_meas_cal(
    mit_pattern: List[List[int]] = None,
    qr: Union[int, List["QuantumRegister"]] = None,
    cr: Union[int, List["ClassicalRegister"]] = None,
    circlabel: str = "",
) -> Tuple[List["QuantumCircuit"], List[List[int]]]:
    """
    Return a list of calibration circuits

    Args:
        mit_pattern: Qubits on which to perform the
            measurement correction, divided to groups according to tensors.
            If `None` and `qr` is given then assumed to be performed over the entire
            `qr` as one group (default `None`).

        qr: A quantum register (or its size).
        If `None`, one is created (default `None`).

        cr: A classical register (or its size).
        If `None`, one is created (default `None`).

        circlabel: A string to add to the front of circuit names for
            unique identification (default ' ').

    Returns:
        A list of two QuantumCircuit objects containing the calibration circuits
        mit_pattern

    Additional Information:
        The returned circuits are named circlabel+cal_XXX
        where XXX is the basis state,
        e.g., cal_000 and cal_111.

        Pass the results of these circuits to the TensoredMeasurementFitter
        constructor.

    Raises:
        QiskitError: if both `mit_pattern` and `qr` are None.
        QiskitError: if a qubit appears more than once in `mit_pattern`.

    """
    # Runtime imports to avoid circular imports causeed by QuantumInstance
    # getting initialized by imported utils/__init__ which is imported
    # by qiskit.circuit
    from qiskit.circuit.quantumregister import QuantumRegister
    from qiskit.circuit.classicalregister import ClassicalRegister
    from qiskit.circuit.quantumcircuit import QuantumCircuit
    from qiskit.circuit.exceptions import QiskitError

    if mit_pattern is None and qr is None:
        raise QiskitError("Must give one of mit_pattern or qr")

    if isinstance(qr, int):
        qr = QuantumRegister(qr)

    qubits_in_pattern = []
    if mit_pattern is not None:
        for qubit_list in mit_pattern:
            for qubit in qubit_list:
                if qubit in qubits_in_pattern:
                    raise QiskitError(
                        "mit_pattern cannot contain multiple instances of the same qubit"
                    )
                qubits_in_pattern.append(qubit)

        # Create the registers if not already done
        if qr is None:
            qr = QuantumRegister(max(qubits_in_pattern) + 1)
    else:
        qubits_in_pattern = range(len(qr))
        mit_pattern = [qubits_in_pattern]

    nqubits = len(qubits_in_pattern)

    # create classical bit registers
    if cr is None:
        cr = ClassicalRegister(nqubits)

    if isinstance(cr, int):
        cr = ClassicalRegister(cr)

    qubits_list_sizes = [len(qubit_list) for qubit_list in mit_pattern]
    nqubits = sum(qubits_list_sizes)
    size_of_largest_group = max(qubits_list_sizes)
    largest_labels = count_keys(size_of_largest_group)

    state_labels = []
    for largest_state in largest_labels:
        basis_state = ""
        for list_size in qubits_list_sizes:
            basis_state = largest_state[:list_size] + basis_state
        state_labels.append(basis_state)

    cal_circuits = []
    for basis_state in state_labels:
        qc_circuit = QuantumCircuit(qr,
                                    cr,
                                    name=f"{circlabel}cal_{basis_state}")

        end_index = nqubits
        for qubit_list, list_size in zip(mit_pattern, qubits_list_sizes):

            start_index = end_index - list_size
            substate = basis_state[start_index:end_index]

            for qind in range(list_size):
                if substate[list_size - qind - 1] == "1":
                    qc_circuit.x(qr[qubit_list[qind]])

            end_index = start_index

        qc_circuit.barrier(qr)

        # add measurements
        end_index = nqubits
        for qubit_list, list_size in zip(mit_pattern, qubits_list_sizes):

            for qind in range(list_size):
                qc_circuit.measure(qr[qubit_list[qind]],
                                   cr[nqubits - (end_index - qind)])

            end_index -= list_size

        cal_circuits.append(qc_circuit)

    return cal_circuits, mit_pattern
Пример #18
0
def _experiments_to_circuits(qobj):
    """Return a list of QuantumCircuit object(s) from a qobj

    Args:
        qobj (Qobj): The Qobj object to convert to QuantumCircuits

    Returns:
        list: A list of QuantumCircuit objects from the qobj
    """
    if qobj.experiments:
        circuits = []
        for x in qobj.experiments:
            quantum_registers = [
                QuantumRegister(i[1], name=i[0]) for i in x.header.qreg_sizes
            ]
            classical_registers = [
                ClassicalRegister(i[1], name=i[0]) for i in x.header.creg_sizes
            ]
            circuit = QuantumCircuit(*quantum_registers,
                                     *classical_registers,
                                     name=x.header.name)
            qreg_dict = {}
            creg_dict = {}
            for reg in quantum_registers:
                qreg_dict[reg.name] = reg
            for reg in classical_registers:
                creg_dict[reg.name] = reg
            for i in x.instructions:
                name = i.name
                if i.name == 'id':
                    name = 'iden'
                qubits = []
                params = getattr(i, 'params', [])
                try:
                    for qubit in i.qubits:
                        qubit_label = x.header.qubit_labels[qubit]
                        qubits.append(
                            qreg_dict[qubit_label[0]][qubit_label[1]])
                except Exception:  # pylint: disable=broad-except
                    pass
                clbits = []
                try:
                    for clbit in i.memory:
                        clbit_label = x.header.clbit_labels[clbit]
                        clbits.append(
                            creg_dict[clbit_label[0]][clbit_label[1]])
                except Exception:  # pylint: disable=broad-except
                    pass
                if hasattr(circuit, name):
                    instr_method = getattr(circuit, name)
                    if i.name in ['snapshot']:
                        instr_method(i.label,
                                     snapshot_type=i.snapshot_type,
                                     qubits=qubits,
                                     params=params)
                    elif i.name == 'initialize':
                        instr_method(params, qubits)
                    else:
                        instr_method(*params, *qubits, *clbits)
                else:
                    temp_opaque_instruction = Instruction(
                        name=name,
                        num_qubits=len(qubits),
                        num_clbits=len(clbits),
                        params=params)
                    circuit.append(temp_opaque_instruction, qubits, clbits)
            circuits.append(circuit)
        return circuits
    return None
def circuit_to_instruction(circuit,
                           parameter_map=None,
                           equivalence_library=None):
    """Build an ``Instruction`` object from a ``QuantumCircuit``.

    The instruction is anonymous (not tied to a named quantum register),
    and so can be inserted into another circuit. The instruction will
    have the same string name as the circuit.

    Args:
        circuit (QuantumCircuit): the input circuit.
        parameter_map (dict): For parameterized circuits, a mapping from
           parameters in the circuit to parameters to be used in the instruction.
           If None, existing circuit parameters will also parameterize the
           instruction.
        equivalence_library (EquivalenceLibrary): Optional equivalence library
           where the converted instruction will be registered.

    Raises:
        QiskitError: if parameter_map is not compatible with circuit

    Return:
        qiskit.circuit.Instruction: an instruction equivalent to the action of the
        input circuit. Upon decomposition, this instruction will
        yield the components comprising the original circuit.

    Example:
        .. jupyter-execute::

            from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
            from qiskit.converters import circuit_to_instruction
            %matplotlib inline

            q = QuantumRegister(3, 'q')
            c = ClassicalRegister(3, 'c')
            circ = QuantumCircuit(q, c)
            circ.h(q[0])
            circ.cx(q[0], q[1])
            circ.measure(q[0], c[0])
            circ.rz(0.5, q[1]).c_if(c, 2)
            circuit_to_instruction(circ)
    """

    if parameter_map is None:
        parameter_dict = {p: p for p in circuit.parameters}
    else:
        parameter_dict = circuit._unroll_param_dict(parameter_map)

    if parameter_dict.keys() != circuit.parameters:
        raise QiskitError(('parameter_map should map all circuit parameters. '
                           'Circuit parameters: {}, parameter_map: {}').format(
                               circuit.parameters, parameter_dict))

    instruction = Instruction(
        name=circuit.name,
        num_qubits=sum([qreg.size for qreg in circuit.qregs]),
        num_clbits=sum([creg.size for creg in circuit.cregs]),
        params=sorted(parameter_dict.values(), key=lambda p: p.name))
    instruction.condition = None

    def find_bit_position(bit):
        """find the index of a given bit (Register, int) within
        a flat ordered list of bits of the circuit
        """
        if isinstance(bit, Qubit):
            ordered_regs = circuit.qregs
        else:
            ordered_regs = circuit.cregs
        reg_index = ordered_regs.index(bit.register)
        return sum([reg.size for reg in ordered_regs[:reg_index]]) + bit.index

    target = circuit.assign_parameters(parameter_dict, inplace=False)

    if equivalence_library is not None:
        equivalence_library.add_equivalence(instruction, target)

    definition = target.data

    if instruction.num_qubits > 0:
        q = QuantumRegister(instruction.num_qubits, 'q')
    if instruction.num_clbits > 0:
        c = ClassicalRegister(instruction.num_clbits, 'c')

    definition = list(
        map(
            lambda x:
            (x[0], list(map(lambda y: q[find_bit_position(y)], x[1])),
             list(map(lambda y: c[find_bit_position(y)], x[2]))), definition))
    instruction.definition = definition

    return instruction
Пример #20
0
def _experiments_to_circuits(qobj):
    """Return a list of QuantumCircuit object(s) from a qobj.

    Args:
        qobj (Qobj): The Qobj object to convert to QuantumCircuits

    Returns:
        list: A list of QuantumCircuit objects from the qobj
    """
    if qobj.experiments:
        circuits = []
        for x in qobj.experiments:
            quantum_registers = [
                QuantumRegister(i[1], name=i[0]) for i in x.header.qreg_sizes
            ]
            classical_registers = [
                ClassicalRegister(i[1], name=i[0]) for i in x.header.creg_sizes
            ]
            circuit = QuantumCircuit(*quantum_registers,
                                     *classical_registers,
                                     name=x.header.name)
            qreg_dict = collections.OrderedDict()
            creg_dict = collections.OrderedDict()
            for reg in quantum_registers:
                qreg_dict[reg.name] = reg
            for reg in classical_registers:
                creg_dict[reg.name] = reg
            conditional = {}
            for i in x.instructions:
                name = i.name
                qubits = []
                params = getattr(i, 'params', [])
                try:
                    for qubit in i.qubits:
                        qubit_label = x.header.qubit_labels[qubit]
                        qubits.append(
                            qreg_dict[qubit_label[0]][qubit_label[1]])
                except Exception:  # pylint: disable=broad-except
                    pass
                clbits = []
                try:
                    for clbit in i.memory:
                        clbit_label = x.header.clbit_labels[clbit]
                        clbits.append(
                            creg_dict[clbit_label[0]][clbit_label[1]])
                except Exception:  # pylint: disable=broad-except
                    pass
                if hasattr(circuit, name):
                    instr_method = getattr(circuit, name)
                    if i.name in ['snapshot']:
                        _inst = instr_method(i.label,
                                             snapshot_type=i.snapshot_type,
                                             qubits=qubits,
                                             params=params)
                    elif i.name == 'initialize':
                        _inst = instr_method(params, qubits)
                    elif i.name == 'isometry':
                        _inst = instr_method(*params, qubits, clbits)
                    else:
                        _inst = instr_method(*params, *qubits, *clbits)
                elif name == 'bfunc':
                    conditional['value'] = int(i.val, 16)
                    full_bit_size = sum([creg_dict[x].size for x in creg_dict])
                    mask_map = {}
                    raw_map = {}
                    raw = []

                    for creg in creg_dict:
                        size = creg_dict[creg].size
                        reg_raw = [1] * size
                        if not raw:
                            raw = reg_raw
                        else:
                            for pos, val in enumerate(raw):
                                if val == 1:
                                    raw[pos] = 0
                            raw = reg_raw + raw
                        mask = [0] * (full_bit_size - len(raw)) + raw
                        raw_map[creg] = mask
                        mask_map[int("".join(str(x) for x in mask), 2)] = creg
                    creg = mask_map[int(i.mask, 16)]
                    conditional['register'] = creg_dict[creg]
                    val = int(i.val, 16)
                    mask = raw_map[creg]
                    for j in reversed(mask):
                        if j == 0:
                            val = val >> 1
                        else:
                            conditional['value'] = val
                            break
                else:
                    _inst = temp_opaque_instruction = Instruction(
                        name=name,
                        num_qubits=len(qubits),
                        num_clbits=len(clbits),
                        params=params)
                    circuit.append(temp_opaque_instruction, qubits, clbits)
                if conditional and name != 'bfunc':
                    _inst.c_if(conditional['register'], conditional['value'])
                    conditional = {}
            circuits.append(circuit)
        return circuits
    return None