# Untitled

a guest
Sep 23rd, 2020
38
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. #%% Imports
2. from pennylane import numpy as np # get pennylane's numpy wrapper
3. import pennylane as qml
4. from itertools import combinations, groupby
5. import qiskit
6. import random
7. import networkx as nx
8. from pennylane import expval, var
9. from functools import partial
10. from collections import defaultdict
11. import qiskit.providers.aer.noise as noise
12.
13. """
14. Setup a way to construct connected graph instance problems
15. """
16. def gnp_random_connected_graph(n, p, seed):
17.     """Generate a random connected graph
18.    n     : int, number of nodes
19.    p     : float in [0,1]. Probability of creating an edge
20.    seed  : int for initialising randomness
21.    """
22.     edges = combinations(range(n), 2)
23.     G = nx.Graph()
25.     if p <= 0:
26.         return G
27.     if p >= 1:
28.         return nx.complete_graph(n, create_using=G)
29.     for _, node_edges in groupby(edges, key=lambda x: x[0]):
30.         node_edges = list(node_edges)
31.         random_edge = random.choice(node_edges)
33.         for e in node_edges:
34.             if random.random() < p:
36.     return G
37.
38. pauli_z = [[1, 0], [0, -1]]
39. pauli_z_2 = np.kron(pauli_z, pauli_z)
40.
42.     # SETUP PARAMETERS
43.     n_wires = len(graph.nodes)
44.     edges = graph.edges
45.
46.     def U_B(beta):
47.         for wire in range(n_wires):
48.             qml.RX(2 * beta, wires=wire)
49.
50.     def U_C(gamma):
51.         for edge in edges:
52.             wire1 = edge[0]
53.             wire2 = edge[1]
54.             qml.CNOT(wires=[wire1, wire2])
55.             qml.RZ(gamma, wires=wire2)
56.             qml.CNOT(wires=[wire1, wire2])
57.
58.     analytic_dev = qml.device("qiskit.aer", wires=n_wires, analytic=True, shots=1000)
59.     noisy_dev = qml.device("qiskit.aer", wires=n_wires, analytic=True, noise_model=NoiseModel)
60.
61.     @qml.qnode(noisy_dev)
62.     def noisy_circuit(gammas, betas, edge=None, n_layers=1, n_wires=1):
63.         for wire in range(n_wires):
65.         for i in range(n_layers):
66.             U_C(gammas[i])
67.             U_B(betas[i])
68.         return qml.expval(qml.Hermitian(pauli_z_2, wires=edge))
69.
70.     @qml.qnode(analytic_dev)
71.     def analytic_circuit(gammas, betas, edge=None, n_layers=1, n_wires=1):
72.         for wire in range(n_wires):
74.         for i in range(n_layers):
75.             U_C(gammas[i])
76.             U_B(betas[i])
77.         if edges is None:
78.             # measurement phase
79.             return qml.expval(comp_basis_measurement(range(n_wires)))
80.         return qml.expval(qml.Hermitian(pauli_z_2, wires=edge))
81.
82.     def noisy_objective(params, analytic=False):
83.         gammas = params[0]
84.         betas = params[1]
85.         neg_obj = 0
86.         for edge in edges:
87.             if analytic:
88.                 neg_obj -= 0.5 * (1 - analytic_circuit(gammas, betas, edge=edge, n_layers=n_layers, n_wires=n_wires))
89.             else:
90.                 neg_obj -= 0.5 * (1 - noisy_circuit(gammas, betas, edge=edge, n_layers=n_layers, n_wires=n_wires))
91.         return neg_obj
92.
93.     analytic_objective = partial(noisy_objective, analytic=True)
94.