functional.py 5.3 KB
Newer Older
Q
Quleaf 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
# !/usr/bin/env python3
# Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.
#
# 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.

"""
用于构建量子电路层的函数操作。
该模块依赖于 paddlepaddle 和 paddle_quantum
"""

import paddle
from paddle_quantum.circuit import UAnsatz


# Rotation layer function
def rot_layer(
        cir: UAnsatz,
        parameters: "paddle.Tensor[paddle.float64]",
        gate_type: str
) -> UAnsatz:
    r"""该函数用来在量子线路上添加一层单比特旋转门,"Rx", "Ry", "Rz"

    Args:
        cir (UAnsatz): 量子线路
        parameters (paddle.Tensor[paddle.float64]): 旋转门的旋转角度
        gate_type (str): "X", "Y" 和 "Z",例如:如果是 "Rx" 门,则添 "X"

    Returns:
        UAnsatz
    """

    n_qubits = cir.n
    assert n_qubits == len(parameters), \
        "length of the parameters must equal the number of qubits"

    for i in range(n_qubits):
        if gate_type == "X":
            cir.rx(parameters[i], i)
        elif gate_type == "Y":
            cir.ry(parameters[i], i)
        elif gate_type == "Z":
            cir.rz(parameters[i], i)

    return cir


# Euler rotation gate function
def euler_rotation(
        cir: UAnsatz,
        which_qubit: int,
        angles: "paddle.Tensor[paddle.float64]",
) -> UAnsatz:
    r"""该函数定义了单比特的 Euler 旋转门(使用 ZXZ 规范)

    .. math::
        U(\theta,\phi,\gamma)=e^{-i\gamma/2\hat{Z}}e^{-i\phi/2\hat{X}}e^{-i\theta/2\hat{X}}.

    Args:
        cir (UAnsatz): 量子线路
        which (int): Euler 旋转门作用的量子比特编号
        angles (paddle.Tensor[paddle.float64]): Euler 角,存储顺序与 ZXZ 操作的顺序相反。

    Returns:
        UAnsatz
    """
    cir.rz(angles[0], which_qubit)
    cir.rx(angles[1], which_qubit)
    cir.rz(angles[2], which_qubit)
    return cir


# Euler rotation layer function
def euler_rotation_layer(
        cir: UAnsatz,
        parameters: "paddle.Tensor[paddle.float64]",
) -> UAnsatz:
    r"""该函数会在给定的量子线路上添加一层 Euler 旋转门。

    Args:
        cir (UAnsatz): 量子线路。
        parameters (paddle.Tensor[paddle.float64]): Euler 角参数集合。
    """
    n_qubits = cir.n
    assert len(
        parameters) == 3 * n_qubits, "length of parameter should be 3 times of the number of qubits in the circuit."

    for i in range(n_qubits):
        cir = euler_rotation(cir, i, parameters[3 * i:3 * (i + 1)])

    return cir


# Cross resonance gate function
def cross_resonance(
        cir: UAnsatz,
        ctrl_targ: "list[int]",
        phase_angle: paddle.Tensor
) -> UAnsatz:
    r"""该函数定义了一个双比特的 cross resonance (CR) 门。

    .. math::
        U(\theta) = \exp(-i\frac{\theta}{2}\hat{X}\otimes\hat{Z})

    Args:
        cir (UAnsatz): 量子线路。
        ctrl_targ (list[int]): 控制比特和目标比特对应的比特编号。
        phase_angle (paddle.Tensor[paddle.float64]): 旋转角度。

    Returns:
        UAnsatz
    """
    cir.h(ctrl_targ[0])
    cir.rzz(phase_angle, ctrl_targ)
    cir.h(ctrl_targ[0])
    return cir


# Cross resonance layer function
def cr_layer(
        cir: UAnsatz,
        parameters: "paddle.Tensor[paddle.float64]",
        ctrl_qubit_index: "list[int]",
        targ_qubit_index: "list[int]"
) -> UAnsatz:
    """该函数在给定线路上按照给定的控制和目标比特编号添加一层 cross resonance (CR) 门。

    Args:
        cir (UAnsatz): 量子线路。
        parameters (paddle.Tensor[paddle.float64]): CR 门中的角度。
        ctrl_qubit_index (list[int]): 控制比特序号。
        targ_qubit_index (list[int]): 目标比特序号。

    Returns:
        UAnsatz
    """
    assert len(parameters) == len(ctrl_qubit_index) and len(ctrl_qubit_index) == len(targ_qubit_index), \
        "length of parameter must be the same as the number of cr gates"

    for i, ct_index in enumerate(zip(ctrl_qubit_index, targ_qubit_index)):
        cir = cross_resonance(cir, list(ct_index), parameters[i])

    return cir


# Nearest neighbor Givens rotation gate function
def givens_rotation(
        cir: UAnsatz,
        theta: "paddle.Tensor[paddle.float64]",
        q1_index: int,
        q2_index: int
) -> UAnsatz:
    r"""该函数定义了两个相邻比特之间的 Givens 旋转门。详细信息参见 https://arxiv.org/abs/1711.05395.

    Note:
        在 paddlequantum :math:`Ry(\theta)=e^{-i\frac{\theta}{2}\hat{Y}}`.

    Args:
        cir (UAnsatz): 量子线路。
        theta (paddle.Tensor[paddle.float64]): 操作中 Ry 门的角度。
        q1_index (int): 第一个 qubit 的编号。
        q2_index (int): 第二个 qubit 的编号。

    Returns:
        UAnsatz
    """

    cir.cnot([q2_index, q1_index])
    cir.cry(-2 * theta, [q1_index, q2_index])
    cir.cnot([q2_index, q1_index])
    return cir