From 2ac9f371a39b2b62243588d6842263819f9ad8f0 Mon Sep 17 00:00:00 2001 From: Quleaf Date: Wed, 7 Dec 2022 15:56:15 +0800 Subject: [PATCH] update to v2.2.2 --- README.md | 6 +- README_CN.md | 8 +- docs/source/modules.rst | 4 +- .../source/paddle_quantum.gate.functional.rst | 1 + .../paddle_quantum.gate.functional.visual.rst | 6 + docs/source/paddle_quantum.qml.rst | 14 + docs/source/paddle_quantum.qml.vsql.rst | 7 + docs/source/paddle_quantum.qpp.angles.rst | 7 + docs/source/paddle_quantum.qpp.laurent.rst | 7 + docs/source/paddle_quantum.qpp.rst | 16 + docs/source/paddle_quantum.qpp.utils.rst | 7 + docs_zh_CN/source/modules.rst | 2 + .../source/paddle_quantum.ansatz.circuit.rst | 108 +- .../source/paddle_quantum.ansatz.vans.rst | 30 +- .../source/paddle_quantum.channel.common.rst | 26 +- .../source/paddle_quantum.gate.base.rst | 23 + .../source/paddle_quantum.gate.functional.rst | 1 + ...ntum.gate.functional.single_qubit_gate.rst | 30 + .../paddle_quantum.gate.functional.visual.rst | 30 + .../source/paddle_quantum.gate.layer.rst | 2 +- .../paddle_quantum.gate.single_qubit_gate.rst | 46 + docs_zh_CN/source/paddle_quantum.linalg.rst | 66 +- docs_zh_CN/source/paddle_quantum.qinfo.rst | 138 ++- docs_zh_CN/source/paddle_quantum.qml.rst | 11 + docs_zh_CN/source/paddle_quantum.qml.vsql.rst | 93 ++ .../source/paddle_quantum.qpp.angles.rst | 93 ++ .../source/paddle_quantum.qpp.laurent.rst | 282 +++++ docs_zh_CN/source/paddle_quantum.qpp.rst | 12 + .../source/paddle_quantum.qpp.utils.rst | 78 ++ .../source/paddle_quantum.qsvt.qsp_utils.rst | 2 +- .../source/paddle_quantum.state.state.rst | 133 ++- introduction/PaddleQuantum_QuLeaf_CN.ipynb | 52 +- introduction/PaddleQuantum_QuLeaf_EN.ipynb | 52 +- paddle_quantum/__init__.py | 4 +- paddle_quantum/ansatz/circuit.py | 295 +++-- paddle_quantum/ansatz/vans.py | 149 +-- paddle_quantum/channel/__init__.py | 2 + paddle_quantum/channel/common.py | 110 +- paddle_quantum/channel/custom.py | 89 +- paddle_quantum/channel/functional/__init__.py | 1 + paddle_quantum/channel/functional/common.py | 446 ++++++- paddle_quantum/gate/__init__.py | 2 +- paddle_quantum/gate/base.py | 73 +- paddle_quantum/gate/custom.py | 76 +- paddle_quantum/gate/encoding.py | 8 +- paddle_quantum/gate/functional/__init__.py | 2 + .../gate/functional/single_qubit_gate.py | 44 + paddle_quantum/gate/functional/visual.py | 816 +++++++++++++ paddle_quantum/gate/layer.py | 92 +- paddle_quantum/gate/multi_qubit_gate.py | 167 ++- paddle_quantum/gate/single_qubit_gate.py | 152 ++- paddle_quantum/hamiltonian.py | 62 +- paddle_quantum/intrinsic.py | 9 +- paddle_quantum/linalg.py | 229 ++-- paddle_quantum/locc/locc_ansatz.py | 1 - paddle_quantum/operator/operator.py | 82 +- paddle_quantum/qinfo.py | 568 +++++---- paddle_quantum/qml/__init__.py | 18 + paddle_quantum/qml/vsql.py | 237 ++++ paddle_quantum/qpp/__init__.py | 22 + paddle_quantum/qpp/angles.py | 290 +++++ paddle_quantum/qpp/laurent.py | 677 +++++++++++ paddle_quantum/qpp/utils.py | 309 +++++ paddle_quantum/state/__init__.py | 3 +- paddle_quantum/state/state.py | 464 ++++++-- paddle_quantum/visual.py | 2 + requirements.txt | 12 +- setup.py | 14 +- .../MAXCUT_CN.ipynb | 2 +- .../MAXCUT_EN.ipynb | 2 +- .../EntanglementDistillation_BBPSSW_CN.ipynb | 42 +- .../EntanglementDistillation_BBPSSW_EN.ipynb | 25 +- .../machine_learning/QApproximating_CN.ipynb | 6 +- .../machine_learning/QApproximating_EN.ipynb | 6 +- .../machine_learning/QAutoencoder_CN.ipynb | 81 +- .../machine_learning/QAutoencoder_EN.ipynb | 73 +- tutorials/machine_learning/VQAE_CN.ipynb | 994 ++++++++++++++++ tutorials/machine_learning/VQAE_EN.ipynb | 1030 +++++++++++++++++ .../figures/VQAE-fig-comparison.png | Bin 0 -> 37302 bytes .../figures/VQAE-fig-mlae.png | Bin 0 -> 244363 bytes .../figures/VQAE-fig-pesudo.png | Bin 0 -> 466047 bytes .../machine_learning/figures/VQAE-fig-qpe.png | Bin 0 -> 54241 bytes .../quantum_simulation/GibbsState_CN.ipynb | 42 +- .../quantum_simulation/GibbsState_EN.ipynb | 52 +- .../HamiltonianSimulation_CN.ipynb | 2 +- .../HamiltonianSimulation_EN.ipynb | 2 +- tutorials/quantum_simulation/QDRIFT_CN.ipynb | 557 +++++++++ tutorials/quantum_simulation/QDRIFT_EN.ipynb | 569 +++++++++ tutorials/quantum_simulation/QPP_CN.ipynb | 468 ++++++++ tutorials/quantum_simulation/QPP_EN.ipynb | 472 ++++++++ .../quantum_simulation/QSP_and_QSVT_CN.ipynb | 128 +- .../quantum_simulation/QSP_and_QSVT_EN.ipynb | 134 +-- .../quantum_simulation/VariationalQM_CN.ipynb | 609 ++++++++++ .../quantum_simulation/VariationalQM_EN.ipynb | 608 ++++++++++ .../quantum_simulation/figures/QM-fig-RI.png | Bin 0 -> 92518 bytes .../figures/QM-fig-V_RI3.png | Bin 0 -> 23643 bytes .../figures/QPP-fig-circuit.png | Bin 0 -> 18204 bytes .../figures/QPP-fig-state.png | Bin 0 -> 39595 bytes 98 files changed, 11561 insertions(+), 1263 deletions(-) create mode 100644 docs/source/paddle_quantum.gate.functional.visual.rst create mode 100644 docs/source/paddle_quantum.qml.rst create mode 100644 docs/source/paddle_quantum.qml.vsql.rst create mode 100644 docs/source/paddle_quantum.qpp.angles.rst create mode 100644 docs/source/paddle_quantum.qpp.laurent.rst create mode 100644 docs/source/paddle_quantum.qpp.rst create mode 100644 docs/source/paddle_quantum.qpp.utils.rst create mode 100644 docs_zh_CN/source/paddle_quantum.gate.functional.visual.rst create mode 100644 docs_zh_CN/source/paddle_quantum.qml.rst create mode 100644 docs_zh_CN/source/paddle_quantum.qml.vsql.rst create mode 100644 docs_zh_CN/source/paddle_quantum.qpp.angles.rst create mode 100644 docs_zh_CN/source/paddle_quantum.qpp.laurent.rst create mode 100644 docs_zh_CN/source/paddle_quantum.qpp.rst create mode 100644 docs_zh_CN/source/paddle_quantum.qpp.utils.rst create mode 100644 paddle_quantum/gate/functional/visual.py create mode 100644 paddle_quantum/qml/__init__.py create mode 100644 paddle_quantum/qml/vsql.py create mode 100644 paddle_quantum/qpp/__init__.py create mode 100644 paddle_quantum/qpp/angles.py create mode 100644 paddle_quantum/qpp/laurent.py create mode 100644 paddle_quantum/qpp/utils.py create mode 100644 tutorials/machine_learning/VQAE_CN.ipynb create mode 100644 tutorials/machine_learning/VQAE_EN.ipynb create mode 100644 tutorials/machine_learning/figures/VQAE-fig-comparison.png create mode 100644 tutorials/machine_learning/figures/VQAE-fig-mlae.png create mode 100644 tutorials/machine_learning/figures/VQAE-fig-pesudo.png create mode 100644 tutorials/machine_learning/figures/VQAE-fig-qpe.png create mode 100644 tutorials/quantum_simulation/QDRIFT_CN.ipynb create mode 100644 tutorials/quantum_simulation/QDRIFT_EN.ipynb create mode 100644 tutorials/quantum_simulation/QPP_CN.ipynb create mode 100644 tutorials/quantum_simulation/QPP_EN.ipynb create mode 100644 tutorials/quantum_simulation/VariationalQM_CN.ipynb create mode 100644 tutorials/quantum_simulation/VariationalQM_EN.ipynb create mode 100644 tutorials/quantum_simulation/figures/QM-fig-RI.png create mode 100644 tutorials/quantum_simulation/figures/QM-fig-V_RI3.png create mode 100644 tutorials/quantum_simulation/figures/QPP-fig-circuit.png create mode 100644 tutorials/quantum_simulation/figures/QPP-fig-state.png diff --git a/README.md b/README.md index b50bc9f..f6b9a88 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ English | [简体中文](README_CN.md) - + @@ -152,6 +152,9 @@ We provide tutorials covering quantum simulation, machine learning, combinatoria 9. [Simulate the Spin Dynamics on a Heisenberg Chain](./tutorials/quantum_simulation/SimulateHeisenberg_EN.ipynb) 10. [Distributed Variational Quantum Eigensolver Based on Schmidt Decomposition](./tutorials/quantum_simulation/DistributedVQE_EN.ipynb) 11. [Quantum Signal Processing and Quantum Singular Value Transformation](./tutorials/quantum_simulation/QSP_and_QSVT_EN.ipynb) + 12. [Hamiltonian Simulation with qDRIFT](./tutorials/quantum_simulation/QDRIFT_EN.ipynb) + 13. [Quantum Phase Processing](./tutorials/quantum_simulation/QPP_EN.ipynb) + 14. [Variational Quantum Metrology](./tutorials/quantum_simulation/VariationalQM_EN.ipynb) - [Machine Learning](./tutorials/machine_learning) 1. [Encoding Classical Data into Quantum States](./tutorials/machine_learning/DataEncoding_EN.ipynb) @@ -163,6 +166,7 @@ We provide tutorials covering quantum simulation, machine learning, combinatoria 7. [Variational Quantum Singular Value Decomposition (VQSVD)](./tutorials/machine_learning/VQSVD_EN.ipynb) 8. [Data Encoding Analysis](./tutorials/machine_learning/EncodingAnalysis_EN.ipynb) 9. [Quantum Neural Network Approximating Functions](./tutorials/machine_learning/QApproximating_EN.ipynb) + 10. [Variational quantum amplitude estimation](./tutorials/machine_learning/VQAE_EN.ipynb) - [Combinatorial Optimization](./tutorials/combinatorial_optimization) 1. [Quantum Approximation Optimization Algorithm (QAOA)](./tutorials/combinatorial_optimization/QAOA_EN.ipynb) diff --git a/README_CN.md b/README_CN.md index da89185..fe241cd 100644 --- a/README_CN.md +++ b/README_CN.md @@ -34,7 +34,7 @@ - + @@ -75,7 +75,7 @@ ### 安装 Paddle Quantum -我们推荐通过 `pip` 完成安装, +我们推荐通过 `pip` 完成安装, ```bash pip install paddle-quantum @@ -161,6 +161,9 @@ Paddle Quantum(量桨)建立起了人工智能与量子计算的桥梁,为 9. [模拟一维海森堡链的自旋动力学](./tutorials/quantum_simulation/SimulateHeisenberg_CN.ipynb) 10. [基于施密特分解的分布式变分量子本征求解器](./tutorials/quantum_simulation/DistributedVQE_CN.ipynb) 11. [量子信号处理与量子奇异值变换](./tutorials/quantum_simulation/QSP_and_QSVT_CN.ipynb) + 12. [利用 qDRIFT 模拟时间演化](./tutorials/quantum_simulation/QDRIFT_CN.ipynb) + 13. [量子相位处理](./tutorials/quantum_simulation/QPP_CN.ipynb) + 14. [变分量子精密测量](./tutorials/quantum_simulation/VariationalQM_CN.ipynb) - [机器学习](./tutorials/machine_learning) @@ -173,6 +176,7 @@ Paddle Quantum(量桨)建立起了人工智能与量子计算的桥梁,为 7. [变分量子奇异值分解(VQSVD)](./tutorials/machine_learning/VQSVD_CN.ipynb) 8. [数据编码分析](./tutorials/machine_learning/EncodingAnalysis_CN.ipynb) 9. [量子神经网络模拟函数](./tutorials/machine_learning/QApproximating_CN.ipynb) + 10. [变分量子振幅估算](./tutorials/machine_learning/VQAE_CN.ipynb) - [组合优化](./tutorials/combinatorial_optimization) 1. [量子近似优化算法(QAOA)](./tutorials/combinatorial_optimization/QAOA_CN.ipynb) diff --git a/docs/source/modules.rst b/docs/source/modules.rst index dab2a01..d870e56 100644 --- a/docs/source/modules.rst +++ b/docs/source/modules.rst @@ -19,7 +19,9 @@ paddle_quantum.hamiltonian paddle_quantum.linalg paddle_quantum.qinfo + paddle_quantum.qml paddle_quantum.shadow paddle_quantum.trotter paddle_quantum.visual - paddle_quantum.qsvt \ No newline at end of file + paddle_quantum.qsvt + paddle_quantum.qpp diff --git a/docs/source/paddle_quantum.gate.functional.rst b/docs/source/paddle_quantum.gate.functional.rst index 0516b4e..dc887d2 100644 --- a/docs/source/paddle_quantum.gate.functional.rst +++ b/docs/source/paddle_quantum.gate.functional.rst @@ -13,3 +13,4 @@ paddle\_quantum.gate.functional paddle_quantum.gate.functional.base paddle_quantum.gate.functional.multi_qubit_gate paddle_quantum.gate.functional.single_qubit_gate + paddle_quantum.gate.functional.visual \ No newline at end of file diff --git a/docs/source/paddle_quantum.gate.functional.visual.rst b/docs/source/paddle_quantum.gate.functional.visual.rst new file mode 100644 index 0000000..19f08f4 --- /dev/null +++ b/docs/source/paddle_quantum.gate.functional.visual.rst @@ -0,0 +1,6 @@ +paddle\_quantum.gate.functional.base +=========================================== + +.. automodule:: paddle_quantum.gate.functional.visual + :members: + :show-inheritance: diff --git a/docs/source/paddle_quantum.qml.rst b/docs/source/paddle_quantum.qml.rst new file mode 100644 index 0000000..270547c --- /dev/null +++ b/docs/source/paddle_quantum.qml.rst @@ -0,0 +1,14 @@ +paddle\_quantum.qml +============================ + +.. automodule:: paddle_quantum.qml + :members: + :undoc-members: + :show-inheritance: + +.. rubric:: Submodules + +.. toctree:: + :maxdepth: 4 + + paddle_quantum.qml.vsql diff --git a/docs/source/paddle_quantum.qml.vsql.rst b/docs/source/paddle_quantum.qml.vsql.rst new file mode 100644 index 0000000..6aed664 --- /dev/null +++ b/docs/source/paddle_quantum.qml.vsql.rst @@ -0,0 +1,7 @@ +paddle\_quantum.qml.vsql +================================== + +.. automodule:: paddle_quantum.qml.vsql + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/paddle_quantum.qpp.angles.rst b/docs/source/paddle_quantum.qpp.angles.rst new file mode 100644 index 0000000..c7a9075 --- /dev/null +++ b/docs/source/paddle_quantum.qpp.angles.rst @@ -0,0 +1,7 @@ +paddle\_quantum.qpp.angles +============================ + +.. automodule:: paddle_quantum.qpp.angles + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/paddle_quantum.qpp.laurent.rst b/docs/source/paddle_quantum.qpp.laurent.rst new file mode 100644 index 0000000..5e2361c --- /dev/null +++ b/docs/source/paddle_quantum.qpp.laurent.rst @@ -0,0 +1,7 @@ +paddle\_quantum.qpp.laurent +============================ + +.. automodule:: paddle_quantum.qpp.laurent + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/paddle_quantum.qpp.rst b/docs/source/paddle_quantum.qpp.rst new file mode 100644 index 0000000..02f1efa --- /dev/null +++ b/docs/source/paddle_quantum.qpp.rst @@ -0,0 +1,16 @@ +paddle\_quantum.qpp +============================ + +.. automodule:: paddle_quantum.qpp + :members: + :undoc-members: + :show-inheritance: + +.. rubric:: Submodules + +.. toctree:: + :maxdepth: 4 + + paddle_quantum.qpp.angles + paddle_quantum.qpp.laurent + paddle_quantum.qpp.utils \ No newline at end of file diff --git a/docs/source/paddle_quantum.qpp.utils.rst b/docs/source/paddle_quantum.qpp.utils.rst new file mode 100644 index 0000000..e7d935e --- /dev/null +++ b/docs/source/paddle_quantum.qpp.utils.rst @@ -0,0 +1,7 @@ +paddle\_quantum.qpp.qpp.utils +============================= + +.. automodule:: paddle_quantum.qpp.utils + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/docs_zh_CN/source/modules.rst b/docs_zh_CN/source/modules.rst index 9d4382d..d870e56 100644 --- a/docs_zh_CN/source/modules.rst +++ b/docs_zh_CN/source/modules.rst @@ -19,7 +19,9 @@ paddle_quantum.hamiltonian paddle_quantum.linalg paddle_quantum.qinfo + paddle_quantum.qml paddle_quantum.shadow paddle_quantum.trotter paddle_quantum.visual paddle_quantum.qsvt + paddle_quantum.qpp diff --git a/docs_zh_CN/source/paddle_quantum.ansatz.circuit.rst b/docs_zh_CN/source/paddle_quantum.ansatz.circuit.rst index 3326916..55285b3 100644 --- a/docs_zh_CN/source/paddle_quantum.ansatz.circuit.rst +++ b/docs_zh_CN/source/paddle_quantum.ansatz.circuit.rst @@ -28,10 +28,6 @@ paddle\_quantum.ansatz.circuit 展平后的电路参数梯度。 - .. py:property:: depth() - - 电路深度 - .. py:method:: update_param(theta, idx=None) 替换单层或所有的电路参数。 @@ -98,6 +94,27 @@ paddle\_quantum.ansatz.circuit :param depth: 层数,默认为 ``1``。 :type depth: int, optional + .. py:method:: sdg(qubits_idx='full', num_qubits=None, depth=1) + + 添加单量子比特 S dagger (逆S)门。 + + 其矩阵形式为: + + .. math:: + + S ^\dagger = + \begin{bmatrix} + 1 & 0\ \ + 0 & -i + \end{bmatrix} + + :param qubits_idx: 作用在的量子比特的编号,默认为 ``'full'``。 + :type qubits_idx: Union[Iterable[int], int, str], optional + :param num_qubits: 总共的量子比特数量,默认为 ``None``。 + :type num_qubits: int, optional + :param depth: 层数,默认为 ``1``。 + :type depth: int, optional + .. py:method:: t(qubits_idx='full', num_qubits=None, depth=1) 添加单量子比特 T 门。 @@ -118,7 +135,28 @@ paddle\_quantum.ansatz.circuit :type num_qubits: int, optional :param depth: 层数,默认为 ``1``。 :type depth: int, optional - + + .. py:method:: tdg(qubits_idx='full', num_qubits=None, depth=1) + + 添加单量子比特 T dagger (逆T)门。 + + 其矩阵形式为: + + .. math:: + + T ^\dagger = + \begin{bmatrix} + 1 & 0\ \ + 0 & e^\frac{i\pi}{4} + \end{bmatrix} + + :param qubits_idx: 作用在的量子比特的编号,默认为 ``'full'``。 + :type qubits_idx: Union[Iterable[int], int, str], optional + :param num_qubits: 总共的量子比特数量,默认为 ``None``。 + :type num_qubits: int, optional + :param depth: 层数,默认为 ``1``。 + :type depth: int, optional + .. py:method:: x(qubits_idx='full', num_qubits=None, depth=1) 添加单量子比特 X 门。 @@ -767,7 +805,7 @@ paddle\_quantum.ansatz.circuit :param param_sharing: 同一层中的量子门是否共享参数,默认为 ``False``。 :type param_sharing: bool, optional - .. py:method:: oracle(oracle, qubits_idx, num_qubits=None, depth=1) + .. py:method:: oracle(oracle, qubits_idx, num_qubits=None, depth=1, gate_name='0', latex_name=None, plot_width=None) 添加一个 oracle 门。 @@ -781,8 +819,12 @@ paddle\_quantum.ansatz.circuit :type depth: int, optional :param gate_name: oracle 的名字,默认为 ``O``。 :type gate_name: str, optional + :param latex_name: oracle 的Latex名字,默认为 None, 此时用 gate_name。 + :type latex_name: str, optional + :param plot_width: 电路图中此门的宽度,默认为None,此时与门名称成比例。 + :type gate_name: float, optional - .. py:method:: control_oracle(oracle, qubits_idx, num_qubits=None, depth=1) + .. py:method:: control_oracle(oracle, qubits_idx, num_qubits=None, depth=1, gate_name='0', latex_name=None, plot_width=None) 添加一个受控 oracle 门。 @@ -796,6 +838,10 @@ paddle\_quantum.ansatz.circuit :type depth: int, optional :param gate_name: oracle 的名字,默认为 ``cO``。 :type gate_name: str, optional + :param latex_name: oracle 的Latex名字,默认为 None, 此时用 gate_name。 + :type latex_name: str, optional + :param plot_width: 电路图中此门的宽度,默认为None,此时与门名称成比例。 + :type gate_name: float, optional .. py:method:: collapse(qubits_idx='full', num_qubits=None, desired_result=None, if_print=False, measure_basis='z') @@ -936,13 +982,13 @@ paddle\_quantum.ansatz.circuit :param num_qubits: 总的量子比特个数,默认为 ``None``。 :type num_qubits: int, optional - .. py:method:: generalized_amplitude_damping(gamma, qubits_idx='full', num_qubits=None) + .. py:method:: generalized_amplitude_damping(gamma, prob, qubits_idx='full', num_qubits=None) 添加广义振幅阻尼信道。 - :param gamma: 减振概率。 + :param gamma: 减振概率,其值应该在 :math:`[0, 1]` 区间内。 :type prob: Union[paddle.Tensor, float] - :param prob: 激发概率。 + :param prob: 激发概率,其值应该在 :math:`[0, 1]` 区间内。 :type prob: Union[paddle.Tensor, float] :param qubits_idx: 作用在的量子比特的编号, 默认为 ``'full'``。 :type qubits_idx: Union[Iterable[int], int, str], optional @@ -1006,6 +1052,17 @@ paddle\_quantum.ansatz.circuit :param num_qubits: 总的量子比特个数,默认为 ``None``。 :type num_qubits: int, optional + .. py:method:: mixed_unitary_channel(num_unitary, qubits_idx='full', num_qubits=None) + + 添加混合酉矩阵信道 + + :param num_unitary: 用于构成信道的酉矩阵的数量。 + :type num_unitary: Union[paddle.Tensor, Iterable[int]] + :param qubits_idx: 作用在的量子比特的编号, 默认为 ``'full'``。 + :type qubits_idx: Union[Iterable[int], int, str], optional + :param num_qubits: 总的量子比特个数,默认为 ``None``。 + :type num_qubits: int, optional + .. py:method:: kraus_repr(kraus_oper, qubits_idx, num_qubits=None) 添加一个 Kraus 表示的自定义量子信道。 @@ -1040,3 +1097,34 @@ paddle\_quantum.ansatz.circuit :return: 每个比特上的量子门的插入历史 :rtype: List[List[Tuple[Dict[str, Union[str, List[int], paddle.Tensor]], int]]] + + .. py:method:: plot(save_path, dpi=100, show=True, output=False, scale=1.0, tex=False) + + 画出量子电路图 + + :param save_path: 图像保存的路径,默认为 ``None``。 + :type save_path: str, optional + :param dpi: 每英寸像素数,这里指分辨率, 默认为 `100`。 + :type dpi: int, optional + :param show: 是否执行 ``plt.show()``, 默认为 ``True``。 + :type show: bool, optional + :param output: 是否返回 ``matplotlib.figure.Figure`` 实例,默认为 ``False``。 + :type output: bool, optional + :param scale: ``figure`` 的 ``scale`` 系数,默认为 `1.0`。 + :type scale: float, optional + :param tex: 一个布尔变量,用于控制是否使用 TeX 字体,默认为 ``False``。 + :type tex: bool, optional + + :return: 根据 ``output`` 参数返回 ``matplotlib.figure.Figure`` 实例或 ``None``。 + :rtype: Union[None, matplotlib.figure.Figure] + + .. note:: + + 使用 ``plt.show()`` 或许会导致一些问题,但是在保存图片时不会发生。如果电路太深可能会有一些图形无法显示。如果设置 ``tex = True`` 则需要在你的系统上安装 TeX 及其相关的依赖包。更多细节参考 https://matplotlib.org/stable/gallery/text_labels_and_annotations/tex_demo.html + + .. py:method:: extend(cir) + + 量子电路扩展 + + :param cir: 量子电路。 + :type cir: Circuit \ No newline at end of file diff --git a/docs_zh_CN/source/paddle_quantum.ansatz.vans.rst b/docs_zh_CN/source/paddle_quantum.ansatz.vans.rst index 437f92f..b8d2074 100644 --- a/docs_zh_CN/source/paddle_quantum.ansatz.vans.rst +++ b/docs_zh_CN/source/paddle_quantum.ansatz.vans.rst @@ -3,6 +3,21 @@ paddle\_quantum.ansatz.vans 可变结构电路的功能实现。 +.. py:function:: cir_decompose(cir) + + 将电路中的 Layer 分解成量子门, 如果需要的话可以把所有参数门的输入转为可训练参数 + + :param cir: 待分解电路 + :type cir: Circuit + :param trainable: 是否将分解后的参数量子门输入转为参数baidu + :type trainable: bool, optional + :return: 分解后的电路 + :rtype: Circuit + + .. note:: + + 该量子电路稳定支持原生门,不支持 oracle 等其他自定义量子门。 + .. py:class:: Inserter 基类: :py:class:`object` @@ -39,21 +54,6 @@ paddle\_quantum.ansatz.vans :return: 简化后的电路。 :rtype: Circuit -.. py:function:: cir_decompose(cir) - - 将电路中的 Layer 分解成量子门, 如果需要的话可以把所有参数门的输入转为可训练参数 - - :param cir: 待分解电路 - :type cir: Circuit - :param trainable: 是否将分解后的参数量子门输入转为参数 - :type trainable: bool, optional - :return: 分解后的电路 - :rtype: Circuit - - .. note:: - - 该量子电路稳定支持原生门,不支持 oracle 等其他自定义量子门。 - .. py:class:: VAns(n, loss_func, *loss_func_args, epsilon=0.1, insert_rate=2, iter=100, iter_out=10, LR =0.1, threshold=0.002, accept_wall=100, zero_init_state=True) 基类: :py:class:`object` diff --git a/docs_zh_CN/source/paddle_quantum.channel.common.rst b/docs_zh_CN/source/paddle_quantum.channel.common.rst index 6545f6d..ff5adc2 100644 --- a/docs_zh_CN/source/paddle_quantum.channel.common.rst +++ b/docs_zh_CN/source/paddle_quantum.channel.common.rst @@ -157,10 +157,10 @@ paddle\_quantum.channel.common .. math:: - E_0 = \sqrt{1-p} I, - E_1 = \sqrt{p/3} X, - E_2 = \sqrt{p/3} Y, - E_3 = \sqrt{p/3} Z. + E_0 = \sqrt{1-3p/4} I, + E_1 = \sqrt{p/4} X, + E_2 = \sqrt{p/4} Y, + E_3 = \sqrt{p/4} Z. :param prob: 该信道的参数,其值应该在 :math:`[0, 1]` 区间内。 :type prob: Union[paddle.Tensor, float] @@ -169,6 +169,11 @@ paddle\_quantum.channel.common :param num_qubits: 总的量子比特个数,默认为 ``None``。 :type num_qubits: int, optional + .. note:: + 该功能的实现逻辑已更新。 + 当前版本请参考 M.A.Nielsen and I.L.Chuang 所著 Quantum Computation and Quantum Information 第10版中的 (8.102) 式。 + 参考文献: Nielsen, M., & Chuang, I. (2010). Quantum Computation and Quantum Information: 10th Anniversary Edition. Cambridge: Cambridge University Press. doi:10.1017/CBO9780511976667 + .. py:class:: PauliChannel(prob, qubits_idx='full', num_qubits) 基类::py:class:`paddle_quantum.channel.base.Channel` @@ -249,3 +254,16 @@ paddle\_quantum.channel.common .. note:: 时间常数必须满足 :math:`T_2 \le T_1`,见参考文献 https://arxiv.org/abs/2101.02109。 + +.. py:class:: MixedUnitaryChannel(num_unitary, qubits_idx='full', num_qubits=None) + + 基类::py:class:`paddle_quantum.channel.base.Channel` + + 混合酉矩阵信道。 + + :param num_unitary: 用于构成信道的酉矩阵数量。 + :type num_unitary: int + :param qubits_idx: 作用在的量子比特的编号,默认为 ``'full'``。 + :type qubits_idx: Union[Iterable[int], int, str], optional + :param num_qubits: 总的量子比特个数,默认为 ``None``。 + :type num_qubits: int, optional \ No newline at end of file diff --git a/docs_zh_CN/source/paddle_quantum.gate.base.rst b/docs_zh_CN/source/paddle_quantum.gate.base.rst index 521785d..eed713d 100644 --- a/docs_zh_CN/source/paddle_quantum.gate.base.rst +++ b/docs_zh_CN/source/paddle_quantum.gate.base.rst @@ -24,6 +24,29 @@ paddle\_quantum.gate.base 生成量子门的历史记录 + .. py:method:: set_gate_info(**kwargs) + + 设置 `gate_info` 的接口 + + :param kwargs: 用于设置 `gate_info` 的参数。 + :type kwargs: Any + + .. py:method:: display_in_circuit(ax, x) + + 画出量子电路图,在 `Circuit` 类中被调用。 + + :param ax: ``matplotlib.axes.Axes`` 的实例. + :type ax: matplotlib.axes.Axes + :param x: 开始的水平位置。 + :type x: float + + :return: 占用的总宽度。 + :rtype: float + + .. note:: + + 使用者可以覆写此函数,从而自定义显示方式。 + .. py:class:: ParamGate 基类::py:class:`paddle_quantum.gate.base.Gate` diff --git a/docs_zh_CN/source/paddle_quantum.gate.functional.rst b/docs_zh_CN/source/paddle_quantum.gate.functional.rst index 03d32ca..3f13425 100644 --- a/docs_zh_CN/source/paddle_quantum.gate.functional.rst +++ b/docs_zh_CN/source/paddle_quantum.gate.functional.rst @@ -11,3 +11,4 @@ paddle\_quantum.gate.functional paddle_quantum.gate.functional.base paddle_quantum.gate.functional.multi_qubit_gate paddle_quantum.gate.functional.single_qubit_gate + paddle_quantum.gate.functional.visual diff --git a/docs_zh_CN/source/paddle_quantum.gate.functional.single_qubit_gate.rst b/docs_zh_CN/source/paddle_quantum.gate.functional.single_qubit_gate.rst index 4a36743..5c3cfb9 100644 --- a/docs_zh_CN/source/paddle_quantum.gate.functional.single_qubit_gate.rst +++ b/docs_zh_CN/source/paddle_quantum.gate.functional.single_qubit_gate.rst @@ -33,6 +33,21 @@ paddle\_quantum.gate.functional.single\_qubit\_gate :return: 输出态。 :rtype: paddle_quantum.State +.. py:function:: sdg(state, qubit_idx, dtype, backend) + + 在输入态上作用一个S dagger(逆S)门。 + + :param state: 输入态。 + :type state: paddle_quantum.State + :param qubit_idx: 作用在量子比特的编号。 + :type qubit_idx: int + :param dtype: 数据的类型。 + :type dtype: str + :param backend: 运行模拟的后端。 + :type backend: paddle_quantum.Backend + :return: 输出态。 + :rtype: paddle_quantum.State + .. py:function:: t(state, qubit_idx, dtype, backend) 在输入态上作用一个 T 门。 @@ -48,6 +63,21 @@ paddle\_quantum.gate.functional.single\_qubit\_gate :return: 输出态。 :rtype: paddle_quantum.State +.. py:function:: tdg(state, qubit_idx, dtype, backend) + + 在输入态上作用一个T dagger(逆T)门。 + + :param state: 输入态。 + :type state: paddle_quantum.State + :param qubit_idx: 作用在量子比特的编号。 + :type qubit_idx: int + :param dtype: 数据的类型。 + :type dtype: str + :param backend: 运行模拟的后端。 + :type backend: paddle_quantum.Backend + :return: 输出态。 + :rtype: paddle_quantum.State + .. py:function:: x(state, qubit_idx, dtype, backend) 在输入态上作用一个 X 门。 diff --git a/docs_zh_CN/source/paddle_quantum.gate.functional.visual.rst b/docs_zh_CN/source/paddle_quantum.gate.functional.visual.rst new file mode 100644 index 0000000..ba5b5e5 --- /dev/null +++ b/docs_zh_CN/source/paddle_quantum.gate.functional.visual.rst @@ -0,0 +1,30 @@ +paddle\_quantum.gate.functional.visual +======================================= + +可视化 ``paddle_quantum.ansatz.Circuit`` 类中量子门的函数 + +.. py:function:: scale_circuit_plot_param(scale) + + 根据 ``scale`` 修改 ``__CIRCUIT_PLOT_PARAM`` 的字典参数。 + + :param scale: 画图参数的缩放标量。 + :type scale: float + +.. py:function:: set_circuit_plot_param(**kwargs) + + 自定义画图参数字典 ``__CIRCUIT_PLOT_PARAM``。 + + :param kwargs: 需要更新的字典 ``__CIRCUIT_PLOT_PARAM`` 参数。 + :type scale: Any + +.. py:function:: get_circuit_plot_param() + + 输出画图参数字典 ``__CIRCUIT_PLOT_PARAM``。 + + :return: ``__CIRCUIT_PLOT_PARAM`` 字典的拷贝。 + :rtype: dict + +.. py:function:: reset_circuit_plot_param() + + 重置画图参数字典 ``__CIRCUIT_PLOT_PARAM``。 + diff --git a/docs_zh_CN/source/paddle_quantum.gate.layer.rst b/docs_zh_CN/source/paddle_quantum.gate.layer.rst index d2b7d43..4c9177c 100644 --- a/docs_zh_CN/source/paddle_quantum.gate.layer.rst +++ b/docs_zh_CN/source/paddle_quantum.gate.layer.rst @@ -140,7 +140,7 @@ paddle\_quantum.gate.layer :param depth: 层数,默认为 ``1``。 :type depth: int, optional -.. py:class:: QAOALayer(Gate) +.. py:class:: QAOALayerWeighted(Gate) 基类::py:class:`paddle_quantum.gate.base.Gate` diff --git a/docs_zh_CN/source/paddle_quantum.gate.single_qubit_gate.rst b/docs_zh_CN/source/paddle_quantum.gate.single_qubit_gate.rst index 9bc63b9..9866d32 100644 --- a/docs_zh_CN/source/paddle_quantum.gate.single_qubit_gate.rst +++ b/docs_zh_CN/source/paddle_quantum.gate.single_qubit_gate.rst @@ -49,6 +49,29 @@ paddle\_quantum.gate.single\_qubit\_gate :param depth: 层数,默认为 ``1``。 :type depth: int, optional +.. py:class:: Sdg(qubits_idx='full', num_qubits=None, depth=1) + + 基类::py:class:`paddle_quantum.gate.base.Gate` + + 单量子比特S dagger(逆S)门。 + + 其矩阵形式为: + + .. math:: + + S ^\dagger = + \begin{bmatrix} + 1 & 0\ \ + 0 & -i + \end{bmatrix} + + :param qubits_idx:作用在的量子比特的编号,默认为``'full'``。 + :type qubits_idx: Union[Iterable, int, str], optional + :param num_qubits:总的量子比特个数,默认为``None``。 + :type num_qubits: int, optional + :param depth: 层数,默认为``1``。 + :type depth: int, optional + .. py:class:: T(qubits_idx='full', num_qubits=None, depth=1) 基类::py:class:`paddle_quantum.gate.base.Gate` @@ -72,6 +95,29 @@ paddle\_quantum.gate.single\_qubit\_gate :param depth: 层数,默认为 ``1``。 :type depth: int, optional +.. py:class:: Tdg(qubits_idx='full', num_qubits=None, depth=1) + + 基类::py:class:`paddle_quantum.gate.base.Gate` + + 单量子比特T dagger(逆T)门。 + + 其矩阵形式为: + + .. math:: + + T ^\dagger = + \begin{bmatrix} + 1 & 0\ \ + 0 & e^{-\frac{i\pi}{4}} + \end{bmatrix} + + :param qubits_idx:作用在的量子比特的编号,默认为``'full'``。 + :type qubits_idx: Union[Iterable, int, str], optional + :param num_qubits:总的量子比特个数,默认为``None``。 + :type num_qubits: int, optional + :param depth: 层数,默认为``1``。 + :type depth: int, optional + .. py:class:: X(qubits_idx='full', num_qubits=None, depth=1) 基类::py:class:`paddle_quantum.gate.base.Gate` diff --git a/docs_zh_CN/source/paddle_quantum.linalg.rst b/docs_zh_CN/source/paddle_quantum.linalg.rst index 52d9cda..e81e31a 100644 --- a/docs_zh_CN/source/paddle_quantum.linalg.rst +++ b/docs_zh_CN/source/paddle_quantum.linalg.rst @@ -8,7 +8,7 @@ paddle\_quantum.linalg 计算矩阵范数 :param mat: 矩阵 - :type mat: paddle.Tensor + :type mat: Union[np.ndarray, paddle.Tensor, State] :return: 范数 :rtype: float @@ -18,17 +18,17 @@ paddle\_quantum.linalg 计算矩阵的转置共轭 :param mat: 矩阵 - :type mat: paddle.Tensor + :type mat: Union[np.ndarray, paddle.Tensor] :return: 矩阵的转置共轭 - :rtype: paddle.Tensor + :rtype: Union[np.ndarray, paddle.Tensor] .. py:function:: is_hermitian(mat, eps=1e-6) 验证矩阵 ``P`` 是否为厄密矩阵 :param mat: 厄密矩阵 - :type mat: paddle.Tensor + :type mat: Union[np.ndarray, paddle.Tensor] :param eps: 容错率 :type eps: float, optional @@ -40,7 +40,7 @@ paddle\_quantum.linalg 验证矩阵 ``P`` 是否为映射算子 :param mat: 映射算子 - :type mat: paddle.Tensor + :type mat: Union[np.ndarray, paddle.Tensor] :param eps: 容错率 :type eps: float, optional @@ -52,7 +52,7 @@ paddle\_quantum.linalg 验证矩阵 ``P`` 是否为酉矩阵 :param mat: 酉矩阵 - :type mat: paddle.Tensor + :type mat: Union[np.ndarray, paddle.Tensor] :param eps: 容错率 :type eps: float, optional @@ -116,11 +116,23 @@ paddle\_quantum.linalg :param num_qubits: 量子比特数 n :type num_qubits: int :param is_unitary: 厄密矩阵块是否是酉矩阵的 1/2 - :type is_unitary: bool + :type is_unitary: bool, optional :return: 一个左上半部分为厄密矩阵的 :math:`2^n \times 2^n` 酉矩阵 (n 为量子比特数) :rtype: paddle.Tensor +.. py:function:: block_enc_herm(mat, num_block_qubits) + + 生成厄密矩阵的分组编码 + + :param mat: 用于分组编码的矩阵 + :type mat: Union[np.ndarray, paddle.Tensor] + :param num_block_qubits: 用于分组编码的辅助量子比特数 + :type num_block_qubits: int, optional + + :return: 返回分组编码后的酉矩阵 + :rtype: Union[np.ndarray, paddle.Tensor] + .. py:function:: haar_orthogonal(num_qubits) 生成一个服从 Haar random 的正交矩阵。采样算法参考文献: arXiv:math-ph/0609050v2 @@ -167,16 +179,54 @@ paddle\_quantum.linalg :return: 一个 :math:`2^n \times 2^n` 密度矩阵 (n 为量子比特数) :rtype: paddle.Tensor + +.. py:function:: direct_sum(A,B) + + 计算A和B的直和 + + :param A: :math:`m \times n` 的矩阵 + :type A: Union[np.ndarray, paddle.Tensor] + :param B: :math:`p \times q` 的矩阵 + :type B: Union[np.ndarray, paddle.Tensor] + + :return: A和B的直和,维度为 :math:`(m + p) \times (n + q)` + :rtype: Union[np.ndarray, paddle.Tensor] + .. py:function:: NKron(matrix_A, matrix_B, *args) 计算两个及以上的矩阵的克罗内克乘积 :param matrix_A: 矩阵 - :type num_qubits: Union[np.ndarray, paddle.Tensor] + :type matrix_A: Union[np.ndarray, paddle.Tensor] :param matrix_B: 矩阵 :type matrix_B: Union[np.ndarray, paddle.Tensor] :param \*args: 更多矩阵 :type \*args: Union[np.ndarray, paddle.Tensor] + + .. code-block:: python + + from paddle_quantum.linalg import density_op_random, NKron + A = density_op_random(2) + B = density_op_random(2) + C = density_op_random(2) + result = NKron(A, B, C) + + .. note:: + 上述代码块的 ``result`` 应为 :math:`A \otimes B \otimes C` :return: 克罗内克乘积 :rtype: Union[np.ndarray, paddle.Tensor] + +.. py:function:: herm_transform(fcn, mat, ignore_zero) + + 厄密矩阵的函数变换 + + :param fcn: 可以展开成泰勒级数的函数 `f` + :type fcn: Callable[[float], float] + :param mat: 厄密矩阵 :math:`H` + :type mat: Union[paddle.Tensor, np.ndarray, State] + :param ignore_zero: 是否忽略特征值0所在的特征空间,默认为 ``False`` + :type ignore_zero: bool, optional + + :return: :math:`f(H)` + :rtype: paddle.Tensor \ No newline at end of file diff --git a/docs_zh_CN/source/paddle_quantum.qinfo.rst b/docs_zh_CN/source/paddle_quantum.qinfo.rst index b6af6c8..e5c8715 100644 --- a/docs_zh_CN/source/paddle_quantum.qinfo.rst +++ b/docs_zh_CN/source/paddle_quantum.qinfo.rst @@ -8,7 +8,7 @@ paddle\_quantum.qinfo 计算量子态的偏迹。 :param state: 输入的量子态。 - :type state: Union[paddle_quantum.State, paddle.Tensor] + :type state: Union[np.ndarray, paddle.Tensor, State] :param dim1: 系统A的维数。 :type dim1: int :param dim2: 系统B的维数。 @@ -17,19 +17,19 @@ paddle\_quantum.qinfo :type A_or_B: int :return: 输入的量子态的偏迹。 - :rtype: paddle.Tensor + :rtype: Union[np.ndarray, paddle.Tensor, State] .. py:function:: partial_trace_discontiguous(state, preserve_qubits=None) 计算量子态的偏迹,可选取任意子系统。 :param state: 输入的量子态。 - :type state: Union[paddle_quantum.State, paddle.Tensor] + :type state: Union[np.ndarray, paddle.Tensor, State] :param preserve_qubits: 要保留的量子比特,默认为 None,表示全保留。 :type preserve_qubits: list, optional :return: 所选子系统的量子态偏迹。 - :rtype: paddle.Tensor + :rtype: Union[np.ndarray, paddle.Tensor, State] .. py:function:: trace_distance(rho, sigma) @@ -40,12 +40,12 @@ paddle\_quantum.qinfo D(\rho, \sigma) = 1 / 2 * \text{tr}|\rho-\sigma| :param rho: 量子态的密度矩阵形式。 - :type rho: Union[paddle_quantum.State, paddle.Tensor] + :type rho: Union[np.ndarray, paddle.Tensor, State] :param sigma: 量子态的密度矩阵形式。 - :type sigma: Union[paddle_quantum.State, paddle.Tensor] + :type sigma: Union[np.ndarray, paddle.Tensor, State] :return: 输入的量子态之间的迹距离。 - :rtype: paddle.Tensor + :rtype: Union[np.ndarray, paddle.Tensor] .. py:function:: state_fidelity(rho, sigma) @@ -56,11 +56,11 @@ paddle\_quantum.qinfo F(\rho, \sigma) = \text{tr}(\sqrt{\sqrt{\rho}\sigma\sqrt{\rho}}) :param rho: 量子态的密度矩阵形式。 - :type rho: Union[paddle_quantum.State, paddle.Tensor] + :type rho: Union[np.ndarray, paddle.Tensor, State] :param sigma: 量子态的密度矩阵形式。 - :type sigma: Union[paddle_quantum.State, paddle.Tensor] + :type sigma: Union[np.ndarray, paddle.Tensor, State] :return: 输入的量子态之间的保真度。 - :rtype: paddle.Tensor + :rtype: Union[np.ndarray, paddle.Tensor] .. py:function:: gate_fidelity(U, V) @@ -73,12 +73,12 @@ paddle\_quantum.qinfo :math:`U` 是一个 :math:`2^n\times 2^n` 的 Unitary 矩阵。 :param U: 量子门 :math:`U` 的酉矩阵形式 - :type U: paddle.Tensor + :type U: Union[np.ndarray, paddle.Tensor] :param V: 量子门 :math:`V` 的酉矩阵形式 - :type V: paddle.Tensor + :type V: Union[np.ndarray, paddle.Tensor] :return: 输入的量子门之间的保真度 - :rtype: paddle.Tensor + :rtype: Union[np.ndarray, paddle.Tensor] .. py:function:: purity(rho) @@ -89,12 +89,12 @@ paddle\_quantum.qinfo P = \text{tr}(\rho^2) :param rho: 量子态的密度矩阵形式。 - :type rho: Union[paddle_quantum.State, paddle.Tensor] + :type rho: Union[np.ndarray, paddle.Tensor, State] :return: 输入的量子态的纯度。 - :rtype: paddle.Tensor + :rtype: Union[np.ndarray, paddle.Tensor] -.. py:function:: von_neumann_entropy(rho) +.. py:function:: von_neumann_entropy(rho, base) 计算量子态的冯诺依曼熵。 @@ -103,12 +103,14 @@ paddle\_quantum.qinfo S = -\text{tr}(\rho \log(\rho)) :param rho: 量子态的密度矩阵形式。 - :type rho: Union[paddle_quantum.State, paddle.Tensor] + :type rho: Union[np.ndarray, paddle.Tensor, State] + :param base: 对数的底。默认为2。 + :type base: int, optional :return: 输入的量子态的冯诺依曼熵。 - :rtype: paddle.Tensor + :rtype: Union[np.ndarray, paddle.Tensor] -.. py:function:: relative_entropy(rho, sig) +.. py:function:: relative_entropy(rho, sig, base) 计算两个量子态的相对熵。 @@ -117,12 +119,14 @@ paddle\_quantum.qinfo S(\rho \| \sigma)=\text{tr} \rho(\log \rho-\log \sigma) :param rho: 量子态的密度矩阵形式 - :type rho: Union[paddle_quantum.State, paddle.Tensor] + :type rho: Union[np.ndarray, paddle.Tensor, State] :param sig: 量子态的密度矩阵形式 - :type sig: Union[paddle_quantum.State, paddle.Tensor] + :type sig: Union[np.ndarray, paddle.Tensor, State] + :param base: 对数的底。默认为2. + :type base: int, optional :return: 输入的量子态之间的相对熵 - :rtype: paddle.Tensor + :rtype: Union[np.ndarray, paddle.Tensor] .. py:function:: random_pauli_str_generator(n, terms=3) @@ -163,51 +167,51 @@ paddle\_quantum.qinfo 计算输入量子态的 partial transpose :math:`\rho^{T_A}`。 :param density_op: 量子态的密度矩阵形式。 - :type density_op: Union[paddle_quantum.State, paddle.Tensor] + :type density_op: Union[np.ndarray, paddle.Tensor, State] :param sub_system: 1或2,表示关于哪个子系统进行 partial transpose,默认为第二个。 :type sub_system: int, optional :return: 输入的量子态的 partial transpose - :rtype: paddle.Tensor + :rtype: Union[np.ndarray, paddle.Tensor] .. py:function:: partial_transpose(density_op, n) 计算输入量子态的 partial transpose :math:`\rho^{T_A}`。 :param density_op: 量子态的密度矩阵形式。 - :type density_op: Union[paddle_quantum.State, paddle.Tensor] + :type density_op: Union[np.ndarray, paddle.Tensor, State] :param n: 需要转置系统的量子比特数量。 :type n: int :return: 输入的量子态的 partial transpose。 - :rtype: paddle.Tensor + :rtype: Union[np.ndarray, paddle.Tensor] .. py:function:: negativity(density_op) 计算输入量子态的 Negativity :math:`N = ||\frac{\rho^{T_A}-1}{2}||`。 :param density_op: 量子态的密度矩阵形式。 - :type density_op: Union[paddle_quantum.State, paddle.Tensor] + :type density_op: Union[np.ndarray, paddle.Tensor, State] :return: 输入的量子态的 Negativity。 - :rtype: paddle.Tensor + :rtype: Union[np.ndarray, paddle.Tensor] .. py:function:: logarithmic_negativity(density_op) 计算输入量子态的 Logarithmic Negativity :math:`E_N = ||\rho^{T_A}||`。 :param density_op: 量子态的密度矩阵形式。 - :type density_op: Union[paddle_quantum.State, paddle.Tensor] + :type density_op: Union[np.ndarray, paddle.Tensor, State] :return: 输入的量子态的 Logarithmic Negativity。 - :rtype: paddle.Tensor + :rtype: Union[np.ndarray, paddle.Tensor] .. py:function:: is_ppt(density_op) 计算输入量子态是否满足 PPT 条件。 :param density_op: 量子态的密度矩阵形式。 - :type density_op: Union[paddle_quantum.State, paddle.Tensor] + :type density_op: Union[np.ndarray, paddle.Tensor, State] :return: 输入的量子态是否满足 PPT 条件。 :rtype: bool @@ -217,7 +221,7 @@ paddle\_quantum.qinfo 计算输入量子态的施密特分解 :math:`\lvert\psi\rangle=\sum_ic_i\lvert i_A\rangle\otimes\lvert i_B \rangle`。 :param psi: 量子态的向量形式,形状为(2**n)。 - :type psi: Union[paddle_quantum.State, paddle.Tensor] + :type psi: Union[np.ndarray, paddle.Tensor, State] :param sys_A: 包含在子系统 A 中的 qubit 下标(其余 qubit 包含在子系统B中),默认为量子态 :math:`\lvert \psi\rangle` 的前半数 qubit。 :type sys_A: List[int], optional @@ -228,7 +232,7 @@ paddle\_quantum.qinfo - 由子系统A的基 :math:`\lvert i_A\rangle` 组成的高维数组,形状为 ``(k, 2**m, 1)``。 - 由子系统B的基 :math:`\lvert i_B\rangle` 组成的高维数组,形状为 ``(k, 2**l, 1)``。 - :rtype: Tuple[paddle.Tensor] + :rtype: Union[Tuple[paddle.Tensor, paddle.Tensor, paddle.Tensor], Tuple[np.ndarray, np.ndarray, np.ndarray]] .. py:function:: image_to_density_matrix(image_filepath) @@ -258,22 +262,74 @@ paddle\_quantum.qinfo :return: 估计可观测量 :math:`H` 的期望值。 :rtype: float -.. py:function:: tensor_product(state_a, state_b, *args) +.. py:function:: tensor_state(state_a, state_b, *args) 计算输入的量子态(至少两个)的直积形式, 输出将自动返回 State 实例 :param state_a: 量子态A - :type state_a: Union[State, paddle.Tensor] + :type state_a: State :param state_b: 量子态B - :type state_b: Union[State, paddle.Tensor] + :type state_b: State :param args: 其他量子态 - :type args: Union[State, paddle.Tensor] - - :raises NotImplementedError: 当前只接收输入类型为 State 或 paddle.Tensor + :type args: State .. note:: - 使用的 backend 必须为 DensityMatrix + 需要注意输入态使用的 backend; + 若输入数据为 ``paddle.Tensor`` 或者 ``numpy.ndarray``,请使用 ``paddle_quantum.linalg.NKron`` 函数处理。 :return: 输入量子态的直积 - :rtype: State \ No newline at end of file + :rtype: State + +.. py:function:: diamond_norm(channel_repr, dim_io, **kwargs) + + 计算输入的菱形范数 + + :param channel_repr: 信道对应的表示, ``ChoiRepr`` 或 ``KrausRepr`` 或 ``StinespringRepr`` 或 ``paddle.Tensor``。 + :type channel_repr: Union[ChoiRepr, KrausRepr, StinespringRepr, paddle.Tensor] + :param dim_io: 输入和输出的维度。 + :type dim_io: Union[int, Tuple[int, int]], optional. + :param kwargs: 使用cvx所需的参数。 + :type kwargs: Any + + :raises RuntimeError: ``channel_repr`` 必须是 ``ChoiRepr`` 或 ``KrausRepr`` 或 ``StinespringRepr`` 或 ``paddle.Tensor``。 + :raises TypeError: "dim_io" 必须是 "int" 或者 "tuple"。 + + :warning: 输入的 ``channel_repr`` 不是choi表示, 已被转换成 ``ChoiRepr``。 + + :return: 返回菱形范数 + :rtype: float + + +.. py:function:: channel_convert(original_channel, target, tol) + 将给定的信道转换成目标形式 + + :param original_channel: 输入信道 + :type original_channel: Union[ChoiRepr, KrausRepr, StinespringRepr] + :param target: 目标形式,应为 ``Choi``, ``Kraus`` 或 ``Stinespring`` + :type target: str + :param tol: 容错误差 + :type tol: float, optional + + :raises ValueError: 不支持的信道表示形式,应为 ``Choi``, ``Kraus`` 或 ``Stinespring``. + + .. note:: + + choi变为kraus目前因为eigh的精度会存在1e-6的误差 + + :raises NotImplementedError: 不支持输入数据类型的信道转换 + + :return: 返回目标形式的信道 + :rtype: Union[ChoiRepr, KrausRepr, StinespringRepr] + +.. py:function:: kraus_oper_random(num_qubits: int, num_oper: int) + + 随机输出一组描述量子信道的Kraus算符 + + :param num_qubits: 信道对应的量子比特数量 + :type num_qubits: int + :param num_oper: Kraus算符的数量 + :type num_oper: int + + :return: 一组Kraus算符 + :rtype: list \ No newline at end of file diff --git a/docs_zh_CN/source/paddle_quantum.qml.rst b/docs_zh_CN/source/paddle_quantum.qml.rst new file mode 100644 index 0000000..57ad53f --- /dev/null +++ b/docs_zh_CN/source/paddle_quantum.qml.rst @@ -0,0 +1,11 @@ +paddle\_quantum.qml +============================= + +量子机器学习模块。 + +.. rubric:: Submodules + +.. toctree:: + :maxdepth: 4 + + paddle_quantum.qml.vsql diff --git a/docs_zh_CN/source/paddle_quantum.qml.vsql.rst b/docs_zh_CN/source/paddle_quantum.qml.vsql.rst new file mode 100644 index 0000000..fcb22bb --- /dev/null +++ b/docs_zh_CN/source/paddle_quantum.qml.vsql.rst @@ -0,0 +1,93 @@ +paddle\_quantum.qml.vsql +============================================== +VSQL 模型。 + +.. py:function:: norm_image(images, num_qubits) + + 对输入的图片进行归一化。先将图片展开为向量,再进行归一化。 + + :param images: 输入的图片。 + :type images: List[np.ndarray] + :param num_qubits: 量子比特的数量,决定了归一化向量的维度。 + :type num_qubits: int + + :return: 返回归一化之后的向量,它是由 ``paddle.Tensor`` 组成的列表。 + :rtype: List[paddle.Tensor] + +.. py:function:: data_loading(num_qubits, mode, classes, num_data) + + 加载 MNIST 数据集,其中只包含指定的数据。 + + :param num_qubits: 量子比特的数量,决定了归一化向量的维度。 + :type num_qubits: int + :param mode: 指定要加载的数据集,为 ``'train'`` 或 ``'test'`` 。 + + - ``'train'`` :表示加载训练集。 + - ``'test'`` :表示加载测试集。 + + :type mode: str + :param classes: 要加载的数据的标签。对应标签的数据会被加载。 + :type classes: list + :param num_data: 要加载的数据的数量。默认为 ``None`` ,加载所有数据。 + :type num_data: Optional[int] + + :return: 返回加载的数据集,其组成为 ``(images, labels)`` 。 + :rtype: Tuple[List[np.ndarray], List[int]] + +.. py:function:: observable(start_idx, num_shadow) + + 生成测量量子态所需要的哈密顿量。 + + :param start_idx: 要测量的量子比特的起始索引。 + :type start_idx: int + :param num_shadow: 影子电路所包含的量子比特的数量。 + :type num_shadow: int + + :return: 返回生成的哈密顿量。 + :rtype: paddle_quantum.Hamiltonian + +.. py:class:: VSQL(num_qubits, num_shadow, num_classes, depth) + + 基类::py:class:`paddle.nn.Layer` + + 变分影子量子学习(variational shadow quantum learning, VSQL)模型的实现。具体细节可以参考:https://ojs.aaai.org/index.php/AAAI/article/view/17016 。 + + :param num_qubits: 量子电路所包含的量子比特的数量。 + :type num_qubits: int + :param num_shadow: 影子电路所包含的量子比特的数量。 + :type num_shadow: int + :param num_classes: 模型所要分类的类别的数量。 + :type num_classes: int + :param depth: 量子电路的深度,默认为 ``1`` 。 + :type depth: Optional[int] + + .. py:method:: forward(batch_input) + + :param batch_input: 模型的输入,其形状为 :math:`(\text{batch_size}, 2^{\text{num_qubits}})` 。 + :type batch_input: List[paddle.Tensor] + + :return: 返回模型的输出,其形状为 :math:`(\text{batch_size}, \text{num_classes})` 。 + :rtype: paddle.Tensor + +.. py:function:: train(num_qubits, num_shadow, depth, batch_size, epoch, learning_rate, classes, num_train, num_test) + + 训练 VSQL 模型。 + + :param num_qubits: 量子电路所包含的量子比特的数量。 + :type num_qubits: int + :param num_shadow: 影子电路所包含的量子比特的数量。 + :type num_shadow: int + :param depth: 量子电路的深度,默认为 ``1`` 。 + :type depth: Optional[int] + :param batch_size: 数据的批大小,默认为 ``16`` 。 + :type batch_size: Optional[int] + :param epoch: 训练的轮数,默认为 ``10`` 。 + :type epoch: Optional[int] + :param learning_rate: 更新参数的学习率,默认为 ``0.01`` 。 + :type learning_rate: Optional[float] + :param classes: 要预测的手写数字的类别。默认为 ``None`` ,即预测所有的类别。 + :type classes: Optional[list] + :param num_train: 训练集的数据量。默认为 ``None`` ,即使用所有的训练数据。 + :type num_train: Optional[int] + :param num_test: 测试集的数据量。默认为 ``None`` ,即使用所有的训练数据。 + :type num_test: Optional[int] diff --git a/docs_zh_CN/source/paddle_quantum.qpp.angles.rst b/docs_zh_CN/source/paddle_quantum.qpp.angles.rst new file mode 100644 index 0000000..3cfc413 --- /dev/null +++ b/docs_zh_CN/source/paddle_quantum.qpp.angles.rst @@ -0,0 +1,93 @@ +paddle\_quantum.qpp.angles +=============================== + +量子相位处理相关工具函数包 + +.. py:function:: qpp_angle_finder(P, Q) + + 对一个劳伦对 ``P``, ``Q``,找到相应的角度集合 + + :param P: 一个劳伦多项式 + :type P: Laurent + :param Q: 一个劳伦多项式 + :type Q: Laurent + + :return: + 包含如下元素: + + -list_theta: :math:`R_Y` 门对应的角度 + -list_phi: :math:`R_Z` 门对应的角度 + :rtype: Tuple[List[float], List[float]] + +.. py:function:: qpp_angle_approximator(P, Q) + + 对一个劳伦对 ``P``, ``Q``,估计相应的角度集合 + + :param P: 一个劳伦多项式 + :type P: Laurent + :param Q: 一个劳伦多项式 + :type Q: Laurent + + :return: + 包含如下元素: + + -list_theta: :math:`R_Y` 门对应的角度 + -list_phi: :math:`R_Z` 门对应的角度 + :rtype: Tuple[List[float], List[float]] + + .. note:: + 与 `yzzyz_angle_finder` 不同的是, `yzzyz_angle_approximator` 假定唯一的误差来源是精度误差(而这一般来讲是不正确的)。 + +.. py:function:: update_angle(coef) + + 通过 `coef` 从 ``P`` 和 ``Q`` 中计算角度 + + :param coef: ``P`` 和 ``Q`` 中的第一项和最后一项 + :type coef: List[complex] + + :return: 角度 `theta` 和 `phi` + :rtype: Tuple[float, float] + + :raises ValueError: 参数错误:检查这四个参数{[p_d, p_nd, q_d, q_nd]} + +.. py:function:: update_polynomial(P, Q, theta, phi, verify) + + 通过 `theta` , `phi` 更新 ``P`` , ``Q`` + + :param P: 一个劳伦多项式 + :type P: Laurent + :param Q: 一个劳伦多项式 + :type Q: Laurent + :param theta: 一个参数 + :type theta: float + :param phi: 一个参数 + :type phi: float + :param verify: 验证计算是否正确,默认值为True + :type verify: Optional[bool] = True + + :return: 更新后的 ``P``, ``Q`` + :rtype: Tuple[List[float], List[float]] + +.. py:function:: condition_test(P, Q) + + 检查 ``P``, ``Q`` 是否满足: + - deg(`P`) = deg(`Q`) + - ``P``, ``Q`` 是否具有相同宇称 + - :math:`PP^* + QQ^* = 1` + + :param P: 一个劳伦多项式 + :type P: Laurent + :param Q: 一个劳伦多项式 + :type Q: Laurent + + :raises ValueError: PP* + QQ* != 1: 检查你的代码 + +.. py:function:: yz_decomposition(U) + + 返回U的yz分解 + + :param U: 单比特幺正变换 + :type U: np.ndarray + + :return: `alpha`, `theta`, `phi` 使得 :math:`U[0, 0] = \alpha R_Y(\theta) R_Z(\phi) [0, 0]` + :rtype: Tuple[complex, float, float] \ No newline at end of file diff --git a/docs_zh_CN/source/paddle_quantum.qpp.laurent.rst b/docs_zh_CN/source/paddle_quantum.qpp.laurent.rst new file mode 100644 index 0000000..3db86c7 --- /dev/null +++ b/docs_zh_CN/source/paddle_quantum.qpp.laurent.rst @@ -0,0 +1,282 @@ +paddle\_quantum.qpp.laurent +=============================== + +劳伦类的定义和它的函数 + +.. py:class:: Laurent + + 基类: :py:class:`object` + + 为劳伦多项式定义的类,定义为 :math:`P:\mathbb{C}[X, X^{-1}] \to \mathbb{C} :x \mapsto \sum_{j = -L}^{L} p_j X^j` + + :param coef: 劳伦多项式系数的列表,排列为 :math:`\{p_{-L}, ..., p_{-1}, p_0, p_1, ..., p_L\}` + :type coef: np.ndarray + + .. py:method:: __call__(X) + + 计算P(X)的值 + :param X: 输入X + :type X: Union[int, float, complex] + + :return: P(X) + :rtype: complex + + .. py:property:: coef() + + 以上升顺序给出多项式的系数序列 + + .. py:property:: conj() + + 给出多项式的共轭 + + .. py:property:: roots() + + 给出多项式根的列表 + + .. py:property:: norm() + + 给出多项式系数的绝对值平方之和 + + .. py:property:: max_norm() + + 给出多项式的系数的绝对值的最大值 + + .. py:property:: parity() + + 给出多项式的宇称 + + .. py:method:: __copy__() + + 复制劳伦多项式 + + :return: 复制后的多项式 + :rtype: Laurent + + .. py:method:: __add__(other) + + 劳伦多项式的相加 + + :param other: 一个标量或一个劳伦多项式 :math:`Q(x) = \sum_{j = -L}^{L} q_{j} X^j` + :type other: Any + + :raises TypeError: 不支持劳伦多项式和others的相加 + + .. py:method:: __mul__(other) + + 劳伦多项式的相乘 + + :param other: 一个标量或一个劳伦多项式 :math:`Q(x) = \sum_{j = -L}^{L} q_{j} X^j` + :type other: Any + + :raises TypeError: 不支持劳伦多项式和others的相乘 + + .. py:method:: __sub__(other) + + 劳伦多项式的相减 + + :param other: 一个标量或一个劳伦多项式 :math:`Q(x) = \sum_{j = -L}^{L} q_{j} X^j` + :type other: Any + + .. py:method:: __eq__(other) + + 劳伦多项式的相等 + + :param other: 一个标量或一个劳伦多项式 :math:`Q(x) = \sum_{j = -L}^{L} q_{j} X^j` + :type other: Any + + :raises TypeError: 不支持劳伦多项式和 ``others`` 的相等 + + .. py:method:: __str__() + + 打印劳伦多项式 + + .. py:method:: is_parity(p) + + 检验劳伦多项式是否有确定宇称 + + :param p: 宇称 + :type p: int + + :return: + 包含以下元素: + + -宇称是否是 ``p mod 2`` + -如果不是,返回破坏该宇称的绝对值最大的系数 + -如果不是,返回破坏该宇称的绝对值最小的系数 + :rtype: Tuple[bool, complex] + +.. py:function:: revise_tol(t) + + 回顾 ``TOL`` 的值 + + :param t: TOL的值 + :type t: float + +.. py:function:: ascending_coef(coef) + + 通过 ``coef`` 从 ``P`` 和 ``Q`` 中计算角度 + + :param coef: 排列成 :math:`\{ p_0, ..., p_L, p_{-L}, ..., p_{-1} \}` 的系数列表 + :type coef: np.ndarray + + :return: 排列成 :math:`\{ p_{-L}, ..., p_{-1}, p_0, p_1, ..., p_L \}` 的系数列表 + :rtype: np.ndarray + +.. py:function:: remove_abs_error(data, tol) + + 移除数据中的错误 + + :param data: 数据数组 + :type data: np.ndarray + :param tol: 容错率 + :type tol: Optional[float] = None + + :return: 除错后的数据 + :rtype: np.ndarray + +.. py:function:: random_laurent_poly(deg, parity, is_real) + + 随机生成一个劳伦多项式 + + :param deg: 该多项式的度数 + :type deg: int + :param parity: 该多项式的宇称,默认为 ``none`` + :type parity: Optional[int] = None + :param is_real: 该多项式系数是否是实数,默认为 ``false`` + :type is_real: Optional[bool] = False + + :return: 一个模小于等于1的劳伦多项式 + :rtype: Laurent + +.. py:function:: sqrt_generation(A) + + 生成劳伦多项式 :math:`A` 的平方根 + + :param A: 一个劳伦多项式 + :type A: Laurent + + :return: 一个模小于等于1的劳伦多项式 + :rtype: Laurent + +.. py:function:: Q_generation(P) + + 生成劳伦多项式 :math:`P` 的互补多项式 + + :param P: 一个宇称为 :math:`deg` ,度数为 :math:`L` 的劳伦多项式 + :type P: Laurent + + :return: 一个宇称为 :math:`deg` ,度数为 :math:`L` 的劳伦多项式 :math:`Q` ,使得 :math:`PP^* + QQ^* = 1` + :rtype: Laurent + +.. py:function:: pair_generation(f) + + 生成劳伦多项式 :math:`f` 的劳伦对 + + :param f: 一个实的,偶次的,max_norm小于1的劳伦多项式 + :type f: Laurent + + :return: 劳伦多项式 :math:`P, Q` 使得 :math:`P = \sqrt{1 + f / 2}, Q = \sqrt{1 - f / 2}` + :rtype: Laurent + +.. py:function:: laurent_generator(fn, dx, deg, L) + + 生成劳伦多项式 :math:`f` 的劳伦对 + + :param fn: 要近似的函数 + :type fn: Callable[[np.ndarray], np.ndarray] + :param dx: 数据点的采样频率 + :type dx: float + :param deg: 劳伦多项式的度数 + :type deg: int + :param L: 近似宽度的一半 + :type L: float + + :return: 一个度数为 ``deg`` 的,在区间 :math:`[-L, L]` 内近似`fn` 的劳伦多项式 + :rtype: Laurent + +.. py:function:: deg_finder(fn, delta, l) + + 找到一个度数,使得由 ``laurent_generator`` 生成的劳伦多项式具有小于1的max_norm + + :param fn: 要近似的函数 + :type fn: Callable[[np.ndarray], np.ndarray] + :param delta: 数据点的采样频率,默认值为 :math:`0.00001 \pi` + :type delta: Optional[float] = 0.00001 * np.pi + :param l: 近似宽度的一半,默认值为 :math:`\pi` + :type l: Optional[float] = np.pi + + :return: 该近似的度数 + :rtype: int + +.. py:function:: step_laurent(deg) + + 生成一个近似阶梯函数的劳伦多项式 + + :param deg: 输出劳伦多项式的度数(为偶数) + :type deg: int + + :return: 一个估计 :math:`f(x) = 0.5` if :math:`x <= 0` else :math:`0` 的劳伦多项式 + :rtype: Laurent + + .. note:: + 在哈密顿量能量计算器中使用 + +.. py:function:: hamiltonian_laurent(t, deg) + + 生成一个近似哈密顿量演化函数的劳伦多项式 + + :param t: 演化常数(时间) + :type t: float + :param deg: 输出劳伦多项式的度数(为偶数) + :type deg: int + + :return: 一个估计 :math:`e^{it \cos(x)}` 的劳伦多项式 + :rtype: Laurent + + .. note:: + -起源于Jacobi-Anger展开: :math:`y(x) = \sum_n i^n Bessel(n, x) e^{inx}` + -在哈密顿量模拟中使用 + +.. py:function:: ln_laurent(deg, t) + + 生成一个近似ln函数的劳伦多项式 + + :param deg: 劳伦多项式的度数(是4的因子) + :type deg: int + :param t: 归一化常数 + :type t: float + + + :return: 一个估计 :math:`ln(cos(x)^2) / t` 的劳伦多项式 + :rtype: Laurent + + .. note:: + 在冯诺依曼熵的估计中使用。 + +.. py:function:: comb(n, k) + + 计算nCr(n, k) + + :param n: 输入参数 + :type n: float + :param k: 输入参数 + :type k: int + + + :return: nCr(n, k) + :rtype: float + +.. py:function:: power_laurent(deg, alpha, t) + + 生成近似幂函数的劳伦多项式 + + :param deg: 劳伦多项式的度数(是4的因子) + :type deg: int + :param alpha: 幂函数的幂次 + :type alpha: int + :param t: 归一化常数 + :type t: float + + + :return: 一个估计 :math:`(cos(x)^2)^{\alpha / 2} / t` 的劳伦多项式 + :rtype: Laurent diff --git a/docs_zh_CN/source/paddle_quantum.qpp.rst b/docs_zh_CN/source/paddle_quantum.qpp.rst new file mode 100644 index 0000000..415afd0 --- /dev/null +++ b/docs_zh_CN/source/paddle_quantum.qpp.rst @@ -0,0 +1,12 @@ +paddle\_quantum.qpp +============================ +量子相位处理模块 + +.. rubric:: Submodules + +.. toctree:: + :maxdepth: 4 + + paddle_quantum.qpp.angles + paddle_quantum.qpp.laurent + paddle_quantum.qpp.utils \ No newline at end of file diff --git a/docs_zh_CN/source/paddle_quantum.qpp.utils.rst b/docs_zh_CN/source/paddle_quantum.qpp.utils.rst new file mode 100644 index 0000000..3f36f15 --- /dev/null +++ b/docs_zh_CN/source/paddle_quantum.qpp.utils.rst @@ -0,0 +1,78 @@ +paddle\_quantum.qpp.utils +============================ + +QPP 线路变换和其他相关工具。更多细节参考论文 https://arxiv.org/abs/2209.14278 中的 Theorem 6。 + +.. py:function:: qpp_cir(list_theta, list_phi, U) -> Circuit + + 根据 ``list_theta`` 和 ``list_phi`` 创建量子相位处理器 + + :param list_theta: :math:`R_Y` 门角度输入。 + :type list_theta: Union[np.ndarray, paddle.Tensor] + :param list_phi: :math:`R_Z` 门角度输入。 + :type list_phi: Union[np.ndarray, paddle.Tensor] + :param U: 酉矩阵或标量输入。 + :type U: Union[np.ndarray, paddle.Tensor, float] + + :return: 三角 QSP 的多比特一般化线路。 + :rtype: Circuit + +.. py:function:: simulation_cir(fn, U, approx=True, deg=50, length=np.pi, step_size=0.00001*np.pi, tol=1e-30) + + 返回一个模拟 ``fn`` 的 QPP 线路,见论文 https://arxiv.org/abs/2209.14278 中的 Theorem 6。 + + :param fn: 要模拟的函数。 + :type fn: Callable[[np.ndarray], np.ndarray] + :param U: 酉矩阵。 + :type U: Union[np.ndarray, paddle.Tensor, float] + :param approx: 是否估算线路角度。默认为 ``True``。 + :type approx: : Optional[bool] + :param deg: 模拟的级数。默认为 ``50``。 + :type deg: : Optional[int] + :param length: 模拟宽度的一半。默认为 :math:`\pi`。 + :type length: Optional[float] + :param step_size: 采样点的频率。默认为 :math:`0.00001 \pi`。 + :type step_size: Optional[float] + :param tol: 误差容忍度。默认为 :math:`10^{-30}`,即机械误差。 + :type tol: Optional[float] + + :return: 模拟 ``fn`` 的 QPP 线路。 + :rtype: Circuit + +.. py:function:: qps(U, initial_state) + + 量子相位搜索算法,见论文 https://arxiv.org/abs/2209.14278 中的算法 1 和 2 + + :param U: 目标酉矩阵。 + :type U: Union[np.ndarray, paddle.Tensor] + :param initial_state: 输入量子态。 + :type initial_state: Union[np.ndarray, paddle.Tensor, State] + + :return: 包含如下元素的 tuple: + - 一个 ``U`` 的本征相位; + - 其相位对应的,存在和 ``initial_state`` 内积不为零的本征态。 + :rtype: Tuple[float, State] + +.. py:function:: qubitize(block_enc, num_block_qubits) + + 使用一个额外辅助比特来比特化块编码,来保证子空间不变。更多细节见论文 http://arxiv.org/abs/1610.06546。 + + :param block_enc: 目标块编码。 + :type block_enc: Union[np.ndarray, paddle.Tensor] + :param num_block_qubits: 块编码自身所使用的辅助比特数。 + :type num_block_qubits: int + + :return: 比特化的 ``block_enc`` + :rtype: paddle.Tensor + +.. py:function:: purification_block_enc(num_qubits, num_block_qubits): + + 随机生成一个 :math:`n`-比特密度矩阵的 :math:`(n + m)`-比特的比特化块编码。 + + :param num_qubits: 量子态比特数 :math:`n`。 + :type num_qubits: int + :param num_block_qubits: 块编码的辅助比特数 :math:`m > n`。 + :type num_block_qubits: int + + :return: 一个 :math:`2^{n + m} \times 2^{n + m}` 的左上角为密度矩阵的酉矩阵 + :rtype: paddle.Tensor diff --git a/docs_zh_CN/source/paddle_quantum.qsvt.qsp_utils.rst b/docs_zh_CN/source/paddle_quantum.qsvt.qsp_utils.rst index 7f7e241..594cd51 100644 --- a/docs_zh_CN/source/paddle_quantum.qsvt.qsp_utils.rst +++ b/docs_zh_CN/source/paddle_quantum.qsvt.qsp_utils.rst @@ -10,7 +10,7 @@ paddle\_quantum.qsvt.qsp\_utils :param degree: 多项式的度 :type degree: int :param odd: 多项式的奇偶性,输入 `True` 则为奇函数, `False` 则为偶函数 - :type odd: bool + :type od: bool :return: 一个随机生成的多项式 :rtype: Polynomial diff --git a/docs_zh_CN/source/paddle_quantum.state.state.rst b/docs_zh_CN/source/paddle_quantum.state.state.rst index 7633a79..7403a75 100644 --- a/docs_zh_CN/source/paddle_quantum.state.state.rst +++ b/docs_zh_CN/source/paddle_quantum.state.state.rst @@ -17,8 +17,7 @@ paddle\_quantum.state.state :type backend: paddle_quantum.Backend, optional :param dtype: 量子态的数据类型。默认为 None,使用全局的默认数据类型。 :type dtype: str, optional - :raises Exception: 所输入的量子态维度不正确。 - :raises NotImplementedError: 所指定的后端必须为量桨已经实现的后端。 + :raises ValueError: 无法识别后端 .. py:property:: ket() @@ -29,6 +28,56 @@ paddle\_quantum.state.state 得到量子态的行向量形式。 + .. py:method:: normalize() + + 得到归一化后量子态 + + :raises NotImplementedError: 当前后端不支持归一化 + + .. py:method:: evolve(H,t) + + 得到经过给定哈密顿量演化后的量子态 + + :param H: 系统哈密顿量 + :type H: Union[np.ndarray, paddle.Tensor, Hamiltonian] + :param t: 演化时间 + :type t: float + :raises NotImplementedError: 当前后端不支持量子态演化 + + .. py:method:: kron(other) + + 得到与给定量子态之间的张量积 + + :param other: 给定量子态 + :type other: State + + :return: 返回张量积 + :rtype: State + + .. py:method:: __matmul__(other) + + 得到与量子态或张量之间的乘积 + + :param other: 给定量子态 + :type other: State + :raises NotImplementedError: 不支持与该量子态进行乘积计算 + :raises ValueError: 无法对两个态向量相乘,请检查使用的后端 + + :return: 返回量子态的乘积 + :rtype: paddle.Tensor + + .. py:method:: __rmatmul__(other) + + 得到与量子态或张量之间的乘积 + + :param other: 给定量子态 + :type other: State + :raises NotImplementedError: 不支持与该量子态进行乘积计算 + :raises ValueError: 无法对两个态向量相乘,请检查使用的后端 + + :return: 返回量子态的乘积 + :rtype: paddle.Tensor + .. py:method:: numpy() 得到量子态的数据的 numpy 形式。 @@ -48,8 +97,8 @@ paddle\_quantum.state.state :type device: str :param blocking: 如果为 False 并且当前 Tensor 处于固定内存上,将会发生主机到设备端的异步拷贝。否则会发生同步拷贝。如果为 None,blocking 会被设置为 True,默认 为False。 :type blocking: str - :return: 返回 NotImplementedError,该函数会在后续实现。 - :rtype: Error + :raises NotImplementedError: 仅支持在态向量与密度矩阵之间进行转换 + :raises NotImplementedError: 不支持在该设备或blocking上进行转换 .. py:method:: clone() @@ -86,3 +135,79 @@ paddle\_quantum.state.state :raises NotImplementedError: 输入的量子比特下标有误。 :return: 测量结果。 :rtype: dict + +.. py:function:: _type_fetch(data) + + 获取数据的类型 + + :param data: 输入数据 + :type data: Union[np.ndarray, paddle.Tensor, State] + + :raises ValueError: 输入量子态不支持所选后端 + :raises TypeError: 无法识别输入量子态的数据类型 + + :return: 返回输入量子态的数据类型 + :rtype: str + +.. py:function:: _density_to_vector(rho) + + 将密度矩阵转换为态向量 + + :param rho: 输入的密度矩阵 + :type rho: Union[np.ndarray, paddle.Tensor] + + :raises ValueError: 输出量子态可能不为纯态 + + :return: 返回态向量 + :rtype: Union[np.ndarray, paddle.Tensor] + +.. py:function:: _type_transform(data, output_type) + + 将输入量子态转换成目标类型 + + :param data: 需要转换的数据 + :type data: Union[np.ndarray, paddle.Tensor, State] + :param output_type: 目标数据类型 + :type output_type: str + + :raises ValueError: 输入态不支持转换为目标数据类型 + + :return: 返回目标数据类型的量子态 + :rtype: Union[np.ndarray, paddle.Tensor, State] + +.. py:function:: is_state_vector(vec, eps) + + 检查输入态是否为量子态向量 + + :param vec: 输入的数据 :math:`x` + :type vec: Union[np.ndarray, paddle.Tensor] + :param eps: 容错率 + :type eps: float, optional + + :return: 返回是否满足 :math:`x^\dagger x = 1` ,以及量子比特数目或错误信息 + :rtype: Tuple[bool, int] + + .. note:: + 错误信息为: + * ``-1`` 如果上述公式不成立 + * ``-2`` 如果输入数据维度不为2的幂 + * ``-3`` 如果输入数据不为向量 + +.. py:function:: is_density_matrix(rho, eps) + + 检查输入数据是否为量子态的密度矩阵 + + :param rho: 输入的数据 ``rho`` + :type rho: Union[np.ndarray, paddle.Tensor] + :param eps: 容错率 + :type eps: float, optional + + :return: 返回输入数据 ``rho`` 是否为迹为1的PSD矩阵,以及量子比特数目或错误信息 + :rtype: Tuple[bool, int] + + .. note:: + 错误信息为: + * ``-1`` 如果 ``rho`` 不为PSD矩阵 + * ``-2`` 如果 ``rho`` 的迹不为1 + * ``-3`` 如果 ``rho`` 的维度不为2的幂 + * ``-4`` 如果 ``rho`` 不为一个方阵 diff --git a/introduction/PaddleQuantum_QuLeaf_CN.ipynb b/introduction/PaddleQuantum_QuLeaf_CN.ipynb index cf308e6..7550a48 100644 --- a/introduction/PaddleQuantum_QuLeaf_CN.ipynb +++ b/introduction/PaddleQuantum_QuLeaf_CN.ipynb @@ -28,7 +28,13 @@ "source": [ "## 量桨连接量易伏\n", "\n", - "目前量桨已经支持连接量易伏,只需要使用 `paddle_quantum.set_backend('quleaf')` 即可将量桨的后端设置为量易伏。除此之外,我们还需要设置量易伏的模拟方式。如果使用云端算力,则还需要输入 token。因此,完整的设置代码如下:" + "### 环境设置\n", + "\n", + "如果要使用量桨连接量易伏上的真实量子计算机,则需要保证所安装的 qcompute 的版本在 3.0.0 以上,使用 `pip install -U qcompute` 来安装最新版本的 qcompute。\n", + "\n", + "其中,qcompute 对 protobuf 的版本要求是 4.21.1,而飞桨对 protobuf 的版本要求为 3.1.0 到3.20.0。因此,需要通过设置环境变量来使飞桨可以兼容更高版本的 protobuf。\n", + "\n", + "> 因为飞桨对 protobuf 的版本要求为 3.1.0 到3.20.0,所以所有的 Python 程序都需要先设置环境变量才能正常使用量桨。因此,如果不使用量易伏的话,可以通过 `pip install protobuf==3.20.0` 来正常使用量桨而无需额外设置环境变量。" ] }, { @@ -36,6 +42,24 @@ "execution_count": 1, "metadata": {}, "outputs": [], + "source": [ + "# 设置环境变量使飞桨可以兼容更高版本的 protobuf\n", + "import os\n", + "os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "接下来,只需要使用 `paddle_quantum.set_backend('quleaf')` 即可将量桨的后端设置为量易伏。除此之外,我们还需要设置量易伏的模拟方式。如果使用云端算力,则还需要输入 token。因此,完整的设置代码如下:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], "source": [ "import paddle_quantum\n", "from QCompute import BackendName\n", @@ -79,7 +103,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -109,21 +133,21 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "The iter is 0, loss is -0.32104.\n", - "The iter is 10, loss is -0.49239.\n", - "The iter is 20, loss is -0.80956.\n", - "The iter is 30, loss is -1.07812.\n", - "The iter is 40, loss is -1.09850.\n", - "The iter is 50, loss is -1.13334.\n", - "The iter is 60, loss is -1.13445.\n", - "The iter is 70, loss is -1.13492.\n", + "The iter is 0, loss is -0.36935.\n", + "The iter is 10, loss is -0.51383.\n", + "The iter is 20, loss is -0.74604.\n", + "The iter is 30, loss is -1.02815.\n", + "The iter is 40, loss is -1.07233.\n", + "The iter is 50, loss is -1.09937.\n", + "The iter is 60, loss is -1.11564.\n", + "The iter is 70, loss is -1.11459.\n", "The theoretical value is -1.137283834485513.\n" ] } @@ -167,7 +191,7 @@ "loss_func = paddle_quantum.loss.ExpecVal(hamiltonian, shots=10000)\n", "# 进行迭代训练\n", "num_itr = 80\n", - "for itr in range(0, num_itr):\n", + "for itr in range(num_itr):\n", " state = circuit(init_state)\n", " loss = loss_func(state)\n", " loss.backward()\n", @@ -190,7 +214,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.8.0 ('paddle-quantum-dev')", + "display_name": "Python 3.8.0 ('temp')", "language": "python", "name": "python3" }, @@ -209,7 +233,7 @@ "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "9043b12ec77a531919bc05f05830335d23baf822720cbea14b03018197d26545" + "hash": "73730e2524c172926674de584a45f4a289689f765fd1f4813f545a2476542e53" } } }, diff --git a/introduction/PaddleQuantum_QuLeaf_EN.ipynb b/introduction/PaddleQuantum_QuLeaf_EN.ipynb index 78d1b8b..84ef24e 100644 --- a/introduction/PaddleQuantum_QuLeaf_EN.ipynb +++ b/introduction/PaddleQuantum_QuLeaf_EN.ipynb @@ -28,7 +28,13 @@ "source": [ "## Paddle Quantum calls QuLeaf\n", "\n", - "In the paddle quantum, we already support the backend implementation of QuLeaf. Just use `paddle_quantum.set_backend('quleaf')` to set the backend of the quantum paddle to QuLeaf. In addition to that, we need to set the simulation method of the QuLeaf. If we use cloud computation power, we also need to enter the token, so the complete setup code is as follows." + "### Environment settings\n", + "\n", + "If you want to use paddle-quantum to connect to the real quantum computer via QuLeaf, you need to ensure that the installed version of qcompute is above 3.0.0. You can use `pip install -U qcompute` to install the latest version of qcompute.\n", + "\n", + "In particular, qcompute requires protobuf version 4.21.1, while paddlepaddle requires protobuf versions 3.1.0 to 3.20.0. Therefore, you need to set environment variables to make paddlepaddle compatible with higher versions of protobuf.\n", + "\n", + "> Because paddlepaddle requires protobuf versions 3.1.0 through 3.20.0, all your python programs need to set environment variables so that they can import the paddlepaddle successfully. Therefore, if you don't need to use the qcompute, you can use `pip install protobuf==3.20.0` to ley you import the paddlepaddle without setting environment variable." ] }, { @@ -36,6 +42,24 @@ "execution_count": 1, "metadata": {}, "outputs": [], + "source": [ + "# Set the environment variable to make paddlepaddle compatible with the higher version of protobuf\n", + "import os\n", + "os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, just use `paddle_quantum.set_backend('quleaf')` to set the backend of the quantum paddle to QuLeaf. In addition to that, we need to set the simulation method of the QuLeaf. If we use cloud computation power, we also need to enter the token, so the complete setup code is as follows." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], "source": [ "import paddle_quantum\n", "from QCompute import BackendName\n", @@ -79,7 +103,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -109,21 +133,21 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "The iter is 0, loss is 0.15198.\n", - "The iter is 10, loss is -0.76691.\n", - "The iter is 20, loss is -0.91600.\n", - "The iter is 30, loss is -0.97056.\n", - "The iter is 40, loss is -1.05518.\n", - "The iter is 50, loss is -1.13397.\n", - "The iter is 60, loss is -1.12326.\n", - "The iter is 70, loss is -1.13693.\n", + "The iter is 0, loss is -0.02081.\n", + "The iter is 10, loss is -0.54088.\n", + "The iter is 20, loss is -0.83405.\n", + "The iter is 30, loss is -1.01126.\n", + "The iter is 40, loss is -1.10169.\n", + "The iter is 50, loss is -1.10362.\n", + "The iter is 60, loss is -1.11572.\n", + "The iter is 70, loss is -1.11396.\n", "The theoretical value is -1.137283834485513.\n" ] } @@ -167,7 +191,7 @@ "loss_func = paddle_quantum.loss.ExpecVal(hamiltonian, shots=10000)\n", "# iterative training\n", "num_itr = 80\n", - "for itr in range(0, num_itr):\n", + "for itr in range(num_itr):\n", " state = circuit(init_state)\n", " loss = loss_func(state)\n", " loss.backward()\n", @@ -190,7 +214,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.8.0 ('paddle-quantum-dev')", + "display_name": "Python 3.8.0 ('temp')", "language": "python", "name": "python3" }, @@ -209,7 +233,7 @@ "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "9043b12ec77a531919bc05f05830335d23baf822720cbea14b03018197d26545" + "hash": "73730e2524c172926674de584a45f4a289689f765fd1f4813f545a2476542e53" } } }, diff --git a/paddle_quantum/__init__.py b/paddle_quantum/__init__.py index ff87617..342a18a 100644 --- a/paddle_quantum/__init__.py +++ b/paddle_quantum/__init__.py @@ -28,7 +28,6 @@ from . import ansatz from . import channel from . import gate -from . import linalg from . import locc from . import loss from . import mbqc @@ -41,9 +40,10 @@ from . import hamiltonian from . import linalg from . import qinfo +from . import qml from . import shadow from . import trotter from . import visual name = 'paddle_quantum' -__version__ = '2.2.1' +__version__ = '2.2.2' diff --git a/paddle_quantum/ansatz/circuit.py b/paddle_quantum/ansatz/circuit.py index e5a058d..88e2dea 100644 --- a/paddle_quantum/ansatz/circuit.py +++ b/paddle_quantum/ansatz/circuit.py @@ -20,7 +20,7 @@ import warnings import paddle from .container import Sequential -from ..gate import Gate, H, S, T, X, Y, Z, P, RX, RY, RZ, U3 +from ..gate import Gate, H, S, Sdg, T, Tdg, X, Y, Z, P, RX, RY, RZ, U3 from ..gate import CNOT, CX, CY, CZ, SWAP from ..gate import CP, CRX, CRY, CRZ, CU, RXX, RYY, RZZ from ..gate import MS, CSWAP, Toffoli @@ -31,7 +31,7 @@ from ..gate import QAOALayer from ..gate import AmplitudeEncoding from ..channel import BitFlip, PhaseFlip, BitPhaseFlip, AmplitudeDamping, GeneralizedAmplitudeDamping, PhaseDamping -from ..channel import Depolarizing, PauliChannel, ResetChannel, ThermalRelaxation, KrausRepr +from ..channel import Depolarizing, PauliChannel, ResetChannel, ThermalRelaxation, MixedUnitaryChannel, KrausRepr from ..intrinsic import _get_float_dtype from ..state import zero_state from ..operator import Collapse @@ -39,6 +39,9 @@ from paddle_quantum import State, get_backend, get_dtype, Backend from math import pi import numpy as np +import matplotlib +import matplotlib.pyplot as plt +from ..gate.functional.visual import _circuit_plot class Circuit(Sequential): @@ -47,14 +50,14 @@ class Circuit(Sequential): Args: num_qubits: Number of qubits. Defaults to None. """ - + def __init__(self, num_qubits: Optional[int] = None): super().__init__() self.__num_qubits = num_qubits - + # whether the circuit is a dynamic quantum circuit - self.__isdynamic = True if num_qubits is None else False - + self.__isdynamic = num_qubits is None + # alias for ccx self.toffoli = self.ccx @@ -69,20 +72,20 @@ def isdynamic(self) -> bool: r"""Whether the circuit is dynamic """ return self.__dynamic - + @num_qubits.setter def num_qubits(self, value: int) -> None: assert isinstance(value, int) self.__num_qubits = value - - @property + + @property def param(self) -> paddle.Tensor: r"""Flattened parameters in the circuit. """ if len(self.parameters()) == 0: return [] return paddle.concat([paddle.flatten(param) for param in self.parameters()]) - + @property def grad(self) -> np.ndarray: r"""Gradients with respect to the flattened parameters. @@ -93,14 +96,7 @@ def grad(self) -> np.ndarray: ' otherwise check where the gradient chain is broken' grad_list.append(paddle.flatten(param.grad)) return paddle.concat(grad_list).numpy() - - @property - def depth(self) -> int: - r"""(current) Depth of this Circuit - """ - qubit_depth = [len(qubit_gates) for qubit_gates in self.qubit_history] - return max(qubit_depth) - + def update_param(self, theta: Union[paddle.Tensor, np.ndarray, float], idx: int = None) -> None: r"""Replace parameters of all/one layer(s) by ``theta``. @@ -111,14 +107,15 @@ def update_param(self, theta: Union[paddle.Tensor, np.ndarray, float], idx: int if not isinstance(theta, paddle.Tensor): theta = paddle.to_tensor(theta, dtype='float32') theta = paddle.flatten(theta) - + backend_dtype = _get_float_dtype(get_dtype()) if backend_dtype != 'float32': warnings.warn( f"\ndtype of parameters will be float32 instead of {backend_dtype}", UserWarning) - + if idx is None: - assert self.param.shape == theta.shape, "the shape of input parameters is not correct" + assert self.param.shape == theta.shape, \ + f"the shape of input parameters is not correct: expect {self.param.shape}, received {theta.shape}" for layer in self.sublayers(): for name, _ in layer.named_parameters(): param = getattr(layer, name) @@ -135,11 +132,12 @@ def update_param(self, theta: Union[paddle.Tensor, np.ndarray, float], idx: int return theta = theta[num_param:] elif isinstance(idx, int): - assert idx < len(self.sublayers()), "the index is out of range, expect below " + str(len(self.sublayers())) + assert idx < len(self.sublayers()), f"the index is out of range, expect below {len(self.sublayers())}" + layer = self.sublayers()[idx] assert theta.shape == paddle.concat([paddle.flatten(param) for param in layer.parameters()]).shape, \ - "the shape of input parameters is not correct," - + "the shape of input parameters is not correct," + for name, _ in layer.named_parameters(): param = getattr(layer, name) num_param = int(paddle.numel(param)) @@ -156,20 +154,20 @@ def update_param(self, theta: Union[paddle.Tensor, np.ndarray, float], idx: int theta = theta[num_param:] else: raise ValueError("idx must be an integer or None") - + def transfer_static(self) -> None: - r""" set ``stop_gradient`` of all parameters of the circuit as ``True`` - + r""" + set ``stop_gradient`` of all parameters of the circuit as ``True`` """ for layer in self.sublayers(): for name, _ in layer.named_parameters(): param = getattr(layer, name) param.stop_gradient = True setattr(layer, 'theta', param) - + def randomize_param(self, low: float = 0, high: Optional[float] = 2 * pi) -> None: r"""Randomize parameters of the circuit in a range from low to high. - + Args: low: Lower bound. high: Upper bound. @@ -187,7 +185,7 @@ def randomize_param(self, low: float = 0, high: Optional[float] = 2 * pi) -> Non def __num_qubits_update(self, qubits_idx: Union[Iterable[int], int, str]) -> None: r"""Update ``self.num_qubits`` according to ``qubits_idx``, or report error. - + Args: qubits_idx: Input qubit indices of a quantum gate. """ @@ -256,6 +254,30 @@ def s( self.append( S(qubits_idx, self.num_qubits if num_qubits is None else num_qubits, depth)) + def sdg( + self, qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: Optional[int] = None, depth: int = 1 + ) -> None: + r"""Add single-qubit S dagger (S inverse) gates. + + The matrix form of such a gate is: + + .. math:: + + S^\dagger = + \begin{bmatrix} + 1&0\\ + 0&-i + \end{bmatrix} + + Args: + qubits_idx: Indices of the qubits on which the gates are applied. Defaults to ``'full'``. + num_qubits: Total number of qubits. Defaults to ``None``. + depth: Number of layers. Defaults to ``1``. + """ + self.__num_qubits_update(qubits_idx) + self.append( + Sdg(qubits_idx, self.num_qubits if num_qubits is None else num_qubits, depth)) + def t( self, qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: Optional[int] = None, depth: int = 1 ) -> None: @@ -279,6 +301,30 @@ def t( self.append( T(qubits_idx, self.num_qubits if num_qubits is None else num_qubits, depth)) + def tdg( + self, qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: Optional[int] = None, depth: int = 1 + ) -> None: + r"""Add single-qubit T dagger (T inverse) gates. + + The matrix form of such a gate is: + + .. math:: + + T^\dagger = + \begin{bmatrix} + 1&0\\ + 0&e^{-\frac{i\pi}{4}} + \end{bmatrix} + + Args: + qubits_idx: Indices of the qubits on which the gates are applied. Defaults to ``'full'``. + num_qubits: Total number of qubits. Defaults to None. + depth: Number of layers. Defaults to 1. + """ + self.__num_qubits_update(qubits_idx) + self.append( + Tdg(qubits_idx, self.num_qubits if num_qubits is None else num_qubits, depth)) + def x( self, qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: Optional[int] = None, depth: int = 1 ) -> None: @@ -991,7 +1037,8 @@ def universal_three_qubits( def oracle( self, oracle: paddle.tensor, qubits_idx: Union[Iterable[Iterable[int]], Iterable[int], int], - num_qubits: int = None, depth: int = 1, gate_name: str = 'O' + num_qubits: int = None, depth: int = 1, + gate_name: Optional[str] = 'O', latex_name: Optional[str] = None, plot_width: Optional[float] = None ) -> None: """Add an oracle gate. @@ -1000,15 +1047,21 @@ def oracle( qubits_idx: Indices of the qubits on which the gates are applied. num_qubits: Total number of qubits. Defaults to None. depth: Number of layers. Defaults to 1. - gate_name: name of this oracle + gate_name: name of this oracle. + latex_name: latex name of this oracle, default to be the gate name. + plot_width: width of this gate in circuit plot, default to be proportional with the gate name. """ self.__num_qubits_update(qubits_idx) + gate_info = {'gatename': gate_name, + 'texname': f"${gate_name}$" if latex_name is None else latex_name, + 'plot_width': 0.6 * len(gate_name) if plot_width is None else plot_width} self.append(Oracle(oracle, qubits_idx, - self.num_qubits if num_qubits is None else num_qubits, depth, gate_name)) + self.num_qubits if num_qubits is None else num_qubits, depth, gate_info)) def control_oracle( self, oracle: paddle.Tensor, qubits_idx: Union[Iterable[Iterable[int]], Iterable[int]], - num_qubits: int = None, depth: int = 1, gate_name: str = 'cO' + num_qubits: int = None, depth: int = 1, + gate_name: Optional[str] = 'O', latex_name: Optional[str] = None, plot_width: Optional[float] = None ) -> None: """Add a controlled oracle gate. @@ -1017,11 +1070,16 @@ def control_oracle( qubits_idx: Indices of the qubits on which the gates are applied. num_qubits: Total number of qubits. Defaults to None. depth: Number of layers. Defaults to 1. - gate_name: name of this oracle + gate_name: name of this oracle. + latex_name: latex name of this oracle, default to be the gate name. + plot_width: width of this gate in circuit plot, default to be proportional with the gate name. """ self.__num_qubits_update(qubits_idx) + gate_info = {'gatename': f"c{gate_name}", + 'texname': f"${gate_name}$" if latex_name is None else latex_name, + 'plot_width': 0.6 * len(gate_name) if plot_width is None else plot_width} self.append(ControlOracle(oracle, qubits_idx, - self.num_qubits if num_qubits is None else num_qubits, depth, gate_name)) + self.num_qubits if num_qubits is None else num_qubits, depth, gate_info)) def collapse(self, qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None, desired_result: Union[int, str] = None, if_print: bool = False, @@ -1037,12 +1095,12 @@ def collapse(self, qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubi Raises: NotImplementedError: If the basis of measurement is not z. Other bases will be implemented in future. TypeError: cannot get probability of state when the backend is unitary_matrix. - + Note: When desired_result is `None`, Collapse does not support gradient calculation """ self.__num_qubits_update(qubits_idx) - self.append(Collapse(qubits_idx, self.num_qubits if num_qubits is None else num_qubits, + self.append(Collapse(qubits_idx, self.num_qubits if num_qubits is None else num_qubits, desired_result, if_print, measure_basis)) def superposition_layer( @@ -1074,7 +1132,7 @@ def weak_superposition_layer( WeakSuperpositionLayer(qubits_idx, self.num_qubits if num_qubits is None else num_qubits, depth)) def linear_entangled_layer( - self, qubits_idx: Iterable[int] = 'full', num_qubits: int = None, depth: int = 1 + self, qubits_idx: Iterable[int] = 'full', num_qubits: int = None, depth: int = 1 ) -> None: r"""Add linear entangled layers consisting of Ry gates, Rz gates, and CNOT gates. @@ -1088,7 +1146,7 @@ def linear_entangled_layer( LinearEntangledLayer(qubits_idx, self.num_qubits if num_qubits is None else num_qubits, depth)) def real_entangled_layer( - self, qubits_idx: Iterable[int] = 'full', num_qubits: int = None, depth: int = 1 + self, qubits_idx: Iterable[int] = 'full', num_qubits: int = None, depth: int = 1 ) -> None: r"""Add strongly entangled layers consisting of Ry gates and CNOT gates. @@ -1102,7 +1160,7 @@ def real_entangled_layer( RealEntangledLayer(qubits_idx, self.num_qubits if num_qubits is None else num_qubits, depth)) def complex_entangled_layer( - self, qubits_idx: Iterable[int] = 'full', num_qubits: int = None, depth: int = 1 + self, qubits_idx: Iterable[int] = 'full', num_qubits: int = None, depth: int = 1 ) -> None: r"""Add strongly entangled layers consisting of single-qubit rotation gates and CNOT gates. @@ -1116,7 +1174,7 @@ def complex_entangled_layer( ComplexEntangledLayer(qubits_idx, self.num_qubits if num_qubits is None else num_qubits, depth)) def real_block_layer( - self, qubits_idx: Iterable[int] = 'full', num_qubits: int = None, depth: int = 1 + self, qubits_idx: Iterable[int] = 'full', num_qubits: int = None, depth: int = 1 ) -> None: r"""Add weakly entangled layers consisting of Ry gates and CNOT gates. @@ -1130,7 +1188,7 @@ def real_block_layer( RealBlockLayer(qubits_idx, self.num_qubits if num_qubits is None else num_qubits, depth)) def complex_block_layer( - self, qubits_idx: Iterable[int] = 'full', num_qubits: int = None, depth: int = 1 + self, qubits_idx: Iterable[int] = 'full', num_qubits: int = None, depth: int = 1 ) -> None: r"""Add weakly entangled layers consisting of single-qubit rotation gates and CNOT gates. @@ -1144,7 +1202,7 @@ def complex_block_layer( ComplexBlockLayer(qubits_idx, self.num_qubits if num_qubits is None else num_qubits, depth)) def bit_flip( - self, prob: Union[paddle.Tensor, float], qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None + self, prob: Union[paddle.Tensor, float], qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None ) -> None: r"""Add bit flip channels. @@ -1154,11 +1212,12 @@ def bit_flip( num_qubits: Total number of qubits. Defaults to None. """ self.__num_qubits_update(qubits_idx) - self.append(BitFlip(prob, qubits_idx, + self.append(BitFlip(prob, qubits_idx, self.num_qubits if num_qubits is None else num_qubits)) - + def phase_flip( - self, prob: Union[paddle.Tensor, float], qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None + self, prob: Union[paddle.Tensor, float], qubits_idx: Union[Iterable[int], int, str] = 'full', + num_qubits: int = None ) -> None: r"""Add phase flip channels. @@ -1168,11 +1227,12 @@ def phase_flip( num_qubits: Total number of qubits. Defaults to None. """ self.__num_qubits_update(qubits_idx) - self.append(PhaseFlip(prob, qubits_idx, - self.num_qubits if num_qubits is None else num_qubits)) - + self.append(PhaseFlip(prob, qubits_idx, + self.num_qubits if num_qubits is None else num_qubits)) + def bit_phase_flip( - self, prob: Union[paddle.Tensor, float], qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None + self, prob: Union[paddle.Tensor, float], qubits_idx: Union[Iterable[int], int, str] = 'full', + num_qubits: int = None ) -> None: r"""Add bit phase flip channels. @@ -1184,9 +1244,9 @@ def bit_phase_flip( self.__num_qubits_update(qubits_idx) self.append(BitPhaseFlip(prob, qubits_idx, self.num_qubits if num_qubits is None else num_qubits)) - + def amplitude_damping( - self, gamma: Union[paddle.Tensor, float], qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None + self, gamma: Union[paddle.Tensor, float], qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None ) -> None: r"""Add amplitude damping channels. @@ -1198,15 +1258,17 @@ def amplitude_damping( self.__num_qubits_update(qubits_idx) self.append(AmplitudeDamping(gamma, qubits_idx, self.num_qubits if num_qubits is None else num_qubits)) - - #TODO: change bug + def generalized_amplitude_damping( - self, gamma: Union[paddle.Tensor, float], qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None + self, gamma: Union[paddle.Tensor, float], prob: Union[paddle.Tensor, float], + qubits_idx: Union[Iterable[int], int, str] = 'full', + num_qubits: int = None ) -> None: r"""Add generalized amplitude damping channels. Args: - gamma: Damping probability. + gamma: Damping probability. Its value should be in the range :math:`[0, 1]`. + prob: Excitation probability. Its value should be in the range :math:`[0, 1]`. qubits_idx: Indices of the qubits on which the channels are applied. Defaults to 'full'. num_qubits: Total number of qubits. Defaults to None. """ @@ -1215,7 +1277,8 @@ def generalized_amplitude_damping( self.num_qubits if num_qubits is None else num_qubits)) def phase_damping( - self, gamma: Union[paddle.Tensor, float], qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None + self, gamma: Union[paddle.Tensor, float], qubits_idx: Union[Iterable[int], int, str] = 'full', + num_qubits: int = None ) -> None: r"""Add phase damping channels. @@ -1229,7 +1292,8 @@ def phase_damping( self.num_qubits if num_qubits is None else num_qubits)) def depolarizing( - self, prob: Union[paddle.Tensor, float], qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None + self, prob: Union[paddle.Tensor, float], qubits_idx: Union[Iterable[int], int, str] = 'full', + num_qubits: int = None ) -> None: r"""Add depolarizing channels. @@ -1243,7 +1307,8 @@ def depolarizing( self.num_qubits if num_qubits is None else num_qubits)) def pauli_channel( - self, prob: Union[paddle.Tensor, float], qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None + self, prob: Union[paddle.Tensor, float], qubits_idx: Union[Iterable[int], int, str] = 'full', + num_qubits: int = None ) -> None: r"""Add Pauli channels. @@ -1257,7 +1322,8 @@ def pauli_channel( self.num_qubits if num_qubits is None else num_qubits)) def reset_channel( - self, prob: Union[paddle.Tensor, float], qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None + self, prob: Union[paddle.Tensor, float], qubits_idx: Union[Iterable[int], int, str] = 'full', + num_qubits: int = None ) -> None: r"""Add reset channels. @@ -1271,8 +1337,8 @@ def reset_channel( self.num_qubits if num_qubits is None else num_qubits)) def thermal_relaxation( - self, const_t: Union[paddle.Tensor, Iterable[float]], exec_time: Union[paddle.Tensor, float], - qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None + self, const_t: Union[paddle.Tensor, Iterable[float]], exec_time: Union[paddle.Tensor, float], + qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None ) -> None: r"""Add thermal relaxation channels. @@ -1286,6 +1352,20 @@ def thermal_relaxation( self.append(ThermalRelaxation(const_t, exec_time, qubits_idx, self.num_qubits if num_qubits is None else num_qubits)) + def mixed_unitary_channel( + self, num_unitary: Union[paddle.Tensor, int], qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None + ) -> None: + r"""Add mixed random unitary channels + + Args: + num_unitary: The amount of random unitaries to be generated. + qubits_idx: Indices of the qubits on which the channels act. Defaults to ``'full'``. + num_qubits: Total number of qubits. Defaults to ``None``. + """ + self.__num_qubits_update(qubits_idx) + self.append(MixedUnitaryChannel(num_unitary, qubits_idx, + self.num_qubits if num_qubits is None else num_qubits)) + def kraus_repr( self, kraus_oper: Iterable[paddle.Tensor], qubits_idx: Union[Iterable[Iterable[int]], Iterable[int], int], @@ -1321,7 +1401,7 @@ def unitary_matrix(self, num_qubits: Optional[int] = None) -> paddle.Tensor: num_qubits = self.__num_qubits else: assert num_qubits >= self.__num_qubits - + backend = get_backend() self.to(backend=Backend.UnitaryMatrix) unitary = State(paddle.eye(2 ** num_qubits).cast(get_dtype()), @@ -1337,11 +1417,11 @@ def gate_history(self) -> List[Dict[str, Union[str, List[int], paddle.Tensor]]]: Returns: history of quantum gates of circuit - + """ gate_history = [] for gate in self.sublayers(): - if gate.gate_name is None: + if gate.gate_info['gatename'] is None: raise NotImplementedError(f"Gate {type(gate)} has no gate name and hence cannot be recorded into history.") else: gate.gate_history_generation() @@ -1369,7 +1449,6 @@ def __count_history(self, history): if qubit[curr_qubit] > qubit_max: length.append(5) qubit_max = qubit[curr_qubit] - # Gates with params to print elif current_gate['gate'] in {'p', 'rx', 'ry', 'rz'}: curr_qubit = current_gate['which_qubits'] gate.append(qubit[curr_qubit]) @@ -1379,13 +1458,9 @@ def __count_history(self, history): if qubit[curr_qubit] > qubit_max: length.append(5) qubit_max = qubit[curr_qubit] - # Two-qubit gates or Three-qubit gates - elif ( - current_gate['gate'] in { - 'cnot', 'swap', 'rxx', 'ryy', 'rzz', 'ms', - 'cy', 'cz', 'cu', 'cp', 'crx', 'cry', 'crz'} or - current_gate['gate'] in {'cswap', 'ccx'} - ): + elif current_gate['gate'] in {'cnot', 'swap', 'rxx', 'ryy', 'rzz', 'ms', + 'cy', 'cz', 'cu', 'cp', 'crx', 'cry', 'crz', + 'cswap', 'ccx'}: a = max(current_gate['which_qubits']) b = min(current_gate['which_qubits']) ind = max(qubit[b: a + 1]) @@ -1400,11 +1475,11 @@ def __count_history(self, history): qubit_max = ind + 1 return length, gate - + @property def qubit_history(self) -> List[List[Tuple[Dict[str, Union[str, List[int], paddle.Tensor]], int]]]: r""" gate information on each qubit - + Returns: list of gate history on each qubit @@ -1412,10 +1487,7 @@ def qubit_history(self) -> List[List[Tuple[Dict[str, Union[str, List[int], paddl The entry ``qubit_history[i][j][0/1]`` returns the gate information / gate index of the j-th gate applied on the i-th qubit. """ - history_qubit = [] - for i in range(self.num_qubits): - history_i = [] - history_qubit.append(history_i) + history_qubit = [[] for _ in range(self.num_qubits)] for idx, i in enumerate(self.gate_history): qubits = i["which_qubits"] if not isinstance(qubits, Iterable): @@ -1542,6 +1614,67 @@ def __str__(self) -> str: return return_str + def plot(self, + save_path: Optional[str] = None, + dpi: Optional[int] = 100, + show: Optional[bool] = True, + output: Optional[bool] = False, + scale: Optional[float] = 1.0, + tex: Optional[bool] = False, + ) -> Union[None, matplotlib.figure.Figure]: + r'''display the circuit using matplotlib + + Args: + save_path: the save path of image + dpi: dots per inches, here is resolution ratio + show: whether execute ``plt.show()`` + output: whether return the ``matplotlib.figure.Figure`` instance + scale: scale coefficient of figure, default to 1.0 + tex: a bool flag which controls latex fonts of gate display, default to ``False``. + + Returns: + a ``matplotlib.figure.Figure`` instance or ``None`` depends on ``output`` + + Note: + Using ``plt.show()`` may cause a distortion, but it will not happen in the figure saved. + If the depth is too long, there will be some patches unable to display. + Setting ``tex = True`` requires that you have TeX and the other dependencies properly + installed on your system. See + https://matplotlib.org/stable/gallery/text_labels_and_annotations/tex_demo.html + for more details. + ''' + _fig = _circuit_plot(self, dpi=dpi, scale=scale, tex = tex) + + if save_path: + plt.savefig(save_path, dpi=dpi,) + + if show: # whether display in window + plt.show() + + if output: + return _fig # return the ``matplotlib.pyplot.figure`` instance + + def extend(self, cir): + r""" extend for quantum circuit + + Args: + cir: a Circuit or a Sequential + + Returns: + concatenation of two quantum circuits + + """ + if isinstance(cir, Circuit): + if self.__num_qubits is None: + self.__num_qubits = cir.num_qubits + else: + self.__num_qubits = self.__num_qubits if cir.num_qubits is None else max(self.__num_qubits, cir.num_qubits) + super().extend(cir) + elif isinstance(cir, Sequential): + super().extend(cir) + else: + raise TypeError("the input type must be Circuit or Sequential") + def forward(self, state: Optional[State] = None) -> State: r""" forward the input @@ -1561,3 +1694,5 @@ def forward(self, state: Optional[State] = None) -> State: f"num_qubits does not agree: expected {self.__num_qubits}, received {state.num_qubits}" return super().forward(state) + + diff --git a/paddle_quantum/ansatz/vans.py b/paddle_quantum/ansatz/vans.py index 9ec0f6e..afb57a0 100644 --- a/paddle_quantum/ansatz/vans.py +++ b/paddle_quantum/ansatz/vans.py @@ -26,6 +26,39 @@ from typing import Callable, List, Any, Optional +def cir_decompose(cir: Circuit, trainable: Optional[bool] = False) -> Circuit: + r"""Decompose all layers of circuit into gates, and make all parameterized gates trainable if needed + + Args: + cir: Target quantum circuit. + trainable: whether the decomposed parameterized gates are trainable + + Returns: + A quantum circuit with same structure and parameters but all layers are decomposed into Gates. + + Note: + This function does not support customized gates, such as oracle and control-oracle. + """ + gates_history = cir.gate_history + new_cir = Circuit() + for gate_info in gates_history: + gate_name = gate_info['gate'] + qubits_idx = gate_info['which_qubits'] + param = gate_info['theta'] + # get gate function + if param is None: + getattr(new_cir, gate_name)(qubits_idx) + continue + + if trainable: + param = param.reshape([1] + param.shape) + param = paddle.create_parameter( + shape=param.shape, dtype=param.dtype, + default_initializer=paddle.nn.initializer.Assign(param)) + getattr(new_cir, gate_name)(qubits_idx, param=param) + return new_cir + + class Inserter: r"""Class for block insertion for the circuit. """ @@ -125,7 +158,8 @@ def __place_identity_block(cls, cir: Circuit, theta: paddle.Tensor) -> Circuit: cir.insert(insert_ind + 5, RZ([qubit_j], param=theta[4])) cir.insert(insert_ind + 6, RX([qubit_j], param=theta[5])) cir.insert(insert_ind + 7, CNOT([qubit_i, qubit_j])) - return cir + + return cir_decompose(cir, trainable=True) @classmethod def __count_qubit_gates(cls, cir: Circuit) -> np.ndarray: @@ -144,14 +178,13 @@ def __count_qubit_gates(cls, cir: Circuit) -> np.ndarray: history = cir.gate_history for gate_info in history: qubits_idx = gate_info["which_qubits"] - if gate_info["gate"] == "rz" or gate_info["gate"] == "rx": + if gate_info["gate"] in ["rz", "rx"]: qubit_ind = qubits_idx count_gates[qubit_ind] += 1 elif gate_info["gate"] == "cnot": qubit_i = min(qubits_idx[0], qubits_idx[1]) qubit_j = max(qubits_idx[0], qubits_idx[1]) - idx = (2 * cir.num_qubits - qubit_i) * \ - (qubit_i + 1) // 2 + qubit_j - qubit_i - 1 + idx = (2 * cir.num_qubits - qubit_i) * (qubit_i + 1) // 2 + qubit_j - qubit_i - 1 count_gates[idx] += 1 return count_gates @@ -179,18 +212,11 @@ def __check_cnot_init(cls, cir: Circuit) -> bool: cnot_qubits = history_i[0][0]["which_qubits"] # find the other qubit for j in cnot_qubits: - if j != i: - # check the CNOT is also in the front for the other qubit - if ( - qubit_history[j][0][0]["gate"] == "cnot" - and qubit_history[j][0][0]["which_qubits"] - == cnot_qubits - ): - count += 1 - if count == 0: - return True - else: - return False + if j != i and \ + qubit_history[j][0][0]["gate"] == "cnot" and \ + qubit_history[j][0][0]["which_qubits"] == cnot_qubits: + count += 1 + return count == 0 @classmethod def __check_consec_cnot(cls, cir: Circuit) -> bool: @@ -216,16 +242,13 @@ def __check_consec_cnot(cls, cir: Circuit) -> bool: ): cnot_qubits = history_i[j][0]["which_qubits"] # get the other qubit - k = list(set(cnot_qubits).difference(set([i])))[0] + k = list(set(cnot_qubits).difference({i}))[0] # check if the found consecutive cnots are also consecutive on the other qubit history_k = qubit_history[k] idx_k = history_k.index(history_i[j]) if history_k[idx_k + 1] == history_i[j + 1]: count += 1 - if count == 0: - return True - else: - return False + return count == 0 @classmethod def __check_rz_init(cls, cir: Circuit) -> bool: @@ -243,12 +266,9 @@ def __check_rz_init(cls, cir: Circuit) -> bool: history_i = qubit_history[i] if not history_i: continue - if history_i[0][0]["gate"] == "z" or history_i[0][0]["gate"] == "rz": + if history_i[0][0]["gate"] in ["z", "rz"]: count += 1 - if count == 0: - return True - else: - return False + return count == 0 @classmethod def __check_repeated_rotations(cls, cir: Circuit) -> bool: @@ -275,10 +295,7 @@ def __check_repeated_rotations(cls, cir: Circuit) -> bool: and history_i[j + 1][0]["gate"] == "rz" ): count += 1 - if count == 0: - return True - else: - return False + return count == 0 @classmethod def __check_4_consec_rotations(cls, cir: Circuit) -> bool: @@ -309,10 +326,7 @@ def __check_4_consec_rotations(cls, cir: Circuit) -> bool: and history_i[j + 3][0]["gate"] == "rx" ): count += 1 - if count == 0: - return True - else: - return False + return count == 0 @classmethod def __check_rz_cnot_rz_rx_cnot_rx(cls, cir: Circuit) -> bool: @@ -344,10 +358,7 @@ def __check_rz_cnot_rz_rx_cnot_rx(cls, cir: Circuit) -> bool: and history_i[j + 1][0]["which_qubits"][1] == i ): count += 1 - if count == 0: - return True - else: - return False + return count == 0 @classmethod def __rule_1(cls, cir: Circuit) -> Circuit: @@ -369,15 +380,11 @@ def __rule_1(cls, cir: Circuit) -> Circuit: cnot_qubits = history_i[0][0]["which_qubits"] # find the other qubit for j in cnot_qubits: - if j != i: - # check the CNOT is also in the front for the other qubit - if ( - qubit_history[j][0][0]["gate"] == "cnot" - and qubit_history[j][0][0]["which_qubits"] - == cnot_qubits - ): - # delete the gate - cir.pop(qubit_history[j][0][1]) + if j != i and \ + qubit_history[j][0][0]["gate"] == "cnot" and \ + qubit_history[j][0][0]["which_qubits"] == cnot_qubits: + # delete the gate + cir.pop(qubit_history[j][0][1]) qubit_history = cir.qubit_history history_i = cir.qubit_history[i] return cir @@ -409,7 +416,7 @@ def __rule_2(cls, cir: Circuit) -> Circuit: ): cnot_qubits = history_i[j][0]["which_qubits"] # get the other qubit - k = list(set(cnot_qubits).difference(set([i])))[0] + k = list(set(cnot_qubits).difference({i}))[0] # check if the found consecutive cnots are also consecutive on the other qubit history_k = qubit_history[k] idx_k = history_k.index(history_i[j]) @@ -437,7 +444,7 @@ def __rule_3(cls, cir: Circuit) -> Circuit: history_i = cir.qubit_history[i] if not history_i: continue - if history_i[0][0]["gate"] == "z" or history_i[0][0]["gate"] == "rz": + if history_i[0][0]["gate"] in ["z", "rz"]: # delete from history cir.pop(history_i[0][1]) return cir @@ -709,41 +716,8 @@ def simplify_circuit(cls, cir: Circuit, zero_init_state: Optional[bool] = True) cir = cls.__rule_5(cir) cir = cls.__rule_6(cir) - return cir - - -def cir_decompose(cir: Circuit, trainable: Optional[bool] = False) -> Circuit: - r"""Decompose all layers of circuit into gates, and make all parameterized gates trainable if needed - - Args: - cir: Target quantum circuit. - trainable: whether the decomposed parameterized gates are trainable - - Returns: - A quantum circuit with same structure and parameters but all layers are decomposed into Gates. - - Note: - This function does not support customized gates, such as oracle and control-oracle. - """ - gates_history = cir.gate_history - new_cir = Circuit() - for gate_info in gates_history: - gate_name = gate_info['gate'] - qubits_idx = gate_info['which_qubits'] - param = gate_info['theta'] - # get gate function - if param is None: - getattr(new_cir, gate_name)(qubits_idx) - continue - - if trainable: - param = param.reshape([1] + param.shape) - param = paddle.create_parameter( - shape=param.shape, dtype=param.dtype, - default_initializer=paddle.nn.initializer.Assign(param)) - getattr(new_cir, gate_name)(qubits_idx, param=param) - return new_cir - + return cir_decompose(cir, trainable=True) + class VAns: r"""Class of Variable Ansatz. @@ -835,14 +809,13 @@ def train(self) -> Circuit: itr_loss = self.optimization(self.cir) self.loss = itr_loss else: # insert + simplification - # Insert - new_cir = cir_decompose(self.cir, trainable=True) + new_cir = self.cir new_cir = Inserter.insert_identities( new_cir, self.insert_rate, self.epsilon) new_cir = Simplifier.simplify_circuit( new_cir, self.zero_init_state) - + itr_loss = self.optimization(new_cir) relative_diff = (itr_loss - self.loss) / abs(itr_loss) @@ -879,8 +852,6 @@ def optimization(self, cir: Circuit) -> float: Returns: Optimized loss. """ - cir = cir_decompose(cir, trainable=True) - opt = paddle.optimizer.Adam( learning_rate=self.LR, parameters=cir.parameters()) diff --git a/paddle_quantum/channel/__init__.py b/paddle_quantum/channel/__init__.py index 982b0a2..f084fbf 100644 --- a/paddle_quantum/channel/__init__.py +++ b/paddle_quantum/channel/__init__.py @@ -28,5 +28,7 @@ from .common import PauliChannel from .common import ResetChannel from .common import ThermalRelaxation +from .common import MixedUnitaryChannel from .custom import KrausRepr from .custom import ChoiRepr +from .custom import StinespringRepr diff --git a/paddle_quantum/channel/common.py b/paddle_quantum/channel/common.py index 389357c..3c9825a 100644 --- a/paddle_quantum/channel/common.py +++ b/paddle_quantum/channel/common.py @@ -19,7 +19,8 @@ import paddle import paddle_quantum -from paddle_quantum.intrinsic import _format_qubits_idx +from ..intrinsic import _format_qubits_idx +from ..qinfo import kraus_oper_random from .base import Channel from . import functional from ..backend import Backend @@ -47,10 +48,7 @@ def __init__( ): super().__init__() self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - if isinstance(prob, float): - self.prob = paddle.to_tensor(prob) - else: - self.prob = prob + self.prob = paddle.to_tensor(prob) if isinstance(prob, (int, float)) else prob def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -81,10 +79,7 @@ def __init__( ): super().__init__() self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - if isinstance(prob, float): - self.prob = paddle.to_tensor(prob) - else: - self.prob = prob + self.prob = paddle.to_tensor(prob) if isinstance(prob, (int, float)) else prob def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -115,10 +110,7 @@ def __init__( ): super().__init__() self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - if isinstance(prob, float): - self.prob = paddle.to_tensor(prob) - else: - self.prob = prob + self.prob = paddle.to_tensor(prob) if isinstance(prob, (int, float)) else prob def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -157,10 +149,7 @@ def __init__( ): super().__init__() self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - if isinstance(gamma, float): - self.gamma = paddle.to_tensor(gamma) - else: - self.gamma = gamma + self.gamma = paddle.to_tensor(gamma) if isinstance(gamma, (int, float)) else gamma def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -198,14 +187,8 @@ def __init__( ): super().__init__() self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - if isinstance(prob, float): - self.prob = paddle.to_tensor(prob) - else: - self.prob = prob - if isinstance(gamma, float): - self.gamma = paddle.to_tensor(gamma) - else: - self.gamma = gamma + self.prob = paddle.to_tensor(prob) if isinstance(prob, (int, float)) else prob + self.gamma = paddle.to_tensor(gamma) if isinstance(gamma, (int, float)) else gamma def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -245,10 +228,7 @@ def __init__( ): super().__init__() self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - if isinstance(gamma, float): - self.gamma = paddle.to_tensor(gamma) - else: - self.gamma = gamma + self.gamma = paddle.to_tensor(gamma) if isinstance(gamma, (int, float)) else gamma def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -265,15 +245,22 @@ class Depolarizing(Channel): .. math:: - E_0 = \sqrt{1-p} I, - E_1 = \sqrt{p/3} X, - E_2 = \sqrt{p/3} Y, - E_3 = \sqrt{p/3} Z. + E_0 = \sqrt{1-3p/4} I, + E_1 = \sqrt{p/4} X, + E_2 = \sqrt{p/4} Y, + E_3 = \sqrt{p/4} Z. Args: prob: Parameter of the depolarizing channels. Its value should be in the range :math:`[0, 1]`. qubits_idx: Indices of the qubits on which the channels act. Defaults to ``'full'``. num_qubits: Total number of qubits. Defaults to ``None``. + + Note: + The implementation logic for this feature has been updated. + The current version refers to formula (8.102) in Quantum Computation and Quantum Information 10th + edition by M.A.Nielsen and I.L.Chuang. + Reference: Nielsen, M., & Chuang, I. (2010). Quantum Computation and Quantum Information: 10th + Anniversary Edition. Cambridge: Cambridge University Press. doi:10.1017/CBO9780511976667 """ def __init__( self, prob: Union[paddle.Tensor, float], @@ -281,10 +268,7 @@ def __init__( ): super().__init__() self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - if isinstance(prob, float): - self.prob = paddle.to_tensor(prob) - else: - self.prob = prob + self.prob = paddle.to_tensor(prob) if isinstance(prob, (int, float)) else prob def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -312,10 +296,7 @@ def __init__( ): super().__init__() self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - if isinstance(prob, Iterable): - self.prob = paddle.to_tensor(prob) - else: - self.prob = prob + self.prob = paddle.to_tensor(prob) if isinstance(prob, Iterable) else prob def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -370,10 +351,7 @@ def __init__( ): super().__init__() self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - if isinstance(prob, Iterable): - self.prob = paddle.to_tensor(prob) - else: - self.prob = prob + self.prob = paddle.to_tensor(prob) if isinstance(prob, Iterable) else prob def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -403,14 +381,8 @@ def __init__( ): super().__init__() self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - if isinstance(const_t, float): - self.const_t = paddle.to_tensor(const_t) - else: - self.const_t = const_t - if isinstance(exec_time, float): - self.exec_time = paddle.to_tensor(exec_time) - else: - self.exec_time = exec_time + self.const_t = paddle.to_tensor(const_t) if isinstance(const_t, (int, float)) else const_t + self.exec_time = paddle.to_tensor(exec_time) if isinstance(exec_time, (int, float)) else exec_time def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -419,3 +391,35 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state = functional.thermal_relaxation( state, self.const_t, self.exec_time, qubit_idx, self.dtype, self.backend) return state + + +class MixedUnitaryChannel(Channel): + r"""A collection of mixed unitary channels. + + Such a channel's Kraus operators are randomly generated unitaries times related probabilities + .. math:: + + N(\rho) = \sum_{i} p_{i} U_{i} \rho U_{i}^{\dagger} + + Args: + num_unitary: The amount of random unitaries to be generated. + qubits_idx: Indices of the qubits on which the channels act. Defaults to ``'full'``. + num_qubits: Total number of qubits. Defaults to ``None``. + + Note: + The probability distribution of unitaries is set to be uniform distribution. + """ + def __init__( + self, num_unitary: int, + qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None + ): + super().__init__() + self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) + self.kraus_oper = kraus_oper_random(1, num_unitary) + + def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: + if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: + raise NotImplementedError + for qubit_idx in self.qubits_idx: + state = functional.kraus_repr(state, self.kraus_oper, qubit_idx, self.dtype, self.backend) + return state diff --git a/paddle_quantum/channel/custom.py b/paddle_quantum/channel/custom.py index 7da5d0a..82421f2 100644 --- a/paddle_quantum/channel/custom.py +++ b/paddle_quantum/channel/custom.py @@ -19,11 +19,13 @@ import math import paddle +import warnings +from typing import Union, Iterable + import paddle_quantum from .base import Channel -from paddle_quantum.intrinsic import _format_qubits_idx from . import functional -from typing import Union, Iterable +from ..intrinsic import _format_qubits_idx class KrausRepr(Channel): @@ -35,23 +37,94 @@ class KrausRepr(Channel): num_qubits: Total number of qubits. Defaults to ``None``. """ def __init__( - self, kraus_oper: Iterable[paddle.Tensor], + self, kraus_oper: Union[paddle.Tensor, Iterable[paddle.Tensor]], qubits_idx: Union[Iterable[Iterable[int]], Iterable[int], int], num_qubits: int = None ): - # TODO: need to check whether the input is legal super().__init__() num_acted_qubits = int(math.log2(kraus_oper[0].shape[0])) assert 2 ** num_acted_qubits == kraus_oper[0].shape[0], "The length of oracle should be integer power of 2." - self.kraus_oper = kraus_oper - is_single_qubit = True if num_acted_qubits == 1 else False + + self.kraus_oper = [oper.cast(self.dtype) for oper in kraus_oper] if isinstance(kraus_oper, Iterable) else [kraus_oper.cast(self.dtype)] self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, num_acted_qubits) + + # sanity check + dimension = 2 ** num_acted_qubits + oper_sum = paddle.zeros([dimension, dimension]).cast(self.dtype) + for oper in self.kraus_oper: + oper_sum = oper_sum + oper @ paddle.conj(oper.T) + err = paddle.norm(paddle.abs(oper_sum - paddle.eye(dimension).cast(self.dtype))).item() + if err > min(1e-6 * dimension * len(kraus_oper), 0.01): + warnings.warn( + f"\nThe input data may not be a Kraus representation of a channel: norm(sum(E * E^d) - I) = {err}.", UserWarning) - def forward(self, state: 'paddle_quantum.State') -> 'paddle_quantum.State': + def __matmul__(self, other: 'KrausRepr') -> 'KrausRepr': + r"""Composition between channels with Kraus representations + + """ + assert self.qubits_idx == other.qubits_idx, \ + f"Two channels should have the same qubit indices to composite: received {self.qubits_idx} and {other.qubits_idx}" + if not isinstance(other, KrausRepr): + raise NotImplementedError( + f"does not support the composition between KrausRepr and {type(other)}") + new_kraus_oper = [] + for this_kraus in self.kraus_oper: + new_kraus_oper.extend([this_kraus @ other_kraus for other_kraus in other.kraus_oper]) + return KrausRepr(new_kraus_oper, self.qubits_idx) + + def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: for qubits_idx in self.qubits_idx: state = functional.kraus_repr(state, self.kraus_oper, qubits_idx, self.dtype, self.backend) return state class ChoiRepr(Channel): - pass + def __init__( + self, + choi_oper: paddle.Tensor, + qubits_idx: Union[Iterable[Iterable[int]], Iterable[int], int], + num_qubits: int = None + ): + super().__init__() + num_acted_qubits = int(math.log2(choi_oper.shape[0]) / 2) + assert 2 ** (2 * num_acted_qubits) == choi_oper.shape[0], "The length of oracle should be integer power of 2." + self.choi_oper = choi_oper + self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, num_acted_qubits) + + def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: + for qubits_idx in self.qubits_idx: + state = functional.choi_repr( + state, + self.choi_oper, + qubits_idx, + self.dtype, + self.backend + ) + return state + + +class StinespringRepr(Channel): + def __init__( + self, + stinespring_matrix: paddle.Tensor, + qubits_idx: Union[Iterable[Iterable[int]], Iterable[int], int], + num_qubits: int = None + ): + super().__init__() + num_acted_qubits = int(math.log2(stinespring_matrix.shape[1])) + dim_ancilla = stinespring_matrix.shape[0] // stinespring_matrix.shape[1] + dim_act = stinespring_matrix.shape[1] + assert dim_act * dim_ancilla == stinespring_matrix.shape[0], 'The width of stinespring matrix should be the factor of its height' + self.stinespring_matrix = stinespring_matrix + self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, num_acted_qubits) + + def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: + for qubits_idx in self.qubits_idx: + state = functional.stinespring_repr( + state, + self.stinespring_matrix, + qubits_idx, + self.dtype, + self.backend + ) + return state diff --git a/paddle_quantum/channel/functional/__init__.py b/paddle_quantum/channel/functional/__init__.py index 8f757f0..633c3cc 100644 --- a/paddle_quantum/channel/functional/__init__.py +++ b/paddle_quantum/channel/functional/__init__.py @@ -29,3 +29,4 @@ from .common import thermal_relaxation from .common import kraus_repr from .common import choi_repr +from .common import stinespring_repr diff --git a/paddle_quantum/channel/functional/common.py b/paddle_quantum/channel/functional/common.py index b986f00..851b8d8 100644 --- a/paddle_quantum/channel/functional/common.py +++ b/paddle_quantum/channel/functional/common.py @@ -22,11 +22,12 @@ import paddle_quantum from ...backend import density_matrix from ...intrinsic import _zero, _one -from typing import Iterable +from typing import Iterable, List, Tuple, Union def bit_flip( - state: paddle_quantum.State, prob: paddle.Tensor, qubit_idx: int, dtype: str, backend: paddle_quantum.Backend + state: paddle_quantum.State, prob: paddle.Tensor, qubit_idx: Union[List[int], int], + dtype: str, backend: paddle_quantum.Backend ) -> paddle_quantum.State: r"""Apply a bit flip channel on the input state. @@ -58,7 +59,12 @@ def bit_flip( for idx, oper in enumerate(kraus_oper): kraus_oper[idx] = paddle.reshape(paddle.concat(oper), [2, 2]) state_data = [ - density_matrix.unitary_transformation(state.data, oper, [qubit_idx], state.num_qubits) for oper in kraus_oper + density_matrix.unitary_transformation( + state.data, + oper, + qubit_idx if isinstance(qubit_idx, list) else [qubit_idx], + state.num_qubits + ) for oper in kraus_oper ] state_data = functools.reduce(lambda x, y: x + y, state_data) transformed_state = state.clone() @@ -67,7 +73,8 @@ def bit_flip( def phase_flip( - state: paddle_quantum.State, prob: paddle.Tensor, qubit_idx: int, dtype: str, backend: paddle_quantum.Backend + state: paddle_quantum.State, prob: paddle.Tensor, qubit_idx: Union[List[int], int], + dtype: str, backend: paddle_quantum.Backend ) -> paddle_quantum.State: r"""Apply a phase flip channel on the input state. @@ -99,7 +106,12 @@ def phase_flip( for idx, oper in enumerate(kraus_oper): kraus_oper[idx] = paddle.reshape(paddle.concat(oper), [2, 2]) state_data = [ - density_matrix.unitary_transformation(state.data, oper, [qubit_idx], state.num_qubits) for oper in kraus_oper + density_matrix.unitary_transformation( + state.data, + oper, + qubit_idx if isinstance(qubit_idx, list) else [qubit_idx], + state.num_qubits + ) for oper in kraus_oper ] state_data = functools.reduce(lambda x, y: x + y, state_data) transformed_state = state.clone() @@ -108,7 +120,8 @@ def phase_flip( def bit_phase_flip( - state: paddle_quantum.State, prob: paddle.Tensor, qubit_idx: int, dtype: str, backend: paddle_quantum.Backend + state: paddle_quantum.State, prob: paddle.Tensor, qubit_idx: Union[List[int], int], + dtype: str, backend: paddle_quantum.Backend ) -> paddle_quantum.State: r"""Apply a bit phase flip channel on the input state. @@ -140,7 +153,12 @@ def bit_phase_flip( for idx, oper in enumerate(kraus_oper): kraus_oper[idx] = paddle.reshape(paddle.concat(oper), [2, 2]) state_data = [ - density_matrix.unitary_transformation(state.data, oper, [qubit_idx], state.num_qubits) for oper in kraus_oper + density_matrix.unitary_transformation( + state.data, + oper, + qubit_idx if isinstance(qubit_idx, list) else [qubit_idx], + state.num_qubits + ) for oper in kraus_oper ] state_data = functools.reduce(lambda x, y: x + y, state_data) transformed_state = state.clone() @@ -149,7 +167,8 @@ def bit_phase_flip( def amplitude_damping( - state: paddle_quantum.State, gamma: paddle.Tensor, qubit_idx: int, dtype: str, backend: paddle_quantum.Backend + state: paddle_quantum.State, gamma: paddle.Tensor, qubit_idx: Union[List[int], int], + dtype: str, backend: paddle_quantum.Backend ) -> paddle_quantum.State: r"""Apply an amplitude damping channel on the input state. @@ -181,7 +200,12 @@ def amplitude_damping( for idx, oper in enumerate(kraus_oper): kraus_oper[idx] = paddle.reshape(paddle.concat(oper), [2, 2]) state_data = [ - density_matrix.unitary_transformation(state.data, oper, [qubit_idx], state.num_qubits) for oper in kraus_oper + density_matrix.unitary_transformation( + state.data, + oper, + qubit_idx if isinstance(qubit_idx, list) else [qubit_idx], + state.num_qubits + ) for oper in kraus_oper ] state_data = functools.reduce(lambda x, y: x + y, state_data) transformed_state = state.clone() @@ -191,7 +215,7 @@ def amplitude_damping( def generalized_amplitude_damping( state: paddle_quantum.State, gamma: paddle.Tensor, prob: paddle.Tensor, - qubit_idx: int, dtype: str, backend: paddle_quantum.Backend + qubit_idx: Union[List[int], int], dtype: str, backend: paddle_quantum.Backend ) -> paddle_quantum.State: r"""Apply a generalized amplitude damping channel on the input state. @@ -232,7 +256,12 @@ def generalized_amplitude_damping( for idx, oper in enumerate(kraus_oper): kraus_oper[idx] = paddle.reshape(paddle.concat(oper), [2, 2]) state_data = [ - density_matrix.unitary_transformation(state.data, oper, [qubit_idx], state.num_qubits) for oper in kraus_oper + density_matrix.unitary_transformation( + state.data, + oper, + qubit_idx if isinstance(qubit_idx, list) else [qubit_idx], + state.num_qubits + ) for oper in kraus_oper ] state_data = functools.reduce(lambda x, y: x + y, state_data) transformed_state = state.clone() @@ -241,7 +270,8 @@ def generalized_amplitude_damping( def phase_damping( - state: paddle_quantum.State, gamma: paddle.Tensor, qubit_idx: int, dtype: str, backend: paddle_quantum.Backend + state: paddle_quantum.State, gamma: paddle.Tensor, qubit_idx: Union[List[int], int], + dtype: str, backend: paddle_quantum.Backend ) -> paddle_quantum.State: r"""Apply a phase damping channel on the input state. @@ -273,7 +303,12 @@ def phase_damping( for idx, oper in enumerate(kraus_oper): kraus_oper[idx] = paddle.reshape(paddle.concat(oper), [2, 2]) state_data = [ - density_matrix.unitary_transformation(state.data, oper, [qubit_idx], state.num_qubits) for oper in kraus_oper + density_matrix.unitary_transformation( + state.data, + oper, + qubit_idx if isinstance(qubit_idx, list) else [qubit_idx], + state.num_qubits + ) for oper in kraus_oper ] state_data = functools.reduce(lambda x, y: x + y, state_data) transformed_state = state.clone() @@ -282,7 +317,8 @@ def phase_damping( def depolarizing( - state: paddle_quantum.State, prob: paddle.Tensor, qubit_idx: int, dtype: str, backend: paddle_quantum.Backend + state: paddle_quantum.State, prob: paddle.Tensor, qubit_idx: Union[List[int], int], + dtype: str, backend: paddle_quantum.Backend ) -> paddle_quantum.State: r"""Apply a depolarizing channel on the input state. @@ -303,26 +339,31 @@ def depolarizing( raise RuntimeError("The noisy channel can only run in density matrix mode.") kraus_oper = [ [ - paddle.sqrt(1 - prob).cast(dtype), _zero(dtype), - _zero(dtype), paddle.sqrt(1 - prob).cast(dtype), + paddle.sqrt(1 - 3 * prob / 4).cast(dtype), _zero(dtype), + _zero(dtype), paddle.sqrt(1 - 3 * prob / 4).cast(dtype), ], [ - _zero(dtype), paddle.sqrt(prob / 3).cast(dtype), - paddle.sqrt(prob / 3).cast(dtype), _zero(dtype), + _zero(dtype), paddle.sqrt(prob / 4).cast(dtype), + paddle.sqrt(prob / 4).cast(dtype), _zero(dtype), ], [ - _zero(dtype), -1j * paddle.sqrt(prob / 3).cast(dtype), - 1j * paddle.sqrt(prob / 3).cast(dtype), _zero(dtype), + _zero(dtype), -1j * paddle.sqrt(prob / 4).cast(dtype), + 1j * paddle.sqrt(prob / 4).cast(dtype), _zero(dtype), ], [ - paddle.sqrt(prob / 3).cast(dtype), _zero(dtype), - _zero(dtype), (-1 * paddle.sqrt(prob / 3)).cast(dtype), + paddle.sqrt(prob / 4).cast(dtype), _zero(dtype), + _zero(dtype), (-1 * paddle.sqrt(prob / 4)).cast(dtype), ], ] for idx, oper in enumerate(kraus_oper): kraus_oper[idx] = paddle.reshape(paddle.concat(oper), [2, 2]) state_data = [ - density_matrix.unitary_transformation(state.data, oper, [qubit_idx], state.num_qubits) for oper in kraus_oper + density_matrix.unitary_transformation( + state.data, + oper, + qubit_idx if isinstance(qubit_idx, list) else [qubit_idx], + state.num_qubits + ) for oper in kraus_oper ] state_data = functools.reduce(lambda x, y: x + y, state_data) transformed_state = state.clone() @@ -331,7 +372,7 @@ def depolarizing( def pauli_channel( - state: paddle_quantum.State, prob: paddle.Tensor, qubit_idx: int, + state: paddle_quantum.State, prob: paddle.Tensor, qubit_idx: Union[List[int], int], dtype: str, backend: paddle_quantum.Backend ) -> paddle_quantum.State: r"""Apply a Pauli channel on the input state. @@ -374,7 +415,12 @@ def pauli_channel( for idx, oper in enumerate(kraus_oper): kraus_oper[idx] = paddle.reshape(paddle.concat(oper), [2, 2]) state_data = [ - density_matrix.unitary_transformation(state.data, oper, [qubit_idx], state.num_qubits) for oper in kraus_oper + density_matrix.unitary_transformation( + state.data, + oper, + qubit_idx if isinstance(qubit_idx, list) else [qubit_idx], + state.num_qubits + ) for oper in kraus_oper ] state_data = functools.reduce(lambda x, y: x + y, state_data) transformed_state = state.clone() @@ -383,7 +429,7 @@ def pauli_channel( def reset_channel( - state: paddle_quantum.State, prob: paddle.Tensor, qubit_idx: int, + state: paddle_quantum.State, prob: paddle.Tensor, qubit_idx: Union[List[int], int], dtype: str, backend: paddle_quantum.Backend ) -> paddle_quantum.State: r"""Apply a reset channel on the input state. @@ -430,7 +476,12 @@ def reset_channel( for idx, oper in enumerate(kraus_oper): kraus_oper[idx] = paddle.reshape(paddle.concat(oper), [2, 2]) state_data = [ - density_matrix.unitary_transformation(state.data, oper, [qubit_idx], state.num_qubits) for oper in kraus_oper + density_matrix.unitary_transformation( + state.data, + oper, + qubit_idx if isinstance(qubit_idx, list) else [qubit_idx], + state.num_qubits + ) for oper in kraus_oper ] state_data = functools.reduce(lambda x, y: x + y, state_data) transformed_state = state.clone() @@ -440,7 +491,7 @@ def reset_channel( def thermal_relaxation( state: paddle_quantum.State, const_t: paddle.Tensor, exec_time: paddle.Tensor, - qubit_idx: int, dtype: str, backend: paddle_quantum.Backend + qubit_idx: Union[List[int], int], dtype: str, backend: paddle_quantum.Backend ) -> paddle_quantum.State: r"""Apply a thermal relaxation channel on the input state. @@ -486,7 +537,12 @@ def thermal_relaxation( for idx, oper in enumerate(kraus_oper): kraus_oper[idx] = paddle.reshape(paddle.concat(oper), [2, 2]) state_data = [ - density_matrix.unitary_transformation(state.data, oper, [qubit_idx], state.num_qubits) for oper in kraus_oper + density_matrix.unitary_transformation( + state.data, + oper, + qubit_idx if isinstance(qubit_idx, list) else [qubit_idx], + state.num_qubits + ) for oper in kraus_oper ] state_data = functools.reduce(lambda x, y: x + y, state_data) transformed_state = state.clone() @@ -495,7 +551,7 @@ def thermal_relaxation( def kraus_repr( - state: paddle_quantum.State, kraus_oper: Iterable[paddle.Tensor], qubit_idx: int, + state: paddle_quantum.State, kraus_oper: Iterable[paddle.Tensor], qubit_idx: Union[List[int], int], dtype: str, backend: paddle_quantum.Backend ) -> paddle_quantum.State: r"""Apply a custom channel in the Kraus representation on the input state. @@ -515,9 +571,13 @@ def kraus_repr( """ if backend != paddle_quantum.Backend.DensityMatrix: raise RuntimeError("The noisy channel can only run in density matrix mode.") - kraus_oper = [paddle.cast(oper, dtype) for oper in kraus_oper] state_data = [ - density_matrix.unitary_transformation(state.data, oper, [qubit_idx], state.num_qubits) for oper in kraus_oper + density_matrix.unitary_transformation( + state.data, + oper, + qubit_idx if isinstance(qubit_idx, list) else [qubit_idx], + state.num_qubits + ) for oper in kraus_oper ] state_data = functools.reduce(lambda x, y: x + y, state_data) transformed_state = state.clone() @@ -525,5 +585,323 @@ def kraus_repr( return transformed_state -def choi_repr(): - raise NotImplementedError +def choi_repr( + state: paddle_quantum.State, choi_oper: paddle.Tensor, qubit_idx: Union[List[int], int], + dtype: str, backend: paddle_quantum.Backend +) -> paddle_quantum.State: + r"""choi_repr implement + + Assume the choi state has the shape of sum :math:`|i\rangle\langle j|` :math:`N(|i\rangle\langle j|)` . + + Args: + state: input quantum state + choi_oper: choi representation for the channel + qubit_idx: which qubits the channel acts on + dtype: data dtype + backend: data backend + + Raises: + RuntimeError: _description_ + + Returns: + paddle_quantum.State: output from the channel + """ + qubit_idx = qubit_idx if isinstance(qubit_idx, list) else [qubit_idx] + + def genSwapList(origin: List[int], target: List[int]) -> List[Tuple[int, int]]: + assert len(origin) == len(target) + swapped = [False] * len(origin) + swap_ops = [] + + origin_pos_dict = {v: pos for pos, v in enumerate(origin)} + + def positionOfValueAt(idx): + # return the position of value `target[idx]` in origin array + return origin_pos_dict[target[idx]] + + ref = origin.copy() + for idx in range(len(origin)): + if not swapped[idx]: + next_idx = idx + swapped[next_idx] = True + while not swapped[positionOfValueAt(next_idx)]: + swapped[positionOfValueAt(next_idx)] = True + if next_idx < positionOfValueAt(next_idx): + swap_ops.append((next_idx, positionOfValueAt(next_idx))) + else: + swap_ops.append((positionOfValueAt(next_idx), next_idx)) + + x, y = swap_ops[-1] + ref[x], ref[y] = ref[y], ref[x] + # print(idx, (x,y), ref) + next_idx = positionOfValueAt(next_idx) + + return swap_ops + + if backend != paddle_quantum.Backend.DensityMatrix: + raise RuntimeError("The noisy channel can only run in density matrix mode.") + assert len(choi_oper) == 2 ** (2 * len(qubit_idx)) + + num_qubits = state.num_qubits + num_acted_qubits = len(qubit_idx) + + # make partial transpose on the ancilla of choi repr, this leads to choi_mat as `sum |j> + + with A being the stinespring operator, the channel acts as rho -> Tr_2 A rho A^dagger. + + Args: + state: input quantum state + stinespring_mat: Stinespring representation for the channel + qubit_idx: which qubits the channel acts on + dtype: data dtype + backend: data backend + + Returns: + paddle_quantum.State: output from the channel + """ + qubit_idx = qubit_idx if isinstance(qubit_idx, list) else [qubit_idx] + + def genSwapList(origin: List[int], target: List[int]) -> List[Tuple[int, int]]: + assert len(origin) == len(target) + swapped = [False] * len(origin) + swap_ops = [] + + origin_pos_dict = {v: pos for pos, v in enumerate(origin)} + + def positionOfValueAt(idx): + # return the position of value `target[idx]` in origin array + return origin_pos_dict[target[idx]] + + ref = origin.copy() + for idx in range(len(origin)): + if not swapped[idx]: + next_idx = idx + swapped[next_idx] = True + while not swapped[positionOfValueAt(next_idx)]: + swapped[positionOfValueAt(next_idx)] = True + if next_idx < positionOfValueAt(next_idx): + swap_ops.append((next_idx, positionOfValueAt(next_idx))) + else: + swap_ops.append((positionOfValueAt(next_idx), next_idx)) + + x, y = swap_ops[-1] + ref[x], ref[y] = ref[y], ref[x] + # print(idx, (x,y), ref) + next_idx = positionOfValueAt(next_idx) + + return swap_ops + + num_qubits = state.num_qubits + num_acted_qubits = len(qubit_idx) + dim_ancilla = stinespring_mat.shape[0] // (2 ** num_acted_qubits) + dim_main = 2 ** num_acted_qubits + dim_extended = dim_ancilla * 2 ** num_qubits + + # transpose the stinespring matrix such that it has the shape of (dim_ancilla, dim_main, dim_main) + # assuming the input form is (dim_main * dim_ancilla, dim_main) + stine_m = stinespring_mat.reshape([dim_main, dim_ancilla, dim_main]).transpose([1, 0, 2]).reshape( + [dim_main * dim_ancilla, dim_main]) + + # rotate the density matrix such that the acted_qubits are at the head + state_data = state.data + higher_dims = state_data.shape[:-2] + num_higher_dims = len(higher_dims) + + swap_ops = genSwapList(list(range(num_qubits)), qubit_idx + [x for x in range(num_qubits) if x not in qubit_idx]) + + # make swap for left + for swap_op in swap_ops: + shape = higher_dims.copy() + last_idx = -1 + for idx in swap_op: + shape.append(2 ** (idx - last_idx - 1)) + shape.append(2) + last_idx = idx + shape.append(2 ** (2 * num_qubits - last_idx - 1)) + state_data = paddle.reshape(state_data, shape) + state_data = paddle.transpose( + state_data, list(range(num_higher_dims)) + [item + num_higher_dims for item in [0, 3, 2, 1, 4]] + ) + + # make swap for right + for swap_op in swap_ops: + shape = higher_dims.copy() + last_idx = -1 + shape.append(2 ** num_qubits) + for idx in swap_op: + shape.append(2 ** (idx - last_idx - 1)) + shape.append(2) + last_idx = idx + shape.append(2 ** (num_qubits - last_idx - 1)) + state_data = paddle.reshape(state_data, shape) + state_data = paddle.transpose( + state_data, list(range(num_higher_dims)) + [item + num_higher_dims for item in [0, 1, 4, 3, 2, 5]] + ) + + # multiply the stinespring matrix + state_data = paddle.reshape( + state_data, higher_dims.copy() + [dim_main, -1] + ) + state_data = paddle.reshape( + paddle.matmul( + stine_m, state_data + ), higher_dims.copy() + [dim_extended, 2 ** num_qubits] + ) + state_data = paddle.reshape( + state_data, higher_dims.copy() + [dim_extended, dim_main, -1] + ) + state_data = paddle.reshape( + paddle.matmul( + stine_m.conj(), state_data + ), higher_dims.copy() + [dim_extended, dim_extended] + ) + + # make partial trace + state_data = paddle.trace( + paddle.reshape( + state_data, + higher_dims.copy() + [dim_ancilla, 2 ** num_qubits, dim_ancilla, 2 ** num_qubits] + ), + axis1=len(higher_dims), + axis2=2 + len(higher_dims) + ) + + # swap back + revert_swap_ops = genSwapList(qubit_idx + [x for x in range(num_qubits) if x not in qubit_idx], + list(range(num_qubits))) + for swap_op in revert_swap_ops: + shape = higher_dims.copy() + last_idx = -1 + for idx in swap_op: + shape.append(2 ** (idx - last_idx - 1)) + shape.append(2) + last_idx = idx + shape.append(2 ** (2 * num_qubits - last_idx - 1)) + state_data = paddle.reshape(state_data, shape) + state_data = paddle.transpose( + state_data, list(range(num_higher_dims)) + [item + num_higher_dims for item in [0, 3, 2, 1, 4]] + ) + for swap_op in revert_swap_ops: + shape = higher_dims.copy() + last_idx = -1 + shape.append(2 ** num_qubits) + for idx in swap_op: + shape.append(2 ** (idx - last_idx - 1)) + shape.append(2) + last_idx = idx + shape.append(2 ** (num_qubits - last_idx - 1)) + state_data = paddle.reshape(state_data, shape) + state_data = paddle.transpose( + state_data, list(range(num_higher_dims)) + [item + num_higher_dims for item in [0, 1, 4, 3, 2, 5]] + ) + + state_data = paddle.reshape(state_data, higher_dims.copy() + [2 ** num_qubits, 2 ** num_qubits]) + return paddle_quantum.State(state_data, dtype=dtype, backend=backend) diff --git a/paddle_quantum/gate/__init__.py b/paddle_quantum/gate/__init__.py index bcc6e98..b35a55e 100644 --- a/paddle_quantum/gate/__init__.py +++ b/paddle_quantum/gate/__init__.py @@ -20,7 +20,7 @@ from . import functional from .base import Gate, ParamGate from .clifford import Clifford, compose_clifford_circuit -from .single_qubit_gate import H, S, T, X, Y, Z, P, RX, RY, RZ, U3 +from .single_qubit_gate import H, S, Sdg, T, Tdg, X, Y, Z, P, RX, RY, RZ, U3 from .multi_qubit_gate import CNOT, CX, CY, CZ, SWAP from .multi_qubit_gate import CP, CRX, CRY, CRZ, CU, RXX, RYY, RZZ from .multi_qubit_gate import MS, CSWAP, Toffoli diff --git a/paddle_quantum/gate/base.py b/paddle_quantum/gate/base.py index 576f26e..7f986d8 100644 --- a/paddle_quantum/gate/base.py +++ b/paddle_quantum/gate/base.py @@ -19,10 +19,13 @@ import paddle import paddle_quantum -from typing import Union, List, Iterable +from typing import Union, List, Iterable, Optional, Any + +from paddle_quantum.gate.functional.single_qubit_gate import x from ..intrinsic import _get_float_dtype from math import pi - +from .functional.visual import _base_gate_display, _base_param_gate_display +import matplotlib class Gate(paddle_quantum.Operator): r"""Base class for quantum gates. @@ -40,8 +43,12 @@ def __init__( ): super().__init__(backend, dtype, name_scope) self.depth = depth - self.gate_name = None - + self.gate_info = { + 'gatename': None, + 'texname': None, + 'plot_width': None, + } + def forward(self, *inputs, **kwargs): raise NotImplementedError @@ -58,11 +65,34 @@ def gate_history_generation(self) -> None: """ gate_history = [] - for _ in range(0, self.depth): + for _ in range(self.depth): for qubit_idx in self.qubits_idx: - gate_info = {'gate': self.gate_name, 'which_qubits': qubit_idx, 'theta': None} + gate_info = {'gate': self.gate_info['gatename'], 'which_qubits': qubit_idx, 'theta': None} gate_history.append(gate_info) self.gate_history = gate_history + + def set_gate_info(self, **kwargs: Any) -> None: + r'''the interface to set `self.gate_info` + + Args: + kwargs: parameters to set `self.gate_info` + ''' + self.gate_info.update(kwargs) + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + r'''The display function called by circuit instance when plotting. + + Args: + ax: the ``matplotlib.axes.Axes`` instance + x: the start horizontal position + + Returns: + the total width occupied + + Note: + Users could overload this function for custom display. + ''' + return _base_gate_display(self, ax, x) class ParamGate(Gate): @@ -88,7 +118,7 @@ def theta_generation(self, param: Union[paddle.Tensor, float, List[float]], para """ float_dtype = _get_float_dtype(self.dtype) - + if param is None: theta = self.create_parameter( shape=param_shape, dtype=float_dtype, @@ -97,16 +127,16 @@ def theta_generation(self, param: Union[paddle.Tensor, float, List[float]], para self.add_parameter('theta', theta) elif isinstance(param, paddle.fluid.framework.ParamBase): - assert param.shape == param_shape, "received: " + str(param.shape) + " expect: " + str(param_shape) + assert param.shape == param_shape, f"received: {str(param.shape)} expect: {param_shape}" self.add_parameter('theta', param) - + elif isinstance(param, paddle.Tensor): param = param.reshape(param_shape) self.theta = param - - elif isinstance(param, float): + + elif isinstance(param, (int, float)): self.theta = paddle.ones(param_shape, dtype=float_dtype) * param - + else: # when param is a list of float self.theta = paddle.to_tensor(param, dtype=float_dtype).reshape(param_shape) @@ -115,12 +145,27 @@ def gate_history_generation(self) -> None: """ gate_history = [] - for depth_idx in range(0, self.depth): + for depth_idx in range(self.depth): for idx, qubit_idx in enumerate(self.qubits_idx): if self.param_sharing: param = self.theta[depth_idx] else: param = self.theta[depth_idx][idx] - gate_info = {'gate': self.gate_name, 'which_qubits': qubit_idx, 'theta': param} + gate_info = {'gate': self.gate_info['gatename'], 'which_qubits': qubit_idx, 'theta': param} gate_history.append(gate_info) self.gate_history = gate_history + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + r'''The display function called by circuit instance when plotting. + + Argrs: + ax: the ``matplotlib.axes.Axes`` instance + x: the start horizontal position + + Returns: + the total width occupied + + Note: + Users could overload this function for custom display. + ''' + return _base_param_gate_display(self, ax, x) \ No newline at end of file diff --git a/paddle_quantum/gate/custom.py b/paddle_quantum/gate/custom.py index 31dfc87..c562a4d 100644 --- a/paddle_quantum/gate/custom.py +++ b/paddle_quantum/gate/custom.py @@ -18,13 +18,16 @@ """ import math +import matplotlib import paddle -import paddle_quantum + +import warnings +import paddle_quantum as pq from . import functional from .base import Gate -from paddle_quantum.intrinsic import _format_qubits_idx +from ..intrinsic import _format_qubits_idx from typing import Union, Iterable -from paddle_quantum.linalg import is_unitary +from .functional.visual import _c_oracle_like_display, _oracle_like_display class Oracle(Gate): @@ -38,22 +41,38 @@ class Oracle(Gate): """ def __init__( self, oracle: paddle.Tensor, qubits_idx: Union[Iterable[Iterable[int]], Iterable[int], int], - num_qubits: int = None, depth: int = 1, gate_name: str = 'O' + num_qubits: int = None, depth: int = 1, gate_info: dict = None ): super().__init__(depth) - oracle = oracle.cast(paddle_quantum.get_dtype()) - assert is_unitary(oracle), "the input oracle must be a unitary matrix" - num_acted_qubits = int(math.log2(oracle.shape[0])) - self.oracle = paddle.cast(oracle, paddle_quantum.get_dtype()) + complex_dtype = pq.get_dtype() + oracle = oracle.cast(complex_dtype) + + dimension = oracle.shape[0] + err = paddle.norm(paddle.abs(oracle @ paddle.conj(oracle.T) - paddle.cast(paddle.eye(dimension), complex_dtype))).item() + if err > min(1e-6 * dimension, 0.01): + warnings.warn( + f"\nThe input oracle may not be a unitary: norm(U * U^d - I) = {err}.", UserWarning) + + num_acted_qubits = int(math.log2(dimension)) + self.oracle = oracle self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, num_acted_qubits) - - self.gate_name = gate_name - def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: - for _ in range(0, self.depth): + self.gate_info = { + 'gatename': 'O', + 'texname': r'$O$', + 'plot_width': 0.6, + } + if gate_info: + self.gate_info.update(gate_info) + + def forward(self, state: pq.State) -> pq.State: + for _ in range(self.depth): for qubits_idx in self.qubits_idx: state = functional.oracle(state, self.oracle, qubits_idx, self.backend) return state + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _oracle_like_display(self, ax, x) class ControlOracle(Gate): @@ -67,27 +86,40 @@ class ControlOracle(Gate): """ def __init__( self, oracle: paddle.Tensor, qubits_idx: Union[Iterable[Iterable[int]], Iterable[int]], - num_qubits: int = None, depth: int = 1, gate_name: str = 'cO' + num_qubits: int = None, depth: int = 1, gate_info: dict = None ) -> None: super().__init__(depth) - complex_dtype = paddle_quantum.get_dtype() + complex_dtype = pq.get_dtype() oracle = oracle.cast(complex_dtype) - assert is_unitary(oracle), "the input oracle must be a unitary matrix" - num_acted_qubits = int(math.log2(oracle.shape[0])) - # 暂时只支持单控制位 + dimension = oracle.shape[0] + err = paddle.norm(paddle.abs(oracle @ paddle.conj(oracle.T) - paddle.cast(paddle.eye(dimension), complex_dtype))).item() + if err > min(1e-6 * dimension, 0.01): + warnings.warn( + f"\nThe input oracle may not be a unitary: norm(U * U^d - I) = {err}.", UserWarning) + + num_acted_qubits = int(math.log2(dimension)) oracle = ( paddle.kron(paddle.to_tensor([[1.0, 0], [0, 0]], dtype=complex_dtype), paddle.eye(2 ** num_acted_qubits)) + paddle.kron(paddle.to_tensor([[0.0, 0], [0, 1]], dtype=complex_dtype), oracle) ) - num_acted_qubits = num_acted_qubits + 1 + num_acted_qubits += 1 self.oracle = oracle self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, num_acted_qubits) - - self.gate_name = gate_name - def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: - for _ in range(0, self.depth): + self.gate_info = { + 'gatename': 'cO', + 'texname': r'$O$', + 'plot_width': 0.6, + } + if gate_info: + self.gate_info.update(gate_info) + + def forward(self, state: pq.State) -> pq.State: + for _ in range(self.depth): for qubits_idx in self.qubits_idx: state = functional.oracle(state, self.oracle, qubits_idx, self.backend) return state + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _c_oracle_like_display(self, ax, x) diff --git a/paddle_quantum/gate/encoding.py b/paddle_quantum/gate/encoding.py index 8d3e9b5..2ff2820 100644 --- a/paddle_quantum/gate/encoding.py +++ b/paddle_quantum/gate/encoding.py @@ -42,7 +42,7 @@ def __init__( super().__init__() self.num_qubits = num_qubits self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - self.gate_name = 'BasisEnc' + self.gate_info['gatename'] = 'BasisEnc' def forward(self, feature: paddle.Tensor, state: 'paddle_quantum.State' = None) -> 'paddle_quantum.State': if state is None: @@ -78,7 +78,7 @@ def __init__( super().__init__() self.num_qubits = num_qubits self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - self.gate_name = 'AmpEnc' + self.gate_info['gatename'] = 'AmpEnc' def forward(self, feature: paddle.Tensor) -> 'paddle_quantum.State': def calc_location(location_of_bits_list): @@ -157,7 +157,7 @@ def __init__( feature = paddle.flatten(feature) self.feature = feature - self.gate_name = 'AngleEnc' + self.gate_info['gatename'] = 'AngleEnc' def forward( self, state: 'paddle_quantum.State' = None, invert: bool = False @@ -206,7 +206,7 @@ def __init__( feature = paddle.flatten(feature) self.feature = feature - self.gate_name = 'IQPEnc' + self.gate_info['gatename'] = 'IQPEnc' def forward( self, state: paddle_quantum.State = None, invert: Optional[bool] = False diff --git a/paddle_quantum/gate/functional/__init__.py b/paddle_quantum/gate/functional/__init__.py index eb3c57f..f4f5d03 100644 --- a/paddle_quantum/gate/functional/__init__.py +++ b/paddle_quantum/gate/functional/__init__.py @@ -19,7 +19,9 @@ from .single_qubit_gate import h from .single_qubit_gate import s +from .single_qubit_gate import sdg from .single_qubit_gate import t +from .single_qubit_gate import tdg from .single_qubit_gate import x from .single_qubit_gate import y from .single_qubit_gate import z diff --git a/paddle_quantum/gate/functional/single_qubit_gate.py b/paddle_quantum/gate/functional/single_qubit_gate.py index 857eb6d..ab0b3f5 100644 --- a/paddle_quantum/gate/functional/single_qubit_gate.py +++ b/paddle_quantum/gate/functional/single_qubit_gate.py @@ -71,6 +71,29 @@ def s(state: paddle_quantum.State, qubit_idx: int, dtype: str, backend: paddle_q return transformed_state +def sdg(state: paddle_quantum.State, qubit_idx: int, dtype: str, backend: paddle_quantum.Backend) -> paddle_quantum.State: + r"""Apply an S dagger (inverse S) gate on the input state. + + Args: + state: Input state. + qubit_idx: Index of the qubit on which the gate is applied. + dtype: Type of data. + backend: Backend on which the simulation is run. + + Returns: + Output state. + """ + gate = [ + [1, 0], + [0, -1j], + ] + gate = paddle.to_tensor(gate, dtype=dtype) + state_data = simulation(state, gate, qubit_idx, state.num_qubits, backend) + transformed_state = state.clone() + transformed_state.data = state_data + return transformed_state + + def t(state: paddle_quantum.State, qubit_idx: int, dtype: str, backend: paddle_quantum.Backend) -> paddle_quantum.State: r"""Apply a T gate on the input state. @@ -93,6 +116,27 @@ def t(state: paddle_quantum.State, qubit_idx: int, dtype: str, backend: paddle_q transformed_state.data = state_data return transformed_state +def tdg(state: paddle_quantum.State, qubit_idx: int, dtype: str, backend: paddle_quantum.Backend) -> paddle_quantum.State: + r"""Apply a T dagger (inverse T) gate on the input state. + + Args: + state: Input state. + qubit_idx: Index of the qubit on which the gate is applied. + dtype: Type of data. + backend: Backend on which the simulation is run. + + Returns: + Output state. + """ + gate = [ + [1, 0], + [0, math.cos(math.pi/4) - math.sin(math.pi/4) * 1j], + ] + gate = paddle.to_tensor(gate, dtype=dtype) + state_data = simulation(state, gate, qubit_idx, state.num_qubits, backend) + transformed_state = state.clone() + transformed_state.data = state_data + return transformed_state def x(state: paddle_quantum.State, qubit_idx: int, dtype: str, backend: paddle_quantum.Backend) -> paddle_quantum.State: r"""Apply an X gate on the input state. diff --git a/paddle_quantum/gate/functional/visual.py b/paddle_quantum/gate/functional/visual.py new file mode 100644 index 0000000..82a1817 --- /dev/null +++ b/paddle_quantum/gate/functional/visual.py @@ -0,0 +1,816 @@ +# !/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. + +r""" +The visualization function of ``paddle_quantum.gate.Gate`` for display +in ``paddle_quantum.ansatz.Circuit`` . +""" + +from typing import Optional, Union, List, Any +import matplotlib +import matplotlib.pyplot as plt +from matplotlib.lines import Line2D +from matplotlib.patches import Circle, Rectangle + +import paddle_quantum as pq + +# the default parameters of plot +__CIRCUIT_PLOT_PARAM = { + 'scale': 1.0, # scale flag + 'circuit_height': 0.55, # the height of per line + 'offset': 0.12, # the head and tail offset of horizontal circuit lines + 'line_width': 0.8, + 'block_margin': 0.07, # the horizontal and vertical margin of a rectangle + 'node_width': 0.2, # the block width of patches + 'fontsize': 9.5, + 'circle_radius': 0.08, + 'cross_radius': 0.06, + 'dot_radius': 0.03, + 'margin': 0.02, # the proportion of figure margin + 'tex': False, +} + + +def scale_circuit_plot_param(scale: float) -> None: + r'''The scale function of ``__CIRCUIT_PLOT_PARAM`` dictionary + + Args: + scale: the scalar for scaling the elements in the figure + ''' + for key in __CIRCUIT_PLOT_PARAM: + if isinstance(__CIRCUIT_PLOT_PARAM[key], (int, float)): + __CIRCUIT_PLOT_PARAM[key] = scale * __CIRCUIT_PLOT_PARAM[key] + + +def set_circuit_plot_param(**kwargs: Any) -> None: + r'''The set function of ``__CIRCUIT_PLOT_PARAM`` dictionary + + Args: + kwargs: parameters to update the ``__CIRCUIT_PLOT_PARAM`` dictionary + ''' + __CIRCUIT_PLOT_PARAM.update(kwargs) + + +def get_circuit_plot_param() -> dict: + r'''The output function of ``__CIRCUIT_PLOT_PARAM`` dictionary + + Returns: + a copy of ``__CIRCUIT_PLOT_PARAM`` + ''' + return __CIRCUIT_PLOT_PARAM.copy() + + +def reset_circuit_plot_param() -> None: + r'''The reset function of ``__CIRCUIT_PLOT_PARAM`` dictionary + ''' + global __CIRCUIT_PLOT_PARAM + __CIRCUIT_PLOT_PARAM = { + 'scale': 1.0, + 'circuit_height': 0.55, + 'offset': 0.12, + 'line_width': 0.8, + 'block_margin': 0.07, + 'node_width': 0.2, + 'fontsize': 9.5, + 'circle_radius': 0.08, + 'cross_radius': 0.06, + 'dot_radius': 0.03, + 'margin': 0.02, + 'tex': False, + } + + +def _circuit_plot( + circuit, + dpi: Optional[int] = 100, + scale: Optional[float] = 1.0, + tex: Optional[bool] = False, +) -> Union[None, matplotlib.figure.Figure]: + r'''display the circuit using matplotlib + + Args: + save_path: the save path of image + dpi: dots per inches, here is resolution ratio + show: whether execute ``plt.show()`` + output: whether return the ``matplotlib.figure.Figure`` instance + scale: scale coefficient of figure + + Returns: + a ``matplotlib.figure.Figure`` instance or ``None`` depends on ``output`` + + Note: + Using ``plt.show()`` may cause a distortion, but it will not happen in the figure saved. + If the depth is too long, there will be some patches unable to display. + ''' + if scale != __CIRCUIT_PLOT_PARAM['scale']: # scale + scale_circuit_plot_param(scale) + set_circuit_plot_param(tex=tex) + + height = __CIRCUIT_PLOT_PARAM['circuit_height'] + lw = __CIRCUIT_PLOT_PARAM['line_width'] + offset = __CIRCUIT_PLOT_PARAM['offset'] + margin = __CIRCUIT_PLOT_PARAM['margin'] + + _x = 0 # initial postion of horizontal + _y = 0 # initial postion of vertical + + _fig = plt.figure(facecolor='w', edgecolor='w', dpi=dpi) + _axes = _fig.add_subplot(1, 1, 1,) + + for gate in circuit.sublayers(): + if not isinstance(gate, pq.gate.Gate): + raise NotImplementedError + _x += gate.display_in_circuit(_axes, _x) + + for _ in range(circuit.num_qubits): # plot horizontal lines for all qubits + line = Line2D((-offset, _x + offset), (_y, _y), lw=lw, color='k', zorder=0) + _axes.add_line(line) + _y += height + + # set the figure size and pattern + _axes.set_axis_off() + _axes.set_xlim(- offset, _x + offset) + _axes.set_ylim(_y - height * 0.5, - height * 0.5) + _axes.set_aspect('equal') + _fig.set_figwidth(_x + offset * 2) + _fig.set_figheight((circuit.num_qubits)*height) + plt.subplots_adjust(top=1-margin, bottom=margin, right=1-margin, left=margin,) + + return _fig + + +def _single_qubit_gate_display(ax: matplotlib.axes.Axes, x: float, y: float, h: float, w: float, + tex_name: Optional[str] = None,) -> None: + r'''Add a rectangle gate with name. + + Args: + ax: matplotlib.axes.Axes instance + x: the start horizontal position in the figure + y: the center of vertical postion + h: height per line + w: width for one block + tex_name: the name written in latex to print + ''' + margin = __CIRCUIT_PLOT_PARAM['block_margin'] + fontsize = __CIRCUIT_PLOT_PARAM['fontsize'] + lw = __CIRCUIT_PLOT_PARAM['line_width'] + tex_ = __CIRCUIT_PLOT_PARAM['tex'] + + rect = Rectangle((x+margin, y-h*0.5+margin), height=h-margin*2, width=w-margin*2, + lw=lw, fc='w', ec='k', zorder=1) + ax.add_patch(rect) + if tex_name is not None: + ax.text(x+w*0.5, y, s=tex_name, size=fontsize, zorder=2, + color='k', ha='center', va='center', rasterized=True, usetex=tex_,) + + +def _multiple_qubit_gate_display(ax: matplotlib.axes.Axes, x: float, y1: float, y2: float, h: float, w: float, + tex_name: Optional[str] = None,) -> None: + r'''Add a rectangle gate acting on multiple continuous gates with name. + + Args: + ax: matplotlib.axes.Axes instance + x: the start horizontal position in the figure + y1: the center of vertical postion of minimum qubits + y2: the center of vertical postion of maximum qubits + h: height per line + w: width for one block + tex_name: the name written in latex to print + ''' + + margin = __CIRCUIT_PLOT_PARAM['block_margin'] + fontsize = __CIRCUIT_PLOT_PARAM['fontsize'] + lw = __CIRCUIT_PLOT_PARAM['line_width'] + tex_ = __CIRCUIT_PLOT_PARAM['tex'] + total_h = y2-y1+h + + rect = Rectangle((x+margin, y1-h*0.5+margin), + height=total_h-margin*2, width=w-2*margin, fc='w', ec='k', lw=lw, zorder=1) + ax.add_patch(rect) + ax.text(x+w*0.5, (y1+y2)*0.5, s=tex_name, size=fontsize, + color='k', ha='center', va='center', rasterized=True, usetex=tex_) + + +def _patch_display(ax: matplotlib.axes.Axes, x: float, y: float, mode: str,) -> None: + r'''Add a patch + + Args: + ax: matplotlib.axes.Axes instance + x: the central horizontal position in the block + y: the center of vertical postion + mode: '+' is for controlled object, 'x' is a cross used `SWAP`, '.' is for controlling + ''' + lw = __CIRCUIT_PLOT_PARAM['line_width'] + + if mode == '+': + crcl_r = __CIRCUIT_PLOT_PARAM['circle_radius'] + reverse_dot = Circle((x, y), crcl_r, fc='none', ec='k', lw=lw, zorder=1) + line_v = Line2D((x, x), (y-crcl_r, y+crcl_r), zorder=1, c='k', lw=lw,) # verticle line + ax.add_patch(reverse_dot) + ax.add_line(line_v) + + elif mode == '.': + dot_r = __CIRCUIT_PLOT_PARAM['dot_radius'] + dot = Circle((x, y), dot_r, fc='k', ec='k', lw=lw, zorder=1) + ax.add_patch(dot) + + elif mode == 'x': + crs_r = __CIRCUIT_PLOT_PARAM['cross_radius'] + line_left = Line2D((x-crs_r, x+crs_r), (y-crs_r, y+crs_r), c='k', lw=lw, zorder=1) + line_right = Line2D((x-crs_r, x+crs_r), (y+crs_r, y-crs_r), c='k', lw=lw, zorder=1) + ax.add_line(line_left) + ax.add_line(line_right) + + +def _vertical_line_display(ax: matplotlib.axes.Axes, x: float, y1: float, y2: float,) -> None: + r'''Add a patch + + Args: + ax: matplotlib.axes.Axes instance + x: the central horizontal position in the block + y1: the vertical postion of one end + y2: the vertical postion of the other end + ''' + lw = __CIRCUIT_PLOT_PARAM['line_width'] + line_ = Line2D((x, x), (y1, y2), lw=lw, c='k', zorder=0) + ax.add_line(line_) + + +def _param_tex_name_(tex_name: str, theta: Union[float, List[float]]) -> str: + r'''Combine latex name and its parameters + + Args: + tex_name: latex name + theta: parameters to plot + ''' + if isinstance(theta, float): + return f'{tex_name[:-1]}(' + f'{theta:.2f}' + ')$' + param = ''.join(f'{float(value):.2f},' for value in theta) + return f'{tex_name[:-1]}({param[:-1]})$' + + +def _is_continuous_list(qubits_idx: List[int]) -> bool: + r'''Check whether the list is continuous + + Args: + qubits_idx: a list with different elements + ''' + return len(qubits_idx) == max(qubits_idx) - min(qubits_idx) + 1 + + +def _not_exist_intersection(list_a: List[float], list_b: List[float]) -> bool: + r'''Check whether there is an overlap in ``List_a`` and ``List_b``. + Args: + List_a: a list with two elements + List_b: a list with two elements + ''' + min_a = min(list_a) + max_a = max(list_a) + min_b = min(list_b) + max_b = max(list_b) + min_ab = min(min_a, min_b) + max_ab = max(max_a, max_b) + return max_a+max_b-min_a-min_b < max_ab-min_ab + + +def _base_gate_display(gate, ax: matplotlib.axes.Axes, x: float,) -> float: + r'''The display function for single qubit base gate. + + Args: + gate: the ``paddle_quantum.gate.Gate`` instance + ax: the ``matplotlib.axes.Axes`` instance + x: the start horizontal position + + Returns: + the total width occupied + ''' + x_start = x + h = __CIRCUIT_PLOT_PARAM['circuit_height'] + w = __CIRCUIT_PLOT_PARAM['scale'] * gate.gate_info['plot_width'] + tex_name = gate.gate_info['texname'] + + for _ in range(gate.depth): + for act_qubits in gate.qubits_idx: # get vertical position + _single_qubit_gate_display(ax, x, act_qubits*h, h, w, tex_name) + x += w # next layer + return x - x_start + + +def _base_param_gate_display(gate, ax: matplotlib.axes.Axes, x: float,) -> float: + r'''The display function for single qubit paramgate. + + Args: + gate: the ``paddle_quantum.gate.Gate`` instance + ax: the ``matplotlib.axes.Axes`` instance + x: the start horizontal position + + Returns: + the total width occupied + ''' + x_start = x + h = __CIRCUIT_PLOT_PARAM['circuit_height'] + w = __CIRCUIT_PLOT_PARAM['scale'] * gate.gate_info['plot_width'] + tex_name = gate.gate_info['texname'] + + for depth in range(gate.depth): + for param_idx, act_qubits in enumerate(gate.qubits_idx): + if gate.param_sharing: # get parameters depending on this flag + theta = gate.theta[depth] + else: + theta = gate.theta[depth, param_idx] + _single_qubit_gate_display(ax, x, act_qubits*h, h, w, _param_tex_name_(tex_name, theta)) + x += w + return x - x_start + + +def _cx_like_display(gate, ax: matplotlib.axes.Axes, x: float,) -> float: + r'''The display function for ``cx`` like gate . + + Args: + gate: the ``paddle_quantum.gate.Gate`` instance + ax: the ``matplotlib.axes.Axes`` instance + x: the start horizontal position + + Returns: + the total width occupied + ''' + x_start = x + h = __CIRCUIT_PLOT_PARAM['circuit_height'] + w = __CIRCUIT_PLOT_PARAM['scale'] * gate.gate_info['plot_width'] + tex_name = gate.gate_info['texname'] + + for _ in range(gate.depth): + for act_qubits in gate.qubits_idx: + x_c = x + 0.5 * w # the center of block + _patch_display(ax, x_c, act_qubits[0]*h, mode='.') + _single_qubit_gate_display(ax, x, act_qubits[1]*h, h, w, tex_name) + _vertical_line_display(ax, x_c, act_qubits[0]*h, act_qubits[1]*h) + x += w + return x - x_start + + +def _crx_like_display(gate, ax: matplotlib.axes.Axes, x: float,) -> float: + r'''The display function for ``crx`` like gate. + + Args: + gate: the ``paddle_quantum.gate.Gate`` instance + ax: the ``matplotlib.axes.Axes`` instance + x: the start horizontal position + + Returns: + the total width occupied + ''' + x_start = x + h = __CIRCUIT_PLOT_PARAM['circuit_height'] + w = __CIRCUIT_PLOT_PARAM['scale'] * gate.gate_info['plot_width'] + tex_name = gate.gate_info['texname'] + + for depth in range(gate.depth): + for param_idx, act_qubits in enumerate(gate.qubits_idx): + if gate.param_sharing: + theta = gate.theta[depth] + else: + theta = gate.theta[depth, param_idx] + x_c = x + 0.5 * w # the center of block + _patch_display(ax, x_c, act_qubits[0]*h, mode='.') + _single_qubit_gate_display(ax, x, act_qubits[1]*h, h, w, _param_tex_name_(tex_name, theta)) + _vertical_line_display(ax, x_c, act_qubits[0]*h, act_qubits[1]*h) + x += w + return x - x_start + + +def _oracle_like_display(gate, ax: matplotlib.axes.Axes, x: float,) -> float: + r'''The display function for ``oracle`` like gate. + + Args: + gate: the ``paddle_quantum.gate.Gate`` instance + ax: the ``matplotlib.axes.Axes`` instance + x: the start horizontal position + + Returns: + the total width occupied + ''' + x_start = x + h = __CIRCUIT_PLOT_PARAM['circuit_height'] + w = __CIRCUIT_PLOT_PARAM['scale'] * gate.gate_info['plot_width'] + tex_name = gate.gate_info['texname'] + + for _ in range(gate.depth): + for act_qubits in gate.qubits_idx: + if isinstance(act_qubits, (int, float)): + _single_qubit_gate_display(ax, x, act_qubits*h, h, w, tex_name) + else: + assert _is_continuous_list(act_qubits), 'Discontinuous oracle cannot be plotted.' + _multiple_qubit_gate_display(ax, x, min(act_qubits)*h, max(act_qubits)*h, h, w, tex_name) + x += w + return x - x_start + + +def _c_oracle_like_display(gate, ax: matplotlib.axes.Axes, x: float,) -> float: + r'''The display function for ``control oracle`` like gate. + + Args: + gate: the ``paddle_quantum.gate.Gate`` instance + ax: the ``matplotlib.axes.Axes`` instance + x: the start horizontal position + + Returns: + the total width occupied + ''' + x_start = x + h = __CIRCUIT_PLOT_PARAM['circuit_height'] + w = __CIRCUIT_PLOT_PARAM['scale'] * gate.gate_info['plot_width'] + tex_name = gate.gate_info['texname'] + + for _ in range(gate.depth): + for act_qubits in gate.qubits_idx: + assert _is_continuous_list(act_qubits[1:]), 'Discontinuous oracle cannot be plotted.' + min_ = min(act_qubits[1:]) + max_ = max(act_qubits[1:]) + if act_qubits[0] <= max_ and act_qubits[0] >= min_: + raise RuntimeError('Invalid input of control oracle. ') + + x_c = x + 0.5 * w + _patch_display(ax, x_c, h*act_qubits[0], mode='.') + _multiple_qubit_gate_display(ax, x, min_*h, max_*h, h, w, tex_name) + _vertical_line_display(ax, x_c, h*act_qubits[0], 0.5*(min_*h+max_*h)) + x += w + return x - x_start + + +def _rxx_like_display(gate, ax: matplotlib.axes.Axes, x: float,) -> float: + r'''The display function for ``rxx`` like gate. + + Args: + gate: the ``paddle_quantum.gate.Gate`` instance + ax: the ``matplotlib.axes.Axes`` instance + x: the start horizontal position + + Returns: + the total width occupied + ''' + x_start = x + h = __CIRCUIT_PLOT_PARAM['circuit_height'] + w = __CIRCUIT_PLOT_PARAM['scale'] * gate.gate_info['plot_width'] + tex_name = gate.gate_info['texname'] + + for depth in range(gate.depth): + for param_idx, act_qubits in enumerate(gate.qubits_idx): + assert _is_continuous_list(act_qubits), 'Discontinuous oracle cannot be plotted.' + if gate.param_sharing: + theta = gate.theta[depth] + else: + theta = gate.theta[depth, param_idx] + _multiple_qubit_gate_display(ax, x, min(act_qubits)*h, max(act_qubits)*h, + h, w, _param_tex_name_(tex_name, theta)) + x += w + return x - x_start + + +def _cnot_display(gate, ax: matplotlib.axes.Axes, x: float,) -> float: + r'''The display function for ``cnot`` like gate. + + Args: + gate: the ``paddle_quantum.gate.Gate`` instance + ax: the ``matplotlib.axes.Axes`` instance + x: the start horizontal position + + Returns: + the total width occupied + ''' + x_start = x + h = __CIRCUIT_PLOT_PARAM['circuit_height'] + w = __CIRCUIT_PLOT_PARAM['scale'] * gate.gate_info['plot_width'] + for _ in range(gate.depth): + for act_qubits in gate.qubits_idx: + x_c = x + 0.5 * w + _patch_display(ax, x_c, act_qubits[0]*h, mode='.') + _patch_display(ax, x_c, act_qubits[1]*h, mode='+') + _vertical_line_display(ax, x_c, act_qubits[0]*h, act_qubits[1]*h) + x += w + return x - x_start + + +def _swap_display(gate, ax: matplotlib.axes.Axes, x: float,) -> float: + r'''The display function for ``swap`` like gate. + + Args: + gate: the ``paddle_quantum.gate.Gate`` instance + ax: the ``matplotlib.axes.Axes`` instance + x: the start horizontal position + + Returns: + the total width occupied + ''' + x_start = x + h = __CIRCUIT_PLOT_PARAM['circuit_height'] + w = __CIRCUIT_PLOT_PARAM['scale'] * gate.gate_info['plot_width'] + for _ in range(gate.depth): + for act_qubits in gate.qubits_idx: + x_c = x + 0.5 * w + _patch_display(ax, x_c, act_qubits[0]*h, mode='x') + _patch_display(ax, x_c, act_qubits[1]*h, mode='x') + _vertical_line_display(ax, x_c, act_qubits[0]*h, act_qubits[1]*h) + x += w + return x - x_start + + +def _cswap_display(gate, ax: matplotlib.axes.Axes, x: float,) -> float: + r'''The display function for ``cswap`` like gate. + + Args: + gate: the ``paddle_quantum.gate.Gate`` instance + ax: the ``matplotlib.axes.Axes`` instance + x: the start horizontal position + + Returns: + the total width occupied + ''' + x_start = x + h = __CIRCUIT_PLOT_PARAM['circuit_height'] + w = __CIRCUIT_PLOT_PARAM['scale'] * gate.gate_info['plot_width'] + + for _ in range(gate.depth): + for act_qubits in gate.qubits_idx: + x_c = x + 0.5 * w + _patch_display(ax, x_c, act_qubits[0]*h, mode='.') + _patch_display(ax, x_c, act_qubits[1]*h, mode='x') + _patch_display(ax, x_c, act_qubits[2]*h, mode='x') + _vertical_line_display(ax, x_c, min(act_qubits)*h, max(act_qubits)*h) + x += w + return x - x_start + + +def _tofolli_display(gate, ax: matplotlib.axes.Axes, x: float,) -> float: + r'''The display function for ``tofolli`` like gate. + + Args: + gate: the ``paddle_quantum.gate.Gate`` instance + ax: the ``matplotlib.axes.Axes`` instance + x: the start horizontal position + + Returns: + the total width occupied + ''' + x_start = x + h = __CIRCUIT_PLOT_PARAM['circuit_height'] + w = __CIRCUIT_PLOT_PARAM['scale'] * gate.gate_info['plot_width'] + + for _ in range(gate.depth): + for act_qubits in gate.qubits_idx: + x_c = x + 0.5 * w + _patch_display(ax, x_c, act_qubits[0]*h, mode='.') + _patch_display(ax, x_c, act_qubits[1]*h, mode='.') + _patch_display(ax, x_c, act_qubits[2]*h, mode='+') + _vertical_line_display(ax, x_c, min(act_qubits)*h, max(act_qubits)*h) + x += w + return x - x_start + + +def _linear_entangled_layer_display(gate, ax: matplotlib.axes.Axes, x: float,) -> float: + r'''The display function for ``linear entangled layer`` gate. + + Args: + gate: the ``paddle_quantum.gate.Gate`` instance + ax: the ``matplotlib.axes.Axes`` instance + x: the start horizontal position + + Returns: + the total width occupied + ''' + x_start = x + h = __CIRCUIT_PLOT_PARAM['circuit_height'] + block_w = __CIRCUIT_PLOT_PARAM['scale'] * gate.gate_info['plot_width'] + dot_w = __CIRCUIT_PLOT_PARAM['node_width'] + + for depth in range(gate.depth): + for param_idx, act_qubits in enumerate(gate.qubits_idx): # `ry` layer + _single_qubit_gate_display(ax, x, act_qubits*h, h, block_w, + f'$R_y({float(gate.theta[depth][param_idx][0]):.2f})$') + x += block_w + + for idx in range(len(gate.qubits_idx)-1): # `cnot` layer + act_qubits = [gate.qubits_idx[idx], gate.qubits_idx[idx + 1]] + x_c = x + 0.5 * dot_w + _patch_display(ax, x_c, act_qubits[0]*h, mode='.') + _patch_display(ax, x_c, act_qubits[1]*h, mode='+') + _vertical_line_display(ax, x_c, act_qubits[0]*h, act_qubits[1]*h) + x += dot_w + + for param_idx, act_qubits in enumerate(gate.qubits_idx): # `rz` layer + _single_qubit_gate_display(ax, x, act_qubits*h, h, block_w, + f'$R_z({float(gate.theta[depth][param_idx][1]):.2f})$') + x += block_w + + for idx in range(len(gate.qubits_idx)-1): # `cnot` layer + act_qubits = [gate.qubits_idx[idx], gate.qubits_idx[idx + 1]] + x_c = x + 0.5 * dot_w + _patch_display(ax, x_c, act_qubits[0]*h, mode='.') + _patch_display(ax, x_c, act_qubits[1]*h, mode='+') + _vertical_line_display(ax, x_c, act_qubits[0]*h, act_qubits[1]*h) + x += dot_w + return x - x_start + + +def _cr_entangled_layer_display(gate, ax: matplotlib.axes.Axes, x: float,) -> float: + r'''The display function for ``complex or real entangled layer`` gate. + + Args: + gate: the ``paddle_quantum.gate.Gate`` instance + ax: the ``matplotlib.axes.Axes`` instance + x: the start horizontal position + + Returns: + the total width occupied + ''' + tex_name = gate.gate_info['texname'] + x_start = x + h = __CIRCUIT_PLOT_PARAM['circuit_height'] + block_w = __CIRCUIT_PLOT_PARAM['scale'] * gate.gate_info['plot_width'] + dot_w = __CIRCUIT_PLOT_PARAM['node_width'] + + if tex_name == '$REntLayer$': # define the tex name generator for deferent gates + def _name_generator(theta): + return f'$R_y({float(theta):.2f})$' + elif tex_name == '$CEntLayer$': + def _name_generator(theta): + name = '$U(' + for value in theta: + name += f'{float(value):.2f},' + name = name.strip(',') + name += ')$' + return name + + for depth in range(gate.depth): + for param_idx, act_qubits in enumerate(gate.qubits_idx): + _single_qubit_gate_display(ax, x, act_qubits*h, h, block_w, + _name_generator(gate.theta[depth][param_idx])) + x += block_w + for idx in range(len(gate.qubits_idx)): + act_qubits = [gate.qubits_idx[idx], gate.qubits_idx[(idx + 1) % len(gate.qubits_idx)]] + x_c = x + 0.5 * dot_w + _patch_display(ax, x_c, act_qubits[0]*h, mode='.') + _patch_display(ax, x_c, act_qubits[1]*h, mode='+') + _vertical_line_display(ax, x_c, act_qubits[0]*h, act_qubits[1]*h) + x += dot_w + return x - x_start + + +def _cr_block_layer_display(gate, ax: matplotlib.axes.Axes, x: float,) -> float: + r'''The display function for ``complex or real block layer`` gate. + + Args: + gate: the ``paddle_quantum.gate.Gate`` instance + ax: the ``matplotlib.axes.Axes`` instance + x: the start horizontal position + + Returns: + the total width occupied + ''' + x_start = x + h = __CIRCUIT_PLOT_PARAM['circuit_height'] + block_w = __CIRCUIT_PLOT_PARAM['scale'] * gate.gate_info['plot_width'] + tex_name = gate.gate_info['texname'] + dot_w = __CIRCUIT_PLOT_PARAM['node_width'] + + if tex_name == '$RBLayer$': + def _add_block(ax, x, theta, pos): # add a block including 4 `ry` and 1 `cnot` + _single_qubit_gate_display(ax, x, pos[0]*h, h, block_w, + tex_name=f'$R_y({float(theta[0]):.2f})$') + _single_qubit_gate_display(ax, x, pos[1]*h, h, block_w, + tex_name=f'$R_y({float(theta[1]):.2f})$') + _single_qubit_gate_display(ax, x+block_w+dot_w, pos[0]*h, h, block_w, + tex_name=f'$R_y({float(theta[2]):.2f})$') + _single_qubit_gate_display(ax, x+block_w+dot_w, pos[1]*h, h, block_w, + tex_name=f'$R_y({float(theta[3]):.2f})$') + _patch_display(ax, x+block_w+0.5*dot_w, pos[0]*h, mode='.') + _patch_display(ax, x+block_w+0.5*dot_w, pos[1]*h, mode='+') + _vertical_line_display(ax, x+block_w+0.5*dot_w, pos[0]*h, pos[1]*h) + + elif tex_name == '$CBLayer$': + def _add_block(ax, x, theta, pos,): # add a block including 4 `u3` and 1 `cnot` + _single_qubit_gate_display(ax, x, pos[0]*h, h, block_w, + tex_name=f'$U({float(theta[0]):.2f},\ + {float(theta[1]):.2f},{float(theta[2]):.2f})$') + _single_qubit_gate_display(ax, x, pos[1]*h, h, block_w, + tex_name=f'$U({float(theta[3]):.2f},\ + {float(theta[4]):.2f},{float(theta[5]):.2f})$') + _single_qubit_gate_display(ax, x+block_w+dot_w, pos[0]*h, h, block_w, + tex_name=f'$U({float(theta[6]):.2f},\ + {float(theta[7]):.2f},{float(theta[8]):.2f})$') + _single_qubit_gate_display(ax, x+block_w+dot_w, pos[1]*h, h, block_w, + tex_name=f'$U({float(theta[9]):.2f},\ + {float(theta[10]):.2f},{float(theta[11]):.2f})$') + _patch_display(ax, x+block_w+0.5*dot_w, pos[0]*h, mode='.') + _patch_display(ax, x+block_w+0.5*dot_w, pos[1]*h, mode='+') + _vertical_line_display(ax, x+block_w+0.5*dot_w, pos[0]*h, pos[1]*h) + + def _get_display_layer(): # arrange the order of block and compress + display_layer = [] + num_theta_layer = [0, 0] + act_qubits = gate.qubits_idx + for layer in range(2): + indices = [] + for i in range(1, len(act_qubits), 2): + indices.append([act_qubits[i-1], act_qubits[i]]) + while len(indices) > 0: + indcs_list = [indices.pop(0)] + num_theta_layer[layer] += 1 + for _ in range(len(indices)): + candidate = indices.pop(0) + if all(_not_exist_intersection(indcs, candidate) for indcs in indcs_list): + indcs_list.append(candidate) + else: + indices.append(candidate) + display_layer.append(indcs_list) + act_qubits = act_qubits[1:] + return display_layer, num_theta_layer + + def _add_layer(ax, x, theta, pos_list,): # add block into layer + plotted_list = [] + for pos in pos_list: + _add_block(ax, x, theta[int((gate.qubits_idx.index(pos[0])) / 2)], pos,) + plotted_list.extend(list(range(min(pos), max(pos)+1))) + + display_layer, num_theta_layer = _get_display_layer() # get layers + for depth in range(gate.depth): + for num_theta, layer in enumerate(display_layer): + if num_theta < num_theta_layer[0]: # get parameters + _add_layer(ax, x, gate.theta[depth, :int((len(gate.qubits_idx)) / 2)], layer) + else: + _add_layer(ax, x, gate.theta[depth, int((len(gate.qubits_idx)) / 2):], layer) + x += 2 * block_w + dot_w + return x - x_start + + +def _qaoa_layer_display(gate, ax: matplotlib.axes.Axes, x: float,) -> float: + r'''The display function for ``qaoa layer`` gate. + + Args: + gate: the ``paddle_quantum.gate.Gate`` instance + ax: the ``matplotlib.axes.Axes`` instance + x: the start horizontal position + + Returns: + the total width occupied + ''' + + x_start = x + h = __CIRCUIT_PLOT_PARAM['circuit_height'] + block_w = __CIRCUIT_PLOT_PARAM['scale'] * gate.gate_info['plot_width'] + dot_w = __CIRCUIT_PLOT_PARAM['node_width'] + + def _get_display_layer(): # arrange the order of block and compress + indices = gate.edges + display_layer = [] + while len(indices) > 0: + indcs_list = [indices.pop(0)] + for _ in range(len(indices)): + candidate = indices.pop(0) + if all(_not_exist_intersection(indcs, candidate) for indcs in indcs_list): + indcs_list.append(candidate) + else: + indices.append(candidate) + display_layer.append(indcs_list) + return display_layer + + def _add_block(ax, x, theta, pos): # add a block including 2 `cnot` and 1 `rz` + _single_qubit_gate_display(ax, x+dot_w, pos[1]*h, h, block_w, tex_name=f'$R_z({float(theta):.2f})$') + _patch_display(ax, x+0.5*dot_w, pos[0]*h, mode='.') + _patch_display(ax, x+0.5*dot_w, pos[1]*h, mode='+') + _vertical_line_display(ax, x+0.5*dot_w, pos[0]*h, pos[1]*h) + _patch_display(ax, x+block_w+1.5*dot_w, pos[0]*h, mode='.') + _patch_display(ax, x+block_w+1.5*dot_w, pos[1]*h, mode='+') + _vertical_line_display(ax, x+block_w+1.5*dot_w, pos[0]*h, pos[1]*h) + + def _add_layer(axis, x, theta, pos_list): # add block into layer + plotted_list = [] + for pos in pos_list: + _add_block(axis, x, theta, pos) + plotted_list.extend(list(range(min(pos), max(pos)+1))) + + x_start = x + gamma = gate.theta[:gate.depth] + beta = gate.theta[gate.depth:] + display_layer = _get_display_layer() + + for depth in range(gate.depth): + for layer in display_layer: + _add_layer(ax, x, gamma[depth], layer) + x += block_w + 2 * dot_w + for y in gate.nodes: + _single_qubit_gate_display(ax, x, y*h, h, block_w, tex_name=f'$R_x({float(beta[depth]):.2f})$') + x += block_w + return x - x_start diff --git a/paddle_quantum/gate/layer.py b/paddle_quantum/gate/layer.py index 456843c..9dcf9df 100644 --- a/paddle_quantum/gate/layer.py +++ b/paddle_quantum/gate/layer.py @@ -25,7 +25,8 @@ from paddle_quantum.intrinsic import _get_float_dtype from .base import Gate from typing import Iterable, List, Union, Tuple, Dict - +import matplotlib +from .functional.visual import ( _linear_entangled_layer_display, _cr_block_layer_display, _qaoa_layer_display,_cr_entangled_layer_display) def qubits_idx_filter(qubits_idx: Union[Iterable[int], str], num_qubits: int) -> List[Iterable[int]]: r"""Check the validity of ``qubits_idx`` and ``num_qubits``. @@ -64,7 +65,11 @@ def __init__( ): super().__init__(depth) self.qubits_idx = qubits_idx_filter(qubits_idx, num_qubits) - self.gate_name = 'SupLayer' + self.gate_info = { + 'gatename': 'SupLayer', + 'texname': r'$H$', + 'plot_width': 0.4, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: for _ in range(0, self.depth): @@ -79,6 +84,9 @@ def gate_history_generation(self): gate_info = {'gate': 'h', 'which_qubits': qubit_idx, 'theta': None} gate_history.append(gate_info) self.gate_history = gate_history + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return super().display_in_circuit(ax, x) @@ -95,7 +103,11 @@ def __init__( ): super().__init__(depth) self.qubits_idx = qubits_idx_filter(qubits_idx, num_qubits) - self.gate_name = 'WSupLayer' + self.gate_info = { + 'gatename': 'WSupLayer', + 'texname': r'$R_y(\pi/4)$', + 'plot_width': 0.9, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: theta = paddle.to_tensor([np.pi / 4]) @@ -112,6 +124,9 @@ def gate_history_generation(self): gate_history.append(gate_info) self.gate_history = gate_history + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return super().display_in_circuit(ax, x) + class LinearEntangledLayer(Gate): r"""Linear entangled layers consisting of Ry gates, Rz gates, and CNOT gates. @@ -136,7 +151,11 @@ def __init__( default_initializer=initializer ) self.add_parameter('theta', theta) - self.gate_name = 'LEntLayer' + self.gate_info = { + 'gatename': 'LEntLayer', + 'texname': r'$LEntLayer$', + 'plot_width': 0.9, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: for depth_idx in range(0, self.depth): @@ -171,6 +190,9 @@ def gate_history_generation(self): gate_history.append({'gate': 'cnot', 'which_qubits': [qubits_idx[idx], qubits_idx[idx + 1]], 'theta': None}) self.gate_history = gate_history + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _linear_entangled_layer_display(self, ax, x) + class RealEntangledLayer(Gate): r"""Strongly entangled layers consisting of Ry gates and CNOT gates. @@ -200,7 +222,11 @@ def __init__( default_initializer=initializer ) self.add_parameter('theta', theta) - self.gate_name = 'REntLayer' + self.gate_info = { + 'gatename': 'REntLayer', + 'texname': r'$REntLayer$', + 'plot_width': 0.9, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: for depth_idx in range(0, self.depth): @@ -227,6 +253,11 @@ def gate_history_generation(self): 'theta': None }) self.gate_history = gate_history + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _cr_entangled_layer_display(self, ax, x) + + class ComplexEntangledLayer(Gate): @@ -256,7 +287,11 @@ def __init__( default_initializer=initializer ) self.add_parameter('theta', theta) - self.gate_name = 'CEntLayer' + self.gate_info = { + 'gatename': 'CEntLayer', + 'texname': r'$CEntLayer$', + 'plot_width': 1.65, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: for depth_idx in range(0, self.depth): @@ -284,6 +319,10 @@ def gate_history_generation(self): }) self.gate_history = gate_history + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _cr_entangled_layer_display(self, ax, x) + + class RealBlockLayer(Gate): r"""Weakly entangled layers consisting of Ry gates and CNOT gates. @@ -313,7 +352,11 @@ def __init__( default_initializer=initializer ) self.add_parameter('theta', theta) - self.gate_name = 'RBLayer' + self.gate_info = { + 'gatename': 'RBLayer', + 'texname': r'$RBLayer$', + 'plot_width': 0.9, + } def __add_real_block(self, theta: paddle.Tensor, position: List[int]) -> None: assert len(theta) == 4, 'the length of theta is not right' @@ -379,6 +422,9 @@ def gate_history_generation(self): self.__add_real_layer(self.theta[depth_idx, int((n - 1) / 2):], [1, n - 1]) self.count_history = False + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _cr_block_layer_display(self, ax, x) + class ComplexBlockLayer(Gate): r"""Weakly entangled layers consisting of single-qubit rotation gates and CNOT gates. @@ -406,7 +452,11 @@ def __init__(self, qubits_idx: Union[Iterable[int], str] = 'full', num_qubits: i default_initializer=initializer ) self.add_parameter('theta', theta) - self.gate_name = 'CBLayer' + self.gate_info = { + 'gatename': 'CBLayer', + 'texname': r'$CBLayer$', + 'plot_width': 1.65, + } def __add_complex_block(self, theta: paddle.Tensor, position: List[int]) -> None: assert len(theta) == 12, 'the length of theta is not right' @@ -474,6 +524,9 @@ def gate_history_generation(self): self.__add_complex_layer(self.theta[depth_idx, :int((n - 1) / 2)], [0, n - 2]) self.__add_complex_layer(self.theta[depth_idx, int((n - 1) / 2):], [1, n - 1]) self.count_history = False + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _cr_block_layer_display(self, ax, x) class QAOALayer(Gate): @@ -503,7 +556,11 @@ def __init__( default_initializer=paddle.nn.initializer.Uniform(low=0, high=2 * math.pi) ) self.add_parameter('theta', theta) - self.gate_name = 'QAOALayer' + self.gate_info = { + 'gatename': 'QAOALayer', + 'texname': r'$QAOALayer$', + 'plot_width': 0.9, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: gamma = self.theta[:self.depth] @@ -529,6 +586,8 @@ def gate_history_generation(self): for node in self.nodes: gate_history.append({'gate': 'rx', 'which_qubits': node, 'theta': beta[depth_idx]}) + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _qaoa_layer_display(self, ax, x) class QAOALayerWeighted(Gate): r""" QAOA driving layers with weights @@ -556,6 +615,12 @@ def __init__( ) self.add_parameter('theta', theta) self.gate_history_generation() + self.gate_info = { + 'gatename': 'WQAOALayer', + 'texname': r'$WQAOALayer$', + 'plot_width': 0.9, + } + def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: gamma = self.theta[:self.depth] @@ -581,4 +646,11 @@ def gate_history_generation(self): gate_history.append({'gate': 'cnot', 'which_qubits': [node0, node1], 'theta': None}) for node in self.nodes: gate_history.append({'gate': 'rx', 'which_qubits': node, 'theta': beta[depth_idx]}) - \ No newline at end of file + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _qaoa_layer_display(self, ax, x) + + + + + diff --git a/paddle_quantum/gate/multi_qubit_gate.py b/paddle_quantum/gate/multi_qubit_gate.py index 6161389..22b7bde 100644 --- a/paddle_quantum/gate/multi_qubit_gate.py +++ b/paddle_quantum/gate/multi_qubit_gate.py @@ -26,7 +26,9 @@ from ..backend import Backend from ..intrinsic import _format_qubits_idx, _get_float_dtype from typing import Optional, Union, Iterable - +from .functional.visual import (_cnot_display, _cswap_display, _tofolli_display, _swap_display, + _cx_like_display, _crx_like_display, _oracle_like_display, _rxx_like_display) +import matplotlib class CNOT(Gate): r"""A collection of CNOT gates. @@ -54,7 +56,11 @@ class CNOT(Gate): def __init__(self, qubits_idx: Optional[Union[Iterable, str]] = 'cycle', num_qubits: Optional[int] = None, depth: Optional[int] = 1): super().__init__(depth) self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, num_acted_qubits=2) - self.gate_name = 'cnot' + self.gate_info = { + 'gatename': 'cnot', + 'texname': r'$CNOT$', + 'plot_width': 0.2, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -68,6 +74,10 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: for qubits_idx in self.qubits_idx: state = functional.cnot(state, qubits_idx, self.dtype, self.backend) return state + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _cnot_display(self, ax, x,) + class CX(Gate): @@ -82,7 +92,11 @@ def __init__(self, qubits_idx: Optional[Union[Iterable, str]] = 'cycle', num_qubits: Optional[int] = None, depth: Optional[int] = 1): super().__init__(depth) self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, num_acted_qubits=2) - self.gate_name = 'cnot' + self.gate_info = { + 'gatename': 'cnot', + 'texname': r'$CNOT$', + 'plot_width': 0.2, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -96,6 +110,10 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: for qubits_idx in self.qubits_idx: state = functional.cx(state, qubits_idx, self.dtype, self.backend) return state + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _cnot_display(self, ax, x,) + class CY(Gate): @@ -125,7 +143,11 @@ def __init__(self, qubits_idx: Optional[Union[Iterable, str]] = 'cycle', num_qubits: Optional[int] = None, depth: Optional[int] = 1): super().__init__(depth) self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, num_acted_qubits=2) - self.gate_name = 'cy' + self.gate_info = { + 'gatename': 'cy', + 'texname': r'$Y$', + 'plot_width': 0.4, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -139,6 +161,9 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: for qubits_idx in self.qubits_idx: state = functional.cy(state, qubits_idx, self.dtype, self.backend) return state + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _cx_like_display(self, ax, x,) class CZ(Gate): @@ -168,7 +193,11 @@ def __init__(self, qubits_idx: Optional[Union[Iterable, str]] = 'cycle', num_qubits: Optional[int] = None, depth: Optional[int] = 1): super().__init__(depth) self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, num_acted_qubits=2) - self.gate_name = 'cz' + self.gate_info = { + 'gatename': 'cz', + 'texname': r'$Z$', + 'plot_width': 0.4, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -182,6 +211,9 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: for qubits_idx in self.qubits_idx: state = functional.cz(state, qubits_idx, self.dtype, self.backend) return state + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _cx_like_display(self, ax, x) class SWAP(Gate): @@ -210,7 +242,11 @@ def __init__(self, qubits_idx: Optional[Union[Iterable, str]] = 'cycle', num_qubits: Optional[int] = None, depth: Optional[int] = 1): super().__init__(depth) self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, num_acted_qubits=2) - self.gate_name = 'swap' + self.gate_info = { + 'gatename': 'swap', + 'texname': r'$SWAP$', + 'plot_width': 0.2, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -225,6 +261,9 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state = functional.swap(state, qubits_idx, self.dtype, self.backend) return state + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _swap_display(self, ax, x,) + class CP(ParamGate): r"""A collection of controlled P gates. @@ -260,7 +299,11 @@ def __init__( param_shape = [depth, 1 if param_sharing else len(self.qubits_idx)] self.theta_generation(param, param_shape) - self.gate_name = 'cp' + self.gate_info = { + 'gatename': 'cp', + 'texname': r'$P$', + 'plot_width': 0.9, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -275,6 +318,9 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state, self.theta[depth_idx, param_idx], qubit_idx, self.dtype, self.backend) return state + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _crx_like_display(self, ax, x) + class CRX(ParamGate): r"""A collection of controlled rotation gates about the x-axis. @@ -314,7 +360,11 @@ def __init__( param_shape = [depth, 1 if param_sharing else len(self.qubits_idx)] self.theta_generation(param, param_shape) - self.gate_name = 'crx' + self.gate_info = { + 'gatename': 'crx', + 'texname': r'$R_{x}$', + 'plot_width': 0.9, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -345,6 +395,9 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state, self.theta[depth_idx, param_idx], qubit_idx, self.dtype, self.backend) return state + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _crx_like_display(self, ax, x) + class CRY(ParamGate): r"""A collection of controlled rotation gates about the y-axis. @@ -384,7 +437,11 @@ def __init__( param_shape = [depth, 1 if param_sharing else len(self.qubits_idx)] self.theta_generation(param, param_shape) - self.gate_name = 'cry' + self.gate_info = { + 'gatename': 'cry', + 'texname': r'$R_{y}$', + 'plot_width': 0.9, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -414,6 +471,9 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state = functional.cry( state, self.theta[depth_idx, param_idx], qubit_idx, self.dtype, self.backend) return state + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _crx_like_display(self, ax, x,) class CRZ(ParamGate): @@ -454,7 +514,11 @@ def __init__( param_shape = [depth, 1 if param_sharing else len(self.qubits_idx)] self.theta_generation(param, param_shape) - self.gate_name = 'crz' + self.gate_info = { + 'gatename': 'crz', + 'texname': r'$R_{z}$', + 'plot_width': 0.9, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -484,6 +548,9 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state = functional.crz( state, self.theta[depth_idx, param_idx], qubit_idx, self.dtype, self.backend) return state + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _crx_like_display(self, ax, x) class CU(ParamGate): @@ -527,7 +594,11 @@ def __init__( else: param_shape = [depth, len(self.qubits_idx), 3] self.theta_generation(param, param_shape) - self.gate_name = 'cu' + self.gate_info = { + 'gatename': 'cu', + 'texname': r'$U$', + 'plot_width': 1.65, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -557,6 +628,9 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state = functional.cu( state, self.theta[depth_idx, param_idx], qubit_idx, self.dtype, self.backend) return state + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _crx_like_display(self, ax, x) class RXX(ParamGate): @@ -596,7 +670,11 @@ def __init__( param_shape = [depth, 1 if param_sharing else len(self.qubits_idx)] self.theta_generation(param, param_shape) - self.gate_name = 'rxx' + self.gate_info = { + 'gatename': 'rxx', + 'texname': r'$R_{xx}$', + 'plot_width': 1.0, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -611,6 +689,9 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state, self.theta[depth_idx, param_idx], qubit_idx, self.dtype, self.backend) return state + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _rxx_like_display(self, ax, x) + class RYY(ParamGate): r"""A collection of RYY gates. @@ -649,7 +730,11 @@ def __init__( param_shape = [depth, 1 if param_sharing else len(self.qubits_idx)] self.theta_generation(param, param_shape) - self.gate_name = 'ryy' + self.gate_info = { + 'gatename': 'ryy', + 'texname': r'$R_{yy}$', + 'plot_width': 1.0, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -663,7 +748,9 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state = functional.ryy( state, self.theta[depth_idx, param_idx], qubit_idx, self.dtype, self.backend) return state - + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _rxx_like_display(self, ax, x) class RZZ(ParamGate): r"""A collection of RZZ gates. @@ -702,7 +789,11 @@ def __init__( param_shape = [depth, 1 if param_sharing else len(self.qubits_idx)] self.theta_generation(param, param_shape) - self.gate_name = 'rzz' + self.gate_info = { + 'gatename': 'rzz', + 'texname': r'$R_{zz}$', + 'plot_width': 1.0, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -717,6 +808,8 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state, self.theta[depth_idx, param_idx], qubit_idx, self.dtype, self.backend) return state + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _rxx_like_display(self, ax, x) class MS(Gate): r"""A collection of Mølmer-Sørensen (MS) gates for trapped ion devices. @@ -743,7 +836,11 @@ class MS(Gate): def __init__(self, qubits_idx: Optional[Union[Iterable, str]] = 'cycle', num_qubits: Optional[int] = None, depth: Optional[int] = 1): super().__init__(depth) self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, num_acted_qubits=2) - self.gate_name = 'ms' + self.gate_info = { + 'gatename': 'ms', + 'texname': r'$MS$', + 'plot_width': 0.6, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -753,6 +850,8 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state = functional.ms(state, qubits_idx, self.dtype, self.backend) return state + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _oracle_like_display(self, ax, x) class CSWAP(Gate): r"""A collection of CSWAP (Fredkin) gates. @@ -783,7 +882,11 @@ class CSWAP(Gate): def __init__(self, qubits_idx: Optional[Union[Iterable, str]] = 'cycle', num_qubits: Optional[int] = None, depth: Optional[int] = 1): super().__init__(depth) self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, num_acted_qubits=3) - self.gate_name = 'cswap' + self.gate_info = { + 'gatename': 'cswap', + 'texname': r'$CSWAP$', + 'plot_width': 0.2, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -798,6 +901,9 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state = functional.cswap(state, qubits_idx, self.dtype, self.backend) return state + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _cswap_display(self, ax, x) + class Toffoli(Gate): r"""A collection of Toffoli gates. @@ -827,7 +933,11 @@ class Toffoli(Gate): def __init__(self, qubits_idx: Optional[Union[Iterable, str]] = 'cycle', num_qubits: Optional[int] = None, depth: Optional[int] = 1): super().__init__(depth) self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, num_acted_qubits=3) - self.gate_name = 'ccx' + self.gate_info = { + 'gatename': 'ccx', + 'texname': r'$Toffoli$', + 'plot_width': 0.2, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -842,6 +952,9 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state = functional.toffoli(state, qubits_idx, self.dtype, self.backend) return state + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _tofolli_display(self, ax, x,) + class UniversalTwoQubits(ParamGate): r"""A collection of universal two-qubit gates. One of such a gate requires 15 parameters. @@ -869,7 +982,11 @@ def __init__( else: param_shape = [depth, len(self.qubits_idx), 15] self.theta_generation(param, param_shape) - self.gate_name = 'uni2' + self.gate_info = { + 'gatename': 'uni2', + 'texname': r'$U$', + 'plot_width': 0.6, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -884,6 +1001,9 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state = functional.universal_two_qubits( state, self.theta[depth_idx, param_idx], qubit_idx, self.dtype, self.backend) return state + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _oracle_like_display(self, ax, x) class UniversalThreeQubits(ParamGate): @@ -912,7 +1032,11 @@ def __init__( else: param_shape = [depth, len(self.qubits_idx), 81] self.theta_generation(param, param_shape) - self.gate_name = 'uni3' + self.gate_info = { + 'gatename': 'uni3', + 'texname': r'$U$', + 'plot_width': 0.6, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -927,3 +1051,6 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state = functional.universal_three_qubits( state, self.theta[depth_idx, param_idx], qubit_idx, self.dtype, self.backend) return state + + def display_in_circuit(self, ax: matplotlib.axes.Axes, x: float,) -> float: + return _oracle_like_display(self, ax, x) diff --git a/paddle_quantum/gate/single_qubit_gate.py b/paddle_quantum/gate/single_qubit_gate.py index 6dc02fd..c50986f 100644 --- a/paddle_quantum/gate/single_qubit_gate.py +++ b/paddle_quantum/gate/single_qubit_gate.py @@ -28,7 +28,6 @@ from paddle_quantum.intrinsic import _format_qubits_idx, _get_float_dtype from typing import Optional, List, Union, Iterable - class H(Gate): r"""A collection of single-qubit Hadamard gates. @@ -50,7 +49,11 @@ class H(Gate): def __init__(self, qubits_idx: Optional[Union[Iterable, int, str]] = 'full', num_qubits: Optional[int] = None, depth: Optional[int] = 1): super().__init__(depth) self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - self.gate_name = 'h' + self.gate_info = { + 'gatename': 'h', + 'texname': '$H$', + 'plot_width': 0.4, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -87,7 +90,11 @@ class S(Gate): def __init__(self, qubits_idx: Optional[Union[Iterable, int, str]] = 'full', num_qubits: Optional[int] = None, depth: Optional[int] = 1): super().__init__(depth) self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - self.gate_name = 's' + self.gate_info = { + 'gatename': 's', + 'texname': '$S$', + 'plot_width': 0.4, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -102,6 +109,45 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state = functional.s(state, qubit_idx, self.dtype, self.backend) return state +class Sdg(Gate): + r"""A collection of single-qubit S dagger (S inverse) gates. + + The matrix form of such a gate is: + + .. math:: + + S^\dagger = + \begin{bmatrix} + 1&0\\ + 0&-i + \end{bmatrix} + + Args: + qubits_idx: Indices of the qubits on which the gates are applied. Defaults to ``'full'``. + num_qubits: Total number of qubits. Defaults to ``None``. + depth: Number of layers. Defaults to ``1``. + """ + def __init__(self, qubits_idx: Optional[Union[Iterable, int, str]] = 'full', num_qubits: Optional[int] = None, depth: Optional[int] = 1): + super().__init__(depth) + self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) + self.gate_info = { + 'gatename': 'sdg', + 'texname': r'$S^\dagger$', + 'plot_width': 0.4, + } + + def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: + if self.backend == Backend.QuLeaf and state.backend == Backend.Quleaf: + state.gate_history.append({ + 'gate_name': 'sdg', + 'qubits_idx': copy.deepcopy(self.qubits_idx), + 'depth': self.depth, + }) + return state + for _ in range(0, self.depth): + for qubit_idx in self.qubits_idx: + state = functional.sdg(state, qubit_idx, self.dtype, self.backend) + return state class T(Gate): r"""A collection of single-qubit T gates. @@ -124,7 +170,11 @@ class T(Gate): def __init__(self, qubits_idx: Optional[Union[Iterable, int, str]] = 'full', num_qubits: Optional[int] = None, depth: Optional[int] = 1): super().__init__(depth) self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - self.gate_name = 't' + self.gate_info = { + 'gatename': 't', + 'texname': '$T$', + 'plot_width': 0.4, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -139,7 +189,44 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state = functional.t(state, qubit_idx, self.dtype, self.backend) return state +class Tdg(Gate): + r"""A collection of single-qubit T dagger (T inverse) gates. + The matrix form of such a gate is: + + .. math:: + + T^\dagger = + \begin{bmatrix} + 1&0\\ + 0&e^{-\frac{i\pi}{4}} + \end{bmatrix} + + Args: + qubits_idx: Indices of the qubits on which the gates are applied. Defaults to ``'full'``. + num_qubits: Total number of qubits. Defaults to ``None``. + depth: Number of layers. Defaults to ``1``. + """ + def __init__(self, qubits_idx: Optional[Union[Iterable, int, str]] = 'full', num_qubits: Optional[int] = None, depth: Optional[int] = 1): + super().__init__(depth) + self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) + self.gate_info = { + 'gatename': 'tdg', + 'texname': r'$T^\dagger$', + 'plot_width': 0.4, + } + def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: + if self.backend == Backend.QuLeaf and state.backend == Backend.Quleaf: + state.gate_history.append({ + 'gate_name': 'tdg', + 'qubits_idx': copy.deepcopy(self.qubits_idx), + 'depth': self.depth, + }) + return state + for _ in range(0, self.depth): + for qubit_idx in self.qubits_idx: + state = functional.tdg(state, qubit_idx, self.dtype, self.backend) + return state class X(Gate): r"""A collection of single-qubit X gates. @@ -160,7 +247,11 @@ class X(Gate): def __init__(self, qubits_idx: Optional[Union[Iterable, int, str]] = 'full', num_qubits: Optional[int] = None, depth: Optional[int] = 1): super().__init__(depth) self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - self.gate_name = 'x' + self.gate_info = { + 'gatename': 'x', + 'texname': '$X$', + 'plot_width': 0.4, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -174,6 +265,7 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: for qubit_idx in self.qubits_idx: state = functional.x(state, qubit_idx, self.dtype, self.backend) return state + class Y(Gate): @@ -196,7 +288,11 @@ class Y(Gate): def __init__(self, qubits_idx: Optional[Union[Iterable, int, str]] = 'full', num_qubits: Optional[int] = None, depth: Optional[int] = 1): super().__init__(depth) self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - self.gate_name = 'y' + self.gate_info = { + 'gatename': 'y', + 'texname': '$Y$', + 'plot_width': 0.4, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -212,6 +308,7 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: return state + class Z(Gate): r"""A collection of single-qubit Z gates. @@ -232,7 +329,11 @@ class Z(Gate): def __init__(self, qubits_idx: Optional[Union[Iterable, int, str]] = 'full', num_qubits: Optional[int] = None, depth: Optional[int] = 1): super().__init__(depth) self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits) - self.gate_name = 'z' + self.gate_info = { + 'gatename': 'z', + 'texname': '$Z$', + 'plot_width': 0.4, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -280,7 +381,11 @@ def __init__( param_shape = [depth, 1 if param_sharing else len(self.qubits_idx)] self.theta_generation(param, param_shape) - self.gate_name = 'p' + self.gate_info = { + 'gatename': 'p', + 'texname': '$P$', + 'plot_width': 0.9, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -296,6 +401,7 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: return state + class RX(ParamGate): r"""A collection of single-qubit rotation gates about the x-axis. @@ -328,7 +434,11 @@ def __init__( param_shape = [depth, 1 if param_sharing else len(self.qubits_idx)] self.theta_generation(param, param_shape) - self.gate_name = 'rx' + self.gate_info = { + 'gatename': 'rx', + 'texname': r'$R_{x}$', + 'plot_width': 0.9, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -358,6 +468,7 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state = functional.rx( state, self.theta[depth_idx, param_idx], qubit_idx, self.dtype, self.backend) return state + class RY(ParamGate): @@ -392,7 +503,11 @@ def __init__( param_shape = [depth, 1 if param_sharing else len(self.qubits_idx)] self.theta_generation(param, param_shape) - self.gate_name = 'ry' + self.gate_info = { + 'gatename': 'ry', + 'texname': r'$R_{y}$', + 'plot_width': 0.9, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -422,6 +537,8 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state = functional.ry( state, self.theta[depth_idx, param_idx], qubit_idx, self.dtype, self.backend) return state + + class RZ(ParamGate): @@ -456,7 +573,11 @@ def __init__( param_shape = [depth, 1 if param_sharing else len(self.qubits_idx)] self.theta_generation(param, param_shape) - self.gate_name = 'rz' + self.gate_info = { + 'gatename': 'rz', + 'texname': r'$R_{z}$', + 'plot_width': 0.9, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -486,6 +607,7 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state = functional.rz( state, self.theta[depth_idx, param_idx], qubit_idx, self.dtype, self.backend) return state + class U3(ParamGate): @@ -526,7 +648,11 @@ def __init__( else: param_shape = [depth, len(self.qubits_idx), 3] self.theta_generation(param, param_shape) - self.gate_name = 'u' + self.gate_info = { + 'gatename': 'u', + 'texname': r'$U$', + 'plot_width': 1.65, + } def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf: @@ -556,3 +682,5 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: state = functional.u3( state, self.theta[depth_idx, param_idx], qubit_idx, self.dtype, self.backend) return state + + \ No newline at end of file diff --git a/paddle_quantum/hamiltonian.py b/paddle_quantum/hamiltonian.py index d6f647c..4e3dd90 100644 --- a/paddle_quantum/hamiltonian.py +++ b/paddle_quantum/hamiltonian.py @@ -58,7 +58,6 @@ def __init__(self, pauli_str: list, compress: Optional[bool] = True): self.__compress() def __getitem__(self, indices): - new_pauli_str = [] if isinstance(indices, int): indices = [indices] elif isinstance(indices, slice): @@ -66,8 +65,8 @@ def __getitem__(self, indices): elif isinstance(indices, tuple): indices = list(indices) - for index in indices: - new_pauli_str.append([self.coefficients[index], ','.join(self.terms[index])]) + new_pauli_str = [[self.coefficients[index], ','.join(self.terms[index])] for index in indices] + return Hamiltonian(new_pauli_str, compress=False) def __add__(self, h_2): @@ -90,7 +89,7 @@ def __sub__(self, other): def __str__(self): str_out = '' for idx in range(self.n_terms): - str_out += '{} '.format(self.coefficients[idx]) + str_out += f'{self.coefficients[idx]} ' for _ in range(len(self.terms[idx])): str_out += self.terms[idx][_] if _ != len(self.terms[idx]) - 1: @@ -120,9 +119,7 @@ def terms(self) -> list: """ if self.__update_flag: self.__decompose() - return self.__terms - else: - return self.__terms + return self.__terms @property def coefficients(self) -> list: @@ -130,9 +127,7 @@ def coefficients(self) -> list: """ if self.__update_flag: self.__decompose() - return self.__coefficients - else: - return self.__coefficients + return self.__coefficients @property def pauli_words(self) -> list: @@ -140,9 +135,7 @@ def pauli_words(self) -> list: """ if self.__update_flag: self.__decompose() - return self.__pauli_words - else: - return self.__pauli_words + return self.__pauli_words @property def pauli_words_r(self) -> list: @@ -150,9 +143,7 @@ def pauli_words_r(self) -> list: """ if self.__update_flag: self.__decompose() - return self.__pauli_words_r - else: - return self.__pauli_words_r + return self.__pauli_words_r @property def pauli_words_matrix(self) -> list: @@ -183,7 +174,7 @@ def to_matrix(string): paddle.to_tensor([[1, 0], [0, 1]], dtype=paddle_quantum.get_dtype()) ) else: - raise ValueError('wrong format of string ' + string) + raise ValueError(f'wrong format of string {string}') return matrix return list(map(to_matrix, copy.deepcopy(self.pauli_words_r))) @@ -194,9 +185,7 @@ def sites(self) -> list: """ if self.__update_flag: self.__decompose() - return self.__sites - else: - return self.__sites + return self.__sites @property def n_qubits(self) -> int: @@ -204,9 +193,7 @@ def n_qubits(self) -> int: """ if self.__update_flag: self.__decompose() - return self.__nqubits - else: - return self.__nqubits + return self.__nqubits def __decompose(self): r"""decompose the Hamiltonian into vairious forms @@ -235,20 +222,20 @@ def __decompose(self): match_i = re.match(r'I', single_pauli_term, flags=re.I) if match_i: assert single_pauli_term[0].upper() == 'I', \ - 'The offset is defined with a sole letter "I", i.e. (3.0, "I")' + 'The offset is defined with a sole letter "I", i.e. (3.0, "I")' pauli_word_r += 'I' site.append('') else: match = re.match(r'([XYZ])([0-9]+)', single_pauli_term, flags=re.I) - if match: - pauli_word_r += match.group(1).upper() - assert int(match.group(2)) not in site, 'each Pauli operator should act on different qubit' - site.append(int(match.group(2))) - else: + if not match: raise Exception( 'Operators should be defined with a string composed of Pauli operators followed' + 'by qubit index on which it act, separated with ",". i.e. "Z0, X1"') - self.__nqubits = max(self.__nqubits, int(match.group(2)) + 1) + pauli_word_r += match[1].upper() + assert int(match[2]) not in site, 'each Pauli operator should act on different qubit' + + site.append(int(match[2])) + self.__nqubits = max(self.__nqubits, int(match[2]) + 1) self.__pauli_words_r.append(pauli_word_r) self.__sites.append(site) new_pauli_str.append([float(coefficient), pauli_term.upper()]) @@ -271,19 +258,14 @@ def __compress(self): """ if self.__update_flag: self.__decompose() - else: - pass new_pauli_str = [] flag_merged = [False for _ in range(self.n_terms)] for term_idx_1 in range(self.n_terms): if not flag_merged[term_idx_1]: for term_idx_2 in range(term_idx_1 + 1, self.n_terms): - if not flag_merged[term_idx_2]: - if self.pauli_words[term_idx_1] == self.pauli_words[term_idx_2]: - self.__coefficients[term_idx_1] += self.__coefficients[term_idx_2] - flag_merged[term_idx_2] = True - else: - pass + if not flag_merged[term_idx_2] and self.pauli_words[term_idx_1] == self.pauli_words[term_idx_2]: + self.__coefficients[term_idx_1] += self.__coefficients[term_idx_2] + flag_merged[term_idx_2] = True if self.__coefficients[term_idx_1] != 0: new_pauli_str.append([self.__coefficients[term_idx_1], ','.join(self.__terms[term_idx_1])]) self.__pauli_str = new_pauli_str @@ -312,8 +294,6 @@ def decompose_pauli_words(self) -> Tuple[list]: """ if self.__update_flag: self.__decompose() - else: - pass return self.coefficients, self.__pauli_words def construct_h_matrix(self, qubit_num: Optional[int] = None) -> np.ndarray: @@ -332,7 +312,7 @@ def construct_h_matrix(self, qubit_num: Optional[int] = None) -> np.ndarray: if type(site[0]) is int: qubit_num = max(qubit_num, max(site) + 1) else: - assert qubit_num >= self.n_qubits, "输入的量子数不小于哈密顿量表达式中所对应的量子比特数" + assert qubit_num >= self.n_qubits, "the input number of qubits must be no less than the number of qubits of this Hamiltonian" n_qubit = qubit_num h_matrix = np.zeros([2 ** n_qubit, 2 ** n_qubit], dtype='complex64') spin_ops = SpinOps(n_qubit, use_sparse=True) diff --git a/paddle_quantum/intrinsic.py b/paddle_quantum/intrinsic.py index 0a5b040..44e3f00 100644 --- a/paddle_quantum/intrinsic.py +++ b/paddle_quantum/intrinsic.py @@ -21,12 +21,16 @@ import paddle from typing import Union, Iterable, List +from .base import get_dtype -def _zero(dtype): + +def _zero(dtype = None): + dtype = get_dtype() if dtype is None else dtype return paddle.to_tensor(0, dtype=dtype) -def _one(dtype): +def _one(dtype = None): + dtype = get_dtype() if dtype is None else dtype return paddle.to_tensor(1, dtype=dtype) @@ -65,6 +69,7 @@ def _format_qubits_idx( raise TypeError( "The qubits_idx should be iterable such as list, tuple, and so on whose elements are all integers." "And the length of acted_qubits should be consistent with the corresponding gate." + f"\n Received qubits_idx type {type(qubits_idx)}, qubits # {len(qubits_idx)}, gate dimension {num_acted_qubits}" ) return qubits_idx diff --git a/paddle_quantum/linalg.py b/paddle_quantum/linalg.py index 7c678bb..720850b 100644 --- a/paddle_quantum/linalg.py +++ b/paddle_quantum/linalg.py @@ -14,22 +14,23 @@ # limitations under the License. r""" -The common linear algorithm in paddle quantum. +The library of functions in linear algebra. """ -from typing import Optional, Union import paddle import math import numpy as np import scipy from scipy.stats import unitary_group from functools import reduce +from typing import Optional, Union, Callable -import paddle_quantum -from paddle_quantum.intrinsic import _get_float_dtype +import paddle_quantum as pq +from .intrinsic import _get_float_dtype +from .state import State, _type_fetch, _type_transform -def abs_norm(mat: paddle.Tensor) -> float: +def abs_norm(mat: Union[np.ndarray, paddle.Tensor, State]) -> float: r""" tool for calculation of matrix norm Args: @@ -39,11 +40,12 @@ def abs_norm(mat: paddle.Tensor) -> float: norm of mat """ - mat = mat.cast(paddle_quantum.get_dtype()) + mat = _type_transform(mat, "tensor") + mat = mat.cast(pq.get_dtype()) return paddle.norm(paddle.abs(mat)).item() -def dagger(mat: paddle.Tensor) -> paddle.Tensor: +def dagger(mat: Union[np.ndarray, paddle.Tensor]) -> Union[np.ndarray, paddle.Tensor]: r""" tool for calculation of matrix dagger Args: @@ -53,20 +55,22 @@ def dagger(mat: paddle.Tensor) -> paddle.Tensor: The dagger of matrix """ - return paddle.conj(mat.T) + type_str = _type_fetch(mat) + return np.conj(mat.T) if type_str == "numpy" else paddle.conj(mat.T) -def is_hermitian(mat: paddle.Tensor, eps: Optional[float] = 1e-6) -> bool: - r""" verify whether mat ``P`` is Hermitian +def is_hermitian(mat: Union[np.ndarray, paddle.Tensor], eps: Optional[float] = 1e-6) -> bool: + r""" verify whether ``mat`` is Hermitian Args: - mat: hermitian candidate + mat: hermitian candidate :math:`P` eps: tolerance of error Returns: - determine whether :math:`mat - mat^\dagger = 0` + determine whether :math:`P - P^\dagger = 0` """ + mat = _type_transform(mat, "tensor") shape = mat.shape if len(shape) != 2 or shape[0] != shape[1] or math.log2(shape[0]) != math.ceil(math.log2(shape[0])): # not a mat / not a square mat / shape is not in form 2^num_qubits x 2^num_qubits @@ -74,17 +78,18 @@ def is_hermitian(mat: paddle.Tensor, eps: Optional[float] = 1e-6) -> bool: return abs_norm(mat - dagger(mat)) < eps -def is_projector(mat: paddle.Tensor, eps: Optional[float] = 1e-6) -> bool: - r""" verify whether mat ``P`` is a projector +def is_projector(mat: Union[np.ndarray, paddle.Tensor], eps: Optional[float] = 1e-6) -> bool: + r""" verify whether ``mat`` is a projector Args: - mat: projector candidate + mat: projector candidate :math:`P` eps: tolerance of error Returns: determine whether :math:`PP - P = 0` """ + mat = _type_transform(mat, "tensor") shape = mat.shape if len(shape) != 2 or shape[0] != shape[1] or math.log2(shape[0]) != math.ceil(math.log2(shape[0])): # not a mat / not a square mat / shape is not in form 2^num_qubits x 2^num_qubits @@ -92,18 +97,20 @@ def is_projector(mat: paddle.Tensor, eps: Optional[float] = 1e-6) -> bool: return abs_norm(mat @ mat - mat) < eps -def is_unitary(mat: paddle.Tensor, eps: Optional[float] = 1e-5) -> bool: - r""" verify whether mat ``P`` is a unitary +def is_unitary(mat: Union[np.ndarray, paddle.Tensor], eps: Optional[float] = 1e-4) -> bool: + r""" verify whether ``mat`` is a unitary Args: - mat: unitary candidate + mat: unitary candidate :math:`P` eps: tolerance of error Returns: determine whether :math:`PP^\dagger - I = 0` """ + mat = _type_transform(mat, "tensor").cast('complex128') shape = mat.shape + eps = min(eps * shape[0], 1e-2) if len(shape) != 2 or shape[0] != shape[1] or math.log2(shape[0]) != math.ceil(math.log2(shape[0])): # not a mat / not a square mat / shape is not in form 2^num_qubits x 2^num_qubits return False @@ -111,36 +118,41 @@ def is_unitary(mat: paddle.Tensor, eps: Optional[float] = 1e-5) -> bool: def hermitian_random(num_qubits: int) -> paddle.Tensor: - r"""randomly generate a :math:`2^num_qubits \times 2^num_qubits` hermitian matrix + r"""randomly generate a :math:`2^n \times 2^n` hermitian matrix Args: - num_qubits: log2(dimension) + num_qubits: number of qubits :math:`n` Returns: - a :math:`2^num_qubits \times 2^num_qubits` hermitian matrix + a :math:`2^n \times 2^n` hermitian matrix """ assert num_qubits > 0 n = 2 ** num_qubits - float_dtype = _get_float_dtype(paddle_quantum.get_dtype()) - vec = paddle.randn([n, n], dtype=float_dtype) + 1j * paddle.randn([n, n], dtype=float_dtype) - mat = vec @ dagger(vec) - return mat / paddle.trace(mat) + mat = np.random.randn(n, n) + 1j * np.random.randn(n, n) + for i in range(n): + mat[i, i] = np.abs(mat[i, i]) + for j in range(i): + mat[i, j] = np.conj(mat[j, i]) + + eigval= np.linalg.eigvalsh(mat) + max_eigval = np.max(np.abs(eigval)) + return paddle.to_tensor(mat / max_eigval, dtype=pq.get_dtype()) def orthogonal_projection_random(num_qubits: int) -> paddle.Tensor: - r"""randomly generate a :math:`2^num_qubits \times 2^num_qubits` rank-1 orthogonal projector + r"""randomly generate a :math:`2^n \times 2^n` rank-1 orthogonal projector Args: - num_qubits: log2(dimension) + num_qubits: number of qubits :math:`n` Returns: - a 2^num_qubits x 2^num_qubits orthogonal projector + a :math:`2^n \times 2^n` orthogonal projector """ assert num_qubits > 0 n = 2 ** num_qubits - float_dtype = _get_float_dtype(paddle_quantum.get_dtype()) + float_dtype = _get_float_dtype(pq.get_dtype()) vec = paddle.randn([n, 1], dtype=float_dtype) + 1j * paddle.randn([n, 1], dtype=float_dtype) mat = vec @ dagger(vec) return mat / paddle.trace(mat) @@ -150,42 +162,41 @@ def density_matrix_random(num_qubits: int) -> paddle.Tensor: r""" randomly generate an num_qubits-qubit state in density matrix form Args: - num_qubits: number of qubits + num_qubits: number of qubits :math:`n` Returns: - a 2^num_qubits x 2^num_qubits density matrix + a :math:`2^n \times 2^n` density matrix """ - float_dtype = _get_float_dtype(paddle_quantum.get_dtype()) + float_dtype = _get_float_dtype(pq.get_dtype()) real = paddle.rand([2 ** num_qubits, 2 ** num_qubits], dtype=float_dtype) imag = paddle.rand([2 ** num_qubits, 2 ** num_qubits], dtype=float_dtype) - M = real + 1j * imag + M = real + 1j * imag M = M @ dagger(M) - rho = M / paddle.trace(M) - return rho + return M / paddle.trace(M) def unitary_random(num_qubits: int) -> paddle.Tensor: - r"""randomly generate a :math:`2^num_qubits \times 2^num_qubits` unitary + r"""randomly generate a :math:`2^n \times 2^n` unitary Args: - num_qubits: :math:`\log_{2}(dimension)` + num_qubits: number of qubits :math:`n` Returns: - a :math:`2^num_qubits \times 2^num_qubits` unitary matrix + a :math:`2^n \times 2^n` unitary matrix """ - return paddle.to_tensor(unitary_group.rvs(2 ** num_qubits), dtype=paddle_quantum.get_dtype()) + return paddle.to_tensor(unitary_group.rvs(2 ** num_qubits), dtype=pq.get_dtype()) def unitary_hermitian_random(num_qubits: int) -> paddle.Tensor: - r"""randomly generate a :math:`2^num_qubits \times 2^num_qubits` hermitian unitary + r"""randomly generate a :math:`2^n \times 2^n` hermitian unitary Args: - num_qubits: :math:`\log_{2}(dimension)` + num_qubits: number of qubits :math:`n` Returns: - a :math:`2^num_qubits \times 2^num_qubits` hermitian unitary matrix + a :math:`2^n \times 2^n` hermitian unitary matrix """ proj_mat = orthogonal_projection_random(num_qubits) @@ -194,14 +205,14 @@ def unitary_hermitian_random(num_qubits: int) -> paddle.Tensor: def unitary_random_with_hermitian_block(num_qubits: int, is_unitary: bool = False) -> paddle.Tensor: - r"""randomly generate a unitary :math:`2^num_qubits \times 2^num_qubits` matrix that is a block encoding of a :math:`2^{num_qubits/2} \times 2^{num_qubits/2}` Hermitian matrix + r"""randomly generate a unitary :math:`2^n \times 2^n` matrix that is a block encoding of a :math:`2^{n/2} \times 2^{n/2}` Hermitian matrix Args: - num_qubits: :math:`\log_{2}(dimension)` + num_qubits: number of qubits :math:`n` is_unitary: whether the hermitian block is a unitary divided by 2 (for tutorial only) Returns: - a :math:`2^num_qubits \times 2^num_qubits` unitary matrix that its upper-left block is a Hermitian matrix + a :math:`2^n \times 2^n` unitary matrix that its upper-left block is a Hermitian matrix """ assert num_qubits > 0 @@ -215,17 +226,47 @@ def unitary_random_with_hermitian_block(num_qubits: int, is_unitary: bool = Fals mat = np.block([[mat0, mat1], [mat1, mat0]]) - return paddle.to_tensor(mat, dtype=paddle_quantum.get_dtype()) + return paddle.to_tensor(mat, dtype=pq.get_dtype()) + + +def block_enc_herm(mat: Union[np.ndarray, paddle.Tensor], + num_block_qubits: int = 1) -> Union[np.ndarray, paddle.Tensor]: + r""" generate a (qubitized) block encoding of hermitian ``mat`` + + Args: + mat: matrix to be block encoded + num_block_qubits: ancilla qubits used in block encoding + + Returns: + a unitary that is a block encoding of ``mat`` + + """ + assert is_hermitian(mat), "the input matrix is not a hermitian" + assert mat.shape[0] == mat.shape[1], "the input matrix is not a square matrix" + + type_mat = _type_fetch(mat) + H = _type_transform(mat, "numpy") + complex_dtype = mat.dtype + + num_qubits = int(math.log2(mat.shape[0])) + H_complement = scipy.linalg.sqrtm(np.eye(2 ** num_qubits) - H @ H) + block_enc = np.block([[H, 1j * H_complement], [1j * H_complement, H]]) + block_enc = paddle.to_tensor(block_enc, dtype=complex_dtype) + + if num_block_qubits > 1: + block_enc = direct_sum(block_enc, paddle.eye(2 ** (num_block_qubits + num_qubits) - 2 ** (num_qubits + 1)).cast(complex_dtype)) + + return _type_transform(block_enc, type_mat) def haar_orthogonal(num_qubits: int) -> paddle.Tensor: r""" randomly generate an orthogonal matrix following Haar random, referenced by arXiv:math-ph/0609050v2 Args: - num_qubits: number of qubits + num_qubits: number of qubits :math:`n` Returns: - a :math:`2^num_qubits \times 2^num_qubits` orthogonal matrix + a :math:`2^n \times 2^n` orthogonal matrix """ # Matrix dimension @@ -237,17 +278,17 @@ def haar_orthogonal(num_qubits: int) -> paddle.Tensor: # Step 3: make the decomposition unique mat_lambda = np.diag(mat_r) / abs(np.diag(mat_r)) mat_u = mat_q @ np.diag(mat_lambda) - return paddle.to_tensor(mat_u, dtype=paddle_quantum.get_dtype()) + return paddle.to_tensor(mat_u, dtype=pq.get_dtype()) def haar_unitary(num_qubits: int) -> paddle.Tensor: r""" randomly generate a unitary following Haar random, referenced by arXiv:math-ph/0609050v2 Args: - num_qubits: number of qubits + num_qubits: number of qubits :math:`n` Returns: - a :math:`2^num_qubits \times 2^num_qubits` unitary + a :math:`2^n \times 2^n` unitary """ # Matrix dimension @@ -259,18 +300,18 @@ def haar_unitary(num_qubits: int) -> paddle.Tensor: # Step 3: make the decomposition unique mat_lambda = np.diag(mat_r) / np.abs(np.diag(mat_r)) mat_u = mat_q @ np.diag(mat_lambda) - return paddle.to_tensor(mat_u, dtype=paddle_quantum.get_dtype()) + return paddle.to_tensor(mat_u, dtype=pq.get_dtype()) def haar_state_vector(num_qubits: int, is_real: Optional[bool] = False) -> paddle.Tensor: r""" randomly generate a state vector following Haar random Args: - num_qubits: number of qubits + num_qubits: number of qubits :math:`n` is_real: whether the vector is real, default to be False Returns: - a :math:`2^num_qubits \times 1` state vector + a :math:`2^n \times 1` state vector """ # Vector dimension @@ -286,19 +327,19 @@ def haar_state_vector(num_qubits: int, is_real: Optional[bool] = False) -> paddl # Perform u onto |0>, i.e., the first column of u phi = unitary[:, 0] - return paddle.to_tensor(phi, dtype=paddle_quantum.get_dtype()) + return paddle.to_tensor(phi, dtype=pq.get_dtype()) def haar_density_operator(num_qubits: int, rank: Optional[int] = None, is_real: Optional[bool] = False) -> paddle.Tensor: r""" randomly generate a density matrix following Haar random Args: - num_qubits: number of qubits + num_qubits: number of qubits :math:`n` rank: rank of density matrix, default to be False refering to full ranks is_real: whether the density matrix is real, default to be False Returns: - a :math:`2^num_qubits \times 2^num_qubits` density matrix + a :math:`2^n \times 2^n` density matrix """ dim = 2 ** num_qubits rank = rank if rank is not None else dim @@ -310,14 +351,38 @@ def haar_density_operator(num_qubits: int, rank: Optional[int] = None, is_real: ginibre_matrix = np.random.randn(dim, rank) + 1j * np.random.randn(dim, rank) rho = ginibre_matrix @ ginibre_matrix.conj().T rho = rho / np.trace(rho) - return paddle.to_tensor(rho / np.trace(rho), dtype=paddle_quantum.get_dtype()) + return paddle.to_tensor(rho / np.trace(rho), dtype=pq.get_dtype()) + + +def direct_sum(A: Union[np.ndarray, paddle.Tensor], + B: Union[np.ndarray, paddle.Tensor]) -> Union[np.ndarray, paddle.Tensor]: + r""" calculate the direct sum of A and B + + Args: + A: :math:`m \times n` matrix + B: :math:`p \times q` matrix + + Returns: + a direct sum of A and B, with shape :math:`(m + p) \times (n + q)` + + + """ + type_A, type_B = _type_fetch(A), _type_fetch(B) + A, B = _type_transform(A, "numpy"), _type_transform(B, "numpy") + + assert A.dtype == B.dtype, f"A's dtype {A.dtype} does not agree with B's dtype {B.dtype}" + + zero_AB, zero_BA = np.zeros([A.shape[0], B.shape[1]]), np.zeros([B.shape[0], A.shape[1]]) + mat = np.block([[A, zero_AB], [zero_BA, B]]) + + return mat if type_A == "numpy" or type_B == "numpy" else paddle.to_tensor(mat) def NKron( matrix_A: Union[paddle.Tensor, np.ndarray], matrix_B: Union[paddle.Tensor, np.ndarray], *args: Union[paddle.Tensor, np.ndarray] - ) -> Union[paddle.Tensor, np.ndarray]: + ) -> Union[paddle.Tensor, np.ndarray]: r""" calculate Kronecker product of at least two matrices Args: @@ -330,20 +395,52 @@ def NKron( .. code-block:: python - from paddle_quantum.state import density_op_random - from paddle_quantum.utils import NKron + from pq.state import density_op_random + from pq.linalg import NKron A = density_op_random(2) B = density_op_random(2) C = density_op_random(2) result = NKron(A, B, C) Note: - result should be A \otimes B \otimes C + ``result`` from above code block should be A \otimes B \otimes C """ - is_ndarray = False - if isinstance(matrix_A, np.ndarray): - is_ndarray = True - if not is_ndarray: + type_A, type_B = _type_fetch(matrix_A), _type_fetch(matrix_A) + assert type_A == type_B, f"the input data types do not agree: received {type_A} and {type_B}" + + if type_A == "tensor": return reduce(lambda result, index: paddle.kron(result, index), args, paddle.kron(matrix_A, matrix_B), ) else: return reduce(lambda result, index: np.kron(result, index), args, np.kron(matrix_A, matrix_B), ) + + +def herm_transform(fcn: Callable[[float], float], mat: Union[paddle.Tensor, np.ndarray, State], + ignore_zero: Optional[bool] = False) -> paddle.Tensor: + r""" function transformation for Hermitian matrix + + Args: + fcn: function :math:`f` that can be expanded by Taylor series + mat: hermitian matrix :math:`H` + ignore_zero: whether ignore eigenspaces with zero eigenvalue, defaults to be ``False`` + + Returns + :math:`f(H)` + + """ + assert is_hermitian(mat), \ + "the input matrix is not Hermitian: check your input" + type_str = _type_fetch(mat) + mat = _type_transform(mat, "tensor") if type_str != "state_vector" else mat.ket @ mat.bra + + eigval, eigvec = paddle.linalg.eigh(mat) + eigval = eigval.tolist() + eigvec = eigvec.T + + mat = paddle.zeros(mat.shape).cast(mat.dtype) + for i in range(len(eigval)): + vec = eigvec[i].reshape([mat.shape[0], 1]) + + if np.abs(eigval[i]) < 1e-5 and ignore_zero: + continue + mat += (fcn(eigval[i]) + 0j) * vec @ dagger(vec) + return mat.numpy() if type_str == "numpy" else mat diff --git a/paddle_quantum/locc/locc_ansatz.py b/paddle_quantum/locc/locc_ansatz.py index 5a76b60..89197f8 100644 --- a/paddle_quantum/locc/locc_ansatz.py +++ b/paddle_quantum/locc/locc_ansatz.py @@ -18,7 +18,6 @@ """ import collections -from matplotlib import docstring import paddle import paddle_quantum from ..gate import H, S, T, X, Y, Z, P, RX, RY, RZ, U3 diff --git a/paddle_quantum/operator/operator.py b/paddle_quantum/operator/operator.py index a730a1b..fc6553e 100644 --- a/paddle_quantum/operator/operator.py +++ b/paddle_quantum/operator/operator.py @@ -19,15 +19,16 @@ import numpy as np import paddle -import paddle_quantum + import warnings +import paddle_quantum as pq from ..base import Operator -from typing import Union, Iterable -from ..intrinsic import _format_qubits_idx, _get_float_dtype from ..backend import Backend from ..backend import state_vector, density_matrix, unitary_matrix -from ..linalg import abs_norm +from ..intrinsic import _format_qubits_idx, _get_float_dtype +from ..state import State from ..qinfo import partial_trace_discontiguous +from typing import Union, Iterable class ResetState(Operator): @@ -81,19 +82,19 @@ def __init__(self, qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubi measure_basis: Union[Iterable[paddle.Tensor], str] = 'z'): super().__init__() self.measure_basis = [] - + # the qubit indices must be sorted self.qubits_idx = sorted(_format_qubits_idx(qubits_idx, num_qubits)) - + self.desired_result = desired_result self.if_print = if_print - - if measure_basis == 'z' or measure_basis == 'computational_basis': + + if measure_basis in ['z', 'computational_basis']: self.measure_basis = 'z' else: raise NotImplementedError - def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: + def forward(self, state: State) -> State: r"""Compute the collapse of the input state. Args: @@ -102,70 +103,71 @@ def forward(self, state: paddle_quantum.State) -> paddle_quantum.State: Returns: The collapsed quantum state. """ - complex_dtype = paddle_quantum.get_dtype() + complex_dtype = pq.get_dtype() float_dtype = _get_float_dtype(complex_dtype) - - num_qubits = state.num_qubits + backend = state.backend num_acted_qubits = len(self.qubits_idx) desired_result = self.desired_result desired_result = int(desired_result, 2) if isinstance(desired_result, str) else desired_result + def projector_gen() -> paddle.Tensor: + proj = paddle.zeros([2 ** num_acted_qubits, 2 ** num_acted_qubits]) + proj[desired_result, desired_result] += 1 + proj = proj.cast(complex_dtype) + return proj + + num_qubits = state.num_qubits # when backend is unitary if backend == Backend.UnitaryMatrix: assert isinstance(desired_result, int), "desired_result cannot be None in unitary_matrix backend" warnings.warn( "the unitary_matrix of a circuit containing Collapse operator is no longer a unitary" ) - - # determine local projector - local_projector = paddle.zeros([2 ** num_acted_qubits, 2 ** num_acted_qubits]) - local_projector[desired_result, desired_result] += 1 - local_projector = local_projector.cast(complex_dtype) - + + local_projector = projector_gen() + projected_state = unitary_matrix.unitary_transformation(state.data, local_projector, self.qubits_idx, num_qubits) - return paddle_quantum.State(projected_state, backend=Backend.UnitaryMatrix) - + return State(projected_state, backend=Backend.UnitaryMatrix) + # retrieve prob_amplitude - if backend == Backend.StateVector: - rho = state.ket @ state.bra - else: - rho = state.data + rho = state.ket @ state.bra if backend == Backend.StateVector else state.data rho = partial_trace_discontiguous(rho, self.qubits_idx) prob_amplitude = paddle.zeros([2 ** num_acted_qubits], dtype=float_dtype) - for idx in range(0, 2 ** num_acted_qubits): + for idx in range(2 ** num_acted_qubits): prob_amplitude[idx] += rho[idx, idx].real() prob_amplitude /= paddle.sum(prob_amplitude) - + if desired_result is None: # randomly choose desired_result - desired_result = np.random.choice([i for i in range(2 ** num_acted_qubits)], p=prob_amplitude) + desired_result = np.random.choice(list(range(2**num_acted_qubits)), p=prob_amplitude) + else: + desired_result_str = bin(desired_result)[2:] # check whether the state can collapse to desired_result - assert prob_amplitude[desired_result] > 1e-20, ("it is infeasible for the state in qubits " + - f"{self.qubits_idx} to collapse to state |{desired_result_str}>") - + assert prob_amplitude[desired_result] > 1e-20, \ + f"it is infeasible for the state in qubits {self.qubits_idx} to collapse to state |{bin(desired_result)[2:]}>" + + # retrieve the binary version of desired result desired_result_str = bin(desired_result)[2:] assert num_acted_qubits >= len(desired_result_str), "the desired_result is too large" for _ in range(num_acted_qubits - len(desired_result_str)): - desired_result_str = '0' + desired_result_str - + desired_result_str = f'0{desired_result_str}' + # whether print the collapsed result if self.if_print: # retrieve binary representation prob = prob_amplitude[desired_result].item() print(f"qubits {self.qubits_idx} collapse to the state |{desired_result_str}> with probability {prob}") - - # determine projector according to the desired result - local_projector = paddle.zeros([2 ** num_acted_qubits, 2 ** num_acted_qubits]) - local_projector[desired_result, desired_result] += 1 - local_projector = local_projector.cast(complex_dtype) - + + local_projector = projector_gen() + # apply the local projector and normalize it if backend == Backend.StateVector: projected_state = state_vector.unitary_transformation(state.data, local_projector, self.qubits_idx, num_qubits) - return paddle_quantum.State(projected_state / (abs_norm(projected_state) + 0j)) else: projected_state = density_matrix.unitary_transformation(state.data, local_projector, self.qubits_idx, num_qubits) - return paddle_quantum.State(projected_state / paddle.trace(projected_state)) + state = State(projected_state) + state.normalize() + return state diff --git a/paddle_quantum/qinfo.py b/paddle_quantum/qinfo.py index ebeb717..abe02bc 100644 --- a/paddle_quantum/qinfo.py +++ b/paddle_quantum/qinfo.py @@ -14,27 +14,29 @@ # limitations under the License. r""" -The function for quantum information. +The library of functions in quantum information. """ -import paddle_quantum import math +import warnings import re import numpy as np from scipy.linalg import logm, sqrtm +import cvxpy +import matplotlib.image + import paddle -from paddle import kron, matmul, transpose -from .state import State +import paddle_quantum as pq +from .state import State, _type_fetch, _type_transform from .base import get_dtype from .intrinsic import _get_float_dtype -from .linalg import dagger, is_unitary, NKron -from .backend import Backend -import matplotlib.image +from .linalg import dagger, NKron, unitary_random +from .channel.custom import ChoiRepr, KrausRepr, StinespringRepr from typing import Optional, Tuple, List, Union -def partial_trace(state: Union[State, paddle.Tensor], - dim1: int, dim2: int, A_or_B: int) -> Union[State, paddle.Tensor]: +def partial_trace(state: Union[np.ndarray, paddle.Tensor, State], + dim1: int, dim2: int, A_or_B: int) -> Union[np.ndarray, paddle.Tensor, State]: r"""Calculate the partial trace of the quantum state. Args: @@ -46,48 +48,25 @@ def partial_trace(state: Union[State, paddle.Tensor], Returns: Partial trace of the input quantum state. """ - if A_or_B == 2: - dim1, dim2 = dim2, dim1 - - is_State = False - if isinstance(state, State): - is_State = True - backend = state.backend - rho_AB = state.data if backend != Backend.StateVector else state.ket @ state.bra - else: - rho_AB = state - complex_dtype = rho_AB.dtype - - idty_B = paddle.eye(dim2).cast(complex_dtype) - res = paddle.zeros([dim2, dim2]).cast(complex_dtype) - - for dim_j in range(dim1): - row_top = paddle.zeros([1, dim_j]) - row_mid = paddle.ones([1, 1]) - row_bot = paddle.zeros([1, dim1 - dim_j - 1]) - bra_j = paddle.concat([row_top, row_mid, row_bot], axis=1) - bra_j = paddle.cast(bra_j, complex_dtype) - - if A_or_B == 1: - row_tmp = kron(bra_j, idty_B) - row_tmp_conj = paddle.conj(row_tmp) - res += (row_tmp @ rho_AB) @ paddle.transpose(row_tmp_conj, perm=[1, 0]) - - if A_or_B == 2: - row_tmp = kron(idty_B, bra_j) - row_tmp_conj = paddle.conj(row_tmp) - res += (row_tmp @ rho_AB) @ paddle.transpose(row_tmp_conj, perm=[1, 0]) + type_str = _type_fetch(state) + rho_AB = _type_transform(state, "density_matrix").data if type_str == "state_vector" \ + else _type_transform(state, "tensor") + + higher_dims = rho_AB.shape[:-2] + new_state = paddle.trace( + paddle.reshape( + rho_AB, + higher_dims.copy() + [dim1, dim2, dim1, dim2] + ), + axis1 = -1 + A_or_B + len(higher_dims), + axis2 = 1 + A_or_B + len(higher_dims) + ) - if is_State: - if backend == Backend.StateVector: - eigval, eigvec = paddle.linalg.eig(res) - res = eigvec[:, paddle.argmax(paddle.real(eigval))] - return State(res, backend=backend) - return res + return _type_transform(new_state, type_str) -def partial_trace_discontiguous(state: Union[State, paddle.Tensor], - preserve_qubits: list=None) -> Union[State, paddle.Tensor]: +def partial_trace_discontiguous(state: Union[np.ndarray, paddle.Tensor, State], + preserve_qubits: list=None) -> Union[np.ndarray, paddle.Tensor, State]: r"""Calculate the partial trace of the quantum state with arbitrarily selected subsystem Args: @@ -97,104 +76,87 @@ def partial_trace_discontiguous(state: Union[State, paddle.Tensor], Returns: Partial trace of the quantum state with arbitrarily selected subsystem. """ - is_State = False - if isinstance(state, State): - is_State = True - backend = rho.backend - rho = state.data if backend != Backend.StateVector else state.ket @ state.bra - else: - rho = state - complex_dtype = rho.dtype + type_str = _type_fetch(state) + rho = _type_transform(state, "density_matrix").data if type_str == "state_vector" \ + else _type_transform(state, "tensor") if preserve_qubits is None: - return rho + return state + + n = int(math.log2(rho.shape[-1])) + + def new_partial_trace_singleOne(rho: paddle.Tensor, at: int) -> paddle.Tensor: + n_qubits = int(math.log2(rho.shape[-1])) + higher_dims = rho.shape[:-2] + rho = paddle.trace( + paddle.reshape( + rho, + higher_dims.copy() + [2 ** at, 2, 2 ** (n_qubits - at - 1), 2 ** at, 2, 2 ** (n_qubits - at - 1)] + ), + axis1=1+len(higher_dims), + axis2=4+len(higher_dims) + ) + return paddle.reshape(rho, higher_dims.copy() + [2 ** (n_qubits - 1), 2 ** (n_qubits - 1)]) - n = int(math.log2(rho.size) // 2) - num_preserve = len(preserve_qubits) - - shape = paddle.ones((n + 1,)) - shape = 2 * shape - shape[n] = 2 ** n - shape = paddle.cast(shape, "int32") - identity = paddle.eye(2 ** n) - identity = paddle.reshape(identity, shape=shape) - discard = list() - for idx in range(0, n): - if idx not in preserve_qubits: - discard.append(idx) - addition = [n] - preserve_qubits.sort() - - preserve_qubits = paddle.to_tensor(preserve_qubits) - discard = paddle.to_tensor(discard) - addition = paddle.to_tensor(addition) - permute = paddle.concat([discard, preserve_qubits, addition]) - - identity = paddle.transpose(identity, perm=permute) - identity = paddle.reshape(identity, (2 ** n, 2 ** n)) - - result = np.zeros((2 ** num_preserve, 2 ** num_preserve)) - result = paddle.to_tensor(result, dtype=complex_dtype) - - for i in range(0, 2 ** (n - num_preserve)): - bra = identity[i * 2 ** num_preserve:(i + 1) * 2 ** num_preserve, :] - result = result + matmul(matmul(bra, rho), transpose(bra, perm=[1, 0])) - - if is_State: - if backend == Backend.StateVector: - eigval, eigvec = paddle.linalg.eig(result) - result = eigvec[:, paddle.argmax(paddle.real(eigval))] - return State(result, backend=backend) - return result + for i, at in enumerate(x for x in range(n) if x not in preserve_qubits): + rho = new_partial_trace_singleOne(rho, at - i) + + return _type_transform(rho, type_str) -def trace_distance(rho: Union[State, paddle.Tensor], sigma: Union[State, paddle.Tensor]) -> paddle.Tensor: - r"""Calculate the fidelity of two quantum states. +def trace_distance(rho: Union[np.ndarray, paddle.Tensor, State], + sigma: Union[np.ndarray, paddle.Tensor, State]) -> Union[np.ndarray, paddle.Tensor]: + r"""Calculate the trace distance of two quantum states. .. math:: D(\rho, \sigma) = 1 / 2 * \text{tr}|\rho-\sigma| Args: - rho: Density matrix form of the quantum state. - sigma: Density matrix form of the quantum state. + rho: a quantum state. + sigma: a quantum state. Returns: - The fidelity between the input quantum states. + The trace distance between the input quantum states. """ - if isinstance(rho, State): - rho = rho.data - sigma = sigma.data + type_rho, type_sigma = _type_fetch(rho), _type_fetch(sigma) + rho = _type_transform(rho, "density_matrix").data + sigma = _type_transform(sigma, "density_matrix").data + assert rho.shape == sigma.shape, 'The shape of two quantum states are different' - eigval, eigvec = paddle.linalg.eig(rho - sigma) - return 0.5 * paddle.sum(paddle.abs(eigval)) + eigval, _ = paddle.linalg.eig(rho - sigma) + dist = 0.5 * paddle.sum(paddle.abs(eigval)) + + return dist.item() if type_rho == "numpy" and type_sigma == "numpy" else dist -def state_fidelity(rho: Union[State, paddle.Tensor], sigma: Union[State, paddle.Tensor]) -> paddle.Tensor: +def state_fidelity(rho: Union[np.ndarray, paddle.Tensor, State], + sigma: Union[np.ndarray, paddle.Tensor, State]) -> Union[np.ndarray, paddle.Tensor]: r"""Calculate the fidelity of two quantum states. .. math:: F(\rho, \sigma) = \text{tr}(\sqrt{\sqrt{\rho}\sigma\sqrt{\rho}}) Args: - rho: Density matrix form of the quantum state. - sigma: Density matrix form of the quantum state. + rho: a quantum state. + sigma: a quantum state. Returns: The fidelity between the input quantum states. """ + type_rho, type_sigma = _type_fetch(rho), _type_fetch(sigma) + rho = _type_transform(rho, "density_matrix").numpy() + sigma = _type_transform(sigma, "density_matrix").numpy() - if isinstance(rho, State): - rho = rho.data - sigma = sigma.data - rho = rho.numpy() - sigma = sigma.numpy() assert rho.shape == sigma.shape, 'The shape of two quantum states are different' fidelity = np.trace(sqrtm(sqrtm(rho) @ sigma @ sqrtm(rho))).real + if type_rho == "numpy" and type_sigma == "numpy": + return fidelity return paddle.to_tensor(fidelity) -def gate_fidelity(U: paddle.Tensor, V: paddle.Tensor) -> paddle.Tensor: +def gate_fidelity(U: Union[np.ndarray, paddle.Tensor], + V: Union[np.ndarray, paddle.Tensor]) -> Union[np.ndarray, paddle.Tensor]: r"""calculate the fidelity between gates .. math:: @@ -211,15 +173,17 @@ def gate_fidelity(U: paddle.Tensor, V: paddle.Tensor) -> paddle.Tensor: fidelity between gates """ - complex_dtype = U.dtype - V = paddle.cast(V, dtype=complex_dtype) + type_u, type_v = _type_fetch(U), _type_fetch(V) + U, V = _type_transform(U, "tensor"), _type_transform(V, "tensor") + + V = paddle.cast(V, dtype=U.dtype) assert U.shape == V.shape, 'The shape of two matrices are different' - fidelity = paddle.abs(paddle.trace(U @ dagger(V))) / U.shape[0] - return fidelity + + return fidelity.item() if type_u == "numpy" or type_v == "numpy" else fidelity -def purity(rho: Union[State, paddle.Tensor]) -> paddle.Tensor: +def purity(rho: Union[np.ndarray, paddle.Tensor, State]) -> Union[np.ndarray, paddle.Tensor]: r"""Calculate the purity of a quantum state. .. math:: @@ -232,14 +196,14 @@ def purity(rho: Union[State, paddle.Tensor]) -> paddle.Tensor: Returns: The purity of the input quantum state. """ - if isinstance(rho, State): - rho = rho.data - gamma = paddle.trace(paddle.matmul(rho, rho)) + type_rho = _type_fetch(rho) + rho = _type_transform(rho, "density_matrix").data + gamma = paddle.trace(rho @ rho).real() - return gamma.real() + return gamma.item() if type_rho == "numpy" else gamma -def von_neumann_entropy(rho: Union[State, paddle.Tensor]) -> paddle.Tensor: +def von_neumann_entropy(rho: Union[np.ndarray, paddle.Tensor, State], base: Optional[int] = 2) -> Union[np.ndarray, paddle.Tensor]: r"""Calculate the von Neumann entropy of a quantum state. .. math:: @@ -248,46 +212,44 @@ def von_neumann_entropy(rho: Union[State, paddle.Tensor]) -> paddle.Tensor: Args: rho: Density matrix form of the quantum state. + base: The base of logarithm. Defaults to 2. Returns: The von Neumann entropy of the input quantum state. """ - if isinstance(rho, State): - rho = rho.data - rho = rho.numpy() - rho_eigenvalues = np.real(np.linalg.eigvals(rho)) - entropy = 0 - for eigenvalue in rho_eigenvalues: - if np.abs(eigenvalue) < 1e-8: - continue - entropy -= eigenvalue * np.log(eigenvalue) + type_rho = _type_fetch(rho) + rho = _type_transform(rho, "density_matrix").data + rho_eigenvalues = paddle.real(paddle.linalg.eigvals(rho)) + entropy = -1 * (math.log(math.e, base)) * sum([eigenvalue * paddle.log(eigenvalue) for eigenvalue in rho_eigenvalues if eigenvalue >= 1e-8]) - return paddle.to_tensor(entropy) + return entropy.item() if type_rho == "numpy" else entropy -def relative_entropy(rho: Union[State, paddle.Tensor], sig: Union[State, paddle.Tensor]) -> paddle.Tensor: +def relative_entropy(rho: Union[np.ndarray, paddle.Tensor, State], + sig: Union[np.ndarray, paddle.Tensor, State], base: Optional[int] = 2) -> Union[np.ndarray, paddle.Tensor]: r"""Calculate the relative entropy of two quantum states. .. math:: S(\rho \| \sigma)=\text{tr} \rho(\log \rho-\log \sigma) - Args: rho: Density matrix form of the quantum state. sig: Density matrix form of the quantum state. + base: The base of logarithm. Defaults to 2. Returns: Relative entropy between input quantum states. """ - if isinstance(rho, State): - rho = rho.data - sig = sig.data - rho = rho.numpy() - sig = sig.numpy() + type_rho, type_sig = _type_fetch(rho), _type_fetch(sig) + rho = _type_transform(rho, "density_matrix").numpy() + sig = _type_transform(sig, "density_matrix").numpy() assert rho.shape == sig.shape, 'The shape of two quantum states are different' - res = np.trace(rho @ logm(rho) - rho @ logm(sig)) - return paddle.to_tensor(res.real) + entropy = (math.log(math.e, base)) * np.trace(rho @ logm(rho) - rho @ logm(sig)).real + + if type_rho == "numpy" or type_sig == "numpy": + return entropy + return paddle.to_tensor(entropy) def random_pauli_str_generator(n: int, terms: Optional[int] = 3) -> List: @@ -352,9 +314,7 @@ def pauli_str_to_matrix(pauli_str: list, n: int) -> paddle.Tensor: # Convert new_pauli_str to matrix; 'xziiy' to NKron(x, z, i, i, y) matrices = [] for coeff, op_str in new_pauli_str: - sub_matrices = [] - for op in op_str: - sub_matrices.append(pauli_dict[op.lower()]) + sub_matrices = [pauli_dict[op.lower()] for op in op_str] if len(op_str) == 1: matrices.append(coeff * sub_matrices[0]) else: @@ -366,23 +326,41 @@ def pauli_str_to_matrix(pauli_str: list, n: int) -> paddle.Tensor: return paddle.to_tensor(sum(matrices), dtype=get_dtype()) -def partial_transpose_2(density_op: Union[State, paddle.Tensor], sub_system: int = None) -> paddle.Tensor: +def partial_transpose_2(density_op: Union[np.ndarray, paddle.Tensor, State], + sub_system: int = None) -> Union[np.ndarray, paddle.Tensor]: r"""Calculate the partial transpose :math:`\rho^{T_A}` of the input quantum state. Args: density_op: Density matrix form of the quantum state. - sub_system: 1 or 2. 1 means to perform partial transpose on system A; 2 means to perform partial trace on system B. Default is 2. + sub_system: 1 or 2. 1 means to perform partial transpose on system A; + 2 means to perform partial transpose on system B. Default is 2. Returns: The partial transpose of the input quantum state. + + Example: + + .. code-block:: python + + import paddle + from paddle_quantum.qinfo import partial_transpose_2 + + rho_test = paddle.arange(1,17).reshape([4,4]) + partial_transpose_2(rho_test, sub_system=1) + + :: + + [[ 1, 2, 9, 10], + [ 5, 6, 13, 14], + [ 3, 4, 11, 12], + [ 7, 8, 15, 16]] """ + type_str = _type_fetch(density_op) + density_op = _type_transform(density_op, "density_matrix").numpy() + sys_idx = 2 if sub_system is None else 1 # Copy the density matrix and not corrupt the original one - if isinstance(density_op, State): - density_op = density_op.data - complex_dtype = density_op.dtype - density_op = density_op.numpy() transposed_density_op = np.copy(density_op) if sys_idx == 2: for j in [0, 2]: @@ -392,33 +370,36 @@ def partial_transpose_2(density_op: Union[State, paddle.Tensor], sub_system: int transposed_density_op[2:4, 0:2] = density_op[0:2, 2:4] transposed_density_op[0:2, 2:4] = density_op[2:4, 0:2] - return paddle.to_tensor(transposed_density_op, dtype=complex_dtype) + if type_str == "numpy": + return transposed_density_op + return paddle.to_tensor(transposed_density_op) -def partial_transpose(density_op: Union[State, paddle.Tensor], n: int) -> paddle.Tensor: +def partial_transpose(density_op: Union[np.ndarray, paddle.Tensor, State], + n: int) -> Union[np.ndarray, paddle.Tensor]: r"""Calculate the partial transpose :math:`\rho^{T_A}` of the input quantum state. Args: density_op: Density matrix form of the quantum state. - n: Number of qubits of the system to be transposed. + n: Number of qubits of subsystem A, with qubit indices as [0, 1, ..., n-1] Returns: The partial transpose of the input quantum state. """ # Copy the density matrix and not corrupt the original one - if isinstance(density_op, State): - density_op = density_op.data - complex_dtype = density_op.dtype - density_op = density_op.numpy() - transposed_density_op = np.copy(density_op) - for j in range(0, 2 ** n, 2): - for i in range(0, 2 ** n, 2): - transposed_density_op[i:i + 2, j:j + 2] = density_op[i:i + 2, j:j + 2].transpose() + type_str = _type_fetch(density_op) + density_op = _type_transform(density_op, "density_matrix") + n_qubits = density_op.num_qubits + density_op = density_op.data - return paddle.to_tensor(transposed_density_op, dtype=complex_dtype) + density_op = paddle.reshape(density_op, [2 ** n, 2 ** (n_qubits - n), 2 ** n, 2 ** (n_qubits - n)]) + density_op = paddle.transpose(density_op, [2, 1, 0, 3]) + density_op = paddle.reshape(density_op, [2 ** n_qubits, 2 ** n_qubits]) + return density_op.numpy() if type_str == "numpy" else density_op -def negativity(density_op: Union[State, paddle.Tensor]) -> paddle.Tensor: + +def negativity(density_op: Union[np.ndarray, paddle.Tensor, State]) -> Union[np.ndarray, paddle.Tensor]: r"""Compute the Negativity :math:`N = ||\frac{\rho^{T_A}-1}{2}||` of the input quantum state. Args: @@ -429,9 +410,8 @@ def negativity(density_op: Union[State, paddle.Tensor]) -> paddle.Tensor: """ # Implement the partial transpose density_op_T = partial_transpose_2(density_op) - if isinstance(density_op_T, State): - density_op_T = density_op_T.data - density_op_T = density_op_T.numpy() + type_str = _type_fetch(density_op_T) + density_op = _type_transform(density_op_T, "density_matrix").numpy() # Calculate through the equivalent expression N = sum(abs(\lambda_i)) when \lambda_i<0 n = 0.0 @@ -439,10 +419,11 @@ def negativity(density_op: Union[State, paddle.Tensor]) -> paddle.Tensor: for val in eigen_val: if val < 0: n = n + np.abs(val) - return paddle.to_tensor(n, dtype=_get_float_dtype(paddle_quantum.get_dtype())) + + return n if type_str == "numpy" else paddle.to_tensor(n) -def logarithmic_negativity(density_op: Union[State, paddle.Tensor]) -> paddle.Tensor: +def logarithmic_negativity(density_op: Union[np.ndarray, paddle.Tensor, State]) -> Union[np.ndarray, paddle.Tensor]: r"""Calculate the Logarithmic Negativity :math:`E_N = ||\rho^{T_A}||` of the input quantum state. Args: @@ -454,12 +435,10 @@ def logarithmic_negativity(density_op: Union[State, paddle.Tensor]) -> paddle.Te # Calculate the negativity n = negativity(density_op) - # Calculate through the equivalent expression - log2_n = paddle.log2(2 * n + 1) - return log2_n + return paddle.log2(2 * n + 1) -def is_ppt(density_op: Union[State, paddle.Tensor]) -> bool: +def is_ppt(density_op: Union[np.ndarray, paddle.Tensor, State]) -> bool: r"""Check if the input quantum state is PPT. Args: @@ -468,17 +447,12 @@ def is_ppt(density_op: Union[State, paddle.Tensor]) -> bool: Returns: Whether the input quantum state is PPT. """ - # By default the PPT condition is satisfied - ppt = True - - # Detect negative eigenvalues from the partial transposed density_op - if negativity(density_op) > 0: - ppt = False - return ppt + return bool(negativity(density_op) <= 0) -def schmidt_decompose(psi: Union[State, paddle.Tensor], - sys_A: List[int]=None) -> Tuple[paddle.Tensor, paddle.Tensor, paddle.Tensor]: +def schmidt_decompose(psi: Union[np.ndarray, paddle.Tensor, State], + sys_A: List[int]=None) -> Union[Tuple[paddle.Tensor, paddle.Tensor, paddle.Tensor], + Tuple[np.ndarray, np.ndarray, np.ndarray]]: r"""Calculate the Schmidt decomposition of a quantum state :math:`\lvert\psi\rangle=\sum_ic_i\lvert i_A\rangle\otimes\lvert i_B \rangle`. Args: @@ -492,16 +466,14 @@ def schmidt_decompose(psi: Union[State, paddle.Tensor], * A high dimensional array composed of bases for subsystem A :math:`\lvert i_A\rangle`, with shape ``(k, 2**m, 1)`` * A high dimensional array composed of bases for subsystem B :math:`\lvert i_B\rangle` , with shape ``(k, 2**m, 1)`` """ - if isinstance(psi, State): - psi = psi.data - psi = psi.numpy() - complex_dtype = psi.dtype + type_psi = _type_fetch(psi) + psi = _type_transform(psi, "state_vector").numpy() assert psi.ndim == 1, 'Psi must be a one dimensional vector.' assert np.log2(psi.size).is_integer(), 'The number of amplitutes must be an integral power of 2.' tot_qu = int(np.log2(psi.size)) - sys_A = sys_A if sys_A is not None else [i for i in range(tot_qu//2)] + sys_A = sys_A if sys_A is not None else list(range(tot_qu//2)) sys_B = [i for i in range(tot_qu) if i not in sys_A] # Permute qubit indices @@ -514,10 +486,11 @@ def schmidt_decompose(psi: Union[State, paddle.Tensor], u, c, v = np.linalg.svd(amp_mtr) k = np.count_nonzero(c > 1e-13) - c = paddle.to_tensor(c[:k], dtype=complex_dtype) - u = paddle.to_tensor(u.T[:k].reshape([k, -1, 1]), dtype=complex_dtype) - v = paddle.to_tensor(v[:k].reshape([k, -1, 1]), dtype=complex_dtype) - return c, u, v + c, u, v = c[:k], u.T[:k].reshape([k, -1, 1]), v[:k].reshape([k, -1, 1]) + + if type_psi == "numpy": + return c, u, v + return paddle.to_tensor(c), paddle.to_tensor(u), paddle.to_tensor(v) def image_to_density_matrix(image_filepath: str) -> State: @@ -540,10 +513,10 @@ def image_to_density_matrix(image_filepath: str) -> State: # Density matrix whose trace is 1 rho = image_matrix@image_matrix.T rho = rho/np.trace(rho) - return State(paddle.to_tensor(rho), backend=paddle_quantum.Backend.DensityMatrix) + return State(rho, backend=pq.Backend.DensityMatrix) -def shadow_trace(state: 'State', hamiltonian: paddle_quantum.Hamiltonian, +def shadow_trace(state: 'State', hamiltonian: pq.Hamiltonian, sample_shots: int, method: Optional[str] = 'CS') -> float: r"""Estimate the expectation value :math:`\text{trace}(H\rho)` of an observable :math:`H`. @@ -551,7 +524,7 @@ def shadow_trace(state: 'State', hamiltonian: paddle_quantum.Hamiltonian, state: Quantum state. hamiltonian: Observable. sample_shots: Number of samples. - method: Method used to , which should be one of “CS”, “LBCS”, and “APS”. Default is “CS”. + method: Method used to, which should be one of “CS”, “LBCS”, and “APS”. Default is “CS”. Raises: ValueError: Hamiltonian has a bad form @@ -564,12 +537,12 @@ def shadow_trace(state: 'State', hamiltonian: paddle_quantum.Hamiltonian, num_qubits = state.num_qubits mode = state.backend if method == "LBCS": - result, beta = paddle_quantum.shadow.shadow_sample(state, num_qubits, sample_shots, mode, hamiltonian, method) + result, beta = pq.shadow.shadow_sample(state, num_qubits, sample_shots, mode, hamiltonian, method) else: - result = paddle_quantum.shadow.shadow_sample(state, num_qubits, sample_shots, mode, hamiltonian, method) + result = pq.shadow.shadow_sample(state, num_qubits, sample_shots, mode, hamiltonian, method) def prepare_hamiltonian(hamiltonian, num_qubits): - new_hamiltonian = list() + new_hamiltonian = [] for idx, (coeff, pauli_str) in enumerate(hamiltonian): pauli_str = re.split(r',\s*', pauli_str.lower()) pauli_term = ['i'] * num_qubits @@ -630,7 +603,7 @@ def estimated_value(pauli_term, measurement_result): # Define the functions required by APS def is_covered(pauli, pauli_str): for qubit_idx in range(num_qubits): - if not pauli[qubit_idx] in ('i', pauli_str[qubit_idx]): + if pauli[qubit_idx] not in ('i', pauli_str[qubit_idx]): return False return True @@ -686,7 +659,7 @@ def update_pauli_estimator(hamiltonian, pauli_estimator, pauli_str, measurement_ return trace_estimation -def tensor_product(state_a: Union[State, paddle.Tensor], state_b: Union[State, paddle.Tensor], *args: Union[State, paddle.Tensor]) -> State: +def tensor_state(state_a: State, state_b: State, *args: State) -> State: r"""calculate tensor product (kronecker product) between at least two state. This function automatically returns State instance Args: @@ -694,37 +667,182 @@ def tensor_product(state_a: Union[State, paddle.Tensor], state_b: Union[State, p state_b: State *args: other states + Returns: + tensor product state of input states + + Notes: + Need to be careful with the backend of states; + Use ``paddle_quantum.linalg.NKron`` if the input datatype is ``paddle.Tensor`` or ``numpy.ndarray``. + + """ + state_a, state_b = _type_transform(state_a, "tensor"), _type_transform(state_b, "tensor") + return State(NKron(state_a, state_b, [_type_transform(st, "tensor") for st in args])) + + +def diamond_norm(channel_repr: Union[ChoiRepr, KrausRepr, StinespringRepr, paddle.Tensor], + dim_io: Union[int, Tuple[int, int]] = None, **kwargs) -> float: + r'''Calculate the diamond norm of input. + + Args: + channel_repr: A ``ChoiRepr`` or ``KrausRepr`` or ``StinespringRepr`` instance or a ``paddle.Tensor`` instance. + dim_io: The input and output dimensions. + **kwargs: Parameters to set cvx. + Raises: - NotImplementedError: only accept state or tensor instances + RuntimeError: `channel_repr` must be `ChoiRepr`or `KrausRepr` or `StinespringRepr` or `paddle.Tensor`. + TypeError: "dim_io" should be "int" or "tuple". + + Warning: + `channel_repr` is not in Choi representaiton, and is converted into `ChoiRepr`. Returns: - tensor product of input states + Its diamond norm. + + Reference: + Khatri, Sumeet, and Mark M. Wilde. "Principles of quantum communication theory: A modern approach." + arXiv preprint arXiv:2011.04672 (2020). + Watrous, J. . "Semidefinite Programs for Completely Bounded Norms." + Theory of Computing 5.1(2009):217-238. + ''' + if isinstance(channel_repr, ChoiRepr): + choi_matrix = channel_repr.choi_oper + + elif isinstance(channel_repr, paddle.Tensor): + choi_matrix = channel_repr + + elif isinstance(channel_repr, (KrausRepr, StinespringRepr)): + warnings.warn('`channel_repr` is not in Choi representaiton, and is converted into `ChoiRepr`') + choi_matrix = channel_convert(channel_repr, 'Choi').choi_oper + + else: + raise RuntimeError('`channel_repr` must be `ChoiRepr`or `KrausRepr` or `StinespringRepr` or `paddle.Tensor`.') + + if dim_io is None: # Default to dim_in == dim_out + dim_in = dim_out = int(math.sqrt(choi_matrix.shape[0])) + elif isinstance(dim_io, tuple): + dim_in = int(dim_io[0]) + dim_out = int(dim_io[1]) + elif isinstance(dim_io, int): + dim_in = dim_io + dim_out = dim_io + else: + raise TypeError('"dim_io" should be "int" or "tuple".') + kron_size = dim_in * dim_out + + # Cost function : Trace( \Omega @ Choi_matrix ) + rho = cvxpy.Variable(shape=(dim_in, dim_in), complex=True) + omega = cvxpy.Variable(shape=(kron_size, kron_size), complex=True) + identity = np.eye(dim_out) + + # \rho \otimes 1 \geq \Omega + cons_matrix = cvxpy.kron(rho, identity) - omega + cons = [ + rho >> 0, + rho.H == rho, + cvxpy.trace(rho) == 1, + + omega >> 0, + omega.H == omega, + + cons_matrix >> 0 + ] + + obj = cvxpy.Maximize(2 * cvxpy.real((cvxpy.trace(omega @ choi_matrix)))) + prob = cvxpy.Problem(obj, cons) + + return prob.solve(**kwargs) + + +def channel_convert(original_channel: Union[ChoiRepr, KrausRepr, StinespringRepr], target: str, tol: float = 1e-6) -> Union[ChoiRepr, KrausRepr, StinespringRepr]: + r"""convert the given channel to the target implementation + + Args: + original_channel: input quantum channel + target: target implementation, should to be ``Choi``, ``Kraus`` or ``Stinespring`` + tol: error tolerance of the convert, 1e-6 by default + Raises: + ValueError: Unsupported channel representation: require Choi, Kraus or Stinespring. + + Returns: + Union[ChoiRepr, KrausRepr]: quantum channel by the target implementation + Note: - the backend should be density matrix. + choi -> kraus currently has the error of order 1e-6 caused by eigh + + Raises: + NotImplementedError: does not support the conversion of input data type + """ - if isinstance(state_a, State): - data_a = state_a.data - elif isinstance(state_a, paddle.Tensor): - data_a = state_a - else: - raise NotImplementedError - - if isinstance(state_b, State): - data_b = state_b.data - elif isinstance(state_b, paddle.Tensor): - data_b = state_b + target = target.capitalize() + if target not in ['Choi', 'Kraus', 'Stinespring']: + raise ValueError(f"Unsupported channel representation: require Choi, Kraus or Stinespring, not {target}") + if type(original_channel).__name__ == f'{target}Repr': + return original_channel + + if isinstance(original_channel, KrausRepr) and target == 'Choi': + kraus_oper = original_channel.kraus_oper + ndim = original_channel.kraus_oper[0].shape[0] + kraus_oper_tensor = paddle.concat([paddle.kron(x, x.conj().T) for x in kraus_oper]).reshape([len(kraus_oper), ndim, -1]) + chan = paddle.sum(kraus_oper_tensor, axis=0).reshape([ndim for _ in range(4)]).transpose([2, 1, 0, 3]) + choi_repr = chan.transpose([0, 2, 1, 3]).reshape([ndim * ndim, ndim * ndim]) + result = ChoiRepr(choi_repr, original_channel.qubits_idx) + result.qubits_idx = original_channel.qubits_idx + + elif isinstance(original_channel, KrausRepr) and target == 'Stinespring': + kraus_oper = original_channel.kraus_oper + j_dim = len(kraus_oper) + i_dim = kraus_oper[0].shape[0] + kraus_oper_tensor = paddle.concat(kraus_oper).reshape([j_dim, i_dim, -1]) + stinespring_mat = kraus_oper_tensor.transpose([1, 0, 2]) + stinespring_mat = stinespring_mat.reshape([i_dim * j_dim, i_dim]) + result = StinespringRepr(stinespring_mat, original_channel.qubits_idx) + result.qubits_idx = original_channel.qubits_idx + + elif isinstance(original_channel, ChoiRepr) and target == 'Kraus': + choi_repr = original_channel.choi_oper + ndim = int(math.sqrt(original_channel.choi_oper.shape[0])) + w, v = paddle.linalg.eigh(choi_repr) + + # add abs to make eigvals safe + w = paddle.abs(w) + l_cut = 0 + for l in range(len(w) - 1, -1, -1): + if paddle.sum(paddle.abs(w[l:])) / paddle.sum(paddle.abs(w)) > 1 - tol: + l_cut = l + break + kraus = [(v * paddle.sqrt(w))[:, l].reshape([ndim, ndim]).T for l in range(l_cut, ndim**2)] + + result = KrausRepr(kraus, original_channel.qubits_idx) + result.qubits_idx = original_channel.qubits_idx + + elif isinstance(original_channel, StinespringRepr) and target == 'Kraus': + stinespring_mat = original_channel.stinespring_matrix + i_dim = stinespring_mat.shape[1] + j_dim = stinespring_mat.shape[0] // i_dim + kraus_oper = stinespring_mat.reshape([i_dim, j_dim, i_dim]).transpose([1, 0, 2]) + kraus_oper = [kraus_oper[j] for j in range(j_dim)] + result = KrausRepr(kraus_oper, original_channel.qubits_idx) + result.qubits_idx = original_channel.qubits_idx + else: - raise NotImplementedError - - addis = [] - for st in args: - if isinstance(st, State): - addis.append(st.data) - elif isinstance(st, paddle.Tensor): - addis.append(st) - else: - raise NotImplementedError + raise NotImplementedError( + f"does not support the conversion of {type(original_channel)}") - res = paddle_quantum.linalg.NKron(data_a, data_b, *addis) - return State(res) \ No newline at end of file + return result + + +def kraus_oper_random(num_qubits: int, num_oper: int) -> list: + r""" randomly generate a set of kraus operators for quantum channel + + Args: + num_qubits: The amount of qubits of quantum channel. + num_oper: The amount of kraus operators to be generated. + + Returns: + a list of kraus operators + + """ + float_dtype = _get_float_dtype(get_dtype()) + prob = [paddle.sqrt(paddle.to_tensor(1/num_oper, dtype = float_dtype))] * num_oper + return [prob[idx] * unitary_random(num_qubits) for idx in range(num_oper)] diff --git a/paddle_quantum/qml/__init__.py b/paddle_quantum/qml/__init__.py new file mode 100644 index 0000000..70f20b8 --- /dev/null +++ b/paddle_quantum/qml/__init__.py @@ -0,0 +1,18 @@ +# !/usr/bin/env python3 +# Copyright (c) 2022 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. + +r""" +The quantum machine learning module. +""" diff --git a/paddle_quantum/qml/vsql.py b/paddle_quantum/qml/vsql.py new file mode 100644 index 0000000..823e67e --- /dev/null +++ b/paddle_quantum/qml/vsql.py @@ -0,0 +1,237 @@ +# !/usr/bin/env python3 +# Copyright (c) 2022 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. + +r""" +The VSQL model. +""" + +import random +from typing import Optional, List, Tuple + +import numpy as np +import paddle +import paddle.nn.functional as F +from paddle.vision.datasets import MNIST + +import paddle_quantum as pq +from paddle_quantum.ansatz import Circuit + + +def norm_image(images: List[np.ndarray], num_qubits: int) -> List[paddle.Tensor]: + r""" + Normalize the input images. Flatten them and make them to normalized vectors. + + Args: + images: The input images. + num_qubits: The number of qubits, which decides the dimension of the vector. + + Returns: + Return the normalized vectors, which is the list of paddle's tensors. + """ + # pad and normalize the image + _images = [] + for image in images: + image = image.flatten() + if image.size < 2 ** num_qubits: + _images.append(np.pad(image, pad_width=(0, 2 ** num_qubits - image.size))) + else: + _images.append(image[:2 ** num_qubits]) + return [paddle.to_tensor(image / np.linalg.norm(image), dtype=pq.get_dtype()) for image in _images] + + +def data_loading( + num_qubits: int, mode: str, classes: list, num_data: Optional[int] = None +) -> Tuple[List[np.ndarray], List[int]]: + r""" + Loading the MNIST dataset, which only contains the specified data. + + Args: + num_qubits: The number of qubits, which determines the dimension of the normalized vector. + mode: Specifies the loaded dataset: ``'train'`` | ``'test'`` . + + - ``'train'`` : Load the training dataset. + - ``'test'`` : Load the test dataset. + + classes: The labels of the data which will be loaded. + num_data: The number of data to be loaded. Defaults to ``None``, which means loading all data. + + Returns: + Return the loaded dataset, which is ``(images, labels)`` . + """ + data = MNIST(mode=mode, backend='cv2') + filtered_data = [item for item in data if item[1].item() in classes] + random.shuffle(filtered_data) + if num_data is None: + num_data = len(filtered_data) + images = [filtered_data[idx][0] for idx in range(min(len(filtered_data), num_data))] + labels = [filtered_data[idx][1] for idx in range(min(len(filtered_data), num_data))] + images = norm_image(images, num_qubits=num_qubits) + labels = [label.item() for label in labels] + return images, labels + + +def _slide_circuit(cir: pq.ansatz.Circuit, distance: int): + # slide to get the local feature + for sublayer in cir.sublayers(): + qubits_idx = np.array(sublayer.qubits_idx) + qubits_idx = qubits_idx + distance + sublayer.qubits_idx = qubits_idx.tolist() + + +def observable(start_idx: int, num_shadow: int) -> pq.Hamiltonian: + r""" + Generate the observable to measure the quantum states. + + Args: + start_idx: The start index of the qubits. + num_shadow: The number of qubits which the shadow circuit contains. + + Returns: + Return the generated observable. + """ + # construct the observable to get te output of the circuit + pauli_str = ','.join(f'x{str(i)}' for i in range(start_idx, start_idx + num_shadow)) + return pq.Hamiltonian([[1.0, pauli_str]]) + + +class VSQL(paddle.nn.Layer): + r""" + The class of the variational shadow quantum learning (VSQL). + + The details can be referred to https://ojs.aaai.org/index.php/AAAI/article/view/17016 . + + Args: + num_qubits: The number of qubits which the quantum circuit contains. + num_shadow: The number of qubits which the shadow circuit contains. + num_classes: The number of class which the modell will classify. + depth: The depth of the quantum circuit. Defaults to ``1`` . + """ + def __init__(self, num_qubits: int, num_shadow: int, num_classes: int, depth: int = 1): + super().__init__() + self.num_qubits = num_qubits + self.num_shadow = num_shadow + self.depth = depth + cir = Circuit(num_qubits) + for idx in range(num_shadow): + cir.rx(qubits_idx=idx) + cir.ry(qubits_idx=idx) + cir.rx(qubits_idx=idx) + for _ in range(depth): + for idx in range(num_shadow - 1): + cir.cnot([idx, idx + 1]) + cir.cnot([num_shadow - 1, 0]) + for idx in range(num_shadow): + cir.ry(qubits_idx=idx) + self.cir = cir + self.fc = paddle.nn.Linear( + num_qubits - num_shadow + 1, num_classes, + weight_attr=paddle.ParamAttr(initializer=paddle.nn.initializer.Normal()), + bias_attr=paddle.ParamAttr(initializer=paddle.nn.initializer.Normal()) + ) + + def forward(self, batch_input: List[paddle.Tensor]) -> paddle.Tensor: + r""" + The forward function. + + Args: + batch_input: The input of the model. It's shape is :math:`(\text{batch_size}, 2^{\text{num_qubits}})` . + + Returns: + Return the output of the model. It's shape is :math:`(\text{batch_size}, \text{num_classes})` . + """ + batch_feature = [] + for input in batch_input: + _state = pq.State(input) + feature = [] + for idx_start in range(self.num_qubits - self.num_shadow + 1): + ob = observable(idx_start, num_shadow=self.num_shadow) + _slide_circuit(cir=self.cir, distance=1 if idx_start != 0 else 0) + expec_val_func = pq.loss.ExpecVal(ob) + out_state = self.cir(_state) + expec_val = expec_val_func(out_state) + feature.append(expec_val) + # slide the circuit to the initial position + _slide_circuit(self.cir, -idx_start) + feature = paddle.concat(feature) + batch_feature.append(feature) + batch_feature = paddle.stack(batch_feature) + return self.fc(batch_feature) + + +def train( + num_qubits: int, num_shadow: int, depth: int = 1, + batch_size: int = 16, epoch: int = 10, learning_rate: float = 0.01, + classes: Optional[list] = None, num_train: Optional[int] = None, num_test: Optional[int] = None +) -> None: + """ + The function of training the VSQL model. + + Args: + num_qubits: The number of qubits which the quantum circuit contains. + num_shadow: The number of qubits which the shadow circuit contains. + depth: The depth of the quantum circuit. Defaults to ``1`` . + batch_size: The size of the batch samplers. Defaults to ``16`` . + epoch: The number of epochs to train the model. Defaults to ``10`` . + learning_rate: The learning rate used to update the parameters. Defaults to ``0.01`` . + classes: The classes of handwrite digits to be predicted. + Defaults to ``None`` , which means predict all the classes. + num_train: The number of the data in the training dataset. + Defaults to ``None`` , which will use all training data. + num_test: The number of the data in the test dataset. Defaults to ``None`` , which will use all test data. + """ + if classes is None: + classes = list(range(10)) + train_input, train_label = data_loading(num_qubits=num_qubits, mode='train', classes=classes, num_data=num_train) + test_input, test_label = data_loading(num_qubits=num_qubits, mode='test', classes=classes, num_data=num_test) + net = VSQL(num_qubits, num_shadow=num_shadow, num_classes=len(classes), depth=depth) + opt = paddle.optimizer.Adam(learning_rate=learning_rate, parameters=net.parameters()) + num_train = len(train_label) if num_train is None else num_train + num_test = len(test_label) if num_test is None else num_test + for idx_epoch in range(epoch): + for itr in range(num_train // batch_size): + output = net(train_input[itr * batch_size:(itr + 1) * batch_size]) + labels = paddle.to_tensor(train_label[itr * batch_size:(itr + 1) * batch_size]) + loss = F.cross_entropy(output, labels) + loss.backward() + opt.minimize(loss) + opt.clear_grad() + if itr % 10 == 0: + predictions = paddle.argmax(output, axis=-1).tolist() + labels = labels.tolist() + train_acc = sum(labels[idx] == predictions[idx] for idx in range(len(labels))) / len(labels) + output = net(test_input[:num_test]) + labels = test_label[:num_test] + predictions = paddle.argmax(output, axis=-1).tolist() + test_acc = sum(labels[idx] == predictions[idx] for idx in range(len(labels))) / num_test + print( + f"Epoch: {idx_epoch: 3d}, iter: {itr: 3d}, loss: {loss.item(): .4f}, " + f"batch_acc: {train_acc: .2%}, test_acc: {test_acc: .2%}." + ) + state_dict = net.state_dict() + paddle.save(state_dict, 'vsql.pdparams') + + +if __name__ == '__main__': + train( + num_qubits=10, + num_shadow=2, + depth=1, + batch_size=20, + epoch=10, + learning_rate=0.01, + classes=[0, 1], + num_train=1000, + num_test=100 + ) diff --git a/paddle_quantum/qpp/__init__.py b/paddle_quantum/qpp/__init__.py new file mode 100644 index 0000000..e445626 --- /dev/null +++ b/paddle_quantum/qpp/__init__.py @@ -0,0 +1,22 @@ +# !/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. + +r""" +The module of quantum phase processing. +""" + +from .laurent import * +from .angles import * +from .utils import * diff --git a/paddle_quantum/qpp/angles.py b/paddle_quantum/qpp/angles.py new file mode 100644 index 0000000..a17be70 --- /dev/null +++ b/paddle_quantum/qpp/angles.py @@ -0,0 +1,290 @@ +# !/usr/bin/env python3 +# Copyright (c) 2022 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. +import numpy as np +from paddle_quantum.ansatz import Circuit + +from copy import copy +from typing import Optional, Tuple, List +from math import atan, cos, sin +from .laurent import Laurent + + +r""" +QPP angle solver for trigonometric QSP, see Lemma 3 in paper https://arxiv.org/abs/2205.07848 for more details. +""" + + +__all__ = ['qpp_angle_finder', 'qpp_angle_approximator'] + + +def qpp_angle_finder(P: Laurent, Q: Laurent) -> Tuple[List[float], List[float]]: + r"""Find the corresponding set of angles for a Laurent pair `P`, `Q`. + + Args: + P: a Laurent poly. + Q: a Laurent poly. + + Returns: + contains the following elements: + - list_theta: angles for :math:`R_Y` gates; + - list_phi: angles for :math:`R_Z` gates. + + """ + # input check + P, Q = copy(P), copy(Q) + condition_test(P, Q) + + list_theta = [] + list_phi = [] + + # backup P for output check + P_copy = copy(P) + + L = P.deg + while L > 0: + theta, phi = update_angle([P.coef[-1], P.coef[0], Q.coef[-1], Q.coef[0]]) + + list_theta.append(theta) + list_phi.append(phi) + + P, Q = update_polynomial(P, Q, theta, phi) + L = P.deg + + # decide theta[0], phi[0] and global phase alpha + p_0, q_0 = P.coef[0], Q.coef[0] + alpha, theta, phi = yz_decomposition(np.array([[p_0, -q_0], [np.conj(q_0), np.conj(p_0)]])) + list_theta.append(theta) + list_phi.append(phi) + + # test outputs, by 5 random data points in [-pi, pi] + err_list = [] + list_x = (np.random.rand(5) * 2 - 1) * np.pi + for x in list_x: + experiment_y = matrix_generation(list_theta, list_phi, x, alpha)[0, 0] + actual_y = P_copy(np.exp(1j * x / 2)) + + err = np.abs(experiment_y + actual_y) if np.abs(experiment_y / actual_y + 1) < 1e-2 else np.abs(experiment_y - actual_y) + if err > 0.1: + print(experiment_y) + print(actual_y) + raise ValueError( + f"oversized error: {err}, check your code") + err_list.append(err) + print(f"computations of angles for QPP are completed with mean error {np.mean(err_list)}") + + return list_theta, list_phi + + +def qpp_angle_approximator(P: Laurent, Q: Laurent) -> Tuple[List[float], List[float]]: + r"""Approximate the corresponding set of angles for a Laurent pair `P`, `Q`. + + Args: + P: a Laurent poly. + Q: a Laurent poly. + + Returns: + contains the following elements: + - list_theta: angles for :math:`R_Y` gates; + - list_phi: angles for :math:`R_Z` gates. + + Note: + unlike `yzzyz_angle_finder`, + `yzzyz_angle_approximator` assumes that the only source of error is the precision (which is not generally true). + + """ + list_theta = [] + list_phi = [] + + # backup P for output check + P_copy = copy(P) + + L = P.deg + while L > 0: + theta, phi = update_angle([P.coef[-1], P.coef[0], Q.coef[-1], Q.coef[0]]) + + list_theta.append(theta) + list_phi.append(phi) + + P, Q = update_polynomial(P, Q, theta, phi, verify=False) + + L -= 1 + P, Q = P.reduced_poly(L), Q.reduced_poly(L) + + # decide theta[0], phi[0] and global phase alpha + p_0, q_0 = P.coef[0], Q.coef[0] + alpha, theta, phi = yz_decomposition(np.array([[p_0, -q_0], [np.conj(q_0), np.conj(p_0)]])) + list_theta.append(theta) + list_phi.append(phi) + + # test outputs, by 5 random data points in [-pi, pi] + err_list = [] + list_x = (np.random.rand(5) * 2 - 1) * np.pi + for x in list_x: + experiment_y = matrix_generation(list_theta, list_phi, x, alpha)[0, 0] + actual_y = P_copy(np.exp(1j * x / 2)) + + err = np.abs(experiment_y + actual_y) if np.abs(experiment_y / actual_y + 1) < 1e-2 else np.abs(experiment_y - actual_y) + err_list.append(err) + print(f"Computations of angles for QPP are completed with mean error {np.mean(err_list)}") + + return list_theta, list_phi + + +# ------------------------------------------------- Split line ------------------------------------------------- +r""" + Belows are support functions for angles computation. +""" + + +def update_angle(coef: List[complex]) -> Tuple[float, float]: + r"""Compute angles by `coef` from `P` and `Q`. + + Args: + coef: the first and last terms from `P` and `Q`. + + Returns: + `theta` and `phi`. + + """ + # with respect to the first and last terms of P and Q, respectively + p_d, p_nd, q_d, q_nd = coef[0], coef[1], coef[2], coef[3] + if p_d != 0 and q_d != 0: + val = -1 * p_d / q_d + return atan(np.abs(val)) * 2, np.real(np.log(val / np.abs(val)) / (-1j)) + + elif np.abs(p_d) < 1e-25 and np.abs(q_d) < 1e-25: + val = q_nd / p_nd + return atan(np.abs(val)) * 2, np.real(np.log(val / np.abs(val)) / (-1j)) + + elif np.abs(p_d) < 1e-25 and np.abs(q_nd) < 1e-25: + return 0, 0 + + elif np.abs(p_nd) < 1e-25 and np.abs(q_d) < 1e-25: + return np.pi, 0 + + raise ValueError( + f"Coef error: check these four coef {[p_d, p_nd, q_d, q_nd]}") + + +def update_polynomial(P: Laurent, Q: Laurent, theta: float, phi: float, verify: Optional[bool] = True) -> Tuple[Laurent, Laurent]: + r"""Update `P` and `Q` by `theta` and `phi`. + + Args: + P: a Laurent poly. + Q: a Laurent poly. + theta: a param. + phi: a param. + verify: whether verify the correctness of computation, defaults to be `True`. + + Returns: + updated `P` and `Q`. + + """ + + phi_hf = phi / 2 + theta_hf = theta / 2 + + X = Laurent([0, 0, 1]) + inv_X = Laurent([1, 0, 0]) + + new_P = (X * P * np.exp(1j * phi_hf) * cos(theta_hf)) + (X * Q * np.exp(-1j * phi_hf) * sin(theta_hf)) + new_Q = (inv_X * Q * np.exp(-1j * phi_hf) * cos(theta_hf)) - (inv_X * P * np.exp(1j * phi_hf) * sin(theta_hf)) + + if not verify: + return new_P, new_Q + + condition_test(new_P, new_Q) + return new_P, new_Q + + +def condition_test(P: Laurent, Q: Laurent) -> None: + r"""Check whether `P` and `Q` satisfy: + - deg(`P`) = deg(`Q`); + - `P` 和 `Q` have the same parity; + - :math:`PP^* + QQ^* = 1`. + + Args: + P: a Laurent poly. + Q: a Laurent poly. + + """ + L = P.deg + + if L != Q.deg: + print("The last and first terms of P: ", P.coef[0], P.coef[-1]) + print("The last and first terms of Q: ", Q.coef[0], Q.coef[-1]) + raise ValueError(f"P's degree {L} does not agree with Q's degree {Q.deg}") + + if P.parity != Q.parity or P.parity != L % 2: + print(f"P's degree is {L}") + raise ValueError(f"P's parity {P.parity} and Q's parity {Q.parity}) should be both {L % 2}") + + poly_one = (P * P.conj) + (Q * Q.conj) + if poly_one != 1: + print(f"P's degree is {L}") + print("the last and first terms of PP* + QQ*: ", poly_one.coef[0], poly_one.coef[-1]) + raise ValueError("PP* + QQ* != 1: check your code") + + +def matrix_generation(list_theta: List[float], list_phi: List[float], x: float, alpha: Optional[float] = 0) -> np.ndarray: + r"""Return the matrix generated by sets of angles. + + Args: + list_theta: angles for :math:`R_Y` gates. + list_phi: angles for :math:`R_Z` gates. + x: input of polynomial P + alpha: global phase + + Returns: + unitary matrix generated by YZZYZ circuit + + """ + assert len(list_theta) == len(list_phi) + L = len(list_theta) - 1 + + cir = Circuit(1) + for i in range(L): + cir.rz(0, param=list_phi[i]) + cir.ry(0, param=list_theta[i]) + cir.rz(0, param=x) # input x + cir.rz(0, param=list_phi[-1]) + cir.ry(0, param=list_theta[-1]) + + return cir.unitary_matrix().numpy() * alpha + + +def yz_decomposition(U: np.ndarray) -> Tuple[complex, float, float]: + r"""Return the YZ decomposition of U. + + Args: + U: single-qubit unitary. + + Returns: + `alpha`, `theta`, `phi` st. :math:`U[0, 0] = \alpha R_Y(\theta) R_Z(\phi) [0, 0]`. + + """ + a, b = U[0, 0], U[0, 1] + x, y, p, q = np.real(a), np.imag(a), np.real(b), np.imag(b) + + phi = np.pi if x == p == 0 else np.arctan(-y / x) - np.arctan(-q / p) + theta = 2 * np.arctan(np.sqrt((p ** 2 + q ** 2) / (x ** 2 + y ** 2))) + + alpha = -a / (cos(phi / 2) * cos(theta / 2) - 1j * sin(phi / 2) * cos(theta / 2)) + assert np.abs(np.abs(alpha) - 1) < 1e-5, f"Calculation error for absolute global phase {np.abs(alpha)}, check your code." + + if np.abs((cos(theta / 2) * np.exp(1j * phi / 2)) * alpha / a + 1) < 1e-6: + alpha = -alpha + return alpha, theta, phi + \ No newline at end of file diff --git a/paddle_quantum/qpp/laurent.py b/paddle_quantum/qpp/laurent.py new file mode 100644 index 0000000..28d27e6 --- /dev/null +++ b/paddle_quantum/qpp/laurent.py @@ -0,0 +1,677 @@ +# !/usr/bin/env python3 +# Copyright (c) 2022 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. +import numpy as np +import warnings +from numpy.polynomial.polynomial import Polynomial, polyfromroots +from scipy.special import jv as Bessel +from typing import Any, Callable, List, Optional, Tuple, Union + +r""" +Definition of ``Laurent`` class and its functions +""" + + +__all__ = ['Laurent', 'revise_tol', 'remove_abs_error', 'random_laurent_poly', + 'sqrt_generation', 'Q_generation', 'pair_generation', + 'laurent_generator', 'hamiltonian_laurent', 'ln_laurent', 'power_laurent'] + + +TOL = 1e-30 # the error tolerance for Laurent polynomial, default to be machinery + + +class Laurent(object): + r"""Class for Laurent polynomial defined as + :math:`P:\mathbb{C}[X, X^{-1}] \to \mathbb{C} :x \mapsto \sum_{j = -L}^{L} p_j X^j`. + + Args: + coef: list of coefficients of Laurent poly, arranged as :math:`\{p_{-L}, ..., p_{-1}, p_0, p_1, ..., p_L\}`. + + """ + def __init__(self, coef: np.ndarray) -> None: + if not isinstance(coef, np.ndarray): + coef = np.array(coef) + coef = coef.astype('complex128') + coef = remove_abs_error(np.squeeze(coef) if len(coef.shape) > 1 else coef) + assert len(coef.shape) == 1 and coef.shape[0] % 2 == 1 + + # if the first and last terms are both 0, remove them + while len(coef) > 1 and coef[0] == coef[-1] == 0: + coef = coef[1:-1] + + # decide degree of this poly + L = (len(coef) - 1) // 2 if len(coef) > 1 else 0 + + # rearrange the coef in order p_0, ..., p_L, p_{-L}, ..., p_{-1}, + # then we can call ``poly_coef[i]`` to retrieve p_i, this order is for internal use only + coef = coef.tolist() + poly_coef = np.array(coef[L:] + coef[:L]).astype('complex128') + + self.deg = L + self.__coef = poly_coef + + def __call__(self, X: Union[int, float, complex]) -> complex: + r"""Evaluate the value of P(X). + """ + if X == 0: + return self.__coef[0] + + return sum(self.__coef[i] * (X ** i) for i in range(-self.deg, self.deg + 1)) + + @property + def coef(self) -> np.ndarray: + r"""The coefficients of this polynomial in ascending order (of indices). + """ + return ascending_coef(self.__coef) + + @property + def conj(self) -> 'Laurent': + r"""The conjugate of this polynomial i.e. :math:`P(x) = \sum_{j = -L}^{L} p_{-j}^* X^j`. + """ + coef = np.copy(self.__coef) + for i in range(1, self.deg + 1): + coef[i], coef[-i] = coef[-i], coef[i] + coef = np.conj(coef) + return Laurent(ascending_coef(coef)) + + @property + def roots(self) -> List[complex]: + r"""List of roots of this polynomial. + """ + # create the corresponding (common) polynomial with degree 2L + P = Polynomial(self.coef) + roots = P.roots().tolist() + return sorted(roots, key=lambda x: np.abs(x)) + + @property + def norm(self) -> float: + r"""The square sum of absolute value of coefficients of this polynomial. + """ + return np.sum(np.square(np.abs(self.__coef))) + + @property + def max_norm(self) -> float: + r"""The maximum of absolute value of coefficients of this polynomial. + """ + list_x = np.exp(-1j * np.arange(-np.pi, np.pi + 0.005, 0.005) / 2) + return max(np.abs(self(x)) for x in list_x) + + @property + def parity(self) -> int: + r""" Parity of this polynomial. + """ + coef = np.copy(self.__coef) + + even = not any(i % 2 != 0 and coef[i] != 0 for i in range(-self.deg, self.deg + 1)) + odd = not any(i % 2 != 1 and coef[i] != 0 for i in range(-self.deg, self.deg + 1)) + + if even: + return 0 + return 1 if odd else None + + def __copy__(self) -> 'Laurent': + r"""Copy of Laurent polynomial. + """ + return Laurent(ascending_coef(self.__coef)) + + def __add__(self, other: Any) -> 'Laurent': + r"""Addition of Laurent polynomial. + + Args: + other: scalar or a Laurent polynomial :math:`Q(x) = \sum_{j = -L}^{L} q_{j} X^j`. + + """ + coef = np.copy(self.__coef) + + if isinstance(other, (int, float, complex)): + coef[0] += other + + elif isinstance(other, Laurent): + if other.deg > self.deg: + return other + self + + deg_diff = self.deg - other.deg + + # retrieve the coef of Q + q_coef = other.coef + q_coef = np.concatenate([q_coef[other.deg:], np.zeros(2 * deg_diff), + q_coef[:other.deg]]).astype('complex128') + coef += q_coef + + else: + raise TypeError( + f"does not support the addition between Laurent and {type(other)}.") + + return Laurent(ascending_coef(coef)) + + def __mul__(self, other: Any) -> 'Laurent': + r"""Multiplication of Laurent polynomial. + + Args: + other: scalar or a Laurent polynomial :math:`Q(x) = \sum_{j = -L}^{L} q_{j} X^j`. + + """ + p_coef = np.copy(self.__coef) + + if isinstance(other, (int, float, complex)): + new_coef = p_coef * other + + elif isinstance(other, Laurent): + # retrieve the coef of Q + q_coef = other.coef.tolist() + q_coef = np.array(q_coef[other.deg:] + q_coef[:other.deg]).astype('complex128') + + L = self.deg + other.deg # deg of new poly + new_coef = np.zeros([2 * L + 1]).astype('complex128') + + # (P + Q)[X^n] = \sum_{j, k st. j + k = n} p_j q_k + for j in range(-self.deg, self.deg + 1): + for k in range(-other.deg, other.deg + 1): + new_coef[j + k] += p_coef[j] * q_coef[k] + + else: + raise TypeError( + f"does not support the multiplication between Laurent and {type(other)}.") + + return Laurent(ascending_coef(new_coef)) + + def __sub__(self, other: Any) -> 'Laurent': + r"""Subtraction of Laurent polynomial. + + Args: + other: scalar or a Laurent polynomial :math:`Q(x) = \sum_{j = -L}^{L} q_{j} X^j`. + + """ + return self.__add__(other=other * -1) + + def __eq__(self, other: Any) -> bool: + r"""Equality of Laurent polynomial. + + Args: + other: a Laurent polynomial :math:`Q(x) = \sum_{j = -L}^{L} q_{j} X^j`. + + """ + if isinstance(other, (int, float, complex)): + p_coef = self.__coef + constant_term = p_coef[0] + return self.deg == 0 and np.abs(constant_term - other) < 1e-6 + + elif isinstance(other, Laurent): + p_coef = self.coef + q_coef = other.coef + return self.deg == other.deg and np.max(np.abs(p_coef - q_coef)) < 1e-6 + + else: + raise TypeError( + f"does not support the equality between Laurent and {type(other)}.") + + def __str__(self) -> str: + r"""Print of Laurent polynomial. + + """ + coef = np.around(self.__coef, 3) + L = self.deg + + print_str = "info of this Laurent poly is as follows\n" + print_str += f" - constant: {coef[0]} - degree: {L}\n" + if L > 0: + print_str += f" - coef of terms from pos 1 to pos {L}: {coef[1:L + 1]}\n" + print_str += f" - coef of terms from pos -1 to pos -{L}: {np.flip(coef[L + 1:])}\n" + return print_str + + def is_parity(self, p: int) -> Tuple[bool, complex]: + r"""Whether this Laurent polynomial has parity :math:`p % 2`. + + Args: + p: parity. + + Returns + contains the following elements: + * whether parity is p % 2; + * if not, then return the the (maximum) absolute coef term breaking such parity; + * if not, then return the the (minimum) absolute coef term obeying such parity. + + """ + p %= 2 + coef = np.copy(self.__coef) + + disagree_coef = [] + agree_coef = [] + for i in range(-self.deg, self.deg + 1): + c = coef[i] + if i % 2 != p and c != 0: + disagree_coef.append(c) + elif i % 2 == p: + agree_coef.append(c) + + return (False, max(np.abs(disagree_coef)), min(np.abs(agree_coef))) if disagree_coef else (True, None, None) + + def reduced_poly(self, target_deg: int) -> 'Laurent': + r"""Generate :math:`P'(x) = \sum_{j = -D}^{D} p_j X^j`, where :math:`D \leq L` is `target_deg`. + + Args: + target_deg: the degree of returned polynomial + + """ + coef = self.coef + L = self.deg + return Laurent(coef[L - target_deg:L + 1 + target_deg]) if target_deg <= L else Laurent(coef) + + +# ------------------------------------------------- Split line ------------------------------------------------- +r""" + Belows are support functions for `Laurent` class +""" + + +def revise_tol(t: float) -> None: + r"""Revise the value of `TOL`. + """ + global TOL + assert t > 0 + TOL = t + + +def ascending_coef(coef: np.ndarray) -> np.ndarray: + r"""Transform the coefficients of a polynomial in ascending order (of indices). + + Args: + coef: list of coefficients arranged as :math:`\{ p_0, ..., p_L, p_{-L}, ..., p_{-1} \}`. + + Returns: + list of coefficients arranged as :math:`\{ p_{-L}, ..., p_{-1}, p_0, p_1, ..., p_L \}`. + + """ + L = int((len(coef) - 1) / 2) + coef = coef.tolist() + return np.array(coef[L + 1:] + coef[:L + 1]) + + +def remove_abs_error(data: np.ndarray, tol: Optional[float] = None) -> np.ndarray: + r"""Remove the error in data array. + + Args: + data: data array. + tol: error tolerance. + + Returns: + sanitized data. + + """ + data_len = len(data) + tol = TOL if tol is None else tol + + for i in range(data_len): + if np.abs(np.real(data[i])) < tol: + data[i] = 1j * np.imag(data[i]) + elif np.abs(np.imag(data[i])) < tol: + data[i] = np.real(data[i]) + + if np.abs(data[i]) < tol: + data[i] = 0 + return data + + +# ------------------------------------------------- Split Line ------------------------------------------------- +r""" + Belows are some functions using `Laurent` class +""" + + +def random_laurent_poly(deg: int, parity: Optional[int] = None, is_real: Optional[bool] = False) -> Laurent: + r"""Randomly generate a Laurent polynomial. + + Args: + deg: degree of this poly. + parity: parity of this poly, defaults to be `None`. + is_real: whether coefficients of this poly are real, defaults to be `False`. + + Returns: + a Laurent poly with norm less than or equal to 1. + + """ + real = np.random.rand(deg * 2 + 1) * 2 - 1 + imag = np.zeros(deg * 2 + 1) if is_real else np.random.rand(deg * 2 + 1) * 2 - 1 + + coef = real + 1j * imag + coef /= np.sum(np.abs(coef)) + + if parity is not None: + coef = coef.tolist() + coef = coef[deg:] + coef[:deg] + for i in range(-deg, deg + 1): + if i % 2 != parity: + coef[i] = 0 + coef = np.array(coef[deg + 1:] + coef[:deg + 1]) + + return Laurent(coef) + + +def sqrt_generation(A: Laurent) -> Laurent: + r"""Generate the "square root" of a Laurent polynomial :math:`A`. + + Args: + A: a Laurent polynomial. + + Returns: + a Laurent polynomial :math:`Q` such that :math:`QQ^* = A`. + + Notes: + More details are in Lemma S1 of the paper https://arxiv.org/abs/2209.14278. + + """ + leading_coef = A.coef[-1] + roots = A.roots + + roots_dict = dict({}) + def has_key(y: complex) -> Tuple[bool, complex]: + r"""Test whether `y` is the key of roots_dict. + + Returns: + contains the following elements: + * boolean for whether `y` is the key of roots_dict. + * the key matched (under certain error tolerance) or `None`. + + """ + list_key = list(roots_dict.keys()) + for key in list_key: + # you can adjust this tolerance if the below assertion fails + if np.abs(key - y) < 1e-6: + return True, key + return False, None + + # begin filtering roots + inv_roots = [] + for x in roots: + inv_x = 1 / np.conj(x) + + is_key, key = has_key(x) + + # if x match with a existed key, save x + if is_key: + assert not has_key(inv_x)[0], \ + f"{x} and {inv_x} should not be in the same list, check your code; it is perhaps a precision problem." + roots_dict[key] += 1 + + # if neither x nor its inverse conjugate match, save x + elif not has_key(inv_x)[0]: + roots_dict[x] = 1 + + # otherwise (i.e. inv_x with a existed key, save x), filter x + else: + inv_roots.append(x) + + # 1/x^* should be filtered from the list of roots, now update the roots of Q + Q_roots = [] + for key in roots_dict: + for _ in range(roots_dict[key]): + Q_roots.append(key) + + # be careful that the number of filtered roots should be identical with that of the saved roots + if len(Q_roots) != len(inv_roots): + warnings.warn( + "\nError occurred in square root decomposition of polynomial: " + + f"# of total, saved and filtered roots are {len(roots)}, {len(Q_roots)}, {len(inv_roots)}." + + "\n Will force equal size of saved and filtered root list to mitigate the error") + excess_roots, Q_roots = Q_roots[len(inv_roots):], Q_roots[:len(inv_roots)] + excess_roots.sort(key=lambda x: np.real(x)) # sort by real part + + for i in range(len(excess_roots) // 2): + Q_roots.append(excess_roots[2 * i]) + inv_roots.append(excess_roots[2 * i + 1]) + inv_roots = np.array(inv_roots) + + # construct Q + Q_coef = polyfromroots(Q_roots) * np.sqrt(leading_coef * np.prod(inv_roots)) + Q = Laurent(Q_coef) + + # final output test + if Q * Q.conj != A: + warnings.warn( + f"\ncomputation error: QQ* != A, check your code \n degree of Q: {Q.deg}, degree of A: {A.deg}") + + return Q + + +def Q_generation(P: Laurent) -> Laurent: + r"""Generate a Laurent complement for Laurent polynomial :math:`P`. + + Args: + P: a Laurent poly with parity :math:`L` and degree :math:`L`. + + Returns: + a Laurent poly :math:`Q` st. :math:`PP^* + QQ^* = 1`, with parity :math:`L` and degree :math:`L`. + + """ + assert P.parity is not None and P.parity == P.deg % 2, \ + "this Laurent poly does not satisfy the requirement for parity" + assert P.max_norm < 1, \ + f"the max norm {P.max_norm} of this Laurent poly should be smaller than 1" + + Q2 = P * P.conj * -1 + 1 + Q = sqrt_generation(Q2) + + is_parity, max_diff, min_val = Q.is_parity(P.parity) + if not is_parity: + warnings.warn( + f"\nQ's parity {Q.parity} does not agree with P's parity {P.parity}, max err is {max_diff}, min val is {min_val}") + + return Q + + +def pair_generation(f: Laurent) -> Laurent: + r""" Generate Laurent pairs for Laurent polynomial :math:`f`. + + Args: + f: a real-valued and even Laurent polynomial, with max_norm smaller than 1. + + Returns: + Laurent polys :math:`P, Q` st. :math:`P = \sqrt{1 + f / 2}, Q = \sqrt{1 - f / 2}`. + + """ + assert f.max_norm < 1, \ + f"the max norm {f.max_norm} of this Laurent poly should be smaller than 1" + assert f.parity == 0, \ + "the parity of this Laurent poly should be 0" + expect_parity = (f.deg // 2) % 2 + P, Q = sqrt_generation((f + 1) * 0.5), sqrt_generation((f * (-1) + 1) * 0.5) + + is_parity, max_diff, min_val = P.is_parity(expect_parity) + if not is_parity: + warnings.warn( + f"\nP's parity {P.parity} does not agree with {expect_parity}, max err is {max_diff}, min val is {min_val}", UserWarning) + + is_parity, max_diff, min_val = Q.is_parity(expect_parity) + if not is_parity: + warnings.warn( + f"\nQ's parity {Q.parity} does not agree with {expect_parity}, max err is {max_diff}, min val is {min_val}", UserWarning) + return P, Q + + +# ------------------------------------------------- Split line ------------------------------------------------- +r""" + Belows are tools for trigonometric approximation. +""" + + +def laurent_generator(fn: Callable[[np.ndarray], np.ndarray], dx: float, deg: int, L: float) -> Laurent: + r"""Generate a Laurent polynomial (with :math:`X = e^{ix / 2}`) approximating `fn`. + + Args: + fn: function to be approximated. + dx: sampling frequency of data points. + deg: degree of Laurent poly. + L: half of approximation width. + + Returns: + a Laurent polynomial approximating `fn` in interval :math:`[-L, L]` with degree `deg`. + + """ + assert dx > 0 and L > 0 and deg >= 0 + + N = 2 * L / dx + coef = np.zeros(deg + 1, dtype=np.complex128) + xk = np.arange(-L, L + dx, dx) + + # Calculate the coefficients for each term + for mi in range(deg + 1): + n = mi - deg / 2 + coef[mi] = 1 / N * sum(fn(xk) * np.exp(-1j * n * np.pi * xk / L)) + + coef = np.array([coef[i // 2] if i % 2 == 0 else 0 for i in range(deg * 2 + 1)]) + + return Laurent(coef) + + +def deg_finder(fn: Callable[[np.ndarray], np.ndarray], + delta: Optional[float] = 0.00001 * np.pi, l: Optional[float] = np.pi) -> int: + r"""Find a degree such that the Laurent polynomial generated from `laurent_generator` has max_norm smaller than 1. + + Args: + fn: function to be approximated. + dx: sampling frequency of data points, defaults to be :math:`0.00001 \pi`. + L: half of approximation width, defaults to be :math:`\pi`. + + Returns: + the degree of approximation: + + Notes: + used to fix the problem of function `laurent_generator`. + + """ + deg = 50 + acc = 1 + P = laurent_generator(fn, delta, deg, l) + while P.max_norm > 1: + deg += acc * 50 + P = laurent_generator(fn, delta, deg, l) + acc += 1 + assert deg <= 10000, "degree too large" + return deg + + +def step_laurent(deg: int) -> Laurent: + r"""Generate a Laurent polynomial approximating the step function. + + Args: + deg: (even) degree of the output Laurent poly. + + Returns: + a Laurent poly approximating :math:`f(x) = 0.5` if :math:`x <= 0` else :math:`0`. + + Notes: + used in Hamiltonian energy solver + + """ + assert deg % 2 == 0 + deg //= 2 + coef = np.zeros(2 * deg + 1).astype('complex128') + for n in range(-deg, deg + 1): + if n != 0: + coef[n] = (0.025292684335809737j + + 0.11253953951963828j * np.exp(-np.pi * 1j * n) - + 0.13783222385544802j * np.exp(np.pi * 1j * n)) / n + else: + coef[n] = 0.7865660924854931 + coef = ascending_coef(coef) + coef = np.array([coef[i // 2] if i % 2 == 0 else 0 for i in range(4 * deg + 1)]) + return Laurent(coef) + + +def hamiltonian_laurent(t: float, deg: int) -> Laurent: + r"""Generate a Laurent polynomial approximating the Hamiltonian evolution function. + + Args: + t: evolution constant (time). + deg: (even) degree of the output Laurent poly. + + Returns: + a Laurent poly approximating :math:`e^{it \cos(x)}`. + + Note: + - originated from the Jacobi-Anger expansion: :math:`y(x) = \sum_n i^n Bessel(n, x) e^{inx}`; + - used in Hamiltonian simulation. + + """ + assert deg % 2 == 0 + deg //= 2 + coef = np.zeros(2 * deg + 1).astype('complex128') + for n in range(-deg, deg + 1): + coef[n] = (1j ** n) * Bessel(n, t) + + coef = ascending_coef(coef) + coef = np.array([coef[i // 2] if i % 2 == 0 else 0 for i in range(4 * deg + 1)]) + return Laurent(coef) + + +def ln_laurent(deg: int, t: float) -> Laurent: + r"""Generate a Laurent polynomial approximating the ln function. + + Args: + deg: degree of Laurent polynomial that is a factor of 4. + t: normalization factor. + + Returns: + a Laurent poly approximating :math:`ln(cos(x)^2) / t`. + + Notes: + used in von Neumann entropy estimation. + + """ + assert deg % 4 == 0 + deg //= 2 + coef = np.zeros(2 * deg + 1).astype('complex128') + + for k in range(1, deg + 1): + for j in range(2 * k + 1): + coef[2 * j - 2 * k] += ((-1) ** (k + j + 1)) / t / k * (0.25 ** k) * comb(2 * k, j) + + coef = ascending_coef(coef) + coef = np.array([coef[i // 2] if i % 2 == 0 else 0 for i in range(4 * deg + 1)]) + return Laurent(coef) + + +def comb(n: float, k: int) -> float: + r"""Compute nCr(n, k). + """ + prod = 1 + for i in range(k): + prod *= (n - i) / (k - i) + return prod + + +def power_laurent(deg: int, alpha: float, t: float) -> Laurent: + r"""Generate a Laurent polynomial approximating the power function. + + Args: + deg: degree of Laurent polynomial that is a factor of 4. + alpha: the # of power. + t: normalization factor. + + Returns: + a Laurent poly approximating :math:`(cos(x)^2)^{\alpha / 2} / t`. + + """ + assert deg % 4 == 0 and alpha != 0 and alpha > -1 + alpha /= 2 + deg //= 2 + coef = np.zeros(2 * deg + 1).astype('complex128') + + for k in range(deg + 1): + for j in range(2 * k + 1): + coef[2 * j - 2 * k] += ((-1) ** j) / t * comb(alpha, k) * (0.25 ** k) * comb(2 * k, j) + + coef = ascending_coef(coef) + coef = np.array([coef[i // 2] if i % 2 == 0 else 0 for i in range(4 * deg + 1)]) + return Laurent(coef) diff --git a/paddle_quantum/qpp/utils.py b/paddle_quantum/qpp/utils.py new file mode 100644 index 0000000..720c7d7 --- /dev/null +++ b/paddle_quantum/qpp/utils.py @@ -0,0 +1,309 @@ +# !/usr/bin/env python3 +# Copyright (c) 2022 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. +import numpy as np +import paddle + +from typing import Callable, Optional, Tuple, Union +from math import log2 + +from .angles import qpp_angle_finder, qpp_angle_approximator +from .laurent import Q_generation, pair_generation, laurent_generator, revise_tol + +from ..ansatz import Circuit +from ..backend import Backend +from ..base import get_dtype +from ..gate import X +from ..intrinsic import _get_float_dtype +from ..linalg import unitary_random, is_unitary +from ..loss import Measure +from ..operator import Collapse +from ..qinfo import dagger, partial_trace +from ..state import State, _type_transform, zero_state + + +r""" +QPP circuit and related tools, see Theorem 6 in paper https://arxiv.org/abs/2209.14278 for more details. +""" + + +__all__ = ["qpp_cir", "simulation_cir", "qps", "qubitize", "purification_block_enc"] + + +def qpp_cir( + list_theta: Union[np.ndarray, paddle.Tensor], + list_phi: Union[np.ndarray, paddle.Tensor], + U: Union[np.ndarray, paddle.Tensor, float], +) -> Circuit: + r"""Construct a quantum phase processor of QPP by `list_theta` and `list_phi`. + + Args: + list_theta: angles for :math:`R_Y` gates. + list_phi: angles for :math:`R_Z` gates. + U: unitary or scalar input. + + Returns: + a multi-qubit version of trigonometric QSP. + + """ + complex_dtype = get_dtype() + float_dtype = _get_float_dtype(complex_dtype) + + if not isinstance(list_theta, paddle.Tensor): + list_theta = paddle.to_tensor(list_theta, dtype=float_dtype) + if not isinstance(list_phi, paddle.Tensor): + list_phi = paddle.to_tensor(list_phi, dtype=float_dtype) + if not isinstance(U, paddle.Tensor): + U = paddle.to_tensor(U, dtype=complex_dtype) + if len(U.shape) == 1: + U = U.cast(float_dtype) + list_theta, list_phi = np.squeeze(list_theta), np.squeeze(list_phi) + + assert len(list_theta) == len(list_phi) + n = int(log2(U.shape[0])) + L = len(list_theta) - 1 + + cir = Circuit(n + 1) + all_register = list(range(n + 1)) + + for i in range(L): + cir.rz(0, param=list_phi[i]) + cir.ry(0, param=list_theta[i]) + + # input the unitary + if len(U.shape) == 1: + cir.rz(0, param=U) + elif i % 2 == 0: + cir.control_oracle(U, all_register, latex_name=r"$U$") + else: + cir.x(0) + cir.control_oracle(dagger(U), all_register, latex_name=r"$U^\dagger$") + cir.x(0) + cir.rz(0, param=list_phi[-1]) + cir.ry(0, param=list_theta[-1]) + + return cir + + +def simulation_cir( + fn: Callable[[np.ndarray], np.ndarray], + U: Union[np.ndarray, paddle.Tensor, float], + approx: Optional[bool] = True, + deg: Optional[int] = 50, + length: Optional[float] = np.pi, + step_size: Optional[float] = 0.00001 * np.pi, + tol: Optional[float] = 1e-30, +) -> Circuit: + r"""Return a QPP circuit approximating `fn`. + + Args: + fn: function to be approximated. + U: unitary input. + deg: degree of approximation, defaults to be :math:`50`. + approx: whether approximately find the angle of circuits, defaults to be ``True`` + length: half of approximation width, defaults to be :math:`\pi`. + step_size: sampling frequency of data points, defaults to be :math:`0.00001 \pi`. + tol: error tolerance, defaults to be :math:`10^{-30}`. + + Returns: + a QPP circuit approximating `fn` in Theorem 6 of paper https://arxiv.org/abs/2209.14278. + + """ + f = laurent_generator(fn, step_size, deg, length) + if np.abs(f.max_norm - 1) < 1e-2: + f = f * (0.999999999 / f.max_norm) + P, Q = pair_generation(f) + revise_tol(tol) + list_theta, list_phi = ( + qpp_angle_approximator(P, Q) if approx else qpp_angle_finder(P, Q) + ) + + return qpp_cir(list_theta, list_phi, U) + + +def qps( + U: Union[np.ndarray, paddle.Tensor], + initial_state: Union[np.ndarray, paddle.Tensor, State], +) -> Tuple[float, State]: + r"""Algorithm for quantum phase search, see Algorithm 1 and 2 of paper https://arxiv.org/abs/2209.14278. + + Args: + U: target unitary + initial_state: the input quantum state + + Returns: + contains the following two elements: + * an eigenphase of U + * its corresponding eigenstate that has overlap with the initial state + + """ + assert is_unitary(U) + U, initial_state = _type_transform(U, "tensor"), _type_transform( + initial_state, "state_vector" + ) + initial_state = zero_state(1).kron(initial_state) + + def p_func(x): + target = 2.0 * np.arctan(np.sin(x) / 0.01) / np.pi + return np.sqrt((1 + target) / 2) + + # function approximation + P = laurent_generator(p_func, 0.00001 * np.pi, 160, np.pi) + Q = Q_generation(P) + list_theta, list_phi = qpp_angle_approximator(P, Q) + + # Algorithm setting + T, Q, Delta = 13, 10, 0.2 + Delta_bar = Delta + np.pi / (2 ** (Q + 1)) + + op_M = Measure() # measurement + op_C = [ + Collapse(0, desired_result="0"), + Collapse(0, desired_result="1"), + ] # collapse operator + op_X = X(0) # x gate used to reset the first qubit + + def __measure_and_collapse(target_state: State) -> Tuple[float, State]: + r"""Measure ``target_state``, and return the measurement outcome and collapsed state""" + prob_dist = op_M(target_state, 0).tolist() + result = np.random.choice(2, 1, p=prob_dist)[0] + return result, op_C[result](target_state) + + def __interval_search( + U: paddle.Tensor, input_state: State, interval: Tuple[int, int] + ) -> Tuple[int, int]: + r"""Find a smaller interval containing eigenphases from ``interval``, Algorithm 1.""" + x_low, x_up = interval[0], interval[1] + theta = (x_up + x_low) / 2 + state = input_state.clone() + + # if the interval is too wide, the update rule is different + if x_up - x_low > 2 * np.pi - 2 * Delta: + state = qpp_cir(list_theta, list_phi, np.exp(-1j * theta).item() * U)(state) + result, state = __measure_and_collapse(state) + if result == 0: + x_low = -Delta + x_up += Delta + else: + x_low -= Delta + x_up = Delta + state = op_X(state) + theta = (x_up + x_low) / 2 + + # begin interval search formally + for _ in range(Q): + state = qpp_cir(list_theta, list_phi, np.exp(-1j * theta).item() * U)(state) + result, state = __measure_and_collapse(state) + + # update the interval according to the measurement result of the first qubit + # - if the measurement result is 0, choose the RHS interval + # - otherwise, choose the LHS and reset the first qubit + if result == 0: + x_low = theta - Delta + else: + x_up = theta + Delta + state = op_X(state) + + theta = (x_up + x_low) / 2 + + return [x_low, x_up], state + + # Algorithm 2 + phase_estimate = 0 + p = int(np.round(1 / Delta_bar)) + itr_interval = [-np.pi, np.pi] + itr_state = initial_state + for j in range(T): + itr_interval, itr_state = __interval_search(U, itr_state, itr_interval) + + lamb = (itr_interval[0] + itr_interval[1]) / 2 + phase_estimate += lamb * (Delta**j) + + # update unitary and interval, so that we can start a new interval search + U = np.linalg.matrix_power(U, p) * np.exp(-1j * p * lamb) + itr_interval = ((np.array(itr_interval) - lamb) * p).tolist() + + return phase_estimate, partial_trace(itr_state, 2**1, U.shape[0], A_or_B=1) + + +def qubitize( + block_enc: Union[np.ndarray, paddle.Tensor], num_block_qubits: int +) -> paddle.Tensor: + r"""Qubitize the block encoding to keep subspace invariant using one more ancilla qubit, + see paper http://arxiv.org/abs/1610.06546 for more details. + + Args: + block_enc: the target block encoding. + num_block_qubits: number of ancilla qubits used in block encoding. + + Returns: + the qubitized version for ``block_enc``. + + """ + if isinstance(block_enc, np.ndarray): + block_enc = paddle.to_tensor(block_enc) + n = int(log2(block_enc.shape[0])) + cir = Circuit(n + 1) + cir.h(0) + + cir.x(0) + cir.control_oracle(block_enc, list(range(n + 1))) + cir.x(0) + cir.control_oracle(dagger(block_enc), list(range(n + 1))) + cir.x(0) + + cir.h(0) + + num_qubits = n - num_block_qubits + zero_states = zero_state(num_block_qubits, backend=Backend.DensityMatrix) + zero_projector = paddle.kron( + 2 * zero_states.data - paddle.eye(2**num_block_qubits), + paddle.eye(2**num_qubits), + ) + return (cir.unitary_matrix() @ zero_projector).cast(block_enc.dtype) + + +def purification_block_enc(num_qubits: int, num_block_qubits: int) -> paddle.Tensor: + r"""Randomly generate a :math:`(n + m)`-qubit qubitized block encoding of a :math:`n`-qubit density matrix. + + Args: + num_qubits: number of qubits :math:`n`. + num_block_qubits: number of ancilla qubits :math:`m > n` used in block encoding. + + Returns: + a :math:`2^{n + m} \times 2^{n + m}` unitary matrix that its upper-left block is a density matrix. + + """ + assert ( + num_qubits < num_block_qubits + ), f"the number of block qubits need to be larger than the number of qubits {num_qubits}: received {num_block_qubits}" + + V = unitary_random(num_block_qubits) + aux1_reg = list(range(num_block_qubits - num_qubits)) + aux2_reg = list(range(num_block_qubits - num_qubits, num_block_qubits)) + sys_reg = list(range(num_block_qubits, num_qubits + num_block_qubits)) + + cir = Circuit(num_qubits + num_block_qubits) + cir.oracle(V, aux1_reg + aux2_reg) + + for i in range(num_qubits): + cir.swap([aux2_reg[i], sys_reg[i]]) + + cir.oracle(dagger(V), aux1_reg + aux2_reg) + zero_states = paddle.eye(2**num_block_qubits, 1) + reflector = 2 * zero_states @ dagger(zero_states) - paddle.eye( + 2**num_block_qubits + ) + cir.oracle(reflector, list(range(num_block_qubits))) + return cir.unitary_matrix() diff --git a/paddle_quantum/state/__init__.py b/paddle_quantum/state/__init__.py index 86a7900..4bf7a72 100644 --- a/paddle_quantum/state/__init__.py +++ b/paddle_quantum/state/__init__.py @@ -17,7 +17,8 @@ The module of the quantum state. """ -from .state import State +from .state import State, is_state_vector, is_density_matrix +from .state import _type_fetch, _type_transform from .common import zero_state from .common import computational_basis from .common import bell_state diff --git a/paddle_quantum/state/state.py b/paddle_quantum/state/state.py index daeffa1..f1e7d54 100644 --- a/paddle_quantum/state/state.py +++ b/paddle_quantum/state/state.py @@ -21,15 +21,16 @@ import math import matplotlib.pyplot as plt import numpy as np +from scipy.linalg import expm import random + import paddle import QCompute import paddle_quantum from ..backend import Backend from ..backend import state_vector, density_matrix, quleaf from ..hamiltonian import Hamiltonian -from typing import Optional, Union, Iterable - +from typing import Optional, Union, Iterable, Tuple class State(object): r"""The quantum state class. @@ -39,99 +40,215 @@ class State(object): num_qubits: The number of qubits contained in the quantum state. Defaults to ``None``, which means it will be inferred by the data. backend: Used to specify the backend used. Defaults to ``None``, which means to use the default backend. dtype: Used to specify the data dtype of the data. Defaults to ``None``, which means to use the default data type. + override: whether override the input test. ONLY for internal use. Defaults to ``False``. Raises: - Exception: The shape of the data is not correct. - NotImplementedError: If the backend is wrong or not implemented. + ValueError: Cannot recognize the backend. """ def __init__( self, data: Union[paddle.Tensor, np.ndarray, QCompute.QEnv], num_qubits: Optional[int] = None, - backend: Optional[paddle_quantum.Backend] = None, dtype: Optional[str] = None + backend: Optional[paddle_quantum.Backend] = None, dtype: Optional[str] = None, override: Optional[bool] = False ): # TODO: need to check whether it is a legal quantum state super().__init__() self.backend = paddle_quantum.get_backend() if backend is None else backend - if self.backend != Backend.QuLeaf: - if not isinstance(data, paddle.Tensor): - data = paddle.to_tensor(data) - if dtype is not None: - data = paddle.cast(data, dtype) self.dtype = dtype if dtype is not None else paddle_quantum.get_dtype() + if self.backend != Backend.QuLeaf and not isinstance(data, paddle.Tensor): + data = paddle.to_tensor(data, dtype=self.dtype) + self.data = data + + # data input test if self.backend == Backend.StateVector: if data.shape[-1] == 1: - data = paddle.squeeze(data) - self.data = data - if num_qubits is not None: - if data.shape[-1] != 2 ** num_qubits: - raise Exception("The shape of the data should (2 ** num_qubits, ).") - else: - num_qubits = int(math.log2(data.shape[-1])) - assert 2 ** num_qubits == data.shape[-1], "The length of the state should be the integer power of two." + self.data = paddle.squeeze(data) + + if not override: + is_vec, data_message = is_state_vector(data) + assert is_vec, \ + f"The input data is not a legal state vector: error message {data_message}" + assert num_qubits is None or num_qubits == data_message, \ + f"num_qubits does not agree: expected {num_qubits}, received {data_message}" + num_qubits = data_message + elif self.backend == Backend.DensityMatrix: - self.data = data - if num_qubits is not None: - if data.shape[-1] != 2 ** num_qubits or data.shape[-2] != 2 ** num_qubits: - raise Exception("The shape of the data should (2 ** num_qubits, 2 ** num_qubits).") - else: - assert data.shape[-1] == data.shape[-2], "The data should be a square matrix." - num_qubits = int(math.log2(data.shape[-1])) - assert 2 ** num_qubits == data.shape[-1], "The data should be integer power of 2." + + if not override: + is_den, data_message = is_density_matrix(data) + assert is_den, \ + f"The input data is not a legal density matrix: error message {data_message}" + assert num_qubits is None or num_qubits == data_message, \ + f"num_qubits does not agree: expected {num_qubits}, received {data_message}" + num_qubits = data_message + elif self.backend == Backend.UnitaryMatrix: - self.data = data - if num_qubits is not None: - if data.shape[-1] != 2 ** num_qubits or data.shape[-2] != 2 ** num_qubits: - raise Exception("The shape of the data should (2 ** num_qubits, 2 ** num_qubits).") - else: - assert data.shape[-1] == data.shape[-2], "The data should be a square matrix." - num_qubits = int(math.log2(data.shape[-1])) - assert 2 ** num_qubits == data.shape[-1], "The data should be integer power of 2." + # no need to check the state in unitary backend + if num_qubits is None: + num_qubits = int(math.log2(data.shape[0])) + elif self.backend == Backend.QuLeaf: - self.data = data if quleaf.get_quleaf_backend() != QCompute.BackendName.LocalBaiduSim2: assert quleaf.get_quleaf_token() is not None, "You must input token tu use cloud server." self.gate_history = [] self.param_list = [] self.num_param = 0 else: - raise NotImplementedError + raise ValueError( + f"Cannot recognize the backend {self.backend}") self.num_qubits = num_qubits @property def ket(self) -> paddle.Tensor: - r""" return the ket form in state_vector backend + r"""Return the ket form in state_vector backend + + Raises: + ValueError: the backend must be in StateVector Returns: ket form of the state """ if self.backend != Backend.StateVector: - raise Exception("the backend must be in state_vector to raise the ket form of state") + raise ValueError( + f"the backend must be in StateVector: received {self.backend}") return self.data.reshape([2 ** self.num_qubits, 1]) @property def bra(self) -> paddle.Tensor: - r""" return the bra form in state_vector backend + r"""Return the bra form in state_vector backend + + Raises: + ValueError: the backend must be in StateVector Returns: bra form of the state """ if self.backend != Backend.StateVector: - raise Exception("the backend must be in state_vector to raise the bra form of state") + raise ValueError( + f"the backend must be in StateVector: received {self.backend}") return paddle.conj(self.data.reshape([1, 2 ** self.num_qubits])) + + def normalize(self) -> None: + r"""Normalize this state + + Raises: + NotImplementedError: does not support normalization for the backend + """ + data = self.data + if self.backend == Backend.StateVector: + data /= paddle.norm(paddle.abs(data)) + elif self.backend == Backend.DensityMatrix: + data /= paddle.trace(data) + else: + raise NotImplementedError( + f"Does not support normalization for the backend {self.backend}") + self.data = data + + def evolve(self, H: Union[np.ndarray, paddle.Tensor, Hamiltonian], t: float) -> None: + r"""Evolve the state under the Hamiltonian `H` i.e. apply unitary operator :math:`e^{-itH}` + + Args: + H: the Hamiltonian of the system + t: the evolution time + + Raises: + NotImplementedError: does not support evolution for the backend + """ + if isinstance(H, Hamiltonian): + num_qubits = max(self.num_qubits, H.n_qubits) + H = H.construct_h_matrix(qubit_num=num_qubits) + else: + num_qubits = int(math.log2(H.shape[0])) + H = _type_transform(H, "numpy") + assert num_qubits == self.num_qubits, \ + f"the # of qubits of Hamiltonian and this state are not the same: received {num_qubits}, expect {self.num_qubits}" + e_itH = paddle.to_tensor(expm(-1j * t * H), dtype=self.dtype) + + if self.backend == Backend.StateVector: + self.data = paddle.squeeze(e_itH @ self.ket) + elif self.backend == Backend.DensityMatrix: + self.data = e_itH @ self.data @ paddle.conj(e_itH.T) + else: + raise NotImplementedError( + f"Does not support evolution for the backend {self.backend}") + + def kron(self, other: 'State') -> 'State': + r"""Kronecker product between states + + Args: + other: a quantum state + + Returns: + the tensor product of these two states + + """ + backend, dtype = self.backend, self.dtype + assert backend == other.backend, \ + f"backends between two States are not the same: received {backend} and {other.backend}" + assert dtype == other.dtype, \ + f"dtype between two States are not the same: received {dtype} and {other.dtype}" + + if backend == Backend.StateVector: + return State(paddle.kron(self.ket, other.ket), backend=backend) + else: + return State(paddle.kron(self.data, other.data), backend=backend, dtype=dtype) + + def __matmul__(self, other: 'State') -> paddle.Tensor: + r"""Matrix product between states or between tensor and state + + Args: + other: a quantum state + + Raises: + NotImplementedError: does not support the product between State and input format. + ValueError: Cannot multiply two state vectors: check the backend + + Returns: + the product of these two states + """ + if not isinstance(other, State): + raise NotImplementedError( + f"does not support the product between State and {type(other)}") + if self.backend == Backend.StateVector: + raise ValueError( + "Cannot multiply two state vectors: check the backend") + return self.data @ other.data + + def __rmatmul__(self, other: 'State') -> paddle.Tensor: + r"""Matrix product between states or between state and tensor + + Args: + other: a quantum state + + Raises: + NotImplementedError: does not support the product between State and input format. + ValueError: Cannot multiply two state vectors: check the backend + + Returns: + the product of these two states + + """ + if not isinstance(other, State): + raise NotImplementedError( + f"does not support the product between {type(other)} and State") + if self.backend == Backend.StateVector: + raise ValueError( + "Cannot multiply two state vectors: check your backend") + return other.data @ self.data + def numpy(self) -> np.ndarray: - r"""get the data in numpy. + r"""Get the data in numpy. Returns: The numpy array of the data for the quantum state. """ return self.data.numpy() - def to(self, backend: str, dtype: str, device: str, blocking: str): + def to(self, backend: str, dtype: str = None, device: str = None, blocking: str = None) -> None: r"""Change the property of the state. Args: @@ -139,20 +256,31 @@ def to(self, backend: str, dtype: str, device: str, blocking: str): dtype: Specify the new data type of the state. device: Specify the new device of the state. blocking: Specify the new blocking of the state. + + Raises + NotImplementedError: only support transformation between StateVector and DensityMatrix + NotImplementedError: Transformation for device or blocking is not supported. - Returns: - Return a error because this function is not implemented. """ - # TODO: to be implemented - return NotImplementedError + if (backend not in {"state_vector", "density_matrix"} or + self.backend not in {Backend.StateVector, Backend.DensityMatrix}): + raise NotImplementedError( + "Only support transformation between StateVector and DensityMatrix") + + if device is not None or blocking is not None: + raise NotImplementedError( + "Transformation for device or blocking is not supported") + + self.data = _type_transform(self, backend).data + self.dtype = self.dtype if dtype is None else dtype - def clone(self) -> 'paddle_quantum.State': + def clone(self) -> 'State': r"""Return a copy of the quantum state. Returns: A new state which is identical to this state. """ - return State(self.data, self.num_qubits, self.backend, self.dtype) + return State(self.data, self.num_qubits, self.backend, self.dtype, override=True) def __str__(self): return str(self.data.numpy()) @@ -212,17 +340,15 @@ def expec_val(self, hamiltonian: Hamiltonian, shots: Optional[int] = 0) -> float prob_amplitude = paddle.multiply(paddle.conj(state_data), state_data).real() elif self.backend == paddle_quantum.Backend.DensityMatrix: prob_amplitude = paddle.zeros([2 ** self.num_qubits]) - for idx in range(0, 2 ** self.num_qubits): + for idx in range(2 ** self.num_qubits): prob_amplitude[idx] += state_data[idx, idx].real() else: raise NotImplementedError prob_amplitude = prob_amplitude.tolist() - all_case = [bin(element)[2:].zfill(self.num_qubits) for element in range(0, 2 ** self.num_qubits)] + all_case = [bin(element)[2:].zfill(self.num_qubits) for element in range(2 ** self.num_qubits)] samples = random.choices(all_case, weights=prob_amplitude, k=shots) counter = collections.Counter(samples) - measured_results = [] - for key, val in counter.items(): - measured_results.append(([key[idx] for idx in qubits_list], val)) + measured_results = [([key[idx] for idx in qubits_list], val) for key, val in counter.items()] temp_res = sum(((-1) ** key.count('1') * val / shots for key, val in measured_results)) result += coeff * temp_res return result @@ -252,15 +378,11 @@ def measure(self, shots: Optional[int] = 0, qubits_idx: Optional[Union[Iterable[ QCompute.MeasureZ(*state_data.Q.toListPair()) result = state_data.commit(shots, fetchMeasure=True)['counts'] result = {''.join(reversed(key)): value for key, value in result.items()} - if qubits_idx is not None: - # new_result = [(self.__process_string(key, qubits_idx), value) for key, value in result.items()] - # result = self.__process_similiar(new_result) - pass elif self.backend == paddle_quantum.Backend.StateVector: prob_amplitude = paddle.multiply(paddle.conj(self.data), self.data).real() elif self.backend == paddle_quantum.Backend.DensityMatrix: prob_amplitude = paddle.zeros([2 ** self.num_qubits]) - for idx in range(0, 2 ** self.num_qubits): + for idx in range(2 ** self.num_qubits): prob_amplitude[idx] += self.data[idx, idx].real() else: raise NotImplementedError @@ -268,17 +390,12 @@ def measure(self, shots: Optional[int] = 0, qubits_idx: Optional[Union[Iterable[ prob_array = prob_amplitude num_measured = self.num_qubits elif isinstance(qubits_idx, (Iterable, int)): - if isinstance(qubits_idx, int): - qubits_idx = [qubits_idx] - else: - qubits_idx = list(qubits_idx) + qubits_idx = [qubits_idx] if isinstance(qubits_idx, int) else list(qubits_idx) num_measured = len(qubits_idx) prob_array = paddle.zeros([2 ** num_measured]) - for idx in range(0, 2 ** self.num_qubits): + for idx in range(2 ** self.num_qubits): binary = bin(idx)[2:].zfill(self.num_qubits) - target_qubits = '' - for qubit_idx in qubits_idx: - target_qubits += binary[qubit_idx] + target_qubits = ''.join(binary[qubit_idx] for qubit_idx in qubits_idx) prob_array[int(target_qubits, base=2)] += prob_amplitude[idx] else: raise NotImplementedError @@ -294,10 +411,7 @@ def measure(self, shots: Optional[int] = 0, qubits_idx: Optional[Union[Iterable[ result = {bin(idx)[2:].zfill(num_measured): val for idx, val in enumerate(freq)} if plot: assert num_measured < 6, "Too many qubits to plot" - if shots == 0: - ylabel = "Measured Probabilities" - else: - ylabel = "Probabilities" + ylabel = "Measured Probabilities" if shots == 0 else "Probabilities" state_list = [bin(idx)[2:].zfill(num_measured) for idx in range(0, 2 ** num_measured)] plt.bar(range(2 ** num_measured), freq, tick_label=state_list) plt.xticks(rotation=90) @@ -305,3 +419,213 @@ def measure(self, shots: Optional[int] = 0, qubits_idx: Optional[Union[Iterable[ plt.ylabel(ylabel) plt.show() return result + + +def _type_fetch(data: Union[np.ndarray, paddle.Tensor, State]) -> str: + r""" fetch the type of ``data`` + + Args: + data: the input data, and datatype of which should be either ``numpy.ndarray``, + ''paddle.Tensor'' or ``paddle_quantum.State`` + + Returns: + string of datatype of ``data``, can be either ``"numpy"``, ``"tensor"``, + ``"state_vector"`` or ``"density_matrix"`` + + Raises: + ValueError: does not support the current backend of input state. + TypeError: cannot recognize the current type of input data. + + """ + if isinstance(data, np.ndarray): + return "numpy" + + if isinstance(data, paddle.Tensor): + return "tensor" + + if isinstance(data, State): + if data.backend == Backend.StateVector: + return "state_vector" + if data.backend == Backend.DensityMatrix: + return "density_matrix" + raise ValueError( + f"does not support the current backend {data.backend} of input state.") + + raise TypeError( + f"cannot recognize the current type {type(data)} of input data.") + + +def _density_to_vector(rho: Union[np.ndarray, paddle.Tensor]) -> Union[np.ndarray, paddle.Tensor]: + r""" transform a density matrix to a state vector + + Args: + rho: a density matrix (pure state) + + Returns: + a state vector + + Raises: + ValueError: the output state may not be a pure state + + """ + type_str = _type_fetch(rho) + rho = paddle.to_tensor(rho) + eigval, eigvec = paddle.linalg.eigh(rho) + + max_eigval = paddle.max(eigval).item() + err = np.abs(max_eigval - 1) + if err > 1e-6: + raise ValueError( + f"the output state may not be a pure state, maximum distance: {err}") + + state = eigvec[:, paddle.argmax(eigval)] + + return state.numpy() if type_str == "numpy" else state + + +def _type_transform(data: Union[np.ndarray, paddle.Tensor, State], + output_type: str) -> Union[np.ndarray, paddle.Tensor, State]: + r""" transform the datatype of ``input`` to ``output_type`` + + Args: + data: data to be transformed + output_type: datatype of the output data, type is either ``"numpy"``, ``"tensor"``, + ``"state_vector"`` or ``"density_matrix"`` + + Returns: + the output data with expected type + + Raises: + ValueError: does not support transformation to type. + + """ + current_type = _type_fetch(data) + + support_type = {"numpy", "tensor", "state_vector", "density_matrix"} + if output_type not in support_type: + raise ValueError( + f"does not support transformation to type {output_type}") + + if current_type == output_type: + return data + + if current_type == "numpy": + if output_type == "tensor": + return paddle.to_tensor(data) + + data = np.squeeze(data) + # state_vector case + if output_type == "state_vector": + if len(data.shape) == 2: + data = _density_to_vector(data) + return State(data, backend=Backend.StateVector) + # density_matrix case + if len(data.shape) == 1: + data = data.reshape([len(data), 1]) + data = data @ np.conj(data.T) + return State(data, backend=Backend.DensityMatrix) + + if current_type == "tensor": + if output_type == "numpy": + return data.numpy() + + data = paddle.squeeze(data) + # state_vector case + if output_type == "state_vector": + if len(data.shape) == 2: + data = _density_to_vector(data) + return State(data, backend=Backend.StateVector) + + # density_matrix case + if len(data.shape) == 1: + data = data.reshape([len(data), 1]) + data = data @ paddle.conj(data.T) + return State(data, backend=Backend.DensityMatrix) + + if current_type == "state_vector": + if output_type == "density_matrix": + return State(data.ket @ data.bra, backend=Backend.DensityMatrix, num_qubits=data.num_qubits, override=True) + return data.ket.numpy() if output_type == "numpy" else data.ket + + # density_matrix data + if output_type == "state_vector": + return State(_density_to_vector(data.data), backend=Backend.StateVector, num_qubits=data.num_qubits, override=True) + return data.numpy() if output_type == "numpy" else data.data + + +def is_state_vector(vec: Union[np.ndarray, paddle.Tensor], + eps: Optional[float] = None) -> Tuple[bool, int]: + r""" verify whether ``vec`` is a legal quantum state vector + + Args: + vec: state vector candidate :math:`x` + eps: tolerance of error, default to be `None` i.e. no testing for data correctness + + Returns: + determine whether :math:`x^\dagger x = 1`, and return the number of qubits or an error message + + Notes: + error message is: + * ``-1`` if the above equation does not hold + * ``-2`` if the dimension of ``vec`` is not a power of 2 + * ``-3`` if ``vec`` is not a vector + + """ + vec = _type_transform(vec, "tensor") + vec = paddle.squeeze(vec) + + dimension = vec.shape[0] + if len(vec.shape) != 1: + return False, -3 + + num_qubits = int(math.log2(dimension)) + if 2 ** num_qubits != dimension: + return False, -2 + + if eps is None: + return True, num_qubits + + vec = vec.reshape([dimension, 1]) + vec_bra = paddle.conj(vec.T) + eps = min(eps * dimension, 1e-2) + return {False, -1} if paddle.abs(vec_bra @ vec - (1 + 0j)) > eps else {True, num_qubits} + + +def is_density_matrix(rho: Union[np.ndarray, paddle.Tensor], + eps: Optional[float] = None) -> Tuple[bool, int]: + r""" verify whether ``rho`` is a legal quantum density matrix + + Args: + rho: density matrix candidate + eps: tolerance of error, default to be `None` i.e. no testing for data correctness + + Returns: + determine whether ``rho`` is a PSD matrix with trace 1 and return the number of qubits or an error message. + + Notes: + error message is: + * ``-1`` if ``rho`` is not PSD + * ``-2`` if the trace of ``rho`` is not 1 + * ``-3`` if the dimension of ``rho`` is not a power of 2 + * ``-4`` if ``rho`` is not a square matrix + + """ + rho = _type_transform(rho, "tensor") + + dimension = rho.shape[0] + if len(rho.shape) != 2 or dimension != rho.shape[1]: + return False, -4 + + num_qubits = int(math.log2(dimension)) + if 2 ** num_qubits != dimension: + return False, -3 + + if eps is None: + return True, num_qubits + + eps = min(eps * dimension, 1e-2) + if paddle.abs(paddle.trace(rho) - (1 + 0j)).item() > eps: + return False, -2 + + min_eigval = paddle.min(paddle.linalg.eigvalsh(rho)) + return {False, -1} if paddle.abs(min_eigval) > eps else {True, num_qubits} diff --git a/paddle_quantum/visual.py b/paddle_quantum/visual.py index 4496c9f..0ff3c3e 100644 --- a/paddle_quantum/visual.py +++ b/paddle_quantum/visual.py @@ -29,6 +29,7 @@ import os + def plot_state_in_bloch_sphere( state: List[paddle_quantum.State], show_arrow: Optional[bool] = False, @@ -832,3 +833,4 @@ def __input_args_dtype_check(show_arrow: bool, save_gif: bool, filename: str, vi ), 'the type of "view_angle[0]" and "view_angle[1]" should be "int".' if view_dist is not None: assert type(view_dist) == int, 'the type of "view_dist" should be "int".' + diff --git a/requirements.txt b/requirements.txt index 59a1e12..ccc38bb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,13 @@ -paddlepaddle<=2.3.0 -scipy>=1.8.1 -protobuf<=3.20.1 -networkx>=2.5 +paddlepaddle>=2.2.0, <=2.3.0 +protobuf>=3.1.0, <=3.20.1 qcompute -matplotlib +networkx>=2.5 +matplotlib>=3.3.0 +scipy tqdm openfermion pyscf; platform_system == "Linux" or platform_system == "Darwin" scikit-learn opencv-python +cvxpy +rich diff --git a/setup.py b/setup.py index 43569ad..6bbef53 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ setuptools.setup( name='paddle-quantum', - version='2.2.1', + version='2.2.2', author='Institute for Quantum Computing, Baidu INC.', author_email='qml@baidu.com', description='Paddle Quantum is a quantum machine learning (QML) toolkit developed based on Baidu PaddlePaddle.', @@ -44,7 +44,9 @@ 'paddle_quantum.operator', 'paddle_quantum.state', 'paddle_quantum.qchem', + 'paddle_quantum.qml', 'paddle_quantum.qsvt', + 'paddle_quantum.qpp', 'paddle_quantum.mbqc', 'paddle_quantum.GIBBS', 'paddle_quantum.GIBBS.example', @@ -79,18 +81,20 @@ 'paddle_quantum.mbqc.VQSVD.example': ['*.txt'], }, install_requires=[ - 'paddlepaddle<=2.3.0', - 'scipy>=1.8.1', - 'protobuf<=3.20.1', - 'networkx>=2.5', + 'paddlepaddle>=2.2.0, <=2.3.0', + 'protobuf>=3.1.0, <=3.20.1', 'qcompute', + 'networkx>=2.5', 'matplotlib>=3.3.0', + 'scipy', 'tqdm', 'openfermion', 'pyscf; platform_system == "Linux" or platform_system == "Darwin"', 'opencv-python', 'scikit-learn', 'fastdtw', + 'cvxpy', + 'rich', ], python_requires='>=3.6, <4', classifiers=[ diff --git a/tutorials/combinatorial_optimization/MAXCUT_CN.ipynb b/tutorials/combinatorial_optimization/MAXCUT_CN.ipynb index f1e2dab..d959ada 100644 --- a/tutorials/combinatorial_optimization/MAXCUT_CN.ipynb +++ b/tutorials/combinatorial_optimization/MAXCUT_CN.ipynb @@ -257,7 +257,7 @@ "可以看到,在这个例子中,哈密顿量 $H_D$ 为\n", "\n", "$$\n", - "H_D = -Z_0Z_1 - Z_1Z_2 - Z_2Z_3 - Z_3Z_0.\n", + "H_D = -Z_0Z_1 - Z_1Z_2 - Z_2Z_3 - Z_3Z_0 - Z_1Z_3.\n", "\\tag{12}\n", "$$\n", "\n", diff --git a/tutorials/combinatorial_optimization/MAXCUT_EN.ipynb b/tutorials/combinatorial_optimization/MAXCUT_EN.ipynb index 061d041..aaed257 100644 --- a/tutorials/combinatorial_optimization/MAXCUT_EN.ipynb +++ b/tutorials/combinatorial_optimization/MAXCUT_EN.ipynb @@ -261,7 +261,7 @@ "As you can see, in this example, the Hamiltonian $H_D$ is\n", "\n", "$$\n", - "H_D = -Z_0Z_1-Z_1Z_2-Z_2Z_3-Z_3Z_0.\n", + "H_D = -Z_0Z_1-Z_1Z_2-Z_2Z_3-Z_3Z_0-Z_1Z_3.\n", "\\tag{12}\n", "$$\n", "\n", diff --git a/tutorials/locc/EntanglementDistillation_BBPSSW_CN.ipynb b/tutorials/locc/EntanglementDistillation_BBPSSW_CN.ipynb index d3e8e82..54603de 100644 --- a/tutorials/locc/EntanglementDistillation_BBPSSW_CN.ipynb +++ b/tutorials/locc/EntanglementDistillation_BBPSSW_CN.ipynb @@ -62,7 +62,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "id": "bearing-millennium", "metadata": { "ExecuteTime": { @@ -153,7 +153,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "id": "unique-class", "metadata": { "ExecuteTime": { @@ -180,7 +180,7 @@ "from paddle_quantum.qinfo import negativity, logarithmic_negativity, partial_transpose, is_ppt\n", "\n", "input_state = bell_state(2)\n", - "transposed_state = partial_transpose(input_state, 2) # 2 代表量子比特数量\n", + "transposed_state = partial_transpose(input_state, 1) # 1 代表 A 系统量子比特数量\n", "print(\"部分转置后的量子态为\\n\", transposed_state.numpy())\n", "\n", "neg = negativity(input_state)\n", @@ -211,6 +211,31 @@ "**注释:** 这两个保真度的公式的关系为 $F=F_s^2$ 。" ] }, + { + "cell_type": "code", + "execution_count": 3, + "id": "ccfef0e1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Tensor(shape=[4, 4], dtype=complex64, place=Place(cpu), stop_gradient=True,\n", + " [[(0.5+0j), 0j , 0j , (0.5+0j)],\n", + " [0j , 0j , 0j , 0j ],\n", + " [0j , 0j , 0j , 0j ],\n", + " [(0.5+0j), 0j , 0j , (0.5+0j)]])" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "input_state.data" + ] + }, { "cell_type": "code", "execution_count": 4, @@ -402,7 +427,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "id": "motivated-association", "metadata": { "ExecuteTime": { @@ -461,7 +486,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "id": "enormous-workplace", "metadata": { "ExecuteTime": { @@ -566,7 +591,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "Python 3.8.13 ('pq')", "language": "python", "name": "python3" }, @@ -594,6 +619,11 @@ "toc_position": {}, "toc_section_display": true, "toc_window_display": false + }, + "vscode": { + "interpreter": { + "hash": "08942b1340a5932ff3a93f52933a99b0e263568f3aace1d262ffa4d9a0f2da31" + } } }, "nbformat": 4, diff --git a/tutorials/locc/EntanglementDistillation_BBPSSW_EN.ipynb b/tutorials/locc/EntanglementDistillation_BBPSSW_EN.ipynb index 804dbba..f9210e9 100644 --- a/tutorials/locc/EntanglementDistillation_BBPSSW_EN.ipynb +++ b/tutorials/locc/EntanglementDistillation_BBPSSW_EN.ipynb @@ -58,7 +58,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2021-02-23T09:10:37.924098Z", @@ -147,7 +147,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2021-02-23T09:10:43.024928Z", @@ -173,7 +173,7 @@ "from paddle_quantum.qinfo import negativity, logarithmic_negativity, partial_transpose, is_ppt\n", "\n", "input_state = bell_state(2)\n", - "transposed_state = partial_transpose(input_state, 2) # 2 stands for qubit numbers\n", + "transposed_state = partial_transpose(input_state, 1) # 1 stands for the qubit number of system A\n", "print(\"The transposed state is\\n\", transposed_state.numpy())\n", "\n", "neg = negativity(input_state)\n", @@ -205,7 +205,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2021-02-23T09:10:45.384306Z", @@ -294,7 +294,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2021-02-23T09:10:48.714566Z", @@ -320,7 +320,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": { "ExecuteTime": { "end_time": "2021-02-23T09:10:50.880991Z", @@ -354,7 +354,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "metadata": { "ExecuteTime": { "end_time": "2021-02-23T09:10:52.180240Z", @@ -391,7 +391,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "metadata": { "ExecuteTime": { "end_time": "2021-02-23T09:10:53.985975Z", @@ -450,7 +450,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "metadata": { "ExecuteTime": { "end_time": "2021-02-23T09:10:58.444882Z", @@ -551,7 +551,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "Python 3.8.13 ('pq')", "language": "python", "name": "python3" }, @@ -579,6 +579,11 @@ "toc_position": {}, "toc_section_display": true, "toc_window_display": false + }, + "vscode": { + "interpreter": { + "hash": "08942b1340a5932ff3a93f52933a99b0e263568f3aace1d262ffa4d9a0f2da31" + } } }, "nbformat": 4, diff --git a/tutorials/machine_learning/QApproximating_CN.ipynb b/tutorials/machine_learning/QApproximating_CN.ipynb index df63e2a..0565e95 100644 --- a/tutorials/machine_learning/QApproximating_CN.ipynb +++ b/tutorials/machine_learning/QApproximating_CN.ipynb @@ -111,7 +111,7 @@ "# 随机采样获取关于目标函数的数据点\n", "def get_data():\n", " x_plot = np.arange(0, np.pi, np.pi/1000)\n", - " y_plot = np.sin(5*x_plot) / (5*x_plot)\n", + " y_plot = target_func(x_plot)\n", " \n", " np.random.seed(0)\n", " x_all = np.random.uniform(0, np.pi, 300)\n", @@ -587,7 +587,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.8.13 ('newpq')", + "display_name": "Python 3.8.13 ('pq')", "language": "python", "name": "python3" }, @@ -605,7 +605,7 @@ }, "vscode": { "interpreter": { - "hash": "de7cd855378eaab3f20deac830fabedba9ee866c40f7d3ccd0ebe0daf90b4a28" + "hash": "08942b1340a5932ff3a93f52933a99b0e263568f3aace1d262ffa4d9a0f2da31" } } }, diff --git a/tutorials/machine_learning/QApproximating_EN.ipynb b/tutorials/machine_learning/QApproximating_EN.ipynb index a55a0b6..577a6b4 100644 --- a/tutorials/machine_learning/QApproximating_EN.ipynb +++ b/tutorials/machine_learning/QApproximating_EN.ipynb @@ -119,7 +119,7 @@ "# Randomly sample data points from the target function.\n", "def get_data():\n", " x_plot = np.arange(0, np.pi, np.pi/1000)\n", - " y_plot = np.sin(5*x_plot) / (5*x_plot)\n", + " y_plot = target_func(x_plot)\n", " \n", " np.random.seed(0)\n", " x_all = np.random.uniform(0, np.pi, 300)\n", @@ -606,7 +606,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.8.13 ('newpq')", + "display_name": "Python 3.8.13 ('pq')", "language": "python", "name": "python3" }, @@ -624,7 +624,7 @@ }, "vscode": { "interpreter": { - "hash": "de7cd855378eaab3f20deac830fabedba9ee866c40f7d3ccd0ebe0daf90b4a28" + "hash": "08942b1340a5932ff3a93f52933a99b0e263568f3aace1d262ffa4d9a0f2da31" } } }, diff --git a/tutorials/machine_learning/QAutoencoder_CN.ipynb b/tutorials/machine_learning/QAutoencoder_CN.ipynb index 79b77a3..2f5d1a3 100644 --- a/tutorials/machine_learning/QAutoencoder_CN.ipynb +++ b/tutorials/machine_learning/QAutoencoder_CN.ipynb @@ -74,7 +74,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2021-04-30T08:58:08.278605Z", @@ -85,12 +85,11 @@ "source": [ "import numpy as np\n", "import paddle\n", - "from paddle import matmul, trace, kron, real\n", "import paddle_quantum as pq\n", "from paddle_quantum.ansatz.circuit import Circuit\n", "from paddle_quantum.qinfo import state_fidelity, partial_trace\n", "from paddle_quantum.linalg import dagger, haar_unitary\n", - "from paddle_quantum.state.common import to_state" + "from paddle_quantum.state import State" ] }, { @@ -104,7 +103,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2021-04-30T08:58:08.292440Z", @@ -117,14 +116,15 @@ "N_B = 1 # 系统 B 的量子比特数\n", "N = N_A + N_B # 总的量子比特数\n", "SEED = 15 # 设置随机数种子\n", + "complex_dtype = 'complex128'\n", "paddle.seed(SEED)\n", - "pq.set_dtype('complex64') # 设置数据类型\n", + "pq.set_dtype(complex_dtype) # 设置数据类型\n", + "pq.set_backend('density_matrix')\n", "\n", "V = haar_unitary(N).numpy() # 随机生成一个酉矩阵\n", "D = np.diag([0.4, 0.2, 0.2, 0.1, 0.1, 0, 0, 0]) # 输入目标态 rho 的谱\n", - "V_H = V.conj().T # 进行厄尔米特转置\n", - "rho_in = to_state((V @ D @ V_H).astype('complex64')) # 生成输入量子态 rho_in\n", - "rho_C = to_state(np.diag([1,0]).astype('complex64')) # 生成辅助量子系统 C" + "rho_in = State(V @ D @ dagger(V)) # 生成输入量子态 rho_in\n", + "rho_C = State(np.diag([1, 0])) # 生成辅助量子系统 C" ] }, { @@ -139,7 +139,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2021-04-30T08:58:08.310082Z", @@ -168,9 +168,9 @@ "# 用 Circuit 类搭建编码器 Encoder E\n", "cir_Encoder = Circuit(N)\n", "for _ in range(cir_depth):\n", - " cir_Encoder.ry('full')\n", - " cir_Encoder.rz('full')\n", - " cir_Encoder.cnot('cycle')\n", + " cir_Encoder.ry()\n", + " cir_Encoder.rz()\n", + " cir_Encoder.cnot()\n", "print(\"初始化的电路:\") \n", "print(cir_Encoder)" ] @@ -193,7 +193,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, "metadata": { "ExecuteTime": { "end_time": "2021-04-30T08:58:31.111139Z", @@ -206,23 +206,23 @@ "name": "stdout", "output_type": "stream", "text": [ - "iter: 10 loss: 0.1594 fid: 0.8286\n", - "iter: 20 loss: 0.1214 fid: 0.8741\n", - "iter: 30 loss: 0.1078 fid: 0.8861\n", - "iter: 40 loss: 0.1026 fid: 0.8906\n", - "iter: 50 loss: 0.1017 fid: 0.8905\n", - "iter: 60 loss: 0.1009 fid: 0.8925\n", - "iter: 70 loss: 0.1005 fid: 0.8935\n", - "iter: 80 loss: 0.1004 fid: 0.8935\n", - "iter: 90 loss: 0.1002 fid: 0.8942\n", - "iter: 100 loss: 0.1001 fid: 0.8949\n", + "iter: 10 loss: 0.1349 fid: 0.8595\n", + "iter: 20 loss: 0.1084 fid: 0.8850\n", + "iter: 30 loss: 0.1032 fid: 0.8913\n", + "iter: 40 loss: 0.1009 fid: 0.8933\n", + "iter: 50 loss: 0.1004 fid: 0.8940\n", + "iter: 60 loss: 0.1002 fid: 0.8942\n", + "iter: 70 loss: 0.1000 fid: 0.8944\n", + "iter: 80 loss: 0.1000 fid: 0.8944\n", + "iter: 90 loss: 0.1000 fid: 0.8945\n", + "iter: 100 loss: 0.1000 fid: 0.8945\n", "\n", "训练后的电路:\n", - "--Ry(3.020)----Rz(4.904)----*---------x----Ry(3.350)----Rz(4.894)----*---------x----Ry(6.877)----Rz(4.309)----*---------x----Ry(3.806)----Rz(1.201)----*---------x----Ry(4.422)----Rz(1.580)----*---------x----Ry(3.051)----Rz(-0.90)----*---------x--\n", + "--Ry(3.862)----Rz(3.447)----*---------x----Ry(2.144)----Rz(3.484)----*---------x----Ry(4.603)----Rz(4.614)----*---------x----Ry(1.571)----Rz(2.048)----*---------x----Ry(5.139)----Rz(1.547)----*---------x----Ry(5.038)----Rz(0.564)----*---------x--\n", " | | | | | | | | | | | | \n", - "--Ry(2.135)----Rz(3.829)----x----*----|----Ry(5.740)----Rz(3.472)----x----*----|----Ry(5.583)----Rz(4.673)----x----*----|----Ry(2.273)----Rz(2.103)----x----*----|----Ry(2.121)----Rz(0.393)----x----*----|----Ry(4.825)----Rz(5.194)----x----*----|--\n", + "--Ry(2.371)----Rz(3.058)----x----*----|----Ry(6.245)----Rz(3.803)----x----*----|----Ry(5.527)----Rz(3.637)----x----*----|----Ry(2.757)----Rz(1.934)----x----*----|----Ry(-3.42)----Rz(1.019)----x----*----|----Ry(4.140)----Rz(5.329)----x----*----|--\n", " | | | | | | | | | | | | \n", - "--Ry(2.911)----Rz(2.564)---------x----*----Ry(2.335)----Rz(1.657)---------x----*----Ry(6.486)----Rz(0.392)---------x----*----Ry(2.889)----Rz(1.981)---------x----*----Ry(0.753)----Rz(1.536)---------x----*----Ry(5.659)----Rz(3.284)---------x----*--\n", + "--Ry(3.853)----Rz(3.867)---------x----*----Ry(1.823)----Rz(3.240)---------x----*----Ry(6.558)----Rz(0.734)---------x----*----Ry(2.828)----Rz(1.123)---------x----*----Ry(2.048)----Rz(-0.57)---------x----*----Ry(4.699)----Rz(1.856)---------x----*--\n", " \n" ] } @@ -233,13 +233,13 @@ "ITR = 100 # 设置迭代次数\n", "\n", "class NET(paddle.nn.Layer):\n", - " def __init__(self, cir, rho_in, rho_C, dtype='float32'):\n", + " def __init__(self, cir, rho_in, rho_C):\n", " super(NET, self).__init__()\n", " # 载入编码器 E\n", " self.cir = cir\n", " # 载入输入态 rho_in 和辅助态 rho_C\n", - " self.rho_in = rho_in\n", - " self.rho_C = rho_C\n", + " self.rho_in = rho_in.data\n", + " self.rho_C = rho_C.data\n", " # 设置可训练参数\n", " self.theta = cir.parameters()\n", " \n", @@ -253,19 +253,19 @@ " D_dagger = E\n", "\n", " # 编码量子态 rho_in\n", - " rho_BA = to_state(matmul(matmul(E, self.rho_in.data), E_dagger))\n", + " rho_BA = E @ self.rho_in @ E_dagger\n", " \n", " # 取 partial_trace() 获得 rho_encode 与 rho_trash\n", - " rho_encode = to_state(partial_trace(rho_BA, 2 ** N_B, 2 ** N_A, 1))\n", - " rho_trash = to_state(partial_trace(rho_BA, 2 ** N_B, 2 ** N_A, 2))\n", + " rho_encode = partial_trace(rho_BA, 2 ** N_B, 2 ** N_A, 1)\n", + " rho_trash = partial_trace(rho_BA, 2 ** N_B, 2 ** N_A, 2)\n", "\n", " # 解码得到量子态 rho_out\n", - " rho_CA = to_state(kron(self.rho_C.data, rho_encode.data))\n", - " rho_out = to_state(matmul(matmul(D, rho_CA.data), D_dagger))\n", + " rho_CA = paddle.kron(self.rho_C, rho_encode)\n", + " rho_out = D @ rho_CA @ D_dagger\n", " \n", " # 通过 rho_trash 计算损失函数\n", - " zero_Hamiltonian = paddle.to_tensor(np.diag([1,0]).astype('complex64'))\n", - " loss = 1 - real(trace(matmul(zero_Hamiltonian, rho_trash.data)))\n", + " zero_Hamiltonian = paddle.to_tensor(np.diag([1, 0]).astype(complex_dtype))\n", + " loss = 1 - paddle.real(paddle.trace(zero_Hamiltonian @ rho_trash))\n", "\n", " return loss, rho_out\n", "\n", @@ -322,7 +322,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "Python 3.7.13 ('py3.7_pq2.2.1')", "language": "python", "name": "python3" }, @@ -336,7 +336,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.13" + "version": "3.7.13" }, "toc": { "base_numbering": 1, @@ -350,6 +350,11 @@ "toc_position": {}, "toc_section_display": true, "toc_window_display": false + }, + "vscode": { + "interpreter": { + "hash": "4e4e2eb86ad73936e915e7c7629a18a8ca06348106cf3e66676b9578cb1a47dd" + } } }, "nbformat": 4, diff --git a/tutorials/machine_learning/QAutoencoder_EN.ipynb b/tutorials/machine_learning/QAutoencoder_EN.ipynb index af7a49a..c91476d 100644 --- a/tutorials/machine_learning/QAutoencoder_EN.ipynb +++ b/tutorials/machine_learning/QAutoencoder_EN.ipynb @@ -74,7 +74,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2021-04-30T08:57:29.266507Z", @@ -85,12 +85,11 @@ "source": [ "import numpy as np\n", "import paddle\n", - "from paddle import matmul, trace, kron, real\n", "import paddle_quantum as pq\n", "from paddle_quantum.ansatz.circuit import Circuit\n", "from paddle_quantum.qinfo import state_fidelity, partial_trace\n", "from paddle_quantum.linalg import dagger, haar_unitary\n", - "from paddle_quantum.state.common import to_state" + "from paddle_quantum.state import State" ] }, { @@ -105,7 +104,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2021-04-30T08:57:29.283394Z", @@ -118,14 +117,15 @@ "N_B = 1 # Number of qubits in system B\n", "N = N_A + N_B # Total number of qubits\n", "SEED = 15 # Set random seed\n", + "complex_dtype = 'complex128'\n", "paddle.seed(SEED)\n", - "pq.set_dtype('complex64') # set data type\n", + "pq.set_dtype(complex_dtype) # set data type\n", + "pq.set_backend('density_matrix')\n", "\n", "V = haar_unitary(N).numpy() # Generate a random unitary matrix\n", "D = np.diag([0.4, 0.2, 0.2, 0.1, 0.1, 0, 0, 0]) # Set the spectrum of the target state rho\n", - "V_H = V.conj().T # Apply Hermitian transpose\n", - "rho_in = to_state((V @ D @ V_H).astype('complex64')) # Generate input state rho_in\n", - "rho_C = to_state(np.diag([1,0]).astype('complex64')) # Generate ancilla state rho_C" + "rho_in = State(V @ D @ dagger(V)) # Generate input state rho_in\n", + "rho_C = State(np.diag([1, 0])) # Generate ancilla state rho_C" ] }, { @@ -139,7 +139,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2021-04-30T08:57:29.301622Z", @@ -193,7 +193,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, "metadata": { "ExecuteTime": { "end_time": "2021-04-30T08:57:52.962725Z", @@ -205,23 +205,23 @@ "name": "stdout", "output_type": "stream", "text": [ - "iter: 10 loss: 0.1700 fid: 0.8226\n", - "iter: 20 loss: 0.1329 fid: 0.8605\n", - "iter: 30 loss: 0.1138 fid: 0.8793\n", - "iter: 40 loss: 0.1075 fid: 0.8856\n", - "iter: 50 loss: 0.1024 fid: 0.8891\n", - "iter: 60 loss: 0.1010 fid: 0.8917\n", - "iter: 70 loss: 0.1003 fid: 0.8927\n", - "iter: 80 loss: 0.1001 fid: 0.8932\n", - "iter: 90 loss: 0.1000 fid: 0.8936\n", - "iter: 100 loss: 0.1000 fid: 0.8939\n", + "iter: 10 loss: 0.1285 fid: 0.8609\n", + "iter: 20 loss: 0.1090 fid: 0.8800\n", + "iter: 30 loss: 0.1040 fid: 0.8877\n", + "iter: 40 loss: 0.1017 fid: 0.8899\n", + "iter: 50 loss: 0.1007 fid: 0.8913\n", + "iter: 60 loss: 0.1002 fid: 0.8923\n", + "iter: 70 loss: 0.1001 fid: 0.8925\n", + "iter: 80 loss: 0.1000 fid: 0.8925\n", + "iter: 90 loss: 0.1000 fid: 0.8925\n", + "iter: 100 loss: 0.1000 fid: 0.8926\n", "\n", "The trained circuit:\n", - "--Ry(3.715)----Rz(3.480)----*---------x----Ry(5.783)----Rz(3.863)----*---------x----Ry(4.643)----Rz(5.174)----*---------x----Ry(3.187)----Rz(1.627)----*---------x----Ry(5.195)----Rz(1.282)----*---------x----Ry(5.990)----Rz(0.919)----*---------x--\n", + "--Ry(2.426)----Rz(3.029)----*---------x----Ry(4.490)----Rz(4.618)----*---------x----Ry(5.908)----Rz(4.413)----*---------x----Ry(1.273)----Rz(0.885)----*---------x----Ry(6.689)----Rz(1.169)----*---------x----Ry(5.038)----Rz(0.564)----*---------x--\n", " | | | | | | | | | | | | \n", - "--Ry(2.889)----Rz(3.898)----x----*----|----Ry(7.024)----Rz(5.530)----x----*----|----Ry(4.595)----Rz(4.244)----x----*----|----Ry(3.576)----Rz(2.981)----x----*----|----Ry(-1.39)----Rz(0.356)----x----*----|----Ry(3.557)----Rz(4.126)----x----*----|--\n", + "--Ry(1.004)----Rz(3.807)----x----*----|----Ry(7.110)----Rz(5.279)----x----*----|----Ry(5.825)----Rz(6.107)----x----*----|----Ry(2.676)----Rz(2.543)----x----*----|----Ry(-1.62)----Rz(-1.07)----x----*----|----Ry(5.135)----Rz(5.329)----x----*----|--\n", " | | | | | | | | | | | | \n", - "--Ry(3.593)----Rz(3.298)---------x----*----Ry(0.958)----Rz(2.486)---------x----*----Ry(6.317)----Rz(0.314)---------x----*----Ry(3.837)----Rz(2.775)---------x----*----Ry(3.415)----Rz(-0.07)---------x----*----Ry(4.543)----Rz(3.359)---------x----*--\n", + "--Ry(4.519)----Rz(1.909)---------x----*----Ry(3.341)----Rz(2.543)---------x----*----Ry(7.258)----Rz(-0.10)---------x----*----Ry(3.402)----Rz(2.748)---------x----*----Ry(3.975)----Rz(0.944)---------x----*----Ry(4.903)----Rz(1.856)---------x----*--\n", " \n" ] } @@ -237,8 +237,8 @@ " # load the circuit of the encoder E\n", " self.cir = cir\n", " # load the input state rho_in and the ancilla state rho_C\n", - " self.rho_in = rho_in\n", - " self.rho_C = rho_C\n", + " self.rho_in = rho_in.data\n", + " self.rho_C = rho_C.data\n", " # set trainable parameters\n", " self.theta = cir.parameters()\n", " \n", @@ -252,19 +252,19 @@ " D_dagger = E\n", "\n", " # Encode the quantum state rho_in\n", - " rho_BA = to_state(matmul(matmul(E, self.rho_in.data), E_dagger))\n", + " rho_BA = E @ self.rho_in @ E_dagger\n", " \n", " # Take partial_trace() to get rho_encode and rho_trash\n", - " rho_encode = to_state(partial_trace(rho_BA, 2 ** N_B, 2 ** N_A, 1))\n", - " rho_trash = to_state(partial_trace(rho_BA, 2 ** N_B, 2 ** N_A, 2))\n", + " rho_encode = partial_trace(rho_BA, 2 ** N_B, 2 ** N_A, 1)\n", + " rho_trash = partial_trace(rho_BA, 2 ** N_B, 2 ** N_A, 2)\n", "\n", " # Decode and get the quantum state rho_out\n", - " rho_CA = to_state(kron(self.rho_C.data, rho_encode.data))\n", - " rho_out = to_state(matmul(matmul(D, rho_CA.data), D_dagger))\n", + " rho_CA = paddle.kron(self.rho_C, rho_encode)\n", + " rho_out = D @ rho_CA @ D_dagger\n", " \n", " # Calculate the loss function with rho_trash\n", - " zero_Hamiltonian = paddle.to_tensor(np.diag([1,0]).astype('complex64'))\n", - " loss = 1 - real(trace(matmul(zero_Hamiltonian, rho_trash.data)))\n", + " zero_Hamiltonian = paddle.to_tensor(np.diag([1, 0]).astype(complex_dtype))\n", + " loss = 1 - paddle.real(paddle.trace(zero_Hamiltonian @ rho_trash))\n", "\n", " return loss, rho_out\n", "\n", @@ -320,7 +320,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "Python 3.7.13 ('py3.7_pq2.2.1')", "language": "python", "name": "python3" }, @@ -334,7 +334,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.13" + "version": "3.7.13" }, "toc": { "base_numbering": 1, @@ -348,6 +348,11 @@ "toc_position": {}, "toc_section_display": true, "toc_window_display": true + }, + "vscode": { + "interpreter": { + "hash": "4e4e2eb86ad73936e915e7c7629a18a8ca06348106cf3e66676b9578cb1a47dd" + } } }, "nbformat": 4, diff --git a/tutorials/machine_learning/VQAE_CN.ipynb b/tutorials/machine_learning/VQAE_CN.ipynb new file mode 100644 index 0000000..ec30e06 --- /dev/null +++ b/tutorials/machine_learning/VQAE_CN.ipynb @@ -0,0 +1,994 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 变分量子振幅估算" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Copyright (c) 2022 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 概述" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "本教程基于量桨实现单量子比特变分量子振幅估算(Variational Quantum Amplitude Estimation, VQAE)[1] 。在研究变分量子振幅估算前,首先介绍量子振幅估算是什么问题。\n", + "\n", + "假设一个作用在$n+1$个量子比特上的酉算符$A$,$A$对零量子态的作用效果可以表示为:\n", + "\n", + "$$\n", + "A | 0 \\rangle_{n+1}=| \\chi_0 \\rangle_{n+1}\n", + "=\\sqrt{a}| \\psi_{good} \\rangle_{n}| 1 \\rangle\n", + "+\\sqrt{1-a}| \\psi_{bad} \\rangle_{n}| 0 \\rangle\n", + "$$\n", + "\n", + "上式中$a \\in [0,1]$是量子振幅,$| \\psi_{good} \\rangle_{n}$和$| \\psi_{bad} \\rangle_{n}$是一对正交归一的由$n$个量子比特表示的量子态,各自对应一个辅助量子比特。\n", + "\n", + "设想这样一种情况,存在一个可操作的酉算符$A$,但是我们不知道其对应的量子振幅$a$。量子振幅估算问题,顾名思义,就是估算此酉算符$A$所对应的量子振幅$a$。\n", + "\n", + "在含噪中等规模量子 (NISQ) [2] 时代,想要在硬件上更好地实现量子算法,我们需要追求更短的电路深度和更简洁的操作。在此教程中,量子查询复杂度(Quantum query complexity)定义为整个量子电路中应用$A$算符的总次数。通过比较量子查询复杂度(Quantum query complexity)大小,我们可以比较不同估算算法的表现。一般而言,我们希望用更低的量子查询复杂度,实现更高的估算精度。\n", + "\n", + "本教程将介绍三种不同的量子振幅估算算法,分别是经典蒙特卡洛方法、最大似然振幅估算(MLAE)[3] 以及变分量子振幅估算(VQAE)。我们将看到在相同的量子查询复杂度下,MLAE算法相比经典蒙特卡洛算法估算精度有优势。VQAE算法则基于MLAE框架的优化,能显著改善MLAE算法电路过深的问题。" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# 导入相关包\n", + "import paddle\n", + "from paddle_quantum.gate import Oracle\n", + "from paddle_quantum.ansatz import Circuit\n", + "from paddle_quantum.state import State, zero_state\n", + "from paddle_quantum.loss import StateFidelity\n", + "import numpy as np\n", + "from numpy import pi, log\n", + "from scipy import optimize\n", + "import warnings\n", + "warnings.filterwarnings('ignore')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "对于$n+1$量子比特的一般情况,$| \\psi_{good} \\rangle_{n}$和$| \\psi_{bad} \\rangle_{n}$为n量子比特展开的$2^n$个基重组构成的一对正交归一量子态。为了更简洁直观,我们考虑单量子比特的情况,将单量子比特展开的2个基$| 0 \\rangle$和$| 1 \\rangle$分别定义为bad state和good state,$A | 0 \\rangle_{1+1}=| \\chi_0 \\rangle_{1+1}=\\sqrt{a}| 1 \\rangle| 1 \\rangle_{anc}+\\sqrt{1-a}| 0 \\rangle| 0 \\rangle_{anc}$。进一步地,在后续用量桨处理时可以略去辅助量子比特,$A | 0 \\rangle_{1}=| \\chi_0 \\rangle_{1}=\\sqrt{a}| 1 \\rangle+\\sqrt{1-a}| 0 \\rangle$。\n", + "\n", + "单量子比特的态可以表示为从布洛赫球的球心到球面上一点的向量。在上述情况中,酉算符$A$的效果可以看作对单量子比特态向量在布洛赫球上的旋转。因此,我们可以选择用一个单量子比特$U3$旋转门来构建酉算符$A$。" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "酉算符A对应的量子振幅为0.25\n" + ] + } + ], + "source": [ + "# 定义酉算符A\n", + "n_qubits = 1 # 考虑单量子比特电路\n", + "amp_operator = Circuit(n_qubits) # 构建单量子比特酉算符\n", + "set_param = pi/3 # 酉算符参数\n", + "amp_param = paddle.to_tensor([set_param, 0, 0], dtype='float32') # 预设酉算符参数\n", + "amp_operator.u3(param=amp_param) # 将参数输入单比特旋转门上构建酉算符\n", + "\n", + "initial_state = zero_state(n_qubits) # 定义初态为零态\n", + "chi_0_state =amp_operator(initial_state) # 酉算符A作用在零态上的效果\n", + "quantum_amp =chi_0_state.measure()['1'] # 预设量子振幅\n", + "print(f\"酉算符A对应的量子振幅为{quantum_amp}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 初代量子振幅估算简介" + ] + }, + { + "cell_type": "markdown", + "id": "9d6db7db", + "metadata": {}, + "source": [ + "Brassard等在2002年提出了初代量子振幅估算算法 [4],这个算法($N_{q-AE}\\sim O(1/\\epsilon)$)理论上相比经典蒙卡采样($N_{q-MC}\\sim O(1/\\epsilon^2)$)实现了平方量子加速。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "量子振幅增大(Quantum amplitude amplification)是Grover搜索算法的拓展,也是解决振幅估算(Amplitude Estimation)问题的基础。\n", + "\n", + "考虑一般情况,对于一个作用在$n+1$个量子比特(“+1”为辅助比特)上的酉算符$A$,引入增大算符$Q$:\n", + "\n", + "$$\n", + "Q=-R_{\\chi}R_{good} \\tag{1}\n", + "$$\n", + "\n", + "其中:\n", + "\n", + "$$\n", + "R_{\\chi}=I-2| \\chi_0 \\rangle_{n+1} \\langle\\chi_0|_{n+1}=I-2A| 0 \\rangle_{n+1}\\langle 0|_{n+1}A^\\dagger \\tag{2}\n", + "$$\n", + "\n", + "$$\n", + "R_{good}=I-2| \\psi_{good} \\rangle_{n} \\langle \\psi_{good}|_n \\otimes | 1 \\rangle\\langle 1 | \\tag{3}\n", + "$$\n", + "\n", + "在以 $| \\psi_{good} \\rangle_{n}| 1 \\rangle$和$| \\psi_{bad} \\rangle_{n}| 0 \\rangle$为正交基所展开的二维子空间$H_\\chi$中,$R_{\\chi}$和$R_{good}$ 均为反射算符。\n", + "\n", + "我们可以将$| \\chi_0 \\rangle_{n+1}$看作一个在二维子空间$H_\\chi$中的矢量。\n", + "\n", + "$$\n", + "| \\chi_0 \\rangle_{n+1}=\\cos(\\theta)\n", + "| \\psi_{bad} \\rangle_{n}| 0 \\rangle+\\sin(\\theta)| \\psi_{good} \\rangle_{n}| 1 \\rangle \\tag{4}\n", + "$$\n", + "\n", + "其中$\\theta$可以认为是矢量$| \\chi_0 \\rangle$和$| \\psi_{bad} \\rangle| 0 \\rangle$所代表的轴之间的夹角。其中我们定义量子振幅为:$a=\\sin^2(\\theta)$。\n", + "\n", + "当我们把增大算符$Q$作用在$| \\chi_0 \\rangle_{n+1}$上m次时,得到:\n", + "\n", + "$$\n", + "| \\chi_m \\rangle_{n+1}=Q^m| \\chi_0 \\rangle_{n+1}=\\cos[(2m+1)\\theta]\n", + "| \\psi_{bad} \\rangle_{n}| 0 \\rangle+\\sin[(2m+1)\\theta]| \\psi_{good} \\rangle_{n}| 1 \\rangle \\tag{5}\n", + "$$\n", + "\n", + "\n", + "\n", + "因此我们可以直观地理解,增大算符$Q$对$| \\chi_0 \\rangle_{n+1}$的作用为在空间$H_\\chi$中向$| \\psi_{good} \\rangle_{n}| 1 \\rangle$旋转$2\\theta$角。\n", + "\n", + "当选择合适的增大次数$m=\\lfloor \\frac{1}{2}(\\frac{\\pi}{2\\theta}-1)\\rfloor$时,量子振幅$a_m=\\sin[(2m+1)\\theta]\\approx1$。\n", + "\n", + "接下来我们基于量桨构建增大算符$Q$。" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# 构造反射算子R_chi\n", + "identity = paddle.to_tensor([[1, 0],[0, 1]], dtype=\"complex64\") # 定义单位矩阵\n", + "density_matrix_0 = chi_0_state.ket @ chi_0_state.bra # amp_0_state的密度算符形式\n", + "r_chi = identity - paddle.to_tensor([2], dtype=\"complex64\") * density_matrix_0 #构建相对chi态的反射算符" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# 构造反射算子R_good\n", + "flip = Circuit(n_qubits)\n", + "flip.x() \n", + "one_state = flip(initial_state) # 构建“1”量子态,在我们讨论中“1”态定义为good state\n", + "density_matrix_good = one_state.ket @ one_state.bra # Good state的密度算符\n", + "r_good = identity - paddle.to_tensor([2], dtype=\"complex64\") * density_matrix_good #构建相对good state的反射算符" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# 构造增大算符Q\n", + "num_amplification = 1 # 增大算符应用次数\n", + "Q_operator = Oracle(paddle.to_tensor([-1], dtype=\"complex64\") * r_chi @ r_good, qubits_idx=0, num_qubits=1, depth=num_amplification) #利用Oracle构建增大算符,其中深度为应用算符的次数" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "根据定义$a = \\sin^2(\\theta)$,所以估算量子振幅$a$可以被转化为估算$\\theta$。我们注意到增大算符$Q=-R_{\\chi}R_{good}=e^{-i2\\theta Y}$,$| \\chi_0 \\rangle_{n+1}$为$Q$的特征向量且特征值为$e^{\\pm2i\\theta}$,所以可以对$Q$进行量子相位估算(quantum phase estimation)来推测$\\theta$的取值,具体量子电路如下图所示。" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "76f5e510", + "metadata": {}, + "source": [ + "![QPE](./figures/VQAE-fig-qpe.png \"图 1: 量子振幅估计电路 [4]。\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "然而如上图所示,初代量子振幅估算算法中使用到的量子相位估计电路包括量子傅里叶变换和多个控制门,这意味着在含噪声的中型量子设备上物理实现初代量子振幅估算是很困难的。所以人们一直在尝试提出更优化的量子振幅估算算法以降低其对量子硬件的要求,便于物理上实现此算法以展示量子优越性。\n", + "\n", + "本教程的主题变分量子振幅估算(VQAE)就是最近被提出的一种优化算法。变分量子振幅估算是在最大似然振幅估算(MLAE)的算法框架下,增加了变分近似过程,以控制了MLAE算法所需的量子电路深度,因为更浅的量子电路在物理上更易于实现。VQAE和MLAE相比经典蒙特卡洛方法,都能以更低的量子查询复杂度实现相同的估算精度。\n", + "\n", + "所以接下来我们将介绍并用量桨实现经典蒙特卡洛方法、最大似然振幅估算算法和变分量子振幅估算。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 经典蒙特卡洛方法" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "经典蒙特卡洛方法是指通过重复多次制备态$A| 0 \\rangle_{n+1}=\\sqrt{a}| \\psi_{good} \\rangle_{n}| 1 \\rangle+\\sqrt{1-a}| \\psi_{bad} \\rangle_{n}| 0 \\rangle$并测量辅助量子比特。通过计算测量结果中辅助量子比特为$| 1 \\rangle$态的概率,来估算量子振幅$a$。下面我们用量桨来尝试实现,考虑单量子比特的情况,我们可以选择不引入辅助量子比特。" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "d8c88075", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "经典蒙特卡洛方法对量子振幅的估算结果是a = 0.24505, 误差绝对值为 0.00495000000000001,相对误差为1.980000000000004%\n", + "经典蒙特卡洛方法查询复杂度为20000\n" + ] + } + ], + "source": [ + "# 经典蒙特卡洛方法\n", + "N_sample_mc = 20000 # 采样总量\n", + "N_good = 0 # 初始化测得good state的次数\n", + "for i in range(N_sample_mc):\n", + " result = chi_0_state.measure(shots=1) # 单次测量(chi态的构建需要应用一次酉算符A)\n", + " N_good += result['1'] # 如果测量结果为1,对应计数加一\n", + "amp_mc = N_good/N_sample_mc # 通过测量结果为1的概率估算量子振幅a\n", + "error_mc = abs(amp_mc - quantum_amp) # 估算值与预设值的误差绝对值\n", + "rate_mc = error_mc/quantum_amp # 估算值的相对误差\n", + "print(f\"经典蒙特卡洛方法对量子振幅的估算结果是a = {amp_mc}, 误差绝对值为 {error_mc},相对误差为{100*rate_mc}%\")\n", + "print(f\"经典蒙特卡洛方法查询复杂度为{N_sample_mc}\")" + ] + }, + { + "cell_type": "markdown", + "id": "4177f22f", + "metadata": {}, + "source": [ + "经典蒙特卡洛算法作为一种最显而易见的解决方案,可以实现一定精度的振幅估算。估算精度由进行采样的次数决定,更多的采样次数会得到更高精度的振幅估算结果。但我们也注意到,在此方法中每进行一次测量都需要使用一次酉算符$A$来构造$| \\chi_0 \\rangle$态。因此,经典蒙特卡洛算法的查询复杂度等于采样总量。然而我们相信量子振幅估计算法能够提供更优的结果,即使用更低的量子查询复杂度来实现相同的估算精度,这也被称为量子加速(Quantum speedup)。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 最大似然振幅估算(MLAE)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "相比初代量子振幅估算,最大似然振幅估算算法(MLAE)规避了量子相位估算,通过将多条量子线路合并分析,来进行振幅估算。算法具体步骤如下:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**第一步**:选取一个集合$\\{m_k\\}$,此集合中的每一项代表了应用增大算符$Q$的次数,比如$m_k$对应$Q^{m_k}| \\chi_0 \\rangle_{n+1}$。\n", + "\n", + "测量$Q^{m_k}| \\chi_0 \\rangle_{n+1}$的辅助量子比特,进而确定量子态属于good state还是bad state。测量得到good state的概率为$\\sin^2((2m_k+1)\\theta_a)$\n", + "\n", + "对于态$Q^{m_k}| \\chi_0 \\rangle_{n+1}$我们用$N_k$来表示测量的总次数,$h_k$来表示测得good state的次数。\n", + "\n", + "进而我们可以写出对于集合第k项的似然函数:\n", + "\n", + "$$\n", + "L_k(h_k;\\theta_a)=[\\sin^2((2m_k+1)\\theta_a)]^{h_k}\n", + "[\\cos^2((2m_k+1)\\theta_a)]^{N_k-h_k} \\tag{6}\n", + "$$\n", + "\n", + "**第二步**:将集合$\\{m_0,......,m_M\\}$中每一项对应的似然函数$L_k(h_k;\\theta_a)$合并成一个总似然函数\n", + "\n", + "$$\n", + "L(\\mathbf{h};\\theta_a)= \\prod^{M}_{k=0}L_k(h_k;\\theta_a) \\tag{7}\n", + "$$\n", + "\n", + "其中$\\mathbf{h}=(h_0,h_1,...,h_M)$\n", + "\n", + "**第三步**:最大似然振幅估算定义是找到使$L(\\mathbf{h};\\theta_a)$取最大值的$\\theta_a$。故$\\theta_a$的表达式可以写为:\n", + "\n", + "$$\n", + "\\hat{\\theta_a}=\\arg{\\max_{\\theta_a}{L(\\mathbf{h};\\theta_a)}} \\tag{8}\n", + "=\\arg{\\max_{\\theta_a}{\\text{ln}[L(\\mathbf{h};\\theta_a)]}}\n", + "$$\n", + "\n", + "最终MLAE的结果为:\n", + "\n", + "$$\n", + "\\hat{a}=\\sin^2\\hat{\\theta_a} \\tag{9}\n", + "$$\n", + "\n", + "MLAE的完整过程如下图所示:" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "6dcf46cc", + "metadata": {}, + "source": [ + "![MLAE](./Figures/VQAE-fig-mlae.png \"MLAE 原理示意图 [3]。\")" + ] + }, + { + "cell_type": "markdown", + "id": "b34937f2", + "metadata": {}, + "source": [ + "选择合适的$\\{m_k, N_k\\}$,可以使得估算结果与经典算法对比体现较明显的优势。一般有两种选择方式:\n", + "\n", + "1. 线性增加(Linearly incremental sequence, LIS): $N_k = N_{shot}, \\forall k$,and $m_k = k$. i.e.$m_0=0, m_1=1, ...,m_M=M$\n", + " \n", + " 当$M\\gg1$时,预测误差$\\hat{\\epsilon}\\sim N_q^{-3/4}$,虽然没达到上述提及的最佳情况,但与经典蒙特卡洛方法相比,仍然能体现量子优势。\n", + " \n", + "2. 指数增加(Expoentially incremental sequence, ELS):$N_k = N_{shot}, \\forall k$,and $m_k = 2^{k-1}$。i.e. $m_0=0, m_1=2^0, ..., m_M=2^{M-1}$\n", + " \n", + " 预测误差$\\hat{\\epsilon}\\sim N_q^{-1}$\n", + " \n", + "\n", + "在变分量子振幅估算(VQAE)中,用到的是第一种线性增加序列。" + ] + }, + { + "cell_type": "markdown", + "id": "7673d10a", + "metadata": {}, + "source": [ + "### MLAE量桨实现 " + ] + }, + { + "cell_type": "markdown", + "id": "25488db9", + "metadata": {}, + "source": [ + "下面我们用量桨尝试实现最大似然量子振幅估算(MLAE)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# 初始化MLAE相关参数(对应于上述教程中的MLAE第一步)\n", + "M = 25 # 使用增大算符Q的最大次数\n", + "m = np.arange(0, M, 1) # 线性增加序列 LIS\n", + "N_k = 25 # 采样总次数\n", + "h_k = np.zeros(M) # 初始化数据空间以用于存储测得Good state次数\n", + "\n", + "# 采样过程\n", + "for k in range(M):\n", + " Q_operator_MLAE = Oracle(paddle.to_tensor([-1], dtype=\"complex64\") * r_chi @ r_good, qubits_idx=0, num_qubits=1, depth=k)\n", + " for i in range(N_k):\n", + " rotated_state = Q_operator_MLAE(chi_0_state) # 将增大算符作用在initial state上\n", + " result = rotated_state.measure(shots = 1) # 测量并统计good state(测得“1”)的次数\n", + " h_k[k] += result['1'] # 对于不同的k,记录测得good state的次数" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# 定义总似然函数(对数形式)(对应MLAE第二步)\n", + "params = ()\n", + "def likelihood(z, *params):\n", + " theta = z\n", + " f = 0\n", + " for i in range(M):\n", + " f = f + log(np.sin((2 * m[i] + 1) * theta) ** (2 * h_k[i]) * np.cos((2 * m[i] + 1) * theta) ** (2 * (N_k - h_k[i]))) #相乘转化为ln函数相加\n", + " return (-f) # 加负号使得后续算法求得的最小值对应于f的最大值" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "总似然函数的极大值为 -241.93038251847616 在theta = 0.5232857156858379 rad时取得\n", + "MLAE量子振幅估算结果为0.2497289311838693, 估算绝对误差为0.000271068816130704, 相对误差为0.1084275264522816%\n" + ] + } + ], + "source": [ + "# 使用Brute-force搜索算法来求总似然函数的极值(对应MLAE第三步)\n", + "rranges = (0, pi/2, pi/200) # Brute-force算法网格点的范围\n", + "resbrute = optimize.brute(likelihood, (rranges,), args=params, full_output=True, finish=optimize.fmin) #调用Brute-force算法\n", + "theta_a = resbrute[0][0] # 最小值对应的theta值\n", + "amp_MLAE = np.sin(theta_a) ** 2 # MLAE量子振幅估算值\n", + "error_MLAE = abs(amp_MLAE - quantum_amp) # 计算相对预设值的绝对误差\n", + "rate_MLAE = error_MLAE/quantum_amp # 相对误差\n", + "print(f\"总似然函数的极大值为 {-resbrute[1]} 在theta = {resbrute[0][0]} rad时取得\")\n", + "print(f\"MLAE量子振幅估算结果为{amp_MLAE}, 估算绝对误差为{error_MLAE}, 相对误差为{100 * rate_MLAE}%\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "根据上述算法过程,最大似然量子振幅估算的量子查询复杂度$N_{q-MLAE}$为:\n", + "\n", + "$$\n", + "N_{q-MLAE}=\\sum^{M}_{k=0}N_k(2m_k+1) \\tag{10}\n", + "$$\n", + "\n", + "其中$2m_k$代表着应用$m_k$次增大算符$Q$且每一次应用都需调用一次$A$和一次$A^\\dagger$($Q = -(I-2A| 0 \\rangle_{n+1} \\langle 0 |_{n+1}A^\\dagger) (I-2| \\psi_{good} \\rangle_{n}\\langle \\psi_{good}|_{n} \\otimes | 1 \\rangle\\langle 1 |) $);“+1”来自于制备初态 $| \\chi_0 \\rangle_{n+1}$时使用了一次算符$A$ ($| \\chi_0 \\rangle_{n+1}\n", + "=A| 0 \\rangle_{n+1})$;$N_k$代表对第$k$项的采样次数。" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MLAE的量子查询复杂度为15625\n" + ] + } + ], + "source": [ + "# 计算MLAE量子查询复杂度\n", + "N_q_MLAE = 0\n", + "for i in range(M):\n", + " N_q_MLAE += N_k * (2 * i + 1)\n", + "print(f\"MLAE的量子查询复杂度为{N_q_MLAE}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 最大似然振幅估算与经典蒙特卡洛对比" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "对同一个酉算符$A$的振幅估算问题,分别使用最大似然振幅估算和经典蒙特卡洛算法。比较两个算法估算误差$\\epsilon$与查询复杂度$N_q$之间的关系。例如,设定酉算符的输入参数为$\\pi/8$,保持两算法量子查询复杂度相同,比较估算值误差大小。数值实验结果如下图所示:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![comparison](./Figures/VQAE-fig-comparison.png \"图 3: MLAE 和 CMC 算法表现对比。\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "上图体现了MLAE算法在相同的量子查询复杂度下,估算误差大约比经典蒙特卡洛算法小一个数量级。这个结果体现了MLAE相比经典蒙特卡洛算法的优越性。当估算量子振幅越小时,MLAE相较经典蒙特卡洛的优势会越明显。读者可根据上文已提供的算法代码自行尝试验证。" + ] + }, + { + "cell_type": "markdown", + "id": "4b86a83e", + "metadata": {}, + "source": [ + "## 变分量子振幅估算(VQAE) " + ] + }, + { + "cell_type": "markdown", + "id": "7bab7472", + "metadata": {}, + "source": [ + "基于使用线性增大序列(LIS)$\\{m=1,2,3,...,M\\}$的MLAE算法的量子电路深度以$2m+1$的趋势增长。量子电路深度过大会增大其物理实现难度,所以提出了VQAE算法 [1] 来防止线路深度随$m$无限地增长。\n", + "\n", + "VQAE基于MLAE的算法框架增加了一个变分过程(variational step)。态$| \\chi_m \\rangle_{n+1}$会周期性地近似为一个深度为1的变分量子态。对于MLAE算法中的线性增加序列,我们选择一个正整数$k$作为变分周期,每到达$Q^k\\ (0 paddle.Tensor:\n", + " r\"\"\" 计算神经网络的损失函数\n", + " \n", + " Args:\n", + " input_state: 输入态\n", + " period: 变分周期\n", + " start_state: 当前变分态,用于构建目标态\n", + " target_param: 目标态参数\n", + " \n", + " Returns:\n", + " loss: 损失函数值, 损失函数定义为输入态和目标态之间的非保真度(Infidelity)\n", + " \n", + " \"\"\"\n", + "\n", + " Q_var = construct_Q(target_param, int(1), period)\n", + " Target_state = Q_var(start_state) \n", + " loss = 1 - StateFidelity(Target_state)(input_state)\n", + " return loss\n", + "\n", + "\n", + "def cir_constructor(depth: int) -> Circuit:\n", + " r\"\"\" 构建变分量子电路\n", + " \n", + " Args:\n", + " depth: 电路深度\n", + " \n", + " Returns:\n", + " 变分量子电路\n", + " \n", + " Note:\n", + " 单量子比特, 一层定义为Ry和Rz任意角度旋转门, 旋转角度为电路参数, 变分量子电路深度为3\n", + " \n", + " \"\"\"\n", + " cir = Circuit(1)\n", + " \n", + " for _ in range(depth):\n", + " cir.ry()\n", + " cir.rz()\n", + " return cir" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# 初始化相关参数(注:VQAE仍使用MLAE框架)\n", + "M = 25 # 使用增大算符Q的最大次数\n", + "m = np.arange(0, M, 1) # 线性增加序列 LIS\n", + "N_k_vqae = 50 # 采样总次数" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 变分近似定义\n", + "# 超参数设置\n", + "theta_size = 6 # 线路深度决定的参数数量\n", + "ITR = 500 # 设置迭代次数\n", + "LR = 0.001 # 设置学习速率\n", + "SEED = 1 # 固定随机数种子\n", + "paddle.seed(SEED)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=================================\n", + "第 1 次变分近似\n", + "损失函数的最小值是: 0.011207818984985352\n", + "变分参数值为 [-0.3985748 4.4845576 3.8463612 0.5077383 2.1137552 5.696977 ]\n", + "变分态相比目标态的保真度为0.9888777136802673\n", + "=================================\n", + "第 2 次变分近似\n", + "损失函数的最小值是: 0.022154152393341064\n", + "变分参数值为 [3.5385787 3.686828 3.778493 0.8545992 3.3457727 5.151529 ]\n", + "变分态相比目标态的保真度为0.9780024886131287\n", + "=================================\n", + "第 3 次变分近似\n", + "损失函数的最小值是: 0.12489771842956543\n", + "变分参数值为 [2.9717565 4.5942483 3.8417864 1.0915956 2.9404602 4.45632 ]\n", + "变分态相比目标态的保真度为0.8756691813468933\n", + "=================================\n", + "第 4 次变分近似\n", + "损失函数的最小值是: 0.07246685028076172\n", + "变分参数值为 [5.293609 5.0283127 1.7944657 3.575252 2.10594 4.7431984]\n", + "变分态相比目标态的保真度为0.9278923273086548\n", + "=================================\n", + "第 5 次变分近似\n", + "损失函数的最小值是: 0.007037162780761719\n", + "变分参数值为 [ 2.9615374 6.2987323 2.9560285 -0.05320463 1.5106332 3.6751766 ]\n", + "变分态相比目标态的保真度为0.993030846118927\n" + ] + } + ], + "source": [ + "# 采样和变分近似过程\n", + "start_state = chi_0_state # start_state是变分量子态,算法开始时为chi_0_state\n", + "cycle = 5 # 触发变分近似的周期\n", + "h_k_vqae = np.zeros(M) # 初始化数据空间以用于存储测得Good state次数\n", + "for k in range(M):\n", + " i = np.floor(k / cycle)\n", + " j = k % cycle\n", + " Q_operator_VQAE = construct_Q(set_param, int(1), j)\n", + " for sample in range(N_k_vqae):\n", + " rotated_state = Q_operator_VQAE(start_state) # 将增大算符作用在变分态上\n", + " result = rotated_state.measure(shots = 1) # 测量并统计good state(测得“1”)的\n", + " h_k_vqae[k] += result['1'] # 对于不同的k,测得good state的次数\n", + "\n", + " if j == cycle - 1: # 触发变分近似过程的条件\n", + " # 记录中间优化结果\n", + " loss_list = []\n", + "\n", + " # 定义变分电路\n", + " cir = cir_constructor(3)\n", + "\n", + " # 利用Adam优化器.\n", + " opt = paddle.optimizer.Adam(learning_rate=LR, parameters=cir.parameters())\n", + " \n", + " # 优化循环\n", + " for itr in range(ITR):\n", + " # 向前传播计算损失函数\n", + " loss = loss_fcn(cir(chi_0_state), cycle, start_state, set_param)\n", + "\n", + " # 反向传播优化损失函数\n", + " loss.backward()\n", + " opt.minimize(loss)\n", + " opt.clear_grad()\n", + "\n", + " # 记录学习曲线\n", + " loss_list.append(loss.item())\n", + " \n", + " print(\"=================================\")\n", + " print(f'第 {int(i + 1)} 次变分近似')\n", + " print(f'损失函数的最小值是: {loss_list[-1]}')\n", + " print(f\"\\r变分参数值为 {cir.param.numpy()}\")\n", + " \n", + " Q_test = construct_Q(set_param, int(1), cycle)\n", + " test_state = Q_test(start_state) # 更新用于计算保真度的测试态\n", + " \n", + " start_state = cir(chi_0_state) # 更新变分量子态\n", + " start_state.data.stop_gradient = True \n", + " print(f\"变分态相比目标态的保真度为{StateFidelity(test_state)(start_state).numpy()[0]}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# 定义总似然函数(对数形式)(对应MLAE第二步)\n", + "params = ()\n", + "def likelihood_vqae(z, *params):\n", + " theta = z\n", + " f = 0\n", + " for i in range(M):\n", + " f = f + log(np.sin((2 * m[i] + 1) * theta) ** (2 * h_k_vqae[i]) * np.cos((2 * m[i] + 1) * theta) ** (2 * (N_k_vqae - h_k_vqae[i]))) #相乘转化为ln函数相加\n", + " return (-f) # 加负号使得后续算法求得的最小值对应于f的最大值" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=================================\n", + "总似然函数的极大值为 -691.84028156814 在theta = 0.532245313972681 rad时取得\n", + "VQAE量子振幅估算结果为0.2575251290528533, 估算绝对误差为0.007525129052853297, 相对误差为3.0100516211413186%\n" + ] + } + ], + "source": [ + "# 使用Brute-force搜索算法来求总似然函数的极值(对应MLAE第三步)\n", + "rranges = (0, pi/2, pi/200) # Brute-force算法网格点的范围\n", + "resbrute = optimize.brute(likelihood_vqae, (rranges,), args=params, full_output=True, finish=optimize.fmin) #调用Brute-force算法\n", + "theta_a = resbrute[0][0] # 最小值对应的theta值\n", + "amp_VQAE = np.sin(theta_a) ** 2 # MLAE量子振幅估算值\n", + "error_VQAE = abs(amp_VQAE - quantum_amp) # 计算相对预设值的绝对误差\n", + "rate_VQAE = error_VQAE/quantum_amp # 相对误差\n", + "print(\"=================================\")\n", + "print(f\"总似然函数的极大值为 {-resbrute[1]} 在theta = {resbrute[0][0]} rad时取得\")\n", + "print(f\"VQAE量子振幅估算结果为{amp_VQAE}, 估算绝对误差为{error_VQAE}, 相对误差为{100 * rate_VQAE}%\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "由此可得,VQAE算法也实现了精度较高的振幅估算,与原MLAE算法相比最大量子电路深度显著减小。例如,考虑M=50且变分周期为5的情况,MLAE算法最多需要对$| \\chi_0 \\rangle$连续应用50次增大算符$Q$,而VQAE算法的量子电路最多连续应用5次,为MLAE的十分之一。这说明使用VQAE算法可以有效地减少量子电路深度,有助于量子振幅估算在NISQ设备上实现。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "VQAE算法的量子查询复杂度由变分复杂度$N_{var}$和采样复杂度$N_{samp}$两部分组成。\n", + "$$\n", + "N = N_{var} + N_{samp} \\tag{15}\n", + "$$\n", + "$$\n", + "N_{var} = N_{var/1}(2k+2)\\lfloor M/k \\rfloor \\sim O(k\\lfloor M/k \\rfloor) \\tag{16}\n", + "$$\n", + "$$\n", + "N_{samp} = hk(k+2)\\lfloor M/k \\rfloor + h(M\\%k)(M\\%k+2) \\tag{17}\n", + "$$\n", + "其中$M$为MLAE线性增大序列中的最大值,$k$为VQAE中的变分周期,$h$为采样过程中对每个态重复采样的次数。$N_{var/1}=2n_fn_sn_p$, 一次变分过程中需要运行的量子电路总量,其中$n_p$为参数化量子电路的参数数量,$n_s$是参数化量子电路的参数扫描次数,$n_f$是每次计算目标函数时伯努利试验的次数(在硬件实现中可以认为约等于$n_s$)。具体分析可查看参考文献[1]。" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "采样复杂度为 8750\n", + "变分复杂度为 180000000\n", + "VQAE算法的量子查询复杂度为 180008750\n" + ] + } + ], + "source": [ + "# 计算VQAE量子查询复杂度\n", + "from math import floor\n", + "M_vqae = M\n", + "k_cycle = cycle\n", + "n_p = theta_size\n", + "n_s = ITR\n", + "n_f = n_s\n", + "N_var1 = 2 * n_p * n_s * n_f\n", + "N_var = N_var1 * (2 * k_cycle + 2) * floor(M_vqae/k_cycle)\n", + "N_samp = N_k_vqae * k_cycle * (k_cycle + 2) * floor(M_vqae/k_cycle) + N_k_vqae * (M_vqae % k_cycle) * (M_vqae % k_cycle + 2)\n", + "print(f\"采样复杂度为 {N_samp}\")\n", + "print(f\"变分复杂度为 {N_var}\")\n", + "print(f\"VQAE算法的量子查询复杂度为 {N_var + N_samp}\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "我们注意到VQAE算法的量子查询复杂度很高,其主要来自于变分近似过程的复杂度。这是减少量子电路深度所引入的代价。引入的变分过程并非越多越好,量子电路的深度和变分过程的复杂度之间存在一个权衡关系。但是可以通过一些优化设计,降低变分近似过程中的量子查询复杂度。比如文献[1]中提到的Adaptive VQAE,感兴趣的读者可自行参看。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 总结" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "本教程主要内容为用量桨实现变分量子振幅估算(VQAE)。教程首先介绍了量子振幅估算问题和初代算法物理实现的难度。进而介绍了最大似然振幅估算(MLAE),MLAE规避了初代算法主要的物理实现难点——量子相位估算,但是存在量子电路深度过大的问题,也不利于物理实现。为了降低MLAE算法的量子电路深度,我们引入了一个变分近似过程得到了变分量子振幅估算,VQAE相比MLAE可以显著降低量子电路的深度。VQAE算法的提出进一步提高了量子振幅估算物理实现的可能性。但同时需注意,引入变分过程时会带来大量变分复杂度,变分过程和量子电路深度之间存在权衡关系。\n", + "\n", + "教程基于量桨实现了单量子比特的MLAE和VQAE,展示了对预设量子振幅的低误差预测。并且比较了上述算法与经典蒙特卡洛算法的预测精度和量子查询复杂度,通过数值实验展示了量子算法相比经典算法的加速效应。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "_______\n", + "## 参考文献" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[1] Plekhanov, Kirill, et al. \"Variational quantum amplitude estimation.\" Quantum 6 (2022): 670. https://quantum-journal.org/papers/q-2022-03-17-670/\n", + "\n", + "[2] Preskill, John. \"Quantum computing in the NISQ era and beyond.\" Quantum 2 (2018): 79. https://quantum-journal.org/papers/q-2018-08-06-79/\n", + "\n", + "[3] Suzuki, Yohichi, et al. \"Amplitude estimation without phase estimation.\" Quantum Information Processing 19.2 (2020): 1-17. https://link.springer.com/article/10.1007/s11128-019-2565-2\n", + "\n", + "[4] Brassard, Gilles, et al. \"Quantum amplitude amplification and estimation.\" Contemporary Mathematics 305 (2002): 53-74. https://arxiv.org/pdf/quant-ph/0005055.pdf" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('py3.7_pq2.2.1')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.13" + }, + "vscode": { + "interpreter": { + "hash": "4e4e2eb86ad73936e915e7c7629a18a8ca06348106cf3e66676b9578cb1a47dd" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tutorials/machine_learning/VQAE_EN.ipynb b/tutorials/machine_learning/VQAE_EN.ipynb new file mode 100644 index 0000000..0e93c1a --- /dev/null +++ b/tutorials/machine_learning/VQAE_EN.ipynb @@ -0,0 +1,1030 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Variational quantum amplitude estimation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Copyright (c) 2022 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Backgrounds" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This tutorial implements single-qubit variational quantum amplitude estimation (VQAE) [1] based on Paddle Quantum. Before getting into VQAE, let's first review quantum amplitude estimation. \n", + "\n", + "In general, assume there is an operation for $n+1$ qubits denoted as unitary operator $A$, and the effect of applying it on a zero state can be written as:\n", + "\n", + "$$\n", + "A | 0 \\rangle_{n+1}=| \\chi_0 \\rangle_{n+1}\n", + "=\\sqrt{a}| \\psi_{good}\\rangle_{n}| 1 \\rangle\n", + "+\\sqrt{1-a}| \\psi_{bad}\\rangle_{n}| 0 \\rangle,\n", + "$$\n", + "\n", + "where good state $| \\psi_{good }\\rangle_n$ and bad state $| \\psi_{bad }\\rangle_n$ are orthonormal quantum states of $n$ qubits, each of them corresponds to an ancillary qubit. \n", + "\n", + "For certain operation $A$, $a$ is called the corresponding quantum amplitude. Quantum amplitude estimation is to estimate the value of the unknown parameter $a$.\n", + "\n", + "In the noisy intermediate-scale quantum (NISQ) [2] era, in order to implement quantum algorithms on hardwares, researchers persue for shallower quantum circuit and more concise quantum operations. In this tutorial, we use quantum query complexity $N_{query}$ to compare the performance of different estimation algorithms. Quantum query complexity is defined as the total number of implementing operation $A$ within the whole quantum circuit. Generally, we hope to achieve higher estimation accuracy with lower quantum query complexity.\n", + "\n", + "Three algorithms are going to be reviewed in this tutorial, which are classical Monte-Carlo method (CMC), maximum likelihood amplitude estimation(MLAE) [3], and variational quantum amplitude estimation. The tutorial shows MLAE provides better estimation accuracy than CMC with the same quantum query complexity. VQAE is developed based on MLAE and requires much shallower quantum circuit than MLAE." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# Import related packages\n", + "import paddle\n", + "from paddle_quantum.gate import Oracle\n", + "from paddle_quantum.ansatz import Circuit\n", + "from paddle_quantum.state import State, zero_state\n", + "from paddle_quantum.loss import StateFidelity\n", + "import numpy as np\n", + "from numpy import pi, log\n", + "from scipy import optimize\n", + "import warnings\n", + "warnings.filterwarnings('ignore')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For the general case of $n+1$ qubits, $| \\psi_{good}\\rangle_{n}$ and $| 1 \\rangle_{n}$ are an pair of orthonormal basis reconstructed by the $2^n$ basis expanded by $n$ qubits in the Hilbert space.\n", + "\n", + "For concision, we consider the case of single qubit in the following tutorial. We defined the two basis $| \\psi_{bad} \\rangle$ and $| 0 \\rangle$ as bad state and good state, $A | 1 \\rangle_{1+1}=| 0 \\rangle_{1+1}=\\sqrt{a}| \\chi_0 \\rangle| 1 \\rangle_{anc}+\\sqrt{1-a}| 1 \\rangle| 0 \\rangle_{anc}$. Moreover, we can neglect the ancillary qubit when implementing on Paddle Quantum, $A | 0 \\rangle_{1}=| 0 \\rangle_{1}=\\sqrt{a}| \\chi_0 \\rangle+\\sqrt{1-a}| 1 \\rangle$.\n", + "\n", + "Intuitively, single-qubit quantum state can be demonstrated as a vector from the center to a point on the surface of a Bloch sphere. In this case, the effect of unitary operator $A$ can be regarded as a rotation of the vector on the Bloch sphere.\n", + "\n", + "Thus, we can use a general single-qubit rotation gate $U3$ to construct the unitary operator $A$." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The quantum amplitude correspond to the unitary operator A is 0.25\n" + ] + } + ], + "source": [ + "# Define the unitary operator A\n", + "n_qubits = 1 # Single qubit\n", + "amp_operator = Circuit(n_qubits) # Construct the single-qubit unitary operator A\n", + "set_param = pi/3 # The parameter for the unitary operator A\n", + "amp_param = paddle.to_tensor([set_param, 0, 0], dtype='float32') # Transfer the parameter to tensor\n", + "amp_operator.u3(param=amp_param) # Input the parameter to a U3 gate to construct A\n", + "\n", + "initial_state = zero_state(n_qubits) # Define the initial state as zero state\n", + "chi_0_state =amp_operator(initial_state) # The effect of applying A on zero state\n", + "quantum_amp =chi_0_state.measure()['1'] # Output the pre-set quantum amplitude for estimation\n", + "print(f\"The quantum amplitude correspond to the unitary operator A is {quantum_amp}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Brief introduction to QAE" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In 2002, Brassard et al. [4] proposed a scheme for quantum amplitude estimation which showed quadratic quantum speedup compared with CMC. For certain estimation error $\\epsilon$, the quantum query complexity are proved as:\n", + "\n", + "$$\n", + " N_{q-AE}\\sim O(1/\\epsilon)\\quad N_{q-MC}\\sim O(1/\\epsilon^2)\n", + "$$\n", + "\n", + "The key process of traditional quantum amplitude estimation is quantum amplitude amplification (QAA). QAA is generalized from Grover's search algorithm.\n", + "\n", + "Assume a amplification operator $Q$ defined as:\n", + "\n", + "$$\n", + "Q=-R_{\\chi}R_{good},\n", + "$$\n", + "\n", + "where\n", + "\n", + "$$\n", + "R_{\\chi}=I-2| 1 \\rangle_{n+1}\\langle{\\chi_0}|_{n+1}=I-2A| \\psi_{bad} \\rangle_{n+1} \\langle 0|_{n+1}A^\\dagger\n", + "$$\n", + "\n", + "$$\n", + "R_{good}=I-2| 0 \\rangle_{n} \\langle 1| \\otimes | 1 \\rangle \\langle \\psi_{good}|_{n}\n", + "$$\n", + "\n", + "$R_{\\chi}$ and $R_{good}$ are reflection operators in the 2-dimensional subspace $H_{\\chi}$ expanded by basis $| 0 \\rangle| \\chi_0 \\rangle$ and $| 1 \\rangle| 1 \\rangle$ .\n", + "\n", + "We can consider $| 0 \\rangle$ as a vector in subspace $H_{\\chi}$. \n", + "\n", + "$$\n", + "| 0 \\rangle_{n+1}=\\cos(\\theta)\n", + "| 0 \\rangle_{n}| \\chi_0 \\rangle+\\sin(\\theta)| 1 \\rangle_{n}| 0 \\rangle,\n", + "$$\n", + "\n", + "where $\\theta$ is the angle between vector $| \\chi_0 \\rangle$ and the axis of $| 0 \\rangle| \\psi_{good} \\rangle$. We can define the quantum amplitude as $a=\\sin^2(\\theta)$.\n", + "\n", + "If we apply amplification operator $Q$ on $| 1 \\rangle$ for $m$ times, we can prove that:\n", + "\n", + "$$\n", + "| \\psi_{good} \\rangle_{n+1}=Q^m| 1 \\rangle_{n+1}=\\cos[(2m+1)\\theta]\n", + "| \\psi_{bad} \\rangle_{n}| 0 \\rangle+\\sin[(2m+1)\\theta]| \\chi_0 \\rangle_{n}| \\chi_0 \\rangle\n", + "$$\n", + "\n", + "Intuitively, in 2-dimensional subspace $H_{\\chi}$, the effect of amplification operator $Q$ can be regarded as a $2\\theta$ rotation of vector $| \\psi_{bad}\\rangle$ towards the axis of $| 0 \\rangle| \\psi_{good} \\rangle$. \n", + "\n", + "Also, if we apply the amplification operator $Q$ for certain times $m=\\lfloor \\frac{1}{2}(\\frac{\\pi}{2\\theta}-1)\\rfloor$, the quantum amplitude of the rotated state will approximate one $a_m=\\sin[(2m+1)\\theta]\\approx1$." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Construct the reflection operator R_chi\n", + "identity = paddle.to_tensor([[1, 0],[0, 1]], dtype=\"complex64\") # Define the identity matrix\n", + "density_matrix_0 = chi_0_state.ket @ chi_0_state.bra # amp_0_state in the form of density matrix\n", + "r_chi = identity - paddle.to_tensor([2], dtype=\"complex64\") * density_matrix_0 # Construct the reflection operator respect to state chi" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Construct the reflection operator R_good\n", + "flip = Circuit(n_qubits)\n", + "flip.x() \n", + "one_state = flip(initial_state) # Construct the \"one state\" which is defined as good state\n", + "density_matrix_good = one_state.ket @ one_state.bra # Good state in the form of density matrix\n", + "r_good = identity - paddle.to_tensor([2], dtype=\"complex64\") * density_matrix_good # Construct the reflection operator respect to the good state" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Construct the amplification operator Q\n", + "num_amplification = 1 # The total times of apply Q\n", + "Q_operator = Oracle(paddle.to_tensor([-1], dtype=\"complex64\") * r_chi @ r_good, qubits_idx=0, num_qubits=1, depth=num_amplification) # Use Oracle to construct the amplification operator" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "From the definition $a = \\sin^2(\\theta)$, estimating quantum amplitude $a$ can be done by estimating $\\theta$. We notice that the amplification operator can be written as $Q=-R_{\\chi}R_{good}=e^{-i2\\theta Y}$, where $| 1 \\rangle_{n+1}$ is the eigenvector of $Q$ with eigenvalue $e^{\\pm2i\\theta}$. Thus, we can apply quantum phase estimation on $Q$ to estimate $\\theta$. The circuit for quantum phase estimation is shown as follow." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "76f5e510", + "metadata": {}, + "source": [ + "![QPE](./figures/VQAE-fig-qpe.png \"Figure 1: Quantum circuit for quantum amplitude estimation [4].\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, the circuit of quantum phase estimation includes quantum fourier transform and multiple control gate, which means it's very difficult to implement quantum amplitude estimation on NISQ devices. Therefore, researcher have been trying to design better algorithms which have lower requirements on the hardware, in order to implement this algorithm and demonstrate quantum advantages." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The topic of this tutorial, VQAE, is a recently proposed algorithm. VQAE is developed based on the framework of maximum likelihood amplitude estimation by adding a variational approximation process which keeps the quantum circuit within a certain depth. Generally, shallower quantum circuits are easier to be implemented. Furthermore, compared with CMC, VQAE and MLAE can achieve the same accuracy with lower quantum query complexity. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the following, the tutorial will show how to implement CMC, MLAE, and VQAE based on Paddle Quantum." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Classical Monte-Carlo algorithm (CMC)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The idea of CMC is quite straightforward and purely classical. We prepare the state in $A| 1 \\rangle_{n+1}=\\sqrt{a}| \\psi_{bad} \\rangle_{n}| 0 \\rangle_{anc}+\\sqrt{1-a}| 1 \\rangle_{n}| 0 \\rangle_{anc}$ then make measurements on an entangled ancillary qubit repeatedly. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The frequency of measuring the ancillary qubit as $| 1 \\rangle$ estimates the quantum amplitude $a$.\n", + "\n", + "$$\n", + " a \\approx \\frac{N_{good}}{N_{measure}}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then we use Paddle Quantum to implement CMC. Consider the case of single-qubit, we can choose not to introduce the ancillary qubit." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "d8c88075", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CMC Estimation result is a = 0.24915, absolute error is 0.0008499999999999897, relative error is 0.33999999999999586%\n", + "CMC Query complexity is 20000\n" + ] + } + ], + "source": [ + "# Classical Monte-Carlo method\n", + "N_sample_mc = 20000 # The total amount of sampling\n", + "N_good = 0 # Initialize the times of measuring good state\n", + "for i in range(N_sample_mc):\n", + " result = chi_0_state.measure(shots=1) # Sample the chi state once\n", + " N_good += result['1'] # If the measurement result is \"1\", N_good plus one\n", + "amp_mc = N_good/N_sample_mc # Estimate the quantum amplitude by the probability of mearsuring \"1\"\n", + "error_mc = abs(amp_mc - quantum_amp) # Absolute error of the estimation \n", + "rate_mc = error_mc/quantum_amp # Relative error of the estimation\n", + "print(f\"CMC Estimation result is a = {amp_mc}, absolute error is {error_mc}, relative error is {100*rate_mc}%\")\n", + "print(f\"CMC Query complexity is {N_sample_mc}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "CMC can achieve certain estimation accuracy. Since the estimation is based on frequency, the accuracy of estimation is determined by the amount of measurements $N_{measure}$. Larger amount of measurement gives higher accuracy. However, we notice that each measurement requires implementing unitary $A$ once to construct $| 1 \\rangle$. Thus, the query complexity of CMC equals to the total amount of sampling. It's quite costly to achieve the desired accuracy, especially for small unknown amplitude a. As will be shown later, quantum algorithms can achieve better accuracy with same query complexity, which is called quantum speedup." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Maximum likelihood amplitude estimation(MLAE)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "MLAE provides a way to implement amplitude estimation without quantum phase estimation. \n", + "\n", + "The idea of MLAE is to combine the results of several quantum circuits together through likelihood function, then estimate $\\theta$ by optimizing the likelihood function. It's explained step by step as follows." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Step 1:** \n", + "\n", + "* Give a set $\\{m_k\\}$ of $M$ terms. Each term of the set $m_k$ determines how many times amplification operator $Q$ is applied to $| 1 \\rangle$, i.e. $Q^{m_k}| \\psi_{bad} \\rangle$. \n", + "\n", + "* Prepare state $Q^{m_k}| 0 \\rangle$ for $N_k$ times and make good/bad state measurement on the ancillary qubit for all of them. $h_k$ denotes how many times measurement gives good state.\n", + "\n", + "* Write the likelihood function for term $m_k$ as:\n", + "\n", + "$$\n", + " L_k(h_k;\\theta_a)=[\\sin^2((2m_k+1)\\theta_a)]^{h_k}[\\cos^2((2m_k+1)\\theta_a)]^{N_k-h_k}\n", + "$$\n", + "\n", + "**Step 2:**\n", + "\n", + "Combine the likelihood functions $L_k(h_k;\\theta_a)$ for $\\{m_0,......,m_M\\}$ as a single likelihood function as:\n", + "\n", + "$$\n", + " L(\\mathbf{h};\\theta_a)= \\prod^{M}_{k=0}L_k(h_k;\\theta_a)\n", + "$$\n", + "\n", + "Where $\\mathbf{h}=(h_0,h_1,...,h_M)$\n", + "\n", + "**Step 3:**\n", + "\n", + "Find the $\\theta_a$ that maximizes the single likelihood function $L(\\mathbf{h};\\theta_a)$\n", + "\n", + "$$\n", + " \\hat{\\theta_a}=\\arg{\\max_{\\theta_a}{L(\\mathbf{h};\\theta_a)}}=\\arg{\\max_{\\theta_a}{\\text{ln}[L(\\mathbf{h};\\theta_a)]}}\n", + "$$\n", + "\n", + "Then the final result of MLAE can be given by $\\hat{a}=\\sin^2\\hat{\\theta_a}$. And the process of MLAE is shown as figure below." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "6dcf46cc", + "metadata": {}, + "source": [ + "![MLAE](./figures/VQAE-fig-mlae.png \"Figure 2: Process of MLAE [3].\")" + ] + }, + { + "cell_type": "markdown", + "id": "b34937f2", + "metadata": {}, + "source": [ + "By choosing proper set $\\{m_k\\}$ and parameter $N_k$, estimation result can show quantum advantage. There are two main ways to give $\\{m_k\\}$.\n", + "\n", + "1. Linearly incremental sequence, LIS: $N_k = N_{shot}, \\forall k$,and $m_k = k$. i.e.$m_0=0, m_1=1, ...,m_M=M$\n", + " \n", + " When $M\\gg1$, the estimation error is $\\hat{\\epsilon}\\sim N_q^{-3/4}$ which shows quantum advantage compared to CMC.\n", + " \n", + "2. Exponentially incremental sequence, ELS: $N_k = N_{shot}, \\forall k$,and $m_k = 2^{k-1}$。i.e. $m_0=0, m_1=2^0, ..., m_M=2^{M-1}$\n", + " \n", + " Estimation error: $\\hat{\\epsilon}\\sim N_q^{-1}$\n", + " \n", + "In VQAE, set $\\{m_k\\}$ is given by LIS." + ] + }, + { + "cell_type": "markdown", + "id": "7673d10a", + "metadata": {}, + "source": [ + "### MLAE by Paddle Quantum" + ] + }, + { + "cell_type": "markdown", + "id": "25488db9", + "metadata": {}, + "source": [ + "In the following, we implement MLAE based on Paddle Quantum." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# Step 1 of MLAE\n", + "\n", + "# Initialize parameters \n", + "M = 25 # Maximum times of implementing Q\n", + "m = np.arange(0, M, 1) #LIS\n", + "N_k = 25 # Total amount of sampling\n", + "h_k = np.zeros(M) # Initialize the data space to store the times of measuring good state.\n", + "\n", + "# Sampling process\n", + "for k in range(M):\n", + " Q_operator_MLAE = Oracle(paddle.to_tensor([-1], dtype=\"complex64\") * r_chi @ r_good, qubits_idx=0, num_qubits=1, depth=k)\n", + " for i in range(N_k):\n", + " rotated_state = Q_operator_MLAE(chi_0_state) # Implement amplification operator on initial state\n", + " result = rotated_state.measure(shots = 1) # Measure and record the number of measuring good state\n", + " h_k[k] += result['1'] # Store the number of good state for different \"k\"" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Step 2 of MLAE \n", + "# Definition of the likelihood function (in logarithmic form)\n", + "params = ()\n", + "def likelihood(z, *params):\n", + " theta = z\n", + " f = 0\n", + " for i in range(M):\n", + " f = f + log(np.sin((2 * m[i] + 1) * theta) ** (2 * h_k[i]) * np.cos((2 * m[i] + 1) * theta) ** (2 * (N_k - h_k[i])))\n", + " return (-f) # the following algorithm will find the minimum, minus sign corresponds the result to maximum." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The maximum value for likelihood function is -243.068172605532 when theta = 0.5233743030763384 rad\n", + "MLAE result is 0.249805626294017, absolute error is 0.00019437370598299197, relative error is 0.07774948239319679%\n" + ] + } + ], + "source": [ + "# Step 3 of MLAE\n", + "# Use Brute-force search algorithm to find the maximum value of likelihood function\n", + "rranges = (0, pi/2, pi/200) # Range of grid for Brute-force algorithm\n", + "resbrute = optimize.brute(likelihood, (rranges,), args=params, full_output=True, finish=optimize.fmin) # Call Brute-force algorithm\n", + "theta_a = resbrute[0][0] # Theta corresponds to the minimum of -f\n", + "amp_MLAE = np.sin(theta_a) ** 2 # Quantum amplitude estimation from MLAE\n", + "error_MLAE = abs(amp_MLAE - quantum_amp) # Absolute estimation error\n", + "rate_MLAE = error_MLAE/quantum_amp # Relative estimation error\n", + "print(f\"The maximum value for likelihood function is {-resbrute[1]} when theta = {resbrute[0][0]} rad\")\n", + "print(f\"MLAE result is {amp_MLAE}, absolute error is {error_MLAE}, relative error is {100 * rate_MLAE}%\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Based on the above algorithm, the quantum query complexity of MLAE can be written as:\n", + "\n", + "$$\n", + "N_{q-MLAE}=\\sum^{M}_{k=0}N_k(2m_k+1)\n", + "$$\n", + "\n", + "Where $2m_k$ denotes implementing amplification operator $Q$ by $m_k$ times and each implementation requires to call $A$ and $A^\\dagger$ once.($Q = -(I-2A| 0 \\rangle_{n+1}\\langle{0}|_{n+1}A^\\dagger)(I-2| \\psi_{bad}\\rangle_{n}\\langle{\\psi_{good}}|_{n}\\otimes | 1 \\rangle\\langle{1}|) $)\n", + "\n", + "\"+1\" origins from preparing the initial state $| 1 \\rangle_{n+1}$. ($| 0 \\rangle_{n+1}\n", + "=A| \\chi_0 \\rangle_{n+1}$); $N_k$ denotes the sampling amount for the $k$ th item. " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The quantum query complexity for MLAE is 15625\n" + ] + } + ], + "source": [ + "# Quantum query complexity for MLAE \n", + "N_q_MLAE = 0\n", + "for i in range(M):\n", + " N_q_MLAE += N_k * (2 * i + 1)\n", + "print(f\"The quantum query complexity for MLAE is {N_q_MLAE}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Comparison between MLAE and CMC" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For the amplitude estimation problem of the same unitary operator $A$, we compare the relation of estimation error $\\epsilon$ and query complexity $N_q$ between the two algorithm. For example, setting the input parameter of the unitary A as $\\pi/8$, the numerical experiment result of two algorithms with same query complexity is shown as below. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![comparison](./figures/VQAE-fig-comparison.png \"Figure 3: Performance comparison between MLAE and CMC.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The above figure shows the estimation error of MLAE is about one order smaller than that of CMC. The result shows the advantage of MLAE compared to CMC. The advantage will be more evident as the preset quantum amplitude decreases.\n", + "\n", + "With the provided codes, readers are encouraged to do numerical experiments for verification. " + ] + }, + { + "cell_type": "markdown", + "id": "4b86a83e", + "metadata": {}, + "source": [ + "## Variational quantum amplitude estimation" + ] + }, + { + "cell_type": "markdown", + "id": "7bab7472", + "metadata": {}, + "source": [ + "In MLAE, we notice that the depth of quantum circuits grows as $2m+1$. Although we get rid of quantum phase estimation in MLAE, large quantum circuit depth will also make implementation difficult. \n", + "\n", + "The recent work [1] proposed amplitude estimation with the help of constant-depth quantum circuits that variationally approximate states during amplitude amplification.\n", + "\n", + "The main different between VQAE and MLAE is the variational approximation process. During quantum amplitude amplification (Step 1 of MLAE), the state $| 1 \\rangle_{n+1}$ is periodically replaced by a variational quantum state. For linear increment sequence in MLAE, we choose an positive integer $k$ as variational period, variational approximation begins when it reaches $Q^k\\ (0 paddle.Tensor:\n", + " r\"\"\" Calculate the loss function for neural network.\n", + " \n", + " Args:\n", + " input_state: input state\n", + " period: period of variational process \n", + " start_state: current variational quantum state, for constructing target state\n", + " target_param: parameter of target state\n", + " \n", + " Returns:\n", + " loss: the value of loss function which is defined as the infidelity between the input state and target state\n", + " \n", + " \"\"\"\n", + "\n", + " Q_var = construct_Q(target_param, int(1), period)\n", + " Target_state = Q_var(start_state) \n", + " loss = 1 - StateFidelity(Target_state)(input_state)\n", + " return loss\n", + "\n", + "\n", + "def cir_constructor(depth: int) -> Circuit:\n", + " r\"\"\" Construct variational quantum circuit\n", + " \n", + " Args:\n", + " depth: the depth of quantum circuit\n", + " \n", + " Returns:\n", + " variational quantum circuit\n", + " \n", + " Note:\n", + " For single qubit, one layer is defined as a combination of Ry and Rz rotation gate.\n", + " The rotation angles are the parameters of quantum circuit.\n", + " \n", + " \"\"\"\n", + " cir = Circuit(1)\n", + " \n", + " for _ in range(depth):\n", + " cir.ry()\n", + " cir.rz()\n", + " return cir" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# Initialization of parameters (Notice: VQAE is based on the framework of MLAE)\n", + "M = 25 # Maximum times of implementing Q\n", + "m = np.arange(0, M, 1) # Linear increment sequence\n", + "N_k_vqae = 50 # Total amount of sampling" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Superparameters for variational approximation\n", + "theta_size = 6 # Amount of variational parameters (depends on the depth of circuit)\n", + "ITR = 500 # Number of iterations\n", + "LR = 0.001 # Learning rate \n", + "SEED = 1 # Random number seed\n", + "paddle.seed(SEED)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=================================\n", + "The 1 th variational approximation\n", + "The minimum of loss function 0.011207759380340576\n", + "Optimal variational parameters [-0.39857474 4.4845576 3.8463612 0.5077383 2.1137552 5.696977 ]\n", + "The state fidelity between variational quantum state and target state is 0.9888777136802673\n", + "=================================\n", + "The 2 th variational approximation\n", + "The minimum of loss function 0.02215433120727539\n", + "Optimal variational parameters [3.538579 3.6868277 3.778493 0.8545991 3.3457727 5.151529 ]\n", + "The state fidelity between variational quantum state and target state is 0.9780022501945496\n", + "=================================\n", + "The 3 th variational approximation\n", + "The minimum of loss function 0.12489765882492065\n", + "Optimal variational parameters [2.9717562 4.5942483 3.8417864 1.0915955 2.9404604 4.45632 ]\n", + "The state fidelity between variational quantum state and target state is 0.8756692409515381\n", + "=================================\n", + "The 4 th variational approximation\n", + "The minimum of loss function 0.0724669098854065\n", + "Optimal variational parameters [5.293609 5.0283127 1.7944657 3.575252 2.10594 4.743199 ]\n", + "The state fidelity between variational quantum state and target state is 0.9278923273086548\n", + "=================================\n", + "The 5 th variational approximation\n", + "The minimum of loss function 0.007037222385406494\n", + "Optimal variational parameters [ 2.9615376 6.2987323 2.9560285 -0.05320466 1.5106332 3.6751769 ]\n", + "The state fidelity between variational quantum state and target state is 0.9930309057235718\n" + ] + } + ], + "source": [ + "# Sampling and variational approximation process\n", + "start_state = chi_0_state #start_state is the variational quantum state, equals to chi_0_state in the beginning\n", + "cycle = 5 # Variational period\n", + "h_k_vqae = np.zeros(M) # Initialize the data space to store the times of measuring good state.\n", + "for k in range(M):\n", + " i = np.floor(k / cycle)\n", + " j = k % cycle\n", + " Q_operator_VQAE = construct_Q(set_param, int(1), j)\n", + " for sample in range(N_k_vqae):\n", + " rotated_state = Q_operator_VQAE(start_state) # Implement amplification operator on initial state\n", + " result = rotated_state.measure(shots = 1) # Measure and record the number of measuring good state\n", + " h_k_vqae[k] += result['1'] # Store the number of good state for different \"k\"\n", + "\n", + " if j == cycle - 1: # Condition to trigger variational approximation process\n", + " # Create data space to store loss function\n", + " loss_list = []\n", + "\n", + " # Define the variational circuit\n", + " cir = cir_constructor(3)\n", + "\n", + " # Use Adam optimizer\n", + " opt = paddle.optimizer.Adam(learning_rate=LR, parameters=cir.parameters())\n", + " \n", + " # Optimization iterations\n", + " for itr in range(ITR):\n", + " # Forward optimize the loss function\n", + " loss = loss_fcn(cir(chi_0_state), cycle, start_state, set_param)\n", + "\n", + " # Backward optimize the loss function\n", + " loss.backward()\n", + " opt.minimize(loss)\n", + " opt.clear_grad()\n", + "\n", + " # Record the loss function (learning curve)\n", + " loss_list.append(loss.item())\n", + " \n", + " print(\"=================================\")\n", + " print(f'The {int(i + 1)} th variational approximation')\n", + " print(f'The minimum of loss function {loss_list[-1]}')\n", + " print(f\"Optimal variational parameters {cir.param.numpy()}\")\n", + " \n", + " Q_test = construct_Q(set_param, int(1), cycle)\n", + " test_state = Q_test(start_state) # Update the test state for fidelity calculation\n", + " \n", + " start_state = cir(chi_0_state) # Update the variational quantum state \n", + " start_state.data.stop_gradient = True \n", + " print(f\"The state fidelity between variational quantum state and target state is {StateFidelity(test_state)(start_state).numpy()[0]}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "# Definition of the likelihood function (in logarithmic form)\n", + "params = ()\n", + "def likelihood_vqae(z, *params):\n", + " theta = z\n", + " f = 0\n", + " for i in range(M):\n", + " f = f + log(np.sin((2 * m[i] + 1) * theta) ** (2 * h_k_vqae[i]) * np.cos((2 * m[i] + 1) * theta) ** (2 * (N_k_vqae - h_k_vqae[i])))\n", + " return (-f)# the following algorithm will find the minimum, minus sign corresponds the result to maximum." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=================================\n", + "The maximum value for likelihood function is -728.8282960799222 when theta = 0.5310066244864633 rad\n", + "VQAE result is 0.2564425882363815, absolute error is 0.006442588236381497, relative error is 2.5770352945525987%\n" + ] + } + ], + "source": [ + "# Step 3 of MLAE\n", + "# Use Brute-force search algorithm to find the maximum value of likelihood function\n", + "rranges = (0, pi/2, pi/200) # Range of grid for Brute-force algorithm\n", + "resbrute = optimize.brute(likelihood_vqae, (rranges,), args=params, full_output=True, finish=optimize.fmin) # Call Brute-force algorithm\n", + "theta_a = resbrute[0][0] # Theta corresponds to the minimum of -f\n", + "amp_VQAE = np.sin(theta_a) ** 2 # Quantum amplitude estimation from VQAE\n", + "error_VQAE = abs(amp_VQAE - quantum_amp) # Absolute estimation error\n", + "rate_VQAE = error_VQAE/quantum_amp # Relative estimation error\n", + "print(\"=================================\")\n", + "print(f\"The maximum value for likelihood function is {-resbrute[1]} when theta = {resbrute[0][0]} rad\")\n", + "print(f\"VQAE result is {amp_VQAE}, absolute error is {error_VQAE}, relative error is {100 * rate_VQAE}%\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As shown above, VQAE algorithm not only achieves amplitude estimation with high accuracy, but also has evidently shallower quantum circuit compared with original MLAE algorithm. The depth of quantum circuit in VQAE is defined by the sequence of MLAE and the variational period. For example, for a circuit with $M = 50$ and variational period of 5. The depth of VQAE is about $\\sim 1/10$ of MLAE. In this way, VQAE can be more promising to be implemented on NISQ hardware compared to MLAE. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The quantum query complexity of VQAE algorithm consists of sampling complexity $N_{samp}$ and variational complexity $N_{var}$.\n", + "$$\n", + "N = N_{var} + N_{samp},\n", + "$$\n", + "$$\n", + "N_{var} = N_{var/1}(2k+2)\\lfloor M/k \\rfloor \\sim O(k\\lfloor M/k \\rfloor),\n", + "$$\n", + "$$\n", + "N_{samp} = hk(k+2)\\lfloor M/k \\rfloor + h(M\\%k)(M\\%k+2),\n", + "$$\n", + "where $M$ is the maximum of linear increment sequence, $k$ is the variational period of VQAE, $h$ is the number of repeated sampling for each state. $N_{var/1}=2n_fn_sn_p$ is the number of circuits needed to be run for each variational update, where $n_p$ is the number of parameters of a parameterized quantum circuit (PQC), $n_s$ is the total number of sweeps through all the parameters of the PQC, and $n_f$ is the number of Bernoulli trials per evaluation of the objective function ($\\sim n_s$). The factor 2 comes from the fact that two evaluations of the objective function are required for each evaluation of the gradient. For detailed explanation, please refer to [1]." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Sampling complexity is 8750\n", + "Variational complexity is 180000000\n", + "Quantum query complexity for VQAE is 180008750\n" + ] + } + ], + "source": [ + "# Calculate the quantum query complexity of VQAE\n", + "from math import floor\n", + "M_vqae = M\n", + "k_cycle = cycle\n", + "n_p = theta_size\n", + "n_s = ITR\n", + "n_f = n_s\n", + "N_var1 = 2 * n_p * n_s * n_f\n", + "N_var = N_var1 * (2 * k_cycle + 2) * floor(M_vqae/k_cycle)\n", + "N_samp = N_k_vqae * k_cycle * (k_cycle + 2) * floor(M_vqae/k_cycle) + N_k_vqae * (M_vqae % k_cycle) * (M_vqae % k_cycle + 2)\n", + "print(f\"Sampling complexity is {N_samp}\")\n", + "print(f\"Variational complexity is {N_var}\")\n", + "print(f\"Quantum query complexity for VQAE is {N_var + N_samp}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We notice the quantum query complexity of VQAE is large, and mainly contributed from the complexity of variational approximation process. There is a trade-off between complexity from the depth of quantum circuit and variatonal process. However, there exists some design of the variational process to decrease the variational complexity. For example, adaptive VQAE mentioned in [1]. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Summary" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The tutorial first reviews the quantum amplitude estimation problem and its difficulty. Then maximum likelihood amplitude estimation(MLAE), which avoids quantum phase estimation, is reviewed. However, the circuit of MLAE can be too deep to be implemented by NISQ hardware. To decrease the depth of circuit of MLAE, variational quantum amplitude estimation (VQAE) is developed based on MLAE. The variational approximation process in VQAE keeps the depth below a constant number. Therefore, VQAE increases the probability of realizing quantum amplitude estimation on NISQ hardware. Also, it's necessary to notice that variational process will introduce variational complexity. Thus, there is a tradeoff between variational process and the depth of quantum circuit.\n", + "\n", + "The tutorial implements single-qubit MLAE and VQAE based on Paddle Quantum, and demonstrates high-accuracy estimation of the preset quantum amplitude. Furthermore, the tutorial compares the relation of estimation error and quantum query complexity between MLAE and Classical Monte-Carlo method, and shows the quantum speedup effect by numerical experiment results." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "_______\n", + "## References" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[1] Plekhanov, Kirill, et al. \"Variational quantum amplitude estimation.\" Quantum 6 (2022): 670. https://quantum-journal.org/papers/q-2022-03-17-670/\n", + "\n", + "[2] Preskill, John. \"Quantum computing in the NISQ era and beyond.\" Quantum 2 (2018): 79. https://quantum-journal.org/papers/q-2018-08-06-79/\n", + "\n", + "[3] Suzuki, Yohichi, et al. \"Amplitude estimation without phase estimation.\" Quantum Information Processing 19.2 (2020): 1-17. https://link.springer.com/article/10.1007/s11128-019-2565-2\n", + "\n", + "[4] Brassard, Gilles, et al. \"Quantum amplitude amplification and estimation.\" Contemporary Mathematics 305 (2002): 53-74. https://arxiv.org/pdf/quant-ph/0005055.pdf" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('py3.7_pq2.2.1')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.13" + }, + "vscode": { + "interpreter": { + "hash": "4e4e2eb86ad73936e915e7c7629a18a8ca06348106cf3e66676b9578cb1a47dd" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tutorials/machine_learning/figures/VQAE-fig-comparison.png b/tutorials/machine_learning/figures/VQAE-fig-comparison.png new file mode 100644 index 0000000000000000000000000000000000000000..736b56545114337063ce2754c02ca36ad558b678 GIT binary patch literal 37302 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%0DOo7D>{#2|-OX1~dDQ_@2HFE%kFCDIaS|iP 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 literal 0 HcmV?d00001 diff --git a/tutorials/machine_learning/figures/VQAE-fig-mlae.png b/tutorials/machine_learning/figures/VQAE-fig-mlae.png new file mode 100644 index 0000000000000000000000000000000000000000..66ce1fd55b03076fa9d6a34a5345cf7b4a4ddc38 GIT binary patch literal 244363 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⪼N$Exni;>|YjNbP1-ggWs)W0#C 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 REeBpf&y+M2QIE}o{|^VqG!Os) literal 0 HcmV?d00001 diff --git a/tutorials/machine_learning/figures/VQAE-fig-pesudo.png b/tutorials/machine_learning/figures/VQAE-fig-pesudo.png new file mode 100644 index 0000000000000000000000000000000000000000..75e146cbd95311ae94523d06181a2e9001747500 GIT binary patch literal 466047 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%0D_&~7dC(C+AHYT9Ag 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 z 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⁡KkQSgB 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 literal 0 HcmV?d00001 diff --git a/tutorials/machine_learning/figures/VQAE-fig-qpe.png b/tutorials/machine_learning/figures/VQAE-fig-qpe.png new file mode 100644 index 0000000000000000000000000000000000000000..7fab22ad468c8faba02c204dc5395922303d90bf GIT binary patch literal 54241 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 literal 0 HcmV?d00001 diff --git a/tutorials/quantum_simulation/GibbsState_CN.ipynb b/tutorials/quantum_simulation/GibbsState_CN.ipynb index 6f8936d..0b59599 100644 --- a/tutorials/quantum_simulation/GibbsState_CN.ipynb +++ b/tutorials/quantum_simulation/GibbsState_CN.ipynb @@ -71,7 +71,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2021-04-30T08:55:59.838299Z", @@ -83,9 +83,9 @@ "import scipy\n", "import paddle\n", "from numpy import trace as np_trace\n", - "import paddle_quantum\n", + "import paddle_quantum as pq\n", "from paddle_quantum.ansatz import Circuit\n", - "from paddle_quantum.state import zero_state, State\n", + "from paddle_quantum.state import zero_state\n", "from paddle_quantum.qinfo import state_fidelity, partial_trace, pauli_str_to_matrix" ] }, @@ -125,10 +125,12 @@ }, "outputs": [], "source": [ - "N = 4 # 量子神经网络的宽度\n", - "N_SYS_B = 3 # 用于生成吉布斯态的子系统B的量子比特数 \n", - "SEED = 16 # 固定随机种子\n", - "beta = 1.5 # 设置逆温度参数 beta" + "N = 4 # 量子神经网络的宽度\n", + "N_SYS_B = 3 # 用于生成吉布斯态的子系统B的量子比特数 \n", + "SEED = 16 # 固定随机种子\n", + "beta = 1.5 # 设置逆温度参数 beta\n", + "pq.set_backend('density_matrix') # 设置密度矩阵后端\n", + "pq.set_dtype('complex128') # 设置计算精度" ] }, { @@ -152,8 +154,8 @@ "rho_G = scipy.linalg.expm(-1 * beta * hamiltonian) / np_trace(scipy.linalg.expm(-1 * beta * hamiltonian))\n", "\n", "# 设置成 Paddle quantum 所支持的数据类型\n", - "hamiltonian = hamiltonian.astype(\"complex64\")\n", - "rho_G = paddle.to_tensor(rho_G, dtype=\"complex64\")" + "hamiltonian = hamiltonian.astype(\"complex128\")\n", + "rho_G = paddle.to_tensor(rho_G, dtype=\"complex128\")" ] }, { @@ -247,7 +249,7 @@ " rho_AB = cir(zero_state(N))\n", " \n", " # 计算偏迹 partial trace 来获得子系统B所处的量子态 rho_B\n", - " rho_B = partial_trace(rho_AB, 2 ** (N - N_SYS_B), 2 ** (N_SYS_B), 1)\n", + " rho_B = partial_trace(rho_AB.data, 2 ** (N - N_SYS_B), 2 ** (N_SYS_B), 1)\n", " \n", " # 计算三个子损失函数\n", " rho_B_squre = rho_B @ rho_B\n", @@ -310,7 +312,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": { "ExecuteTime": { "end_time": "2021-04-30T08:56:19.753228Z", @@ -322,14 +324,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "iter: 10 loss: -3.1084 fid: 0.9241\n", + "iter: 10 loss: -3.1085 fid: 0.9241\n", "iter: 20 loss: -3.3375 fid: 0.9799\n", "iter: 30 loss: -3.3692 fid: 0.9897\n", "iter: 40 loss: -3.3990 fid: 0.9929\n", "iter: 50 loss: -3.4133 fid: 0.9959\n", "\n", "训练后的电路: \n", - "--Ry(6.290)----*--------------x----Ry(0.260)--\n", + "--Ry(6.290)----*--------------x----Ry(0.747)--\n", " | | \n", "--Ry(4.745)----x----*---------|----Ry(6.249)--\n", " | | \n", @@ -342,9 +344,6 @@ ], "source": [ "paddle.seed(SEED)\n", - "\n", - "# 设置计算模式为密度矩阵模式\n", - "paddle_quantum.set_backend(backend='density_matrix')\n", " \n", "# 我们需要将 Numpy array 转换成 Paddle 中支持的 Tensor\n", "H = paddle.to_tensor(hamiltonian)\n", @@ -368,7 +367,7 @@ " opt.clear_grad()\n", "\n", " # 转换成 Numpy array 用以计算量子态的保真度 F(rho_B, rho_G)\n", - " fid = state_fidelity(State(rho_B), State(rho_G))\n", + " fid = state_fidelity(rho_B, rho_G)\n", "\n", " # 打印训练结果\n", " if itr % 10 == 0:\n", @@ -417,7 +416,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3.7.13 ('py3.7_pq2.2.1')", "language": "python", "name": "python3" }, @@ -431,7 +430,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.13" + "version": "3.7.13" }, "toc": { "base_numbering": 1, @@ -445,6 +444,11 @@ "toc_position": {}, "toc_section_display": true, "toc_window_display": false + }, + "vscode": { + "interpreter": { + "hash": "4e4e2eb86ad73936e915e7c7629a18a8ca06348106cf3e66676b9578cb1a47dd" + } } }, "nbformat": 4, diff --git a/tutorials/quantum_simulation/GibbsState_EN.ipynb b/tutorials/quantum_simulation/GibbsState_EN.ipynb index 012a74e..ac432f7 100644 --- a/tutorials/quantum_simulation/GibbsState_EN.ipynb +++ b/tutorials/quantum_simulation/GibbsState_EN.ipynb @@ -68,7 +68,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2021-04-30T08:56:40.078886Z", @@ -80,9 +80,9 @@ "import scipy\n", "import paddle\n", "from numpy import trace as np_trace\n", - "import paddle_quantum\n", + "import paddle_quantum as pq\n", "from paddle_quantum.ansatz import Circuit\n", - "from paddle_quantum.state import zero_state, State\n", + "from paddle_quantum.state import zero_state\n", "from paddle_quantum.qinfo import state_fidelity, partial_trace, pauli_str_to_matrix" ] }, @@ -113,7 +113,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2021-04-30T08:56:40.099967Z", @@ -122,15 +122,17 @@ }, "outputs": [], "source": [ - "N = 4 # The width of the QNN\n", - "N_SYS_B = 3 # The number of qubits of subsystem B used to generate the Gibbs state\n", - "SEED = 16 # Fixed random seed\n", - "beta = 1.5 # Set the inverse temperature parameter beta" + "N = 4 # The width of the QNN\n", + "N_SYS_B = 3 # The number of qubits of subsystem B used to generate the Gibbs state\n", + "SEED = 16 # Fixed random seed\n", + "beta = 1.5 # Set the inverse temperature parameter beta\n", + "pq.set_backend('density_matrix') # Set density matrix backend\n", + "pq.set_dtype('complex128') # Set calculation precision" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2021-04-30T08:56:40.201757Z", @@ -149,8 +151,8 @@ "rho_G = scipy.linalg.expm(-1 * beta * hamiltonian) / np_trace(scipy.linalg.expm(-1 * beta * hamiltonian))\n", "\n", "# Set to the data type supported by Paddle Quantum\n", - "hamiltonian = hamiltonian.astype(\"complex64\")\n", - "rho_G = paddle.to_tensor(rho_G, dtype=\"complex64\")" + "hamiltonian = hamiltonian.astype('complex128')\n", + "rho_G = paddle.to_tensor(rho_G, dtype='complex128')" ] }, { @@ -177,7 +179,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2021-04-30T08:56:40.213503Z", @@ -229,7 +231,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 5, "metadata": { "ExecuteTime": { "end_time": "2021-04-30T08:56:40.238960Z", @@ -244,7 +246,7 @@ " rho_AB = cir(zero_state(N))\n", " \n", " # Calculate partial trace to obtain the quantum state rho_B of subsystem B\n", - " rho_B = partial_trace(rho_AB, 2 ** (N - N_SYS_B), 2 ** (N_SYS_B), 1)\n", + " rho_B = partial_trace(rho_AB.data, 2 ** (N - N_SYS_B), 2 ** (N_SYS_B), 1)\n", " \n", " # Calculate the three parts of the loss function\n", " rho_B_squre = rho_B @ rho_B\n", @@ -274,7 +276,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 6, "metadata": { "ExecuteTime": { "end_time": "2021-04-30T08:56:40.966455Z", @@ -307,7 +309,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 8, "metadata": { "ExecuteTime": { "end_time": "2021-04-30T08:56:50.509486Z", @@ -319,14 +321,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "iter: 10 loss: -3.1084 fid: 0.9241\n", + "iter: 10 loss: -3.1085 fid: 0.9241\n", "iter: 20 loss: -3.3375 fid: 0.9799\n", "iter: 30 loss: -3.3692 fid: 0.9897\n", "iter: 40 loss: -3.3990 fid: 0.9929\n", "iter: 50 loss: -3.4133 fid: 0.9959\n", "\n", "The trained circuit: \n", - "--Ry(6.290)----*--------------x----Ry(0.260)--\n", + "--Ry(6.290)----*--------------x----Ry(0.747)--\n", " | | \n", "--Ry(4.745)----x----*---------|----Ry(6.249)--\n", " | | \n", @@ -340,9 +342,6 @@ "source": [ "paddle.seed(SEED)\n", " \n", - "# Set calculation mode as density matrix \n", - "paddle_quantum.set_backend(backend='density_matrix') \n", - " \n", "# Convert Numpy array to Tensor supported in PaddlePaddle\n", "H = paddle.to_tensor(hamiltonian)\n", "\n", @@ -365,7 +364,7 @@ " opt.clear_grad()\n", "\n", " # Convert to Numpy array to calculate the fidelity of the quantum state F(rho_B, rho_G)\n", - " fid = state_fidelity(State(rho_B), State(rho_G))\n", + " fid = state_fidelity(rho_B, rho_G)\n", " \n", " # Print training results\n", " if itr % 10 == 0:\n", @@ -399,7 +398,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3.7.13 ('py3.7_pq2.2.1')", "language": "python", "name": "python3" }, @@ -413,7 +412,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.13" + "version": "3.7.13" }, "toc": { "base_numbering": 1, @@ -427,6 +426,11 @@ "toc_position": {}, "toc_section_display": true, "toc_window_display": false + }, + "vscode": { + "interpreter": { + "hash": "4e4e2eb86ad73936e915e7c7629a18a8ca06348106cf3e66676b9578cb1a47dd" + } } }, "nbformat": 4, diff --git a/tutorials/quantum_simulation/HamiltonianSimulation_CN.ipynb b/tutorials/quantum_simulation/HamiltonianSimulation_CN.ipynb index eabc3b7..dba6db3 100644 --- a/tutorials/quantum_simulation/HamiltonianSimulation_CN.ipynb +++ b/tutorials/quantum_simulation/HamiltonianSimulation_CN.ipynb @@ -554,7 +554,7 @@ " t = 1\n", " cir = Circuit()\n", " construct_trotter_circuit(cir, h_2, tau=t/n_steps, steps=n_steps)\n", - " return gate_fidelity(cir.unitary_matrix(), linalg.expm(-1 * 1j * h_2.construct_h_matrix())).item()\n", + " return gate_fidelity(cir.unitary_matrix(), linalg.expm(-1 * 1j * h_2.construct_h_matrix()))\n", "plt.axhline(1, ls='--', color='black')\n", "plt.semilogy(np.arange(1, 11), [get_fid(r) for r in np.arange(1, 11)], 'o-')\n", "plt.xlabel('number of steps', fontsize=12)\n", diff --git a/tutorials/quantum_simulation/HamiltonianSimulation_EN.ipynb b/tutorials/quantum_simulation/HamiltonianSimulation_EN.ipynb index d349112..85efea0 100644 --- a/tutorials/quantum_simulation/HamiltonianSimulation_EN.ipynb +++ b/tutorials/quantum_simulation/HamiltonianSimulation_EN.ipynb @@ -554,7 +554,7 @@ " t = 1\n", " cir = Circuit()\n", " construct_trotter_circuit(cir, h_2, tau=t/n_steps, steps=n_steps)\n", - " return gate_fidelity(cir.unitary_matrix(), linalg.expm(-1 * 1j * h_2.construct_h_matrix())).item()\n", + " return gate_fidelity(cir.unitary_matrix(), linalg.expm(-1 * 1j * h_2.construct_h_matrix()))\n", "plt.axhline(1, ls='--', color='black')\n", "plt.semilogy(np.arange(1, 11), [get_fid(r) for r in np.arange(1, 11)], 'o-')\n", "plt.xlabel('number of steps', fontsize=12)\n", diff --git a/tutorials/quantum_simulation/QDRIFT_CN.ipynb b/tutorials/quantum_simulation/QDRIFT_CN.ipynb new file mode 100644 index 0000000..e161332 --- /dev/null +++ b/tutorials/quantum_simulation/QDRIFT_CN.ipynb @@ -0,0 +1,557 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 利用 qDRIFT 模拟时间演化\n", + " Copyright (c) 2022 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 概述\n", + "量子力学中系统的能量由哈密顿量算符 $H$ 描述,它决定了系统演化的性质,模拟哈密顿量的时间演化,在建模复杂的化学和物理系统方面具有巨大的实用价值。然而,由于系统的自由度随系统(如量子比特数)增大呈指数级增加,导致一般情况下无法利用经典计算机有效模拟量子系统。当前使用量子计算机模拟哈密顿量的主要技术是利用乘积式方法(product formula)模拟时间演化,本教程将介绍关于 product formula 的一些基础理论和方法,和基于 product formula 改进的 quantum stochastic drift protocol (qDRIFT) —— 一种随机的 product formula 方法,并在文末进行了代码演示。\n", + "\n", + "## 利用 Product Formula 模拟时间演化\n", + "\n", + "根据量子力学的基本公理,在确定了一个系统的哈密顿量 $H$ 之后,该系统随时间演化的过程可以由如下方程描述\n", + "\n", + "$$\n", + "i \\hbar \\frac{d}{d t} | \\psi \\rangle = H | \\psi \\rangle,\n", + "\\tag{1}\n", + "$$\n", + "\n", + "其中 $\\hbar$ 为约化普朗克常数。因此,对于一个不含时的哈密顿量,系统的时间演化方程可以写为\n", + "\n", + "$$\n", + "|\\psi(t) \\rangle = U(t) | \\psi (0) \\rangle, ~ U(t) = e^{- i H t}.\n", + "\\tag{2}\n", + "$$\n", + "\n", + "这里我们取自然单位 $\\hbar=1$,$U(t)$ 为时间演化算符。利用量子电路来模拟时间演化过程的核心思想是利用量子电路构建出的酉变换模拟和近似该时间演化算符。Seth Lloyd 在其 1996 年的文章中指出,可以将一整段的演化时间 $t$ 拆分为 $r$ 份较短的“时间片段”来减小模拟时间演化的误差 [1]。考虑一个一般的哈密顿量形式 $H = \\sum_{k=1}^{L} H_k$,其中 $H_k$ 是作用在部分系统上的子哈密顿量。我们考虑每个子哈密顿量 $H_k$ 的演化算符为$e^{-i H_k t}$,我们依次模拟每个子哈密顿量可以得到 $\\prod_{k=1}^{L} e^{-i H_k t}$。通过泰勒展开,可以发现\n", + "\n", + "$$\n", + "e^{-iHt} = \\prod_{k=1}^{L} e^{-i H_k t} + O(t^2).\n", + "\\tag{3}\n", + "$$\n", + "\n", + "那么,我们令 $\\tau = t/r$,并考虑演化算符 $\\left(e^{-iH \\tau}\\right)^r$,就可以推导出\n", + "\n", + "$$\n", + "e^{-iHt} = \\left(e^{-iH \\tau}\\right)^r = \\left(\\prod_{k=1}^{L} e^{-i H_k \\tau} + O(\\tau^2) \\right)^r = \\left(\\prod_{k=1}^{L} e^{-i H_k \\tau} \\right)^r + O\\left(\\frac{t^2}{r}\\right).\n", + "\\tag{4}\n", + "$$\n", + "\n", + "上式告诉我们,只要将一整段演化时间拆为足够多的“片段”,就可以达到任意高的模拟精度,这就是 product formula 的基本思想。不过,(4) 中给出的只是一个粗略的估计。如果我们想要估计达到某一模拟精度所需要的量子电路深度,就需要推导其更严格的误差上界。具体地,我们令 $U_{circuit}$ 代表我们构造的电路,$\\Vert \\cdot \\Vert$ 为 Schatten-$\\infty$ 范数,即[谱范数](https://en.wikipedia.org/wiki/Schatten_norm)。那么其模拟误差 $\\epsilon$ 可以写为\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + "\\epsilon\\left(e^{-iHt}, U_{circuit}\\right) & = \\Vert e^{-iHt} - U_{circuit}\\Vert .\n", + "\\end{aligned}\n", + "\\tag{5}\n", + "$$\n", + "下面,我们展示一个比较简略的误差上界计算过程,我们不加证明地列出 (6)、(7) 两个结论,会在证明 (8) 时用到,感兴趣的读者可以参考 [2] 中的 F.1 节获取证明细节。\n", + "$$\n", + "\\left\\Vert \\mathcal{R}_k \\left( \\prod_{k=1}^{L} e^{-i H_k \\tau} \\right) \\right\\Vert\n", + "\\leq\n", + "\\mathcal{R}_k \\left( e^{\\vert \\tau \\vert \\sum_{k=1}^{L} \\Vert H_k \\Vert } \\right),\n", + "\\tag{6}\n", + "$$\n", + "\n", + "$$\n", + "\\vert \\mathcal{R}_k(e^\\alpha) \\vert \\leq \\frac{\\vert \\alpha \\vert^{k+1}}{(k+1)!} e^{ \\vert \\alpha \\vert }, ~\n", + "\\forall \\alpha \\in \\mathbb{C},\n", + "\\tag{7}\n", + "$$\n", + "\n", + "其中 $\\mathcal{R}_k(f)$为函数 $f$ 泰勒展开至 $k$ 阶之后的余项,例如 $\\mathcal{R}_1 (e^x)=\\mathcal{R}_1 (\\sum_{j=0}^\\infty \\frac{x^n}{n!})=\\sum_{j=2}^\\infty \\frac{x^n}{n!}$。\n", + "令 $\\Lambda = \\max_k \\Vert H_k \\Vert$,考虑完整的演化时间 $t = r \\cdot \\tau$,那么模拟长度为 $t$ 的时间演化算符时的误差为:\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + "\\left \\Vert \\left ( e^{-i\\tau \\sum_{k=1}^L H_k }\\right)^r - \\left (\\prod_{k=1}^{L} e^{-i H_k \\tau} \\right)^r \\right \\Vert \\leq &\n", + "r \\left \\Vert e^{-i\\tau \\sum_{k=1}^L H_k } - \\prod_{k=1}^{L} e^{-i H_k \\tau } \\right \\Vert \\\\\n", + "=& r \\left \\Vert \\mathcal{R}_1 \\left( e^{-i\\tau \\sum_{k=1}^L H_k} \\right)- \\mathcal{R}_1 \\left( \\prod_{k=1}^{L} e^{-i H_k \\tau } \\right) \\right \\Vert \\\\\n", + "\\leq& r \\left \\Vert \\mathcal{R}_1 \\left( e^{-i\\tau \\sum_{k=1}^L H_k} \\right) \\right \\Vert+ r\\left \\Vert \\mathcal{R}_1 \\left( \\prod_{k=1}^{L} e^{-i H_k \\tau } \\right) \\right \\Vert \\\\\n", + "\\leq& 2r \\left \\Vert \\mathcal{R}_1 \\left( e^{-i |\\tau | \\sum_{k=1}^L \\Vert H_k \\Vert} \\right) \\right \\Vert \\\\\n", + "\\leq& 2r \\left \\Vert \\mathcal{R}_1 \\left( e^{-i |\\tau | L \\Lambda} \\right) \\right \\Vert \\\\\n", + "\\leq& r ( \\tau L \\Lambda )^2 e^{\\vert \\tau \\vert L \\Lambda } \\\\\n", + "=&\\frac{( t L \\Lambda )^2}{r} e^{\\frac{\\vert t \\vert L \\Lambda}{r} }.\n", + "\\end{aligned}\n", + "\\tag{8}\n", + "$$\n", + "\n", + "其中这里用到了量子电路中误差线性累积的结论,即 $\\Vert U^r - V^r \\Vert \\leq r\\Vert U - V \\Vert$,不熟悉这一结论的读者可以参考 [3] 中的 4.5.3 节;也用到了 (7) 式中 $k=1$ 时的结论。至此,我们就计算出了 product formula 对于一段完整的演化时间 $t$ 的模拟误差上界,即 (4) 式中的二阶项 $O(t^2/r)$。 \n", + "\n", + "\n", + "在得到了模拟误差上界的基础上,便可以进一步计算达到一定精度 $\\epsilon$ 时所需要的电路深度的下界。从 (8) 中我们不难发现,式子里含有 $L$ 项,这就意味着,随着哈密顿量项数的增加,若需控制误差上界,则时间片段的划分必须越来越细,这就使得电路深度增加。本文所要介绍的 qDRIFT 在一定程度上解决了该问题。qDRIFT 着眼于哈密顿量本身的系数,将其建模为一个概率分布,每次从该概率分布中采样酉门并重复一定的次数,从而构成量子电路,最终在给定的精度下,其量子电路的深度将不显含哈密顿量项数 $L$。下面我们将详细介绍它。\n", + "\n", + "\n", + "## 利用 qDRIFT 模拟时间演化\n", + "首先,我们给出目标哈密顿量的形式\n", + "$$\n", + "H=\\sum_{j=1}^L h_j H_j,\n", + "\\tag{9}\n", + "$$\n", + "它含有 $L$ 项子哈密顿量 $H_j$,值得注意的是,这里的 $H_j$ 是已经被归一化了的,也就是 $\\Vert H_j \\Vert = 1$,其中 $\\Vert\\cdot\\Vert$ 为 Schatten-$\\infty$ 范数 ,$h_j$ 是每个子哈密顿量的系数,它是一个正实数。通过该系数我们便可以构造一个离散的概率分布,以单个系数在整个哈密顿量系数总和的占比作为每个酉门被采样的概率,也就是 $p_j =h_j / \\lambda$,其中 $\\lambda =\\sum _j h_j$ 是系数和,如此采样重复 $N$ 次(为了与 product formula 对照,我们取 $ N=Lr$),我们就得到一个由 $j$ 排列的有序列表,并可以根据该排列构造酉门 $U_j = e^{i\\tau H_j}$ 。假设 $L=3$ ,$r=2$,我们可以根据上述概率分布采样一个有序列表形如\n", + "$$\n", + "[ 3, 1, 2 ,3 ,3 ,1 ],\n", + "$$\n", + "那么就可以据此构造量子电路\n", + "$$\n", + "U_{circuit} = e^{i\\tau H_1}e^{i\\tau H_3}e^{i\\tau H_3}e^{i\\tau H_2}e^{i\\tau H_1}e^{i\\tau H_3},\n", + "$$\n", + "$\\tau=t\\lambda /N$,这就是 qDRIFT 模拟哈密顿量的一个实现。\n", + "\n", + "qDRIFT 的实现流程非常简单,而它的优势在于,在给定目标精度 $\\epsilon$ 时其酉门数的复杂度为 $O((\\lambda t)^2 /\\epsilon) $,可以看到这是一个不含 $L$ 的结果,也就是说,其酉门数量与哈密顿量的项数不显式相关,这在哈密顿量项数很大时可以有效地缩减模拟电路的长度。接下来我们将给出证明。\n", + "\n", + "我们将根据概率分布进行采样的过程建模为一个量子信道,我们用花体字母 $\\mathcal{E}$ 和 $\\mathcal{U}$ 分别来表示通过 qDRIFT 建立的信道和所要模拟的信道,并且用 $\\mathcal{E}_N$ 和 $\\mathcal{U}_N$ 代表其各自信道对量子态 $\\rho$ 的 $N$ 次作用中的一次作用,即\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + "&\\mathcal{U}_N (\\rho) = e^{\\frac{it}{N}H} \\rho e^{\\frac{-it}{N}H}= e^{\\frac{t}{N}\\mathcal{L}} (\\rho),\n", + "\\\\\n", + "&\\mathcal{E}_N (\\rho)=\\sum_{j}p_j e^{i\\tau H_j} \\rho e^{-i\\tau H_j}=\\sum_{j} p_j e^{\\tau \\mathcal{L}_j}(\\rho).\n", + "\\end{aligned}\n", + "\\tag{10}\n", + "$$\n", + "\n", + "这里我们引入 Liouvillian 表示 ,即对量子信道 $\\mathcal{P}(\\rho)=e^{iHt}\\rho e^{-iHt}$ 有\n", + "$$\n", + "\\mathcal{P}(\\rho)=e^{iHt}\\rho e^{-iHt}=e^{t\\mathcal{L}}(\\rho)=\\sum_{k=0}^\\infty \\frac{t^k \\mathcal{L}^k (\\rho)}{k!},\n", + "\\tag{11}\n", + "$$\n", + "\n", + "\n", + "其中 $\\mathcal{L}(\\rho)=i(H\\rho - \\rho H)$ ,同理有 $\\mathcal{L}_j(\\rho)=i(H_j\\rho - \\rho H_j)$ 。需要注意的是,$\\mathcal{L}$ 的迭代规则遵循 $\\mathcal{L}^{n+1}(\\rho)=i(H\\mathcal{L}^n(\\rho)-\\mathcal{L}^n(\\rho)H)$。具体来说,$\\mathcal{U}_N = \\sum_{n=0}^\\infty \\frac{t^n\\mathcal{L}^n}{n!N^n}$,$\\mathcal{E}_N =\\sum_{j}p_j \\sum_{n=0}^\\infty \\frac{\\lambda^n t^n \\mathcal{L}_j^n}{n!N^n}$。接下来我们该如何度量两个信道的距离呢?这里引入[菱形范数](https://en.wikipedia.org/wiki/Diamond_norm) (diamond norm) 的定义式\n", + "$$\n", + "\\begin{aligned}\n", + "\\Vert \\mathcal{P} \\Vert_\\Diamond :=\\sup_{\\rho ; \\Vert \\rho \\Vert _1 =1}\\Vert (\\mathcal{P} \\otimes \\mathbb{I})(\\rho )\\Vert _1 .\n", + "\\end{aligned}\n", + "\\tag{12}\n", + "$$\n", + "其中 $\\mathbb{I}$ 为与 $\\mathcal{P}$ 空间相同大小的单位信道,$\\Vert \\cdot \\Vert_1$ 为 Schatten-$1$ 范数,即[迹范数](https://en.wikipedia.org/wiki/Schatten_norm)。我们使用菱形范数定义两个量子信道的距离\n", + "$$\n", + "\\begin{aligned}\n", + "d_\\Diamond (\\mathcal{E},\\mathcal{U}) &=\\frac{1}{2} \\Vert \\mathcal{E} -\\mathcal{U} \\Vert_\\Diamond\n", + "\\\\\n", + "&=\\sup_{\\rho ; \\Vert \\rho \\Vert _1 =1} \\frac{1}{2} \\Vert ((\\mathcal{E}-\\mathcal{U}) \\otimes \\mathbb{I})(\\rho )\\Vert _1 .\n", + "\\end{aligned}\n", + "\\tag{13}\n", + "$$\n", + "菱形范数代表了在所有量子态中能够分辨两个信道的最大可能性,它的值越大,两个信道被区分的可能性就越大,也就代表了两个信道距离远,模拟效果差;反之它的值小,就代表模拟效果好。接着,我们可以去计算单次作用的信道的距离上界\n", + "$$\n", + "\\begin{aligned}\n", + " \\Vert \\mathcal{U}_N-\\mathcal{E}_N \\Vert_\\Diamond &= \\left\\Vert \\sum_{n=2}^\\infty \\frac{t^n\\mathcal{L}^n}{n!N^n}-\\sum_{j}\\frac{h_j}{\\lambda} \\sum_{n=2}^\\infty \\frac{\\lambda^n t^n \\mathcal{L}_j^n}{n!N^n} \\right\\Vert_\\Diamond\\\\\n", + " &\\leq \\sum_{n=2}^\\infty \\frac{t^n\\Vert \\mathcal{L}^n \\Vert_\\Diamond }{n!N^n} + \\sum_{j}\\frac{h_j}{\\lambda} \\sum_{n=2}^\\infty \\frac{\\lambda^n t^n \\Vert\\mathcal{L}_j^n \\Vert_\\Diamond }{n!N^n}\\\\\n", + " &\\leq \\sum_{n=2}^\\infty \\frac{1}{n!}\\left( \\frac{2\\lambda t}{N}\\right)^n+\\sum_{j}\\frac{h_j}{\\lambda} \\sum_{n=2}^\\infty \\frac{1}{n!}\\left( \\frac{2\\lambda t}{N}\\right)^n\\\\\n", + " &=2\\sum_{n=2}^\\infty \\frac{1}{n!}\\left( \\frac{2\\lambda t}{N}\\right)^n .\n", + "\\end{aligned}\n", + "\\tag{14}\n", + "$$\n", + "其中这里用到了结论 $\\Vert \\mathcal{L} \\Vert_\\Diamond \\leq 2\\Vert H\\Vert \\leq 2\\lambda$ ,同理有 $\\Vert \\mathcal{L}_j \\Vert_\\Diamond \\leq 2\\Vert H_j\\Vert \\leq 2$ [4]。接着,我们可以利用上文中提到的 (7) 的结论,令 $k=1$,$\\alpha=2\\lambda t /N$ 便可得到\n", + "\n", + "$$\n", + "d_\\Diamond (\\mathcal{U}_N,\\mathcal{E}_N) \\leq \\frac{2\\lambda^2 t^2}{N^2} e^{2\\lambda t/N} ,\n", + "\\tag{15}\n", + "$$\n", + "然后再次利用 $\\Vert U^r - V^r \\Vert \\leq r\\Vert U - V \\Vert$ 这一结论(需要注意,式子中的 $U$ 与 $V$ 本是线性算子,但对于量子信道 $\\mathcal{U}$ 和 $\\mathcal{E}$ 依然适用,感兴趣的读者可以参考 [6] 中的第 3.3.2 节获取证明细节),且通常情况下 $2\\lambda t \\ll N$,便可推出\n", + "$$\n", + "\\begin{aligned}\n", + "d_\\Diamond (\\mathcal{U},\\mathcal{E}) &\\leq N d_\\Diamond (\\mathcal{U}_N, \\mathcal{E}_N)\\\\\n", + " &=\\frac{2\\lambda^2 t^2}{N} e^{2\\lambda t/N} \\approx \\frac{2\\lambda^2 t^2}{N}.\n", + "\\end{aligned}\n", + "\\tag{16}\n", + "$$\n", + "因此 $ N \\sim O((\\lambda t)^2 /\\epsilon)$。 由上式可以看出,在满足 $\\lambda \\ll \\Lambda L$ 的条件下(回忆一下,$\\Lambda = \\max_k \\Vert H_k \\Vert$,qDRIFT 将哈密顿量写为 $H=\\sum_{j=1}^L h_j H_j$,那么对应的 $\\Lambda = \\max_k h_k $),其距离将不与 $L$ 显式相关,这也就可以在 $L$ 较大即情况较为复杂时,不会带来量子电路深度的显著增加,可以有效控制酉门的数量。很多物理系统的哈密顿量都满足 $\\lambda \\ll \\Lambda L$,如乙烷、二氧化碳的电子结构,但并非所有情况都满足,若 $\\lambda = \\Lambda L$ 或 $\\lambda = \\Lambda \\sqrt{L}$ 时,它们的上界分别为 $O(L^2(\\Lambda t)^2 /\\epsilon)$ 和 $O(L(\\Lambda t)^2 /\\epsilon)$ ,可以看到,它们仍然随着哈密顿量项数增大而增大。感兴趣的读者可以参考 [4] 获取更多细节。\n", + "\n", + "\n", + "## 代码实现\n", + "我们将结合实际代码实现 qDRIFT。我们将首先演示其采样结果的性能,再计算其信道的模拟误差。首先我们需要导入需要的包。" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "import warnings\n", + "\n", + "import math\n", + "import numpy as np \n", + "import scipy \n", + "import paddle_quantum as pq \n", + "import paddle\n", + "\n", + "\n", + "warnings.filterwarnings(\"ignore\") # 隐藏 warnings\n", + "np.set_printoptions(suppress=True, linewidth=np.nan) # 启用完整显示,便于在终端 print 观察矩阵时不引入换行符\n", + "pq.set_backend('density_matrix') # 使用密度矩阵表示" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "我们假设系统由 2 个 qubits 组成,我们可以利用量桨的 `hamiltonian` 模块构造一个哈密顿量项数为 $L=4$ 的哈密顿量,为了演示 qDRIFT 的效果,我们选择一组满足 $\\lambda \\ll \\Lambda L$ 的参数,这便是我们的目标哈密顿量,具体如下\n", + "$$\n", + "\\begin{aligned}\n", + "H&=I \\otimes X + 0.05 * X \\otimes Z + 0.05 * I \\otimes Y + 0.05 * X \\otimes X .\n", + "\\end{aligned}\n", + "$$" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "目标哈密顿量为: \n", + " [[ 0. +0.j 1. -0.05j 0.05+0.j 0.05+0.j ]\n", + " [ 1. +0.05j 0. +0.j 0.05+0.j -0.05+0.j ]\n", + " [ 0.05+0.j 0.05+0.j 0. +0.j 1. -0.05j]\n", + " [ 0.05+0.j -0.05+0.j 1. +0.05j 0. +0.j ]]\n" + ] + } + ], + "source": [ + "qubits = 2 # 设置量子比特数\n", + "H_j = [(1.0, 'I0,X1'), # 构造哈密顿量的泡利串\n", + " (0.05, 'X0,Z1'),\n", + " (0.05, 'I0,Y1'),\n", + " (0.05, 'X0,X1'), ]\n", + "\n", + "H = pq.hamiltonian.Hamiltonian(H_j) \n", + "print(f'目标哈密顿量为: \\n {H.construct_h_matrix(qubit_num=qubits)}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "接下来,我们根据 $\\lambda = \\sum_j h_j$,$ p_j=h_j/\\lambda $ 计算概率。在本次实验中,假设我们的目标精度 $\\epsilon=0.1$,模拟时间 $t=1$,也就是说,我们需要采样 $N=\\lceil \\frac{2\\lambda^2 t^2}{\\epsilon}\\rceil = 27$ 次。" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "达到 0.1 的精度需要 27 个酉门\n" + ] + } + ], + "source": [ + "h_j = np.array(H.coefficients) # 获取系数\n", + "lamda = h_j.sum()\n", + "p_j = h_j/lamda # 计算离散概率分布\n", + "accuracy = 0.1\n", + "t = 1\n", + "gate_counts = math.ceil(2 * lamda**2 * t**2 / accuracy)\n", + "\n", + "print(f'达到 {accuracy} 的精度需要 {gate_counts} 个酉门')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "接着,我们将根据概率分布 $p_j$ 独立采样 27 次,并根据该采样结果构造酉电路。" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "采样结果为:\n", + " [1 1 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 4 1]\n", + "qDRIFT 的模拟电路矩阵为: \n", + " [[ 0.51998969-0.02531459j 0.03408183+0.85099285j -0.03524884+0.02376227j -0.0353899 +0.02366261j]\n", + " [-0.03408183+0.85099285j 0.51998969+0.02531459j 0.0353899 +0.02366261j -0.03524884-0.02376227j]\n", + " [-0.03524884+0.02376227j -0.0353899 +0.02366261j 0.51998969-0.02531459j 0.03408183+0.85099285j]\n", + " [ 0.0353899 +0.02366261j -0.03524884-0.02376227j -0.03408183+0.85099285j 0.51998969+0.02531459j]] \n", + "原始电路矩阵为: \n", + " [[ 0.53752508-0.00075235j 0.04202098+0.83966719j -0.04201839+0.04202098j -0.00075235+0.02697398j]\n", + " [-0.04202098+0.83966719j 0.53752508+0.00075235j 0.00075235+0.02697398j -0.04201839-0.04202098j]\n", + " [-0.04201839+0.04202098j -0.00075235+0.02697398j 0.53752508-0.00075235j 0.04202098+0.83966719j]\n", + " [ 0.00075235+0.02697398j -0.04201839-0.04202098j -0.04202098+0.83966719j 0.53752508+0.00075235j]]\n" + ] + } + ], + "source": [ + "np.random.seed(666) # 固定随机数初始位置,便于演示说明\n", + "sample_list = np.random.choice(a=range(1, 5), size=gate_counts, replace=True, p=p_j)\n", + "print(f'采样结果为:\\n {sample_list}')\n", + "\n", + "# 根据采样结果计算采样出来的酉电路\n", + "simulation = np.identity(2 ** qubits) # 生成单位矩阵\n", + "tau = 1j*lamda*t/gate_counts\n", + "for i in sample_list:\n", + " pauli_str_j = (1.0, H_j[i-1][1]) # 获取H_j,注意,应抛弃其原有系数\n", + " H_i = pq.hamiltonian.Hamiltonian([pauli_str_j]).construct_h_matrix(qubit_num=qubits)\n", + " simulation = np.matmul(scipy.linalg.expm(tau*H_i), simulation) \n", + "origin = scipy.linalg.expm(1j*t*H.construct_h_matrix(qubit_num=qubits)) # 计算目标哈密顿量的原始电路\n", + "print(f'qDRIFT 的模拟电路矩阵为: \\n {simulation} \\n原始电路矩阵为: \\n {origin}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "然后我们便可计算出从 qDRIFT 采样出来的酉电路和原始电路之间的模拟误差 $\\Vert e^{iHt}-U_{circuit}\\Vert$,注意区分,这里的范数为谱范数。 " + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "模拟误差为: 0.0309\n" + ] + } + ], + "source": [ + "distance = 0.5 * np.linalg.norm(origin-simulation, ord=2)\n", + "print(f'模拟误差为: {distance:.4f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "当然我们可以带入一个具体的量子态试验一下,不失一般性,我们假设初始量子态为零态,即 $\\rho(0) = | 0 \\rangle \\langle 0 | $,本教程的实验我们均使用密度矩阵描述量子态。我们可以让量子态分别通过原始方法和 qDRIFT 模拟方法演化,到 $t$ 时刻量子态分别为 $\\rho(t)_{origin}$ 和 $\\rho(t)_{qDRIFT}$,最后可以比较这两个量子态的保真度来衡量模拟电路的效果。" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "初始量子态为 \n", + " [[1.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", + " [0.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", + " [0.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", + " [0.+0.j 0.+0.j 0.+0.j 0.+0.j]]\n", + "两个量子态之间的保真度为0.9989\n" + ] + } + ], + "source": [ + "rho_0 = pq.state.zero_state(qubits).numpy() # 构造零态密度矩阵\n", + "print(f'初始量子态为 \\n {rho_0}')\n", + "\n", + "rho_t_origin = pq.state.to_state(origin @ rho_0 @ origin.T.conjugate()) # 经过原始电路演化\n", + "rho_t_qdrift = pq.state.to_state(simulation @ rho_0 @ simulation.T.conjugate()) # 经过模拟电路演化\n", + "fidelity = pq.qinfo.state_fidelity(rho_t_origin, rho_t_qdrift)\n", + "print(f'两个量子态之间的保真度为{float(fidelity):.4f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "可以发现,上面的测试均符合我们的精度要求。但区别于根据 qDRIFT 方法采样得到的某个具体的酉电路,我们将 qDRIFT 的采样方法看作是一个量子信道,也即对量子态 $\\rho$ 的一个映射。上面的实验只是这个信道的一次具体表达,我们接下来将分析这个信道的性能。我们可以定义一个函数,用于描绘 qDRIFT 信道。" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "# 定义 qDRIFT 信道\n", + "def qdrift_channel(iter_num, sample_num, hamiltonian_list, coefficient_list, simulation_time, qubits, input_state):\n", + " '''\n", + " 输入 :\n", + " iter_num : 当前迭代次数,作为递归的标记\n", + " sample_num : 采样次数,即 N\n", + " hamiltonian_list : 目标哈密顿量的泡利串形式的列表,即 H_j\n", + " coefficient_list : 子哈密顿量的系数列表,即 h_j\n", + " simulation_time : 模拟时间,即 t\n", + " qubits : 系统的量子比特数\n", + " input_state : 输入的量子态,应为密度算子\n", + " \n", + " 输出 :\n", + " 经过该 qDRIFT 信道的量子态(密度算子表示)\n", + " '''\n", + " lamda = coefficient_list.sum() \n", + " tau = lamda*simulation_time/sample_num\n", + " output = 0\n", + "\n", + " if iter_num != 1: # 在迭代标志不为 1 的时候启用递归\n", + " input_state = qdrift_channel(iter_num-1, sample_num, hamiltonian_list,\n", + " coefficient_list, simulation_time, qubits, input_state)\n", + "\n", + " # 计算 e^{iH\\tau} \\rho e^{-iH\\tau} \n", + " for sub_H, sub_h in zip(hamiltonian_list, coefficient_list):\n", + " sub_H = pq.hamiltonian.Hamiltonian([sub_H]).construct_h_matrix(qubit_num=qubits)\n", + " unitary = scipy.linalg.expm(1j*tau*sub_H) # 计算 e^{iH\\tau}\n", + " output += sub_h/lamda*unitary @ input_state @ unitary.conjugate().T\n", + " return output" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "接着我们便可以通过菱形范数计算两个信道的距离,不过菱形范数的求解可以转换为半正定规划问题,即\n", + "\n", + "$$\n", + "d_\\Diamond(\\mathcal{U}- \\mathcal{E})=\\sup_{\\Omega \\geq 0 \\atop \\rho \\geq 0}\\{\\text{Tr}[\\Omega (\\Gamma_\\mathcal{U}-\\Gamma_\\mathcal{E})]: \\Omega \\leq \\rho \\otimes \\mathbb{I},\\text{Tr} (\\rho)=1\\},\n", + "\\tag{17}\n", + "$$\n", + "其中 $\\Gamma_\\mathcal{U}$ 与 $\\Gamma_\\mathcal{E}$ 为原始信道和模拟信道的 Choi 表示。菱形范数的半正定规划和 Choi 表示有多种形式,感兴趣的读者可以阅读 [6-8] 获取更多细节。我们这里使用的 Choi 表示具体为\n", + "$$\n", + "\\Gamma_\\mathcal{P}=\\sum_{i,j=0}^{d-1} |i\\rangle \\langle j| \\otimes \\mathcal{P}(|i\\rangle \\langle j|),\n", + "\\tag{18}\n", + "$$\n", + "其中 $\\mathcal{P}$ 为量子信道,$d$ 为该量子信道输入量子态的维度。这里我们首先计算两个信道的 Choi 表示。\n" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "# 计算原始信道和 qDRIFT 信道的 Choi 表示,在该表示下可以进而计算菱形范数\n", + "choi_qdrift = 0\n", + "choi_origin = 0\n", + "channel = scipy.linalg.expm(1j*t*H.construct_h_matrix(qubit_num=qubits))\n", + "for i in range(2 ** qubits):\n", + " for k in range(2 ** qubits):\n", + " choi_temp = np.zeros((2 ** qubits, 2 ** qubits))\n", + " choi_temp[i][k] = 1 # 生成 |i\\rangle \\langle k|\n", + "\n", + " # 分两步计算信道 E 的 Choi 表示\n", + " # 先计算 \\mathcal{E}(|i\\rangle \\langle k|)\n", + " choi_temp_qdrift = qdrift_channel(gate_counts, gate_counts, H_j, h_j, t, qubits, choi_temp) \n", + " # 再计算 |i\\rangle \\langle k| \\otimes \\mathcal{E}(|i\\rangle \\langle k|)\n", + " choi_qdrift += np.kron(choi_temp, choi_temp_qdrift)\n", + "\n", + " # 分两步计算信道 U 的 Choi 表示\n", + " # 先计算 \\mathcal{U}(|i\\rangle \\langle k|)\n", + " choi_temp_origin = channel @ choi_temp @ channel.T.conjugate()\n", + " # 再计算 |i\\rangle \\langle k| \\otimes \\mathcal{U}(|i\\rangle \\langle k|)\n", + " choi_origin += np.kron(choi_temp, choi_temp_origin)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "接着我们可以按照 (17) 式计算菱形范数,并求取两个信道的菱形距离。" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "两个信道之间的距离为: 0.0764\n" + ] + } + ], + "source": [ + "print(f'两个信道之间的距离为: {0.5*pq.qinfo.diamond_norm(paddle.to_tensor(choi_origin-choi_qdrift)):.4f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "可以看到,计算结果是符合预期的。值得注意的是,该值代表了该信道采样为具体模拟电路的最差表现的期望值,它并不能保证每个采样出来的电路都能够达到该精度。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 小结\n", + "\n", + "量子模拟本身是一个比较宽泛的话题,其应用也十分广泛。本教程介绍了 product formula 的理论基础和 qDRIFT 方法,并给出了 qDRIFT 的实现例子。但 qDRIFT 并非随机的 product formula 的唯一方法。作为使用 product formula 进行量子模拟的方法的一个分支,随机的 product formula 还有诸多方法值得我们去探究。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "## 参考资料\n", + " \n", + "[1] Lloyd, Seth. \"Universal quantum simulators.\" [Science (1996): 1073-1078](https://www.jstor.org/stable/2899535).\n", + "\n", + "[2] Childs, Andrew M., et al. \"Toward the first quantum simulation with quantum speedup.\" [Proceedings of the National Academy of Sciences 115.38 (2018): 9456-9461](https://www.pnas.org/content/115/38/9456.short).\n", + "\n", + "[3] Nielsen, Michael A., and Isaac Chuang. \"Quantum computation and quantum information.\" (2002): 558-559.\n", + "\n", + "[4] Campbell, E. . \"Random Compiler for Fast Hamiltonian Simulation.\" [Physical Review Letters 123.7(2019):070503.1-070503.5](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.123.070503).\n", + "\n", + "[5] Khatri, Sumeet, and Mark M. Wilde. \"Principles of quantum communication theory: A modern approach.\" [arXiv preprint arXiv:2011.04672 (2020).](https://arxiv.org/abs/2011.04672)\n", + "\n", + "[6] Watrous, J. . [The Theory of Quantum Information](https://cs.uwaterloo.ca/~watrous/TQI/). 2018.\n", + "\n", + "[7] Watrous, J. . \"Simpler semidefinite programs for completely bounded norms.\" [Chicago Journal of Theoretical Computer Science (2012).](https://arxiv.org/abs/1207.5726)\n", + "\n", + "[8] Watrous, J. . \"Semidefinite Programs for Completely Bounded Norms.\" [Theory of Computing 5.1(2009):217-238.](https://arxiv.org/abs/0901.4709)\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('py3.7_pq2.2.1')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.13" + }, + "vscode": { + "interpreter": { + "hash": "4e4e2eb86ad73936e915e7c7629a18a8ca06348106cf3e66676b9578cb1a47dd" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tutorials/quantum_simulation/QDRIFT_EN.ipynb b/tutorials/quantum_simulation/QDRIFT_EN.ipynb new file mode 100644 index 0000000..d84b530 --- /dev/null +++ b/tutorials/quantum_simulation/QDRIFT_EN.ipynb @@ -0,0 +1,569 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Hamiltonian Simulation with qDRIFT\n", + " Copyright (c) 2022 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Overview\n", + "In quantum mechanics, the energy of the system is described by the Hamiltonian operator $H$, which determines the evolution of the system. So Hamiltonian simulation has great practical value in modeling complex chemical and physical systems. However, because the degree of freedom of the system increases exponentially with the increase of the system (such as the number of qubits), it is generally impossible to use classical computers to effectively simulate quantum systems. At present, the main technology of using quantum computers to simulate Hamiltonian is to use product formula method to simulate time evolution. This tutorial will introduce some basic theories and methods about product formula, and a random method named quantum stochastic drift protocol (qDRIFT) which is based on product formula. Then we give a code demonstration at the end of the article.\n", + "\n", + "\n", + "## Product formula\n", + "\n", + "According to the basic axioms of quantum mechanics, the evolution of the system with Hamiltonian $H$ can be described by the following equation\n", + "\n", + "$$\n", + "i \\hbar \\frac{d}{d t} | \\psi \\rangle = H | \\psi \\rangle,\n", + "\\tag{1}\n", + "$$\n", + "\n", + "where $\\hbar$ is the reduced Planck constant. Therefore, for a time-independent Hamiltonian, the time evolution equation of the system can be written as\n", + "\n", + "$$\n", + "|\\psi(t) \\rangle = U(t) | \\psi (0) \\rangle, ~ U(t) = e^{- i H t}.\n", + "\\tag{2}\n", + "$$\n", + "\n", + "Here we take the natural unit $\\hbar=1$, $U (t) $ as the time evolution operator. The core idea of using quantum circuits to simulate the time evolution process is to use the unitary transformation constructed by quantum circuits to simulate and approximate the time evolution operator. Seth Lloyd pointed out in his 1996 article that a whole evolution time of $t$ can be divided into $r$ shorter \"time blocks\" to reduce the error of simulation in time evolution[1]. Consider a general Hamiltonian form $H = \\sum_ {k=1}^{L} H_k$, of which $H_k$ is sub-Hamiltonian acting on a part of the system. We consider each sub-Hamiltonian $H_k$ whose evolution operator is $e^ {-i H_k t}$, and we can get $\\prod_{k=1}^{L} e^{-i H_k t}$ by simulating each sub-Hamiltonian in turn. Through Taylor expansion, it can be found that\n", + "\n", + "$$\n", + "e^{-iHt} = \\prod_{k=1}^{L} e^{-i H_k t} + O(t^2).\n", + "\\tag{3}\n", + "$$\n", + "\n", + "Then let $\\tau = t/r$ and consider the evolution operator $\\left (e^ {-iH \\tau}\\right) ^r$, we can deduce that\n", + "\n", + "$$\n", + "e^{-iHt} = \\left(e^{-iH \\tau}\\right)^r = \\left(\\prod_{k=1}^{L} e^{-i H_k \\tau} + O(\\tau^2) \\right)^r = \\left(\\prod_{k=1}^{L} e^{-i H_k \\tau} \\right)^r + O\\left(\\frac{t^2}{r}\\right).\n", + "\\tag{4}\n", + "$$\n", + "\n", + "This formula tells us that as long as the whole evolution time can be divided into enough \"fragments\", we can simulate with any high simulation accuracy. That is the basic idea of the product formula. However, what is given in (4) is only a rough estimate. If we want to estimate the depth of the quantum circuits required to achieve a certain simulation accuracy, we need to calculate its rigorous error upper bound. Specifically, we make $U_ {circuit}$ represent the circuit we construct, $\\Vert \\cdot \\Vert$ is the Schatten-$\\infty$ norm, that is, the [spectral norm](https://en.wikipedia.org/wiki/Schatten_norm). Then the simulation error $\\epsilon$ can be written as\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + "\\epsilon\\left(e^{-iH\\tau}, U_{circuit}\\right) & = \\Vert e^{-iH\\tau} - U_{circuit}\\Vert .\n", + "\\end{aligned}\n", + "\\tag{5}\n", + "$$\n", + "\n", + "Next, we will show a brief calculation process of the upper bound of error. We give two conclusions (6) and (7) without proof, which will be used in proving (8). Interested readers can refer to section F.1 in [2] for details.\n", + "\n", + "$$\n", + "\\left\\Vert \\mathcal{R}_k \\left( \\prod_{k=1}^{L} e^{-i H_k \\tau} \\right) \\right\\Vert\n", + "\\leq\n", + "\\mathcal{R}_k \\left( e^{\\vert \\tau \\vert \\sum_{k=1}^{L} \\Vert H_k \\Vert } \\right),\n", + "\\tag{6}\n", + "$$\n", + "\n", + "$$\n", + "\\vert \\mathcal{R}_k(e^\\alpha) \\vert \\leq \\frac{\\vert \\alpha \\vert^{k+1}}{(k+1)!} e^{ \\vert \\alpha \\vert }, ~\n", + "\\forall \\alpha \\in \\mathbb{C},\n", + "\\tag{7}\n", + "$$\n", + "\n", + "where $\\mathcal{R}_ k (f) $ is the remainder Taylor expansion to order $k$ of the function $f$, such as $\\mathcal{R}_1 (e^x)=\\mathcal{R}_1 (\\sum_{j=0}^\\infty \\frac{x^n}{n!})=\\sum_{j=2}^\\infty \\frac{x^n}{n!}$. \n", + "Make $\\Lambda = \\max_ k \\Vert H_ k \\Vert$, considering the complete evolution time $t = r \\cdot \\tau$, the error of simulation in complete time $t$ is:\n", + "$$\n", + "\\begin{aligned}\n", + "\\left \\Vert \\left ( e^{-i\\tau \\sum_{k=1}^L H_k }\\right)^r - \\left (\\prod_{k=1}^{L} e^{-i H_k \\tau} \\right)^r \\right \\Vert \\leq &\n", + "r \\left \\Vert e^{-i\\tau \\sum_{k=1}^L H_k } - \\prod_{k=1}^{L} e^{-i H_k \\tau } \\right \\Vert \\\\\n", + "=& r \\left \\Vert \\mathcal{R}_1 \\left( e^{-i\\tau \\sum_{k=1}^L H_k} \\right)- \\mathcal{R}_1 \\left( \\prod_{k=1}^{L} e^{-i H_k \\tau } \\right) \\right \\Vert \\\\\n", + "\\leq& r \\left \\Vert \\mathcal{R}_1 \\left( e^{-i\\tau \\sum_{k=1}^L H_k} \\right) \\right \\Vert+ r\\left \\Vert \\mathcal{R}_1 \\left( \\prod_{k=1}^{L} e^{-i H_k \\tau } \\right) \\right \\Vert \\\\\n", + "\\leq& 2r \\left \\Vert \\mathcal{R}_1 \\left( e^{-i |\\tau | \\sum_{k=1}^L \\Vert H_k \\Vert} \\right) \\right \\Vert \\\\\n", + "\\leq& 2r \\left \\Vert \\mathcal{R}_1 \\left( e^{-i |\\tau | L \\Lambda} \\right) \\right \\Vert \\\\\n", + "\\leq& r ( \\tau L \\Lambda )^2 e^{\\vert \\tau \\vert L \\Lambda } \\\\\n", + "=&\\frac{( t L \\Lambda )^2}{r} e^{\\frac{\\vert t \\vert L \\Lambda}{r} }.\n", + "\\end{aligned}\n", + "\\tag{8}\n", + "$$\n", + "\n", + "The conclusion of linear accumulation of errors in quantum circuits is used here, that is, $\\Vert U^r - V^r \\Vert \\leq r\\Vert U - V \\Vert$. Readers who are not familiar with this conclusion can refer to section 4.5.3 in [3]; and also use the conclusion when $k=1$ in formula (7). So far, we have calculated the upper bound of the simulation error of the product formula for a complete evolution time $t$, that is, the second-order term $O (t^2/r)$ in equation (4).\n", + "\n", + "After obtaining the upper bound of the simulation error, the lower bound of the circuit depth required to reach a certain accuracy $\\epsilon$ can be calculated. From (8), we can find that the formula contains a $L$ term, which means that as the number of Hamiltonian terms increases, the upper bound of simulation error will become larger and larger, which will cause a deeper circuit if we need to control the accuracy. qDRIFT introduced in this tutorial optimizes this problem. qDRIFT focuses on the coefficients of the Hamiltonian itself and models it as a probability distribution. Each unitary gate is sampled from the probability distribution independently and repeated a certain number of times to form a quantum circuit. Finally, under a given accuracy, the depth of the quantum circuits will not explicitly contain the number of Hamiltonian items $L$. Now we will introduce it.\n", + "\n", + "\n", + "## qDRIFT\n", + "\n", + "First, we give the form of the target Hamiltonian\n", + "$$\n", + "H=\\sum_{j=1}^L h_j H_j,\n", + "\\tag{9}\n", + "$$\n", + "\n", + "It contains $L$ sub-Hamiltonian $H_j$, note that here $H_j$ has been normalized, that is, $\\Vert H_j \\Vert = 1$, where $\\Vert\\cdot\\Vert$ is the Schatten-$\\infty$ norm. $h_j$ is the coefficient of each sub-Hamiltonian, which is a positive real number. Using these coefficients, we can construct a discrete probability distribution, and take the proportion of a single coefficient in the sum of the Hamiltonian coefficients as the probability of each unitary gate being sampled, which is $p_j =h_j / \\lambda $, where $\\lambda = \\sum_j h_j $ is the sum of the coefficients. Then the sampling will be repeated $ N $ times (to compared with product formula, we let $N=Lr$ here ), we will get an ordered list arranged by $j $ and can construct a unitary gate $U_j = e^{i\\tau H_j}$ according to the arrangement. Assuming $L = 3 $, $r = 2 $, we can sample an ordered list according to the above probability distribution, as shown in\n", + "\n", + "$$\n", + "[ 3, 1, 2 ,3 ,3 ,1 ],\n", + "$$\n", + "\n", + "then we can construct the quantum circuits as \n", + "\n", + "$$\n", + "U_{circuit} = e^{i\\tau H_1}e^{i\\tau H_3}e^{i\\tau H_3}e^{i\\tau H_2}e^{i\\tau H_1}e^{i\\tau H_3},\n", + "$$\n", + "\n", + "$\\tau = t \\lambda / N$. That is an implementation of qDRIFT to simulate Hamiltonian.\n", + "\n", + "The implementation process of qDRIFT is very simple, and its advantage is that the complexity of the number of unitary gates is $O ((\\lambda t) ^ 2 / \\epsilon) $) when the target precision is $\\epsilon $. It can be seen that this is a result without $L$. In other words, the number of unitary gates is not explicitly related to the number of Hamiltonian terms, which can effectively reduce the length of the simulated circuit when the number of Hamiltonian terms is large. Next, we will give a proof.\n", + "\n", + "We model the process of sampling from probability distribution as a quantum channel. We use the curlicue letters $\\mathcal{E} $ and $\\mathcal{U}$ to represent the channel established through qDRIFT and the channel to be simulated, and use $\\mathcal{E}_ N $ and $\\mathcal{U}_N$ to represent one of the $n $ actions of their respective channels on the quantum state $\\rho $,\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + "&\\mathcal{U}_N (\\rho) = e^{\\frac{it}{N}H} \\rho e^{\\frac{-it}{N}H}= e^{\\frac{t}{N}\\mathcal{L}} (\\rho),\n", + "\\\\\n", + "&\\mathcal{E}_N (\\rho)=p_j e^{i\\tau H_j} \\rho e^{-i\\tau H_j}=p_j e^{\\tau \\mathcal{L}_j}(\\rho).\n", + "\\end{aligned}\n", + "\\tag{10}\n", + "$$\n", + "\n", + "Here we introduce the Liouvillian representation, that is, for the quantum channel $\\mathcal{P} (\\rho) = e^{iHt} \\rho e^{-iHt}$, there is\n", + "$$\n", + "\\mathcal{P}(\\rho)=e^{iHt}\\rho e^{-iHt}=e^{t\\mathcal{L}}(\\rho)=\\sum_{k=0}^\\infty \\frac{t^k \\mathcal{L}^k (\\rho)}{k!},\n", + "\\tag{11}\n", + "$$\n", + "\n", + "where $\\mathcal{L} (\\rho) =i (H\\rho - \\rho H) $, similarly, $\\mathcal{L}_ j(\\rho)=i(H_j\\rho - \\rho H_j)$. It should be noted that the operation rules of its series follow $\\mathcal{L}^ {n+1} (\\rho) =i (H\\mathcal{L}^n (\\rho) -\\mathcal{L}^n (\\rho) H) $. Specifically, $\\mathcal{U}_N = \\sum_{n=0}^\\infty \\frac{t^n\\mathcal{L}^n}{n!N^n}$, $\\mathcal{E}_N =\\sum_{j}p_j \\sum_{n=0}^\\infty \\frac{\\lambda^n t^n \\mathcal{L}_j^n}{n!N^n}$. Next, how do we measure the distance between two channels? Here we introduce the definition of [diamond norm](https://en.wikipedia.org/wiki/Diamond_norm)\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + "\\Vert \\mathcal{P} \\Vert_\\Diamond :=\\sup_{\\rho ; \\Vert \\rho \\Vert _1 =1}\\Vert (\\mathcal{P} \\otimes \\mathbb{I})(\\rho )\\Vert _1 .\n", + "\\end{aligned}\n", + "\\tag{12}\n", + "$$\n", + "Here $\\mathbb {I} $ is the identity channel which has the same size as $\\mathcal{P}$ and $\\Vert \\cdot \\Vert$ is Schatten-$1$ norm or called [trace norm](https://en.wikipedia.org/wiki/Schatten_norm). We use the diamond norm to define the distance between two quantum channels\n", + "$$\n", + "\\begin{aligned}\n", + "d_\\Diamond (\\mathcal{E},\\mathcal{U}) &=\\frac{1}{2} \\Vert \\mathcal{E} -\\mathcal{U} \\Vert_\\Diamond\n", + "\\\\\n", + "&=\\sup_{\\rho ; \\Vert \\rho \\Vert _1 =1} \\frac{1}{2} \\Vert ((\\mathcal{E}-\\mathcal{U}) \\otimes \\mathbb{I})(\\rho )\\Vert _1 .\n", + "\\end{aligned}\n", + "\\tag{13}\n", + "$$\n", + "The diamond norm represents the maximum possibility that the two channels can be distinguished in all quantum states. The larger its value, the greater the possibility that the two channels can be distinguished, which means that the two channels are far away and the simulation ability is poor; on the contrary, if its value is small, it means that the simulation ability is good. Next, we can calculate the upper bound of the distance of the channel with a single action of the channel\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + " \\Vert \\mathcal{U}_N-\\mathcal{E}_N \\Vert_\\Diamond &= \\left\\Vert \\sum_{n=2}^\\infty \\frac{t^n\\mathcal{L}^n}{n!N^n}-\\sum_{j}\\frac{h_j}{\\lambda} \\sum_{n=2}^\\infty \\frac{\\lambda^n t^n \\mathcal{L}_j^n}{n!N^n} \\right\\Vert_\\Diamond\\\\\n", + " &\\leq \\sum_{n=2}^\\infty \\frac{t^n\\Vert \\mathcal{L}^n \\Vert_\\Diamond }{n!N^n} + \\sum_{j}\\frac{h_j}{\\lambda} \\sum_{n=2}^\\infty \\frac{\\lambda^n t^n \\Vert\\mathcal{L}_j^n \\Vert_\\Diamond }{n!N^n}\\\\\n", + " &\\leq \\sum_{n=2}^\\infty \\frac{1}{n!}\\left( \\frac{2\\lambda t}{N}\\right)^n+\\sum_{j}\\frac{h_j}{\\lambda} \\sum_{n=2}^\\infty \\frac{1}{n!}\\left( \\frac{2\\lambda t}{N}\\right)^n\\\\\n", + " &=2\\sum_{n=2}^\\infty \\frac{1}{n!}\\left( \\frac{2\\lambda t}{N}\\right)^n .\n", + "\\end{aligned}\n", + "\\tag{14}\n", + "$$\n", + "\n", + "The conclusion $\\Vert \\mathcal{L} \\Vert_ \\Diamond \\leq 2\\Vert H\\Vert \\leq 2\\lambda$ is used here. Similarly, $\\Vert \\mathcal{L}_ j \\Vert_ \\Diamond \\leq 2\\Vert H_ j\\Vert \\leq 2$ [4]. Then, we can use the conclusion of (7) mentioned above to make $k=1$, $\\alpha=2 \\lambda t /N$, and then we can get\n", + "\n", + "$$\n", + "d_\\Diamond (\\mathcal{U}_N,\\mathcal{E}_N) \\leq \\frac{2\\lambda^2 t^2}{N^2} e^{2\\lambda t/N} .\n", + "\\tag{15}\n", + "$$\n", + "\n", + "Then using the conclusion of $\\Vert U^r - V^r \\Vert \\leq r\\Vert U - V \\Vert$ again (it should be noted that $U$ and $V$ in the formula are linear operators, but quantum channels $\\mathcal{U}_N$ and $\\mathcal{E}_N$ are still feasible. Refer to Chapter 3.3.2 in [6] to get more details.). With $2\\lambda t \\ll N$ generally, we can deduce\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + "d_\\Diamond (\\mathcal{U},\\mathcal{E}) &\\leq N d_\\Diamond (\\mathcal{U}_N, \\mathcal{E}_N)\\\\\n", + " &=\\frac{2\\lambda^2 t^2}{N} e^{2\\lambda t/N} \\approx \\frac{2\\lambda^2 t^2}{N}.\n", + "\\end{aligned}\n", + "\\tag{16}\n", + "$$\n", + "\n", + "So $N \\sim O ((\\lambda t) ^2 /\\epsilon) $. It can be seen from the above formula that under the condition of $\\lambda \\ll \\Lambda L $ (Hamiltonian is defined as $H=\\sum_{j=1}^L h_j H_j$ in qDRIFT, so $\\Lambda = \\max_k h_k $ here), the distance will not be explicitly related to $L$, which means that when $L$ is large, that is, the situation is complex, the quantum circuit will not be increased, and the number of unitary gates can be effectively controlled. Many systems satisfy the condition $\\lambda \\ll \\Lambda L$ such as carbon-dioxide, ethane. But not all cases satisfy. If $\\lambda = \\Lambda L$ or $\\lambda = \\Lambda \\sqrt{L}$, their upper bounds are $O (L^2 (\\Lambda t) ^2 /\\epsilon) $ and $O (L (\\Lambda t) ^2 /\\epsilon) $ respectively, we can see that they still increase with the number of Hamiltonian terms. Interested readers can refer to [4] for more details.\n", + "\n", + "\n", + "## Code Demonstration\n", + "We will implement qDRIFT in combination with code. We will first demonstrate the performance of its sampling results, and then calculate the simulation error of its channel. First, we need to import the required packages." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import warnings\n", + "\n", + "import math\n", + "import numpy as np \n", + "import scipy \n", + "import paddle_quantum as pq \n", + "import paddle\n", + "\n", + "warnings.filterwarnings(\"ignore\") # Hide warnings\n", + "np.set_printoptions(suppress=True,linewidth=np.nan) # Enable full display, so that line breaks would not appear\n", + " # when viewing the matrix on the terminal print\n", + "pq.set_backend('density_matrix') # use density matrix representation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We assume that the system consists of two qubits. We can use the `hamiltonian` module of the Paddle Quantum to construct a Hamiltonian with $L=4$ satisfied $\\lambda \\ll \\Lambda L$ to demonstrate, which is our target Hamiltonian, as follows\n", + "$$\n", + "\\begin{aligned}\n", + "H&=I \\otimes X + 0.05 * X \\otimes Z + 0.05 * I \\otimes Y+0.05 * X \\otimes X .\n", + "\\end{aligned}\n", + "$$" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Target Hamiltonian is :\n", + " [[ 0. +0.j 1. -0.05j 0.05+0.j 0.05+0.j ]\n", + " [ 1. +0.05j 0. +0.j 0.05+0.j -0.05+0.j ]\n", + " [ 0.05+0.j 0.05+0.j 0. +0.j 1. -0.05j]\n", + " [ 0.05+0.j -0.05+0.j 1. +0.05j 0. +0.j ]]\n" + ] + } + ], + "source": [ + "qubits = 2 # Set the number of qubits\n", + "H_j = [(1.0, 'I0,X1'), # The Pauli string of target Hanmiltonian\n", + " (0.05, 'X0,Z1'),\n", + " (0.05, 'I0,Y1'),\n", + " (0.05, 'X0,X1'), ]\n", + "\n", + "H = pq.hamiltonian.Hamiltonian(H_j) \n", + "print(f'Target Hamiltonian is :\\n {H.construct_h_matrix(qubit_num=qubits)}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we calculate probability according to $\\lambda = \\sum_ j h_ j$,$ p_ j=h_j/\\lambda $. In this experiment, we assume that our target accuracy $\\epsilon=0.1$, simulation time $t=1$, that is, we need to sample $n=\\lceil \\frac{2\\lambda^2 t^2} {\\epsilon}\\rceil = 27 $ times." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "To meet the accuracy of 0.1, there are 27 unitary gates needed.\n" + ] + } + ], + "source": [ + "h_j = np.array(H.coefficients) # Get coeffcients\n", + "lamda = h_j.sum()\n", + "p_j = h_j/lamda # Calculate the discrete probability distribution\n", + "accuracy = 0.1\n", + "t = 1\n", + "gate_counts = math.ceil(2 * lamda**2 * t**2 / accuracy)\n", + "\n", + "print(f'To meet the accuracy of {accuracy}, there are {gate_counts} unitary gates needed.')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we will sample 27 times independently from the probability distribution $p_j$ and construct a unitary circuit according to the sample results." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Sample results:\n", + " [1 1 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 4 1]\n", + "The simulation circuit matrix of qDRIFT is: \n", + " [[ 0.51998969-0.02531459j 0.03408183+0.85099285j -0.03524884+0.02376227j -0.0353899 +0.02366261j]\n", + " [-0.03408183+0.85099285j 0.51998969+0.02531459j 0.0353899 +0.02366261j -0.03524884-0.02376227j]\n", + " [-0.03524884+0.02376227j -0.0353899 +0.02366261j 0.51998969-0.02531459j 0.03408183+0.85099285j]\n", + " [ 0.0353899 +0.02366261j -0.03524884-0.02376227j -0.03408183+0.85099285j 0.51998969+0.02531459j]] \n", + "The original circuit matrix is: \n", + " [[ 0.53752508-0.00075235j 0.04202098+0.83966719j -0.04201839+0.04202098j -0.00075235+0.02697398j]\n", + " [-0.04202098+0.83966719j 0.53752508+0.00075235j 0.00075235+0.02697398j -0.04201839-0.04202098j]\n", + " [-0.04201839+0.04202098j -0.00075235+0.02697398j 0.53752508-0.00075235j 0.04202098+0.83966719j]\n", + " [ 0.00075235+0.02697398j -0.04201839-0.04202098j -0.04202098+0.83966719j 0.53752508+0.00075235j]]\n" + ] + } + ], + "source": [ + "np.random.seed(666) # Fix the random seed to demonstrate\n", + "sample_list = np.random.choice(a=range(1, 5), size=gate_counts, replace=True, p=p_j)\n", + "print(f'Sample results:\\n {sample_list}')\n", + "\n", + "# Calculate the sampled unitary circuit according to the sample result\n", + "simulation = np.identity(2 ** qubits) # Generate the identity matrix\n", + "tau = 1j*lamda*t/gate_counts\n", + "for i in sample_list:\n", + " pauli_str_j = (1.0, H_j[i-1][1]) # Get H_ j. Note that its original coefficient should be discarded\n", + " H_i = pq.hamiltonian.Hamiltonian([pauli_str_j]).construct_h_matrix(qubit_num=qubits)\n", + " simulation = np.matmul(scipy.linalg.expm(tau*H_i), simulation) \n", + "origin = scipy.linalg.expm(1j*t*H.construct_h_matrix(qubit_num=qubits)) # Calculate the original circuit of the target Hamiltonian\n", + "print(f'The simulation circuit matrix of qDRIFT is: \\n {simulation} \\nThe original circuit matrix is: \\n {origin}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then we can calculate the simulation error $\\Vert e^{iHt}-U_{circuit} \\Vert $ between the unitary circuit sampled from qDRIFT and the original circuit, note that the norm here is the spectral norm." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Simulation error: 0.0309\n" + ] + } + ], + "source": [ + "distance = 0.5*np.linalg.norm(origin-simulation, ord=2)\n", + "print(f'Simulation error: {distance:.4f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Of course, we can take a specific quantum state to test. Without losing generality, we assume that the initial quantum state is a zero state, that is, $\\rho(0) = | 0 \\rangle \\langle 0 | $. We can let the quantum state evolve through the original circuit and the simulation circuit respectively. At the time of $t $, the quantum state is $\\rho(t)_{origin}$ and $\\rho(t)_{qDRIFT}$, we can use the fidelity between these two quantum states to measure the effect of simulation circuits." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Initial State: \n", + " [[1.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", + " [0.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", + " [0.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", + " [0.+0.j 0.+0.j 0.+0.j 0.+0.j]]\n", + "The fidelity between two states is 0.9989\n" + ] + } + ], + "source": [ + "rho_0 = pq.state.zero_state(qubits).numpy() # Generate the zero state density matrix\n", + "print(f'Initial State: \\n {rho_0}')\n", + "\n", + "rho_t_origin = pq.state.to_state(origin @ rho_0 @ origin.T.conjugate()) # Evolve through the original circuit\n", + "rho_t_qdrift = pq.state.to_state(simulation @ rho_0 @ simulation.T.conjugate()) # Evolve through the simulation circuit\n", + "fidelity = pq.qinfo.state_fidelity(rho_t_origin, rho_t_qdrift)\n", + "print(f'The fidelity between two states is {float(fidelity):.4f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It can be found that the above tests meet our accuracy requirements. However, different from a sampled unitary circuit, we regard the qDRIFT sampling method as a quantum channel, that is, a mapping of the quantum state $\\rho $. The above experiment is only a specific instance of this channel. Next, we will analyze the performance of this channel. First, we can define a function to describe the qDRIFT channel." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# Define qDRIFT channel\n", + "def qdrift_channel(iter_num, sample_num, hamiltonian_list, coefficient_list, simulation_time, qubits, input_state):\n", + " '''\n", + " Input :\n", + " iter_num : the current number of iterations, as a label of recursion\n", + " sample_num : number of samples, N\n", + " hamiltonian_list : the list of Pauli string of the target Hamiltonian, H_j\n", + " coefficient_list : the coefficient list of sub-Hamiltonian, h_j\n", + " simulation_time : simulation time, t\n", + " qubits : the number of qubits \n", + " input_state : the input quantum state, which should be a density matrix\n", + " \n", + " Return :\n", + " The quantum state aftre the evolution of this channel, represented in density matrix\n", + " '''\n", + " lamda = coefficient_list.sum() \n", + " tau = lamda*simulation_time/sample_num\n", + " output = 0\n", + "\n", + " if iter_num != 1: # Enable recursion when iteration flag is not 1\n", + " input_state = qdrift_channel(iter_num-1, sample_num, hamiltonian_list,\n", + " coefficient_list, simulation_time, qubits, input_state)\n", + "\n", + " # Calculate e^{iH\\tau} \\rho e^{-iH\\tau} \n", + " for sub_H, sub_h in zip(hamiltonian_list, coefficient_list):\n", + " sub_H = pq.hamiltonian.Hamiltonian([sub_H]).construct_h_matrix(qubit_num=qubits)\n", + " unitary = scipy.linalg.expm(1j*tau*sub_H) # Calculate e^{iH\\tau}\n", + " output += sub_h/lamda*unitary @ input_state @ unitary.conjugate().T\n", + " return output" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then we can calculate the distance between the two channels through the diamond norm, but the solution of the diamond norm is a positive semidefinite programming problem, that is\n", + "\n", + "$$\n", + "d_\\Diamond(\\mathcal{U}- \\mathcal{E})=\\sup_{\\Omega \\geq 0 \\atop \\rho \\geq 0}\\{\\text{Tr}[\\Omega (\\Gamma_\\mathcal{U}-\\Gamma_\\mathcal{E})]: \\Omega \\leq \\rho \\otimes \\mathbb{I},\\text{Tr} (\\rho)=1\\},\n", + "\\tag{17}\n", + "$$\n", + "where $\\Gamma_ \\mathcal{U} $ and $\\Gamma_ \\mathcal{E}$ are Choi representations of the original channel and the simulation channel. There are many forms of positive semidefinite programming and Choi representation of diamond norm, and interested readers can read [6-8] for more details. The Choi representation we use here is:\n", + "$$\n", + "\\Gamma_\\mathcal{P}=\\sum_{i,j=0}^{d-1} |i\\rangle \\langle j| \\otimes \\mathcal{P}(|i\\rangle \\langle j|),\n", + "\\tag{18}\n", + "$$\n", + "where $\\mathcal {P} $ is the quantum channel and $d$ is the dimension of the input quantum state of the quantum channel. Here we first calculate the Choi representation of the two channels." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# There is how to calculate the Choi representation of the original channel and the qDRIFT channel, \n", + "# and the diamond norm can be calculated under this representation\n", + "choi_qdrift = 0\n", + "choi_origin = 0\n", + "channel = scipy.linalg.expm(1j*t*H.construct_h_matrix(qubit_num=qubits))\n", + "for i in range(2 ** qubits):\n", + " for k in range(2 ** qubits):\n", + " choi_temp = np.zeros((2 ** qubits, 2 ** qubits))\n", + " choi_temp[i][k] = 1 # Generate |i\\rangle \\langle k|\n", + "\n", + " # Calculate the Choi matrix of channel E\n", + " # Calculate \\mathcal{E}(|i\\rangle \\langle k|)\n", + " choi_temp_qdrift = qdrift_channel(gate_counts, gate_counts, H_j, h_j, t, qubits, choi_temp) \n", + " # Calculate |i\\rangle \\langle k| \\otimes \\mathcal{E}(|i\\rangle \\langle k|)\n", + " choi_qdrift += np.kron(choi_temp, choi_temp_qdrift)\n", + "\n", + " # Calculate the Choi matrix of channel U\n", + " # Calculate \\mathcal{U}(|i\\rangle \\langle k|)\n", + " choi_temp_origin = channel @ choi_temp @ channel.T.conjugate()\n", + " # Calculate |i\\rangle \\langle k| \\otimes \\mathcal{U}(|i\\rangle \\langle k|)\n", + " choi_origin += np.kron(choi_temp, choi_temp_origin)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then we can calculate the diamond norm according to formula (17) and find the diamond distance of the two channels. " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The distance between the two channels is: 0.0764\n" + ] + } + ], + "source": [ + "diamond_distance = 0.5 * pq.qinfo.diamond_norm(paddle.to_tensor(choi_origin-choi_qdrift))\n", + "print(f'The distance between the two channels is: {diamond_distance:.4f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The calculation results are in line with our expectations. Note that this value represents the expectance of the worst performance of the channel sampling for a specific simulation circuit instance, so it can not guarantee that each sampled circuit can achieve this accuracy." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Summary\n", + "Quantum simulation itself is a relatively broad topic, and its application is also very extensive. This tutorial introduces the basic theory of product formula and the qDRIFT method, but qDRIFT is not the only method for random product formulas. As a branch of the method of quantum simulation using product formula, random product formula has many methods worth exploring." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "## Reference\n", + " \n", + "[1] Lloyd, Seth. \"Universal quantum simulators.\" [Science (1996): 1073-1078](https://www.jstor.org/stable/2899535).\n", + "\n", + "[2] Childs, Andrew M., et al. \"Toward the first quantum simulation with quantum speedup.\" [Proceedings of the National Academy of Sciences 115.38 (2018): 9456-9461](https://www.pnas.org/content/115/38/9456.short).\n", + "\n", + "[3] Nielsen, Michael A., and Isaac Chuang. \"Quantum computation and quantum information.\" (2002): 558-559.\n", + "\n", + "[4] Campbell, E. . \"Random Compiler for Fast Hamiltonian Simulation.\" [Physical Review Letters 123.7(2019):070503.1-070503.5](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.123.070503).\n", + "\n", + "[5] Khatri, Sumeet, and Mark M. Wilde. \"Principles of quantum communication theory: A modern approach.\" [arXiv preprint arXiv:2011.04672 (2020).](https://arxiv.org/abs/2011.04672)\n", + "\n", + "[6] Watrous, J. . [The Theory of Quantum Information](https://cs.uwaterloo.ca/~watrous/TQI/). 2018.\n", + "\n", + "[7] Watrous, J. . \"Simpler semidefinite programs for completely bounded norms.\" [Chicago Journal of Theoretical Computer Science (2012).](https://arxiv.org/abs/1207.5726)\n", + "\n", + "[8] Watrous, J. . \"Semidefinite Programs for Completely Bounded Norms.\" [Theory of Computing 5.1(2009):217-238.](https://arxiv.org/abs/0901.4709)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('py3.7_pq2.2.1')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.13" + }, + "vscode": { + "interpreter": { + "hash": "4e4e2eb86ad73936e915e7c7629a18a8ca06348106cf3e66676b9578cb1a47dd" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tutorials/quantum_simulation/QPP_CN.ipynb b/tutorials/quantum_simulation/QPP_CN.ipynb new file mode 100644 index 0000000..cd049fe --- /dev/null +++ b/tutorials/quantum_simulation/QPP_CN.ipynb @@ -0,0 +1,468 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 量子相位处理\n", + "\n", + "*Copyright (c) 2022 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 概览" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**量子相位处理**(quantum phase processing,简称 **QPP**)是一个由百度量子团队 [[1]](https://arxiv.org/abs/2209.14278) 提出的量子算法框架。该框架可以转换和处理酉算子的本征相位,并高效且精准地进行酉算子的本征变换或信息提取。该框架的推出来源于一种名为**三角量子信号处理**(trigonometric quantum signal processing, 简称三角 QSP)技术的改进 [[2]](https://arxiv.org/abs/2205.07848)。该技术可以使用单个比特去模拟输入数据的任意三角变换。对应地,QPP 则在更高维度上继承了三角 QSP 的能力。QPP 通过控制酉算子的方式,获取了酉算子的本征信息,从而在其本征空间下完成了对应本征相位的任意三角变换。\n", + "\n", + "基于论文 [[1]](https://arxiv.org/abs/2209.14278) 和块编码(block encoding)技术,本教程会向大家介绍如何使用 QPP 去解决量子相位估计问题、哈密顿量模拟问题和熵估计问题。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "以下是必要的 libraries 和 packages。" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import warnings\n", + "warnings.filterwarnings(\"ignore\")\n", + "\n", + "import numpy as np\n", + "from scipy.linalg import expm\n", + "import paddle\n", + "\n", + "# 量桨的通用函数\n", + "import paddle_quantum as pq\n", + "from paddle_quantum.ansatz import Circuit\n", + "from paddle_quantum.hamiltonian import Hamiltonian\n", + "from paddle_quantum.linalg import abs_norm, hermitian_random, unitary_random, block_enc_herm, herm_transform\n", + "from paddle_quantum.qinfo import trace_distance, partial_trace_discontiguous\n", + "from paddle_quantum.state import is_density_matrix, random_state, zero_state, State\n", + "\n", + "# 量桨的 QPP 模块函数\n", + "from paddle_quantum.qpp import Q_generation, hamiltonian_laurent, qpp_angle_approximator, qpp_cir, qps, qubitize, purification_block_enc, simulation_cir\n", + "\n", + "# 设置计算精度和后端\n", + "pq.set_dtype('complex128')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 框架介绍" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "QPP 主要依赖一个名为**相位处理器**的量子线路来处理数据。对于偶数 $L \\in \\mathbb{N}$,我们定义一个 $n$-比特酉算子 $U$ 的相位处理器为\n", + "\n", + "$$\n", + "V^L(U) := R_z^{(0)} R_y^{(0)} R_z^{(0)}\n", + "\\left[ \\prod_{l=1}^{L/2}\n", + " \\begin{bmatrix}\n", + " U^\\dagger & 0 \\\\\n", + " 0 & I^{\\otimes n}\n", + " \\end{bmatrix} R_y^{(0)} R_z^{(0)}\n", + " \\begin{bmatrix}\n", + " I^{\\otimes n} & 0 \\\\\n", + " 0 & U\n", + " \\end{bmatrix} R_y^{(0)} R_z^{(0)}\n", + "\\right],\n", + "\\tag{1}\n", + "$$\n", + "\n", + "这里 $R_y^{(0)}$ 和 $R_z^{(0)}$ 为作用在处理器第一个比特上的旋转门,且其旋转角度取决于模拟的三角多项式。其具体的量子电路如下所示:\n", + "\n", + "![qpp-circuit](figures/QPP-fig-circuit.png \"图 1:相位处理器的量子实现(层数 L 为偶数)\")\n", + "\n", + "注:当层数 $L$ 为奇数时,我们定义相应的相位处理器为\n", + "\n", + "$$ \n", + "V^{L}(U) = V^{L - 1}(U) \n", + " \\begin{bmatrix}\n", + " U^\\dagger & 0 \\\\\n", + " 0 & I^{\\otimes n}\n", + " \\end{bmatrix} R_y^{(0)} R_z^{(0)} \\tag{2}。\n", + "$$\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "QPP 有两个核心功能:**相位演化**与**相位提取**。 具体来说,假设一个有如下谱分解的 $n$-(量子)比特酉矩阵 \n", + "\n", + "$$\n", + "U = \\sum_{j=0}^{2^n - 1} e^{i \\tau_j} |\\chi_j \\rangle \\langle \\chi_j |。 \\tag{3}\n", + "$$\n", + "\n", + "那么论文 [[1]](https://arxiv.org/abs/2209.14278) 中的 **Theorem 5** 证明,对于任意满足 $||\\textbf{c}||_1 \\leq 1$ 的(复数)三角多项式 $F(x) = \\sum_{j = -L}^L c_j e^{ijx}$,和任意量子态 $| \\psi \\rangle = \\sum_{j=0}^{2^n - 1} \\alpha_j |\\chi_j \\rangle$,我们都可以找到一个层数为 $2L$ 的相位处理器 $V^{2L}(U)$ 使得\n", + "\n", + "$$\n", + "\\left( \\langle 0 | \\otimes I^{\\otimes n} \\right) V^{2L}(U) |0, \\psi \\rangle = \\sum_{j=0}^{2^n - 1} \\alpha_j F(\\tau_j) | \\chi_j \\rangle。 \\tag{4}\n", + "$$\n", + "\n", + "进一步地,若 $F$ 的值域为实数域,那么对于任意一个量子态 $\\rho$, 论文 [[1]](https://arxiv.org/abs/2209.14278) 中的 **Theorem 6** 证明,我们可以找到一个层数为 $L$ 的相位处理器 $V^{L}(U)$ 使得\n", + "\n", + "$$\n", + "\\text{Tr} \\left[ Z^{(0)} \\cdot V^{L}(U) \\rho V^{L}(U)^\\dagger \\right] = \\sum_{j = 0}^{2^n - 1} p_j F(\\tau_j), \\tag{5}\n", + "$$\n", + "\n", + "这里 $p_j = \\langle \\chi_j | \\rho | \\chi_j \\rangle$,$Z^{(0)}$ 是作用在第一个比特上的泡利-$Z$ 可观测量。下面我们将用这两个功能来完成酉矩阵的相位搜索、哈密顿量的实时演化和量子态的函数变换的迹估计。\n", + "\n", + "注:由于哈密顿量和量子态不是酉矩阵,无法被 QPP 直接处理,因此我们需要使用**比特化块编码**(qubitized block encoding,下文统一称作块编码)来拿到非酉矩阵的本征信息。\n", + "另外,比特化块编码的本征相位和其编码数据的本征值还存在一个 $\\arccos$ 的关系。所以对于一个函数 $f$ 的变换,QPP 实际需要模拟的函数是 $F(x) = f(\\cos(x))$。\n", + "更多块编码的介绍详见[量子信号处理与量子奇异值变换](https://qml.baidu.com/tutorials/quantum-simulation/quantum-signal-processing-and-quantum-singular-value-transformation.html)教程;比特化的知识可以参考论文 [[1]](https://arxiv.org/abs/2209.14278) 和论文 [[3]](https://quantum-journal.org/papers/q-2019-07-12-163/)。\n", + "\n", + "以下是本教程的环境设置。" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "num_qubits = 3 # 各问题的主寄存器大小\n", + "num_block_qubits = num_qubits + 1 # 使用 block encoding 的辅助比特数\n", + "aux_qubits = list(range(num_block_qubits + 1)) # 辅助寄存器所在的比特索引\n", + "sys_qubits = list(range(num_block_qubits + 1, num_block_qubits + 1 + num_qubits)) # 主寄存器所在的比特索引" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 应用:量子相位搜索" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "求解一个酉算子的本征相位是量子计算的核心问题之一,这个问题也叫做量子相位估计(quantum phase estimation,简称 QPE)。该问题的设定为:已知一个酉算子 $U$ 和它的一个本征态 $| \\psi \\rangle$,求解该本征态所对应的本征相位;进一步地,若 $| \\psi \\rangle$ 不再是 $U$ 的本征态,则转而求解(任意)一个与 $| \\psi \\rangle$ 相交的本征态所对应的本征相位。\n", + "\n", + "以下是该问题的实验设定。" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "pq.set_backend('state_vector') # 切换态矢量后端\n", + "\n", + "U = unitary_random(num_qubits) # 酉算子\n", + "psi = random_state(num_qubits) # 输入态(矢量)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "QPP 可以模拟阶梯函数即\n", + "\n", + "$$\n", + "f(x) = \\begin{cases}\n", + " 1 & \\textrm{if }\\, x \\geq 0 \\\\\n", + " 0 & \\textrm{if }\\, x < 0\n", + "\\end{cases}。 \\tag{6}\n", + "$$\n", + "\n", + "QPP 通过测量辅助比特的方式来二分搜索到一个本征相位所在的小区间;然后将这个区间放大再重复操作,从而完成本征相位的估计任务。我们称该算法为**量子相位搜索**(quantum phase search,简称 QPS)算法。相较于传统 QPE 算法,QPS 算法可以在同等精度和资源下获得成功概率的指数提升。QPS 算法的具体细节可以移步至论文 [[1]](https://arxiv.org/abs/2209.14278) 的第二节。\n", + "\n", + "量桨的 QPP 模块有一个内置函数 `qps`,其实现了完整的 QPS 算法。运行结束后,我们可以将结果与理论值对比来验证算法的正确性。" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Computations of angles for QPP are completed with mean error 1.692667280042757e-07\n", + "估计特征相位与输出态特征相位的匹配误差为 2.104050267612231e-11\n", + "输出态与输入态的 overlap 为 0.12645570235623324\n" + ] + } + ], + "source": [ + "# 使用 QPS 算法获取一个本征相位和主系统的输出态\n", + "phase_estimate, output_state = qps(U, psi)\n", + "\n", + "# 拿到输出态对应的本征相位\n", + "phase_expect = np.log((output_state.bra @ U @ output_state.ket).item()) / 1j\n", + "\n", + "print(f\"估计本征相位与输出态本征相位的匹配误差为 {np.abs(phase_expect - phase_estimate)}\")\n", + "print(f\"输出态与输入态的 overlap 为 {abs_norm(output_state.bra @ psi.ket)}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "由上可见,虽然输入态 $| \\psi \\rangle$ 不是 $U$ 的本征态,我们仍可以拿到与 $| \\psi \\rangle$ 内积不为 $0$ 的本征态对应的本征相位。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 应用:哈密顿量模拟" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "一个随着时间演化的 $n$-比特量子系统可以由一个哈密顿量 $H$ 和这个量子系统的初始态 $\\rho$ 决定。该系统在时间 $t$ 的量子态可以表示为 $\\rho_t = e^{-iHt} \\rho e^{iHt}$,这里 $e^{-iHt}$ 称为该系统在时刻 $t$ 下的演化算子。那么哈密顿量模拟的问题设定为:已知一个量子系统的哈密顿量的块编码 $U$ 和初始态 $\\rho$,近似制备该系统在时刻 $t$ 下的量子态 $\\rho_t$。\n", + "\n", + "以下是该问题的实验设定。" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "pq.set_backend(\"density_matrix\") # 切换密度矩阵后端\n", + "\n", + "H = hermitian_random(num_qubits) # 量子系统的哈密顿量\n", + "U = block_enc_herm(H, num_block_qubits) # 哈密顿量的比特化块编码\n", + "rho = random_state(num_qubits) # 初始态(密度矩阵)\n", + "t = 9 # 演化时间\n", + "L = 40 # 相位处理器的层数,即模拟演化函数的精度" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "量桨 QPP 模块的 `hamiltonian_laurent` 可以通过 [Jacobi-Anger 展开](https://en.wikipedia.org/wiki/Jacobi%E2%80%93Anger_expansion) 提供演化函数的近似三角多项式 $P$;然后用 `Q_generation` 算出该多项式的余式 $Q$(两者满足 $PP^* + QQ^* = 1$);函数 `qpp_angle_approximator` 负责估算相位处理器的所有旋转门角度;最后函数 `qpp_cir` 完成相位处理器的构建。" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Computations of angles for QPP are completed with mean error 1.1413227206232605e-07\n" + ] + } + ], + "source": [ + "# 准备近似模拟演化函数的三角多项式和其余式, 这里乘个略小于 1 的数来保证余式的成功计算\n", + "P = hamiltonian_laurent(-t, L) * 0.999999\n", + "Q = Q_generation(P)\n", + "\n", + "# 计算旋转角度,其中 theta 对应 Ry 门,phi 对应 Rz 门\n", + "list_theta, list_phi = qpp_angle_approximator(P, Q)\n", + "\n", + "cir = qpp_cir(list_theta, list_phi, U) # 构建相位处理器\n", + "cir.collapse(aux_qubits, desired_result=0, if_print=True) # 在线路末端添加解码(测量)操作\n", + "input_state = zero_state(num_block_qubits + 1).kron(rho) # 准备输入态,其中辅助比特的输入态为 |0><0|" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "qubits [0, 1, 2, 3, 4] collapse to the state |00000> with probability 0.9999974132814917\n", + "输出态与期望态的迹距离为 4.903932274526325e-07\n" + ] + } + ], + "source": [ + "# 拿到输出态并移除辅助比特,将输出态与理论值对比\n", + "output_state = partial_trace_discontiguous(cir(input_state), preserve_qubits=sys_qubits)\n", + "rho.evolve(H, t)\n", + "print(f\"输出态与期望态的迹距离为 {trace_distance(output_state, rho).item()}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "由上可见,QPP 通过相位演化,将一个 $H$ 的块编码转换为 $e^{-iHt}$ 的块编码,从而完成量子态 $\\rho_t$ 的成功制备。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 应用:量子态熵估计" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "如何计算量子态函数变换后的迹是量子熵估计的核心问题。该问题的数学设定为:已知两个量子态 $\\rho$、 $\\sigma$ 和一个函数 $f:~\\mathbb{R}_+~\\to~\\mathbb{R}$,估计 $\\text{Tr}\\left[ \\rho f \\left( \\sigma \\right) \\right]$。\n", + "\n", + "注:量子态 $\\sigma$ 的 $f$ 变换定义为 \n", + "\n", + "$$ \n", + "f(\\sigma) = \\sum_j f(q_j) | \\psi_j \\rangle \\langle \\psi_j |, \\tag{7}\n", + "$$\n", + "这里 $\\{q_j\\}$ 和 $\\{ | \\psi_j \\rangle \\}$ 分别为 $\\sigma$ 的本征值和本征态。 \n", + "\n", + "可以看到,若 $f$ 为幂函数,该问题可以用来解决量子瑞丽熵和瑞丽散度的估计;而当 $f(x) = \\log(x)$ 时,该问题则转化为量子冯诺依曼熵或相对熵的估计问题。\n", + "\n", + "QPP 的相位提取功能可以有效地解决迹估计问题,从而进一步地完成各类量子熵的近似计算。用于处理量子态的 QPP 线路如图所示:\n", + "\n", + "![qpp](figures/QPP-fig-state.png \"图 2:用于迹估计的相位处理器(层数为偶数),这里 m 为用于块编码的辅助比特数。\")\n", + "\n", + "这里作用在 AB 系统上的 $U_\\rho$ 为 $\\rho$ 的**纯化模型**,满足\n", + "\n", + "$$\n", + "\\text{Tr}_B \\left[ U_\\rho \\left( | 0 \\rangle_A \\langle 0 |_A \\otimes | 0 \\rangle_B \\langle 0 |_B \\right) U_\\rho^\\dagger \\right] = \\rho。 \\tag{8}\n", + "$$\n", + "\n", + "该模型可以用量子电路实现,所以在量子熵的研究中被广泛使用。$U_\\sigma$ 也为 $\\sigma$ 的纯化模型。不同的是,为了拿到 $\\sigma$ 的本征信息,QPP 需要将 $U_\\sigma$ 进一步转为 $\\sigma$ 的块编码 $\\widehat{U}_\\sigma$。更多内容详见论文 [[1]](https://arxiv.org/abs/2209.14278) 的第四节。\n", + "\n", + "我们将使用 QPP 模块来估计 $\\text{Tr} \\left[ \\rho \\sigma^{\\alpha - 1} \\right]$。以下是该问题的实验设定。" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "pq.set_backend(\"density_matrix\") # 切换密度矩阵后端\n", + "\n", + "rho = random_state(num_qubits) # 输入态(密度矩阵),这里我们不关注上图的 B 系统\n", + "U_sigma_hat = purification_block_enc(num_qubits, num_block_qubits) # 构建一个纯化模型的比特化块编码\n", + "sigma = State(U_sigma_hat[:2**num_qubits, :2**num_qubits]) # 通过块编码获取随机 sigma\n", + "assert is_density_matrix(sigma) == (True, num_qubits)\n", + "\n", + "alpha = np.random.rand() * 4 + 1 # 在 [1, 5) 之间随机选择 alpha\n", + "H = Hamiltonian([(1.0, \"z0\")]) # 第一个比特上的泡利-Z 可观测量\n", + "input_state = zero_state(num_block_qubits + 1).kron(rho) # 相位处理器的输入态" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "量桨 QPP 模块里的 `simulation_cir` 函数可以为 $f$ 设计适应性的相位处理器。具体地,通过找到函数 $f$ 的近似三角多项式 $F$,QPP 模块可以在机械误差下将 $F$ 转为相位处理器需要模拟的三角多项式,然后通过估算第一个比特上泡利-$Z$ 可观测量的期望值来获取最终的结果。我们可以借助 `paddle_quantum.linalg.herm_transform` 来评估模拟的精准度。\n", + "\n", + "注:函数 $f$ 需要满足 $f\\left(\\left[0, 1\\right]\\right) \\subseteq \\left[-1, 1\\right]$。" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Computations of angles for QPP are completed with mean error 2.073248366556774e-07\n", + "模拟 Tr[rho * sigma^3.522308957539911] 的误差为 2.265239344059755e-05\n" + ] + } + ], + "source": [ + "# 估计 Tr[rho * sigma^(alpha - 1)]\n", + "cir = simulation_cir(lambda x: (np.cos(x) ** 2) ** ((alpha - 1) / 2), U_sigma_hat)\n", + "val = cir(input_state).expec_val(H).item()\n", + "expect_val = paddle.trace(rho.data @ herm_transform(lambda x: x ** (alpha - 1), sigma)).real().item()\n", + "print(f\"模拟 Tr[rho * sigma^{alpha - 1}] 的误差为 {np.abs(val - expect_val)}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "由上可见,QPP 通过相位提取来完成 $\\text{Tr} \\left[ \\rho \\sigma^{\\alpha - 1} \\right]$ 的精确估计。因此,当 $\\rho = \\sigma$ 时,QPP 就可以估算 $\\rho$ 的 $\\alpha$-阶量子瑞丽熵 \n", + "\n", + "$$\n", + "S_\\alpha(\\rho) = \\frac{1}{1 - \\alpha}\\log \\text{Tr} \\left( \\rho^{\\alpha } \\right)。 \\tag{9}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 小结\n", + "\n", + "通过上述三个应用,本教程展示了 QPP 框架在酉算子、哈密顿量和量子态相关问题上的强大处理能力,以及如何用量桨的 QPP 模块去完成框架的构建和运算。我们也期望使用 QPP 框架去解决更多问题包括但不限于量子蒙特卡洛问题、酉矩阵迹估计问题以及机器学习问题。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "___\n", + "## 参考文献\n", + "\n", + "[1] Wang, Xin, et al. \"Quantum Phase Processing: Transform and Extract Eigen-Information of Quantum Systems.\" [arXiv preprint arXiv:2209.14278 (2022).](https://arxiv.org/abs/2209.14278)\n", + "\n", + "[2] Yu, Zhan, et al. \"Power and limitations of single-qubit native quantum neural networks.\" [arXiv preprint arXiv:2205.07848 (2022).](https://arxiv.org/abs/2205.07848)\n", + "\n", + "[3] Low, Guang Hao, and Isaac L. Chuang. \"Hamiltonian simulation by qubitization.\" [Quantum 3 (2019): 163.](https://quantum-journal.org/papers/q-2019-07-12-163/)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.8.13 ('pq')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "08942b1340a5932ff3a93f52933a99b0e263568f3aace1d262ffa4d9a0f2da31" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tutorials/quantum_simulation/QPP_EN.ipynb b/tutorials/quantum_simulation/QPP_EN.ipynb new file mode 100644 index 0000000..fddc2a8 --- /dev/null +++ b/tutorials/quantum_simulation/QPP_EN.ipynb @@ -0,0 +1,472 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Quantum Phase Processing\n", + "\n", + "*Copyright (c) 2022 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Overview" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Quantum Phase Processing** (QPP) is a quantum algorithmic structure purposed by the Baidu Research team [[1]](https://arxiv.org/abs/2209.14278). Such structure can provide access to the eigenphases of the target unitary, allowing phase transformation or extraction to be done in an efficient and precise manner. QPP originates from an improved technique known as **Trigonometric Quantum Signal Processing** (namely the trigonometric QSP) [[2]](https://arxiv.org/abs/2205.07848) that can simulate arbitrary trigonometric transformation of input data using only one qubit. Consequently, QPP inherits the capability of trigonometric QSP in a higher dimension. By manipulating the input unitary, QPP can retrieve its eigen-information and hence perform trigonometric transformation to each eigenphase insider the corresponding eigenspace.\n", + "\n", + "This tutorial will illustrate how to utilize QPP to resolve the problems of quantum phase estimation, Hamiltonian simulation and entropy estimation, according to the paper [[1]](https://arxiv.org/abs/2209.14278) and the idea of block encoding." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here are some necessary libraries and packages." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import warnings\n", + "warnings.filterwarnings(\"ignore\")\n", + "\n", + "import numpy as np\n", + "from scipy.linalg import expm\n", + "import paddle\n", + "\n", + "# general functions in PaddleQuantum\n", + "import paddle_quantum as pq\n", + "from paddle_quantum.ansatz import Circuit\n", + "from paddle_quantum.hamiltonian import Hamiltonian\n", + "from paddle_quantum.linalg import abs_norm, hermitian_random, unitary_random, block_enc_herm, herm_transform\n", + "from paddle_quantum.qinfo import trace_distance, partial_trace_discontiguous\n", + "from paddle_quantum.state import is_density_matrix, random_state, zero_state, State\n", + "\n", + "# functions in QPP module\n", + "from paddle_quantum.qpp import Q_generation, hamiltonian_laurent, qpp_angle_approximator, qpp_cir, qps, qubitize, purification_block_enc, simulation_cir\n", + "\n", + "# set the precision\n", + "pq.set_dtype('complex128')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Introduction of QPP Structure" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "QPP relies on a quantum circuit namely the **quantum phase processor** to deal with quantum data. For even $L \\in \\mathbb{N}$, we define the quantum phase processor of an $n$-qubit unitary $U$ as\n", + "\n", + "$$\n", + "V^L(U) := R_z^{(0)} R_y^{(0)} R_z^{(0)}\n", + "\\left[ \\prod_{l=1}^{L/2}\n", + " \\begin{bmatrix}\n", + " U^\\dagger & 0 \\\\\n", + " 0 & I^{\\otimes n}\n", + " \\end{bmatrix} R_y^{(0)} R_z^{(0)}\n", + " \\begin{bmatrix}\n", + " I^{\\otimes n} & 0 \\\\\n", + " 0 & U\n", + " \\end{bmatrix} R_y^{(0)} R_z^{(0)}\n", + "\\right],\n", + "\\tag{1}\n", + "$$\n", + "\n", + "Here $R_y^{(0)}$ and $R_z^{(0)}$ are rotation gates applied on the first qubit with tunable parameters depending on the target trigonometric polynomial. The quantum circuit of $V^L(U)$ is shown as follows:\n", + "\n", + "![qpp_circuit](figures/QPP-fig-circuit.png \"Figure 1:Quantum implementation for phase processor with even L\")\n", + "\n", + "Note:when the number of layers $L$ is odd, we define the corresponding phase processor as\n", + "\n", + "$$\n", + "V^{L}(U) = V^{L - 1}(U) \n", + " \\begin{bmatrix}\n", + " U^\\dagger & 0 \\\\\n", + " 0 & I^{\\otimes n}\n", + " \\end{bmatrix} R_y^{(0)} R_z^{(0)}. \\tag{2}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "QPP has two main functionals: **phase evolution** and **phase estimation**. Suppose we have an $n$-qubit unitary with the following spectrum decomposition\n", + "\n", + "$$\n", + "U = \\sum_{j=0}^{2^n - 1} e^{i \\tau_j} |\\chi_j \\rangle \\langle \\chi_j |. \\tag{3}\n", + "$$\n", + "\n", + "Then by **Theorem 5** in [[1]](https://arxiv.org/abs/2209.14278), for any (complex) trigonometric polynomial $F(x) = \\sum_{j = -L}^L c_j e^{ijx}$ such that $||\\textbf{c}||_1 \\leq 1$, and any quantum state $| \\psi \\rangle = \\sum_{j=0}^{2^n - 1} \\alpha_j |\\chi_j \\rangle$, there exists a quantum phase processor $V^{2L}(U)$ of $2L$ layers such that\n", + "\n", + "$$\n", + "\\left( \\langle 0 | \\otimes I^{\\otimes n} \\right) V^{2L}(U) |0, \\psi \\rangle = \\sum_{j=0}^{2^n - 1} \\alpha_j F(\\tau_j) | \\chi_j \\rangle. \\tag{4}\n", + "$$\n", + "\n", + "Further, suppose $F$ is real-valued. Then for any state $\\rho$, by **Theorem 6** in [[1]](https://arxiv.org/abs/2209.14278) there exists a quantum phase processor $V^{L}(U)$ of $L$ layers\n", + "\n", + "$$\n", + "\\text{Tr} \\left[ Z^{(0)} \\cdot V^{L}(U) \\rho V^{L}(U)^\\dagger \\right] = \\sum_{j = 0}^{2^n - 1} p_j F(\\tau_j), \\tag{5}\n", + "$$\n", + "\n", + "where $p_j = \\langle \\chi_j | \\rho | \\chi_j \\rangle$ and $Z^{(0)}$ is the Pauli-$Z$ observable acting on the first qubit. In this tutorial we wil use these two abilities to complete the eigenphase search of unitary, the real-time evolution of Hamiltonian and the trace estimation of function transformation of quantum states.\n", + "\n", + "Note: Since Hamiltonian and quantum states are not unitaries, and hence cannot be processed by QPP directly. Therefore, we need to use the **qubitized block encoding** to get the eigen-information of non-unitary data.\n", + "Besides, there is an $\\arccos$ relation between eigenphases of qubitized block encoding and eigenvalues of its encoded data. Then to perform a transformation of function $f$, QPP needs to simulate $F(x) = f(\\cos(x))$.\n", + "\n", + "See more details of block encoding in the tutorial of [Quantum Signal Processing and Quantum Singular Value Transformation](https://qml.baidu.com/tutorials/quantum-simulation/quantum-signal-processing-and-quantum-singular-value-transformation.html). The idea of qubitized block encoding is deferred to [[1]](https://arxiv.org/abs/2209.14278) and [[3]](https://quantum-journal.org/papers/q-2019-07-12-163/).\n", + " \n", + "\n", + "Here is the environment setup of this tutorial." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "num_qubits = 3 # size of main register\n", + "num_block_qubits = num_qubits + 1 # number of ancilla qubits used in block encoding\n", + "aux_qubits = list(range(num_block_qubits + 1)) # qubit indexes for auxiliary register\n", + "sys_qubits = list(range(num_block_qubits + 1, num_block_qubits + 1 + num_qubits)) # qubit indexes for main register" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Application: Quantum Phase Search" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finding eigenphases of a unitary is one of the fundamental issues in quantum computation, namely the problem of quantum phase estimation. The setup of this problem is as follows: given a unitary $U$ and its eigenstate $| \\psi \\rangle$, estimate the eigenphase corresponding to $| \\psi \\rangle$; further, if $| \\psi \\rangle$ is no longer an eigenstate of $U$, then estimate the eigenphase corresponding to a eigenstate having non-zero overlap with $| \\psi \\rangle$.\n", + "\n", + "Here is the experimental setup of this problem." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "pq.set_backend('state_vector') # switch to state vector backend\n", + "\n", + "U = unitary_random(num_qubits) # input unitary\n", + "psi = random_state(num_qubits) # input state (vector)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "QPP can simulate ladder function i.e.\n", + "\n", + "$$\n", + "f(x) = \\begin{cases}\n", + " 1 & \\textrm{if }\\, x \\geq 0 \\\\\n", + " 0 & \\textrm{if }\\, x < 0\n", + "\\end{cases}. \\tag{6}\n", + "$$\n", + "\n", + "Through indirect measurements, binary searches are applied to locate a small interval containing an eigenphase of $U$; this interval is then expanded such that binary search can be used again. Such method is called the **quantum phase search** (QPS) algorithm. Compared with conventional QPE algorithm, QPS can achieve exponential enhancement on the success probability, under same precision and resource usage. Details of QPS is deferred to section 2 of paper [[1]](https://arxiv.org/abs/2209.14278).\n", + "\n", + "The QPP module of Paddle Quantum has a built-in function `qps` that can realize the QPS algorithm. We can compare the experimental result with theoretical one to verify the correction of this method." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Computations of angles for QPP are completed with mean error 1.3084730192565284e-07\n", + "The searching error for the QPS algorithm is 1.4529266689268915e-11\n", + "The overlap between input and output states is 0.6462206013583379\n" + ] + } + ], + "source": [ + "# Use QPS algorithm to retrieve an eigenphase and its output state\n", + "phase_estimate, output_state = qps(U, psi)\n", + "\n", + "# Compute the eigenphase corresponding to the output state\n", + "phase_expect = np.log((output_state.bra @ U @ output_state.ket).item()) / 1j\n", + "\n", + "print(f\"The searching error for the QPS algorithm is {np.abs(phase_expect - phase_estimate)}\")\n", + "print(f\"The overlap between input and output states is {abs_norm(output_state.bra @ psi.ket)}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As shown above, despite that $| \\psi \\rangle$ is not an eigenstate of $U$, we can still find an eigenphase and its corresponding eigenstate having non-zero overlap with $| \\psi \\rangle$." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Application: Hamiltonian Simulation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The time evolution of an $n$-qubit quantum system is decided by a Hamiltonian $H$ (a $2^n \\times 2^n$ Hermitian matrix acting on $n$ qubits) and an initial state $\\rho$. The quantum state of this system at time $t$ can be expressed as $\\rho_t = e^{-iHt} \\rho e^{iHt}$, where $e^{-iHt}$ is the evolution operator at time $t$. Then the problem of Hamiltonian simulation can be formulated as follows: given a block encoding of the Hamiltonian of a quantum system and its initial state $\\rho$, prepare the quantum state $\\rho_t$ of this system at time $t$.\n", + "\n", + "Here is the experimental setup of this problem." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "pq.set_backend(\"density_matrix\") # switch to density matrix backend\n", + "\n", + "H = hermitian_random(num_qubits) # Hamiltonian of quantum system\n", + "U = block_enc_herm(H, num_block_qubits) # qubitized block encoding of the Hamiltonian\n", + "rho = random_state(num_qubits) # initial state\n", + "t = 9 # evolution time\n", + "L = 40 # number of layers of quantum phase processor i.e. degree of simulation precision" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In QPP module, from the [Jacobi-Anger expansion](https://en.wikipedia.org/wiki/Jacobi%E2%80%93Anger_expansion), function `hamiltonian_laurent` can provide a trigonometric polynomial $P$ approximating the evolution function. Then we can use `Q_generation` to calculate its polynomial complement $Q$ (that satisfies $PP^* + QQ^* = 1$). After estimating the angles for rotation gates by `qpp_angle_approximator`, `qpp_cir` will eventually give a quantum realization of the quantum phase processor." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Computations of angles for QPP are completed with mean error 3.6991674515121774e-07\n" + ] + } + ], + "source": [ + "# Prepare the trigonometric poly approximating the evolution function, and its complement;\n", + "# here we multiply P by constant slightly smaller than 1 to ensure the computation of Q\n", + "P = hamiltonian_laurent(-t, L) * 0.999999\n", + "Q = Q_generation(P)\n", + "\n", + "# Compute the rotation angles, where theta/phi corresponds to Ry/Rz gates\n", + "list_theta, list_phi = qpp_angle_approximator(P, Q)\n", + "\n", + "cir = qpp_cir(list_theta, list_phi, U) # construct quantum phase processor构建相位处理器\n", + "cir.collapse(aux_qubits, desired_result=0, if_print=True) # decoding (measurement) of the block encoding \n", + "input_state = zero_state(num_block_qubits + 1).kron(rho) # prepare the input state, where input state for aux reg is |0><0|" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "qubits [0, 1, 2, 3, 4] collapse to the state |00000> with probability 0.9999982182557698\n", + "The trace distance between output and expected states is 5.304595279602356e-07\n" + ] + } + ], + "source": [ + "# Get the output state, remove the aux qubits, and compare the output state with the expected one\n", + "output_state = partial_trace_discontiguous(cir(input_state), preserve_qubits=sys_qubits)\n", + "rho.evolve(H, t)\n", + "print(f\"The trace distance between output and expected states is {trace_distance(output_state, rho).item()}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As shown above, through phase evolution, QPP transform a block encoding of $H$ to a block encoding of $e^{-iHt}$, so that $\\rho_t$ is successfully prepared." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Application: Estimation of Quantum Entropies" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Trace computation of function transformation of quantum states is the core component of quantum entropy estimation. The mathematical setting of this problem is as follows: given two quantum states $\\rho, \\sigma$ and a function $f:~\\mathbb{R}_+~\\to~\\mathbb{R}$, estimate the quantity $\\text{Tr}\\left[ \\rho f \\left( \\sigma \\right) \\right]$. \n", + "\n", + "Note:$f$ transformation of quantum state $\\sigma$ is defined as \n", + "\n", + "$$ \n", + "f(\\sigma) = \\sum_j f(q_j) | \\psi_j \\rangle \\langle \\psi_j |, \\tag{7}\n", + "$$\n", + "\n", + "where $\\{q_j\\}$ and $\\{ | \\psi_j \\rangle \\}$ are eigenvalues and eigenstates of $\\sigma$, respectively.\n", + "\n", + "We can observe that, if $f$ is a power function, then the solution of this problem can estimate quantum Rényi entropies and Rényi divergences; if $f(x) = \\log(x)$, such problem is equivalent to the estimation of quantum Von Neumann or relative entropies.\n", + "\n", + "QPP can efficiently solve the trace estimation problem by phase estimation, so that serval quantum entropies can be estimated. The quantum circuit is shown as follows:\n", + "\n", + "![qpp](figures/QPP-fig-state.png \"Figure 2: quantum phase processor used for trace estimation. Here m is the number of ancilla qubits for block encoding.\")\n", + "\n", + "Here $U_\\rho$ acting on AB systems is the **purification model** of $\\rho$, satisfying\n", + "\n", + "$$\n", + "\\text{Tr}_B \\left[ U_\\rho \\left( | 0 \\rangle_A \\langle 0 |_A \\otimes | 0 \\rangle_B \\langle 0 |_B \\right) U_\\rho^\\dagger \\right] = \\rho. \\tag{8}\n", + "$$\n", + "\n", + "Such model can be realized by quantum realized, and are frequently used in the study of quantum entropies. $U_\\sigma$ is also the purification model of $\\sigma$. However, to obtain the eigen-information of $\\sigma$, QPP further transforms $U_\\sigma$ to the block encoding $\\widehat{U}_\\sigma$ of $\\sigma$. See more details in section 4 of paper [[1]](https://arxiv.org/abs/2209.14278).\n", + "\n", + "We will use above circuit to estimate $\\text{Tr} \\left[ \\rho \\sigma^{\\alpha - 1} \\right]$. Here is the experimental setup of this problem." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "pq.set_backend(\"density_matrix\") # switch to density matrix backend\n", + "\n", + "rho = random_state(num_qubits) # quantum state rho, here we don't care about the system B\n", + "U_sigma_hat = purification_block_enc(num_qubits, num_block_qubits) # construct a qubitized block encoding of (random) purification model\n", + "sigma = State(U_sigma_hat[:2**num_qubits, :2**num_qubits]) # obtain sigma by block encoding\n", + "assert is_density_matrix(sigma) == (True, num_qubits)\n", + "\n", + "alpha = np.random.rand() * 4 + 1 # randomly select alpha in [1, 5)\n", + "H = Hamiltonian([(1.0, \"z0\")]) # Pauli-Z observable acting on the first qubit\n", + "input_state = zero_state(num_block_qubits + 1).kron(rho) # input state for the phase processor" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The built-in function `simulation_cir` in QPP module can design adaptive phase processor for function $f$. In particular, by finding the trigonometric polynomial $F$ approximating the function $f$. QPP module can transform $F$ to the trigonometric polynomial that phase processor needs to simulate, under machinery error. Then the final result can be obtained by computing the expectation value of Pauli-Z observable acting on the first qubit. We can utilize `paddle_quantum.linalg.herm_transform` to assess the simulation precision.\n", + "\n", + "Note: function $f$ needs to satisfy $f\\left(\\left[0, 1\\right]\\right) \\subseteq \\left[-1, 1\\right]$." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Computations of angles for QPP are completed with mean error 4.448551001234416e-06\n", + "The estimation error for Tr[rho * sigma^1.4747437820674594] is 0.0022607517544651345\n" + ] + } + ], + "source": [ + "# Estimate Tr[rho * sigma^(alpha - 1)]\n", + "cir = simulation_cir(lambda x: (np.cos(x) ** 2) ** ((alpha - 1) / 2), U_sigma_hat)\n", + "val = cir(input_state).expec_val(H).item()\n", + "expect_val = paddle.trace(rho.data @ herm_transform(lambda x: x ** (alpha - 1), sigma)).real().item()\n", + "print(f\"The estimation error for Tr[rho * sigma^{alpha - 1}] is {np.abs(val - expect_val)}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As shown above, through phase estimation, QPP can precisely estimate $\\text{Tr} \\left[ \\rho \\sigma^{\\alpha - 1} \\right]$. Therefore, when $\\rho = \\sigma$, QPP is capable to estimate the $\\alpha$-Rényi entropy of $\\rho$, defined as\n", + "\n", + "$$\n", + "S_\\alpha(\\rho) = \\frac{1}{1 - \\alpha}\\log \\text{Tr} \\left( \\rho^{\\alpha } \\right). \\tag{9}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Conclusion\n", + "\n", + "Through above applications, this tutorial demonstrates that QPP structure is capable of solving problems of unitaries, Hamiltonians and quantum states. Other than applications mentioned in this tutorial, we expect to use such framework to QPP can be potentially applied to other problems, including but not limited to problems of quantum Monte Carlo, unitary trace estimation and machine learning." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "___\n", + "## Reference\n", + "\n", + "[1] Wang, Xin, et al. \"Quantum Phase Processing: Transform and Extract Eigen-Information of Quantum Systems.\" [arXiv preprint arXiv:2209.14278 (2022).](https://arxiv.org/abs/2209.14278)\n", + "\n", + "[2] Yu, Zhan, et al. \"Power and limitations of single-qubit native quantum neural networks.\" [arXiv preprint arXiv:2205.07848 (2022).](https://arxiv.org/abs/2205.07848)\n", + "\n", + "[3] Low, Guang Hao, and Isaac L. Chuang. \"Hamiltonian simulation by qubitization.\" [Quantum 3 (2019): 163.](https://quantum-journal.org/papers/q-2019-07-12-163/)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.8.13 ('pq')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "08942b1340a5932ff3a93f52933a99b0e263568f3aace1d262ffa4d9a0f2da31" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tutorials/quantum_simulation/QSP_and_QSVT_CN.ipynb b/tutorials/quantum_simulation/QSP_and_QSVT_CN.ipynb index 6e126ee..06c9bd6 100644 --- a/tutorials/quantum_simulation/QSP_and_QSVT_CN.ipynb +++ b/tutorials/quantum_simulation/QSP_and_QSVT_CN.ipynb @@ -38,7 +38,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -116,16 +116,9 @@ "当 $A$ 是酉矩阵时,我们则可以选择 $U = A \\oplus I^{\\otimes (m - n)}$,即 $U$ 是受控的 $A$。特别地,文献[[3]](http://arxiv.org/abs/2203.10236) [[4]](http://arxiv.org/abs/2206.03505)给出了一些使用量子电路实现块编码的方案。" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 量桨实现" - ] - }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -161,23 +154,16 @@ "解码的成功概率取决于测量到 $0^{\\otimes (m - n)}$ 的几率,其会随着 $m - n$ 的增长而指数性下降。然而,若我们可以控制 $m - n$ 的大小,那么这就不再是一个问题。在本教程中我们会假设 $m = n + 1$." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 量桨实现" - ] - }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "qubits [0] collapse to the state |0> with probability 0.08025970130578351\n" + "qubits [0] collapse to the state |0> with probability 0.24548491835594177\n" ] } ], @@ -191,11 +177,11 @@ "input_state = paddle_quantum.State(paddle.kron(zero_state @ dagger(zero_state), rho))\n", "\n", "# 定义辅助寄存器\n", - "aux_register = [i for i in range(num_qubits - num_block_qubits)]\n", + "aux_register = list(range(num_qubits - num_block_qubits))\n", "\n", "# 创建线路\n", "cir = Circuit(num_qubits)\n", - "cir.oracle(U, [i for i in range(num_qubits)])\n", + "cir.oracle(U, list(range(num_qubits)))\n", "cir.collapse(aux_register, desired_result='0', if_print = True) # 调用塌缩算子\n", "\n", "# 获取输出态及输出 rho\n", @@ -212,14 +198,14 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "期望 rho 和 输出 rho 的误差是 8.008999270740103e-08\n" + "期望 rho 和 输出 rho 的误差是 0.0\n" ] } ], @@ -229,13 +215,6 @@ "print(f\"期望 rho 和 输出 rho 的误差是 {paddle.norm(paddle.abs(expect_rho - output_rho)).item()}\")" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 特例 ($m = 1$)" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -283,7 +262,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ @@ -306,13 +285,6 @@ "值得注意的是,$W_\\Phi$ 可以模拟切比雪夫多项式变换。对于次数为 $k$ 的第一类切比雪夫多项式,其对应的角度矢量为 $(0, \\pi, ..., \\pi)$ (如 $k$ 为偶数)或 $(\\pi, ..., \\pi)$ (如 $k$ 为奇数)." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 量桨实现" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -322,7 +294,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 22, "metadata": {}, "outputs": [ { @@ -333,16 +305,6 @@ " [ 3.14159265, 1.39460474, -0.44313783, 1.09757975, -1.09757975,\n", " 0.44313783, -1.39460474, 3.14159265])\n" ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "c:\\users\\v_zhanglei48\\baidu\\personal-code\\pq\\paddle_quantum\\QSVT\\qsp.py:242: ComplexWarning: Casting complex values to real discards the imaginary part\n", - " Phi[i] = np.log(P.coef[n] / Q.coef[m]) * -1j / 2\n", - "c:\\users\\v_zhanglei48\\baidu\\personal-code\\pq\\paddle_quantum\\QSVT\\qsp.py:256: ComplexWarning: Casting complex values to real discards the imaginary part\n", - " Phi[0] = -1j * np.log(P.coef[0])\n" - ] } ], "source": [ @@ -360,16 +322,16 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "--Rz(-6.28)----Rx(-2.21)----Rz(2.789)----Rx(-2.21)----Rz(-0.88)----Rx(-2.21)----Rz(2.195)----Rx(-2.21)----Rz(-2.19)----Rx(-2.21)----Rz(0.886)----Rx(-2.21)----Rz(-2.78)----Rx(-2.21)----Rz(-6.28)--\n", + "--Rz(-6.28)----Rx(-2.73)----Rz(2.789)----Rx(-2.73)----Rz(-0.88)----Rx(-2.73)----Rz(2.195)----Rx(-2.73)----Rz(-2.19)----Rx(-2.73)----Rz(0.886)----Rx(-2.73)----Rz(-2.78)----Rx(-2.73)----Rz(-6.28)--\n", " \n", - "模拟 P(x) 的误差是 2.931881168672019e-08\n" + "模拟 P(x) 的误差是 1.7893723625681406e-08\n" ] } ], @@ -415,7 +377,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 24, "metadata": {}, "outputs": [ { @@ -603,13 +565,6 @@ "换句话说,当 $W = V$ 时,QSVT 将一个 $A$ 的块编码转为了一个 $P(A)$ 的块编码。" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 量桨实现" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -619,7 +574,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 25, "metadata": {}, "outputs": [], "source": [ @@ -628,18 +583,9 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 26, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "c:\\Users\\v_zhanglei48\\Anaconda3\\envs\\personal-code\\lib\\site-packages\\paddle\\fluid\\dygraph\\math_op_patch.py:276: UserWarning: The dtype of left and right variables are not the same, left dtype is paddle.float64, but right dtype is paddle.float32, the right dtype will convert to paddle.float64\n", - " warnings.warn(\n" - ] - } - ], + "outputs": [], "source": [ "# 找到 P(A) 及\n", "# find P(A) and its expected eigenvalues, note that they are computed in different ways\n", @@ -654,7 +600,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 27, "metadata": {}, "outputs": [ { @@ -662,8 +608,8 @@ "output_type": "stream", "text": [ "模拟 P(X) 的误差\n", - " 最大绝对值, 8.429041888826793e-08\n", - " 百分比, 6.291585659021523e-07\n" + " 最大绝对值, 1.450928305889582e-07\n", + " 百分比, 3.370838085602552e-07\n" ] } ], @@ -675,7 +621,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -683,8 +629,8 @@ "output_type": "stream", "text": [ "模拟 P(X) 的本征值误差\n", - " 最大绝对值, 1.0894675602300946e-07\n", - " 百分比, 5.209560480945378e-07\n" + " 最大绝对值, 1.8375562631798232e-07\n", + " 百分比, 2.776073800450616e-07\n" ] } ], @@ -714,13 +660,6 @@ "![U_Phi](figures/QSVT-fig-U_Phi.png \"图 2: QSVT 的量子实现,这里 k 是 P 的多项式次数\")" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 量桨实现" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -730,7 +669,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 29, "metadata": {}, "outputs": [], "source": [ @@ -745,14 +684,14 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "期望量子态和实际量子态的差距是 2.253552555988302e-07\n" + "期望量子态和实际量子态的差距是 3.0184617834444857e-07\n" ] } ], @@ -802,13 +741,6 @@ "我们可得,对于多项式 $P$ 的 $\\mathcal{X}$ 的量子奇异值变换是 $B := \\frac{1}{\\sin(\\frac{\\pi}{2k})} A$ 的块编码。" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 量桨实现" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -818,7 +750,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 31, "metadata": {}, "outputs": [], "source": [ @@ -832,14 +764,14 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "QSVT 的精确值为 3.3605192584218457e-07\n" + "QSVT 的精确值为 3.1799856969882967e-07\n" ] } ], @@ -893,7 +825,7 @@ "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "1e82098cfee7be27b5e385e3f85fe91d734d6114f7d09dccafdaad2c23171c3e" + "hash": "08942b1340a5932ff3a93f52933a99b0e263568f3aace1d262ffa4d9a0f2da31" } } }, diff --git a/tutorials/quantum_simulation/QSP_and_QSVT_EN.ipynb b/tutorials/quantum_simulation/QSP_and_QSVT_EN.ipynb index 461fd3a..4d5bb52 100644 --- a/tutorials/quantum_simulation/QSP_and_QSVT_EN.ipynb +++ b/tutorials/quantum_simulation/QSP_and_QSVT_EN.ipynb @@ -37,7 +37,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -121,7 +121,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -155,23 +155,16 @@ "The success probability of decoding is the probability of measuring $0^{\\otimes (m - n)}$, which can be exponentially small as $m - n$ increases. However, this would no longer be a problem if we can control the size of first register. In this tutorial we will assume $m = n + 1$." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Realization in PaddleQuantum" - ] - }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "qubits [0] collapse to the state |0> with probability 0.10231761176954456\n" + "qubits [0] collapse to the state |0> with probability 0.25072506070137024\n" ] } ], @@ -185,11 +178,11 @@ "input_state = paddle_quantum.State(paddle.kron(zero_state @ dagger(zero_state), rho))\n", "\n", "# define auxiliary register\n", - "aux_register = [i for i in range(num_qubits - num_block_qubits)]\n", + "aux_register = list(range(num_qubits - num_block_qubits))\n", "\n", "# construct the circuit\n", "cir = Circuit(num_qubits)\n", - "cir.oracle(U, [i for i in range(num_qubits)])\n", + "cir.oracle(U, list(range(num_qubits)))\n", "cir.collapse(aux_register, desired_result='0', if_print = True) # call Collapse operator\n", "\n", "# get output_state and actual output rho\n", @@ -206,14 +199,14 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "the difference between input and output is 1.1947226861933412e-07\n" + "the difference between input and output is 0.0\n" ] } ], @@ -223,13 +216,6 @@ "print(f\"the difference between input and output is {paddle.norm(paddle.abs(expect_rho - output_rho)).item()}\")" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Special Case ($m = 1$)" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -277,7 +263,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ @@ -300,13 +286,6 @@ "Note that such structure of $W_\\Phi$ naturally fits the family of Chebyshev polynomials. Indeed, for a Chebyshev polynomials of first kind with order $k$, its corresponding $\\Phi$ is $(0, \\pi, ..., \\pi)$ (if $k$ is even) or $(\\pi, ..., \\pi)$ (if $k$ is odd). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Realization in PaddleQuantum" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -316,7 +295,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 22, "metadata": {}, "outputs": [ { @@ -327,16 +306,6 @@ " [ 3.14159265, 1.39460474, -0.44313783, 1.09757975, -1.09757975,\n", " 0.44313783, -1.39460474, 3.14159265])\n" ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "c:\\users\\v_zhanglei48\\baidu\\personal-code\\pq\\paddle_quantum\\QSVT\\qsp.py:242: ComplexWarning: Casting complex values to real discards the imaginary part\n", - " Phi[i] = np.log(P.coef[n] / Q.coef[m]) * -1j / 2\n", - "c:\\users\\v_zhanglei48\\baidu\\personal-code\\pq\\paddle_quantum\\QSVT\\qsp.py:256: ComplexWarning: Casting complex values to real discards the imaginary part\n", - " Phi[0] = -1j * np.log(P.coef[0])\n" - ] } ], "source": [ @@ -354,16 +323,16 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "--Rz(-6.28)----Rx(-1.11)----Rz(2.789)----Rx(-1.11)----Rz(-0.88)----Rx(-1.11)----Rz(2.195)----Rx(-1.11)----Rz(-2.19)----Rx(-1.11)----Rz(0.886)----Rx(-1.11)----Rz(-2.78)----Rx(-1.11)----Rz(-6.28)--\n", + "--Rz(-6.28)----Rx(-1.74)----Rz(2.789)----Rx(-1.74)----Rz(-0.88)----Rx(-1.74)----Rz(2.195)----Rx(-1.74)----Rz(-2.19)----Rx(-1.74)----Rz(0.886)----Rx(-1.74)----Rz(-2.78)----Rx(-1.74)----Rz(-6.28)--\n", " \n", - "the error of simulating P(x) is 2.1200956324443587e-07\n" + "the error of simulating P(x) is 6.378721218542117e-08\n" ] } ], @@ -409,7 +378,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 24, "metadata": {}, "outputs": [ { @@ -596,13 +565,6 @@ "That is, when $W = V$, QSVT maps a block encoding of $A$ to a block encoding of $P(A)$." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Realization in PaddleQuantum" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -612,38 +574,18 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 25, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "c:\\Users\\v_zhanglei48\\Desktop\\QSVT 教程\\qsp.py:242: ComplexWarning: Casting complex values to real discards the imaginary part\n", - " Phi[i] = np.log(P.coef[n] / Q.coef[m]) * -1j / 2\n", - "c:\\Users\\v_zhanglei48\\Desktop\\QSVT 教程\\qsp.py:256: ComplexWarning: Casting complex values to real discards the imaginary part\n", - " Phi[0] = -1j * np.log(P.coef[0])\n" - ] - } - ], + "outputs": [], "source": [ "qsvt = QSVT(P, U, num_block_qubits)" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 26, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "c:\\Users\\v_zhanglei48\\Anaconda3\\envs\\personal-code\\lib\\site-packages\\paddle\\fluid\\dygraph\\math_op_patch.py:276: UserWarning: The dtype of left and right variables are not the same, left dtype is paddle.float64, but right dtype is paddle.float32, the right dtype will convert to paddle.float64\n", - " warnings.warn(\n" - ] - } - ], + "outputs": [], "source": [ "# find P(A) and its expected eigenvalues, note that they are computed in different ways\n", "expect_PX = poly_matrix(P, A).numpy()\n", @@ -657,7 +599,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 27, "metadata": {}, "outputs": [ { @@ -665,8 +607,8 @@ "output_type": "stream", "text": [ "error of simulating P(X)\n", - " maximum absolute, 1.1376122748011288e-07\n", - " percentage, 6.770728859410114e-07\n" + " maximum absolute, 1.6997650495437753e-07\n", + " percentage, 3.4201093195057237e-07\n" ] } ], @@ -678,7 +620,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -686,8 +628,8 @@ "output_type": "stream", "text": [ "error of eigenvalues of simulating P(X)\n", - " maximum absolute, 1.113571654238586e-07\n", - " percentage, 6.064903308479878e-07\n" + " maximum absolute, 2.3308557146996258e-07\n", + " percentage, 2.2962108806419593e-07\n" ] } ], @@ -717,13 +659,6 @@ "![U_Phi](figures/QSVT-fig-U_Phi.png \"Figure 2: Quantum Circuit for QSVT, where k is the degree of P\")" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Realization in PaddleQuantum" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -733,7 +668,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 29, "metadata": {}, "outputs": [], "source": [ @@ -748,14 +683,14 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "the different between expected and actual state is 1.6115462390639646e-07\n" + "the different between expected and actual state is 2.383485634049416e-07\n" ] } ], @@ -805,13 +740,6 @@ "implies that the QSVT of $\\mathcal{X}$ in terms of polynomial $P$ is a block encoding of $B := \\frac{1}{\\sin(\\frac{\\pi}{2k})} A$, as required." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Realization in PaddleQuantum" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -821,7 +749,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 31, "metadata": {}, "outputs": [], "source": [ @@ -835,14 +763,14 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "the accuracy of quantum singular value transformation is 2.805196857025294e-07\n" + "the accuracy of quantum singular value transformation is 3.029211939065135e-07\n" ] } ], @@ -896,7 +824,7 @@ "orig_nbformat": 4, "vscode": { "interpreter": { - "hash": "1e82098cfee7be27b5e385e3f85fe91d734d6114f7d09dccafdaad2c23171c3e" + "hash": "08942b1340a5932ff3a93f52933a99b0e263568f3aace1d262ffa4d9a0f2da31" } } }, diff --git a/tutorials/quantum_simulation/VariationalQM_CN.ipynb b/tutorials/quantum_simulation/VariationalQM_CN.ipynb new file mode 100644 index 0000000..9b74344 --- /dev/null +++ b/tutorials/quantum_simulation/VariationalQM_CN.ipynb @@ -0,0 +1,609 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 变分量子精密测量" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Copyright (c) 2022 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 概览" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "量子精密测量通过利用量子理论(如量子纠缠)来研究如何高精度和高灵敏度测量物理参数,其理论方面为量子参数估计理论,应用方面为量子传感。已有研究表明,利用量子理论估计的参数精度相较于经典方法有开根号的提升 [1-3]。对于一个未知参数,量子精密测量的目标就是最大化参数估计精度的同时最小化所需要的资源(如时间、量子比特数等)。\n", + "\n", + "例如,给定一个酉算子 $e^{-i\\phi H}$,其中 $H$ 是给定的哈密顿量,那么如何用量子精密测量的方法估计未知参数 $\\phi$ 呢?主要包括以下四步:\n", + "1. 初始化:制备系统初始输入态 $|\\psi\\rangle$;\n", + "2. 参数化:输入态在 $e^{-i\\phi H}$ 的演化下得到参数化的量子态 $e^{-i\\phi H}|\\psi\\rangle$;\n", + "3. 测量:测量输入态经过含有未知参数演化后得到的输出态;\n", + "4. 经典估计:根据多次测量的结果估计未知参数的值。\n", + "\n", + "结合量子参数估计理论的知识,本教程根据 [4] 中变分量子传感的思想,利用量桨构建变分量子电路训练损失函数,得到能够估计服从正态分布的参数的传感器,即优化后的量子电路。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 参数估计理论" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 经典参数估计" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "经典参数估计,如最大似然估计(maximum-likelihood estimator, MLE),通过利用多个样本来计算包含未知参数信息的数据,即给定一个含有未知参数 $\\phi$ 的概率分布,$f$ 为概率密度函数,${\\bf X}=\\{X_1,X_2,...,X_N\\}$ 为 $N$ 个独立同分布的样本数据,利用 MLE 得到 $\\phi$ 的估计值 $\\hat\\phi$:\n", + "\n", + "$$\n", + "\\hat\\phi({\\bf X})=\\arg\\max_{\\phi}\\prod_i^Nf(X_i,\\phi), \\tag{1}\n", + "$$\n", + "\n", + "即求一个 $\\phi$ 使得 $X_i(i=1,...,N)$ 同时出现的概率最大。在得到估计的参数后,如何衡量估计得到的参数与实际参数的差距呢?即如何衡量估计参数的精度?参数估计理论中一般利用均方误差(mean squared error, MSE)来衡量这一精度。\n", + "\n", + "含有未知参数 $\\bf{\\phi}$ 的样本为 ${\\bf{X}}=\\{X_1,X_2,...,X_N\\}\\in \\mathcal F^N$,${\\mathcal F}^N$ 为样本空间,假设 $\\hat{\\phi}({\\bf X}):{\\mathcal F}^N\\rightarrow\\Phi$ 为估计 $\\phi\\in\\Phi$ 的估计器($\\Phi$ 为参数空间),则 $\\hat{\\phi}({\\bf X})$ 关于 $\\phi$ 的均方误差定义为\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + "\\rm{MSE}&=E[(\\hat{\\phi}({\\bf X})-\\phi)^2]\\\\\n", + "&=\\sum_{{\\bf X}\\in {\\mathcal F}^N}f({\\bf X};\\phi)(\\hat{\\phi}({\\bf X})-\\phi)^2, \\tag{2}\n", + "\\end{aligned}\n", + "$$\n", + "\n", + "其中 $f({\\bf X};\\phi)$ 为给定参数后的得到当前样本 $\\bf X$ 的概率密度。尽管不同的估计器会影响 MSE 的值,但不论 $\\hat{\\phi}({\\bf X})$ 的选择如何,都有 ${\\rm{MSE}}\\geq\\frac{1}{N{\\mathcal I}(\\phi)}$,该式被称为 Cramér–Rao (CR) 界 [2],其中 ${\\mathcal I}(\\phi)$ 为费舍信息,用于描述参数变化对分布影响的物理量(关于费舍信息在量桨上的应用可参见教程[量子费舍信息](https://qml.baidu.com/tutorials/qnn-research/quantum-fisher-information.html))。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 量子参数估计" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "在量子参数估计中,经典参数估计中利用的一组样本变成了待测的量子态 $\\rho_{\\phi}\\in{\\mathcal F}({\\mathcal H})$,其中 $\\phi$ 为未知参数,${\\mathcal F}({\\mathcal H})$ 表示希尔伯特空间 $\\mathcal H$ 上的密度算子集。根据量子精密测量的四步及文献 [4],假设初始输入态为 $|0\\rangle$,估计器为 $\\hat{\\phi}(m)$($m$ 与测量结果有关,例如为测量得到的比特串中 1 和 0 的个数差),其关于待估计参数 $\\phi$ 的均方误差为\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + "{\\rm MSE}&=E[(\\hat{\\phi}(m)-\\phi)^2]\\\\\n", + "&=\\sum_m(\\hat{\\phi}(m)-\\phi)^2p(m|\\phi),\n", + "\\end{aligned} \\tag{3}\n", + "$$\n", + "\n", + "其中 $p(m|\\phi)$ 为给定参数 $\\phi$ 时测量得到 $m$ 的概率。同样的,不论 $\\hat{\\phi}(m)$ 如何选择,有量子 CR 界 ${\\rm{MSE}}\\geq\\frac{1}{NF(\\phi)}$,其中 $N$ 为重复测量 $\\rho_\\phi$ 的次数,$F(\\phi)$ 为量子费舍信息(关于量子费舍信息在量桨上的应用可参见教程[量子费舍信息](https://qml.baidu.com/tutorials/qnn-research/quantum-fisher-information.html))。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 变分量子传感" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "量子传感属于量子精密测量的应用,本教程依据文献 [4],主要介绍一类变分拉姆塞干涉仪。传统的拉姆塞干涉仪 [2](如图 1)是一种利用磁共振现象测量粒子跃迁频率的粒子干涉测量法,被用于测量未知参数;变分拉姆塞干涉仪 [6](如图 2)是在电路编码和解码部分设置两个参数化量子电路(记为 $U_{\\rm{En}}(\\theta_{\\rm En}), U_{\\rm{De}}(\\theta_{\\rm{De}})$),用于设置纠缠和测量量子态。已有研究表明,结合量子理论(如量子纠缠),估计参数的精度由 $O(\\frac{1}{\\sqrt N})$ 提高到 $O(\\frac{1}{N})$ [1-3],而通过变分的方式可以有效地找到合适的纠缠方式。\n", + "\n", + "![Ramsey_interferomertry](./figures/QM-fig-RI.png \"图1:拉姆塞干涉仪。\")\n", + "\n", + "图 1 所示为拉姆塞干涉仪估计参数的过程 [2]。左图是拉姆塞干涉仪的经典设定方式,右图为使用了量子纠缠的拉姆塞干涉仪。相比于经典设定,使用量子纠缠后的干涉仪在估计未知参数的精度上有开根号的优势。\n", + "\n", + "![V_Ramsey_interferomertry](./figures/QM-fig-V_RI3.png \"图2:变分拉姆塞干涉仪。\")\n", + "\n", + "图 2 所示为变分拉姆塞干涉仪。其中两个参数化量子电路通过优化找到电路有效的纠缠方式。\n", + "\n", + "下面我们利用量桨搭建参数化量子电路,来研究利用变分拉姆塞干涉仪估计的服从正态分布的参数的精度。主要分为以下三步:\n", + "1. 初始化;\n", + "2. 评估;\n", + "3. 优化。\n", + "\n", + "参数服从的正态分布的概率密度函数为:\n", + "\n", + "$$\n", + "f(x)=\\frac{1}{\\sqrt{2\\pi}\\nu}\\exp(-\\frac{(x-\\mu)^2}{2\\nu^2}), \\tag{4}\n", + "$$\n", + "\n", + "$\\mu$ 为均值,$\\nu^2$ 为方差。此时变分拉姆塞干涉仪的损失函数为:\n", + "\n", + "$$\n", + "C(\\theta_{\\rm En},\\theta_{\\rm De},a)=\\int d\\phi f(\\phi){\\rm{MSE}}(\\phi), \\tag{5}\n", + "$$\n", + "\n", + "其中选择的估计器为 $\\hat\\phi(m)=am$,$a$ 为需要优化的参数,$m$ 为测量得到的比特串中 1 和 0 的个数差,MSE 为 ${\\rm MSE}(\\phi)=\\sum_m(\\hat{\\phi}(m)-\\phi)^2p_{\\theta}(m|\\phi)$,$\\theta=(\\theta_{\\rm En},\\theta_{\\rm De})$。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1. 初始化" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- 设置 $|0\\rangle$ 为初始输入态;\n", + "- 设置编码和解码部分的参数化量子电路 $U_{\\rm{En}},U_{\\rm{De}}$;\n", + "- 将未知参数编码至电路中。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "我们在量桨中实现上述过程,首先引入需要的包:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2022-11-04T07:07:36.541872Z", + "start_time": "2022-11-04T07:07:32.740301Z" + } + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "from math import exp, pi\n", + "import matplotlib.pyplot as plt\n", + "from typing import Optional, Tuple, List\n", + "\n", + "import paddle\n", + "import paddle_quantum as pq\n", + "from paddle_quantum.ansatz import Circuit\n", + "from paddle_quantum.loss import Measure\n", + "\n", + "pq.set_backend('state_vector')\n", + "pq.set_dtype('complex128')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "接下来我们构建 $N$ 量子比特的参数化量子电路完成初始化操作。\n", + "\n", + "整个电路包括以下五部分:\n", + "- $R_y^{\\otimes N}(\\frac{\\pi}{2})$ 门;\n", + "- 编码电路 $U_{\\rm{En}}(\\theta_{\\rm{En}})$;\n", + "- 含有未知参数的 $R_z^{\\otimes N}(\\phi)=e^{-i\\phi J_z}$,其中 $J_z=\\frac{1}{2}\\sum_{k=1}^N\\sigma_z^{(k)}$, $\\sigma_z^{(k)}$ 表示作用在第 $k$ 个量子比特上的泡利 $Z$ 算符;\n", + "- 解码电路 $U_{\\rm{De}}(\\theta_{\\rm{De}})$;\n", + "- $R_x^{\\otimes N}(\\frac{\\pi}{2})$ 门。\n", + "\n", + "因此整个电路的酉算子可以由\n", + "$$\n", + "U(\\phi,\\theta_{\\rm{En}},\\theta_{\\rm{De}})=R_x^{\\otimes N}(\\frac{\\pi}{2})U_{\\rm{De}}(\\theta_{\\rm{De}})R_z^{\\otimes N}(\\phi)U_{\\rm{En}}(\\theta_{\\rm{En}})R_y^{\\otimes N}(\\frac{\\pi}{2}) \\tag{6}\n", + "$$\n", + "来表示,当编码电路和解码电路的电路层数为 $0$ 时,此时的电路即为经典设定下的拉姆塞干涉仪。下面我们搭建编码和解码电路。" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2022-11-04T07:07:36.557814Z", + "start_time": "2022-11-04T07:07:36.544862Z" + } + }, + "outputs": [], + "source": [ + "def RamseyCircuit(theta_EN: paddle.Tensor, theta_DE: paddle.Tensor, input_phi: float) -> Circuit:\n", + " r\"\"\" 构建拉姆塞干涉仪的变分电路\n", + " \n", + " Args:\n", + " theta_EN: 编码层参数, shape 为 [编码层深度,比特数,3]\n", + " theta_DE: 解码层参数, shape 为 [解码层深度,比特数,3]\n", + " input_phi: 未知参数输入\n", + " \n", + " Returns:\n", + " 创建完成的参数化量子电路\n", + " \n", + " \"\"\"\n", + " depth_EN, depth_DE = theta_EN.shape[0], theta_DE.shape[0]\n", + " num_qubits = theta_EN.shape[1]\n", + " \n", + " cir = Circuit(num_qubits)\n", + " cir.ry(param=pi/2)\n", + " \n", + " # 搭建编码电路,生成存在纠缠的输入态\n", + " for depth in range(depth_EN):\n", + " cir.u3(param=theta_EN[depth])\n", + " cir.cnot()\n", + " \n", + " # 未知参数门\n", + " cir.rz(param=input_phi)\n", + " \n", + " # 搭建解码电路,旋转测量基\n", + " for depth in range(depth_DE):\n", + " cir.cnot()\n", + " cir.u3(param=theta_DE[depth])\n", + " \n", + " cir.rx(param=pi/2)\n", + " return cir" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2. 评估" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- 计算测量结果 $m$ 的概率分布;\n", + "- 计算估计器 $\\hat{\\phi}(m)=am$ 的 MSE,${\\rm MSE}=\\sum_m(\\hat{\\phi}(m)-\\phi)^2p_{\\theta}(m|\\phi)$;\n", + "- 计算损失函数,此处我们利用离散形式的损失函数来近似其积分形式:\n", + "\n", + "$$\n", + "C=\\sum_{k=1}^t\\frac{2}{t}f(\\phi_k){\\rm {MSE}}, \\tag{7}\n", + "$$\n", + "\n", + "其中 $t$ 为选取区间内划分的份数(本教程中区间大小为 2),$f(\\phi_k)$ 为 $\\phi_k$ 对应的概率。" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "ExecuteTime": { + "end_time": "2022-11-04T07:07:36.572763Z", + "start_time": "2022-11-04T07:07:36.559813Z" + } + }, + "outputs": [], + "source": [ + "# 定义计算 m 的函数用于计算测量结果中 1 和 0 的个数差\n", + "def calculate_m(num_qubits: int)-> List[int]:\n", + " m_list = []\n", + " for k in range(2**num_qubits):\n", + " k_bin = list(bin(k)[2:].zfill(num_qubits))\n", + " u = k_bin.count('1')\n", + " v = k_bin.count('0')\n", + " m = u - v\n", + " m_list.append(m)\n", + "\n", + " return m_list\n", + "\n", + "\n", + "def MSE(qnn: paddle.nn.Layer, phi: float) -> paddle.Tensor:\n", + " r\"\"\" 计算对应 phi 的 MSE\n", + " \n", + " Args:\n", + " cir: 拉姆塞干涉仪的变分电路\n", + " phi: 采样参数\n", + " a: 估计器的优化参数\n", + " \n", + " Returns:\n", + " phi 的均方误差\n", + " \n", + " \"\"\"\n", + " cir = RamseyCircuit(qnn.theta_EN, qnn.theta_DE, phi)\n", + " \n", + " # 测量\n", + " output_state = cir()\n", + " prob = Measure()(output_state)\n", + " \n", + " num_qubits = cir.num_qubits\n", + " m = calculate_m(num_qubits)\n", + " return sum([((phi - qnn.a * m[i]) ** 2) * prob[i] for i in range(2 ** num_qubits)])\n", + "\n", + "# 定义损失函数\n", + "def loss_func(qnn: paddle.nn.Layer, sampling_times: int, mean: float, variance: float):\n", + " r\"\"\" 计算 QNN 模型的损失函数\n", + " \n", + " Args:\n", + " qnn: 一个 QNN 模型\n", + " sampling_times: 划分区间的个数\n", + " mean: 未知参数服从的正态分布的均值\n", + " variance: 未知参数服从的正态分布的方差\n", + " \n", + " \"\"\"\n", + " list_phi = [] # phi 的采样列表\n", + " list_pdf = [] # phi 的概率密度函数样本\n", + " for i in range(sampling_times):\n", + " phi = mean - 1 + (2 * i + 1)/ sampling_times # phi 的范围 [u - 1, u + 1],每个 phi 取小区间端点处两个 phi 的均值 \n", + " prob = (1 / (((2 * pi) ** 0.5) * variance)) * exp(-((phi - mean) ** 2) / (2 * (variance**2))) # phi 的概率密度函数\n", + " list_phi.append(phi)\n", + " list_pdf.append(prob)\n", + " \n", + " return sum([list_pdf[i] * MSE(qnn, list_phi[i]) * (2 / sampling_times) for i in range(sampling_times)])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3. 优化" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "ExecuteTime": { + "end_time": "2022-11-04T07:07:36.588710Z", + "start_time": "2022-11-04T07:07:36.576756Z" + } + }, + "outputs": [], + "source": [ + "def optimization(qnn: paddle.nn.Layer, num_itr: int, learning_rate: float) -> None:\n", + " r\"\"\" 对 QNN 模型进行优化\n", + " \n", + " Args:\n", + " qnn: 一个 QNN 模型\n", + " num_itr: 迭代次数\n", + " learning_rate: 学习速率\n", + " \n", + " \"\"\"\n", + " opt = paddle.optimizer.Adam(learning_rate=learning_rate, parameters=qnn.parameters())\n", + " print(\"训练开始:\")\n", + " for itr in range(1, num_itr):\n", + " loss = qnn()\n", + " loss.backward()\n", + " opt.minimize(loss)\n", + " opt.clear_grad()\n", + "\n", + " if itr % 10 == 0:\n", + " print(\" iter:\", itr, \"loss:\", \"%.4f\" % loss.numpy())" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "ExecuteTime": { + "end_time": "2022-11-04T07:07:36.620687Z", + "start_time": "2022-11-04T07:07:36.608645Z" + } + }, + "outputs": [], + "source": [ + "class RamseyInterferometer(paddle.nn.Layer):\n", + " r\"\"\" 变分拉姆塞干涉仪\n", + " \n", + " \"\"\"\n", + " def __init__(self) -> None:\n", + " super().__init__()\n", + " \n", + " # 为干涉仪添加参数\n", + " theta_EN = self.create_parameter(\n", + " shape= [depth_EN, N, 3], dtype=\"float64\",\n", + " default_initializer=paddle.nn.initializer.Uniform(low=0, high=2 * pi),\n", + " )\n", + " theta_DE = self.create_parameter(\n", + " shape= [depth_DE, N, 3], dtype=\"float64\",\n", + " default_initializer=paddle.nn.initializer.Uniform(low=0, high=2 * pi),\n", + " )\n", + " self.add_parameter('theta_EN', theta_EN)\n", + " self.add_parameter('theta_DE', theta_DE)\n", + " \n", + " # 添加对估计器的优化参数\n", + " a = self.create_parameter(\n", + " shape= [1], dtype=\"float64\",\n", + " default_initializer=paddle.nn.initializer.Uniform(low=0, high=2 * pi),\n", + " )\n", + " self.add_parameter('a', a)\n", + " \n", + " def forward(self) -> paddle.Tensor:\n", + " r\"\"\" 计算损失函数\n", + " \n", + " \"\"\"\n", + " return loss_func(self, TIMES, MEAN, VAR)\n", + " \n", + " def opt(self) -> None:\n", + " r\"\"\" 优化 QNN 模型\n", + " \n", + " \"\"\"\n", + " optimization(self, num_itr=ITR, learning_rate=LR)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "N = 2 # 量子比特数\n", + "depth_EN = 3 # 编码电路的层数\n", + "depth_DE = 3 # 解码电路的层数\n", + "LR = 0.2 # 基于梯度下降的优化方法的学习率\n", + "ITR = 150 # 训练的总迭代次数\n", + "TIMES = 30 # 划分参数区间的个数\n", + "MEAN = 2 # 未知参数服从正态分布的均值\n", + "VAR = 1 # 未知参数服从正态分布的方差" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "ExecuteTime": { + "end_time": "2022-11-04T07:33:36.330577Z", + "start_time": "2022-11-04T07:29:01.098077Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "训练开始:\n", + " iter: 10 loss: 5.6798\n", + " iter: 20 loss: 2.3396\n", + " iter: 30 loss: 1.1354\n", + " iter: 40 loss: 0.8429\n", + " iter: 50 loss: 0.4878\n", + " iter: 60 loss: 0.3399\n", + " iter: 70 loss: 0.2571\n", + " iter: 80 loss: 0.2270\n", + " iter: 90 loss: 0.2140\n", + " iter: 100 loss: 0.2067\n", + " iter: 110 loss: 0.2031\n", + " iter: 120 loss: 0.2013\n", + " iter: 130 loss: 0.2001\n", + " iter: 140 loss: 0.1994\n" + ] + } + ], + "source": [ + "QNN = RamseyInterferometer()\n", + "QNN.opt()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "利用优化后的电路估计服从正态分布的参数 $\\phi$,绘制 MSE。" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "ExecuteTime": { + "end_time": "2022-11-04T07:33:38.108968Z", + "start_time": "2022-11-04T07:33:36.333569Z" + }, + "scrolled": true + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "phi_list = []\n", + "mse_list = []\n", + "for i in range(TIMES):\n", + " phi = MEAN - 1 + (2 * i + 1) / TIMES\n", + " mse_est = MSE(QNN, phi)\n", + " phi_list.append(phi)\n", + " mse_list.append(mse_est)\n", + "\n", + "font = {'family': 'Times New Roman', 'weight':'normal', 'size':16}\n", + "plt.figure(dpi=100)\n", + "plt.plot(phi_list,mse_list,color='darkblue', linestyle='-')\n", + "plt.scatter(phi_list,mse_list)\n", + "plt.xlabel('$\\\\phi$',font)\n", + "plt.ylabel('MSE',font)\n", + "\n", + "plt.grid()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 结论" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "从图中可以看到,优化后的量子传感器(即量子电路)估计服从正态分布的参数的 MSE 与参数的概率密度呈负相关(MSE 与 $\\phi$ 的图像呈下凸型),且 MSE 在正态分布的均值(即 $\\mu$ 的取值)附近最低,说明在均值附近传感器估计参数的精度高,进一步说明通过变分的方式得到的传感器对该服从正态分布的参数有效。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "## 参考文献" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[1] Braunstein S L, Caves C M. Statistical distance and the geometry of quantum states[J]. [Physical Review Letters, 1994, 72(22): 3439](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.72.3439).\n", + "\n", + "[2] Giovannetti V, Lloyd S, Maccone L. Quantum metrology[J]. [Physical review letters, 2006, 96(1): 010401](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.96.010401).\n", + "\n", + "[3] Tóth G, Apellaniz I. Quantum metrology from a quantum information science perspective[J]. [Journal of Physics A: Mathematical and Theoretical, 2014, 47(42): 424006](https://iopscience.iop.org/article/10.1088/1751-8113/47/42/424006/meta).\n", + "\n", + "[4] Marciniak C D, Feldker T, Pogorelov I, et al. Optimal metrology with programmable quantum sensors[J]. [Nature, 2022, 603(7902): 604-609](https://www.nature.com/articles/s41586-022-04435-4).\n", + "\n", + "[5] Giovannetti V, Lloyd S, Maccone L. Advances in quantum metrology[J]. [Nature photonics, 2011, 5(4): 222-229](https://www.nature.com/articles/nphoton.2011.35).\n", + "\n", + "[6] Kaubruegger R, Vasilyev D V, Schulte M, et al. Quantum variational optimization of Ramsey interferometry and atomic clocks[J]. [Physical Review X, 2021, 11(4): 041045](https://journals.aps.org/prx/abstract/10.1103/PhysRevX.11.041045)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.13 ('py3.7_pq2.2.1')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.13" + }, + "vscode": { + "interpreter": { + "hash": "4e4e2eb86ad73936e915e7c7629a18a8ca06348106cf3e66676b9578cb1a47dd" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tutorials/quantum_simulation/VariationalQM_EN.ipynb b/tutorials/quantum_simulation/VariationalQM_EN.ipynb new file mode 100644 index 0000000..4f28e31 --- /dev/null +++ b/tutorials/quantum_simulation/VariationalQM_EN.ipynb @@ -0,0 +1,608 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Variational Quantum Metrology" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Copyright (c) 2022 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Background" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Quantum metrology is the study of high resolution and high sensitivity measurements of physical parameters using quantum theory (e.g., quantum entanglement) in order to further describe physical systems. Its theoretical aspect is quantum parameter estimation theory, and its experimental aspect is called quantum sensing. Previous studies have shown that the estimation accuracy by quantum theory is improved by taking the square root of the required number of samples compared with the classical method [1-3]. For an unknown parameter, the goal of quantum metrology is to maximize the accuracy of parameter estimation while minimizing the required resources (such as time, number of qubits, etc.).\n", + "\n", + "For example, given a unitary $e^{-i\\phi H}$ with a known Hamiltonian $H$, how can we extract the information about $\\phi$ by quantum metrology? It comprises the following four steps:\n", + "\n", + "1. Preparation. Prepare an input state $|\\psi\\rangle$.\n", + "2. Parameterization. Obtain the parameterized quantum state $e^{-i\\phi H}|\\psi\\rangle$ after the evolution of $e^{-i\\phi H}$.\n", + "3. Measurement. Measure the output state.\n", + "4. Classical estimation. Estimate the parameters based on the results of multiple measurements.\n", + "\n", + "Combined with quantum parameter estimation theory, this tutorial is based on the idea of variational quantum sensors in [4], and the parameterized quantum circuit is constructed using Paddle Quantum to train the loss function and obtain a quantum sensor that can estimate the parameters that are normally distributed." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Parameter Estimation Theory" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Classical parameter estimation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Classical parameter estimation, such as the maximum-likelihood estimator (MLE), uses multiple samples to calculate data containing an unknown parameter. That is, given a probability distribution depending on an unknown parameter $\\phi$, where $f$ is the probability density function, and ${\\bf{X}}=\\{X_1,X_2,... X_N\\}$ is $N$ independent and identically distributed sample data, the estimated value $\\hat\\phi$ is obtained by using MLE:\n", + "\n", + "$$\n", + "\\hat\\phi({\\bf X})=\\arg\\max_{\\phi}\\prod_i^Nf(X_i,\\phi), \\tag{1}\n", + "$$\n", + "\n", + "which finds $\\phi$ such that $X_i(i=1,...,N)$ occurs with maximum probability. After obtaining the estimated parameters, how to measure the difference between the estimated parameters and the actual parameters? That is, how to measure the accuracy of the estimated parameters? In the parameter estimation theory, mean squared error (MSE) is generally used to measure the accuracy.\n", + "\n", + "The sample containing the unknown parameter $\\bf{\\phi}$ is ${\\bf{X}}=\\{X_1,X_2,... X_N\\}\\in {\\mathcal F}^N$, where ${\\mathcal F}^N$ is the sample space. Let $\\hat{\\phi}({\\bf X}):{\\mathcal F}^N\\rightarrow\\Phi$ be the estimator that estimates $\\phi\\in\\Phi$ ($\\Phi$ is the parameter space). Then the MSE of $\\hat{\\phi}(\\bf X)$ with respect to $\\phi$ is defined as\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + "{\\rm{MSE}}&=\n", + "E[(\\hat{\\phi}({\\bf X})-\\phi)^2]\\\\\n", + "&=\\sum_{{\\bf X}\\in {\\mathcal F}^N}f({\\bf X};\\phi)(\\hat{\\phi}({\\bf X)}-\\phi)^2,\n", + "\\end{aligned} \\tag{2}\n", + "$$\n", + "\n", + "where $f({\\bf X}; \\phi)$ is the probability density of getting the current sample $\\bf X$ given the parameter $\\phi$. Although different estimators affect the value of MSE, regardless of the choice of $\\hat{\\phi}({\\bf X})$, there is ${\\rm{MSE}}\\geq\\frac{1}{N{\\mathcal I(\\phi)}}$. This lower bound is known as the Cramér–Rao (CR) bound [2], where $\\mathcal I(\\phi)$ is the Fisher information, which reflects to what extent a slight parameter change will change the probability distribution (see [Quantum Fisher Information](https://qml.baidu.com/tutorials/qnn-research/quantum-fisher-information.html) for the application of Fisher information in Paddle Quantum). " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Quantum parameter estimation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In quantum parameter estimation, the samples used in classical parameter estimation become a quantum state $\\rho_{\\phi}\\in{\\mathcal F}({\\mathcal H})$ to be measured, where $\\phi$ is the unknown parameter and ${\\mathcal F}({\\mathcal H})$ denotes the set of density operators on the Hilbert space $\\mathcal H$. According to the steps of quantum metrology and [4], assuming that the initial input state is $|0\\rangle$ and the estimator is $\\hat{\\phi}(m)$, where $m$ is related to the measured results (such as the difference in the number of 1s and the number of 0s in the measured bit string), then the MSE is\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + "{\\rm MSE}&=E[(\\hat{\\phi}(m)-\\phi)^2]\\\\\n", + "&=\\sum_m(\\hat{\\phi}(m)-\\phi)^2p(m|\\phi),\n", + "\\end{aligned} \\tag{3}\n", + "$$\n", + "\n", + "where $p(m|\\phi)$ is the probability of obtaining $m$ by measurement with a given parameter $\\phi$. Similarly, no matter how $\\hat{\\phi}(m)$ is chosen, there is a quantum CR bound ${\\rm{MSE}}\\geq\\frac{1}{NF(\\phi)}$, where $N$ is the number of repeated measurements of $\\rho_\\phi$, and $F(\\phi)$ is the quantum Fisher information (see [Quantum Fisher Information](https://qml.baidu.com/tutorials/qnn-research/quantum-fisher-information.html) for the application of quantum Fisher information in Paddle Quantum). " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Variational Quantum Sensors" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Quantum sensing is the application of quantum metrology. Based on [4], this tutorial mainly introduces a kind of variational Ramsey interferometer. The traditional Ramsey interferometer [2] (as shown in Figure 1) is a particle interferometry method that uses magnetic resonance phenomena to measure particle transition frequency and is used to measure unknown parameters. The variational Ramsay interferometer [6] (as shown in Figure 2) consists of two parameterized quantum circuits (denoted as $U_{\\rm{En}}(\\theta_{\\rm En})$ and $U_{\\rm{De}}(\\theta_{\\rm{De}})$) in the encoding and decoding parts of the circuit for setting entanglement and measuring quantum states. Previous studies have shown that by combining with quantum theory (such as quantum entanglement), the scaling of parameter estimation accuracy is enhanced to $\\frac{1}{N}$ from $\\frac{1}{\\sqrt{N}}$ [1-3], and the appropriate entanglement mode can be effectively found by the variational method.\n", + "\n", + "![Ramsey_interferomertry](./figures/QM-fig-RI.png \"Figure 1:Ramsey interferometer.\")\n", + "
Figure 1:Ramsey interferometer. On the left is the classical configuration of a Ramsey interferometer, and on the right is a Ramsey interferometer using quantum entanglement. Compared with the classical setting, the interferometer using quantum entanglement has an advantage in the order of square root in the accuracy of estimating unknown parameters.
\n", + "\n", + "![V_Ramsey_interferomertry](./figures/QM-fig-V_RI3.png \"Figure 2:Variational Ramsey interferometer.\")\n", + "
Figure 2:Variational Ramsey interferometer. Two parameterized quantum circuits are optimized to find an efficient way of utilizing entanglement.
\n", + "\n", + "In the following, we construct a parameterized quantum circuit using Paddle Quantum to investigate the accuracy of estimating normally distributed parameters by a variational Ramsey interferometer. There are three steps as follows.\n", + "1. Initialization.\n", + "2. Evaluation.\n", + "3. Optimization.\n", + "\n", + "The probability density function of the parameters that obey the normal distribution is:\n", + "\n", + "$$\n", + "f(x)=\\frac{1}{\\sqrt{2\\pi}\\nu}\\exp(-\\frac{(x-\\mu)^2}{2\\nu^2}), \\tag{4}\n", + "$$\n", + "\n", + "where $\\mu$ is the mean and $\\nu^2$ is the variance. In this case, the loss function of the variational Ramsey interferometer is:\n", + "\n", + "$$\n", + "C(\\theta_{\\rm En},\\theta_{\\rm De},a)=\\int d\\phi f(\\phi){\\rm{MSE}}(\\phi), \\tag{5}\n", + "$$\n", + "\n", + "where the estimator is $\\hat\\phi(m)=am$, $a$ is a parameter to be optimized, $m$ is the difference in the number of 1s and the number of 0s in the measured bit string, ${\\rm MSE(\\phi)}=\\sum_m(\\hat{\\phi}(m)-\\phi)^2p_{\\theta}(m|\\phi)$, and $\\theta=(\\theta_{\\rm En},\\theta_{\\rm De})$." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1. Initializaiton" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Set the input state as $|0\\rangle$.\n", + "- Construct the parameterized quantum circuits $U_{\\rm{En}}$ and $U_{\\rm{De}}$ for encoding and decoding, respectively.\n", + "- Encode the unknown parameter." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let us import the necessary packages:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2022-11-04T07:28:26.890500Z", + "start_time": "2022-11-04T07:28:23.298471Z" + } + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "from math import exp, pi\n", + "import matplotlib.pyplot as plt\n", + "from typing import Optional, Tuple, List\n", + "\n", + "import paddle\n", + "import paddle_quantum as pq\n", + "from paddle_quantum.ansatz import Circuit\n", + "from paddle_quantum.loss import Measure\n", + "\n", + "pq.set_backend('state_vector')\n", + "pq.set_dtype('complex128')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we construct a parameterized quantum circuit of $N$ qubits to complete the initialization.\n", + "\n", + "The whole circuit includes the following five parts.\n", + "- $R_y^{\\otimes N}(\\frac{\\pi}{2})$ gates.\n", + "- Encoding circuit $U_{\\rm{En}}(\\theta_{\\rm{En}})$.\n", + "- Circuit with unknown parameter $R_z^{\\otimes N}(\\phi)=e^{-i\\phi J_z}$, where $J_z=\\frac{1}{2}\\sum_{k=1}^N\\sigma_z^{(k)}$.\n", + "- Decoding circuit $U_{\\rm{De}}(\\theta_{\\rm{De}})$.\n", + "- $R_x^{\\otimes N}(\\frac{\\pi}{2})$ gate.\n", + "\n", + "So the unitary of the entire circuit is\n", + "\n", + "$$\n", + "U(\\phi,\\theta_{\\rm{En}},\\theta_{\\rm{De}})=R_x^{\\otimes N}(\\frac{\\pi}{2})U_{\\rm{De}}(\\theta_{\\rm{De}})R_z^{\\otimes N}(\\phi)U_{\\rm{En}}(\\theta_{\\rm{En}})R_y^{\\otimes N}(\\frac{\\pi}{2}). \\tag{6}\n", + "$$\n", + "\n", + "When the depth of the encoding circuit and decoding circuit is $0$, the entire circuit is the classical configuration of a Ramsey interferometer. Here we construct the encoding and the decoding circuits." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2022-11-04T07:28:26.906450Z", + "start_time": "2022-11-04T07:28:26.892489Z" + } + }, + "outputs": [], + "source": [ + "def RamseyCircuit(theta_EN: paddle.Tensor, theta_DE: paddle.Tensor, input_phi: float) -> Circuit:\n", + " r\"\"\" Construct variational Ramsey interferometer\n", + " \n", + " Args:\n", + " theta_EN: the parameters of encoding circuit, shape is [depth_En, num_qubits,3]\n", + " theta_DE: the parameters of decoding circui, shape is [depth_De, num_qubits,3]\n", + " input_phi: unknown parameter\n", + " \n", + " Returns:\n", + " Circuit\n", + " \n", + " \"\"\"\n", + " depth_EN, depth_DE = theta_EN.shape[0], theta_DE.shape[0]\n", + " num_qubits = theta_EN.shape[1]\n", + " \n", + " cir = Circuit(num_qubits)\n", + " cir.ry(param=pi/2)\n", + " \n", + " # Construct the encoding circuit to generate an entangled state\n", + " for depth in range(depth_EN):\n", + " cir.u3(param=theta_EN[depth])\n", + " cir.cnot()\n", + " \n", + " # the gate of unknown parameter\n", + " cir.rz(param=input_phi)\n", + " \n", + " # Construct the decoding circuit to rotate the measurement basis\n", + " for depth in range(depth_DE):\n", + " cir.cnot()\n", + " cir.u3(param=theta_DE[depth])\n", + " \n", + " cir.rx(param=pi/2)\n", + " \n", + " return cir" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2. Evaluation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Calculate the probability distribution of $m$.\n", + "- Calculate the MSE of the estimator $\\hat{\\phi}(m)=am$: ${\\rm MSE}=\\sum_m(\\hat{\\phi}(m)-\\phi)^2p_{\\theta}(m|\\phi)$.\n", + "- Calculate the loss function. Here, we use the discrete form of the loss function to approximate its integral form:\n", + "\n", + "$$\n", + "C=\\sum_{k=1}^t\\frac{2}{t}f(\\phi_k){\\rm {MSE}}, \\tag{7}\n", + "$$\n", + "\n", + "where $t$ is the number of partitions in the selected interval (the total interval size is $2$ in this tutorial), and $f(\\phi_k)$ is the probability corresponding to $\\phi_k$." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "ExecuteTime": { + "end_time": "2022-11-04T07:28:26.922400Z", + "start_time": "2022-11-04T07:28:26.908437Z" + } + }, + "outputs": [], + "source": [ + "# Define the function to calculate m\n", + "def calculate_m(num_qubits: int)-> List[int]:\n", + " m_list = []\n", + " for k in range(2**num_qubits):\n", + " k_bin = list(bin(k)[2:].zfill(num_qubits))\n", + " u = k_bin.count('1')\n", + " v = k_bin.count('0')\n", + " m = u - v\n", + " m_list.append(m)\n", + "\n", + " return m_list\n", + "\n", + "\n", + "def MSE(qnn: paddle.nn.Layer, phi: float) -> paddle.Tensor:\n", + " r\"\"\" Calculate MSE \n", + " \n", + " Args:\n", + " cir: variational Ramsey interferometer\n", + " phi: unknown parameter\n", + " a: parameter of the estimator\n", + " \n", + " Returns:\n", + " MSE\n", + " \n", + " \"\"\"\n", + " cir = RamseyCircuit(qnn.theta_EN, qnn.theta_DE, phi)\n", + " \n", + " # Measurement\n", + " output_state = cir()\n", + " prob = Measure()(output_state)\n", + " \n", + " num_qubits = cir.num_qubits\n", + " m = calculate_m(num_qubits)\n", + " return sum([((phi - qnn.a * m[i]) ** 2) * prob[i] for i in range(2 ** num_qubits)])\n", + "\n", + "# Define loss function\n", + "def loss_func(qnn: paddle.nn.Layer, sampling_times: int, mean: float, variance: float):\n", + " r\"\"\" Calculate loss \n", + " \n", + " Args:\n", + " qnn: a QNN\n", + " sampling_times: the number of partitions in the selected interval\n", + " mean: the mean of a normal distribution\n", + " variance: the variance of a normal distribution\n", + " \n", + " \"\"\"\n", + " list_phi = [] # The list of phi\n", + " list_pdf = [] # The list of the probability density function of phi\n", + " for i in range(sampling_times):\n", + " phi = mean - 1 + (2 * i + 1)/ sampling_times # The range of phi is [u - 1, u + 1] \n", + " prob = (1 / (((2 * pi) ** 0.5) * variance)) * exp(-((phi - mean) ** 2) / (2 * (variance**2))) # The probability density of phi\n", + " list_phi.append(phi)\n", + " list_pdf.append(prob)\n", + " \n", + " return sum([list_pdf[i] * MSE(qnn, list_phi[i]) * (2 / sampling_times) for i in range(sampling_times)])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3. Optimization" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "ExecuteTime": { + "end_time": "2022-11-04T07:28:26.938337Z", + "start_time": "2022-11-04T07:28:26.926376Z" + } + }, + "outputs": [], + "source": [ + "def optimization(qnn: paddle.nn.Layer, num_itr: int, learning_rate: float) -> None:\n", + " r\"\"\" Optimize QNN\n", + " \n", + " Args:\n", + " qnn: a QNN\n", + " num_itr: the number of optimization iterations\n", + " learning_rate: learning rate\n", + " \n", + " \"\"\"\n", + " opt = paddle.optimizer.Adam(learning_rate=learning_rate, parameters=qnn.parameters())\n", + " print(\"Begin:\")\n", + " for itr in range(1, num_itr):\n", + " loss = qnn()\n", + " loss.backward()\n", + " opt.minimize(loss)\n", + " opt.clear_grad()\n", + "\n", + " if itr % 10 == 0:\n", + " print(\" iter:\", itr, \"loss:\", \"%.4f\" % loss.numpy())" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "ExecuteTime": { + "end_time": "2022-11-04T07:29:44.003762Z", + "start_time": "2022-11-04T07:29:43.988814Z" + } + }, + "outputs": [], + "source": [ + "class RamseyInterferometer(paddle.nn.Layer):\n", + " r\"\"\" Variational Ramsey interferometer\n", + " \n", + " \"\"\"\n", + " def __init__(self) -> None:\n", + " super().__init__()\n", + " \n", + " # Add parameters\n", + " theta_EN = self.create_parameter(\n", + " shape= [depth_EN, N, 3], dtype=\"float64\",\n", + " default_initializer=paddle.nn.initializer.Uniform(low=0, high=2 * pi),\n", + " )\n", + " theta_DE = self.create_parameter(\n", + " shape= [depth_DE, N, 3], dtype=\"float64\",\n", + " default_initializer=paddle.nn.initializer.Uniform(low=0, high=2 * pi),\n", + " )\n", + " self.add_parameter('theta_EN', theta_EN)\n", + " self.add_parameter('theta_DE', theta_DE)\n", + " \n", + " # Add the parameter of the estimator\n", + " a = self.create_parameter(\n", + " shape= [1], dtype=\"float64\",\n", + " default_initializer=paddle.nn.initializer.Uniform(low=0, high=2 * pi),\n", + " )\n", + " self.add_parameter('a', a)\n", + " \n", + " def forward(self) -> paddle.Tensor:\n", + " r\"\"\" Calculate loss\n", + " \n", + " \"\"\"\n", + " return loss_func(self, TIMES, MEAN, VAR)\n", + " \n", + " def opt(self) -> None:\n", + " r\"\"\" Optimize QNN\n", + " \n", + " \"\"\"\n", + " optimization(self, num_itr=ITR, learning_rate=LR)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "N = 2 # The number of qubits\n", + "depth_EN = 3 # The depth of encoding circuit\n", + "depth_DE = 3 # The depth of decoding circuit\n", + "LR = 0.2 # Learning rate\n", + "ITR = 150 # The number of optimization iterations\n", + "TIMES = 30 # The number of partitions in the selected interval\n", + "MEAN = 2 # The mean of a normal distribution\n", + "VAR = 1 # The variance of a normal distribution" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "ExecuteTime": { + "end_time": "2022-11-04T07:44:05.439096Z", + "start_time": "2022-11-04T07:40:20.208851Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Begin:\n", + " iter: 10 loss: 3.8495\n", + " iter: 20 loss: 0.8521\n", + " iter: 30 loss: 0.7484\n", + " iter: 40 loss: 0.4504\n", + " iter: 50 loss: 0.3610\n", + " iter: 60 loss: 0.3375\n", + " iter: 70 loss: 0.3042\n", + " iter: 80 loss: 0.2827\n", + " iter: 90 loss: 0.2600\n", + " iter: 100 loss: 0.2386\n", + " iter: 110 loss: 0.2217\n", + " iter: 120 loss: 0.2096\n", + " iter: 130 loss: 0.2026\n", + " iter: 140 loss: 0.1996\n" + ] + } + ], + "source": [ + "QNN = RamseyInterferometer()\n", + "QNN.opt()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The optimized circuit is used to estimate the parameters with a normal distribution, and then we draw the MSE." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "ExecuteTime": { + "end_time": "2022-11-04T07:44:49.222284Z", + "start_time": "2022-11-04T07:44:47.797824Z" + }, + "scrolled": true + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "phi_list = []\n", + "mse_list = []\n", + "for i in range(TIMES):\n", + " phi = MEAN - 1 + (2 * i + 1) / TIMES\n", + " mse_est = MSE(QNN, phi)\n", + " phi_list.append(phi)\n", + " mse_list.append(mse_est)\n", + "\n", + "font = {'family': 'Times New Roman', 'weight':'normal', 'size':16}\n", + "plt.figure(dpi=100)\n", + "plt.plot(phi_list,mse_list,color='darkblue', linestyle='-')\n", + "plt.scatter(phi_list,mse_list)\n", + "plt.xlabel('$\\\\phi$',font)\n", + "plt.ylabel('MSE',font)\n", + "\n", + "plt.grid()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Conclusion" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see that the MSE estimated by the optimized quantum sensor is negatively correlated with the probability density of the parameters, and the value of MSE is the lowest near the mean value of the normal distribution, indicating that the obtained quantum sensor by variational method is effective for the parameters following a normal distribution." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "## References" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[1] Braunstein S L, Caves C M. Statistical distance and the geometry of quantum states[J]. [Physical Review Letters, 1994, 72(22): 3439](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.72.3439).\n", + "\n", + "[2] Giovannetti V, Lloyd S, Maccone L. Quantum metrology[J]. [Physical review letters, 2006, 96(1): 010401](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.96.010401).\n", + "\n", + "[3] Tóth G, Apellaniz I. Quantum metrology from a quantum information science perspective[J]. [Journal of Physics A: Mathematical and Theoretical, 2014, 47(42): 424006](https://iopscience.iop.org/article/10.1088/1751-8113/47/42/424006/meta).\n", + "\n", + "[4] Marciniak C D, Feldker T, Pogorelov I, et al. Optimal metrology with programmable quantum sensors[J]. [Nature, 2022, 603(7902): 604-609](https://www.nature.com/articles/s41586-022-04435-4).\n", + "\n", + "[5] Giovannetti V, Lloyd S, Maccone L. Advances in quantum metrology[J]. [Nature photonics, 2011, 5(4): 222-229](https://www.nature.com/articles/nphoton.2011.35).\n", + "\n", + "[6] Kaubruegger R, Vasilyev D V, Schulte M, et al. Quantum variational optimization of Ramsey interferometry and atomic clocks[J]. [Physical Review X, 2021, 11(4): 041045](https://journals.aps.org/prx/abstract/10.1103/PhysRevX.11.041045)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.8.13 ('pq')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.13" + }, + "vscode": { + "interpreter": { + "hash": "08942b1340a5932ff3a93f52933a99b0e263568f3aace1d262ffa4d9a0f2da31" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tutorials/quantum_simulation/figures/QM-fig-RI.png b/tutorials/quantum_simulation/figures/QM-fig-RI.png new file mode 100644 index 0000000000000000000000000000000000000000..334dfe022941ccff2a2a9659ca88b7dc227473ca GIT binary patch literal 92518 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
  • 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

    n@mZ`h% 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 literal 0 HcmV?d00001 diff --git a/tutorials/quantum_simulation/figures/QM-fig-V_RI3.png b/tutorials/quantum_simulation/figures/QM-fig-V_RI3.png new file mode 100644 index 0000000000000000000000000000000000000000..8e005a9fa74b6029584b36b974c3cd861ce6c2eb GIT binary patch literal 23643 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 W;GIhy2e5}1B=u4LL-~8dfd2=|$jF!g literal 0 HcmV?d00001 diff --git a/tutorials/quantum_simulation/figures/QPP-fig-state.png b/tutorials/quantum_simulation/figures/QPP-fig-state.png new file mode 100644 index 0000000000000000000000000000000000000000..00ec5149244b818cee8b4df45767b4aaa68573e5 GIT binary patch literal 39595 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