示例#1
0
def _decompose_CnU(cmd):  # pylint: disable=invalid-name
    """
    Decompose a multi-controlled gate U with n control qubits into a single- controlled U.

    It uses (n-1) work qubits and 2 * (n-1) Toffoli gates for general U and (n-2) work qubits and 2n - 3 Toffoli gates
    if U is an X-gate.
    """
    eng = cmd.engine
    qubits = cmd.qubits
    ctrl_qureg = cmd.control_qubits
    gate = cmd.gate
    n_controls = get_control_count(cmd)

    # specialized for X-gate
    if gate == XGate() and n_controls > 2:
        n_controls -= 1
    ancilla_qureg = eng.allocate_qureg(n_controls - 1)

    with Compute(eng):
        Toffoli | (ctrl_qureg[0], ctrl_qureg[1], ancilla_qureg[0])
        for ctrl_index in range(2, n_controls):
            Toffoli | (
                ctrl_qureg[ctrl_index],
                ancilla_qureg[ctrl_index - 2],
                ancilla_qureg[ctrl_index - 1],
            )
    ctrls = [ancilla_qureg[-1]]

    # specialized for X-gate
    if gate == XGate() and get_control_count(cmd) > 2:
        ctrls += [ctrl_qureg[-1]]
    with Control(eng, ctrls):
        gate | qubits

    Uncompute(eng)
示例#2
0
def _add_single_qubit_op_to_circuit(cmd: ProjectQCommand,
                                    circ: Circuit) -> bool:
    assert len(cmd.qubits) == 1
    assert len(cmd.qubits[0]) == 1
    qubit_no = cmd.qubits[0][0].id
    new_qubit = False
    if get_control_count(cmd) > 0:
        raise Exception("singleq gate " + str(cmd.gate) + " has " +
                        str(get_control_count(cmd)) + " control qubits")
    else:
        if qubit_no >= circ.n_qubits:
            circ.add_blank_wires(1 + qubit_no - circ.n_qubits)
            new_qubit = True
        if type(cmd.gate) == pqo.MeasureGate:
            bit = Bit("c", qubit_no)
            if bit not in circ.bits:
                circ.add_bit(bit)
            circ.Measure(qubit_no, qubit_no)
            return new_qubit
        elif type(cmd.gate) in (pqo.Rx, pqo.Ry, pqo.Rz):
            op = Op.create(_pq_to_tk_singleqs[type(cmd.gate)],
                           cmd.gate.angle / np.pi)
        else:
            op = Op.create(_pq_to_tk_singleqs[type(cmd.gate)])
        circ.add_gate(Op=op, args=[qubit_no])
    return new_qubit
示例#3
0
def _recognize_CnU(cmd):  # pylint: disable=invalid-name
    """Recognize an arbitrary gate which has n>=2 control qubits, except a Toffoli gate."""
    if get_control_count(cmd) == 2:
        if not isinstance(cmd.gate, XGate):
            return True
    elif get_control_count(cmd) > 2:
        return True
    return False
示例#4
0
    def _store(self, cmd):

        if self._clear:
            self._clear = False
            self.qasm = ""
            self._allocated_qubits = set()

        gate = cmd.gate

        if gate == ops.Allocate:
            self._allocated_qubits.add(cmd.qubits[0][0].id)
            return

        if gate == ops.Deallocate:
            return

        if gate == ops.Measure:
            assert len(cmd.qubits) == 1 and len(cmd.qubits[0]) == 1
            qb_id = cmd.qubits[0][0].id
            logical_id = None
            for t in cmd.tags:
                if isinstance(t, LogicalQubitIDTag):
                    logical_id = t.logical_qubit_id
                    break
            assert logical_id is not None
            self._measured_ids += [logical_id]
        elif gate == ops.NOT and get_control_count(cmd) == 1:
            ctrl_pos = cmd.control_qubits[0].id
            qb_pos = cmd.qubits[0][0].id
            self.qasm += "\ncx q[{}], q[{}];".format(ctrl_pos, qb_pos)
        elif gate == ops.Barrier:
            qb_pos = [qb.id for qr in cmd.qubits for qb in qr]
            self.qasm += "\nbarrier "
            qb_str = ""
            for pos in qb_pos:
                qb_str += "q[{}], ".format(pos)
            self.qasm += qb_str[:-2] + ";"
        elif isinstance(gate, (ops.Rx, ops.Ry, ops.Rz)):
            assert get_control_count(cmd) == 0
            qb_pos = cmd.qubits[0][0].id
            u_strs = {
                'Rx': 'u3({}, -pi/2, pi/2)',
                'Ry': 'u3({}, 0, 0)',
                'Rz': 'u1({})'
            }
            gate = u_strs[str(gate)[0:2]].format(gate.angle)
            self.qasm += "\n{} q[{}];".format(gate, qb_pos)
        else:
            assert get_control_count(cmd) == 0
            if str(gate) in self._gate_names:
                gate_str = self._gate_names[str(gate)]
            else:
                gate_str = str(gate).lower()

            qb_pos = cmd.qubits[0][0].id
            self.qasm += "\n{} q[{}];".format(gate_str, qb_pos)
示例#5
0
 def is_available(self, cmd):
     g = cmd.gate
     if g == ops.NOT and get_control_count(cmd) <= 1:
         return True
     if get_control_count(cmd) == 0:
         if g in (ops.T, ops.Tdag, ops.S, ops.Sdag, ops.H, ops.Y, ops.Z):
             return True
         if isinstance(g, (ops.Rx, ops.Ry, ops.Rz)):
             return True
     if g in (ops.Measure, ops.Allocate, ops.Deallocate, ops.Barrier):
         return True
     return False
示例#6
0
    def is_available(self, cmd: Command) -> bool:
        """
        Via this method the ProjectQ framework determines which commands (gates) are available in the backend.

        Args:
            cmd: Command with a gate for which to check availability.

        Returns:
            True when the gate in the command is available on the Quantum Inspire backend.
        """
        count = get_control_count(cmd)
        g = cmd.gate
        if self._verbose >= 3:
            print('call to is_available with cmd %s (gate %s)' % (cmd, g))
        if g == NOT and count <= 2:
            return True
        if g == Z and count <= 1:
            return True
        if g in (Measure, Allocate, Deallocate, Barrier):
            return True
        if count != 0:
            return False
        if g in (T, Tdag, S, Sdag, Swap, H, X, Y, Z):
            return True
        elif isinstance(g, (Rx, Ry, Rz)):
            return True
        elif isinstance(g, Ph):
            return False
        else:
            return False
示例#7
0
    def is_available(self, cmd: Command) -> bool:
        """
        Return true if the command can be executed.

        Args:
            cmd: Command for which to check availability.
        """
        count = get_control_count(cmd)
        g = cmd.gate
        if self._verbose:
            print('call to is_available with cmd %s (gate %s)' % (cmd, g))
        if g == NOT and count <= 2:
            return True
        if g == Z and count <= 1:
            return True
        if g in (Measure, Allocate, Deallocate, Barrier):
            return True
        if count != 0:
            return False
        if g in (T, Tdag, S, Sdag, H, X, Y, Z):
            return True
        elif isinstance(g, (Rx, Ry, Rz)):
            return True
        elif isinstance(g, Ph):
            return False
        else:
            return False
示例#8
0
def _recognize_CnU(cmd):
    """
    Recognize an arbitrary gate which has n>=2 control qubits, except a
    Toffoli gate.
    """
    if get_control_count(cmd) == 2:
        if not (isinstance(cmd.gate, XGate) and
            isinstance(cmd.gate, YGate) and
            isinstance(cmd.gate, ZGate) ):
            return True
        if not isinstance(cmd.gate, XGate):
            return True

    elif get_control_count(cmd) > 2:
        return True
    return False
示例#9
0
def _rx_ry_rz(cmd, mapping, qubits):
    """
    Translate a rotation gate into a Cirq roation (phase) gate.

    Global phase difference betwee proejctq rotation gate and cirq phase gate
    is dropped.

    Args:
        cmd (:class:`projectq.ops.Command`): a projectq command instance
        mapping (:class:`dict`): a dictionary of qubit mappings
        qubits (list of :class:cirq.QubitID`): cirq qubits

    Returns:
        :class:`cirq.Operation`
    """
    gates = {pqo.Rx: cop.XPowGate, pqo.Ry: cop.YPowGate, pqo.Rz: cop.ZPowGate}
    qb_pos = [mapping[qb.id] for qr in cmd.qubits for qb in qr]
    assert len(qb_pos) == 1
    cirqGate = gates[type(cmd.gate)](half_turns=cmd.gate.angle / cmath.pi)
    if get_control_count(cmd) > 0:
        ctrl_pos = [mapping[qb.id] for qb in cmd.control_qubits]
        return cop.ControlledGate(cirqGate)(
            *[qubits[c] for c in ctrl_pos + qb_pos])
    else:
        return cirqGate(*[qubits[idx] for idx in qb_pos])
def _recognize_paulis(cmd):
    if isinstance(
            cmd.gate,
        (ops.XGate, ops.YGate, ops.ZGate)) and get_control_count(cmd) == 0:
        return True
    else:
        return False
示例#11
0
    def is_available(self, cmd):
        """
        Test if this backend is available to process the provided command.

        Args:
            cmd (Command): A command to process.

        Returns:
            bool: If this backend can process the command.
        """
        gate = cmd.gate

        # Metagates.
        if gate in (Measure, Allocate, Deallocate, Barrier):
            return True

        if has_negative_control(cmd):
            return False

        # CNOT gates.
        # NOTE: IonQ supports up to 7 control qubits
        num_ctrl_qubits = get_control_count(cmd)
        if 0 < num_ctrl_qubits <= 7:
            return isinstance(gate, (XGate, ))

        # Gates witout control bits.
        if num_ctrl_qubits == 0:
            supported = isinstance(gate, SUPPORTED_GATES)
            supported_transpose = gate in (Sdag, Tdag)
            return supported or supported_transpose
        return False
示例#12
0
def filter_gates(eng, cmd):
    if isinstance(cmd.gate, ClassicalInstructionGate):
        return True
    if ((cmd.gate == X and get_control_count(cmd) == 1) or cmd.gate == H
            or isinstance(cmd.gate, Rz)):
        return False
    return True
示例#13
0
def _hiq_add_cmd(resource_counter, cmd):
    """
    Add a gate to the count.
    """
    if isinstance(cmd.gate, AllocateQuregGate):
        for qureg in cmd.qubits:
            for qubit in qureg:
                resource_counter._active_qubits += 1
                resource_counter._depth_of_qubit[qubit.id] = 0

        # this is original ProjectQ's code copied here from _add_cmd()
        resource_counter.max_width = max(resource_counter.max_width,
                                         resource_counter._active_qubits)

        ctrl_cnt = get_control_count(cmd)
        gate_description = (cmd.gate, ctrl_cnt)
        gate_class_description = (cmd.gate.__class__, ctrl_cnt)

        try:
            resource_counter.gate_counts[gate_description] += 1
        except KeyError:
            resource_counter.gate_counts[gate_description] = 1

        try:
            resource_counter.gate_class_counts[gate_class_description] += 1
        except KeyError:
            resource_counter.gate_class_counts[gate_class_description] = 1
    else:
        resource_counter._old_add_cmd(cmd)
示例#14
0
    def _add_cmd(self, cmd):
        """
        Add a gate to the count.
        """
        if cmd.gate == Allocate:
            self._active_qubits += 1
        elif cmd.gate == Deallocate:
            self._active_qubits -= 1
        elif cmd.gate == Measure:
            for qureg in cmd.qubits:
                for qubit in qureg:
                    self.main_engine.set_measurement_result(qubit, 0)

        self.max_width = max(self.max_width, self._active_qubits)

        ctrl_cnt = get_control_count(cmd)
        gate_description = (cmd.gate, ctrl_cnt)
        gate_class_description = (cmd.gate.__class__, ctrl_cnt)

        try:
            self.gate_counts[gate_description] += 1
        except KeyError:
            self.gate_counts[gate_description] = 1

        try:
            self.gate_class_counts[gate_class_description] += 1
        except KeyError:
            self.gate_class_counts[gate_class_description] = 1
示例#15
0
    def _print_cmd(self, cmd):
        """
        Print a command or, if the command is a measurement instruction and
        the CommandPrinter is the last engine in the engine pipeline: Query
        the user for the measurement result (if accept_input = True) / Set
        the result to 0 (if it's False).

        Args:
            cmd (Command): Command to print.
        """
        if self.is_last_engine and cmd.gate == Measure:
            assert (get_control_count(cmd) == 0)
            print(cmd)
            for qureg in cmd.qubits:
                for qubit in qureg:
                    if self._accept_input:
                        m = None
                        while m != '0' and m != '1' and m != 1 and m != 0:
                            prompt = ("Input measurement result (0 or 1) for"
                                      " qubit " + str(qubit) + ": ")
                            m = input(prompt)
                    else:
                        m = self._default_measure
                    m = int(m)
                    self.main_engine.set_measurement_result(qubit, m)
        else:
            if self._in_place:
                sys.stdout.write("\0\r\t\x1b[K" + str(cmd) + "\r")
            else:
                print(cmd)
示例#16
0
def _add_single_qubit_op_to_circuit(cmd:ProjectQCommand,circ:Circuit):
    assert len(cmd.qubits)==1
    assert len(cmd.qubits[0])==1
    qubit_no = cmd.qubits[0][0].id
    new_qubit = False
    if get_control_count(cmd) > 0:
        raise Exception("singleq gate " + str(cmd.gate) + " has " + str(get_control_count(cmd)) + " control qubits")
    else:
        if type(cmd.gate) in (pqo.Rx,pqo.Ry,pqo.Rz):
            op = circ._get_op(OpType=_pq_to_tk_singleqs[type(cmd.gate)],param=cmd.gate.angle/np.pi)
        else:
            op = circ._get_op(OpType=_pq_to_tk_singleqs[type(cmd.gate)])
        if (qubit_no >= circ.n_qubits):
            circ.add_blank_wires(1+qubit_no-circ.n_qubits)
            new_qubit = True
        circ._add_operation(Op=op,qubits=[qubit_no])
    return new_qubit
示例#17
0
    def _is_swap(self, cmd):  # pylint: disable=no-self-use
        """
        Check if the command corresponds to a Swap gate.

        Args:
            cmd (Command): Command to check
        """
        return get_control_count(cmd) == 0 and cmd.gate == Swap
    def _is_swap(self, cmd):
        """
        Check if the command corresponds to a Swap gate.

        Args:
            cmd (Command): Command to check
        """
        return (get_control_count(cmd) == 0 and cmd.gate == Swap)
示例#19
0
    def _is_cnot(self, cmd):  # pylint: disable=no-self-use
        """
        Check if the command corresponds to a CNOT (controlled NOT gate).

        Args:
            cmd (Command): Command to check
        """
        return isinstance(cmd.gate,
                          NOT.__class__) and get_control_count(cmd) == 1
示例#20
0
    def _is_cnot(self, cmd):
        """
		Check if the command corresponds to a CNOT (controlled NOT gate).
		
		Args:
			cmd (Command): Command to check whether it is a controlled NOT gate.
		"""
        return isinstance(cmd.gate,
                          NOT.__class__) and get_control_count(cmd) == 1
示例#21
0
    def _handle(self, cmd):
        """
        Handle all commands, i.e., call the member functions of the C++-
        simulator object corresponding to measurement, allocation/
        deallocation, and (controlled) single-qubit gate.

        Args:
            cmd (Command): Command to handle.

        Raises:
            Exception: If a non-single-qubit gate needs to be processed
                (which should never happen due to is_available).
        """
        #print(cmd)
        if cmd.gate == Measure:
            assert (get_control_count(cmd) == 0)
            ids = [qb.id for qr in cmd.qubits for qb in qr]
            out = self._simulator.measure_qubits(ids)
            i = 0
            for qr in cmd.qubits:
                for qb in qr:
                    self.main_engine.set_measurement_result(qb, out[i])
                    i += 1
        elif cmd.gate == Allocate:
            ID = cmd.qubits[0][0].id
            self._simulator.allocate_qubit(ID)
        elif cmd.gate == Deallocate:
            ID = cmd.qubits[0][0].id
            self._simulator.deallocate_qubit(ID)
        elif isinstance(cmd.gate, BasicMathGate):
            qubitids = []
            for qr in cmd.qubits:
                qubitids.append([])
                for qb in qr:
                    qubitids[-1].append(qb.id)
            math_fun = cmd.gate.get_math_function(cmd.qubits)
            self._simulator.emulate_math(math_fun, qubitids,
                                         [qb.id for qb in cmd.control_qubits])
        elif isinstance(cmd.gate, TimeEvolution):
            op = [(list(term), coeff)
                  for (term, coeff) in cmd.gate.hamiltonian.terms.items()]
            t = cmd.gate.time
            qubitids = [qb.id for qb in cmd.qubits[0]]
            ctrlids = [qb.id for qb in cmd.control_qubits]
            self._simulator.emulate_time_evolution(op, t, qubitids, ctrlids)
        elif len(cmd.gate.matrix) == 2:
            matrix = cmd.gate.matrix
            self._simulator.apply_controlled_gate(
                matrix.tolist(), [cmd.qubits[0][0].id],
                [qb.id for qb in cmd.control_qubits])
            if not self._gate_fusion:
                self._simulator.run()
        else:
            raise Exception("This simulator only supports controlled single-"
                            "qubit gates!\nPlease add an auto-replacer engine"
                            " to your list of compiler engines.")
示例#22
0
文件: _ibm.py 项目: silky/ProjectQ
    def is_available(self, cmd):
        """
		Return true if the command can be executed.
		
		The IBM quantum chip can do X, Y, Z, T, Tdag, S, Sdag, and CX / CNOT.
		
		Args:
			cmd (Command): Command for which to check availability
		"""
        g = cmd.gate
        if g == NOT and get_control_count(cmd) <= 1:
            return True
        if get_control_count(cmd) == 0:
            if (g == T or g == Tdag or g == S or g == Sdag or g == H or g == Y
                    or g == Z or g == I):
                return True
        if g == Measure or g == Allocate or g == Deallocate:
            return True
        return False
示例#23
0
def _recognize_carb1qubit(cmd):
    """ Recognize single controlled one qubit gates with a matrix."""
    if get_control_count(cmd) == 1:
        try:
            m = cmd.gate.matrix
            if len(m) == 2:
                return True
        except:
            return False
    return False
示例#24
0
def _decompose_CRz(cmd):  # pylint: disable=invalid-name
    """Decompose the controlled Rz gate (into CNOT and Rz)."""
    qubit = cmd.qubits[0]
    ctrl = cmd.control_qubits
    gate = cmd.gate
    n_controls = get_control_count(cmd)

    Rz(0.5 * gate.angle) | qubit
    C(NOT, n_controls) | (ctrl, qubit)
    Rz(-0.5 * gate.angle) | qubit
    C(NOT, n_controls) | (ctrl, qubit)
示例#25
0
    def _add_cmd(self, cmd):
        """
        Add a gate to the count.
        """
        if cmd.gate == Allocate:
            self._active_qubits += 1
            self._depth_of_qubit[cmd.qubits[0][0].id] = 0
        elif cmd.gate == Deallocate:
            self._active_qubits -= 1
            depth = self._depth_of_qubit[cmd.qubits[0][0].id]
            self._previous_max_depth = max(self._previous_max_depth, depth)
            self._depth_of_qubit.pop(cmd.qubits[0][0].id)
        elif self.is_last_engine and cmd.gate == Measure:
            for qureg in cmd.qubits:
                for qubit in qureg:
                    self._depth_of_qubit[qubit.id] += 1
                    # Check if a mapper assigned a different logical id
                    logical_id_tag = None
                    for tag in cmd.tags:
                        if isinstance(tag, LogicalQubitIDTag):
                            logical_id_tag = tag
                    if logical_id_tag is not None:
                        qubit = WeakQubitRef(qubit.engine,
                                             logical_id_tag.logical_qubit_id)
                    self.main_engine.set_measurement_result(qubit, 0)
        else:
            qubit_ids = set()
            for qureg in cmd.all_qubits:
                for qubit in qureg:
                    qubit_ids.add(qubit.id)
            if len(qubit_ids) == 1:
                self._depth_of_qubit[list(qubit_ids)[0]] += 1
            else:
                max_depth = 0
                for qubit_id in qubit_ids:
                    max_depth = max(max_depth, self._depth_of_qubit[qubit_id])
                for qubit_id in qubit_ids:
                    self._depth_of_qubit[qubit_id] = max_depth + 1

        self.max_width = max(self.max_width, self._active_qubits)

        ctrl_cnt = get_control_count(cmd)
        gate_description = (cmd.gate, ctrl_cnt)
        gate_class_description = (cmd.gate.__class__, ctrl_cnt)

        try:
            self.gate_counts[gate_description] += 1
        except KeyError:
            self.gate_counts[gate_description] = 1

        try:
            self.gate_class_counts[gate_class_description] += 1
        except KeyError:
            self.gate_class_counts[gate_class_description] = 1
示例#26
0
def _decompose_CRz(cmd):
    """ Decompose the controlled Rz gate (into CNOT and Rz). """
    qubit = cmd.qubits[0]
    ctrl = cmd.control_qubits
    gate = cmd.gate
    n = get_control_count(cmd)

    Rz(0.5 * gate._angle) | qubit
    C(NOT, n) | (ctrl, qubit)
    Rz(-0.5 * gate._angle) | qubit
    C(NOT, n) | (ctrl, qubit)
示例#27
0
def _recognize_arb1qubit(cmd):
    """
    Recognize an arbitrary one qubit gate which has a matrix property.

    It does not allow gates which have control qubits as otherwise the
    AutoReplacer might go into an infinite loop. Use
    carb1qubit2cnotrzandry instead.
    """
    try:
        return len(cmd.gate.matrix) == 2 and get_control_count(cmd) == 0
    except AttributeError:
        return False
示例#28
0
    def is_available(self, cmd):
        """
        Return true if the command can be executed.

        For supporting gate of QuTiP, pleaser refer to
        http://qutip.org/docs/latest/guide/guide-qip.html.

        Args:
            cmd (Command): Command for which to check availability
        """
        g = cmd.gate
        if g == NOT and get_control_count(cmd) <= 1:
            return True
        if get_control_count(cmd) == 0:
            if g in (H, X, Y, Z):
                return True
            if isinstance(g, (Rx, Ry, Rz)):
                return True
        if g in (Measure, Allocate, Deallocate, Barrier):
            return True
        return False
示例#29
0
文件: _ibm.py 项目: ywlds/ProjectQ
    def is_available(self, cmd):
        """
        Return true if the command can be executed.

        The IBM quantum chip can do X, Y, Z, T, Tdag, S, Sdag,
        rotation gates, barriers, and CX / CNOT.

        Args:
            cmd (Command): Command for which to check availability
        """
        g = cmd.gate
        if g == NOT and get_control_count(cmd) <= 1:
            return True
        if get_control_count(cmd) == 0:
            if g in (T, Tdag, S, Sdag, H, Y, Z):
                return True
            if isinstance(g, (Rx, Ry, Rz)):
                return True
        if g in (Measure, Allocate, Deallocate, Barrier):
            return True
        return False
示例#30
0
    def _store(self, cmd):
        """
        Temporarily store the command cmd.

        Translates the command and stores it in a local variable (self._cmds).

        Args:
            cmd: Command to store
        """
        if self._clear:
            self._mapping = dict()
            self._inverse_mapping = dict()
            self._probabilities = dict()
            self._clear = False
            self.qasm = ""

        gate = cmd.gate
        if gate == Allocate:
            qb_id = cmd.qubits[0][0].id
            for tag in cmd.tags:
                if isinstance(tag, QubitPlacementTag):
                    self._mapping[qb_id] = tag.position
                    self._inverse_mapping[tag.position] = qb_id
                    break
            if not qb_id in self._mapping:
                raise Exception("No qubit placement info found in Allocate.\n"
                                "Please make sure you are using the IBM CNOT "
                                "Mapper.")
            return

        if gate == Deallocate:
            return

        if gate == Measure:
            for qr in cmd.qubits:
                for qb in qr:
                    qb_pos = self._mapping[qb.id]
                    self.qasm += "\nmeasure q[{}] -> c[{}];".format(qb_pos,
                                                                    qb_pos)

        elif not (gate == NOT and get_control_count(cmd) == 1):
            if str(gate) in self._gate_names:
                gate_str = self._gate_names[str(gate)]
            else:
                gate_str = str(gate).lower()

            qb_pos = self._mapping[cmd.qubits[0][0].id]
            self.qasm += "\n{} q[{}];".format(gate_str, qb_pos)
        else:
            ctrl_pos = self._mapping[cmd.control_qubits[0].id]
            qb_pos = self._mapping[cmd.qubits[0][0].id]
            self.qasm += "\ncx q[{}], q[{}];".format(ctrl_pos, qb_pos)