def forward(self, state_in, label): """ Args: state_in: The input quantum state, shape [-1, 1, 2^n] label: label for the input state, shape [-1, 1] Returns: The loss: L = ((<Z> + 1)/2 + bias - label)^2 """ # 我们需要将 Numpy array 转换成 Paddle 动态图模式中支持的 variable Ob = fluid.dygraph.to_variable(Observable(self.n)) #pdb.set_trace() label_pp = fluid.dygraph.to_variable(label) # 按照随机初始化的参数 theta Utheta = U_theta(self.theta, n=self.n, depth=self.depth) # 因为 Utheta是学习得到的,我们这里用行向量运算来提速而不会影响训练效果 state_out = matmul(state_in, Utheta) # 维度 [-1, 1, 2 ** n] # 测量得到泡利 Z 算符的期望值 <Z> E_Z = matmul(matmul(state_out, Ob), transpose(ComplexVariable(state_out.real, -state_out.imag), perm=[0, 2, 1])) # 映射 <Z> 处理成标签的估计值 state_predict = E_Z.real[:, 0] * 0.5 + 0.5 + self.bias loss = fluid.layers.reduce_mean((state_predict - label_pp) ** 2) #pdb.set_trace() # 计算交叉验证正确率 #is_correct = fluid.layers.where( #fluid.layers.abs(state_predict - label_pp) < 0.5).shape[0] #acc = is_correct / label.shape[0] return loss, state_predict.numpy()
def forward(self, input_state, H, N, N_SYS_B, D): """ Args: input_state: The initial state with default |0..> H: The target Hamiltonian Returns: The loss. """ out_state = U_theta(self.theta, input_state, N, D) # rho_AB = utils.matmul(utils.matrix_conjugate_transpose(out_state), out_state) rho_AB = matmul( transpose( fluid.framework.ComplexVariable(out_state.real, -out_state.imag), perm=[1, 0]), out_state) # compute the partial trace and three losses rho_B = partial_trace(rho_AB, 2**(N - N_SYS_B), 2**(N_SYS_B), 1) rho_B_squre = matmul(rho_B, rho_B) loss1 = (trace(matmul(rho_B, H))).real loss2 = (trace(rho_B_squre)).real * 2 loss3 = -(trace(matmul(rho_B_squre, rho_B))).real / 2 loss = loss1 + loss2 + loss3 # 损失函数 # option: if you want to check whether the imaginary part is 0, uncomment the following # print('loss_iminary_part: ', loss.numpy()[1]) return loss - 3 / 2, rho_B
def forward(self, input_state, adjacency_matrix, out_state_store, N, P, METHOD): """ This function constructs the loss function for the QAOA circuit. Args: self: the free parameters to be optimized in the QAOA circuit and defined in the above function input_state: initial state of the QAOA circuit which usually is the uniform superposition of 2^N bit-strings in the computational basis $|0\rangle, |1\rangle$ adjacency_matrix: the adjacency matrix generated from the graph encoding the classical problem out_state_store: the output state of the QAOA circuit N: number of qubits P: number of layers METHOD: which version of QAOA is chosen to solve the problem, i.e., standard version labeled by 1 or extended version by 2. Returns: The loss function for the parameterized QAOA circuit. """ # Generate the problem_based quantum Hamiltonian H_problem based on the classical problem in paddle H, _ = H_generator(N, adjacency_matrix) H_problem = fluid.dygraph.to_variable(H) # The standard QAOA circuit: the function circuit_QAOA is used to construct the circuit, indexed by METHOD 1. if METHOD == 1: out_state = circuit_QAOA(self.theta, input_state, adjacency_matrix, N, P) # The extended QAOA circuit: the function circuit_extend_QAOA is used to construct the net, indexed by METHOD 2. elif METHOD == 2: out_state = circuit_extend_QAOA(self.theta, input_state, adjacency_matrix, N, P) else: raise ValueError("Wrong method called!") out_state_store.append(out_state.numpy()) loss = pp_matmul( pp_matmul(out_state, H_problem), transpose( fluid.framework.ComplexVariable(out_state.real, -out_state.imag), perm=[1, 0], ), ) return loss.real
def forward(self, input_state, H, N, D): """ :param input_state: The initial state with default |0..>, 'mat' :param H: The target Hamiltonian, 'mat' :return: The loss, 'float' """ out_state = U_theta(self.theta, input_state, N, D) loss = matmul( matmul(out_state, H), transpose( fluid.framework.ComplexVariable(out_state.real, -out_state.imag), perm=[1, 0], ), ) return loss.real
def forward(self, state_in, origin_state): """ Args: state_in: The input quantum state, shape [-1, 1, 2^n] label: label for the input state, shape [-1, 1] Returns: The loss: L = ((<Z> + 1)/2 + bias - label)^2 """ # 我们需要将 Numpy array 转换成 Paddle 动态图模式中支持的 variable Ob = self.Ob # 按照随机初始化的参数 theta Encoder = AE_encoder(self.theta1, n=self.n, z_n=self.n_z, depth=self.depth) Decoder = AE_decoder(self.theta2, n=self.n, z_n=self.n_z, depth=self.depth) # State in to input state initial_state = np.array([1]+[0]*(2**(self.n-self.n_z)-1)).astype('complex128') initial_state = fluid.dygraph.to_variable(initial_state) input_state = kron(initial_state, state_in) # 因为 Utheta是学习得到的,我们这里用行向量运算来提速而不会影响训练效果 state_z = matmul(input_state, Encoder) state_out = matmul(state_z, Decoder) # 测量得到泡利 Z 算符的期望值 <Z> E_Z = [matmul(matmul(state_out, Ob[i]), transpose(ComplexVariable(state_out.real, -state_out.imag), perm=[0, 2, 1])).real for i in range(self.n)] output_state = fluid.layers.concat(E_Z, axis=-1) # Calcualate Loss loss = fluid.layers.mean((output_state-origin_state)**2) origin_len = fluid.layers.reduce_sum(origin_state**2, -1) ** 0.5 output_len = fluid.layers.reduce_sum(output_state**2, -1) ** 0.5 dot_product = fluid.layers.reduce_sum(output_state*origin_state, -1) fidelity = fluid.layers.mean(dot_product/origin_len/output_len) return loss, fidelity, output_state.numpy()
def forward(self, state_in, label): """ Args: state_in: The input quantum state, shape [-1, 1, 2^n] label: label for the input state, shape [-1, 1] Returns: The loss: L = ((<Z> + 1)/2 + bias - label)^2 """ state_z = self.net.encoder(state_in) state_z = fluid.dygraph.to_variable(state_z.numpy()) # 我们需要将 Numpy array 转换成 Paddle 动态图模式中支持的 variable unused_n = self.n - self.n_z Ob = fluid.dygraph.to_variable(Observable(2*self.n-self.n_z, measure_index=unused_n)) label_pp = fluid.dygraph.to_variable(label) # 按照随机初始化的参数 theta unused_n = self.n - self.n_z Utheta = U_theta(self.theta, n=self.n_z, depth=self.depth) empty_half = fluid.dygraph.to_variable(np.eye(2**unused_n).astype('complex128')) Utheta = kron(empty_half, Utheta) Utheta = kron(Utheta, empty_half) # 因为 Utheta是学习得到的,我们这里用行向量运算来提速而不会影响训练效果 state_out = matmul(state_z, Utheta) # 维度 [-1, 1, 2 ** n] # 测量得到泡利 Z 算符的期望值 <Z> E_Z = matmul(matmul(state_out, Ob), transpose(ComplexVariable(state_out.real, -state_out.imag), perm=[0, 2, 1])) # 映射 <Z> 处理成标签的估计值 state_predict = E_Z.real[:, 0] * 0.5 + 0.5 + self.bias loss = fluid.layers.reduce_mean((state_predict - label_pp) ** 2) return loss, state_predict.numpy()
def forward(self, H, N): """ Args: input_state: The initial state with default |0..> H: The target Hamiltonian Returns: The loss. """ out_state = U_theta(self.theta, N) loss_struct = matmul( matmul( transpose(fluid.framework.ComplexVariable( out_state.real, -out_state.imag), perm=[1, 0]), H), out_state).real loss_components = [ loss_struct[0][0], loss_struct[1][1], loss_struct[2][2], loss_struct[3][3] ] loss = 4 * loss_components[0] + 3 * loss_components[ 1] + 2 * loss_components[2] + 1 * loss_components[3] return loss, loss_components