예제 #1
0
def dagdependency_to_circuit(dagdependency):
    """Build a ``QuantumCircuit`` object from a ``DAGDependency``.

    Args:
        dagdependency (DAGDependency): the input dag.

    Return:
        QuantumCircuit: the circuit representing the input dag dependency.
    """

    name = dagdependency.name or None
    circuit = QuantumCircuit(dagdependency.qubits,
                             dagdependency.clbits,
                             *dagdependency.qregs.values(),
                             *dagdependency.cregs.values(),
                             name=name)
    circuit.metadata = dagdependency.metadata

    circuit.calibrations = dagdependency.calibrations

    for node in dagdependency.get_nodes():
        # Get arguments for classical control (if any)
        inst = node.op.copy()
        inst.condition = node.condition
        circuit._append(inst, node.qargs, node.cargs)

    return circuit
def dagdependency_to_circuit(dagdependency):
    """Build a ``QuantumCircuit`` object from a ``DAGDependency``.

    Args:
        dagdependency (DAGDependency): the input dag.

    Return:
        QuantumCircuit: the circuit representing the input dag dependency.
    """

    name = dagdependency.name or None
    circuit = QuantumCircuit(
        dagdependency.qubits,
        dagdependency.clbits,
        *dagdependency.qregs.values(),
        *dagdependency.cregs.values(),
        name=name,
    )
    circuit.metadata = dagdependency.metadata

    circuit.calibrations = dagdependency.calibrations

    for node in dagdependency.get_nodes():
        circuit._append(
            CircuitInstruction(node.op.copy(), node.qargs, node.cargs))

    return circuit
예제 #3
0
 def _define(self):
     """Calculate a subcircuit that implements this unitary."""
     if self.num_qubits == 1:
         q = QuantumRegister(1, "q")
         qc = QuantumCircuit(q, name=self.name)
         theta, phi, lam, global_phase = _DECOMPOSER1Q.angles_and_phase(self.to_matrix())
         qc._append(U3Gate(theta, phi, lam), [q[0]], [])
         qc.global_phase = global_phase
         self.definition = qc
     elif self.num_qubits == 2:
         self.definition = two_qubit_cnot_decompose(self.to_matrix())
     else:
         self.definition = qs_decomposition(self.to_matrix())
예제 #4
0
def dag_to_circuit(dag):
    """Build a ``QuantumCircuit`` object from a ``DAGCircuit``.

    Args:
        dag (DAGCircuit): the input dag.

    Return:
        QuantumCircuit: the circuit representing the input dag.

    Example:
        .. jupyter-execute::

            from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
            from qiskit.dagcircuit import DAGCircuit
            from qiskit.converters import circuit_to_dag
            from qiskit.circuit.library.standard_gates import CHGate, U2Gate, CXGate
            from qiskit.converters import dag_to_circuit
            %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)
            dag = circuit_to_dag(circ)
            circuit = dag_to_circuit(dag)
            circuit.draw()
    """

    name = dag.name or None
    circuit = QuantumCircuit(
        dag.qubits,
        dag.clbits,
        *dag.qregs.values(),
        *dag.cregs.values(),
        name=name,
        global_phase=dag.global_phase,
    )
    circuit.metadata = dag.metadata
    circuit.calibrations = dag.calibrations

    for node in dag.topological_op_nodes():
        circuit._append(
            CircuitInstruction(node.op.copy(), node.qargs, node.cargs))

    circuit.duration = dag.duration
    circuit.unit = dag.unit
    return circuit
예제 #5
0
 def _define(self):
     """Calculate a subcircuit that implements this unitary."""
     if self.num_qubits == 1:
         q = QuantumRegister(1, "q")
         qc = QuantumCircuit(q, name=self.name)
         theta, phi, lam = _DECOMPOSER1Q.angles(self.to_matrix())
         qc._append(U3Gate(theta, phi, lam), [q[0]], [])
         self.definition = qc
     elif self.num_qubits == 2:
         self.definition = two_qubit_cnot_decompose(self.to_matrix())
     else:
         q = QuantumRegister(self.num_qubits, "q")
         qc = QuantumCircuit(q, name=self.name)
         qc.append(isometry.Isometry(self.to_matrix(), 0, 0), qargs=q[:])
         self.definition = qc
예제 #6
0
    def inverse(self):
        """Return the inverse.

        Note that the resulting gate has an empty ``params`` property.
        """
        inverse_gate = Gate(
            name=self.name + "_dg", num_qubits=self.num_qubits,
            params=[])  # removing the params because arrays are deprecated

        definition = QuantumCircuit(*self.definition.qregs)
        for inst in reversed(self._definition):
            definition._append(
                inst.replace(operation=inst.operation.inverse()))
        inverse_gate.definition = definition
        return inverse_gate
예제 #7
0
def dag_to_circuit(dag):
    """Build a ``QuantumCircuit`` object from a ``DAGCircuit``.

    Args:
        dag (DAGCircuit): the input dag.

    Return:
        QuantumCircuit: the circuit representing the input dag.

    Example:
        .. jupyter-execute::

            from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
            from qiskit.dagcircuit import DAGCircuit
            from qiskit.converters import circuit_to_dag
            from qiskit.circuit.library.standard_gates import CHGate, U2Gate, CXGate
            from qiskit.converters import dag_to_circuit
            %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)
            dag = circuit_to_dag(circ)
            circuit = dag_to_circuit(dag)
            circuit.draw()
    """

    name = dag.name or None
    circuit = QuantumCircuit(*dag.qregs.values(),
                             *dag.cregs.values(),
                             name=name)

    for node in dag.topological_op_nodes():
        # Get arguments for classical control (if any)
        inst = node.op.copy()
        inst.condition = node.condition
        circuit._append(inst, node.qargs, node.cargs)

    return circuit
예제 #8
0
def _unify_circuit_resources_rebuild(  # pylint: disable=invalid-name  # (it's too long?!)
    true_body: QuantumCircuit, false_body: QuantumCircuit
) -> Tuple[QuantumCircuit, QuantumCircuit]:
    """
    Ensure that ``true_body`` and ``false_body`` have all the same qubits and clbits, and that they
    are defined in the same order.  The order is important for binding when the bodies are used in
    the 3-tuple :obj:`.Instruction` context.

    This function will always rebuild the two parameters into new :obj:`.QuantumCircuit` instances.
    """
    qubits = list(set(true_body.qubits).union(false_body.qubits))
    clbits = list(set(true_body.clbits).union(false_body.clbits))
    # We use the inner `_append` method because everything is already resolved.
    true_out = QuantumCircuit(qubits, clbits, *true_body.qregs, *true_body.cregs)
    for data in true_body.data:
        true_out._append(*data)
    false_out = QuantumCircuit(qubits, clbits, *false_body.qregs, *false_body.cregs)
    for data in false_body.data:
        false_out._append(*data)
    return _unify_circuit_registers(true_out, false_out)
    def run(self, dag):
        """Run the Optimize1qGatesDecomposition pass on `dag`.

        Args:
            dag (DAGCircuit): the DAG to be optimized.

        Returns:
            DAGCircuit: the optimized DAG.
        """
        if not self.basis:
            LOG.info("Skipping pass because no basis is set")
            return dag
        runs = dag.collect_1q_runs()
        for run in runs:
            # Don't try to optimize a single 1q gate
            if len(run) <= 1:
                params = run[0].op.params
                # Remove single identity gates
                if len(params) > 0 and np.array_equal(run[0].op.to_matrix(),
                                                      np.eye(2)):
                    dag.remove_op_node(run[0])
                continue

            new_circs = []
            q = QuantumRegister(1, "q")
            qc = QuantumCircuit(1)
            for gate in run:
                qc._append(gate.op, [q[0]], [])
            operator = Operator(qc)
            for decomposer in self.basis:
                new_circs.append(decomposer(operator))
            if new_circs:
                new_circ = min(new_circs, key=lambda circ: circ.depth())
                if qc.depth() > new_circ.depth():
                    new_dag = circuit_to_dag(new_circ)
                    dag.substitute_node_with_dag(run[0], new_dag)
                    # Delete the other nodes in the run
                    for current_node in run[1:]:
                        dag.remove_op_node(current_node)
        return dag
예제 #10
0
    def _gate_rules_to_qiskit_circuit(self, node, params):
        """From a gate definition in qasm, to a QuantumCircuit format."""
        rules = []
        qreg = QuantumRegister(node['n_bits'])
        bit_args = {node['bits'][i]: q for i, q in enumerate(qreg)}
        exp_args = {node['args'][i]: Real(q) for i, q in enumerate(params)}

        for child_op in node['body'].children:
            qparams = []
            eparams = []
            for param_list in child_op.children[1:]:
                if param_list.type == 'id_list':
                    qparams = [bit_args[param.name] for param in param_list.children]
                elif param_list.type == 'expression_list':
                    for param in param_list.children:
                        eparams.append(param.sym(nested_scope=[exp_args]))
            op = self._create_op(child_op.name, params=eparams)
            rules.append((op, qparams, []))
        circ = QuantumCircuit(qreg)
        for instr, qargs, cargs in rules:
            circ._append(instr, qargs, cargs)
        return circ
예제 #11
0
def dag_to_circuit(dag):
    """Build a ``QuantumCircuit`` object from a ``DAGCircuit``.

    Args:
        dag (DAGCircuit): the input dag.

    Return:
        QuantumCircuit: the circuit representing the input dag.
    """

    name = dag.name or None
    circuit = QuantumCircuit(*dag.qregs.values(),
                             *dag.cregs.values(),
                             name=name)

    for node in dag.topological_op_nodes():
        # Get arguments for classical control (if any)
        inst = node.op.copy()
        inst.condition = node.condition
        circuit._append(inst, node.qargs, node.cargs)

    return circuit
예제 #12
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.circuit import QuantumCircuit, CircuitInstruction

            qc = QuantumCircuit()
            if qargs:
                qc.add_register(qargs)
            if cargs:
                qc.add_register(cargs)
            circuit_instruction = CircuitInstruction(self, qargs, cargs)
            for _ in [None] * n:
                qc._append(circuit_instruction)
        instruction.definition = qc
        return instruction
예제 #13
0
 def _define(self):
     """Allow unrolling to a Kraus instruction"""
     q = QuantumRegister(self.num_qubits, "q")
     qc = QuantumCircuit(q, name=self.name)
     qc._append(Kraus(self._quantum_error).to_instruction(), q, [])
     self.definition = qc
예제 #14
0
    def build(
        self, all_qubits: FrozenSet[Qubit], all_clbits: FrozenSet[Clbit]
    ) -> "qiskit.circuit.QuantumCircuit":
        """Build this scoped block into a complete :obj:`.QuantumCircuit` instance.

        This will build a circuit which contains all of the necessary qubits and clbits and no
        others.

        The ``qubits`` and ``clbits`` arguments should be sets that contains all the resources in
        the outer scope; these will be passed down to inner placeholder instructions, so they can
        apply themselves across the whole scope should they need to.  The resulting
        :obj:`.QuantumCircuit` will be defined over a (nonstrict) subset of these resources.  This
        is used to let ``break`` and ``continue`` span all resources, even if they are nested within
        several :obj:`.IfElsePlaceholder` objects, without requiring :obj:`.IfElsePlaceholder`
        objects *without* any ``break`` or ``continue`` statements to be full-width.

        Args:
            all_qubits: all the qubits in the containing scope of this block.  The block may expand
                to use some or all of these qubits, but will never gain qubits that are not in this
                set.
            all_clbits: all the clbits in the containing scope of this block.  The block may expand
                to use some or all of these clbits, but will never gain clbits that are not in this
                set.

        Returns:
            A circuit containing concrete versions of all the instructions that were in the scope,
            and using the minimal set of resources necessary to support them, within the enclosing
            scope.
        """
        from qiskit.circuit import QuantumCircuit

        # There's actually no real problem with building a scope more than once.  This flag is more
        # so _other_ operations, which aren't safe can be forbidden, such as mutating instructions
        # that may have been built into other objects.
        self._built = True

        potential_qubits = all_qubits - self.qubits
        potential_clbits = all_clbits - self.clbits

        # We start off by only giving the QuantumCircuit the qubits we _know_ it will need, and add
        # more later as needed.
        out = QuantumCircuit(list(self.qubits), list(self.clbits), *self.registers)

        for instruction in self.instructions:
            if isinstance(instruction.operation, InstructionPlaceholder):
                operation, resources = instruction.operation.concrete_instruction(
                    all_qubits, all_clbits
                )
                qubits = tuple(resources.qubits)
                clbits = tuple(resources.clbits)
                instruction = CircuitInstruction(operation, qubits, clbits)
                # We want to avoid iterating over the tuples unnecessarily if there's no chance
                # we'll need to add bits to the circuit.
                if potential_qubits and qubits:
                    add_qubits = potential_qubits.intersection(qubits)
                    if add_qubits:
                        potential_qubits -= add_qubits
                        out.add_bits(add_qubits)
                if potential_clbits and clbits:
                    add_clbits = potential_clbits.intersection(clbits)
                    if add_clbits:
                        potential_clbits -= add_clbits
                        out.add_bits(add_clbits)
                for register in itertools.chain(resources.qregs, resources.cregs):
                    if register not in self.registers:
                        # As of 2021-12-09, QuantumCircuit doesn't have an efficient way to check if
                        # a register is already present, so we use our own tracking.
                        self.add_register(register)
                        out.add_register(register)
            if getattr(instruction.operation, "condition", None) is not None:
                for register in condition_registers(instruction.operation.condition):
                    if register not in self.registers:
                        self.add_register(register)
                        out.add_register(register)
            # We already did the broadcasting and checking when the first call to
            # QuantumCircuit.append happened (which the user wrote), and added the instruction into
            # this scope.  We just need to finish the job now.
            out._append(instruction)
        return out
 def _define(self):
     """Calculate a subcircuit that implements this unitary."""
     q = QuantumRegister(self.num_qubits, 'q')
     qc = QuantumCircuit(q, name=self.name)
     qc._append(UnitaryGate(self.to_matrix()), q[:], [])
     self.definition = qc