コード例 #1
0
ファイル: _isa.py プロジェクト: zyedmaheen/pyquil
def gates_in_isa(isa: ISA) -> List[Gate]:
    """
    Generate the full gateset associated with an ISA.

    :param isa: The instruction set architecture for a QPU.
    :return: A sequence of Gate objects encapsulating all gates compatible with the ISA.
    """
    gates = []
    for q in isa.qubits:
        if q.dead:
            # TODO: dead qubits may in the future lead to some implicit re-indexing
            continue
        if q.type == "Xhalves":
            gates.extend(
                [
                    Gate("I", [], [unpack_qubit(q.id)]),
                    Gate("RX", [np.pi / 2], [unpack_qubit(q.id)]),
                    Gate("RX", [-np.pi / 2], [unpack_qubit(q.id)]),
                    Gate("RX", [np.pi], [unpack_qubit(q.id)]),
                    Gate("RX", [-np.pi], [unpack_qubit(q.id)]),
                    Gate("RZ", [THETA], [unpack_qubit(q.id)]),
                ]
            )
        elif q.type == "WILDCARD":
            gates.extend([Gate("_", "_", [unpack_qubit(q.id)])])
        else:  # pragma no coverage
            raise ValueError("Unknown qubit type: {}".format(q.type))

    for e in isa.edges:
        if e.dead:
            continue
        targets = [unpack_qubit(t) for t in e.targets]
        assert e.type is not None
        edge_type = e.type if isinstance(e.type, list) else [e.type]
        if "CZ" in edge_type:
            gates.append(Gate("CZ", [], targets))
            gates.append(Gate("CZ", [], targets[::-1]))
            continue
        if "ISWAP" in edge_type:
            gates.append(Gate("ISWAP", [], targets))
            gates.append(Gate("ISWAP", [], targets[::-1]))
            continue
        if "CPHASE" in edge_type:
            gates.append(Gate("CPHASE", [THETA], targets))
            gates.append(Gate("CPHASE", [THETA], targets[::-1]))
            continue
        if "XY" in edge_type:
            gates.append(Gate("XY", [THETA], targets))
            gates.append(Gate("XY", [THETA], targets[::-1]))
            continue
        assert e.type is not None
        if "WILDCARD" in e.type:
            gates.append(Gate("_", "_", targets))
            gates.append(Gate("_", "_", targets[::-1]))
            continue

        raise ValueError("Unknown edge type: {}".format(e.type))
    return gates
コード例 #2
0
ファイル: noise_gates.py プロジェクト: vishalbelsare/pyquil
def _transform_rpcq_edge_gate_info_to_qvm_noise_supported_gates(
        edge: Edge) -> List[Gate]:
    operators = [gate.operator for gate in edge.gates]
    targets = [unpack_qubit(t) for t in edge.ids]

    gates = []
    if Supported2QGate.CZ in operators:
        gates.append(Gate("CZ", [], targets))
        gates.append(Gate("CZ", [], targets[::-1]))
        return gates

    if Supported2QGate.ISWAP in operators:
        gates.append(Gate("ISWAP", [], targets))
        gates.append(Gate("ISWAP", [], targets[::-1]))
        return gates

    if Supported2QGate.CPHASE in operators:
        gates.append(Gate("CPHASE", [THETA], targets))
        gates.append(Gate("CPHASE", [THETA], targets[::-1]))
        return gates

    if Supported2QGate.XY in operators:
        gates.append(Gate("XY", [THETA], targets))
        gates.append(Gate("XY", [THETA], targets[::-1]))
        return gates

    if Supported2QGate.WILDCARD in operators:
        gates.append(Gate("_", "_", targets))
        gates.append(Gate("_", "_", targets[::-1]))
        return gates

    _log.warning(f"no gate for edge {edge.ids}")
    return gates
コード例 #3
0
 def ctor(*qubits):
     qubits = stray_qubits + list(qubits)
     if len(qubits) != num_qubits:
         raise ValueError(
             "Wrong number of qubits for {}. {} given, require {}.".
             format(name, len(qubits), num_qubits))
     return Gate(name, params, [unpack_qubit(q) for q in qubits])
コード例 #4
0
    def gate_function(*params):
        params = list(params)
        stray_qubits = []
        if len(params) < num_params:
            raise ValueError(
                "Wrong number of params for {}. {} given, require {}."
                .format(name, len(params), num_params)
            )
        elif len(params) > num_params:
            stray_qubits = params[num_params:]
            params = params[0:num_params]

        def ctor(*qubits):
            qubits = stray_qubits + list(qubits)
            if len(qubits) != num_qubits:
                raise ValueError(
                    "Wrong number of qubits for {}. {} given, require {}."
                    .format(name, len(qubits), num_qubits)
                )
            return Gate(name, params, [unpack_qubit(q) for q in qubits])

        if len(stray_qubits) == num_qubits:
            return Gate(name, params, [unpack_qubit(q) for q in stray_qubits])
        else:
            return ctor
コード例 #5
0
ファイル: quilbase.py プロジェクト: gjz010/pyquil
    def controlled(self, control_qubit):
        """
        Add the CONTROLLED modifier to the gate with the given control qubit.
        """
        control_qubit = unpack_qubit(control_qubit)

        self.modifiers.insert(0, "CONTROLLED")
        self.qubits.insert(0, control_qubit)

        return self
コード例 #6
0
ファイル: quilbase.py プロジェクト: vishalbelsare/pyquil
 def controlled(self, control_qubit: Union[QubitDesignator, Sequence[QubitDesignator]]) -> "Gate":
     """
     Add the CONTROLLED modifier to the gate with the given control qubit or Sequence of control
     qubits.
     """
     control_qubit = control_qubit if isinstance(control_qubit, Sequence) else [control_qubit]
     for qubit in control_qubit:
         qubit = unpack_qubit(qubit)
         self.modifiers.insert(0, "CONTROLLED")
         self.qubits.insert(0, qubit)
     return self
コード例 #7
0
ファイル: gates.py プロジェクト: timasq/pyquil
def H(qubit):
    """
    H = (1 / sqrt(2)) * [[1, 1],
                         [1, -1]]

    Produces the H instruction. This gate is a single qubit Hadamard gate.

    :param qubit: The qubit apply the gate to.
    :returns: A Gate object.
    """
    return Gate(name="H", params=[], qubits=[unpack_qubit(qubit)])
コード例 #8
0
def MEASURE(qubit, classical_reg=None):
    """
    Produce a MEASURE instruction.

    :param qubit: The qubit to measure.
    :param classical_reg: The classical register to measure into, or None.
    :return: A Measurement instance.
    """
    qubit = unpack_qubit(qubit)
    address = None if classical_reg is None else unpack_classical_reg(classical_reg)
    return Measurement(qubit, address)
コード例 #9
0
ファイル: quil.py プロジェクト: MrGoogol/pyquil
    def gate(self, name, params, qubits):
        """
        Add a gate to the program.

        :param string name: The name of the gate.
        :param list params: Parameters to send to the gate.
        :param list qubits: Qubits that the gate operates on.
        :return: The Program instance
        :rtype: Program
        """
        return self.inst(Gate(name, params, [unpack_qubit(q) for q in qubits]))
コード例 #10
0
ファイル: noise_gates.py プロジェクト: vishalbelsare/pyquil
def _transform_rpcq_qubit_gate_info_to_qvm_noise_supported_gate(
        qubit_id: int, gate: GateInfo) -> Optional[Gate]:
    if gate.operator == Supported1QGate.RX:
        if len(gate.parameters) == 1 and gate.parameters[0] == 0.0:
            return None

        parameters = [
            Parameter(param) if isinstance(param, str) else param
            for param in gate.parameters
        ]
        return Gate(gate.operator, parameters, [unpack_qubit(qubit_id)])

    if gate.operator == Supported1QGate.RZ:
        return Gate(Supported1QGate.RZ, [Parameter("theta")],
                    [unpack_qubit(qubit_id)])

    if gate.operator == Supported1QGate.I:
        return Gate(Supported1QGate.I, [], [unpack_qubit(qubit_id)])

    _log.warning("Unknown qubit gate operator: {}".format(gate.operator))
    return None
コード例 #11
0
ファイル: gates.py プロジェクト: timasq/pyquil
def Z(qubit):
    """Produces the Z instruction.

    Z = [[1, 0],
         [0, -1]]

    This gate is a single qubit Z-gate.

    :param qubit: The qubit apply the gate to.
    :returns: A Gate object.
    """
    return Gate(name="Z", params=[], qubits=[unpack_qubit(qubit)])
コード例 #12
0
ファイル: gates.py プロジェクト: timasq/pyquil
def T(qubit):
    """Produces the T instruction.

    T = [[1, 0],
         [0, exp(1j * pi / 4)]]

    This gate is a single qubit T-gate. It is the same as RZ(pi/4).

    :param qubit: The qubit apply the gate to.
    :returns: A Gate object.
    """
    return Gate(name="T", params=[], qubits=[unpack_qubit(qubit)])
コード例 #13
0
ファイル: gates.py プロジェクト: timasq/pyquil
def X(qubit):
    """Produces the X instruction.

    X = [[0, 1],
         [1, 0]]

    This gate is a single qubit X-gate.

    :param qubit: The qubit apply the gate to.
    :returns: A Gate object.
    """
    return Gate(name="X", params=[], qubits=[unpack_qubit(qubit)])
コード例 #14
0
def X(qubit: QubitDesignator) -> Gate:
    """Produces the X ("NOT") gate::

        X = [[0, 1],
             [1, 0]]

    This gate is a single qubit X-gate.

    :param qubit: The qubit apply the gate to.
    :returns: A Gate object.
    """
    return Gate(name="X", params=[], qubits=[unpack_qubit(qubit)])
コード例 #15
0
def S(qubit: QubitDesignator) -> Gate:
    """Produces the S gate::

        S = [[1, 0],
             [0, 1j]]

    This gate is a single qubit S-gate.

    :param qubit: The qubit apply the gate to.
    :returns: A Gate object.
    """
    return Gate(name="S", params=[], qubits=[unpack_qubit(qubit)])
コード例 #16
0
def Y(qubit: QubitDesignator) -> Gate:
    """Produces the Y gate::

        Y = [[0, 0 - 1j],
             [0 + 1j, 0]]

    This gate is a single qubit Y-gate.

    :param qubit: The qubit apply the gate to.
    :returns: A Gate object.
    """
    return Gate(name="Y", params=[], qubits=[unpack_qubit(qubit)])
コード例 #17
0
ファイル: gates.py プロジェクト: timasq/pyquil
def Y(qubit):
    """Produces the Y instruction.

    Y = [[0, 0 - 1j],
         [0 + 1j, 0]]

    This gate is a single qubit Y-gate.

    :param qubit: The qubit apply the gate to.
    :returns: A Gate object.
    """
    return Gate(name="Y", params=[], qubits=[unpack_qubit(qubit)])
コード例 #18
0
ファイル: gates.py プロジェクト: timasq/pyquil
def S(qubit):
    """Produces the S instruction.

    S = [[1, 0],
         [0, 1j]]

    This gate is a single qubit S-gate.

    :param qubit: The qubit apply the gate to.
    :returns: A Gate object.
    """
    return Gate(name="S", params=[], qubits=[unpack_qubit(qubit)])
コード例 #19
0
ファイル: gates.py プロジェクト: zero-cooper/pyquil
def RX(angle, qubit):
    """Produces the RX gate::

        RX(phi) = [[cos(phi / 2), -1j * sin(phi / 2)],
                   [-1j * sin(phi / 2), cos(phi / 2)]]

    This gate is a single qubit X-rotation.

    :param angle: The angle to rotate around the x-axis on the bloch sphere.
    :param qubit: The qubit apply the gate to.
    :returns: A Gate object.
    """
    return Gate(name="RX", params=[angle], qubits=[unpack_qubit(qubit)])
コード例 #20
0
def quil_gates(native_gates=None):
    """Generates quil versions of a gate set (the QSCOUT native gates, by default).

    :returns: A mapping of gate names to functions that take classical parameters and
        qubit indices and build pyquil gates.
    :rtype: dict

    .. warning::
        PyQuil simulators will give an error if QSCOUT native gates are passed to them!
    """
    dkt = {}
    if native_gates is None:
        from qscout.v1.std import NATIVE_GATES

        native_gates = NATIVE_GATES

    gates = {}

    for gate in native_gates:
        if gate.ideal_unitary is None:
            continue
        # pyquil expects non-parametrized gates to be matrices and
        # parametrized ones to be functions that return matrices.
        quil_name = gate.name.upper()
        classical_count = len(gate.classical_parameters)
        if classical_count == 0:
            gates[quil_name] = (
                lambda quil_name, classical_count: (lambda *args: Gate(
                    name=quil_name,
                    params=args[:classical_count],
                    qubits=[unpack_qubit(q) for q in args[classical_count:]],
                )))(quil_name, classical_count)
        else:
            gates[quil_name] = (lambda quil_name: (lambda *args: Gate(
                name=quil_name,
                params=[],
                qubits=[unpack_qubit(q) for q in args],
            )))(quil_name)
    return gates
コード例 #21
0
ファイル: gates.py プロジェクト: timasq/pyquil
def PHASE(angle, qubit):
    """Produces the PHASE instruction.

    PHASE(phi) = [[1, 0],
                  [0, exp(1j * phi)]]

    This is the same as the RZ gate.

    :param angle: The angle to rotate around the z-axis on the bloch sphere.
    :param qubit: The qubit apply the gate to.
    :returns: A Gate object.
    """
    return Gate(name="PHASE", params=[angle], qubits=[unpack_qubit(qubit)])
コード例 #22
0
ファイル: gates.py プロジェクト: timasq/pyquil
def RZ(angle, qubit):
    """Produces the RZ instruction.

    RZ(phi) = [[cos(phi / 2) - 1j * sin(phi / 2), 0]
               [0, cos(phi / 2) + 1j * sin(phi / 2)]]

    This gate is a single qubit Z-rotation.

    :param angle: The angle to rotate around the z-axis on the bloch sphere.
    :param qubit: The qubit apply the gate to.
    :returns: A Gate object.
    """
    return Gate(name="RZ", params=[angle], qubits=[unpack_qubit(qubit)])
コード例 #23
0
ファイル: gates.py プロジェクト: timasq/pyquil
def RY(angle, qubit):
    """Produces the RY instruction.

    RY(phi) = [[cos(phi / 2), -sin(phi / 2)],
               [sin(phi / 2), cos(phi / 2)]]

    This gate is a single qubit Y-rotation.

    :param angle: The angle to rotate around the y-axis on the bloch sphere.
    :param qubit: The qubit apply the gate to.
    :returns: A Gate object.
    """
    return Gate(name="RY", params=[angle], qubits=[unpack_qubit(qubit)])
コード例 #24
0
ファイル: gates.py プロジェクト: vishalbelsare/pyquil
def MEASURE(qubit: QubitDesignator, classical_reg: Optional[MemoryReferenceDesignator]) -> Measurement:
    """
    Produce a MEASURE instruction.

    :param qubit: The qubit to measure.
    :param classical_reg: The classical register to measure into, or None.
    :return: A Measurement instance.
    """
    qubit = unpack_qubit(qubit)
    if classical_reg is None:
        address = None
    else:
        address = unpack_classical_reg(classical_reg)
    return Measurement(qubit, address)
コード例 #25
0
ファイル: gates.py プロジェクト: vishalbelsare/pyquil
def RESET(qubit_index: Optional[QubitDesignator] = None) -> Union[Reset, ResetQubit]:
    """
    Reset all qubits or just one specific qubit.

    :param qubit_index: The qubit to reset.
        This can be a qubit's index, a Qubit, or a QubitPlaceholder.
        If None, reset all qubits.
    :returns: A Reset or ResetQubit Quil AST expression corresponding to a global or targeted
        reset, respectively.
    """
    if qubit_index is not None:
        return ResetQubit(unpack_qubit(qubit_index))
    else:
        return Reset()
コード例 #26
0
ファイル: gates.py プロジェクト: vishalbelsare/pyquil
def XY(angle: ParameterDesignator, q1: QubitDesignator, q2: QubitDesignator) -> Gate:
    """Produces a parameterized ISWAP gate::

        XY(phi) = [[1,               0,               0, 0],
                   [0,      cos(phi/2), 1j * sin(phi/2), 0],
                   [0, 1j * sin(phi/2),      cos(phi/2), 0],
                   [0,               0,               0, 1]

    :param angle: The angle of the rotation to apply to the population 1 subspace.
    :param q1: Qubit 1.
    :param q2: Qubit 2.
    :returns: A Gate object.
    """
    return Gate(name="XY", params=[angle], qubits=[unpack_qubit(q) for q in (q1, q2)])
コード例 #27
0
ファイル: gates.py プロジェクト: vishalbelsare/pyquil
def SWAP(q1: QubitDesignator, q2: QubitDesignator) -> Gate:
    """Produces a SWAP gate which swaps the state of two qubits::

        SWAP = [[1, 0, 0, 0],
                [0, 0, 1, 0],
                [0, 1, 0, 0],
                [0, 0, 0, 1]]


    :param q1: Qubit 1.
    :param q2: Qubit 2.
    :returns: A Gate object.
    """
    return Gate(name="SWAP", params=[], qubits=[unpack_qubit(q) for q in (q1, q2)])
コード例 #28
0
ファイル: gates.py プロジェクト: timasq/pyquil
def I(qubit):
    """Produces the I instruction.

    I = [1, 0]
        [0, 1]

    This gate is a single qubit identity gate.
    Note that this gate is different that the NOP instruction as noise channels
    are typically still applied during the duration of identity gates. Identities will
    also block parallelization like any other gate.

    :param qubit: The qubit apply the gate to.
    :returns: A Gate object.
    """
    return Gate(name="I", params=[], qubits=[unpack_qubit(qubit)])
コード例 #29
0
ファイル: gates.py プロジェクト: timasq/pyquil
def CPHASE(angle, control, target):
    """Produces a CPHASE instruction, which is a synonym for CPHASE11.

    CPHASE(phi) = diag([1, 1, 1, exp(1j * phi)])

    This gate applies to two qubit arguments to produce the variant of the controlled phase
    instruction that affects the state 11.

    :param angle: The input phase angle to apply when both qubits are in the excited state.
    :param control: Qubit 1.
    :param target: Qubit 2.
    :returns: A Gate object.
    """
    qubits = [unpack_qubit(q) for q in (control, target)]
    return Gate(name="CPHASE", params=[angle], qubits=qubits)
コード例 #30
0
ファイル: gates.py プロジェクト: timasq/pyquil
def CPHASE00(angle, control, target):
    """Produces a CPHASE00 instruction.

    CPHASE00(phi) = diag([exp(1j * phi), 1, 1, 1])

    This gate applies to two qubit arguments to produce the variant of the controlled phase
    instruction that affects the state 00.

    :param angle: The input phase angle to apply when both qubits are in the ground state.
    :param control: Qubit 1.
    :param target: Qubit 2.
    :returns: A Gate object.
    """
    qubits = [unpack_qubit(q) for q in (control, target)]
    return Gate(name="CPHASE00", params=[angle], qubits=qubits)