Paddle_VQE.py 4.6 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

Q
Quleaf 已提交
23
import paddle
Q
Quleaf 已提交
24
from numpy import pi as PI
Q
Quleaf 已提交
25
from numpy import savez
Q
Quleaf 已提交
26
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


Q
Quleaf 已提交
61
class StateNet(paddle.nn.Layer):
Q
Quleaf 已提交
62 63 64 65
    """
    Construct the model net
    """

Q
Quleaf 已提交
66
    def __init__(self, shape, param_attr=paddle.nn.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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
    # Determine the dimensions of network
    net = StateNet(shape=[D + 1, N, 1])

    # Usually, we recommend Adam optimizer for better result. If you wish, you could use SGD or RMS prop.
    opt = paddle.optimizer.Adam(learning_rate=LR, parameters=net.parameters())

    # Record optimization results
    summary_iter, summary_loss = [], []

    # Optimization iterations
    for itr in range(1, ITR + 1):

        # Run forward propagation to calculate loss function
        loss = net(Hamiltonian, N, D)

        # In dynamic graph, run backward propagation to minimize loss function
        loss.backward()
        opt.minimize(loss)
        opt.clear_grad()

        # Update optimized results
        summary_loss.append(loss.numpy())
        summary_iter.append(itr)

        # Print results
        if itr % 20 == 0:
            print("iter:", itr, "loss:", "%.4f" % loss.numpy())
            print("iter:", itr, "Ground state energy:", "%.4f Ha" % loss.numpy())

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


def main():
Q
Quleaf 已提交
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
    # 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 已提交
149 150


Q
Quleaf 已提交
151
if __name__ == '__main__':
Q
Quleaf 已提交
152
    main()