Paddle_VQE.py 4.8 KB
Newer Older
Q
Quleaf 已提交
1
# Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.
Q
Quleaf 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
VQE: To learn more about the functions and properties of this application,
you could check the corresponding Jupyter notebook under the Tutorial folder.
"""

import os
Q
Quleaf 已提交
21
import platform
Q
Quleaf 已提交
22 23

from numpy import pi as PI
Q
Quleaf 已提交
24
from numpy import savez
Q
Quleaf 已提交
25 26
from paddle import fluid
from paddle_quantum.circuit import UAnsatz
Q
Quleaf 已提交
27 28 29
from paddle_quantum.VQE.benchmark import benchmark_result
from paddle_quantum.VQE.chemistrysub import H2_generator

Q
Quleaf 已提交
30 31 32 33 34 35 36 37

__all__ = [
    "U_theta",
    "StateNet",
    "Paddle_VQE",
]


Q
Quleaf 已提交
38
def U_theta(theta, Hamiltonian, N, D):
Q
Quleaf 已提交
39
    """
Q
Quleaf 已提交
40
    Quantum Neural Network
Q
Quleaf 已提交
41
    """
Q
Quleaf 已提交
42
    # Initialize the quantum neural network by the number of qubits (width of the network)
Q
Quleaf 已提交
43 44
    cir = UAnsatz(N)

Q
Quleaf 已提交
45
    # Use built-in template (R_y + CNOT)
Q
Quleaf 已提交
46 47
    cir.real_entangled_layer(theta[:D], D)

Q
Quleaf 已提交
48
    # Add a layer of R_y rotation gates
Q
Quleaf 已提交
49
    for i in range(N):
Q
Quleaf 已提交
50
        cir.ry(theta=theta[D][i][0], which_qubit=i)
Q
Quleaf 已提交
51

Q
Quleaf 已提交
52
    # Act QNN on the default initial state |0000>
Q
Quleaf 已提交
53
    cir.run_state_vector()
Q
Quleaf 已提交
54

Q
Quleaf 已提交
55
    # Calculate the expectation value of the given Hamiltonian
Q
Quleaf 已提交
56
    expectation_val = cir.expecval(Hamiltonian)
Q
Quleaf 已提交
57

Q
Quleaf 已提交
58
    return expectation_val
Q
Quleaf 已提交
59 60 61 62 63 64 65


class StateNet(fluid.dygraph.Layer):
    """
    Construct the model net
    """

Q
Quleaf 已提交
66
    def __init__(self, shape, param_attr=fluid.initializer.Uniform(low=0.0, high=2 * PI), dtype="float64"):
Q
Quleaf 已提交
67 68
        super(StateNet, self).__init__()

Q
Quleaf 已提交
69
        # Initialize theta by sampling from a uniform distribution [0, 2*pi]
Q
Quleaf 已提交
70
        self.theta = self.create_parameter(shape=shape, attr=param_attr, dtype=dtype, is_bias=False)
Q
Quleaf 已提交
71

Q
Quleaf 已提交
72
    # Define the loss function and forward propagation mechanism
Q
Quleaf 已提交
73
    def forward(self, Hamiltonian, N, D):
Q
Quleaf 已提交
74
        # Calculate loss function (expectation value)
Q
Quleaf 已提交
75
        loss = U_theta(self.theta, Hamiltonian, N, D)
Q
Quleaf 已提交
76

Q
Quleaf 已提交
77
        return loss
Q
Quleaf 已提交
78 79


Q
Quleaf 已提交
80 81 82
def Paddle_VQE(Hamiltonian, N, D=2, ITR=80, LR=0.2):
    r"""
    Main Learning network using dynamic graph
Q
Quleaf 已提交
83 84 85 86 87 88
    :param Hamiltonian: Hamiltonian
    :param N: Width of QNN
    :param D: Depth of QNN
    :param ITR: Number of iterations
    :param LR: Learning rate
    :return: No return
Q
Quleaf 已提交
89 90
    """

Q
Quleaf 已提交
91
    # Initialize PaddlePaddle dynamic graph machanism
Q
Quleaf 已提交
92
    with fluid.dygraph.guard():
Q
Quleaf 已提交
93
        # Determine the dimensions of network
Q
Quleaf 已提交
94 95
        # 确定网络的参数维度
        net = StateNet(shape=[D + 1, N, 1])
Q
Quleaf 已提交
96

Q
Quleaf 已提交
97
        # Usually, we recommend Adam optimizer for better result. If you wish, you could use SGD or RMS prop.
Q
Quleaf 已提交
98
        opt = fluid.optimizer.AdamOptimizer(learning_rate=LR, parameter_list=net.parameters())
Q
Quleaf 已提交
99

Q
Quleaf 已提交
100
        # Record optimization results
Q
Quleaf 已提交
101
        summary_iter, summary_loss = [], []
Q
Quleaf 已提交
102 103
        
        # Optimization iterations
Q
Quleaf 已提交
104 105
        for itr in range(1, ITR + 1):

Q
Quleaf 已提交
106
            # Run forward propagation to calculate loss function
Q
Quleaf 已提交
107 108
            loss = net(Hamiltonian, N, D)

Q
Quleaf 已提交
109
            # In dynamic graph, run backward propogation to minimize loss function
Q
Quleaf 已提交
110 111 112 113
            loss.backward()
            opt.minimize(loss)
            net.clear_gradients()

Q
Quleaf 已提交
114
            # Update optimized results
Q
Quleaf 已提交
115
            summary_loss.append(loss.numpy())
Q
Quleaf 已提交
116 117
            summary_iter.append(itr)

Q
Quleaf 已提交
118
            # Print results
Q
Quleaf 已提交
119 120 121
            if itr % 20 == 0:
                print("iter:", itr, "loss:", "%.4f" % loss.numpy())
                print("iter:", itr, "Ground state energy:", "%.4f Ha" % loss.numpy())
Q
Quleaf 已提交
122

Q
Quleaf 已提交
123
        # Save results in the 'output' directory
Q
Quleaf 已提交
124 125 126 127 128
        os.makedirs("output", exist_ok=True)
        savez("./output/summary_data", iter=summary_iter, energy=summary_loss)


def main():
Q
Quleaf 已提交
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
    # Read data from built-in function or xyz file depending on OS
    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 in ('Linux', '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.")

    Paddle_VQE(hamiltonian, N)
    benchmark_result()
Q
Quleaf 已提交
152 153


Q
Quleaf 已提交
154
if __name__ == '__main__':
Q
Quleaf 已提交
155
    main()