def test_binding_some_params_leaves_free_params(self):
        theta1, theta2, theta3 = sympy.symbols("theta1:4")
        circuit = Circuit(
            [
                RX(theta1)(0),
                RY(theta2)(1),
                RZ(theta3)(0),
                RX(theta2)(0),
            ]
        )

        bound_circuit = circuit.bind({theta1: 0.5, theta3: 3.14})
        assert bound_circuit.free_symbols == [theta2]
    def test_binding_all_params_leaves_no_free_symbols(self):
        alpha, beta, gamma = sympy.symbols("alpha,beta,gamma")
        circuit = Circuit(
            [
                RX(alpha)(0),
                RY(beta)(1),
                RZ(gamma)(0),
                RX(gamma)(0),
            ]
        )
        bound_circuit = circuit.bind({alpha: 0.5, beta: 3.14, gamma: 0})

        assert not bound_circuit.free_symbols
    def test_binding_excessive_params_binds_only_the_existing_ones(self):
        theta1, theta2, theta3 = sympy.symbols("theta1:4")
        other_param = sympy.symbols("other_param")
        circuit = Circuit(
            [
                RX(theta1)(0),
                RY(theta2)(1),
                RZ(theta3)(0),
                RX(theta2)(0),
            ]
        )

        bound_circuit = circuit.bind({theta1: -np.pi, other_param: 42})
        assert bound_circuit.free_symbols == [theta2, theta3]
    def test_circuits_sum_yields_correct_operations(self):
        circuit1 = Circuit()
        circuit1 += H(0)
        circuit1 += CNOT(0, 2)

        circuit2 = Circuit([X(2), YY(sympy.Symbol("theta"))(5)])

        res_circuit = circuit1 + circuit2
        assert res_circuit.operations == [
            H(0),
            CNOT(0, 2),
            X(2),
            YY(sympy.Symbol("theta"))(5),
        ]
        assert res_circuit.n_qubits == 6
    def test_symbols_of_wavefunction_operations_are_present_in_circuits_free_symbols(
        self,
    ):
        alpha, beta = sympy.symbols("alpha, beta")
        circuit = Circuit([RX(alpha)(0), MultiPhaseOperation((beta, 0.5))])

        assert circuit.free_symbols == [alpha, beta]
    def test_appending_to_circuit_yields_correct_operations(self):
        circuit = Circuit()
        circuit += H(0)
        circuit += CNOT(0, 2)

        assert circuit.operations == [H(0), CNOT(0, 2)]
        assert circuit.n_qubits == 3
class TestGates:
    @pytest.fixture
    def simulator(self) -> SymbolicSimulator:
        return SymbolicSimulator()

    @pytest.mark.parametrize(
        "circuit, expected_wavefunction",
        [
            (
                Circuit([RX(Symbol("theta"))(0)]),
                Wavefunction([
                    1.0 * cos(Symbol("theta") / 2),
                    -1j * sin(Symbol("theta") / 2)
                ]),
            ),
            (
                Circuit([X(0), RY(Symbol("theta"))(0)]),
                Wavefunction([
                    -1.0 * sin(Symbol("theta") / 2),
                    1.0 * cos(Symbol("theta") / 2),
                ]),
            ),
            (
                Circuit([
                    H(0),
                    U3(Symbol("theta"), Symbol("phi"), Symbol("lambda"))(0)
                ]),
                Wavefunction([
                    cos(Symbol("theta") / 2) / sqrt(2) +
                    -exp(I * Symbol("lambda")) * sin(Symbol("theta") / 2) /
                    sqrt(2),
                    exp(I * Symbol("phi")) * sin(Symbol("theta") / 2) / sqrt(2)
                    + exp(I * (Symbol("lambda") + Symbol("phi"))) *
                    cos(Symbol("theta") / 2) / sqrt(2),
                ]),
            ),
        ],
    )
    def test_wavefunction_works_as_expected_with_symbolic_circuits(
        self,
        simulator: SymbolicSimulator,
        circuit: Circuit,
        expected_wavefunction: Wavefunction,
    ):
        returned_wavefunction = simulator.get_wavefunction(circuit)

        assert returned_wavefunction == expected_wavefunction
def test_splitting_circuits_partitions_it_into_expected_chunks():
    def _predicate(operation):
        return isinstance(operation, GateOperation) and operation.gate.name in (
            "RX",
            "RY",
            "RZ",
        )

    circuit = Circuit(
        [RX(np.pi)(0), RZ(np.pi / 2)(1), CNOT(2, 3), RY(np.pi / 4)(2), X(0), Y(1)]
    )

    expected_partition = [
        (True, Circuit([RX(np.pi)(0), RZ(np.pi / 2)(1)], n_qubits=4)),
        (False, Circuit([CNOT(2, 3)], n_qubits=4)),
        (True, Circuit([RY(np.pi / 4)(2)], n_qubits=4)),
        (False, Circuit([X(0), Y(1)], n_qubits=4)),
    ]

    assert list(split_circuit(circuit, _predicate)) == expected_partition
    def test_binding_symbols_to_circuit_binds_them_to_wavefunction_operation(self):
        alpha, beta = sympy.symbols("alpha, beta")
        circuit = Circuit(
            [RX(alpha)(0), MultiPhaseOperation((beta, 0.5)), RX(beta)(1)]
        ).bind({beta: 0.3})

        assert circuit.free_symbols == [alpha]
        assert circuit.operations == [
            RX(alpha)(0),
            MultiPhaseOperation((0.3, 0.5)),
            RX(0.3)(1),
        ]
Exemplo n.º 10
0
    def test_circuit_bound_with_all_params_contains_bound_gates(self):
        theta1, theta2, theta3 = sympy.symbols("theta1:4")
        symbols_map = {theta1: 0.5, theta2: 3.14, theta3: 0}

        circuit = Circuit(
            [
                RX(theta1)(0),
                RY(theta2)(1),
                RZ(theta3)(0),
                RX(theta3)(0),
            ]
        )
        bound_circuit = circuit.bind(symbols_map)

        expected_circuit = Circuit(
            [
                RX(theta1).bind(symbols_map)(0),
                RY(theta2).bind(symbols_map)(1),
                RZ(theta3).bind(symbols_map)(0),
                RX(theta3).bind(symbols_map)(0),
            ]
        )

        assert bound_circuit == expected_circuit
Exemplo n.º 11
0
def export_to_pyquil(circuit: _circuit.Circuit) -> pyquil.Program:
    var_declarations = map(_param_declaration,
                           sorted(map(str, circuit.free_symbols)))
    custom_gate_definitions = [
        *circuit.collect_custom_gate_definitions(),
        *_collect_unsupported_builtin_gate_defs(
            [op.gate for op in circuit.operations]),
    ]
    pyquil_gate_definitions = _create_pyquil_custom_gate_definitions(
        custom_gate_definitions)

    gate_instructions = [
        _export_gate(op.gate, op.qubit_indices, pyquil_gate_definitions)
        for op in circuit.operations
    ]
    program = pyquil.Program(*[
        *var_declarations, *pyquil_gate_definitions.values(),
        *gate_instructions
    ])
    return program
Exemplo n.º 12
0
def decompose_zquantum_circuit(
    circuit: Circuit, decomposition_rules: Iterable[DecompositionRule[GateOperation]]
):
    return Circuit(decompose_operations(circuit.operations, decomposition_rules))
Exemplo n.º 13
0
 def test_creating_circuit_with_float_integer_passes(self):
     Circuit(n_qubits=5.0)
Exemplo n.º 14
0
    def test_creating_circuit_with_float_n_qubits_fails(self, n_qubits):
        with pytest.raises(ValueError):
            circuit = Circuit(n_qubits=n_qubits)

            assert circuit.n_qubits == int(n_qubits)
Exemplo n.º 15
0
 def test_creating_circuit_with_negative_n_qubits_fails(self, n_qubits):
     with pytest.raises(ValueError):
         Circuit(n_qubits=n_qubits)
Exemplo n.º 16
0
 def test_creating_circuit_has_correct_operations(self):
     circuit = Circuit(operations=EXAMPLE_OPERATIONS)
     assert circuit.operations == list(EXAMPLE_OPERATIONS)
Exemplo n.º 17
0
    @pytest.mark.parametrize("n_qubits", [1.3523, 2.292])
    def test_creating_circuit_with_float_n_qubits_fails(self, n_qubits):
        with pytest.raises(ValueError):
            circuit = Circuit(n_qubits=n_qubits)

            assert circuit.n_qubits == int(n_qubits)

    def test_creating_circuit_with_float_integer_passes(self):
        Circuit(n_qubits=5.0)


@pytest.mark.parametrize(
    "circuit",
    [
        Circuit(),
        Circuit([]),
        Circuit([H(0)]),
        Circuit([H(0)], 5),
    ],
)
def test_printing_circuit_doesnt_raise_exception(circuit):
    str(circuit)
    repr(circuit)


class TestConcatenation:
    def test_appending_to_circuit_yields_correct_operations(self):
        circuit = Circuit()
        circuit += H(0)
        circuit += CNOT(0, 2)