diff --git a/tests/test_models_encodings.py b/tests/test_models_encodings.py index 63cae6836b..98e2ed7143 100644 --- a/tests/test_models_encodings.py +++ b/tests/test_models_encodings.py @@ -7,8 +7,10 @@ import pytest from scipy.optimize import curve_fit +from qibo import Circuit, gates from qibo.models.encodings import ( comp_basis_encoder, + entangling_layer, phase_encoder, unary_encoder, unary_encoder_random_gaussian, @@ -184,3 +186,75 @@ def test_unary_encoder_random_gaussian(backend, nqubits, seed): backend.assert_allclose(0.0, mean, atol=1e-1) backend.assert_allclose(stddev, theoretical_norm, atol=1e-1) + + +def test_entangling_layer_errors(): + with pytest.raises(TypeError): + entangling_layer(10.5) + with pytest.raises(ValueError): + entangling_layer(-4) + with pytest.raises(TypeError): + entangling_layer(10, architecture=True) + with pytest.raises(NotImplementedError): + entangling_layer(10, architecture="qibo") + with pytest.raises(TypeError): + entangling_layer(10, closed_boundary="True") + with pytest.raises(NotImplementedError): + entangling_layer(10, entangling_gate=gates.GeneralizedfSim) + with pytest.raises(NotImplementedError): + entangling_layer(10, entangling_gate=gates.TOFFOLI) + + +@pytest.mark.parametrize("closed_boundary", [False, True]) +@pytest.mark.parametrize("entangling_gate", ["CNOT", gates.CZ, gates.RBS]) +@pytest.mark.parametrize( + "architecture", ["diagonal", "shifted", "even-layer", "odd-layer"] +) +@pytest.mark.parametrize("nqubits", [4, 9]) +def test_entangling_layer(nqubits, architecture, entangling_gate, closed_boundary): + target_circuit = Circuit(nqubits) + if architecture == "diagonal": + target_circuit.add( + _helper_entangling_test(entangling_gate, qubit) + for qubit in range(nqubits - 1) + ) + elif architecture == "even-layer": + target_circuit.add( + _helper_entangling_test(entangling_gate, qubit) + for qubit in range(0, nqubits - 1, 2) + ) + elif architecture == "odd-layer": + target_circuit.add( + _helper_entangling_test(entangling_gate, qubit) + for qubit in range(1, nqubits - 1, 2) + ) + else: + target_circuit.add( + _helper_entangling_test(entangling_gate, qubit) + for qubit in range(0, nqubits - 1, 2) + ) + target_circuit.add( + _helper_entangling_test(entangling_gate, qubit) + for qubit in range(1, nqubits - 1, 2) + ) + + if closed_boundary: + target_circuit.add(_helper_entangling_test(entangling_gate, nqubits - 1, 0)) + + circuit = entangling_layer(nqubits, architecture, entangling_gate, closed_boundary) + for gate, target in zip(circuit.queue, target_circuit.queue): + assert gate.__class__.__name__ == target.__class__.__name__ + + +def _helper_entangling_test(gate, qubit_0, qubit_1=None): + """Creates two-qubit gate with of without parameters.""" + if qubit_1 is None: + qubit_1 = qubit_0 + 1 + + if callable(gate) and gate.__name__ == "RBS": + return gate(qubit_0, qubit_1, 0.0) + + if gate == "CNOT": + gate = gates.CNOT + + return gate(qubit_0, qubit_1)