示例#1
0
    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()
示例#2
0
    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
示例#3
0
    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
示例#4
0
    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
示例#5
0
    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()
示例#6
0
    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()
示例#7
0
    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