示例#1
0
def Observable(n):
    """
    :param n: number of qubits
    :return: local observable: Z \otimes I \otimes ...\otimes I
    """
    Ob = pauli_str_to_matrix([[1.0, 'z0']], n)
    return Ob
示例#2
0
def Observable(n, measure_index=0):
    """
    :param n: number of qubits
    :return: local observable: Z \otimes I \otimes ...\otimes I
    """
    Ob = fluid.dygraph.to_variable(pauli_str_to_matrix([[1.0, 'z'+str(measure_index)]], n))
    return Ob
示例#3
0
def benchmark_QAOA(classical_graph_adjacency=None, N=None):
    """
     This function benchmarks the performance of QAOA. Indeed, it compares its approximate solution obtained
     from QAOA with predetermined parameters, such as iteration step = 120 and learning rate = 0.1, to the exact solution
     to the classical problem.
    """
    # Generate the graph and its adjacency matrix from the classical problem, such as the Max-Cut problem
    if all(var is None for var in (classical_graph_adjacency, N)):
        N = 4
        _, classical_graph_adjacency = generate_graph(N, 1)

    # Convert the Hamiltonian's list form to matrix form
    H_matrix = pauli_str_to_matrix(H_generator(N, classical_graph_adjacency),
                                   N)
    H_diag = diag(H_matrix).real
    # Compute the exact solution of the original problem to benchmark the performance of QAOA
    H_max = max(H_diag)
    H_min = min(H_diag)

    print('H_max:', H_max, '  H_min:', H_min)

    # Load the data of QAOA
    x1 = load('./output/summary_data.npz')

    H_min = ones([len(x1['iter'])]) * H_min

    # Plot it
    pyplot.figure(1)
    loss_QAOA, = pyplot.plot(x1['iter'],
                             x1['energy'],
                             alpha=0.7,
                             marker='',
                             linestyle="--",
                             linewidth=2,
                             color='m')
    benchmark, = pyplot.plot(x1['iter'],
                             H_min,
                             alpha=0.7,
                             marker='',
                             linestyle=":",
                             linewidth=2,
                             color='b')
    pyplot.xlabel('Number of iteration')
    pyplot.ylabel('Performance of the loss function for QAOA')

    pyplot.legend(
        handles=[loss_QAOA, benchmark],
        labels=[
            r'Loss function $\left\langle {\psi \left( {\bf{\theta }} \right)} '
            r'\right|H\left| {\psi \left( {\bf{\theta }} \right)} \right\rangle $',
            'The benchmark result',
        ],
        loc='best')

    # Show the picture
    pyplot.show()
示例#4
0
def H_generator(N):
    """
    Generate a Hamiltonian with trivial descriptions
    Returns: A Hamiltonian
    """
    # 生成用泡利字符串表示的随机哈密顿量
    hamiltonian = random_pauli_str_generator(N, terms=10)
    print("Random Hamiltonian in Pauli string format = \n", hamiltonian)

    # 生成哈密顿量的矩阵信息
    H = pauli_str_to_matrix(hamiltonian, N)
    return H
示例#5
0
def H_generator(N):
    """
    Generate a Hamiltonian with trivial descriptions
    Returns: A Hamiltonian
    """
    # Generate the Pauli string representing a random Hamiltonian
    hamiltonian = random_pauli_str_generator(N, terms=10)
    print("Random Hamiltonian in Pauli string format = \n", hamiltonian)

    # Generate the marix form of the Hamiltonian
    H = pauli_str_to_matrix(hamiltonian, N)
    return H
示例#6
0
def benchmark_result():
    # Read H and calc using numpy
    sysStr = platform.system()
    if sysStr == 'Windows':
        #  Windows does not support SCF, using H2_generator instead
        print('Molecule data will be read from built-in function')
        Hamiltonian, N = H2_generator()
        print('Read Process Finished')
    elif sysStr == 'Linux' or sysStr == 'Darwin':
        # for linux only
        from paddle_quantum.VQE.chemistrygen import read_calc_H
        # Hamiltonian and cnot module preparing, must be executed under Linux
        # Read the H2 molecule data
        print('Molecule data will be read from h2.xyz')
        Hamiltonian, N = read_calc_H(geo_fn='h2.xyz')
        print('Read Process Finished')
    else:
        print("Don't support this os.")

    result = numpy.load('./output/summary_data.npz')

    eig_val, eig_state = numpy.linalg.eig(pauli_str_to_matrix(Hamiltonian, N))
    min_eig_H = numpy.min(eig_val.real)
    min_loss = numpy.ones([len(result['iter'])]) * min_eig_H

    plt.figure(1)
    func1, = plt.plot(result['iter'],
                      result['energy'],
                      alpha=0.7,
                      marker='',
                      linestyle="-",
                      color='r')
    func_min, = plt.plot(result['iter'],
                         min_loss,
                         alpha=0.7,
                         marker='',
                         linestyle=":",
                         color='b')
    plt.xlabel('Number of iteration')
    plt.ylabel('Energy (Ha)')

    plt.legend(
        handles=[func1, func_min],
        labels=[
            r'$\left\langle {\psi \left( {\theta } \right)} '
            r'\right|H\left| {\psi \left( {\theta } \right)} \right\rangle $',
            'Ground-state energy',
        ],
        loc='best')

    # plt.savefig("vqe.png", bbox_inches='tight', dpi=300)
    plt.show()
示例#7
0
def Generate_H_D(E, n):
    """
    This is to construct Hamiltonia H_D
     Args:
        E: edges of the graph
     Returns:
        Hamiltonia list
        Hamiltonia H_D
    """
    H_D_list = []
    for (u, v) in E:
        H_D_list.append([-1.0, 'z' + str(u) + ',z' + str(v)])
    print(H_D_list)
    H_D_matrix = pauli_str_to_matrix(H_D_list, n)

    return H_D_list, H_D_matrix
示例#8
0
def main():
    # 生成用泡利字符串表示的特定的哈密顿量
    H = [[-1.0, 'z0,z1'], [-1.0, 'z1,z2'], [-1.0, 'z0,z2']]

    # 生成哈密顿量的矩阵信息
    N_SYS_B = 3  # 用于生成吉布斯态的子系统B的量子比特数
    hamiltonian = pauli_str_to_matrix(H, N_SYS_B)

    # 生成理想情况下的目标吉布斯态 rho
    beta = 1.5  # 设置逆温度参数 beta
    rho_G = scipy.linalg.expm(-1 * beta * hamiltonian) / np_trace(scipy.linalg.expm(-1 * beta * hamiltonian))

    # 设置成 Paddle quantum 所支持的数据类型
    hamiltonian = hamiltonian.astype("complex128")
    rho_G = rho_G.astype("complex128")

    rho_B = Paddle_GIBBS(hamiltonian, rho_G)
    print(rho_B)
示例#9
0
def main():
    # Generate Pauli string representing a specific Hamiltonian
    H = [[-1.0, 'z0,z1'], [-1.0, 'z1,z2'], [-1.0, 'z0,z2']]

    # Generate the marix form of the Hamiltonian
    N_SYS_B = 3  # Number of qubits in subsystem B used to generate Gibbs state
    hamiltonian = pauli_str_to_matrix(H, N_SYS_B)

    # Generate the target Gibbs state rho
    beta = 1.5  # Set inverse temperature beta
    rho_G = scipy.linalg.expm(-1 * beta * hamiltonian) / np_trace(
        scipy.linalg.expm(-1 * beta * hamiltonian))

    # Convert to the data type supported by Paddle Quantum
    hamiltonian = hamiltonian.astype("complex128")
    rho_G = rho_G.astype("complex128")

    rho_B = Paddle_GIBBS(hamiltonian, rho_G)
    print(rho_B)
示例#10
0
    def expecval(self, H):
        r"""量子线路输出的量子态关于可观测量 H 的期望值。

        Hint:
            如果想输入的可观测量的矩阵为 :math:`0.7Z\otimes X\otimes I+0.2I\otimes Z\otimes I` 。则 ``H`` 应为 ``[[0.7, 'z0,x1'], [0.2, 'z1']]`` 。
        Args:
            H (list): 可观测量的相关信息
        Returns:
            Tensor: 量子线路输出的量子态关于 H 的期望值

        代码示例:
        
        .. code-block:: python
            
            import numpy as np
            import paddle
            from paddle_quantum.circuit import UAnsatz
            n = 5
            H_info = [[0.1, 'x1'], [0.2, 'y0,z4']]
            theta = paddle.to_tensor(np.ones(3))
            cir = UAnsatz(n)
            cir.rx(theta[0], 0)
            cir.rz(theta[1], 1)
            cir.rx(theta[2], 2)
            cir.run_state_vector()
            expect_value = cir.expecval(H_info).numpy()
            print(f'Calculated expectation value of {H_info} is {expect_value}')

        ::

            Calculated expectation value of [[0.1, 'x1'], [0.2, 'y0,z4']] is [-0.1682942]

        """
        if self.__run_state == 'state_vector':
            return real(vec_expecval(H, self.__state))
        elif self.__run_state == 'density_matrix':
            state = self.__state
            H_mat = paddle.to_tensor(pauli_str_to_matrix(H, self.n))
            return real(trace(matmul(state, H_mat)))
        else:
            # Raise error
            raise ValueError(
                "no state for measurement; please run the circuit first")
示例#11
0
def main(n=4):
    paddle.seed(SEED)

    p = 4  # number of layers in the circuit
    ITR = 120  # number of iterations
    LR = 0.1  # learning rate

    G = nx.cycle_graph(4)
    V = list(G.nodes())
    E = list(G.edges())
    # Draw the original graph
    pos = nx.circular_layout(G)
    nx.draw_networkx(G, pos, **options)
    ax = plt.gca()
    ax.margins(0.20)
    plt.axis("off")
    plt.show()

    # construct the Hamiltonian
    H_D_list = maxcut_hamiltonian(E)
    H_D_matrix = pauli_str_to_matrix(H_D_list, n)
    H_D_diag = np.diag(H_D_matrix).real
    H_max = np.max(H_D_diag)

    print(H_D_diag)
    print('H_max:', H_max)

    cut_bitstring, _ = find_cut(G, p, ITR, LR, print_loss=True, plot=True)
    print("The bit string form of the cut found:", cut_bitstring)

    node_cut = ["blue" if cut_bitstring[v] == "1" else "red" for v in V]
    edge_cut = [
        "solid" if cut_bitstring[u] == cut_bitstring[v] else "dashed"
        for (u, v) in G.edges()
    ]

    nx.draw(G, pos, node_color=node_cut, style=edge_cut, **options)
    ax = plt.gca()
    ax.margins(0.20)
    plt.axis("off")
    plt.show()
示例#12
0
def H_generator():
    """
    Generate a Hamiltonian with trivial descriptions
    Returns: A Hamiltonian
    """
    # Generate Pauli string representing a specific Hamiltonian
    H = [[-1.0, 'z0,z1'], [-1.0, 'z1,z2'], [-1.0, 'z0,z2']]

    # Generate the matrix form of the Hamiltonian
    N_SYS_B = 3  # Number of qubits in subsystem B used to generate Gibbs state
    hamiltonian = pauli_str_to_matrix(H, N_SYS_B)

    # Generate the target Gibbs state rho
    beta = 1.5  # Set inverse temperature beta
    rho_G = scipy.linalg.expm(-1 * beta * hamiltonian) / np_trace(
        scipy.linalg.expm(-1 * beta * hamiltonian))

    # Convert to the data type supported by Paddle Quantum
    hamiltonian = hamiltonian.astype("complex128")
    rho_G = rho_G.astype("complex128")
    return hamiltonian, rho_G
示例#13
0
def H_generator():
    """
    Generate a Hamiltonian with trivial descriptions
    Returns: A Hamiltonian
    """
    # 生成用泡利字符串表示的特定的哈密顿量
    H = [[-1.0, 'z0,z1'], [-1.0, 'z1,z2'], [-1.0, 'z0,z2']]

    # 生成哈密顿量的矩阵信息
    N_SYS_B = 3  # 用于生成吉布斯态的子系统B的量子比特数
    hamiltonian = pauli_str_to_matrix(H, N_SYS_B)

    # 生成理想情况下的目标吉布斯态 rho
    beta = 1.5  # 设置逆温度参数 beta
    rho_G = scipy.linalg.expm(-1 * beta * hamiltonian) / np_trace(
        scipy.linalg.expm(-1 * beta * hamiltonian))

    # 设置成 Paddle quantum 所支持的数据类型
    hamiltonian = hamiltonian.astype("complex128")
    rho_G = rho_G.astype("complex128")
    return hamiltonian, rho_G
示例#14
0
def main(N=4):
    # number of qubits or number of nodes in the graph
    N = 4
    classical_graph, classical_graph_adjacency = generate_graph(N,
                                                                GRAPHMETHOD=1)
    print(classical_graph_adjacency)

    # Convert the Hamiltonian's list form to matrix form
    H_matrix = pauli_str_to_matrix(H_generator(N, classical_graph_adjacency),
                                   N)

    H_diag = np.diag(H_matrix).real
    H_max = np.max(H_diag)
    H_min = np.min(H_diag)

    print(H_diag)
    print('H_max:', H_max, '  H_min:', H_min)

    pos = nx.circular_layout(classical_graph)
    nx.draw(classical_graph,
            pos,
            width=4,
            with_labels=True,
            font_weight='bold')
    plt.show()

    classical_graph, classical_graph_adjacency = generate_graph(N, 1)

    opt_cir = Paddle_QAOA(classical_graph_adjacency,
                          N=4,
                          P=4,
                          METHOD=1,
                          ITR=120,
                          LR=0.1)

    # Load the data of QAOA
    x1 = np.load('./output/summary_data.npz')

    H_min = np.ones([len(x1['iter'])]) * H_min

    # Plot loss
    loss_QAOA, = plt.plot(x1['iter'],
                          x1['energy'],
                          alpha=0.7,
                          marker='',
                          linestyle="--",
                          linewidth=2,
                          color='m')
    benchmark, = plt.plot(x1['iter'],
                          H_min,
                          alpha=0.7,
                          marker='',
                          linestyle=":",
                          linewidth=2,
                          color='b')
    plt.xlabel('Number of iteration')
    plt.ylabel('Performance of the loss function for QAOA')

    plt.legend(
        handles=[loss_QAOA, benchmark],
        labels=[
            r'Loss function $\left\langle {\psi \left( {\bf{\theta }} \right)} '
            r'\right|H\left| {\psi \left( {\bf{\theta }} \right)} \right\rangle $',
            'The benchmark result',
        ],
        loc='best')

    # Show the plot
    plt.show()

    with fluid.dygraph.guard():
        # Measure the output state of the QAOA circuit for 1024 shots by default
        prob_measure = opt_cir.measure(plot=True)

    # Find the max value in measured probability of bitstrings
    max_prob = max(prob_measure.values())
    # Find the bitstring with max probability
    solution_list = [
        result[0] for result in prob_measure.items() if result[1] == max_prob
    ]
    print("The output bitstring:", solution_list)

    # Draw the graph representing the first bitstring in the solution_list to the MaxCut-like problem
    head_bitstring = solution_list[0]

    node_cut = [
        "blue" if head_bitstring[node] == "1" else "red"
        for node in classical_graph
    ]

    edge_cut = [
        "solid"
        if head_bitstring[node_row] == head_bitstring[node_col] else "dashed"
        for node_row, node_col in classical_graph.edges()
    ]
    nx.draw(
        classical_graph,
        pos,
        node_color=node_cut,
        style=edge_cut,
        width=4,
        with_labels=True,
        font_weight="bold",
    )
    plt.show()
示例#15
0
    def expecval(self, H):
        r"""量子线路输出的量子态关于可观测量H的期望值。

        Hint:
            如果想输入的可观测量的矩阵为 :math:`0.7Z\otimes X\otimes I+0.2I\otimes Z\otimes I` 。则 ``H`` 应为 ``[[0.7, 'z0,x1'], [0.2, 'z1']]`` 。
        Args:
            H (list): 可观测量的相关信息
        Returns:
            Variable: 量子线路输出的量子态关于H的期望值

        代码示例:
        
        .. code-block:: python
            
            import numpy as np
            from paddle import fluid
            from paddle_quantum.circuit import UAnsatz
            n = 5
            H_info = [[0.1, 'x1'], [0.2, 'y0,z4']]
            theta = np.ones(3)
            input_state = np.ones(2**n)+0j
            input_state = input_state / np.linalg.norm(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.rz(theta[1], 1)
                cir.rx(theta[2], 2)
                cir.run_state_vector(input_state_var)
                expect_value = cir.expecval(H_info).numpy()
                print(f'计算得到的{H_info}期望值是{expect_value}')
        
        ::
        
            计算得到的[[0.1, 'x1'], [0.2, 'y0,z4']]期望值是[0.05403023]
        
        .. code-block:: python
            
            import numpy as np
            from paddle import fluid
            from paddle_quantum.circuit import UAnsatz
            n = 5
            H_info = [[0.1, 'x1'], [0.2, 'y0,z4']]
            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], 1)
                cir.rz(theta[2], 2)
                cir.run_density_matrix(input_state_var)
                expect_value = cir.expecval(H_info).numpy()
                print(f'计算得到的{H_info}期望值是{expect_value}')
        
        ::

            计算得到的[[0.1, 'x1'], [0.2, 'y0,z4']]期望值是[-0.02171538]
        """
        if self.__run_state == 'state_vector':
            return vec_expecval(H, self.__state).real
        elif self.__run_state == 'density_matrix':
            state = self.__state
            H_mat = fluid.dygraph.to_variable(pauli_str_to_matrix(H, self.n))
            return trace(matmul(state, H_mat)).real
        else:
            # Raise error
            raise ValueError(
                "no state for measurement; please run the circuit first")