示例#1
0
    def test_maxcut_error(self):
        """Tests that the MaxCut Hamiltonian throws the correct error"""

        graph = [(0, 1), (1, 2)]

        with pytest.raises(ValueError,
                           match=r"nput graph must be a nx\.Graph"):
            qaoa.maxcut(graph)
示例#2
0
    def test_cost_graph_error(self):
        """Tests that the cost Hamiltonians throw the correct error"""

        graph = [(0, 1), (1, 2)]

        with pytest.raises(ValueError, match=r"Input graph must be a nx\.Graph"):
            qaoa.maxcut(graph)
        with pytest.raises(ValueError, match=r"Input graph must be a nx\.Graph"):
            qaoa.max_independent_set(graph)
        with pytest.raises(ValueError, match=r"Input graph must be a nx\.Graph"):
            qaoa.min_vertex_cover(graph)
        with pytest.raises(ValueError, match=r"Input graph must be a nx\.Graph"):
            qaoa.max_clique(graph)
示例#3
0
    def test_module_example(self, tol):
        """Test the example in the QAOA module docstring"""

        # Defines the wires and the graph on which MaxCut is being performed
        wires = range(3)
        graph = Graph([(0, 1), (1, 2), (2, 0)])

        # Defines the QAOA cost and mixer Hamiltonians
        cost_h, mixer_h = qaoa.maxcut(graph)

        # Defines a layer of the QAOA ansatz from the cost and mixer Hamiltonians
        def qaoa_layer(gamma, alpha):
            qaoa.cost_layer(gamma, cost_h)
            qaoa.mixer_layer(alpha, mixer_h)

        # Repeatedly applies layers of the QAOA ansatz
        def circuit(params, **kwargs):
            for w in wires:
                qml.Hadamard(wires=w)

            qml.layer(qaoa_layer, 2, params[0], params[1])

        # Defines the device and the QAOA cost function
        dev = qml.device("default.qubit", wires=len(wires))
        cost_function = qml.ExpvalCost(circuit, cost_h, dev)

        res = cost_function([[1, 1], [1, 1]])
        expected = -1.8260274380964299

        assert np.allclose(res, expected, atol=tol, rtol=0)
示例#4
0
    def test_maxcut_output(self, graph, cost_hamiltonian, mixer_hamiltonian):
        """Tests that the output of the MaxCut method is correct"""

        cost_h, mixer_h = qaoa.maxcut(graph)

        assert decompose_hamiltonian(cost_hamiltonian) == decompose_hamiltonian(cost_h)
        assert decompose_hamiltonian(mixer_hamiltonian) == decompose_hamiltonian(mixer_h)
示例#5
0
def qaoa_from_graph(graph, n_layers=1):
    """Uses QAOA to create a cost Hamiltonian for the MaxCut problem."""

    # Number of qubits (wires) equal to the number of nodes in the graph
    wires = range(len(graph.nodes))

    # Define the structure of the cost and mixer subcircuits for the MaxCut problem
    cost_h, mixer_h = qaoa.maxcut(graph)

    # Defines a layer of the QAOA ansatz from the cost and mixer Hamiltonians
    def qaoa_layer(gamma, alpha):
        qaoa.cost_layer(gamma, cost_h)
        qaoa.mixer_layer(alpha, mixer_h)

    # Creates the actual quantum circuit for the QAOA algorithm
    def circuit(params, **kwargs):
        for w in wires:
            qml.Hadamard(wires=w)
        qml.layer(qaoa_layer, n_layers, params[0], params[1])

    # Evaluates the cost Hamiltonian
    def hamiltonian(params, **kwargs):
        """Evaluate the cost Hamiltonian, given the angles and the graph."""

        # We set the default.qubit.tf device for seamless integration with TensorFlow
        dev = qml.device("default.qubit.tf", wires=len(graph.nodes))

        # ExpvalCost evaluates the expectation value of an operator
        cost = qml.ExpvalCost(circuit,
                              cost_h,
                              dev,
                              interface="tf",
                              diff_method="backprop")

        return cost(params)

    return hamiltonian
示例#6
0
class TestLayers:
    """Tests that the cost and mixer layers are being constructed properly"""
    def test_mixer_layer_errors(self):
        """Tests that the mixer layer is throwing the correct errors"""

        hamiltonian = [[1, 1], [1, 1]]

        with pytest.raises(
                ValueError,
                match=r"hamiltonian must be of type pennylane.Hamiltonian"):
            qaoa.mixer_layer(0.1, hamiltonian)

    def test_cost_layer_errors(self):
        """Tests that the cost layer is throwing the correct errors"""

        hamiltonian = [[1, 1], [1, 1]]

        with pytest.raises(
                ValueError,
                match=r"hamiltonian must be of type pennylane.Hamiltonian"):
            qaoa.cost_layer(0.1, hamiltonian)

        hamiltonian = qml.Hamiltonian([1, 1], [qml.PauliZ(0), qml.PauliX(1)])

        with pytest.raises(
                ValueError,
                match=
                r"hamiltonian must be written only in terms of PauliZ and Identity gates"
        ):
            qaoa.cost_layer(0.1, hamiltonian)

    @pytest.mark.parametrize(
        ("mixer", "gates"), [[
            qml.Hamiltonian([1, 1],
                            [qml.PauliX(0), qml.PauliX(1)]),
            [qml.PauliRot(2, "X", wires=[0]),
             qml.PauliRot(2, "X", wires=[1])]
        ],
                             [
                                 qaoa.xy_mixer(Graph([(0, 1), (1, 2),
                                                      (2, 0)])),
                                 [
                                     qml.PauliRot(1, "XX", wires=[0, 1]),
                                     qml.PauliRot(1, "YY", wires=[0, 1]),
                                     qml.PauliRot(1, "XX", wires=[0, 2]),
                                     qml.PauliRot(1, "YY", wires=[0, 2]),
                                     qml.PauliRot(1, "XX", wires=[1, 2]),
                                     qml.PauliRot(1, "YY", wires=[1, 2])
                                 ]
                             ]])
    def test_mixer_layer_output(self, mixer, gates):
        """Tests that the gates of the mixer layer are correct"""

        alpha = 1

        with qml._queuing.OperationRecorder() as rec:
            qaoa.mixer_layer(alpha, mixer)

        for i, j in zip(rec.operations, gates):

            prep = [i.name, i.parameters, i.wires]
            target = [j.name, j.parameters, j.wires]

            assert prep == target

    @pytest.mark.parametrize(
        ("cost", "gates"), [[
            qml.Hamiltonian([1, 1],
                            [qml.PauliZ(0), qml.PauliZ(1)]),
            [qml.PauliRot(2, "Z", wires=[0]),
             qml.PauliRot(2, "Z", wires=[1])]
        ],
                            [
                                qaoa.maxcut(Graph([(0, 1), (1, 2),
                                                   (2, 0)]))[0],
                                [
                                    qml.PauliRot(1, "ZZ", wires=[0, 1]),
                                    qml.PauliRot(1, "ZZ", wires=[0, 2]),
                                    qml.PauliRot(1, "ZZ", wires=[1, 2])
                                ]
                            ]])
    def test_cost_layer_output(self, cost, gates):
        """Tests that the gates of the cost layer is correct"""

        gamma = 1

        with qml._queuing.OperationRecorder() as rec:
            qaoa.cost_layer(gamma, cost)

        for i, j in zip(rec.operations, gates):
            prep = [i.name, i.parameters, i.wires]
            target = [j.name, j.parameters, j.wires]

        assert prep == target