class Approximant_real(Approximant): def __init__(self, layers, domain, ansatz, function): self.function = function super().__init__(layers, domain, ansatz) self.target = self.function(self.domain) self.target = 2 * (self.target - np.min(self.target)) / ( np.max(self.target) - np.min(self.target)) - 1 self.H = Hamiltonian(1, matrices._Z) self.classical = globals()[f"classical_real_{self.ansatz}"] def name_folder(self, quantum=True): folder = self.ansatz + '/' + self.function.name + '/%s_layers' % ( self.layers) if quantum: folder = 'quantum/' + folder else: folder = 'classical/' + folder folder = 'results/' + folder import os try: l = os.listdir(folder) l = [int(_) for _ in l] l.sort() trial = int(l[-1]) + 1 except: trial = 0 os.makedirs(folder) fold_name = folder + '/%s' % (trial) os.makedirs(fold_name) return fold_name, trial def cf_one_point(self, x, f): state = self.get_state(x) o = self.H.expectation(state) cf = (o - f)**2 return cf def derivative_cf_one_point(self, x, f): self.theta_with_x(x) derivatives = np.zeros_like(self.params) index = 0 ch_index = 0 for l in range(self.layers - 1): cir_params_ = self.cir_params.copy() delta = np.zeros_like(cir_params_) delta[ch_index] = np.pi / 2 self.C.set_parameters(cir_params_ + delta) state = self.C() z1 = self.H.expectation(state) self.C.set_parameters(cir_params_ - delta) state = self.C() z2 = self.H.expectation(state) derivatives[index + 1] = 0.5 * ((z1**2 - z2**2) - 2 * f * (z1 - z2)) derivatives[index] = x * derivatives[index + 1] index += 2 ch_index += 1 cir_params_ = self.cir_params.copy() delta = np.zeros_like(cir_params_) delta[ch_index] = np.pi / 2 self.C.set_parameters(cir_params_ + delta) state = self.C() z1 = self.H.expectation(state) self.C.set_parameters(cir_params_ - delta) state = self.C() z2 = self.H.expectation(state) derivatives[index] = 0.5 * ((z1**2 - z2**2) - 2 * f * (z1 - z2)) index += 1 ch_index += 1 cir_params_ = self.cir_params.copy() delta = np.zeros_like(cir_params_) delta[ch_index] = np.pi / 2 self.C.set_parameters(cir_params_ + delta) state = self.C() z1 = self.H.expectation(state) self.C.set_parameters(cir_params_ - delta) state = self.C() z2 = self.H.expectation(state) derivatives[index + 1] = 0.5 * ((z1**2 - z2**2) - 2 * f * (z1 - z2)) derivatives[index] = x * derivatives[index + 1] index += 2 ch_index += 1 return derivatives def derivative_cf(self, params): try: params = params.flatten() except: pass self.set_parameters(params) derivatives = np.zeros_like(params) for x, t in zip(self.domain, self.target): derivatives += self.derivative_cf_one_point(x, t) derivatives /= len(self.domain) return derivatives def paint_representation_1D(self, name): fig, axs = plt.subplots() axs.plot(self.domain, self.target, color='black', label='Target Function') outcomes = np.zeros_like(self.domain) for j, x in enumerate(self.domain): state = self.get_state(x) outcomes[j] = self.H.expectation(state) axs.plot(self.domain, outcomes, color='C1', label='Quantum ' + self.ansatz + ' model') axs.legend() fig.savefig(name) plt.close(fig) def paint_representation_1D_classical(self, prediction, name): fig, axs = plt.subplots() axs.plot(self.domain, self.target, color='black', label='Target Function') axs.plot(self.domain, prediction, color='C0', label='Classical ' + self.ansatz + ' model') axs.legend() fig.savefig(name) plt.close(fig) def paint_representation_2D(self): from mpl_toolkits.mplot3d import Axes3D fig = plt.figure() ax = fig.add_subplot(111, projection='3d') if self.num_functions == 1: ax = fig.gca(projection='3d') print('shape', self.target[0].shape) ax.plot_trisurf(self.domain[:, 0], self.domain[:, 1], self.target[:, 0], label='Target Function', linewidth=0.2, antialiased=True) outcomes = np.zeros_like(self.domain) for j, x in enumerate(self.domain): C = self.circuit(x) state = C.execute() outcomes[j] = self.hamiltonian[0].expectation(state) ax.plot_trisurf(self.domain[:, 0], self.domain[:, 1], outcomes[:, 0] + 0.1, label='Approximation', linewidth=0.2, antialiased=True) #ax.legend() else: for i in range(self.num_functions): ax = fig.add_subplot(1, 1, i + 1, projection='3d') ax.plot(self.domain, self.functions[i](self.domain).flatten(), color='black') outcomes = np.zeros_like(self.domain) for j, x in enumerate(self.domain): C = self.circuit(x) state = C.execute() outcomes[j] = self.hamiltonian[i].expectation(state) ax.scatter(self.domain[:, 0], self.domain[:, 1], outcomes, color='C0', label=self.measurements[i]) ax.legend() fig.savefig(name) plt.close(fig) def paint_historical(self, name): import matplotlib.pyplot as plt fig, axs = plt.subplots(nrows=2) axs[0].plot(np.arange(len(self.hist_chi)), self.hist_chi) axs[0].set(yscale='log', ylabel=r'$\chi^2$') hist_params = np.array(self.hist_params) for i in range(len(self.params)): axs[1].plot(np.arange(len(self.hist_chi)), hist_params[:, i], 'C%s' % i) axs[1].set(ylabel='Parameter', xlabel='Function evaluation') fig.suptitle('Historical behaviour', fontsize=16) fig.savefig(name)
class Approximant_real_2D(Approximant): def __init__(self, layers, domain, function, ansatz): self.function = function super().__init__(layers, domain, ansatz) self.target = np.array(list(self.function(self.domain))) self.target = 2 * (self.target - np.min(self.target)) / ( np.max(self.target) - np.min(self.target)) - 1 self.H = Hamiltonian(1, matrices._Z) self.classical = classical_real_Weighted_2D def name_folder(self, quantum=True): folder = self.ansatz + '/' + self.function.name + '/%s_layers' % ( self.layers) if quantum: folder = 'quantum/' + folder else: folder = 'classical/' + folder folder = 'results/' + folder import os try: l = os.listdir(folder) l = [int(_) for _ in l] l.sort() trial = int(l[-1]) + 1 except: trial = 0 os.makedirs(folder) fold_name = folder + '/%s' % (trial) os.makedirs(fold_name) return fold_name, trial def cf_one_point(self, x, f): state = self.get_state(x) o = self.H.expectation(state) cf = (o - f)**2 return cf def paint_representation_2D(self, name): fig = plt.figure() axs = fig.gca(projection='3d') axs.plot_trisurf(self.domain[:, 0], self.domain[:, 1], self.target, color='black', label='Target Function', alpha=0.5) outcomes = np.zeros_like(self.target) for j, x in enumerate(self.domain): state = self.get_state(x) outcomes[j] = self.H.expectation(state) axs.scatter(self.domain[:, 0], self.domain[:, 1], outcomes, color='C1', label='Quantum ' + self.ansatz + ' model') fig.savefig(name) plt.close(fig) def paint_representation_2D_classical(self, prediction, name): fig = plt.figure() axs = fig.gca(projection='3d') prediction = np.array(list(prediction)) axs.plot_trisurf(self.domain[:, 0], self.domain[:, 1], self.target, color='black', label='Target Function', alpha=0.5) axs.scatter(self.domain[:, 0], self.domain[:, 1], prediction, color='C0', label='Classical ' + self.ansatz + ' model') fig.savefig(name) #plt.show() plt.close(fig)
def expectation(self, state, normalize=False): return Hamiltonian.expectation(self, state, normalize)