def test_finite_diff_coherent_two_wires(self, tol): """Test that the jacobian of the probability for a coherent states is approximated well with finite differences""" cutoff = 4 dev = qml.device("strawberryfields.fock", wires=2, cutoff_dim=cutoff) @qml.qnode(dev) def circuit(a, phi): qml.Displacement(a, phi, wires=0) qml.Displacement(a, phi, wires=1) return qml.probs(wires=[0, 1]) a = 0.4 phi = -0.12 c = np.arange(cutoff) d = np.arange(cutoff) n0, n1 = np.meshgrid(c, d) n0 = n0.flatten() n1 = n1.flatten() # differentiate with respect to parameter a res_F = circuit.jacobian([a, phi], wrt={0}, method="F").flat expected_gradient = (2 * (a**(-1 + 2 * n0 + 2 * n1)) * np.exp(-2 * a**2) * (-2 * a**2 + n0 + n1) / (fac(n0) * fac(n1))) assert np.allclose(res_F, expected_gradient, atol=tol, rtol=0) # differentiate with respect to parameter phi res_F = circuit.jacobian([a, phi], wrt={1}, method="F").flat expected_gradient = 0 assert np.allclose(res_F, expected_gradient, atol=tol, rtol=0)
def plot_surface(surface): X = np.arange(-np.pi, np.pi, 0.25) Y = np.arange(-np.pi, np.pi, 0.25) X, Y = np.meshgrid(X, Y) fig = plt.figure() ax = fig.add_subplot(111, projection="3d") surf = ax.plot_surface(X, Y, surface, cmap="viridis", linewidth=0, antialiased=False) ax.set_zlim(0, 1) ax.zaxis.set_major_locator(LinearLocator(10)) ax.zaxis.set_major_formatter(FormatStrFormatter("%.02f")) plt.show()
def make_meshgrid(X, padding=0.05, n_x=20, n_y=20): __sanity_checks(X) x_min, x_max = X[:, 0].min(), X[:, 0].max() y_min, y_max = X[:, 1].min(), X[:, 1].max() padding_x, padding_y = padding * (x_max - x_min), padding * (y_max - y_min) x_min -= padding_x x_max += padding_x y_min -= padding_y y_max += padding_y xx, yy = np.meshgrid(np.linspace(x_min, x_max, n_x), np.linspace(y_min, y_max, n_y)) return xx, yy
def generate_surface(cost_function): Z = [] Z_assembler = [] X = np.arange(-np.pi, np.pi, 0.25) Y = np.arange(-np.pi, np.pi, 0.25) X, Y = np.meshgrid(X, Y) for x in X[0, :]: for y in Y[:, 0]: rotations = [[x for i in range(wires)], [y for i in range(wires)]] Z_assembler.append(cost_function(rotations)) Z.append(Z_assembler) Z_assembler = [] Z = np.asarray(Z) return Z
def plot_decision_boundaries(classifier, ax, N_gridpoints=14): _xx, _yy = np.meshgrid(np.linspace(-1, 1, N_gridpoints), np.linspace(-1, 1, N_gridpoints)) _zz = np.zeros_like(_xx) for idx in np.ndindex(*_xx.shape): _zz[idx] = classifier.predict( np.array([_xx[idx], _yy[idx]])[np.newaxis, :]) plot_data = {'_xx': _xx, '_yy': _yy, '_zz': _zz} ax.contourf(_xx, _yy, _zz, cmap=mpl.colors.ListedColormap(['#FF0000', '#0000FF']), alpha=.2, levels=[-1, 0, 1]) dataset.plot(ax) return plot_data
def plot_surface(surface): X = np.arange(-np.pi, np.pi, 0.25) Y = np.arange(-np.pi, np.pi, 0.25) X, Y = np.meshgrid(X, Y) fig = plt.figure() ax = fig.add_subplot(111, projection="3d") surf = ax.plot_surface(X, Y, surface, cmap="viridis", linewidth=0, antialiased=False) ax.set_zlim(0, 1) ax.zaxis.set_major_locator(LinearLocator(10)) ax.zaxis.set_major_formatter(FormatStrFormatter("%.02f")) #plt.show() plt.draw() plt.pause(0.001) input("Open Ports --> Open Preview or Browser --> push enter to continue")
def plot_decision_boundaries(classifier, ax, N_gridpoints=14): _xx, _yy = np.meshgrid(np.linspace(-1, 1, N_gridpoints), np.linspace(-1, 1, N_gridpoints)) _zz = np.zeros_like(_xx) for idx in np.ndindex(*_xx.shape): _zz[idx] = classifier.predict( np.array([_xx[idx], _yy[idx]])[np.newaxis, :]) plot_data = {"_xx": _xx, "_yy": _yy, "_zz": _zz} ax.contourf( _xx, _yy, _zz, cmap=mpl.colors.ListedColormap(["#FF0000", "#0000FF"]), alpha=0.2, levels=[-1, 0, 1], ) plot_double_cake_data(X, Y, ax) return plot_data
def test_finite_diff_coherent_two_wires(self, tol): """Test that the jacobian of the probability for a coherent states is approximated well with finite differences""" cutoff = 4 dev = qml.device("strawberryfields.gaussian", wires=2, cutoff_dim=cutoff) @qml.qnode_old.qnode(dev, diff_method="finite-diff") def circuit(a, phi): qml.Displacement(a, phi, wires=0) qml.Displacement(a, phi, wires=1) return qml.probs(wires=[0, 1]) a = np.array(0.4, requires_grad=True) phi = np.array(-0.12, requires_grad=False) c = np.arange(cutoff) d = np.arange(cutoff) n0, n1 = np.meshgrid(c, d) n0 = n0.flatten() n1 = n1.flatten() # differentiate with respect to parameter a res_F = qml.jacobian(circuit)(a, phi) expected_gradient = ( 2 * (a ** (-1 + 2 * n0 + 2 * n1)) * np.exp(-2 * a**2) * (-2 * a**2 + n0 + n1) / (fac(n0) * fac(n1)) ) assert np.allclose(res_F, expected_gradient, atol=tol, rtol=0) # differentiate with respect to parameter phi a = np.array(0.4, requires_grad=False) phi = np.array(-0.12, requires_grad=True) res_F = qml.jacobian(circuit)(a, phi) expected_gradient = 0 assert np.allclose(res_F, expected_gradient, atol=tol, rtol=0)
def draw(var_gd, var_ada): fig = plt.figure(figsize=(6, 4)) ax = fig.gca(projection='3d') X = np.linspace(-3, 3, 30) Y = np.linspace(-3, 3, 30) xx, yy = np.meshgrid(X, Y) Z = np.array([[cost([x, y]) for x in X] for y in Y]).reshape(len(Y), len(X)) surf = ax.plot_surface(xx, yy, Z, cmap=cm.coolwarm, antialiased=False) path_z = [cost(var) + 1e-8 for var in var_gd] path_x = [v[0] for v in var_gd] path_y = [v[1] for v in var_gd] ax.plot(path_x, path_y, path_z, c='green', marker='.', label="graddesc", zorder=10) path_z = [cost(var) + 1e-8 for var in var_ada] path_x = [v[0] for v in var_ada] path_y = [v[1] for v in var_ada] ax.plot(path_x, path_y, path_z, c='purple', marker='.', label="adagrad", zorder=11) ax.set_xlabel("v1") ax.set_ylabel("v2") ax.zaxis.set_major_locator(MaxNLocator(nbins=5, prune='lower')) plt.legend() plt.show()
############################################################################## # Cost function surface for circuit ansatz # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Now, we plot the cost function surface for later comparison with the surface generated # by learning the circuit structure. from matplotlib import cm from matplotlib.ticker import MaxNLocator from mpl_toolkits.mplot3d import Axes3D fig = plt.figure(figsize=(6, 4)) ax = fig.gca(projection="3d") X = np.linspace(-4.0, 4.0, 40) Y = np.linspace(-4.0, 4.0, 40) xx, yy = np.meshgrid(X, Y) Z = np.array([[cost([x, y]) for x in X] for y in Y]).reshape(len(Y), len(X)) surf = ax.plot_surface(xx, yy, Z, cmap=cm.coolwarm, antialiased=False) ax.set_xlabel(r"$\theta_1$") ax.set_ylabel(r"$\theta_2$") ax.zaxis.set_major_locator(MaxNLocator(nbins=5, prune="lower")) plt.show() ############################################################################## # It is apparent that, based on the circuit structure # chosen above, the cost function does not depend on the angle parameter :math:`\theta_2` # for the rotation gate :math:`R_y`. As we will show in the following sections, this independence is not true # for alternative gate choices. #
print(quantum_circ(inits, x=[0.1, 0.3])) print(quantum_circ(inits, x=[0.2, 0.2])) # Plot the normalized Rosenbrock function # In[55]: XX = np.linspace(-2, 2., 30) #Could use linspace instead if dividing YY = np.linspace(-2, 4., 30) #evenly instead of stepping... #Create the mesh grid(s) for all X/Y combos. XX, YY = np.meshgrid(XX, YY) #Rosenbrock function w/ two parameters using numpy Arrays and normalized ZZ = (1.-XX)**2 + 100.*(YY-XX*XX)**2 ZZ = ZZ/np.max(ZZ) # plot ax = fig.gca(projection='3d') ax.view_init(30, 35) ax.dist = 13 surf = ax.plot_surface(XX, YY, ZZ, rstride=1, cstride=1, cmap='coolwarm', edgecolor='none',antialiased=True) #Try coolwarm vs jet ax.set_xlabel('x', rotation=0, labelpad=10, size=22) ax.set_ylabel('y', rotation=0, labelpad=10, size=22) ax.set_xticks([-2, 0, 2]) ax.set_yticks([-2, 0, 2,4])
acc_train = accuracy(Y_train, predictions_train) acc_val = accuracy(Y_val, predictions_val) print( "Iter: {:5d} | Cost: {:0.7f} | Acc train: {:0.7f} | Acc validation: {:0.7f} " "".format(it + 1, cost(var, features, Y), acc_train, acc_val)) ############################################################################## # We can plot the continuous output of the variational classifier for the # first two dimensions of the Iris data set. plt.figure() cm = plt.cm.RdBu # make data for decision regions xx, yy = np.meshgrid(np.linspace(0.0, 1.5, 20), np.linspace(0.0, 1.5, 20)) X_grid = [np.array([x, y]) for x, y in zip(xx.flatten(), yy.flatten())] # preprocess grid points like data inputs above padding = 0.3 * np.ones((len(X_grid), 1)) X_grid = np.c_[np.c_[X_grid, padding], np.zeros((len(X_grid), 1))] # pad each input normalization = np.sqrt(np.sum(X_grid**2, -1)) X_grid = (X_grid.T / normalization).T # normalize each input features_grid = np.array([get_angles(x) for x in X_grid ]) # angles for state preparation are new features predictions_grid = [ variational_classifier(var, angles=f) for f in features_grid ] Z = np.reshape(predictions_grid, xx.shape)
def visualize_trained(var, X_train, X_val, Y_train, Y_val): plt.figure() cm = plt.cm.RdBu # make data for decision regions xx, yy = np.meshgrid(np.linspace(0.0, 1.5, 20), np.linspace(0.0, 1.5, 20)) X_grid = [np.array([x, y]) for x, y in zip(xx.flatten(), yy.flatten())] # preprocess grid points like data inputs above padding = 0.3 * np.ones((len(X_grid), 1)) X_grid = np.c_[np.c_[X_grid, padding], np.zeros((len(X_grid), 1))] # pad each input normalization = np.sqrt(np.sum(X_grid**2, -1)) X_grid = (X_grid.T / normalization).T # normalize each input features_grid = np.array( [get_angles(x) for x in X_grid]) # angles for state preparation are new features predictions_grid = [ variational_classifier(var, angles=f) for f in features_grid ] Z = np.reshape(predictions_grid, xx.shape) # plot decision regions cnt = plt.contourf(xx, yy, Z, levels=np.arange(-1, 1.1, 0.1), cmap=cm, alpha=.8, extend='both') plt.contour(xx, yy, Z, levels=[0.0], colors=('black', ), linestyles=('--', ), linewidths=(0.8, )) plt.colorbar(cnt, ticks=[-1, 0, 1]) # plot data plt.scatter(X_train[:, 0][Y_train == 1], X_train[:, 1][Y_train == 1], c='b', marker='o', edgecolors='k', label="class 1 train") plt.scatter(X_val[:, 0][Y_val == 1], X_val[:, 1][Y_val == 1], c='b', marker='^', edgecolors='k', label="class 1 validation") plt.scatter(X_train[:, 0][Y_train == -1], X_train[:, 1][Y_train == -1], c='r', marker='o', edgecolors='k', label="class -1 train") plt.scatter(X_val[:, 0][Y_val == -1], X_val[:, 1][Y_val == -1], c='r', marker='^', edgecolors='k', label="class -1 validation") plt.legend() plt.show()
def plot_cost_and_model(fun, model, parameters, shift_radius=5 * np.pi / 8, num_points=20): """ Args: fun (callable): Original cost function. model (callable): Model cost function. parameters (array[float]): Parameters at which the model was built. shift_radius (float): Maximal shift value for each parameter. num_points (int): Number of points to create grid. """ coords = np.linspace(-shift_radius, shift_radius, num_points) X, Y = np.meshgrid(coords + parameters[0], coords + parameters[1]) # Compute the original cost function and the model on the grid. Z_original = np.array( [[fun(parameters + np.array([t1, t2])) for t2 in coords] for t1 in coords]) Z_model = np.array([[model(np.array([t1, t2])) for t2 in coords] for t1 in coords]) # Prepare sampled points for plotting. shifts = [-np.pi / 2, 0, np.pi / 2] samples = chain.from_iterable([[[ parameters[0] + s2, parameters[1] + s1, fun(parameters + np.array([s1, s2])) ] for s2 in shifts] for s1 in shifts]) # Display landscapes incl. sampled points and deviation. # Transparency parameter for landscapes. alpha = 0.6 fig, ax = plt.subplots(1, 2, subplot_kw={"projection": "3d"}, figsize=(9, 4)) green = "#209494" orange = "#ED7D31" surf = ax[0].plot_surface(X, Y, Z_original, label="Original energy", color=green, alpha=alpha) surf._facecolors2d = surf._facecolor3d surf._edgecolors2d = surf._edgecolor3d surf = ax[0].plot_surface(X, Y, Z_model, label="Model energy", color=orange, alpha=alpha) surf._facecolors2d = surf._facecolor3d surf._edgecolors2d = surf._edgecolor3d for sample in samples: ax[0].scatter(*sample, marker="d", color="r") ax[0].plot([sample[0]] * 2, [sample[1]] * 2, [np.min(Z_original), sample[2]], color="k") surf = ax[1].plot_surface(X, Y, Z_original - Z_model, label="Deviation", color=green, alpha=alpha) surf._facecolors2d = surf._facecolor3d surf._edgecolors2d = surf._edgecolor3d ax[0].legend() ax[1].legend()
theta_func = np.linspace(0, 2 * np.pi, num_samples) C1 = [circuit(np.array([theta, .5])) for theta in theta_func] C2 = [circuit(np.array([3.3, theta])) for theta in theta_func] # Show the sweeps. fig, ax = plt.subplots(1, 1, figsize=(4, 3)) ax.plot(theta_func, C1, label="$E(\\theta, 0.5)$", color="r") ax.plot(theta_func, C2, label="$E(3.3, \\theta)$", color="orange") ax.set_xlabel("$\\theta$") ax.set_ylabel("$E$") ax.legend() plt.tight_layout() # Create a 2D grid and evaluate the energy on the grid points. # We cut out a part of the landscape to increase clarity. X, Y = np.meshgrid(theta_func, theta_func) Z = np.zeros_like(X) for i, t1 in enumerate(theta_func): for j, t2 in enumerate(theta_func): # Cut out the viewer-facing corner if (2 * np.pi - t2)**2 + t1**2 > 4: Z[i, j] = circuit([t1, t2]) else: X[i, j] = np.nan Y[i, j] = np.nan Z[i, j] = np.nan # Show the energy landscape on the grid. fig, ax = plt.subplots(1, 1, subplot_kw={"projection": "3d"}, figsize=(4, 4)) surf = ax.plot_surface(X, Y,
#%% Let's have a look at the cost landscape from functools import partial def wrap_circuit(param1, param2): def circuit_wrap(theta0, theta1, theta2, theta3): return circuit(np.array([theta0, theta1, theta2, theta3])) circuitwrapvec = np.vectorize(partial(circuit_wrap, param1, param2)) return circuitwrapvec #circuitwrapvec = wrap_circuit(theta[0],theta[1]) circuitwrapvec = wrap_circuit(thetart[0], thetart[1]) grid_size = 30 X, Y = np.meshgrid(np.linspace(-np.pi, np.pi, grid_size), np.linspace(-np.pi, np.pi, grid_size)) Z = circuitwrapvec(X, Y) #%% # Plot this stuff fig = plt.figure() ax = plt.axes(projection='3d') ax.plot_surface(X, Y, Z, cmap='viridis', edgecolor='none') ax.set_title('Cost landscape for two parameters') ax.set_xlabel("theta_1") ax.set_ylabel("$theta_2$") ax.set_zlabel("$\mathcal{L}(\mathbb{\theta})") plt.show() # %% import pickle as pkl
params = 2 * np.pi * (np.random.rand(sum(param_size)) - 0.5) # Define the Hamiltonian operators operators, coeffs = Hamiltonian() # Define the QNodeCollection qnodes = qml.map(circuit, operators, dev, measure="expval") # Evaluate the QNodeCollection def HNode(params): return np.dot(coeffs, qnodes(params, size=SIZE, layers=LAYERS)) # Define the lattice X = np.linspace(-np.pi, np.pi, 100) Y = np.linspace(-np.pi, np.pi, 100) X, Y = np.meshgrid(X, Y) Op, OpG = HNode, qml.grad(HNode) Op_mat, OpG_mat = np.zeros(shape=(100, 100)), np.zeros(shape=(sum(param_size), 100, 100)) for i in range(100): for j in range(100): params[args.coord[0]] = X[i, j] params[args.coord[1]] = Y[i, j] Op_mat[i, j] = Op(params) OpG_mat[:, i, j] = OpG(params)[0] # fig = plt.figure() # ax = fig.gca(projection='3d') # surf = ax.plot_surface(X=X, Y=Y, Z=Op_mat)
def plot(X, y, log, name="", density=23): import matplotlib.pyplot as plt from matplotlib.backends.backend_pdf import PdfPages # data = [(i, step["batch_cost"]) for i, step in enumerate(log)] # data = list(zip(*data)) # plt.figure(figsize=(11, 11)) # plt.plot(*data) # plt.title(f"Learning curve") # plt.xlabel("Learning step") # plt.ylabel("Batch loss") # plt.savefig("learning_curve.pdf") # plt.close() # exit(-1) with PdfPages(f"{name}.pdf") as pdf: for i, step in enumerate(log): theta = step["theta"] plt.figure(figsize=(8, 8)) extent = X[:, 0].min(), X[:, 0].max(), X[:, 1].min(), X[:, 1].max() extent = 0, np.pi, 0, np.pi xx = np.linspace(*extent[0:2], density) yy = np.linspace(*extent[2:4], density) xx, yy = np.meshgrid(xx, yy) Xfull = np.c_[xx.ravel(), yy.ravel()] # Xfull = np.random.rand(density**2,2)*np.pi # View probabilities: scores_full = np.array([circuit(theta, x=x) for x in Xfull]) vmin, vmax = -1, 1 scores = np.array([circuit(theta, x=x) for x in X]) y_pred = sgn(scores) print(metrics.confusion_matrix(y, y_pred)) accuracy = metrics.accuracy_score(y, y_pred) plt.title(f"Classification score, accuracy={accuracy:1.2f} ") plt.xlabel("feature 1") plt.ylabel("feature 2") imshow_handle = plt.contourf(xx, yy, scores_full.reshape( (density, density)), vmin=vmin, vmax=vmax, cmap='seismic') plt.xticks(np.linspace(0, np.pi, 5)) plt.yticks(np.linspace(0, np.pi, 5)) for cls_val, cls_col in {0: 'b', 1: 'r'}.items(): # get row indexes for samples with this class row_ix = np.where(y == cls_val) # create scatter of these samples plt.scatter(X[row_ix, 0], X[row_ix, 1], cmap='seismic', c=cls_col, lw=1, edgecolor='k') ax = plt.axes([0.91, 0.1, 0.02, 0.8]) plt.colorbar(imshow_handle, cax=ax, orientation='vertical') plt.clim(-1, 1) pdf.savefig() plt.close()
def retrieve_landscape(self): x = np.linspace(-self.scale, self.scale, self.grid_size[0]) y = np.linspace(-self.scale, self.scale, self.grid_size[1]) x, y = np.meshgrid(x, y) landscape = self.cache.get_values() return x, y, landscape
def qaoa_maxcut(opt, graph, n_layers, verbose=False, shots=None, MeshGrid=False, NoiseModel=None): start = time.time() if opt == "adam": opt = qml.AdamOptimizer(0.1) elif opt == "gd": opt = qml.GradientDescentOptimizer(0.1) elif opt == "qng": opt = qml.QNGOptimizer(0.1) elif opt == "roto": opt = qml.RotosolveOptimizer() # SETUP PARAMETERS n_wires = len(graph.nodes) edges = graph.edges def U_B(beta): for wire in range(n_wires): qml.RX(2 * beta, wires=wire) def U_C(gamma): for edge in edges: wire1 = edge[0] wire2 = edge[1] qml.CNOT(wires=[wire1, wire2]) qml.RZ(gamma, wires=wire2) qml.CNOT(wires=[wire1, wire2]) if NoiseModel: if shots: print("Starting shots", shots) dev = qml.device("qiskit.aer", wires=n_wires, shots=shots, noise_model=NoiseModel) else: dev = qml.device("qiskit.aer", wires=n_wires, noise_model=NoiseModel) else: if shots: print("Starting shots", shots) dev = qml.device("default.qubit", wires=n_wires, analytic=False, shots=shots) else: dev = qml.device("default.qubit", wires=n_wires, analytic=True, shots=1) @qml.qnode(dev) def circuit(gammas, betas, edge=None, n_layers=1, n_wires=1): for wire in range(n_wires): qml.Hadamard(wires=wire) for i,j in zip(range(n_wires),range(n_layers)): U_C(gammas[i,j]) U_B(betas[i,j]) if edges is None: # measurement phase return qml.sample(comp_basis_measurement(range(n_wires))) return qml.expval(qml.Hermitian(pauli_z_2, wires=edge)) np.random.seed(42) init_params = 0.01 * np.random.rand(2, n_wires, n_layers) def obj_wrapper(params): objstart = partial(objective, params, True, False) objend = partial(objective, params, False, True) return np.vectorize(objstart), np.vectorize(objend) def objective(params, start=False, end=False, X=None, Y=None): gammas = params[0] betas = params[1] if start: gammas[0,0] = X betas[0,0] = Y elif end: gammas[-1,0] = X betas[-1,0] = Y neg_obj = 0 for edge in edges: neg_obj -= 0.5 * (1 - circuit(gammas, betas, edge=edge, n_layers=n_layers, n_wires=n_wires)) return neg_obj paramsrecord = [init_params.tolist()] print(f"Start objective fn {objective(init_params)}") params = init_params losses = [objective(params)] print(f"{str(opt).split('.')[-1]} with {len(graph.nodes)} nodes initial loss {losses[0]}") steps = NUM_STEPS for i in range(steps): params = opt.step(objective, params) if i == 0: print(f"{str(opt).split('.')[-1]} with {len(graph.nodes)} nodes took {time.time()-start:.5f}s for 1 iteration") paramsrecord.append(params.tolist()) losses.append(objective(params)) if verbose: if i % 5 == 0: print(f"Objective at step {i} is {losses[-1]}") if i % 10 == 0 and shots: print("Shots", shots, "is up to", i) if MeshGrid: grid_size = 100 X, Y = np.meshgrid(np.linspace(-np.pi,np.pi,grid_size),np.linspace(-np.pi,np.pi,grid_size)) objstart, objend = obj_wrapper(init_params) meshgridfirststartparams = objstart(X, Y) meshgridfirstlastparams = objend(X,Y) objstart, objend = obj_wrapper(params) meshgridendfirstparams = objstart(X, Y) meshgridendlastparams = objend(X,Y) return {"losses":losses, "params":paramsrecord,\ "MeshGridStartFirstParams":meshgridfirststartparams, "MeshGridStartLastParams":meshgridfirstlastparams, \ "MeshGridEndFirstParams":meshgridendfirstparams, "MeshGridEndLastParams":meshgridendlastparams} else: return shots, losses