Exemplo n.º 1
0
def test_eval():
    x = Parameter('x')
    assert substitute(x, {x: 5}) == 5

    y = Parameter('y')
    assert substitute(x + y, {x: 5, y: 6}) == 11
    assert substitute(x + y, {x: 5}) == 5 + y
    assert substitute(quil_exp(x), {y: 5}) != np.exp(5)
    assert substitute(quil_exp(x), {x: 5}) == np.exp(5)

    assert np.isclose(substitute(quil_sin(x * x**2 / y), {
        x: 5.0,
        y: 10.0
    }), np.sin(12.5))
    assert np.isclose(substitute(quil_sqrt(x), {
        x: 5.0,
        y: 10.0
    }), np.sqrt(5.0))
    assert np.isclose(substitute(quil_cis(x), {
        x: 5.0,
        y: 10.0
    }), np.exp(1j * 5.0))
    assert np.isclose(substitute(x - y, {x: 5.0, y: 10.0}), -5.)

    assert substitute(quil_cis(x), {y: 5}) == quil_cis(x)
    assert np.allclose(substitute_array([quil_sin(x), quil_cos(x)], {x: 5}),
                       [np.sin(5), np.cos(5)])
Exemplo n.º 2
0
def _apply_function(func, arg):
    # type: (QuilParser.FunctionContext, Any) -> Any
    if isinstance(arg, Expression):
        if func.SIN():
            return quil_sin(arg)
        elif func.COS():
            return quil_cos(arg)
        elif func.SQRT():
            return quil_sqrt(arg)
        elif func.EXP():
            return quil_exp(arg)
        elif func.CIS():
            return quil_cis(arg)
        else:
            raise RuntimeError("Unexpected function to apply: " +
                               func.getText())
    else:
        if func.SIN():
            return sin(arg)
        elif func.COS():
            return cos(arg)
        elif func.SQRT():
            return sqrt(arg)
        elif func.EXP():
            return exp(arg)
        elif func.CIS():
            return cos(arg) + complex(0, 1) * sin(arg)
        else:
            raise RuntimeError("Unexpected function to apply: " +
                               func.getText())
Exemplo n.º 3
0
 def apply_fun(self, fun, arg):
     if fun == "SIN":
         return quil_sin(arg) if isinstance(arg, Expression) else np.sin(arg)
     if fun == "COS":
         return quil_cos(arg) if isinstance(arg, Expression) else np.cos(arg)
     if fun == "SQRT":
         return quil_sqrt(arg) if isinstance(arg, Expression) else np.sqrt(arg)
     if fun == "EXP":
         return quil_exp(arg) if isinstance(arg, Expression) else np.exp(arg)
     if fun == "CIS":
         return quil_cis(arg) if isinstance(arg, Expression) else np.cos(arg) + 1j * np.sin(arg)
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
Exemplo n.º 6
0
def test_converting_parametrized_custom_gate_to_pyquil_adds_its_definition_to_program(
):
    x, y, theta = sympy.symbols("x, y, theta")
    # Clearly, the below gate is not unitary. For the purpose of this test
    # it does not matter though.
    custom_gate = CustomGate(
        sympy.Matrix([
            [sympy.cos(x + y), sympy.sin(theta), 0, 0],
            [-sympy.sin(theta), sympy.cos(x + y), 0, 0],
            [0, 0, sympy.sqrt(x), sympy.exp(y)],
            [0, 0, 1.0, sympy.I],
        ]),
        (0, 2),
        "my_gate",
    )

    program = pyquil.Program()
    convert_to_pyquil(custom_gate, program)

    quil_x = pyquil.quil.Parameter("x")
    quil_y = pyquil.quil.Parameter("y")
    quil_theta = pyquil.quil.Parameter("theta")

    expected_pyquil_matrix = np.array([
        [
            quilatom.quil_cos(quil_x + quil_y),
            quilatom.quil_sin(quil_theta), 0, 0
        ],
        [
            -quilatom.quil_sin(quil_theta),
            quilatom.quil_cos(quil_x + quil_y), 0, 0
        ],
        [0, 0, quilatom.quil_sqrt(quil_x),
         quilatom.quil_exp(quil_y)],
        [0, 0, 1.0, 1j],
    ])

    # Note: we cannot replace this with a single assertion. This is because
    # the order of custom_gate.symbolic_params is not known.
    gate_definition = program.defined_gates[0]
    assert len(program.defined_gates) == 1
    assert len(gate_definition.parameters) == 3
    assert set(gate_definition.parameters) == {quil_x, quil_y, quil_theta}
    assert np.array_equal(gate_definition.matrix, expected_pyquil_matrix)
Exemplo n.º 7
0
def test_substitute_memory_reference():
    x_0 = MemoryReference("x", 0, declared_size=2)
    x_1 = MemoryReference("x", 1, declared_size=2)

    # complete substitutions

    assert substitute(x_0, {x_0: 5}) == 5

    assert substitute(x_0 + x_1, {x_0: +5, x_1: -5}) == 0
    assert substitute(x_0 - x_1, {x_0: +5, x_1: -5}) == 10
    assert substitute(x_0 * x_1, {x_0: +5, x_1: -5}) == -25
    assert substitute(x_0 / x_1, {x_0: +5, x_1: -5}) == -1

    assert substitute(x_0 * x_0**2 / x_1, {x_0: 5, x_1: 10}) == 12.5

    assert np.isclose(substitute(quil_exp(x_0), {x_0: 5, x_1: 10}), np.exp(5))
    assert np.isclose(substitute(quil_sin(x_0), {x_0: 5, x_1: 10}), np.sin(5))
    assert np.isclose(substitute(quil_cos(x_0), {x_0: 5, x_1: 10}), np.cos(5))
    assert np.isclose(substitute(quil_sqrt(x_0), {
        x_0: 5,
        x_1: 10
    }), np.sqrt(5))
    assert np.isclose(substitute(quil_cis(x_0), {
        x_0: 5,
        x_1: 10
    }), np.exp(1j * 5.0))

    # incomplete substitutions

    y = MemoryReference("y", 0, declared_size=1)
    z = MemoryReference("z", 0, declared_size=1)

    assert substitute(y + z, {y: 5}) == 5 + z

    assert substitute(quil_cis(z), {y: 5}) == quil_cis(z)

    # array substitution pass-through

    a = MemoryReference("a", 0, declared_size=1)

    assert np.allclose(substitute_array([quil_sin(a), quil_cos(a)], {a: 5}),
                       [np.sin(5), np.cos(5)])
Exemplo n.º 8
0
)
def test_quil_parameters_are_converted_to_instance_of_symbol_with_correct_name(
    pyquil_parameter, expected_symbol
):
    assert expression_from_pyquil(pyquil_parameter) == expected_symbol


@pytest.mark.parametrize(
    "pyquil_function_call, expected_function_call",
    [
        (quilatom.quil_cos(2), FunctionCall("cos", (2,))),
        (
            quilatom.quil_sin(quil.Parameter("theta")),
            FunctionCall("sin", (Symbol("theta"),)),
        ),
        (quilatom.quil_exp(quil.Parameter("x")), FunctionCall("exp", (Symbol("x"),))),
        (quilatom.quil_sqrt(np.pi), FunctionCall("sqrt", (np.pi,))),
    ],
)
def test_pyquil_function_calls_are_converted_to_equivalent_function_call(
    pyquil_function_call, expected_function_call
):
    assert expression_from_pyquil(pyquil_function_call) == expected_function_call


@pytest.mark.parametrize(
    "pyquil_expression, expected_function_call",
    [
        (
            quil.Parameter("x") + quil.Parameter("y"),
            FunctionCall("add", (Symbol("x"), Symbol("y"))),
Exemplo n.º 9
0
@pytest.mark.parametrize(
    "sympy_expression, quil_expression",
    [
        (sympy.Symbol("theta"), quil.Parameter("theta")),
        (
            sympy.Mul(sympy.Symbol("theta"), sympy.Symbol("gamma"), evaluate=False),
            quil.Parameter("theta") * quil.Parameter("gamma"),
        ),
        (sympy.cos(sympy.Symbol("theta")), quilatom.quil_cos(quil.Parameter("theta"))),
        (
            sympy.cos(2 * sympy.Symbol("theta")),
            quilatom.quil_cos(2 * quil.Parameter("theta")),
        ),
        (
            sympy.exp(sympy.Symbol("x") - sympy.Symbol("y")),
            quilatom.quil_exp(quil.Parameter("x") - quil.Parameter("y")),
        ),
        (
            sympy.Add(
                sympy.cos(sympy.Symbol("phi")),
                sympy.I * sympy.sin(sympy.Symbol("phi")),
                evaluate=False,
            ),
            quilatom.quil_cos(quil.Parameter("phi"))
            + 1j * quilatom.quil_sin(quil.Parameter("phi")),
        ),
        (
            sympy.Add(
                sympy.Symbol("x"),
                sympy.Mul(sympy.Symbol("y"), (2 + 3j), evaluate=False),
                evaluate=False,