Example #1
0
def test_defgate():
    dg = DefGate("TEST", np.array([[1., 0.],
                                   [0., 1.]]))
    assert dg.out() == "DEFGATE TEST:\n    1.0, 0.0\n    0.0, 1.0\n"
    test = dg.get_constructor()
    tg = test(DirectQubit(1), DirectQubit(2))
    assert tg.out() == "TEST 1 2"
Example #2
0
def test_defgate():
    # regression test for https://github.com/rigetti/pyquil/issues/1059
    theta = np.pi / 2
    U = np.array([[1, 0, 0, 0], [0, 1, 0, 0],
                  [0, 0, np.cos(theta / 2), -1j * np.sin(theta / 2)],
                  [0, 0, -1j * np.sin(theta / 2),
                   np.cos(theta / 2)]])

    gate_definition = DefGate('U_test', U)
    U_test = gate_definition.get_constructor()

    p = Program()
    p += gate_definition
    p += X(1)
    p += U_test(1, 0)
    qam = PyQVM(n_qubits=2, quantum_simulator_type=NumpyWavefunctionSimulator)
    qam.execute(p)
    wf1 = qam.wf_simulator.wf
    should_be = np.zeros((2, 2), dtype=np.complex128)
    one_over_sqrt2 = 1 / np.sqrt(2)
    should_be[0, 1] = one_over_sqrt2
    should_be[1, 1] = -1j * one_over_sqrt2
    np.testing.assert_allclose(wf1, should_be)

    # Ensure the output of the custom U_test gate matches the standard RX gate. Something like
    # RX(theta, 0).controlled(1) would be a more faithful reproduction of U_test, but
    # NumpyWavefunctionSimulator doesn't (yet) support gate modifiers, so just apply the RX gate
    # unconditionally.
    p = Program()
    p += X(1)
    p += RX(theta, 0)
    qam = PyQVM(n_qubits=2, quantum_simulator_type=NumpyWavefunctionSimulator)
    qam.execute(p)
    wf2 = qam.wf_simulator.wf
    np.testing.assert_allclose(wf1, wf2)
Example #3
0
def test_defgate():
    dg = DefGate("TEST", np.array([[0 + 0.5j, 0.5], [0.5, 0 - 0.5j]]))
    assert dg.out(
    ) == "DEFGATE TEST:\n    0.0+0.5i, 0.5+0.0i\n    0.5+0.0i, 0.0-0.5i\n"
    test = dg.get_constructor()
    tg = test(DirectQubit(1), DirectQubit(2))
    assert tg.out() == "TEST 1 2"
Example #4
0
def controlled_i_X(n, a, b):
    theta = Parameter('theta')
    cirx = controlled_i(
        np.array([[quil_cos(theta / 2), -1j * quil_sin(theta / 2)],
                  [-1j * quil_sin(theta / 2),
                   quil_cos(theta / 2)]]))
    CIRX = DefGate('CIRX', cirx, [theta])
    return str(CIRX) + '\n' + str(CIRX.get_constructor()(n)(a, b))
Example #5
0
def controlled_sY(program):
    csy = np.array([[1., 0., 0., 0.], [0., 1., 0., 0.], [0., 0., 0., -1.j],
                    [0., 0., 1.j, 0.]])

    dg = DefGate('CSY', csy)
    program.inst(dg)

    return dg.get_constructor()
Example #6
0
def test_dagger():
    # these gates are their own inverses
    p = Program().inst(I(0), X(0), Y(0), Z(0),
                       H(0), CNOT(0, 1), CCNOT(0, 1, 2),
                       SWAP(0, 1), CSWAP(0, 1, 2))
    assert p.dagger().out() == 'CSWAP 0 1 2\nSWAP 0 1\n' \
                               'CCNOT 0 1 2\nCNOT 0 1\nH 0\n' \
                               'Z 0\nY 0\nX 0\nI 0\n'

    # these gates require negating a parameter
    p = Program().inst(PHASE(pi, 0), RX(pi, 0), RY(pi, 0),
                       RZ(pi, 0), CPHASE(pi, 0, 1),
                       CPHASE00(pi, 0, 1), CPHASE01(pi, 0, 1),
                       CPHASE10(pi, 0, 1), PSWAP(pi, 0, 1))
    assert p.dagger().out() == 'PSWAP(-pi) 0 1\n' \
                               'CPHASE10(-pi) 0 1\n' \
                               'CPHASE01(-pi) 0 1\n' \
                               'CPHASE00(-pi) 0 1\n' \
                               'CPHASE(-pi) 0 1\n' \
                               'RZ(-pi) 0\n' \
                               'RY(-pi) 0\n' \
                               'RX(-pi) 0\n' \
                               'PHASE(-pi) 0\n'

    # these gates are special cases
    p = Program().inst(S(0), T(0), ISWAP(0, 1))
    assert p.dagger().out() == 'PSWAP(pi/2) 0 1\n' \
                               'RZ(pi/4) 0\n' \
                               'PHASE(-pi/2) 0\n'

    # must invert defined gates
    G = np.array([[0, 1], [0 + 1j, 0]])
    p = Program().defgate("G", G).inst(("G", 0))
    assert p.dagger().out() == 'DEFGATE G-INV:\n' \
                               '    0.0, -i\n' \
                               '    1.0, 0.0\n\n' \
                               'G-INV 0\n'

    # can also pass in a list of inverses
    inv_dict = {"G": "J"}
    p = Program().defgate("G", G).inst(("G", 0))
    assert p.dagger(inv_dict=inv_dict).out() == 'J 0\n'

    # defined parameterized gates cannot auto generate daggered version https://github.com/rigetticomputing/pyquil/issues/304
    theta = Parameter('theta')
    gparam_matrix = np.array([[quil_cos(theta / 2), -1j * quil_sin(theta / 2)],
                             [-1j * quil_sin(theta / 2), quil_cos(theta / 2)]])
    g_param_def = DefGate('GPARAM', gparam_matrix, [theta])
    p = Program(g_param_def)
    with pytest.raises(TypeError):
        p.dagger()

    # defined parameterized gates should passback parameters https://github.com/rigetticomputing/pyquil/issues/304
    GPARAM = g_param_def.get_constructor()
    p = Program(GPARAM(pi)(1, 2))
    assert p.dagger().out() == 'GPARAM-INV(pi) 1 2\n'
Example #7
0
def test_def_gate():
    sqrt_x = DefGate("SQRT-X", np.array([[0.5 + 0.5j, 0.5 - 0.5j], [0.5 - 0.5j, 0.5 + 0.5j]]))
    hadamard = DefGate("HADAMARD", np.array([[1 / np.sqrt(2), 1 / np.sqrt(2)], [1 / np.sqrt(2), -1 / np.sqrt(2)]]))
    defgates = """
DEFGATE SQRT-X:
    0.5+0.5i, 0.5-0.5i
    0.5-0.5i, 0.5+0.5i

DEFGATE HADAMARD:
    1/SQRT(2), 1/SQRT(2)
    1/SQRT(2), -1/SQRT(2)
    """.strip()

    parse_equals(defgates, sqrt_x, hadamard)
Example #8
0
def controlled_Ry(program):
    theta = Parameter('theta')

    cry = np.array([[1., 0., 0., 0.], [0., 1., 0., 0.],
                    [0., 0.,
                     quil_cos(0.5 * theta),
                     quil_sin(0.5 * theta)],
                    [0., 0., -quil_sin(0.5 * theta),
                     quil_cos(0.5 * theta)]])

    dg = DefGate('CRY', cry, [theta])
    program.inst(dg)

    return dg.get_constructor()
Example #9
0
def get_combined_gate(matrix: np.ndarray, name: str) -> Gate:
    """
    :param matrix: The matrix of the combined gate  
    :param name: The of the combined gate
    :return: A Gate (matrix, noisy_name) corresponding to the representation [matrix, name]
            
    :rtype: Gate
    """

    p = Program()
    combined_gate_definition = DefGate(name, matrix)
    p.inst(combined_gate_definition)
    combined_gate = combined_gate_definition.get_constructor()
    return combined_gate
Example #10
0
def test_def_gate_with_parameters():
    theta = Parameter('theta')
    rx = np.array([[quil_cos(theta / 2), -1j * quil_sin(theta / 2)],
                   [-1j * quil_sin(theta / 2), quil_cos(theta / 2)]])

    p = Program().defgate("RX", rx, [theta])
    assert p.out() == 'DEFGATE RX(%theta):\n' \
                      '    cos(%theta/2), -i*sin(%theta/2)\n' \
                      '    -i*sin(%theta/2), cos(%theta/2)\n\n'

    dg = DefGate('MY_RX', rx, [theta])
    MY_RX = dg.get_constructor()
    p = Program().inst(MY_RX(np.pi)(0))
    assert p.out() == 'MY_RX(pi) 0\n'
Example #11
0
 def exitDefGate(self, ctx):
     # type: (QuilParser.DefGateContext) -> None
     gate_name = ctx.name().getText()
     if ctx.variable():
         raise NotImplementedError("%variables are not supported yet")
     matrix = _matrix(ctx.matrix())
     self.result.append(DefGate(gate_name, matrix))
Example #12
0
def CRX_diags(n):
    M = np.identity(2**n).astype(object)
    parameters = [Parameter('p' + str(i)) for i in range(2**(n - 1))]
    for i, p in enumerate(parameters):
        M[2 * i:2 * (i + 1), 2 * i:2 * (i + 1)] = X(p)
    CRX_diag = DefGate('CRX_diag_{}'.format(n), M, parameters)
    return str(CRX_diag)
Example #13
0
def test_def_gate_with_parameters():
    theta = Parameter("theta")
    rx = np.array([
        [quil_cos(theta / 2), -1j * quil_sin(theta / 2)],
        [-1j * quil_sin(theta / 2),
         quil_cos(theta / 2)],
    ])

    p = Program().defgate("RX", rx, [theta])
    assert (p.out() == "DEFGATE RX(%theta):\n"
            "    COS(%theta/2), -i*SIN(%theta/2)\n"
            "    -i*SIN(%theta/2), COS(%theta/2)\n\n")

    dg = DefGate("MY_RX", rx, [theta])
    MY_RX = dg.get_constructor()
    p = Program().inst(MY_RX(np.pi)(0))
    assert p.out() == "MY_RX(pi) 0\n"
def state_two_prep(state, qubits):
    if not isinstance(state, Program):
        print("The input *state* must be in the form of a PyQuil Program")
    # Define the new gate from a matrix
    theta = Parameter('theta')
    crtest = np.array([[1, 0, 0, 0], [0, 1, 0, 0],
                       [0, 0, quil_cos(theta / 2), -quil_sin(theta / 2)],
                       [0, 0, quil_sin(theta / 2),
                        quil_cos(theta / 2)]])

    gate_definition = DefGate('CRTEST', crtest, [theta])
    CRTEST = gate_definition.get_constructor()

    state += gate_definition
    state += H(qubits[0])
    state += Z(qubits[0])
    state += CRTEST(np.pi / 42)(qubits[0], qubits[1])

    return state
Example #15
0
 def exitDefGate(self, ctx: QuilParser.DefGateContext):
     gate_name = ctx.name().getText()
     gate_type = ctx.gatetype()
     if gate_type and gate_type.getText() == 'PERMUTATION':
         permutation = _permutation(ctx.matrix())
         self.result.append(DefPermutationGate(gate_name, permutation))
     else:
         matrix = _matrix(ctx.matrix())
         parameters = [_variable(v) for v in ctx.variable()]
         self.result.append(DefGate(gate_name, matrix, parameters))
Example #16
0
    def defgate(self, name, matrix):
        """
        Define a new static gate.

        :param name: (int) The name of the gate (str).
        :param matrix: List of lists or Numpy 2d array.
        :return: The Program instance.
        """
        self.defined_gates.append(DefGate(name, matrix))
        return self
Example #17
0
    def defgate(self, name, matrix):
        """
        Define a new static gate.

        :param string name: The name of the gate.
        :param array-like matrix: List of lists or Numpy 2d array.
        :return: The Program instance.
        :rtype: Program
        """
        self.defined_gates.append(DefGate(name, matrix))
        return self
Example #18
0
def test_def_gate_with_variables():
    # Note that technically the RX gate includes -i instead of just i but this messes a bit with the test since
    # it's not smart enough to figure out that -1*i == -i
    theta = Parameter('theta')
    rx = np.array([[quil_cos(theta / 2), 1j * quil_sin(theta / 2)],
                   [1j * quil_sin(theta / 2), quil_cos(theta / 2)]])

    defgate = 'DEFGATE RX(%theta):\n' \
              '    cos(%theta/2), i*sin(%theta/2)\n' \
              '    i*sin(%theta/2), cos(%theta/2)\n\n'

    parse_equals(defgate, DefGate('RX', rx, [theta]))
Example #19
0
def test_def_gate_with_variables():
    # Note that technically the RX gate includes -i instead of just i but this messes a bit with
    # the test since it's not smart enough to figure out that -1*i == -i
    theta = Parameter("theta")
    rx = np.array([
        [quil_cos(theta / 2), 1j * quil_sin(theta / 2)],
        [1j * quil_sin(theta / 2),
         quil_cos(theta / 2)],
    ])

    defgate = "DEFGATE RX(%theta):\n" "    COS(%theta/2), i*SIN(%theta/2)\n" "    i*SIN(%theta/2), COS(%theta/2)\n\n"

    parse_equals(defgate, DefGate("RX", rx, [theta]))
def create_CH():
    """
    Defining control RX pyquil Gate

    :return: instruction for CRZ
    """

    ch = np.array([[1, 0, 0, 0],
                    [0, 1, 0, 0],
                    [0, 0, 1/sqrt(2), 1/sqrt(2)],
                    [0, 0, 1/sqrt(2), -1/sqrt(2)]])

    dg = DefGate('CH', ch)
    return dg
def u2_replacement(phi: float, lam: float):
    """ implemented with a custom gate """
    # implemented with X90 pulse: https://qiskit.org/documentation/stubs/qiskit.circuit.library.U2Gate.html
    # p = Program()
    # p += RZ(phi + np.pi/2, 0)
    # p += RX(np.pi/2, 0)
    # p += RZ(lam - np.pi/2, 0)

    phi_param = Parameter('phi')
    lam_param = Parameter('lam')
    matrix = np.array(
        [[1 / np.sqrt(2), -quil_exp(1j * lam_param) * 1 / np.sqrt(2)],
         [
             quil_exp(1j * phi_param) * 1 / np.sqrt(2),
             quil_exp(1j * (phi_param + lam_param)) * 1 / np.sqrt(2)
         ]])
    definition = DefGate('U2', matrix, [phi_param, lam_param])
    U2 = definition.get_constructor()
    p = Program()
    p += definition
    p += U2(phi, lam)(0)

    return p
def u3_replacement(theta: float, phi: float, lam: float):
    """ implemented with a custom gate """

    # implemented with two X90 pulse: https://arxiv.org/pdf/1707.03429.pdf
    # p = Program()
    # p += RZ(phi + 3*np.pi, 0)
    # p += RX(np.pi/2, 0)
    # p += RZ(np.pi + theta, 0)
    # p += RX(np.pi/2, 0)
    # p += RZ(lam, 0)
    # formula from https://qiskit.org/documentation/stubs/qiskit.circuit.library.U3Gate.html (13.07.2020) gives wrong results
    # p = Program()
    # p += RZ(phi - np.pi/2, 0)
    # p += RX(np.pi/2, 0)
    # p += RZ(np.pi - theta, 0)
    # p += RX(np.pi/2, 0)
    # p += RZ(lam - np.pi/2, 0)

    theta_param = Parameter('theta')
    phi_param = Parameter('phi')
    lam_param = Parameter('lam')
    matrix = np.array(
        [[
            quil_cos(theta_param / 2),
            -quil_exp(1j * lam_param) * quil_sin(theta_param / 2)
        ],
         [
             quil_exp(1j * phi_param) * quil_sin(theta_param / 2),
             quil_exp(1j * (phi_param + lam_param)) * quil_cos(theta_param / 2)
         ]])
    definition = DefGate('U3', matrix, [theta_param, phi_param, lam_param])
    U3 = definition.get_constructor()
    p = Program()
    p += definition
    p += U3(theta, phi, lam)(0)

    return p
def create_CRX():
    """
    Defining control RX pyquil Gate

    :return: instruction for CRX
    """

    theta = Parameter('theta')
    crx = np.array([[1, 0, 0, 0],
                    [0, 1, 0, 0],
                    [0, 0, quil_cos(theta / 2), -1j * quil_sin(theta / 2)],
                    [0, 0, -1j * quil_sin(theta / 2), quil_cos(theta / 2)]])

    dg = DefGate('CRX', crx, [theta])
    return dg
def create_CRZ():
    """
    Defining control RX pyquil Gate

    :return: instruction for CRZ
    """

    theta = Parameter('theta')
    crz = np.array([[1, 0, 0, 0],
                    [0, 1, 0, 0],
                    [0, 0, quil_exp(-1j*theta / 2), 0],
                    [0, 0, 0, quil_exp(1j*theta / 2)]])

    dg = DefGate('CRZ', crz, [theta])
    return dg
Example #25
0
    def defgate(self, name, matrix, parameters=None):
        """
        Define a new static gate.

        .. note::

            The matrix elements along each axis are ordered by bitstring. For two qubits the order
            is ``00, 01, 10, 11``, where the the bits **are ordered in reverse** by the qubit index,
            i.e., for qubits 0 and 1 the bitstring ``01`` indicates that qubit 0 is in the state 1.
            See also :ref:`the related documentation section in the QVM Overview <basis-ordering>`.


        :param string name: The name of the gate.
        :param array-like matrix: List of lists or Numpy 2d array.
        :param list parameters: list of parameters that are used in this gate
        :return: The Program instance.
        :rtype: Program
        """
        return self.inst(DefGate(name, matrix, parameters))
Example #26
0
    def defgate(
        self,
        name: str,
        matrix: Union[List[List[Any]], np.ndarray, np.matrix],
        parameters: Optional[List[Parameter]] = None,
    ) -> "Program":
        """
        Define a new static gate.

        .. note::

            The matrix elements along each axis are ordered by bitstring. For two qubits the order
            is ``00, 01, 10, 11``, where the the bits **are ordered in reverse** by the qubit index,
            i.e., for qubits 0 and 1 the bitstring ``01`` indicates that qubit 0 is in the state 1.
            See also :ref:`the related docs in the WavefunctionSimulator Overview <basis_ordering>`.


        :param name: The name of the gate.
        :param matrix: List of lists or Numpy 2d array.
        :param parameters: list of parameters that are used in this gate
        :return: The Program instance.
        """
        return self.inst(DefGate(name, matrix, parameters))
Example #27
0
 def def_gate_matrix(self, name, variables, matrix):
     return DefGate(name, matrix=matrix, parameters=variables)
Example #28
0
def test_prog_merge():
    prog_0 = Program(X(0))
    prog_1 = Program(Y(0))
    assert merge_programs([prog_0, prog_1]).out() == (prog_0 + prog_1).out()
    test_def = DefGate("test", np.eye(2))
    TEST = test_def.get_constructor()
    prog_0.inst(test_def)
    prog_0.inst(TEST(0))
    prog_1.inst(test_def)
    prog_1.inst(TEST(0))
    assert (merge_programs([prog_0, prog_1]).out() == """DEFGATE test:
    1.0, 0
    0, 1.0

X 0
test 0
Y 0
test 0
""")
    perm_def = DefPermutationGate("PERM", [0, 1, 3, 2])
    PERM = perm_def.get_constructor()
    prog_0.inst(perm_def)
    prog_0.inst(PERM(0, 1))
    prog_1.inst(perm_def)
    prog_1.inst(PERM(1, 0))
    assert (merge_programs([prog_0,
                            prog_1]).out() == """DEFGATE PERM AS PERMUTATION:
    0, 1, 3, 2
DEFGATE test:
    1.0, 0
    0, 1.0

X 0
test 0
PERM 0 1
Y 0
test 0
PERM 1 0
""")
    assert (merge_programs([
        Program("DECLARE ro BIT[1]"),
        Program("H 0"),
        Program("MEASURE 0 ro[0]")
    ]).out() == """DECLARE ro BIT[1]
H 0
MEASURE 0 ro[0]
""")

    q0 = QubitPlaceholder()
    q0_str = "{" + str(q0) + "}"
    p0 = Program(X(q0))
    p1 = Program(Z(q0))
    merged = merge_programs([p0, p1])
    assert (str(merged) == f"""X {q0_str}
Z {q0_str}
""")
    assert (address_qubits(merged, {q0: 1}).out() == """X 1
Z 1
""")
    q1 = QubitPlaceholder()
    p2 = Program(Z(q1))
    assert (address_qubits(merge_programs([p0, p2]), {
        q0: 1,
        q1: 2
    }).out() == """X 1
Z 2
""")
    p0 = address_qubits(p0, {q0: 2})
    p1 = address_qubits(p1, {q0: 1})
    assert (merge_programs([p0, p1]).out() == """X 2
Z 1
""")
Example #29
0
def test_defgate_param():
    dgp = DefGate("TEST", [[1.0, 0.0], [0.0, 1.0]])
    assert dgp.out() == "DEFGATE TEST:\n    1.0, 0\n    0, 1.0\n"
    test = dgp.get_constructor()
    tg = test(Qubit(1))
    assert tg.out() == "TEST 1"
Example #30
0
def test_defgate_non_unitary_should_throw_error():
    with pytest.raises(ValueError) as error_info:
        DefGate("TEST", np.array([[0, 1], [2, 3]]))
    assert str(error_info.value) == "Matrix must be unitary."
Example #31
0
from pyquil.quil import Program
from pyquil.gates import *
from pyquil.parameters import Parameter, quil_sin, quil_cos
from pyquil.quilbase import DefGate
#from pyquil.api import QVMConnection
from referenceqvm.api import QVMConnection
import numpy as np
theta = Parameter('theta')
cry = np.array([[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, quil_cos(
    theta / 2), -1 * quil_sin(theta / 2)], [0.0, 0.0, quil_sin(theta / 2), quil_cos(theta / 2)]])
dg = DefGate('CRY', cry, [theta])
CRY = dg.get_constructor()
p = Program()
p.inst(dg)
p.inst(X(0))
p.inst(X(1))
p.inst(CRY(4.304)(0, 2))
qvm = QVMConnection()
wf = qvm.wavefunction(p)
print(wf)