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)
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)
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)
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)
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
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