def __measure_parameterless(self, state, which_qubits, result_desired): r"""进行 01 测量。 Args: state (ComplexVariable): 输入的量子态 which_qubits (list): 测量作用的量子比特编号 result_desired (list): 期望得到的测量结果,如 ``"0"``、``"1"`` 或者 ``["0", "1"]`` Returns: ComplexVariable: 测量坍塌后的量子态 ComplexVariable:测量坍塌得到的概率 list: 测量得到的结果(0 或 1) """ n = self.get_qubit_number() assert len(which_qubits) == len(result_desired), \ "the length of qubits wanted to be measured and the result desired should be same" op_list = [np.eye(2, dtype=np.complex128)] * n for i, ele in zip(which_qubits, result_desired): k = int(ele) rho = np.zeros((2, 2), dtype=np.complex128) rho[int(k), int(k)] = 1 op_list[i] = rho if n > 1: measure_operator = fluid.dygraph.to_variable(NKron(*op_list)) else: measure_operator = fluid.dygraph.to_variable(op_list[0]) state_measured = matmul(matmul(measure_operator, state), dagger(measure_operator)) prob = trace( matmul(matmul(dagger(measure_operator), measure_operator), state)).real state_measured = elementwise_div(state_measured, prob) return state_measured, prob, result_desired
def __measure_parameterless(self, state, which_qubits, result_desired): r"""进行 01 测量。 Args: state (Tensor): 输入的量子态 which_qubits (list): 测量作用的量子比特编号 result_desired (str): 期望得到的测量结果 Returns: Tensor: 测量坍塌后的量子态 Tensor:测量坍塌得到的概率 str: 测量得到的结果 """ n = self.get_qubit_number() assert len(which_qubits) == len(result_desired), \ "the length of qubits wanted to be measured and the result desired should be same" op_list = [np.eye(2, dtype=np.complex128)] * n for i, ele in zip(which_qubits, result_desired): k = int(ele) rho = np.zeros((2, 2), dtype=np.complex128) rho[int(k), int(k)] = 1 op_list[i] = rho if n > 1: measure_operator = paddle.to_tensor(NKron(*op_list)) else: measure_operator = paddle.to_tensor(op_list[0]) state_measured = matmul(matmul(measure_operator, state), dagger(measure_operator)) prob = real( trace( matmul(matmul(dagger(measure_operator), measure_operator), state))) state_measured = divide(state_measured, prob) return state_measured, prob, result_desired
def __measure_parameterized(self, state, which_qubits, result_desired, theta): r"""进行参数化的测量。 Args: state (Tensor): 输入的量子态 which_qubits (list): 测量作用的量子比特编号 result_desired (str): 期望得到的测量结果 theta (Tensor): 测量运算的参数 Returns: Tensor: 测量坍塌后的量子态 Tensor:测量坍塌得到的概率 str: 测量得到的结果 """ n = self.get_qubit_number() assert len(which_qubits) == len(result_desired), \ "the length of qubits wanted to be measured and the result desired should be same" op_list = [paddle.to_tensor(np.eye(2, dtype=np.complex128))] * n for idx in range(0, len(which_qubits)): i = which_qubits[idx] ele = result_desired[idx] if int(ele) == 0: basis0 = paddle.to_tensor( np.array([[1, 0], [0, 0]], dtype=np.complex128)) basis1 = paddle.to_tensor( np.array([[0, 0], [0, 1]], dtype=np.complex128)) rho0 = multiply(basis0, cos(theta[idx])) rho1 = multiply(basis1, sin(theta[idx])) rho = add(rho0, rho1) op_list[i] = rho elif int(ele) == 1: # rho = diag(concat([cos(theta[idx]), sin(theta[idx])])) # rho = paddle.to_tensor(rho, zeros((2, 2), dtype="float64")) basis0 = paddle.to_tensor( np.array([[1, 0], [0, 0]], dtype=np.complex128)) basis1 = paddle.to_tensor( np.array([[0, 0], [0, 1]], dtype=np.complex128)) rho0 = multiply(basis0, sin(theta[idx])) rho1 = multiply(basis1, cos(theta[idx])) rho = add(rho0, rho1) op_list[i] = rho else: print("cannot recognize the result_desired.") # rho = paddle.to_tensor(ones((2, 2), dtype="float64"), zeros((2, 2), dtype="float64")) measure_operator = paddle.to_tensor(op_list[0]) if n > 1: for idx in range(1, len(op_list)): measure_operator = kron(measure_operator, op_list[idx]) state_measured = matmul(matmul(measure_operator, state), dagger(measure_operator)) prob = real( trace( matmul(matmul(dagger(measure_operator), measure_operator), state))) state_measured = divide(state_measured, prob) return state_measured, prob, result_desired
def __measure_parameterized(self, state, which_qubits, result_desired, theta): r"""进行参数化的测量。 Args: state (ComplexVariable): 输入的量子态 which_qubits (list): 测量作用的量子比特编号 result_desired (list): 期望得到的测量结果,如 ``"0"``、``"1"`` 或者 ``["0", "1"]`` theta (Variable): 测量运算的参数 Returns: ComplexVariable: 测量坍塌后的量子态 Variable:测量坍塌得到的概率 list: 测量得到的结果(0 或 1) """ n = self.get_qubit_number() assert len(which_qubits) == len(result_desired), \ "the length of qubits wanted to be measured and the result desired should be same" op_list = [fluid.dygraph.to_variable(np.eye(2, dtype=np.complex128)) ] * n for idx in range(0, len(which_qubits)): i = which_qubits[idx] ele = result_desired[idx] if int(ele) == 0: basis0 = fluid.dygraph.to_variable( np.array([[1, 0], [0, 0]], dtype=np.complex128)) basis1 = fluid.dygraph.to_variable( np.array([[0, 0], [0, 1]], dtype=np.complex128)) rho0 = elementwise_mul(basis0, cos(theta[idx])) rho1 = elementwise_mul(basis1, sin(theta[idx])) rho = elementwise_add(rho0, rho1) op_list[i] = rho elif int(ele) == 1: # rho = diag(concat([cos(theta[idx]), sin(theta[idx])])) # rho = ComplexVariable(rho, zeros((2, 2), dtype="float64")) basis0 = fluid.dygraph.to_variable( np.array([[1, 0], [0, 0]], dtype=np.complex128)) basis1 = fluid.dygraph.to_variable( np.array([[0, 0], [0, 1]], dtype=np.complex128)) rho0 = elementwise_mul(basis0, sin(theta[idx])) rho1 = elementwise_mul(basis1, cos(theta[idx])) rho = elementwise_add(rho0, rho1) op_list[i] = rho else: print("cannot recognize the results_desired.") # rho = ComplexVariable(ones((2, 2), dtype="float64"), zeros((2, 2), dtype="float64")) measure_operator = fluid.dygraph.to_variable(op_list[0]) if n > 1: for idx in range(1, len(op_list)): measure_operator = kron(measure_operator, op_list[idx]) state_measured = matmul(matmul(measure_operator, state), dagger(measure_operator)) prob = trace( matmul(matmul(dagger(measure_operator), measure_operator), state)).real state_measured = elementwise_div(state_measured, prob) return state_measured, prob, result_desired
def forward(self): # 生成初始的编码器 E 和解码器 D\n", E = Encoder(self.theta) E_dagger = dagger(E) D = E_dagger D_dagger = E # 编码量子态 rho_in rho_BA = matmul(matmul(E, self.rho_in), E_dagger) # 取 partial_trace() 获得 rho_encode 与 rho_trash rho_encode = partial_trace(rho_BA, 2**N_B, 2**N_A, 1) rho_trash = partial_trace(rho_BA, 2**N_B, 2**N_A, 2) # 解码得到量子态 rho_out rho_CA = kron(self.rho_C, rho_encode) rho_out = matmul(matmul(D, rho_CA), D_dagger) # 通过 rho_trash 计算损失函数 zero_Hamiltonian = fluid.dygraph.to_variable( np.diag([1, 0]).astype('complex128')) loss = 1 - (trace(matmul(zero_Hamiltonian, rho_trash))).real return loss, self.rho_in, rho_out
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 -> variable Ob = fluid.dygraph.to_variable(Observable(self.n)) label_pp = fluid.dygraph.to_variable(label) Utheta = U_theta(self.theta, n=self.n, depth=self.depth) U_dagger = dagger(Utheta) state_out = matmul(matmul(state_in, Utheta), U_dagger) E_Z = trace(matmul(state_out, Ob)) # map <Z> to the predict label state_predict = E_Z.real * 0.5 + 0.5 + self.bias loss = fluid.layers.reduce_mean((state_predict - label_pp)**2) is_correct = fluid.layers.where( fluid.layers.abs(state_predict - label_pp) < 0.5).shape[0] acc = is_correct / label.shape[0] return loss, acc, state_predict.numpy()
def forward(self, N): # 施加量子神经网络 U = U_theta(self.theta, N) # rho_tilde 是将 U 作用在 rho 后得到的量子态 U*rho*U^dagger rho_tilde = matmul(matmul(U, self.rho), dagger(U)) # 计算损失函数 loss = trace(matmul(self.sigma, rho_tilde)) return loss.real, rho_tilde
def forward(self, N): # Apply quantum neural network onto the initial state U = U_theta(self.theta, N) # rho_tilda is the quantum state obtained by acting U on rho, which is U*rho*U^dagger rho_tilde = matmul(matmul(U, self.rho), dagger(U)) # Calculate loss function loss = trace(matmul(self.sigma, rho_tilde)) return loss.real, rho_tilde
def run_density_matrix(self, input_state=None, store_state=True): r"""运行当前的量子线路,输入输出的形式为密度矩阵。 Args: input_state (ComplexVariable, optional): 输入的密度矩阵,默认为 :math:`|00...0\rangle \langle00...0|` store_state (bool, optional): 是否存储输出的密度矩阵,默认为 ``True`` ,即存储 Returns: ComplexVariable: 量子线路输出的密度矩阵 代码示例: .. code-block:: python import numpy as np from paddle import fluid from paddle_quantum.circuit import UAnsatz n = 1 theta = np.ones(3) input_state = np.diag(np.arange(2**n))+0j input_state = input_state / np.trace(input_state) with fluid.dygraph.guard(): input_state_var = fluid.dygraph.to_variable(input_state) theta = fluid.dygraph.to_variable(theta) cir = UAnsatz(n) cir.rx(theta[0], 0) cir.ry(theta[1], 0) cir.rz(theta[2], 0) density = cir.run_density_matrix(input_state_var).numpy() print(f"密度矩阵是\n{density}") :: 密度矩阵是 [[ 0.35403671+0.j -0.47686058-0.03603751j] [-0.47686058+0.03603751j 0.64596329+0.j ]] """ state = dygraph.to_variable(density_op( self.n)) if input_state is None else input_state assert state.real.shape == [2**self.n, 2**self.n], "The dimension is not right" state = matmul(self.U, matmul(state, dagger(self.U))) if store_state: self.__state = state # Add info about which function user called self.__run_state = 'density_matrix' return state
def run_density_matrix(self, input_state=None, store_state=True): r"""运行当前的量子线路,输入输出的形式为密度矩阵。 Args: input_state (Tensor, optional): 输入的密度矩阵,默认为 :math:`|00...0\rangle \langle00...0|` store_state (bool, optional): 是否存储输出的密度矩阵,默认为 ``True`` ,即存储 Returns: Tensor: 量子线路输出的密度矩阵 代码示例: .. code-block:: python import numpy as np import paddle from paddle_quantum.circuit import UAnsatz from paddle_quantum.state import density_op n = 1 theta = np.ones(3) input_state = paddle.to_tensor(density_op(n)) theta = paddle.to_tensor(theta) cir = UAnsatz(n) cir.rx(theta[0], 0) cir.ry(theta[1], 0) cir.rz(theta[2], 0) density_matrix = cir.run_density_matrix(input_state).numpy() print(f"The output density matrix is\n{density_matrix}") :: The output density matrix is [[0.64596329+0.j 0.47686058+0.03603751j] [0.47686058-0.03603751j 0.35403671+0.j ]] """ state = paddle.to_tensor(density_op( self.n)) if input_state is None else input_state assert paddle.real(state).shape == [2**self.n, 2**self.n ], "The dimension is not right" state = matmul(self.U, matmul(state, dagger(self.U))) if store_state: self.__state = state # Add info about which function user called self.__run_state = 'density_matrix' return state
def forward(self, H, N): # 施加量子神经网络 U = U_theta(self.theta, N) # 计算损失函数 loss_struct = matmul(matmul(dagger(U), H), U).real # 输入计算基去计算每个子期望值,相当于取 U^dagger*H*U 的对角元 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
def forward(self, H, N): # Apply QNN onto the initial state U = U_theta(self.theta, N) # Calculate loss function loss_struct = matmul(matmul(dagger(U), H), U).real # Use computational basis to calculate each expectation value, which is the same # as a diagonal element in U^dagger*H*U loss_components = [ loss_struct[0][0], loss_struct[1][1], loss_struct[2][2], loss_struct[3][3] ] # Calculate the weighted loss function loss = 4 * loss_components[0] + 3 * loss_components[ 1] + 2 * loss_components[2] + 1 * loss_components[3] return loss, loss_components
def forward(self, x): rho_in = fluid.dygraph.to_variable(x) E = Encoder(self.theta) E_dagger = dagger(E) D = E_dagger D_dagger = E rho_BA = matmul(matmul(E, rho_in), E_dagger) rho_encode = partial_trace(rho_BA, 2**N_B, 2**N_A, 1) rho_trash = partial_trace(rho_BA, 2**N_B, 2**N_A, 2) rho_CA = kron(self.rho_C, rho_encode) rho_out = matmul(matmul(D, rho_CA), D_dagger) zero_Hamiltonian = fluid.dygraph.to_variable( np.diag([1, 0]).astype('complex128')) loss = 1 - (trace(matmul(zero_Hamiltonian, rho_trash))).real return loss, rho_out, rho_encode