提交 9a5ad8a6 编写于 作者: Q Quleaf

update to v2.2.1

上级 9c11f358
......@@ -7,7 +7,7 @@ English | [简体中文](README_CN.md)
- [Install PaddlePaddle](#install-paddlepaddle)
- [Install Paddle Quantum](#install-paddle-quantum)
- [Environment setup for Quantum Chemistry module](#environment_setup_for_quantum_chemistry_module)
- [Run programs](#run-programs)
- [Run Example](#run-example)
- [Introduction and developments](#introduction-and-developments)
- [Quick start](#quick-start)
- [Tutorials](#tutorials)
......@@ -18,7 +18,7 @@ English | [简体中文](README_CN.md)
- [Copyright and License](#copyright-and-license)
- [References](#references)
[Paddle Quantum (量桨)](https://qml.baidu.com/) is a quantum machine learning (QML) toolkit developed based on Baidu PaddlePaddle. It provides a platform to construct and train quantum neural networks (QNNs) with easy-to-use QML development kits supporting combinatorial optimization, quantum chemistry and other cutting-edge quantum applications, making PaddlePaddle the first deep learning framework in China that supports quantum machine learning.
[Paddle Quantum (量桨)](https://qml.baidu.com/) is the world's first cloud-integrated quantum machine learning platform based on Baidu PaddlePaddle. It supports the building and training of quantum neural networks, making PaddlePaddle the first deep learning framework in China. Paddle Quantum is feature-rich and easy to use. It provides comprehensive API documentation and tutorials help users get started right away.
<p align="center">
<a href="https://qml.baidu.com/">
......@@ -33,7 +33,7 @@ English | [简体中文](README_CN.md)
</a>
<!-- PyPI -->
<a href="https://pypi.org/project/paddle-quantum/">
<img src="https://img.shields.io/badge/pypi-v2.2.0-orange.svg?style=flat-square&logo=pypi"/>
<img src="https://img.shields.io/badge/pypi-v2.2.1-orange.svg?style=flat-square&logo=pypi"/>
</a>
<!-- Python -->
<a href="https://www.python.org/">
......@@ -55,7 +55,7 @@ Paddle Quantum aims at establishing a bridge between artificial intelligence (AI
## Features
- Easy-to-use
- Many online learning resources (Nearly 40 tutorials)
- Many online learning resources (Nearly 50 tutorials)
- High efficiency in building QNN with various QNN templates
- Automatic differentiation
- Versatile
......@@ -71,7 +71,7 @@ Paddle Quantum aims at establishing a bridge between artificial intelligence (AI
### Install PaddlePaddle
This dependency will be automatically satisfied when users install Paddle Quantum. Please refer to [PaddlePaddle](https://www.paddlepaddle.org.cn/install/quick)'s official installation and configuration page. This project requires PaddlePaddle 2.2.0+.
This dependency will be automatically satisfied when users install Paddle Quantum. Please refer to [PaddlePaddle](https://www.paddlepaddle.org.cn/install/quick)'s official installation and configuration page. This project requires PaddlePaddle 2.2.0 to 2.3.0.
### Install Paddle Quantum
......@@ -151,6 +151,7 @@ We provide tutorials covering quantum simulation, machine learning, combinatoria
8. [Hamiltonian Simulation with Product Formula](./tutorials/quantum_simulation/HamiltonianSimulation_EN.ipynb)
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)
- [Machine Learning](./tutorials/machine_learning)
1. [Encoding Classical Data into Quantum States](./tutorials/machine_learning/DataEncoding_EN.ipynb)
......@@ -160,6 +161,8 @@ We provide tutorials covering quantum simulation, machine learning, combinatoria
5. [Quantum Autoencoder](./tutorials/machine_learning/QAutoencoder_EN.ipynb)
6. [Quantum GAN](./tutorials/machine_learning/QGAN_EN.ipynb)
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)
- [Combinatorial Optimization](./tutorials/combinatorial_optimization)
1. [Quantum Approximation Optimization Algorithm (QAOA)](./tutorials/combinatorial_optimization/QAOA_EN.ipynb)
......
......@@ -19,7 +19,7 @@
- [Copyright and License](#copyright-and-license)
- [References](#references)
[Paddle Quantum(量桨)](https://qml.baidu.com/)是基于百度飞桨开发的量子机器学习工具集,支持量子神经网络的搭建与训练,提供易用的量子机器学习开发套件与量子优化、量子化学等前沿量子应用工具集,使得百度飞桨也因此成为国内首个支持量子机器学习的深度学习框架
[Paddle Quantum(量桨)](https://qml.baidu.com/)是基于百度飞桨研发的全球首个云量一体的量子机器学习平台。量桨支持量子神经网络的搭建与训练等功能,使得百度飞桨也因此成为国内首个支持量子机器学习的深度学习框架。量桨具备轻松上手、功能丰富等特点,提供了完善的API文档和用例教程,使用户可以快速入门和上手
<p align="center">
<a href="https://qml.baidu.com/">
......@@ -34,7 +34,7 @@
</a>
<!-- PyPI -->
<a href="https://pypi.org/project/paddle-quantum/">
<img src="https://img.shields.io/badge/pypi-v2.2.0-orange.svg?style=flat-square&logo=pypi"/>
<img src="https://img.shields.io/badge/pypi-v2.2.1-orange.svg?style=flat-square&logo=pypi"/>
</a>
<!-- Python -->
<a href="https://www.python.org/">
......@@ -55,7 +55,7 @@
## 特色
- 轻松上手
- 丰富的在线学习资源(近 40 篇教程案例)
- 丰富的在线学习资源(近 50 篇教程案例)
- 通过模板高效搭建量子神经网络
- 自动微分框架
- 功能丰富
......@@ -71,7 +71,7 @@
### 安装 PaddlePaddle
当用户安装 Paddle Quantum 时会自动下载安装这个关键依赖包。关于 PaddlePaddle 更全面的安装信息请参考 [PaddlePaddle](https://www.paddlepaddle.org.cn/install/quick) 安装配置页面。此项目需求 PaddlePaddle 2.2.0+
当用户安装 Paddle Quantum 时会自动下载安装这个关键依赖包。关于 PaddlePaddle 更全面的安装信息请参考 [PaddlePaddle](https://www.paddlepaddle.org.cn/install/quick) 安装配置页面。此项目需求 PaddlePaddle 2.2.0 到 2.3.0
### 安装 Paddle Quantum
......@@ -80,6 +80,7 @@
```bash
pip install paddle-quantum
```
用户也可以选择下载全部文件后进行本地安装,
```bash
......@@ -88,7 +89,6 @@ cd quantum
pip install -e .
```
### 量子化学模块的环境设置
我们的量子化学模块是基于 `Psi4` 进行开发的,所以在运行量子化学模块之前需要先行安装该 Python 包。
......@@ -160,6 +160,8 @@ Paddle Quantum(量桨)建立起了人工智能与量子计算的桥梁,为
8. [利用 Product Formula 模拟时间演化](./tutorials/quantum_simulation/HamiltonianSimulation_CN.ipynb)
9. [模拟一维海森堡链的自旋动力学](./tutorials/quantum_simulation/SimulateHeisenberg_CN.ipynb)
10. [基于施密特分解的分布式变分量子本征求解器](./tutorials/quantum_simulation/DistributedVQE_CN.ipynb)
11. [量子信号处理与量子奇异值变换](./tutorials/quantum_simulation/QSP_and_QSVT_CN.ipynb)
- [机器学习](./tutorials/machine_learning)
1. [量子态编码经典数据](./tutorials/machine_learning/DataEncoding_CN.ipynb)
......@@ -169,6 +171,8 @@ Paddle Quantum(量桨)建立起了人工智能与量子计算的桥梁,为
5. [量子变分自编码器(Quantum Autoencoder)](./tutorials/machine_learning/QAutoencoder_CN.ipynb)
6. [量子生成对抗网络(Quantum GAN)](./tutorials/machine_learning/QGAN_CN.ipynb)
7. [变分量子奇异值分解(VQSVD)](./tutorials/machine_learning/VQSVD_CN.ipynb)
8. [数据编码分析](./tutorials/machine_learning/EncodingAnalysis_CN.ipynb)
9. [量子神经网络模拟函数](./tutorials/machine_learning/QApproximating_CN.ipynb)
- [组合优化](./tutorials/combinatorial_optimization)
1. [量子近似优化算法(QAOA)](./tutorials/combinatorial_optimization/QAOA_CN.ipynb)
......
......@@ -22,7 +22,7 @@ copyright = '2022, Baidu Inc'
author = 'Baidu Inc'
# The full version, including alpha/beta/rc tags
release = '2.2.0'
release = '2.2.1'
# -- General configuration ---------------------------------------------------
......
......@@ -3,7 +3,7 @@
Paddle Quantum
=======================
`Paddle Quantum <https://github.com/PaddlePaddle/Quantum>`__\ is a quantum machine learning toolkit developed based on Baidu PaddlePaddle. It provides a platform to construct and train quantum neural networks (QNN) with easy-to-use QML development kits supporting combinatorial optimization, quantum chemistry and other cutting-edge quantum applications, making PaddlePaddle the first deep learning framework in China that supports quantum machine learning.
`Paddle Quantum <https://github.com/PaddlePaddle/Quantum>`__\ is the world's first cloud-integrated quantum machine learning platform based on Baidu PaddlePaddle. It supports the building and training of quantum neural networks, making PaddlePaddle the first deep learning framework in China. Paddle Quantum is feature-rich and easy to use. It provides comprehensive API documentation and tutorials help users get started right away.
.. figure:: https://release-data.cdn.bcebos.com/Paddle%20Quantum.png
:target: https://github.com/PaddlePaddle/Quantum
......@@ -19,7 +19,7 @@ Features
- Easy-to-use
- Many online learning resources (Nearly 40 tutorials)
- Many online learning resources (Nearly 50 tutorials)
- High efficiency in building QNN with various QNN templates
- Automatic differentiation
......@@ -45,7 +45,7 @@ Install
Install PaddlePaddle
~~~~~~~~~~~~~~~~~~~~
This dependency will be automatically satisfied when users install Paddle Quantum. Please refer to `PaddlePaddle <https://www.paddlepaddle.org.cn/install/quick>`__ Install and configuration page. This project requires PaddlePaddle 2.2.0+.
This dependency will be automatically satisfied when users install Paddle Quantum. Please refer to `PaddlePaddle <https://www.paddlepaddle.org.cn/install/quick>`__ Install and configuration page. This project requires PaddlePaddle 2.2.0 to 2.3.0.
.. _header-n19:
......
......@@ -113,7 +113,7 @@ msgid ""
"This dependency will be automatically satisfied when users install Paddle"
" Quantum. Please refer to `PaddlePaddle "
"<https://www.paddlepaddle.org.cn/install/quick>`__ Install and "
"configuration page. This project requires PaddlePaddle 2.2.0+."
"configuration page. This project requires PaddlePaddle 2.2.0 to 2.3.0."
msgstr ""
#: ../../source/introduction.rst:53
......
......@@ -22,3 +22,4 @@
paddle_quantum.shadow
paddle_quantum.trotter
paddle_quantum.visual
paddle_quantum.qsvt
\ No newline at end of file
paddle\_quantum.qsvt.qsp
============================
.. automodule:: paddle_quantum.qsvt.qsp
:members:
:undoc-members:
:show-inheritance:
\ No newline at end of file
paddle\_quantum.qsvt.qsp\_utils
===============================
.. automodule:: paddle_quantum.qsvt.qsp_utils
:members:
:undoc-members:
:show-inheritance:
\ No newline at end of file
paddle\_quantum.qsvt.qsvt
============================
.. automodule:: paddle_quantum.qsvt.qsvt
:members:
:undoc-members:
:show-inheritance:
\ No newline at end of file
paddle\_quantum.qsvt
============================
.. automodule:: paddle_quantum.qsvt
:members:
:undoc-members:
:show-inheritance:
.. rubric:: Submodules
.. toctree::
:maxdepth: 4
paddle_quantum.qsvt.qsp_utils
paddle_quantum.qsvt.qsp
paddle_quantum.qsvt.qsvt
\ No newline at end of file
......@@ -21,14 +21,14 @@ Tutorials
---------
We provide use cases covering quantum simulation, machine learning, combinatorial optimization, local operations and classical communication (LOCC), and other popular quantum machine learning research topics.
Similar to the \ `quick start guide </quick-start/overview.html>`__\ , you can read each tutorial `online </tutorials/overview.html>`__ or download and run `Jupyter Notebooks <https://github.com/PaddlePaddle/Quantum/tree/master/tutorial>`__\ locally.
Similar to the \ `quick start guide </quick-start/overview.html>`__\ , you can read each tutorial `online </tutorials/overview.html>`__ or download and run `Jupyter Notebooks <https://github.com/PaddlePaddle/Quantum/tree/master/tutorials>`__\ locally.
For interested developers, we recommend them to download Jupyter Notebooks and play around with it. Here are the tutorial categories:
- `Quantum Simulation <https://github.com/PaddlePaddle/Quantum/blob/master/tutorial/quantum_simulation>`__
- `Machine Learning <https://github.com/PaddlePaddle/Quantum/blob/master/tutorial/machine_learning>`__
- `Combinatorial Optimization <https://github.com/PaddlePaddle/Quantum/blob/master/tutorial/combinatorial_optimization>`__
- `LOCCNet <https://github.com/PaddlePaddle/Quantum/blob/master/tutorial/locc>`__
- `QNN Research <https://github.com/PaddlePaddle/Quantum/blob/master/tutorial/qnn_research>`__
- `Quantum Simulation <https://github.com/PaddlePaddle/Quantum/blob/master/tutorials/quantum_simulation>`__
- `Machine Learning <https://github.com/PaddlePaddle/Quantum/blob/master/tutorials/machine_learning>`__
- `Combinatorial Optimization <https://github.com/PaddlePaddle/Quantum/blob/master/tutorials/combinatorial_optimization>`__
- `LOCCNet <https://github.com/PaddlePaddle/Quantum/blob/master/tutorials/locc>`__
- `QNN Research <https://github.com/PaddlePaddle/Quantum/blob/master/tutorials/qnn_research>`__
With the latest LOCCNet module, Paddle Quantum can efficiently simulate distributed quantum information processing tasks. Interested readers can
start with this `tutorial on LOCCNet </tutorials/loccnet/loccnet-framework.html>`__. In addition, Paddle Quantum supports quantum neural
......
......@@ -22,7 +22,7 @@ copyright = '2022, Baidu Inc'
author = 'Baidu Inc'
# The full version, including alpha/beta/rc tags
release = '2.2.0'
release = '2.2.1'
# -- General configuration ---------------------------------------------------
......
......@@ -3,7 +3,7 @@
Paddle Quantum(量桨)
=======================
`Paddle Quantum(量桨) <https://github.com/PaddlePaddle/Quantum>`__\ 是基于百度飞桨开发的量子机器学习工具集,支持量子神经网络的搭建与训练,提供易用的量子机器学习开发套件与量子优化、量子化学等前沿量子应用工具集,使得百度飞桨也因此成为国内首个支持量子机器学习的深度学习框架
`Paddle Quantum(量桨) <https://github.com/PaddlePaddle/Quantum>`__\ 是基于百度飞桨研发的全球首个云量一体的量子机器学习平台。量桨支持量子神经网络的搭建与训练等功能,使得百度飞桨也因此成为国内首个支持量子机器学习的深度学习框架。量桨具备轻松上手、功能丰富等特点,提供了完善的API文档和用例教程,使用户可以快速入门和上手
.. figure:: https://release-data.cdn.bcebos.com/Paddle%20Quantum.png
:target: https://github.com/PaddlePaddle/Quantum
......@@ -19,7 +19,7 @@ Paddle Quantum(量桨)
- 轻松上手
- 丰富的在线学习资源(近 40 篇教程案例)
- 丰富的在线学习资源(近 50 篇教程案例)
- 通过模板高效搭建量子神经网络
- 自动微分框架
......@@ -47,7 +47,7 @@ Paddle Quantum(量桨)
当用户安装 Paddle Quantum 时会自动下载安装这个关键依赖包。关于 PaddlePaddle 更全面的安装信息请参考
`PaddlePaddle <https://www.paddlepaddle.org.cn/install/quick>`__
安装配置页面。此项目需求 PaddlePaddle 2.2.0+
安装配置页面。此项目需求 PaddlePaddle 2.2.0 到 2.3.0
.. _header-n19:
......
......@@ -22,3 +22,4 @@
paddle_quantum.shadow
paddle_quantum.trotter
paddle_quantum.visual
paddle_quantum.qsvt
......@@ -3,7 +3,7 @@ paddle\_quantum.ansatz.circuit
量子电路类的功能实现。
.. py:class:: Circuit(num_qubits = None)
.. py:class:: Circuit(num_qubits=None)
基类: :py:class:`paddle_quantum.ansatz.container.Sequential`
......@@ -28,7 +28,11 @@ paddle\_quantum.ansatz.circuit
展平后的电路参数梯度。
.. py:method:: update_param(theta, idx = None)
.. py:property:: depth()
电路深度
.. py:method:: update_param(theta, idx=None)
替换单层或所有的电路参数。
......@@ -39,7 +43,11 @@ paddle\_quantum.ansatz.circuit
:raises ValueError: 索引必须是整数或者 None。
.. py:method:: randomize_param(self, low = 0, high = 2 * pi)
.. py:method:: transfer_static()
将该线路的所有参数的 ``stop_grdient`` 设为 ``True``
.. py:method:: randomize_param(low=0, high=2 * pi)
在 ``[low, high)`` 的范围内随机化电路参数
......@@ -48,7 +56,7 @@ paddle\_quantum.ansatz.circuit
:param high: 随机参数的上界, 默认为 ``2*pi``。
:type high: float, optional
.. py:method:: h(qubits_idx = 'full', num_qubits = None, depth = 1)
.. py:method:: h(qubits_idx='full', num_qubits=None, depth=1)
添加一个单量子比特的 Hadamard 门。
......@@ -69,7 +77,7 @@ paddle\_quantum.ansatz.circuit
:param depth: 层数,默认为 ``1``。
:type depth: int, optional
.. py:method:: s(qubits_idx = 'full', num_qubits = None, depth = 1)
.. py:method:: s(qubits_idx='full', num_qubits=None, depth=1)
添加单量子比特 S 门。
......@@ -90,7 +98,7 @@ paddle\_quantum.ansatz.circuit
:param depth: 层数,默认为 ``1``。
:type depth: int, optional
.. py:method:: t(qubits_idx = 'full', num_qubits = None, depth = 1)
.. py:method:: t(qubits_idx='full', num_qubits=None, depth=1)
添加单量子比特 T 门。
......@@ -111,7 +119,7 @@ paddle\_quantum.ansatz.circuit
:param depth: 层数,默认为 ``1``。
:type depth: int, optional
.. py:method:: x(qubits_idx = 'full', num_qubits = None, depth = 1)
.. py:method:: x(qubits_idx='full', num_qubits=None, depth=1)
添加单量子比特 X 门。
......@@ -701,7 +709,7 @@ paddle\_quantum.ansatz.circuit
:param depth: 层数,默认为 ``1``。
:type depth: int, optional
.. py:method:: ccx(qubits_idx = 'cycle', num_qubits = None, depth = 1)
.. py:method:: ccx(qubits_idx='cycle', num_qubits=None, depth=1)
添加 CCX 门。
......@@ -771,6 +779,8 @@ paddle\_quantum.ansatz.circuit
:type num_qubits: int, optional
:param depth: 层数,默认为 ``1``。
:type depth: int, optional
:param gate_name: oracle 的名字,默认为 ``O``。
:type gate_name: str, optional
.. py:method:: control_oracle(oracle, qubits_idx, num_qubits=None, depth=1)
......@@ -784,8 +794,28 @@ paddle\_quantum.ansatz.circuit
:type num_qubits: int, optional
:param depth: 层数,默认为 ``1``。
:type depth: int, optional
:param gate_name: oracle 的名字,默认为 ``cO``。
:type gate_name: str, optional
.. py:method:: collapse(qubits_idx='full', num_qubits=None, desired_result=None, if_print=False, measure_basis='z')
添加一个坍缩算子
:param qubits_idx: 作用的量子比特的编号。
:type qubits_idx: Union[Iterable[Iterable[int]], Iterable[int], int]
:param num_qubits: 总共的量子比特数量,默认为 ``None``。
:type num_qubits: int, optional
:param desired_result: 期望的坍缩态(现只支持输入计算基),默认为 ``None`` (随机坍缩)。
:type desired_result: Union[int, str]
:param if_print: 是否要打印坍缩的信息,默认为 ``True``。
:type if_print: bool, optional
:param measure_basis: 要观测的测量基底,默认为 ``z``。
:type measure_basis: Union[Iterable[paddle.Tensor], str]
:raises NotImplementdError: 要观测的测量基底只能为 ``z``,其他测量基底会在之后推出。
:raises TypeError: 当 ``backend`` 为 ``unitary_matrix`` 时,无法获取输入态的概率。
.. py:method:: superposition_layer(qubits_idx = 'full', num_qubits = None, depth = 1)
.. py:method:: superposition_layer(qubits_idx='full', num_qubits=None, depth=1)
添加一个 Hadamard 门组成的层。
......@@ -796,7 +826,7 @@ paddle\_quantum.ansatz.circuit
:param depth: 层数,默认为 ``1``。
:type depth: int, optional
.. py:method:: weak_superposition_layer(qubits_idx = 'full', num_qubits = None, depth = 1)
.. py:method:: weak_superposition_layer(qubits_idx='full', num_qubits=None, depth=1)
转角度为 :math:`\pi/4` 的 Ry 门组成的层。
......@@ -807,7 +837,7 @@ paddle\_quantum.ansatz.circuit
:param depth: 层数,默认为 ``1``。
:type depth: int, optional
.. py:method:: linear_entangled_layer(qubits_idx = 'full', num_qubits = None, depth = 1)
.. py:method:: linear_entangled_layer(qubits_idx='full', num_qubits=None, depth=1)
包含 Ry 门、Rz 门,和 CNOT 门的线性纠缠层。
......@@ -818,7 +848,7 @@ paddle\_quantum.ansatz.circuit
:param depth: 层数,默认为 ``1``。
:type depth: int, optional
.. py:method:: real_entangled_layer(qubits_idx = 'full', num_qubits = None, depth = 1)
.. py:method:: real_entangled_layer(qubits_idx='full', num_qubits=None, depth=1)
包含 Ry 门和 CNOT 门的强纠缠层。
......@@ -829,7 +859,7 @@ paddle\_quantum.ansatz.circuit
:param depth: 层数,默认为 ``1``。
:type depth: int, optional
.. py:method:: complex_entangled_layer(qubits_idx = 'full', num_qubits = None, depth = 1)
.. py:method:: complex_entangled_layer(qubits_idx='full', num_qubits=None, depth=1)
包含 U3 门和 CNOT 门的强纠缠层。
......@@ -840,7 +870,7 @@ paddle\_quantum.ansatz.circuit
:param depth: 层数,默认为 ``1``。
:type depth: int, optional
.. py:method:: real_block_layer(qubits_idx = 'full', num_qubits = None, depth = 1)
.. py:method:: real_block_layer(qubits_idx='full', num_qubits=None, depth=1)
包含 Ry 门和 CNOT 门的弱纠缠层。
......@@ -851,7 +881,7 @@ paddle\_quantum.ansatz.circuit
:param depth: 层数,默认为 ``1``。
:type depth: int, optional
.. py:method:: complex_block_layer(qubits_idx = 'full', num_qubits = None, depth = 1)
.. py:method:: complex_block_layer(qubits_idx='full', num_qubits=None, depth=1)
包含 U3 门和 CNOT 门的弱纠缠层。
......@@ -862,7 +892,7 @@ paddle\_quantum.ansatz.circuit
:param depth: 层数,默认为 ``1``。
:type depth: int, optional
.. py:method:: bit_flip(prob, qubits_idx = 'full', num_qubits = None)
.. py:method:: bit_flip(prob, qubits_idx='full', num_qubits=None)
添加比特反转信道。
......@@ -873,7 +903,7 @@ paddle\_quantum.ansatz.circuit
:param num_qubits: 总的量子比特个数,默认为 ``None``。
:type num_qubits: int, optional
.. py:method:: phase_flip(prob, qubits_idx = 'full', num_qubits = None)
.. py:method:: phase_flip(prob, qubits_idx='full', num_qubits=None)
添加相位反转信道。
......@@ -884,7 +914,7 @@ paddle\_quantum.ansatz.circuit
:param num_qubits: 总的量子比特个数,默认为 ``None``。
:type num_qubits: int, optional
.. py:method:: bit_phase_flip(prob, qubits_idx = 'full', num_qubits = None)
.. py:method:: bit_phase_flip(prob, qubits_idx='full', num_qubits=None)
添加比特相位反转信道。
......@@ -895,7 +925,7 @@ paddle\_quantum.ansatz.circuit
:param num_qubits: 总的量子比特个数,默认为 ``None``。
:type num_qubits: int, optional
.. py:method:: amplitude_damping(gamma, qubits_idx = 'full', num_qubits = None)
.. py:method:: amplitude_damping(gamma, qubits_idx='full', num_qubits=None)
添加振幅阻尼信道。
......@@ -906,7 +936,7 @@ 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, qubits_idx='full', num_qubits=None)
添加广义振幅阻尼信道。
......@@ -919,7 +949,7 @@ paddle\_quantum.ansatz.circuit
:param num_qubits: 总的量子比特个数,默认为 ``None``。
:type num_qubits: int, optional
.. py:method:: phase_damping(gamma, qubits_idx = 'full', num_qubits = None)
.. py:method:: phase_damping(gamma, qubits_idx='full', num_qubits=None)
添加相位阻尼信道。
......@@ -930,7 +960,7 @@ paddle\_quantum.ansatz.circuit
:param num_qubits: 总的量子比特个数,默认为 ``None``。
:type num_qubits: int, optional
.. py:method:: depolarizing(prob, qubits_idx = 'full', num_qubits = None)
.. py:method:: depolarizing(prob, qubits_idx='full', num_qubits=None)
添加去极化信道。
......@@ -941,7 +971,7 @@ paddle\_quantum.ansatz.circuit
:param num_qubits: 总的量子比特个数,默认为 ``None``。
:type num_qubits: int, optional
.. py:method:: pauli_channel(prob, qubits_idx = 'full', num_qubits = None)
.. py:method:: pauli_channel(prob, qubits_idx='full', num_qubits=None)
添加泡利信道。
......@@ -952,7 +982,7 @@ paddle\_quantum.ansatz.circuit
:param num_qubits: 总的量子比特个数,默认为 ``None``。
:type num_qubits: int, optional
.. py:method:: reset_channel(prob, qubits_idx = 'full', num_qubits = None)
.. py:method:: reset_channel(prob, qubits_idx='full', num_qubits=None)
添加重置信道。
......@@ -963,7 +993,7 @@ paddle\_quantum.ansatz.circuit
:param num_qubits: 总的量子比特个数,默认为 ``None``。
:type num_qubits: int, optional
.. py:method:: thermal_relaxation(const_t, exec_time, qubits_idx = 'full', num_qubits = None)
.. py:method:: thermal_relaxation(const_t, exec_time, qubits_idx='full', num_qubits=None)
添加热弛豫信道。
......@@ -976,7 +1006,7 @@ paddle\_quantum.ansatz.circuit
:param num_qubits: 总的量子比特个数,默认为 ``None``。
:type num_qubits: int, optional
.. py:method:: kraus_repr(kraus_oper, qubits_idx, num_qubits = None)
.. py:method:: kraus_repr(kraus_oper, qubits_idx, num_qubits=None)
添加一个 Kraus 表示的自定义量子信道。
......@@ -987,7 +1017,7 @@ paddle\_quantum.ansatz.circuit
:param num_qubits: 总的量子比特个数,默认为 ``None``。
:type num_qubits: int, optional
.. py:method:: unitary_matrix(num_qubits = None)
.. py:method:: unitary_matrix(num_qubits=None)
电路的酉矩阵形式
......
......@@ -41,16 +41,18 @@ paddle\_quantum.ansatz.vans
.. py:function:: cir_decompose(cir)
将电路中的 Layer 分解成量子门
将电路中的 Layer 分解成量子门, 如果需要的话可以把所有参数门的输入转为可训练参数
:param cir: 待分解电路
:param cir: 待分解电路
:type cir: Circuit
:return: 分解后的电路。
:param trainable: 是否将分解后的参数量子门输入转为参数
:type trainable: bool, optional
:return: 分解后的电路
:rtype: Circuit
.. note::
函数不支持自定义门,如 oracle 和 control-oracle
量子电路稳定支持原生门,不支持 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)
......
......@@ -175,7 +175,7 @@ paddle\_quantum.dataset
:param dimension: 编码数据的维度。
:type dimension: int
.. py:method:: encode(feature, encoding, num_qubits, return_state = True, full_return = False)
.. py:method:: encode(feature, encoding, num_qubits, return_state=True, full_return=False)
用 ``num_qubits`` 的量子比特对 ``feature`` 进行编码 ``encoding``。
......
......@@ -113,7 +113,7 @@ Fisher 信息的功能实现。
:return: 量子费舍信息矩阵的秩
:rtype: int
.. py:class:: ClassicalFisher(model, num_thetas, num_inputs, model_type = 'quantum', **kwargs)
.. py:class:: ClassicalFisher(model, num_thetas, num_inputs, model_type='quantum', **kwargs)
:param model: 经典或量子神经网络模型的实例
:type model: paddle.nn.Layer
......@@ -164,7 +164,7 @@ Fisher 信息的功能实现。
:rtype: Tuple[np.ndarray, float]
.. py:method:: get_eff_dim(normalized_cfisher, list_num_samples, gamma = 1)
.. py:method:: get_eff_dim(normalized_cfisher, list_num_samples, gamma=1)
计算经典的有效维数
......
......@@ -19,3 +19,38 @@ paddle\_quantum.gate.base
参数名为"mylayer_0.w_n",其中 "w" 是参数的名称,"n" 为自动生成的具有唯一性的后缀。如果为 ``None``,
前缀名将为小写的类名。默认为 ``None``。
:type name_scope: str, optional
.. py:method:: gate_history_generation()
生成量子门的历史记录
.. py:class:: ParamGate
基类::py:class:`paddle_quantum.gate.base.Gate`
可参数化量子门的基类。
.. py:method:: theta_generation(param, param_shape)
规范可参数化量子门的输入,并根据输入决定是否要管理或者生成参数
:param param: 可参数化量子门的输入
:type param: Union[paddle.Tensor, float, List[float]]
:param param_shape: 输入的形状
:type param_shape: List[int]
.. note::
在以下情况 ``param`` 会被转为一个参数
- ``param`` 是 ``None``
在以下情况 ``param`` 会被记录为一个参数
- ``param`` 是 `ParamBase`
在以下情况 ``param`` 会保持不变
- ``param`` 是一个 `paddle.Tensor` 但不是 `ParamBase`
- ``param`` 是一个 `float` 或者 `List[float]`
.. py:method:: gate_history_generation()
生成可参数化量子门的历史记录
......@@ -3,7 +3,7 @@ paddle\_quantum.gate.custom
自定义量子门和受控量子门的功能实现。
.. py:class:: Oracle(oracle, qubits_idx, num_qubits=None, depth=1)
.. py:class:: Oracle(oracle, qubits_idx, num_qubits=None, depth=1, gate_name='O')
基类::py:class:`paddle_quantum.gate.base.Gate`
......@@ -17,8 +17,10 @@ paddle\_quantum.gate.custom
:type num_qubits: int, optional
:param depth: 层数,默认为 ``1``。
:type depth: int, optional
:param gate_name: oracle 的名字,默认为 ``O``。
:type gate_name: str, optional
.. py:class:: ControlOracle(oracle, qubits_idx, num_qubits=None, depth=1)
.. py:class:: ControlOracle(oracle, qubits_idx, num_qubits=None, depth=1, gate_name='cO')
基类::py:class:`paddle_quantum.gate.base.Gate`
......@@ -32,3 +34,5 @@ paddle\_quantum.gate.custom
:type num_qubits: int, optional
:param depth: 层数,默认为 ``1``。
:type depth: int, optional
:param gate_name: oracle 的名字,默认为 ``cO``。
:type gate_name: str, optional
......@@ -124,3 +124,31 @@ paddle\_quantum.gate.layer
:type depth: int, optional
.. py:class:: QAOALayer(Gate)
基类::py:class:`paddle_quantum.gate.base.Gate`
QAOA 驱动层
.. note::
仅支持 MaxCut 问题
:param edges: 图的边
:type edges: Iterable
:param nodes: 图的节点
:type nodes: Iterable
:param depth: 层数,默认为 ``1``。
:type depth: int, optional
.. py:class:: QAOALayer(Gate)
基类::py:class:`paddle_quantum.gate.base.Gate`
带权重的 QAOA 驱动层
:param edges: 带权重的图的边
:type edges: Dict[Tuple[int, int], float]
:param nodes: 带权重的图的节点
:type nodes: Dict[int, float]
:param depth: 层数,默认为 ``1``。
:type depth: int, optional
......@@ -129,7 +129,7 @@ paddle\_quantum.gate.multi\_qubit\_gate
.. py:class:: CP(qubits_idx='cycle', num_qubits=None, depth=1, param=None, param_sharing=False)
基类::py:class:`paddle_quantum.gate.base.Gate`
基类::py:class:`paddle_quantum.gate.base.ParamGate`
受控 P 门。
......@@ -158,7 +158,7 @@ paddle\_quantum.gate.multi\_qubit\_gate
.. py:class:: CRX(qubits_idx='cycle', num_qubits=None, depth=1, param=None, param_sharing=False)
基类::py:class:`paddle_quantum.gate.base.Gate`
基类::py:class:`paddle_quantum.gate.base.ParamGate`
关于 x 轴的受控单量子比特旋转门。
......@@ -191,7 +191,7 @@ paddle\_quantum.gate.multi\_qubit\_gate
.. py:class:: CRY(qubits_idx='cycle', num_qubits=None, depth=1, param=None, param_sharing=False)
基类::py:class:`paddle_quantum.gate.base.Gate`
基类::py:class:`paddle_quantum.gate.base.ParamGate`
关于 y 轴的受控单量子比特旋转门。
......@@ -224,7 +224,7 @@ paddle\_quantum.gate.multi\_qubit\_gate
.. py:class:: CRZ(qubits_idx='cycle', num_qubits=None, depth=1, param=None, param_sharing=False)
基类::py:class:`paddle_quantum.gate.base.Gate`
基类::py:class:`paddle_quantum.gate.base.ParamGate`
关于 z 轴的受控单量子比特旋转门。
......@@ -257,7 +257,7 @@ paddle\_quantum.gate.multi\_qubit\_gate
.. py:class:: CU(qubits_idx='cycle', num_qubits=None, depth=1, param=None, param_sharing=False)
基类::py:class:`paddle_quantum.gate.base.Gate`
基类::py:class:`paddle_quantum.gate.base.ParamGate`
受控单量子比特旋转门。
......@@ -290,7 +290,7 @@ paddle\_quantum.gate.multi\_qubit\_gate
.. py:class:: RXX(qubits_idx='cycle', num_qubits=None, depth=1, param=None, param_sharing=False)
基类::py:class:`paddle_quantum.gate.base.Gate`
基类::py:class:`paddle_quantum.gate.base.ParamGate`
RXX 门。
......@@ -322,7 +322,7 @@ paddle\_quantum.gate.multi\_qubit\_gate
.. py:class:: RYY(qubits_idx='cycle', num_qubits=None, depth=1, param=None, param_sharing=False)
基类::py:class:`paddle_quantum.gate.base.Gate`
基类::py:class:`paddle_quantum.gate.base.ParamGate`
RYY 门。
......@@ -354,7 +354,7 @@ paddle\_quantum.gate.multi\_qubit\_gate
.. py:class:: RZZ(qubits_idx='cycle', num_qubits=None, depth=1, param=None, param_sharing=False)
基类::py:class:`paddle_quantum.gate.base.Gate`
基类::py:class:`paddle_quantum.gate.base.ParamGate`
RZZ 门。
......@@ -474,7 +474,7 @@ paddle\_quantum.gate.multi\_qubit\_gate
.. py:class:: UniversalTwoQubits(qubits_idx='cycle', num_qubits=None, depth=1, param=None, param_sharing=False)
基类::py:class:`paddle_quantum.gate.base.Gate`
基类::py:class:`paddle_quantum.gate.base.ParamGate`
两量子比特通用门,该通用门需要 15 个参数。
......@@ -492,7 +492,7 @@ paddle\_quantum.gate.multi\_qubit\_gate
.. py:class:: UniversalThreeQubits(qubits_idx='cycle', num_qubits=None, depth=1, param=None, param_sharing=False)
基类::py:class:`paddle_quantum.gate.base.Gate`
基类::py:class:`paddle_quantum.gate.base.ParamGate`
三量子比特通用门,该通用门需要 81 个参数。
......
......@@ -140,7 +140,7 @@ paddle\_quantum.gate.single\_qubit\_gate
.. py:class:: P(qubits_idx='full', num_qubits=None, depth=1, param=None, param_sharing=False)
基类::py:class:`paddle_quantum.gate.base.Gate`
基类::py:class:`paddle_quantum.gate.base.ParamGate`
单量子比特 P 门。
......@@ -167,7 +167,7 @@ paddle\_quantum.gate.single\_qubit\_gate
.. py:class:: RX(qubits_idx='full', num_qubits=None, depth=1, param=None, param_sharing=False)
基类::py:class:`paddle_quantum.gate.base.Gate`
基类::py:class:`paddle_quantum.gate.base.ParamGate`
关于 x 轴的单量子比特旋转门。
......@@ -194,7 +194,7 @@ paddle\_quantum.gate.single\_qubit\_gate
.. py:class:: RY(qubits_idx='full', num_qubits=None, depth=1, param=None, param_sharing=False)
基类::py:class:`paddle_quantum.gate.base.Gate`
基类::py:class:`paddle_quantum.gate.base.ParamGate`
关于 y 轴的单量子比特旋转门。
......@@ -221,7 +221,7 @@ paddle\_quantum.gate.single\_qubit\_gate
.. py:class:: RZ(qubits_idx='full', num_qubits=None, depth=1, param=None, param_sharing=False)
基类::py:class:`paddle_quantum.gate.base.Gate`
基类::py:class:`paddle_quantum.gate.base.ParamGate`
关于 z 轴的单量子比特旋转门。
......@@ -248,7 +248,7 @@ paddle\_quantum.gate.single\_qubit\_gate
.. py:class:: U3(qubits_idx='full', num_qubits=None, depth=1, param=None, param_sharing=False)
基类::py:class:`paddle_quantum.gate.base.Gate`
基类::py:class:`paddle_quantum.gate.base.ParamGate`
单量子比特旋转门。
......
......@@ -98,6 +98,8 @@ paddle\_quantum.gradtool
:param \*args: 用于损失函数计算的额外参数列表。
:type \*args: Any
:raise Exception: 训练数据必须是 ``paddle.Tensor`` 类型
:return: 包含如下两个元素:
- loss_list: 损失函数值随训练次数变化的列表。
- grad_list: 各参数梯度随训练次变化的列表。
......@@ -130,6 +132,8 @@ paddle\_quantum.gradtool
:param \*args: 用于损失函数计算的额外参数列表。
:type \*args: Any
:raise Exception: 训练数据必须是 ``paddle.Tensor`` 类型
.. note::
在本函数中提供了三种计算模式,``mode`` 分别可以选择 ``'single'``, ``'max'``, 以及 ``'random'``。
- mode='single': 表示计算电路中的每个可变参数梯度的平均值和方差。
......
......@@ -75,7 +75,7 @@ paddle\_quantum.hamiltonian
- pauli_words: 元素为每一项的泡利字符串,例如 'Z0, Z1, X3' 这一项的泡利字符串为 'ZZIX'。
:rtype: Tuple[list]
.. py:method:: construct_h_matrix(qubit_num = None)
.. py:method:: construct_h_matrix(qubit_num=None)
构建 Hamiltonian 在 Z 基底下的矩阵。
......
......@@ -27,7 +27,7 @@ paddle\_quantum.linalg
验证矩阵 ``P`` 是否为厄密矩阵
:param mat: 矩阵
:param mat: 厄密矩阵
:type mat: paddle.Tensor
:param eps: 容错率
:type eps: float, optional
......@@ -39,7 +39,7 @@ paddle\_quantum.linalg
验证矩阵 ``P`` 是否为映射算子
:param mat: 矩阵
:param mat: 映射算子
:type mat: paddle.Tensor
:param eps: 容错率
:type eps: float, optional
......@@ -47,11 +47,11 @@ paddle\_quantum.linalg
:return: 决定是否 :math:`PP - P = 0`
:rtype: bool
.. py:function:: is_unitary(mat, eps = 1e-5)
.. py:function:: is_unitary(mat, eps=1e-5)
验证矩阵 ``P`` 是否为酉矩阵
:param mat: 矩阵
:param mat: 矩阵
:type mat: paddle.Tensor
:param eps: 容错率
:type eps: float, optional
......@@ -66,7 +66,7 @@ paddle\_quantum.linalg
:param num_qubits: 量子比特数 n
:type num_qubits: int
:return: 一个 :math:`2^n \times 2^n` 厄密矩阵
:return: 一个 :math:`2^n \times 2^n` 厄密矩阵 (n 为量子比特数)
:rtype: paddle.Tensor
.. py:function:: orthogonal_projection_random(num_qubits)
......@@ -76,37 +76,49 @@ paddle\_quantum.linalg
:param num_qubits: 量子比特数 n
:type num_qubits: int
:return: 一个 :math:`2^n \times 2^n` 正交投影算子
:return: 一个 :math:`2^n \times 2^n` 正交投影算子 (n 为量子比特数)
:rtype: paddle.Tensor
.. py:function:: unitary_hermitian_random(num_qubits)
.. py:function:: density_matrix_random(num_qubits)
随机生成一个厄密酉矩阵
随机生成一个密度矩阵
:param num_qubits: 量子比特数 n
:type num_qubits: int
:return: 一个 :math:`2^n \times 2^n` 厄密共轭酉矩阵
:return: 一个 :math:`2^n \times 2^n` 密度矩阵 (n 为量子比特数)
:rtype: paddle.Tensor
.. py:function:: unitary_random_with_hermitian_block(num_qubits)
.. py:function:: unitary_random(num_qubits)
随机生成一个左上半部分为厄密矩阵的酉矩阵
随机生成一个酉矩阵
:param num_qubits: 量子比特数 n
:type num_qubits: int
:return: 一个左上半部分为厄密矩阵的 :math:`2^n \times 2^n` 酉矩阵
:return: 一个 :math:`2^n \times 2^n` 酉矩阵 (n 为量子比特数)
:rtype: paddle.Tensor
.. py:function:: unitary_random(num_qubits)
.. py:function:: unitary_hermitian_random(num_qubits)
随机生成一个酉矩阵
随机生成一个厄密酉矩阵
:param num_qubits: 量子比特数 n
:type num_qubits: int
:return: 一个 :math:`2^n \times 2^n` 厄密共轭酉矩阵 (n 为量子比特数)
:rtype: paddle.Tensor
.. py:function:: unitary_random_with_hermitian_block(num_qubits, is_unitary)
随机生成一个左上半部分为厄密矩阵的酉矩阵
:param num_qubits: 量子比特数 n
:type num_qubits: int
:param is_unitary: 厄密矩阵块是否是酉矩阵的 1/2
:type is_unitary: bool
:return: 一个 :math:`2^n \times 2^n` 酉矩阵
:return: 一个左上半部分为厄密矩阵的 :math:`2^n \times 2^n` 酉矩阵 (n 为量子比特数)
:rtype: paddle.Tensor
.. py:function:: haar_orthogonal(num_qubits)
......@@ -116,7 +128,7 @@ paddle\_quantum.linalg
:param num_qubits: 量子比特数 n
:type num_qubits: int
:return: 一个 :math:`2^n \times 2^n` 正交矩阵
:return: 一个 :math:`2^n \times 2^n` 正交矩阵 (n 为量子比特数)
:rtype: paddle.Tensor
.. py:function:: haar_unitary(num_qubits)
......@@ -126,7 +138,7 @@ paddle\_quantum.linalg
:param num_qubits: 量子比特数 n
:type num_qubits: int
:return: 一个 :math:`2^n \times 2^n` 酉矩阵
:return: 一个 :math:`2^n \times 2^n` 酉矩阵 (n 为量子比特数)
:rtype: paddle.Tensor
.. py:function:: haar_state_vector(num_qubits, is_real=False)
......@@ -138,7 +150,7 @@ paddle\_quantum.linalg
:param is_real: 生成的态矢量是否为实数
:type is_real: bool, optional
:return: 一个 :math:`2^n \times 1` 态矢量
:return: 一个 :math:`2^n \times 1` 态矢量 (n 为量子比特数)
:rtype: paddle.Tensor
.. py:function:: haar_density_operator(num_qubits, rank=None, is_real=False)
......@@ -152,7 +164,7 @@ paddle\_quantum.linalg
:param is_real: 生成的态矢量是否为实数
:type is_real: bool, optional
:return: 一个 :math:`2^n x 2^n` 密度矩阵
:return: 一个 :math:`2^n \times 2^n` 密度矩阵 (n 为量子比特数)
:rtype: paddle.Tensor
.. py:function:: NKron(matrix_A, matrix_B, *args)
......@@ -160,11 +172,11 @@ paddle\_quantum.linalg
计算两个及以上的矩阵的克罗内克乘积
:param matrix_A: 矩阵
:type num_qubits: np.ndarray
:type num_qubits: Union[np.ndarray, paddle.Tensor]
:param matrix_B: 矩阵
:type matrix_B: np.ndarray
:type matrix_B: Union[np.ndarray, paddle.Tensor]
:param \*args: 更多矩阵
:type \*args: np.ndarray
:type \*args: Union[np.ndarray, paddle.Tensor]
:return: 克罗内克乘积
:rtype: np.ndarray
:rtype: Union[np.ndarray, paddle.Tensor]
......@@ -49,5 +49,8 @@ paddle\_quantum.loss.measure
:type qubits_idx: Union[Iterable[int], int, str], optional
:param desired_result: 指定要返回的测量结果的概率值。默认为 ``None``,返回所有测量结果的概率值。
:type desired_result: Union[Iterable[str], str], optional
:raises NotImplementedError: 所指定的后端必须为量桨已经实现的后端
:raises NotImplementedError: ``qubits_idx`` 须为 ``Iterable`` 或 ``'full'``。
:raises NotImplementedError: 目前我们只支持在Z方向上测量。
:return: 测量结果所对应的概率值。
:rtype: paddle.Tensor
......@@ -35,6 +35,14 @@ paddle\_quantum.operator.operator
该类可以让你使用对量子态进行坍缩,坍缩到某一本征态。
:param qubits_idx: 坍缩的量子比特编号,默认为 ``'full'``.
:type qubits_idx: Union[Iterable[int], int, str], optional
:param num_qubits: 总的量子比特数量,默认为 ``None``。
:type num_qubits: int, optional
:param desired_result: 想要坍缩到的特定结果。
:type desired_result: Union[int, str]
:param if_print: 是否打印坍缩后的量子态的信息,默认为 ``'False'``.
:type if_print: bool
:param measure_basis: 测量基底。量子态会坍缩到对应的本征态上。
:type measure_basis: Union[Iterable[paddle.Tensor], str]
:raises NotImplementedError: 所输入的测量基底还没有实现。
......@@ -45,8 +53,5 @@ paddle\_quantum.operator.operator
:param state: 输入的量子态,其将会被坍缩。
:type state: paddle_quantum.State
:param desired_result: 想要坍缩到的特定结果。
:type desired_result: Union[int, str]
:raises NotImplementedError: 当前仅支持 z 基底。
:return: 坍缩后的量子态。
:rtype: paddle_quantum.State
......@@ -3,7 +3,7 @@ paddle\_quantum.qchem.hardware\_efficient
Hardware Efficient 电路模板。
.. py:class:: HardwareEfficientModel(n_qubits, depth, theta = None)
.. py:class:: HardwareEfficientModel(n_qubits, depth, theta=None)
基类: :py:class:`paddle_quantum.gate.base.Gate`
......
......@@ -3,7 +3,7 @@ paddle\_quantum.qchem.loss
量子化学中的损失函数。
.. py:class:: MolEnergyLoss(geometry, basis, multiplicity = 1, charge = 0)
.. py:class:: MolEnergyLoss(geometry, basis, multiplicity=1, charge=0)
基类::py:class:`paddle_quantum.loss.ExpecVal`
......@@ -18,7 +18,7 @@ paddle\_quantum.qchem.loss
:param charge: 分子电荷量, 默认值为 ``0``。
:type charge: int, optional
.. py:class:: RHFEnergyLoss(geometry, basis, multiplicity = 1, charge = 0)
.. py:class:: RHFEnergyLoss(geometry, basis, multiplicity=1, charge=0)
基类: :py:class:`paddle_quantum.Operator`
......
......@@ -3,6 +3,17 @@ paddle\_quantum.qchem.qchem
量子化学中的功能函数。
.. py:function:: qubitOperator_to_Hamiltonian(spin_h,tol)
将openfermion形式转化为量桨的哈密顿量形式。
:param spin_h: openfermion形式的哈密顿量。
:type spin_h: openfermion.ops.operators.qubit_operator.QubitOperator
:param tol: 阈值
:type tol: float, optional
:return: 返回转换成量桨形式的哈密顿量
:rtype: Hamiltonian
.. py:function:: geometry(structure, file)
读取分子几何信息。
......
......@@ -22,7 +22,7 @@ paddle\_quantum.qchem.slater\_determinant
:param theta: 给定旋转角度。
:type theta: float
.. py:class:: RHFSlaterDeterminantModel(n_qubits, n_electrons, mo_coeff = None)
.. py:class:: RHFSlaterDeterminantModel(n_qubits, n_electrons, mo_coeff=None)
基类::py:class:`paddle_quantum.gate.Gate`
......
......@@ -3,7 +3,7 @@ paddle\_quantum.qchem.uccsd
UCCSD 电路模板。
.. py:class:: UCCSDModel(n_qubits, n_electrons, n_trotter_steps, single_excitation_amplitude = None, double_excitation_amplitude = None)
.. py:class:: UCCSDModel(n_qubits, n_electrons, n_trotter_steps, single_excitation_amplitude=None, double_excitation_amplitude=None)
基类::py:class:`paddle_quantum.gate.Gate`
......
......@@ -3,12 +3,12 @@ paddle\_quantum.qinfo
量子信息中的常用功能实现。
.. py:function:: partial_trace(rho_AB, dim1, dim2, A_or_B)
.. py:function:: partial_trace(state, dim1, dim2, A_or_B)
计算量子态的偏迹。
:param rho_AB: 输入的量子态。
:type rho_AB: paddle_quantum.State
:param state: 输入的量子态。
:type state: Union[paddle_quantum.State, paddle.Tensor]
:param dim1: 系统A的维数。
:type dim1: int
:param dim2: 系统B的维数。
......@@ -19,12 +19,12 @@ paddle\_quantum.qinfo
:return: 输入的量子态的偏迹。
:rtype: paddle.Tensor
.. py:function:: partial_trace_discontiguous(rho, preserve_qubits = None)
.. py:function:: partial_trace_discontiguous(state, preserve_qubits=None)
计算量子态的偏迹,可选取任意子系统。
:param rho: 输入的量子态。
:type rho: paddle_quantum.State
:param state: 输入的量子态。
:type state: Union[paddle_quantum.State, paddle.Tensor]
:param preserve_qubits: 要保留的量子比特,默认为 None,表示全保留。
:type preserve_qubits: list, optional
......@@ -40,9 +40,9 @@ paddle\_quantum.qinfo
D(\rho, \sigma) = 1 / 2 * \text{tr}|\rho-\sigma|
:param rho: 量子态的密度矩阵形式。
:type rho: paddle_quantum.State
:type rho: Union[paddle_quantum.State, paddle.Tensor]
:param sigma: 量子态的密度矩阵形式。
:type sigma: paddle_quantum.State
:type sigma: Union[paddle_quantum.State, paddle.Tensor]
:return: 输入的量子态之间的迹距离。
:rtype: paddle.Tensor
......@@ -56,9 +56,9 @@ paddle\_quantum.qinfo
F(\rho, \sigma) = \text{tr}(\sqrt{\sqrt{\rho}\sigma\sqrt{\rho}})
:param rho: 量子态的密度矩阵形式。
:type rho: paddle_quantum.State
:type rho: Union[paddle_quantum.State, paddle.Tensor]
:param sigma: 量子态的密度矩阵形式。
:type sigma: paddle_quantum.State
:type sigma: Union[paddle_quantum.State, paddle.Tensor]
:return: 输入的量子态之间的保真度。
:rtype: paddle.Tensor
......@@ -89,7 +89,7 @@ paddle\_quantum.qinfo
P = \text{tr}(\rho^2)
:param rho: 量子态的密度矩阵形式。
:type rho: paddle_quantum.State
:type rho: Union[paddle_quantum.State, paddle.Tensor]
:return: 输入的量子态的纯度。
:rtype: paddle.Tensor
......@@ -103,7 +103,7 @@ paddle\_quantum.qinfo
S = -\text{tr}(\rho \log(\rho))
:param rho: 量子态的密度矩阵形式。
:type rho: paddle_quantum.State
:type rho: Union[paddle_quantum.State, paddle.Tensor]
:return: 输入的量子态的冯诺依曼熵。
:rtype: paddle.Tensor
......@@ -117,14 +117,14 @@ paddle\_quantum.qinfo
S(\rho \| \sigma)=\text{tr} \rho(\log \rho-\log \sigma)
:param rho: 量子态的密度矩阵形式
:type rho: paddle_quantum.State
:type rho: Union[paddle_quantum.State, paddle.Tensor]
:param sig: 量子态的密度矩阵形式
:type sig: paddle_quantum.State
:type sig: Union[paddle_quantum.State, paddle.Tensor]
:return: 输入的量子态之间的相对熵
:rtype: paddle.Tensor
.. py:function:: random_pauli_str_generator(n, terms = 3)
.. py:function:: random_pauli_str_generator(n, terms=3)
随机生成一个可观测量(observable)的列表( ``list`` )形式。
......@@ -158,12 +158,12 @@ paddle\_quantum.qinfo
:return: 输入列表对应的可观测量的矩阵形式。
:rtype: paddle.Tensor
.. py:function:: partial_transpose_2(density_op, sub_system = None)
.. py:function:: partial_transpose_2(density_op, sub_system=None)
计算输入量子态的 partial transpose :math:`\rho^{T_A}`。
:param density_op: 量子态的密度矩阵形式。
:type density_op: paddle_quantum.State
:type density_op: Union[paddle_quantum.State, paddle.Tensor]
:param sub_system: 1或2,表示关于哪个子系统进行 partial transpose,默认为第二个。
:type sub_system: int, optional
......@@ -175,7 +175,7 @@ paddle\_quantum.qinfo
计算输入量子态的 partial transpose :math:`\rho^{T_A}`。
:param density_op: 量子态的密度矩阵形式。
:type density_op: paddle_quantum.State
:type density_op: Union[paddle_quantum.State, paddle.Tensor]
:param n: 需要转置系统的量子比特数量。
:type n: int
......@@ -187,7 +187,7 @@ paddle\_quantum.qinfo
计算输入量子态的 Negativity :math:`N = ||\frac{\rho^{T_A}-1}{2}||`。
:param density_op: 量子态的密度矩阵形式。
:type density_op: paddle_quantum.State
:type density_op: Union[paddle_quantum.State, paddle.Tensor]
:return: 输入的量子态的 Negativity。
:rtype: paddle.Tensor
......@@ -197,27 +197,27 @@ paddle\_quantum.qinfo
计算输入量子态的 Logarithmic Negativity :math:`E_N = ||\rho^{T_A}||`。
:param density_op: 量子态的密度矩阵形式。
:type density_op: paddle_quantum.State
:type density_op: Union[paddle_quantum.State, paddle.Tensor]
:return: 输入的量子态的 Logarithmic Negativity。
:rtype: paddle.Tensor
.. py:function:: is_ppt(density_op: paddle_quantum.State)
.. py:function:: is_ppt(density_op)
计算输入量子态是否满足 PPT 条件。
:param density_op: 量子态的密度矩阵形式。
:type density_op: paddle_quantum.State
:type density_op: Union[paddle_quantum.State, paddle.Tensor]
:return: 输入的量子态是否满足 PPT 条件。
:rtype: bool
.. py:function:: schmidt_decompose(psi, sys_A = None)
.. py:function:: schmidt_decompose(psi, sys_A=None)
计算输入量子态的施密特分解 :math:`\lvert\psi\rangle=\sum_ic_i\lvert i_A\rangle\otimes\lvert i_B \rangle`。
:param psi: 量子态的向量形式,形状为(2**n)。
:type psi: paddle_quantum.State
:type psi: Union[paddle_quantum.State, paddle.Tensor]
:param sys_A: 包含在子系统 A 中的 qubit 下标(其余 qubit 包含在子系统B中),默认为量子态 :math:`\lvert \psi\rangle` 的前半数 qubit。
:type sys_A: List[int], optional
......@@ -240,7 +240,7 @@ paddle\_quantum.qinfo
:return: 编码得到的密度矩阵。
:rtype: paddle_quantum.State
.. py:function:: shadow_trace(state, hamiltonian, sample_shots, method = 'CS')
.. py:function:: shadow_trace(state, hamiltonian, sample_shots, method='CS')
估计可观测量 :math:`H` 的期望值 :math:`\text{trace}(H\rho)`。
......@@ -253,5 +253,27 @@ paddle\_quantum.qinfo
:param method: 使用 shadow 来进行估计的方法,可选 "CS"、"LBCS"、"APS" 三种方法,默认为 ``CS``。
:type method: str, optional
:raises ValueError: 输入的哈密顿量 (Hamiltonian) 形式不合法
:return: 估计可观测量 :math:`H` 的期望值。
:rtype: float
.. py:function:: tensor_product(state_a, state_b, *args)
计算输入的量子态(至少两个)的直积形式, 输出将自动返回 State 实例
:param state_a: 量子态A
:type state_a: Union[State, paddle.Tensor]
:param state_b: 量子态B
:type state_b: Union[State, paddle.Tensor]
:param args: 其他量子态
:type args: Union[State, paddle.Tensor]
:raises NotImplementedError: 当前只接收输入类型为 State 或 paddle.Tensor
.. note::
使用的 backend 必须为 DensityMatrix
:return: 输入量子态的直积
:rtype: State
\ No newline at end of file
paddle\_quantum.qsvt.qsp
============================
量子信号处理相关类与函数,具体参考论文 https://arxiv.org/abs/1806.01838
.. py:function:: signal_unitary(signal_x)
实现论文中的信号矩阵 :math:`W(x)`
:param signal_x: 输入信号,区间为[-1, 1]
:type signal_x: float
:return: matrix :math:`W(x=\text{signal_x})`
:rtype: ndarray
.. py:function:: poly_parity_verification(poly_p, k, error)
对输入多项式进行奇偶校验,判断 :math:`P` 奇偶性是否为 (k mod 2),详见论文定理 3 中的条件 2.
:param poly_p: 多项式 :math:`P(x)`
:type poly_p: Polynomial
:param k: 项数 k
:type k: int
:param error: 误差阈值,默认为 `1e-6`.
:type error: float
:return: poly_p 奇偶性是否为 (k mod 2)
:rtype: bool
.. py:function:: normalization_verification(poly_p, poly_q, trials, error)
归一化验证,判断多项式 :math:`P(x)` 和 :math:`Q(x)` 是否满足归一化条件,详见论文定理 3 中的条件 3
:param poly_p: 多项式 :math:`P(x)`
:type poly_p: Polynomial
:param poly_q: 多项式 :math:`Q(x)`
:type poly_q: Polynomial
:param trials: 验证次数,默认为 `10`
:type trials: int
:param error: 误差阈值,默认为 `1e-2`.
:type error: float
:return: 多项式是否满足归一化条件 :math:`|P|^2 + (1 - x^2)|Q|^2 = 1`
:rtype: bool
.. py:function:: angle_phi_verification(phi, poly_p, poly_p_hat, poly_q_hat, trials, error)
验证角度 :math:`\phi` 是否满足论文中的等式 6
:param phi: 旋转角 :math:`\phi`
:type phi: float
:param poly_p: 多项式 :math:`P(x)`
:type poly_p: Polynomial
:param poly_q: 多项式 :math:`Q(x)`
:type poly_q: Polynomial
:param poly_p_hat: 多项式 :math:`\tilde{P}(x)`
:type poly_p: Polynomial
:param poly_q_hat: 多项式 :math:`\tilde{Q}(x)`
:type poly_q: Polynomial
:param trials: 验证次数,默认为 `10`
:type trials: int
:param error: 误差阈值,默认为 `1e-2`.
:type error: float
:return: 角度 :math:`\phi` 是否满足论文中的等式 6.
:rtype: bool
.. py:function:: processing_unitary(list_matrices, signal_x)
构造量子信号处理矩阵 :math:`W_\Phi(x)`,详见论文中的等式 1
:param list_matrices: 一个包含信号处理矩阵的数组
:type list_matrices: List[ndarray]
:param signal_x: 输入信号 x,范围为 [-1, 1]
:type signal_x: float
:return: 量子信号处理矩阵 :math:`W_\Phi(x)`
:rtype: ndarray
.. py:function:: Phi_verification(list_phi, poly_p, trials, error)
验证完整的角度 :math:`\Phi`
:param list_phi: 包含所有角度 :math:`\phi` 的数组
:type list_phi: ndarray
:param poly_p: 多项式 :math:`P(x)`
:type poly_p: Polynomial
:param trials: 验证次数,默认为 `100`
:type trials: trials
:param error: 误差阈值,默认为 `1e-6`
:type error: float
:return: 角度 :math:`\Phi` 是否使得 :math:`W_\Phi(x)` 为 :math:`P(x)` 的块编码
:rtype: bool
.. py:function:: update_polynomial(poly_p, poly_q, phi)
计算 :math:`P, Q` 经过一层量子信号处理后的多项式 :math:`\tilde{P}, \tilde{Q}`
:param poly_p: 多项式 :math:`P(x)`
:type poly_p: Polynomial
:param poly_q: 多项式 :math:`Q(x)`
:type poly_q: Polynomial
:param phi: 量子信号处理的旋转角 :math:`\phi`
:type phi: float
:return: 更新之后的多项式 :math:`\tilde{P}(x), \tilde{Q}(x)`
:rtype: Tuple[Polynomial, Polynomial]
.. py:function:: alg_find_Phi(poly_p, poly_q, length)
计算角度 :math:`\Phi` 的算法
:param poly_p: 多项式 :math:`P(x)`
:type poly_p: Polynomial
:param poly_q: 多项式 :math:`Q(x)`
:type poly_q: Polynomial
:param length: 返回角度的个数,即量子信号处理的层数
:type length: int
:return: 包含角度的数组 :math:`\Phi`
:rtype: ndarray
.. py:function:: poly_A_hat_generation(poly_p)
计算多项式 :math:`\hat{A}(y) = 1 - P(x)P^*(x)`,其中 :math:`y = x^2`
:param poly_p: 多项式 :math:`P(x)`
:type poly_p: Polynomial
:return: 多项式 :math:`\hat{A}(y)`
:rtype: Polynomial
.. py:function:: poly_A_hat_decomposition(A_hat, error)
通过求根的方式分解多项式 :math:`\hat{A}(y)`
:param poly_p: 多项式 :math:`P(x)`
:type poly_p: Polynomial
:param error: 误差阈值,默认为 `0.001`
:type error: float
:return: 多项式 :math:`\hat{A}(y)` 的最高项系数以及根
:rtype: Tuple[float, List[float]]
.. py:function:: poly_Q_generation(leading_coef, roots, parity)
根据多项式 :math:`\hat{A}(y)` 的分解,构造多项式 :math:`Q(x)`
:param leading_coef: 多项式 :math:`\hat{A}(y)` 的最高项系数
:type leading_coef: float
:param roots: 多项式 :math:`\hat{A}(y)` 的根
:type roots: List[float]
:param parity: 多项式 :math:`Q(x)` 的奇偶性
:type parity: int
:return: 多项式 :math:`Q(x)`
:rtype: Polynomial
.. py:function:: alg_find_Q(poly_p, k)
根据多项式 :math:`P(x)` 构造多项式 :math:`Q(x)` 的算法
:param poly_p: 多项式 :math:`P(x)`
:type poly_p: Polynomial
:param k: 多项式 :math:`Q(x)` 的项数
:type k: int
:return: 多项式 :math:`Q(x)`
:rtype: Polynomial
.. py:function:: quantum_signal_processing(poly_p, length)
量子信号处理函数,找到一组角度 :math:`\Phi` 使得量子信号处理算子 :math:`W_\Phi(x)` 是一个多项式 :math:`P(x)` 的块编码
:param poly_p: 多项式 :math:`P(x)`
:type poly_p: Polynomial
:param length: 角度的个数,即量子信号处理的层数,默认 `None` 为多项式 :math:`P(x)` 的度
:type length: int
:return: 角度 :math:`\Phi`
:rtype: ndarray
.. py:function:: reflection_based_quantum_signal_processing(P)
基于反射的量子信号处理函数,找到一组角度 :math:`\Phi` 使得量子信号处理算子 :math:`W_\Phi(x)` 是一个多项式 :math:`P(x)` 的块编码,详见论文引理 8
:param poly_p: 多项式 :math:`P(x)`
:type poly_p: Polynomial
:return: 角度 :math:`\Phi`
:rtype: ndarray
.. py:class:: ScalarQSP
基类: :py:class:`object`
基于量子信号处理的类
:param poly_p: 多项式 :math:`P(x)`
:type poly_p: Polynomial
:param length: 角度的个数,即量子信号处理的层数,默认 `None` 为多项式 :math:`P(x)` 的度
:type length: int
.. py:method:: block_encoding(signal_x)
构造一个量子信号处理的电路,即实现多项式 :math:`P(x)` 的块编码电路
:param signal_x: 输入的信号 x
:type signal_x: float
:return: 量子信号处理的电路
:rtype: Circuit
.. py:method:: block_encoding_matrix(signal_x)
构造一个量子信号处理的矩阵,即实现多项式 :math:`P(x)` 的块编码矩阵
:param signal_x: 输入的信号 x
:type signal_x: float
:return: 量子信号处理的矩阵
:rtype: paddle.Tensor
paddle\_quantum.qsvt.qsp\_utils
===============================
量子信号处理相关工具函数包
.. py:function:: random_odd_poly_generation(degree, odd)
生成一个随机的满足量子信号处理要求的多项式
:param degree: 多项式的度
:type degree: int
:param odd: 多项式的奇偶性,输入 `True` 则为奇函数, `False` 则为偶函数
:type odd: bool
:return: 一个随机生成的多项式
:rtype: Polynomial
.. py:function:: clean_small_error(array)
清除相对较小的项,以提升计算精度
:param array: 目标数组
:type array: ndarray
:return: 经过清除后的数组
:rtype: ndarray
.. py:function:: poly_norm(poly, p=1)
计算一个多项式的 p 范数
:param poly: 目标多项式
:type poly: Polynomial
:param p: p 范数,默认为 `1`,输入 `0` 则是无穷范数
:type p: Optional[int]
:return: 目标多项式的 p 范数
:rtype: float
.. py:function:: poly_real(poly)
取一个多项式的实部
:param poly: 目标多项式
:type poly: Polynomial
:return: 目标多项式的实部
:rtype: Polynomial
.. py:function:: poly_imag(poly)
取一个多项式的实部
:param poly: 目标多项式
:type poly: Polynomial
:return: 目标多项式的虚部
:rtype: Polynomial
.. py:function:: poly_matrix(poly, matrix_A)
计算一个矩阵的多项式 poly(matrix_A)
:param poly: 输入多项式
:type poly: Polynomial
:param matrix_A: 输入矩阵
:type matrix_A: paddle.Tensor
:return: 矩阵的多项式结果 poly(matrix_A)
:rtype: paddle.Tensor
.. py:function:: exp_matrix(t, matrix_A)
计算矩阵指数 :math:`e^{itA}`
:param t: 演化时间
:type t: float
:param matrix_A: 目标矩阵 A
:type matrix_A: paddle.Tensor
:return: 矩阵指数 :math:`e^{itA}`
:rtype: paddle.Tensor
\ No newline at end of file
paddle\_quantum.qsvt.qsvt
============================
量子奇异值变换
.. py:function:: block_encoding_projector(num_qubits, num_projected_qubits)
生成块编码的投影算子
:param num_qubits: 量子比特数量
:type num_qubits: int
:param num_projected_qubits: 被投影的量子比特数量,默认为 `num_qubits - 1`
:type num_projected_qubits: int
:return: 投影算子 :math:`|0\rangle\langle0| \otimes I`
:rtype: paddle.Tensor
.. py:function:: qubitization(proj, phi)
单比特化操作,生成等同于 :math:`e^{i \phi (2P - I)}` 的电路
:param proj: 正交投影算子 :math:`P`
:type proj: paddle.Tensor
:param phi: 角度 :math:`\phi`
:type phi: paddle.Tensor
:return: :math:`e^{i \phi (2P - I)}` 的电路
:rtype: Circuit
.. py:class:: QSVT
基类: :py:class:`object`
:param poly_p: 多项式 :math:`P(x)`
:type poly_p: Polynomial
:param oracle: 酉算子 :math:`U`,为一个厄米特矩阵 :math:`X` 的块编码
:type oracle: paddle.Tensor
:param m: 厄米特矩阵 :math:`X` 的系统量子比特数量,默认为酉算子 :math:`U` 量子比特数量 - 1
.. py:method:: block_encoding_matrix()
构造一个对于厄米特矩阵 :math:`X` 的量子奇异值变换矩阵,即实现多项式 :math:`P(X)` 的块编码矩阵
:return: 量子奇异值变换矩阵
:rtype: paddle.Tensor
.. py:method:: block_encoding_circuit()
构造一个对于厄米特矩阵 :math:`X` 的量子奇异值变换电路,即实现多项式 :math:`P(X)` 的块编码电路
:return: 量子奇异值变换电路
:rtype: Circuit
.. py:method:: block_encoding_unitary()
返回一个对于厄米特矩阵 :math:`X` 的量子奇异值变换电路的酉矩阵形式,用于验证正确性
:return: 量子奇异值变换电路的酉矩阵
:rtype: paddle.Tensor
\ No newline at end of file
paddle\_quantum.qsvt
============================
量子奇异值变换模块
.. rubric:: Submodules
.. toctree::
:maxdepth: 4
paddle_quantum.qsvt.qsp_utils
paddle_quantum.qsvt.qsp
paddle_quantum.qsvt.qsvt
\ No newline at end of file
......@@ -20,5 +20,8 @@ paddle\_quantum.shadow
:param method: 进行随机采样的方法,有 ``'CS'`` 、 ``'LBCS'`` 、 ``'APS'`` 三种方法,默认为 ``'CS'``。
:type method: str, optional
:raises ValueError: 输入的哈密顿量 (Hamiltonian) 形式不合法
:raises NotImplementedError: 输入 ``state`` 的 ``backend`` 必须是 ``StateVector`` 或 ``DensityMatrix``
:return: 随机选择的泡利测量基和测量结果,形状为 ``(sample_shots, 2)`` 的list。
:rtype: list
......@@ -77,6 +77,8 @@ paddle\_quantum.state.common
p_{1}|\Phi^{+}\rangle\langle\Phi^{+}|+p_{2}| \Psi^{+}\rangle\langle\Psi^{+}|+p_{3}| \Phi^{-}\rangle\langle\Phi^{-}| +
p_{4}|\Psi^{-}\rangle\langle\Psi^{-}|
:param prob: 各个贝尔态的概率。
:type: List[float]
:raises Exception: 当后端为态矢量时,所输入量子态应该为纯态。
:raises NotImplementedError: 所指定的后端必须为量桨已经实现的后端。
......@@ -123,7 +125,7 @@ paddle\_quantum.state.common
:param num_qubits: 量子态所包含的量子比特数。
:type num_qubits: int
:raises Exception: 所指定的后端必须为态矢量
:raises Exception: 当后端为态矢量时,所输入量子态应该为纯态
:raises NotImplementedError: 所指定的后端必须为量桨已经实现的后端。
:returns: 生成的 GHZ-state。
:rtype: paddle_quantum.State
......
......@@ -17,6 +17,17 @@ paddle\_quantum.state.state
:type backend: paddle_quantum.Backend, optional
:param dtype: 量子态的数据类型。默认为 None,使用全局的默认数据类型。
:type dtype: str, optional
:raises Exception: 所输入的量子态维度不正确。
:raises NotImplementedError: 所指定的后端必须为量桨已经实现的后端。
.. py:property:: ket()
得到量子态的列向量形式。
.. py:property:: bra()
得到量子态的行向量形式。
.. py:method:: numpy()
......@@ -55,6 +66,7 @@ paddle\_quantum.state.state
:type hamiltonian: paddle_quantum.Hamiltonian
:param shots: 测量次数。
:type shots: int
:raises NotImplementedError: 所指定的后端必须为量桨已经实现的后端。
:return: 该量子态关于可观测量的期望值。
:rtype: float
......@@ -69,5 +81,8 @@ paddle\_quantum.state.state
:type qubits_idx: Union[Iterable[int], int], optional
:param plot: 是否画图。默认为 Flase,表示不画图。
:type plot: bool, optional
:raises Exception: 测量的次数必须大于0。
:raises NotImplementedError: 所指定的后端必须为量桨已经实现的后端。
:raises NotImplementedError: 输入的量子比特下标有误。
:return: 测量结果。
:rtype: dict
......@@ -4,7 +4,7 @@ paddle\_quantum.trotter
Trotter 哈密顿量时间演化的功能实现。
.. py:function:: construct_trotter_circuit(circuit, hamiltonian, tau, steps, method = 'suzuki', order = 1, grouping = None, coefficient = None, permutation = None)
.. py:function:: construct_trotter_circuit(circuit, hamiltonian, tau, steps, method='suzuki', order=1, grouping=None, coefficient=None, permutation=None)
向 circuit 的后面添加 trotter 时间演化电路,即给定一个系统的哈密顿量 H,该电路可以模拟系统的时间演化 :math:`U_{cir} e^{-iHt}`。
......@@ -27,6 +27,11 @@ Trotter 哈密顿量时间演化的功能实现。
:param permutation: 自定义哈密顿量的排列方式,默认为 ``None``,仅在 ``method='custom'`` 时有效。
:type permutation: np.ndarray, optional
:raises ValueError: Trotter-Suzuki 分解的阶数 ``order`` 必须为 ``1``, ``2``, 或 ``2k``, 其中 ``k`` 是一个整数
:raises ValueError: ``permutation`` 和 ``coefficient`` 的形状不一致
:raises ValueError: 重排策略 ``grouping`` 的方法不支持, 仅支持 ``'xyz'``, ``'even_odd'``
:raises ValueError: 搭建时间演化电路的方法 ``method`` 不支持, 仅支持 ``'suzuki'``, ``'custom'``
.. Hint::
想知道该函数是如何模拟的?更多信息请移步至量桨官网教程: https://qml.baidu.com/tutorials/overview.html.
......@@ -91,7 +96,7 @@ Trotter 哈密顿量时间演化的功能实现。
:return: 系数数组。
:rtype: np.ndarray
.. py:function:: get_1d_heisenberg_hamiltonian(length, j_x = 1.0, j_y = 1.0, j_z = 1.0, h_z = 0.0, periodic_boundary_condition = True)
.. py:function:: get_1d_heisenberg_hamiltonian(length, j_x=1.0, j_y=1.0, j_z=1.0, h_z=0.0, periodic_boundary_condition=True)
生成一个一维海森堡链的哈密顿量。
......
......@@ -73,4 +73,7 @@ paddle\_quantum.visual
:param density_matrix: 多量子比特的量子态的状态向量或者密度矩阵,要求量子数大于 1。
:type density_matrix: paddle_quantum.State
:param size: 条宽度,在 0 到 1 之间,默认为 ``0.3``。
:type size: float, optional
\ No newline at end of file
:type size: float, optional
:raises TypeError: 要求输入的 ``density_matrix`` 类型为 ``numpy.ndarray``, ``paddle.Tensor``, 或者 ``paddle_quantum.State``
:raises ValueError: 要求输入的 ``density_matrix`` 是一个方阵
\ No newline at end of file
......@@ -23,14 +23,14 @@ Paddle Quantum。目前支持网页阅览和\ `下载运行 Jupyter Notebook <ht
--------
我们提供了涵盖量子模拟、机器学习、组合优化、本地操作与经典通讯(local operations and classical communication, LOCC)、量子神经网络等多个领域的案例供大家学习。与\ `入门手册 </quick-start/overview.html>`__\ 类似,每个教程目前支持
\ `网页阅览 </tutorials/overview.html>`__\ 和\ `下载运行 Jupyter Notebook <https://github.com/PaddlePaddle/Quantum/tree/master/tutorial>`__\ 两种方式。我们推荐用户下载 Notebook
\ `网页阅览 </tutorials/overview.html>`__\ 和\ `下载运行 Jupyter Notebook <https://github.com/PaddlePaddle/Quantum/tree/master/tutorials>`__\ 两种方式。我们推荐用户下载 Notebook
后,本地运行进行实践。
- `量子模拟 <https://github.com/PaddlePaddle/Quantum/blob/master/tutorial/quantum_simulation>`__
- `机器学习 <https://github.com/PaddlePaddle/Quantum/blob/master/tutorial/machine_learning>`__
- `组合优化 <https://github.com/PaddlePaddle/Quantum/blob/master/tutorial/combinatorial_optimization>`__
- `LOCCNet <https://github.com/PaddlePaddle/Quantum/blob/master/tutorial/locc>`__
- `量子神经网络研究 <https://github.com/PaddlePaddle/Quantum/blob/master/tutorial/qnn_research>`__
- `量子模拟 <https://github.com/PaddlePaddle/Quantum/blob/master/tutorials/quantum_simulation>`__
- `机器学习 <https://github.com/PaddlePaddle/Quantum/blob/master/tutorials/machine_learning>`__
- `组合优化 <https://github.com/PaddlePaddle/Quantum/blob/master/tutorials/combinatorial_optimization>`__
- `LOCCNet <https://github.com/PaddlePaddle/Quantum/blob/master/tutorials/locc>`__
- `量子神经网络研究 <https://github.com/PaddlePaddle/Quantum/blob/master/tutorials/qnn_research>`__
随着 LOCCNet 模组的推出,量桨现已支持分布式量子信息处理任务的高效模拟和开发。感兴趣的读者请参见 `教程 </tutorials/loccnet/loccnet-framework.html>`__。
Paddle Quantum 也支持在 GPU
......
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 使用量桨通过量易伏平台连接量子计算机\n",
"\n",
"*Copyright (c) 2022 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.*\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 简介\n",
"\n",
"在量子机器学习中,我们最终想实现的目标就是使用量子计算机和经典计算机进行混合计算,从而实现高效的量子机器学习(Quantum Machine Learning, QML)算法。在量桨(Paddle Quantum)中,我们也支持通过[量易伏](https://quantum-hub.baidu.com/)这一云原生量子计算平台连接到真实的量子计算机,从而使用量子计算机实现 QML 算法。\n",
"\n",
"### 量易伏简介\n",
"\n",
"量易伏是由百度研究院量子计算研究所推出的云原生量子计算平台。量易伏很好地实现了量子计算和云计算的深度融合。量易包含本地模拟器、云端模拟器和云端量子计算机等多种使用方式。其中,云端模拟器和云端量子计算机的使用需要消耗量易伏点数,用户需要在[量易伏网站](https://quantum-hub.baidu.com/)上进行注册后可获得量易伏账号和点数。量易伏包含 QComposer、PyOnline、YunOnline、QCompute SDK 等多种调用方式。其中 QCompute SDK 允许我们通过 Python 进行调用。在 Python 环境中,需要输入账号对应的 token 来进行调用,token 可在 https://quantum-hub.baidu.com/token 上进行查看。如果想使用云端模拟器或云端量子计算机,需要消耗量易伏点数,点数可在 https://quantum-hub.baidu.com/feedback 页面发送邮件进行获取。\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 量桨连接量易伏\n",
"\n",
"目前量桨已经支持连接量易伏,只需要使用 `paddle_quantum.set_backend('quleaf')` 即可将量桨的后端设置为量易伏。除此之外,我们还需要设置量易伏的模拟方式。如果使用云端算力,则还需要输入 token。因此,完整的设置代码如下:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import paddle_quantum\n",
"from QCompute import BackendName\n",
"paddle_quantum.set_backend('quleaf')\n",
"paddle_quantum.backend.quleaf.set_quleaf_backend(BackendName.LocalBaiduSim2)\n",
"# 如果使用本地模拟器,则可以不需要输入 token\n",
"# paddle_quantum.backend.quleaf.set_quleaf_token('your token')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"在 `set_quleaf_backend()` 函数中可以设置量易伏的后端模拟方式。\n",
"\n",
"目前,量易伏的所有后端如下:\n",
"\n",
"| 类型 | 量子端 | 说明 |\n",
"| :--: | :--: | :--: |\n",
"| 本地 | LocalBaiduSim2 | 使用 Python 编写的 Sim2 本地版 |\n",
"| 云端 | CloudBaiduSim2Water | 使用 C++ 编写的多实例 Sim2 模拟器云版 |\n",
"| 云端 | CloudBaiduSim2Earth | 使用 Python 编写的单一实例高配置 Sim2 模拟器云版 |\n",
"| 云端 | CloudBaiduSim2Thunder | 使用 C++ 编写的单一实例高配置 Sim2 模拟器云版 |\n",
"| 云端 | CloudBaiduSim2Wind | 使用 C++ 编写的单一实例 Sim2 模拟器云版(支持稀疏模式) |\n",
"| 云端 | CloudBaiduSim2Heaven | 使用 C++ 编写的单一实例集群 Sim2 模拟器云版 |\n",
"| 云端 | CloudBaiduSim2Lake | 使用 C++ 编写的单一实例 Sim2 模拟器云版 (支持 GPU 运算) |\n",
"| 云端 | CloudAerAtBD | 开源 Aer(C++ 版) 模拟器云版 |\n",
"| 云端 | CloudIoPCAS | 来自中科院物理所的 10 比特量子真机 (VIP) |\n",
"\n",
"其中,`LocalBaiduSim2` 为本地模拟器,不需要输入 token,不会使用量易伏点数;`CloudIoPCAS` 为真实的量子计算机,云端的量子计算机和模拟器都需要输入token,且会消耗量易伏点数。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 贝尔态制备\n",
"\n",
"这里,我们以制备贝尔态为例测试量桨是否成功连接量易伏。在执行了上面的代码之后,用户就已经将量桨设置为了量易伏模式。"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"num_qubits = 2\n",
"init_state = paddle_quantum.state.zero_state(num_qubits)\n",
"circuit = paddle_quantum.ansatz.Circuit(num_qubits)\n",
"circuit.h(0)\n",
"circuit.cnot([0, 1])\n",
"bell_state = circuit(init_state)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"如果上面的代码能成功运行,则说明可以连接到量易伏,并执行量子电路。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## VQE 例子\n",
"\n",
"这里,我们以VQE为例来介绍如何通过量桨调用量易伏算力。我们使用量易伏的本地模拟器来进行 demo 演示。"
]
},
{
"cell_type": "code",
"execution_count": 4,
"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 theoretical value is -1.137283834485513.\n"
]
}
],
"source": [
"import paddle\n",
"\n",
"# 定义哈密顿量\n",
"hamiltonian_list = [\n",
" [-0.0970662686176252, 'I'],\n",
" [-0.04530261550868938, 'X0, X1, Y2, Y3'],\n",
" [0.04530261550868938, 'X0, Y1, Y2, X3'],\n",
" [0.04530261550868938, 'Y0, X1, X2, Y3'],\n",
" [-0.04530261550868938, 'Y0, Y1, X2, X3'],\n",
" [0.1714128263940238, 'Z0'],\n",
" [0.16868898168693292, 'Z0, Z1'],\n",
" [0.12062523481381847, 'Z0, Z2'],\n",
" [0.1659278503225078, 'Z0, Z3'],\n",
" [0.17141282639402383, 'Z1'],\n",
" [0.1659278503225078, 'Z1, Z2'],\n",
" [0.12062523481381847, 'Z1, Z3'],\n",
" [-0.22343153674664024, 'Z2'],\n",
" [0.17441287610651632, 'Z2, Z3'],\n",
" [-0.2234315367466403, 'Z3'],\n",
"]\n",
"\n",
"# 定义电路\n",
"num_qubits = 4\n",
"circuit = paddle_quantum.ansatz.Circuit(num_qubits)\n",
"circuit.ry('full')\n",
"circuit.cnot('cycle')\n",
"circuit.ry('full')\n",
"circuit.cnot('cycle')\n",
"circuit.ry('full')\n",
"# print(circuit)\n",
"\n",
"# 定义初态和优化器\n",
"init_state = paddle_quantum.state.zero_state(num_qubits)\n",
"optimizer = paddle.optimizer.Adam(learning_rate=0.1, parameters=circuit.parameters())\n",
"hamiltonian = paddle_quantum.Hamiltonian(hamiltonian_list)\n",
"loss_func = paddle_quantum.loss.ExpecVal(hamiltonian, shots=10000)\n",
"# 进行迭代训练\n",
"num_itr = 80\n",
"for itr in range(0, num_itr):\n",
" state = circuit(init_state)\n",
" loss = loss_func(state)\n",
" loss.backward()\n",
" optimizer.minimize(loss)\n",
" optimizer.clear_grad()\n",
" if itr % 10 == 0:\n",
" print(f\"The iter is {itr:3d}, loss is {loss.item():3.5f}.\")\n",
"print(\"The theoretical value is -1.137283834485513.\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"由上面的训练过程可以看出,我们可以通过量桨调用量易伏来实现量子机器学习算法。\n",
"\n",
"最后,我们总结一下量桨调用量易伏的用法。只需要在程序的最开头部分设置量桨和量易伏的 backend 就行。需要注意的是,很多函数都不支持在量易伏上运行,只有量子电路相关的功能才支持。"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3.8.0 ('paddle-quantum-dev')",
"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.0"
},
"orig_nbformat": 4,
"vscode": {
"interpreter": {
"hash": "9043b12ec77a531919bc05f05830335d23baf822720cbea14b03018197d26545"
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Using Paddle Quantum to connect to a quantum computer via the QuLeaf platform\n",
"\n",
"*Copyright (c) 2022 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.*\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Introduction\n",
"\n",
"In quantum machine learning, the ultimate goal we want to achieve is to use quantum computers and classical computers for hybrid computation, thus enabling efficient Quantum Machine Learning (QML) algorithms. In Paddle Quantum, we also support the implementation of QML algorithms using quantum computers by connecting to a real quantum computer via [QuLeaf](https://quantum-hub.baidu.com/), a cloud-native quantum computing platform.\n",
"\n",
"### Introduction to QuLeaf\n",
"\n",
"QuLeaf is a cloud-native quantum computing platform launched by the Institute of Quantum Computing of Baidu Research Institute. QuLeaf is a good implementation of the deep integration of quantum computing and cloud computing. QuLeaf includes various usage methods such as local simulator, cloud-based simulator and cloud-based quantum computer. Among them, the use of cloud simulator and cloud quantum computer needs to consume QuLeaf credits, users need to register on the [QuLeaf website](https://quantum-hub.baidu.com/) to get QuLeaf account and points. QuLeaf includes QComposer, PyOnline, YunOnline, QCompute SDK and so on. Among them, QCompute SDK allows us to make calls through Python. In the Python environment, you need to enter the token corresponding to your account to make the call, and the token can be viewed at https://quantum-hub.baidu.com/token. If you want to use the cloud-based simulator or cloud-based quantum computer, you need to consume QuLeaf credits which can be obtained in the https://quantum-hub.baidu.com/feedback."
]
},
{
"cell_type": "markdown",
"metadata": {},
"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."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import paddle_quantum\n",
"from QCompute import BackendName\n",
"paddle_quantum.set_backend('quleaf')\n",
"paddle_quantum.backend.quleaf.set_quleaf_backend(BackendName.LocalBaiduSim2)\n",
"# If you are using the local simulator, you don't need to enter your token\n",
"# paddle_quantum.backend.quleaf.set_quleaf_token('your token')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `set_quleaf_backend()` function allows you to set the quantum end of QuLeaf.\n",
"\n",
"Currently, all the end the QuLeaf are as follows:\n",
"\n",
"| Type | Quantum End | Description |\n",
"| :---: | :---: | :---: |\n",
"| Local | LocalBaiduSim2 | Sim2, local simulator, Python version |\n",
"| Cloud | CloudBaiduSim2Water | Sim2, Cloud Simulator, C++ Version, Dockerd Multiple Instances |\n",
"| Cloud | CloudBaiduSim2Earth | Sim2, Cloud Simulator, Python Version, Single Instance, high-performance |\n",
"| Cloud | CloudBaiduSim2Thunder | Sim2, Cloud Simulator, C++ Version, Single Instance, high-performance |\n",
"| Cloud | CloudBaiduSim2Wind | Sim2, Cloud Simulator, C++ Version, Single Instance, Sparse |\n",
"| Cloud | CloudBaiduSim2Heaven | Sim2, Cloud Simulator, C++ Version, Single Instance, Cluster |\n",
"| Cloud | CloudBaiduSim2Lake | Sim2, Cloud Simulator, C++ Version, Single Instance, GPU |\n",
"| Cloud | CloudAerAtBD | Aer, Cloud Simulator, C++ Version (open-source) |\n",
"| Cloud | CloudIoPCAS | QPU 10-qubit quantum computer, from the Institute of Physics CAS |\n",
"\n",
"In this case, `LocalBaiduSim2` is a local simulator, which does not require token input and does not consume the QuLeaf credits; `CloudIoPCAS` is a real quantum computer, both the quantum computer and the simulator in the cloud require token input and consume the QuLeaf credits."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Bell state preparation\n",
"\n",
"Here, we test whether the paddle quantum is successfully connected to the QuLeaf by the example of the Bell state preparation. After executing the above code, the user has already set the paddle quantum to the QuLeaf mode."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"num_qubits = 2\n",
"init_state = paddle_quantum.state.zero_state(num_qubits)\n",
"circuit = paddle_quantum.ansatz.Circuit(num_qubits)\n",
"circuit.h(0)\n",
"circuit.cnot([0, 1])\n",
"bell_state = circuit(init_state)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If the above code runs successfully, it means that it can connect to the QuLeaf and execute the quantum circuit."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## VQE Example\n",
"\n",
"Here, we use VQE as an example to show how to use the QuLeaf through the paddle quantum. We use QuLeaf's local simulator for the demo."
]
},
{
"cell_type": "code",
"execution_count": 4,
"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 theoretical value is -1.137283834485513.\n"
]
}
],
"source": [
"import paddle\n",
"\n",
"# define the hamiltonian\n",
"hamiltonian_list = [\n",
" [-0.0970662686176252, 'I'],\n",
" [-0.04530261550868938, 'X0, X1, Y2, Y3'],\n",
" [0.04530261550868938, 'X0, Y1, Y2, X3'],\n",
" [0.04530261550868938, 'Y0, X1, X2, Y3'],\n",
" [-0.04530261550868938, 'Y0, Y1, X2, X3'],\n",
" [0.1714128263940238, 'Z0'],\n",
" [0.16868898168693292, 'Z0, Z1'],\n",
" [0.12062523481381847, 'Z0, Z2'],\n",
" [0.1659278503225078, 'Z0, Z3'],\n",
" [0.17141282639402383, 'Z1'],\n",
" [0.1659278503225078, 'Z1, Z2'],\n",
" [0.12062523481381847, 'Z1, Z3'],\n",
" [-0.22343153674664024, 'Z2'],\n",
" [0.17441287610651632, 'Z2, Z3'],\n",
" [-0.2234315367466403, 'Z3'],\n",
"]\n",
"\n",
"# define the quantum circuit\n",
"num_qubits = 4\n",
"circuit = paddle_quantum.ansatz.Circuit(num_qubits)\n",
"circuit.ry('full')\n",
"circuit.cnot('cycle')\n",
"circuit.ry('full')\n",
"circuit.cnot('cycle')\n",
"circuit.ry('full')\n",
"# print(circuit)\n",
"\n",
"# define the initial quantum state and the optimizer\n",
"init_state = paddle_quantum.state.zero_state(num_qubits)\n",
"optimizer = paddle.optimizer.Adam(learning_rate=0.1, parameters=circuit.parameters())\n",
"hamiltonian = paddle_quantum.Hamiltonian(hamiltonian_list)\n",
"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",
" state = circuit(init_state)\n",
" loss = loss_func(state)\n",
" loss.backward()\n",
" optimizer.minimize(loss)\n",
" optimizer.clear_grad()\n",
" if itr % 10 == 0:\n",
" print(f\"The iter is {itr:3d}, loss is {loss.item():3.5f}.\")\n",
"print(\"The theoretical value is -1.137283834485513.\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"From the above training process, we can see that we can implement quantum machine learning algorithm by paddle quantum calling the QuLeaf.\n",
"\n",
"Finally, let's summarize the usage of the paddle quantum to call the QuLeaf. All you need to do is to set the backend of the paddle quantum and the QuLeaf in the beginning of the program. Note that many functions are not supported on the QuLeaf, only quantum circuit related functions are supported."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3.8.0 ('paddle-quantum-dev')",
"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.0"
},
"orig_nbformat": 4,
"vscode": {
"interpreter": {
"hash": "9043b12ec77a531919bc05f05830335d23baf822720cbea14b03018197d26545"
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}
......@@ -35,7 +35,8 @@ options = {
}
def main(n=4):
if __name__ == "__main__":
n = 4
paddle.seed(SEED)
p = 4 # number of layers in the circuit
......@@ -73,7 +74,3 @@ def main(n=4):
ax.margins(0.20)
plt.axis("off")
plt.show()
if __name__ == "__main__":
main()
......@@ -33,13 +33,13 @@ __all__ = [
def maxcut_hamiltonian(E):
r"""生成最大割问题对应的哈密顿量。
r"""Generate the Hamiltonian for Max-Cut problem
Args:
E (list): 图的边
E (list): Edges of the graph
Returns:
list: 生成的哈密顿量的列表形式
list: list form of the generated Hamiltonian
"""
H_D_list = []
for (u, v) in E:
......@@ -49,22 +49,22 @@ def maxcut_hamiltonian(E):
def find_cut(G, p, ITR, LR, print_loss=False, shots=0, plot=False):
r"""运行 QAOA 寻找最大割问题的近似解。
r"""Find the approximated solution of given Max-Cut problem via QAOA
Args:
G (NetworkX graph):
p (int): QAOA 电路的层数
ITR (int): 梯度下降优化参数的迭代次数
LR (float): Adam 优化器的学习率
print_loss (bool, optional): 优化过程中是否输出损失函数的值,默认为 ``False``,即不输出
shots (int, optional): QAOA 电路最终输出的量子态的测量次数,默认 0,则返回测量结果的精确概率分布
plot (bool, optional): 是否绘制测量结果图,默认为 ``False`` ,即不绘制
G (NetworkX graph): Graph
p (int): depth of the QAOA circuit
ITR (int): maximum iteration times for optimization
LR (float): learning rate of the Adam optimizer
print_loss (bool, optional): whether print the loss value during optimization. Defaults to ``False``, not print
shots (int, optional): measurement times at the final output of QAOA circuit, Defaults to ``0``, exact probability distribution
plot (bool, optional): whether plot the result of measurement, Defaults to ``False``, not plot
Returns:
tuple: tuple containing:
string: 寻找到的近似解
dict: 所有测量结果和其对应的出现次数
string: approximated solution
dict: measurement results and their frequencies
"""
V = list(G.nodes())
# Map nodes' labels to integers from 0 to |V|-1
......
......@@ -34,13 +34,15 @@ __all__ = [
def tsp_hamiltonian(g, A, n):
"""
This is to construct Hamiltonia H_C
r"""This is to construct Hamiltonia H_C
Args:
G: the graph to solve
g: the graph to solve
A: the penality parameter
n: the number of vertices of graph g
Returns:
Hamiltonian list
Hamiltonian H_C
Hamiltonian with list form
"""
H_C_list1 = []
for i in range(n - 1):
......@@ -93,8 +95,7 @@ def tsp_hamiltonian(g, A, n):
def solve_tsp(g, A, p=2, ITR=120, LR=0.4, print_loss=False, shots=0):
"""
This is the core function to solve the TSP.
r"""This is the core function to solve the TSP.
Args:
g: the graph to solve
......@@ -102,6 +103,9 @@ def solve_tsp(g, A, p=2, ITR=120, LR=0.4, print_loss=False, shots=0):
p: number of layers of blocks in the complex entangled circuit (default value p=2)
ITR: number of iteration steps for the complex entangled circuit (default value ITR=120)
LR: learning rate for the gradient-based optimization method (default value LR=0.4)
print_loss (bool, optional): whether print the loss value during optimization. Defaults to ``False``, not print
shots (int, optional): measurement times at the final output of QAOA circuit, Defaults to ``0``, exact probability distribution
Returns:
string representation for the optimized walk for the salesman
"""
......
......@@ -23,10 +23,15 @@ __all__ = ["H_generator"]
def H_generator(N):
r"""Generate a Hamiltonian with trivial descriptions
Args:
N: Number of Pauli strings
Returns:
A Hamiltonian
"""
Generate a Hamiltonian with trivial descriptions
Returns: A Hamiltonian
"""
# Generate the Pauli string representing a random Hamiltonian
hamiltonian = random_pauli_str_generator(N, terms=10)
print("Random Hamiltonian in Pauli string format = \n", hamiltonian)
......
......@@ -37,6 +37,16 @@ __all__ = [
def loss_func(U, H):
r"""Compute the loss function of SSVQE
Args:
H: Hamiltonian
U: unitary of the circuit
Returns: Tutle: inlcuding following elements
- loss function
- loss components
"""
# Calculate loss function
loss_struct = paddle.real(matmul(matmul(dagger(U), H), U))
# Use computational basis to calculate each expectation value, which is the same
......@@ -55,13 +65,16 @@ def loss_func(U, H):
def Paddle_SSVQE(H, N=2, ITR=50, LR=0.3):
r"""
Paddle_SSVQE
:param H: Hamiltonian
:param N: Number of qubits/Width of QNN
:param ITR: Number of iterations
:param LR: Learning rate
:return: First several smallest eigenvalues of the Hamiltonian
r"""Paddle_SSVQE
Args:
H: Hamiltonian
N: Number of qubits/Width of QNN
ITR: Number of iterations
LR: Learning rate
Returns:
First several smallest eigenvalues of the Hamiltonian
"""
# We need to convert Numpy array to variable supported in PaddlePaddle
......@@ -89,7 +102,7 @@ def Paddle_SSVQE(H, N=2, ITR=50, LR=0.3):
return loss_components
def main():
if __name__ == '__main__':
paddle.seed(SEED)
N = 2
H = H_generator(N)
......@@ -127,6 +140,3 @@ def main():
output_ordinalvalue(i), numpy.linalg.eigh(H)[0][i])
)
if __name__ == '__main__':
main()
......@@ -20,9 +20,10 @@ main
import numpy
from paddle_quantum.SSVQE.HGenerator import H_generator
from paddle_quantum.SSVQE.Paddle_SSVQE import Paddle_SSVQE
def main():
if __name__ == '__main__':
N = 2
H = H_generator(N)
......@@ -38,8 +39,4 @@ def main():
print('The theoretical 2nd excited state energy: ', numpy.linalg.eigh(H)[0][2])
print('The estimated 3rd excited state energy is: ', loss_components[3].numpy())
print('The theoretical 3rd excited state energy: ', numpy.linalg.eigh(H)[0][3])
if __name__ == '__main__':
main()
print('The theoretical 3rd excited state energy: ', numpy.linalg.eigh(H)[0][3])
\ No newline at end of file
......@@ -37,14 +37,14 @@ __all__ = [
def Paddle_VQE(Hamiltonian, N, D=2, ITR=80, LR=0.2):
r"""
Main Learning network using dynamic graph
:param Hamiltonian: Hamiltonian
:param N: Width of QNN
:param D: Depth of QNN
:param ITR: Number of iterations
:param LR: Learning rate
:return: No return
r"""Main Learning network using dynamic graph
Args:
Hamiltonian: Hamiltonian
N: Width of QNN
D: Depth of QNN. Defaults to 2.
ITR: Number of iterations. Defaults to 80.
LR: Learning rate. Defaults to 0.2.
"""
# Determine the dimensions of network
......@@ -86,7 +86,7 @@ def Paddle_VQE(Hamiltonian, N, D=2, ITR=80, LR=0.2):
savez("./output/summary_data", iter=summary_iter, energy=summary_loss)
def main():
if __name__ == '__main__':
# Read data from built-in function or xyz file depending on OS
sysStr = platform.system()
......@@ -110,7 +110,3 @@ def main():
Paddle_VQE(hamiltonian, N)
benchmark_result()
if __name__ == '__main__':
main()
......@@ -29,10 +29,15 @@ __all__ = [
]
def Hamiltonian_str_convert(qubit_op):
'''
Convert provided Hamiltonian information to Pauli string
'''
def _Hamiltonian_str_convert(qubit_op):
r"""Convert provided Hamiltonian information to Pauli string
Args:
qubit_op: instance of ``QubitOperator`` class defined in ``openfermion``
Returns:
H_info for Hamiltonian
"""
info_dic = qubit_op.terms
def process_tuple(tup):
......@@ -55,10 +60,21 @@ def Hamiltonian_str_convert(qubit_op):
def calc_H_rho_from_qubit_operator(qubit_op, n_qubits):
r"""Generate a Hamiltonian from QubitOperator
Args:
qubit_op: instance of ``QubitOperator`` class defined in ``openfermion``
n_qubits: number of qubits
Raises:
Exception: unrecognized basis
Returns:
Tuple:
- H: (2**n, 2**n) complex128 array, as the Hamiltonian (n == n_qubits)
- rho: (2**n, 2**n) complex128 array, as the density matrix (n == n_qubits)
"""
Generate a Hamiltonian from QubitOperator
Returns: H, rho
"""
# const
beta = 1
......@@ -94,9 +110,20 @@ def calc_H_rho_from_qubit_operator(qubit_op, n_qubits):
def read_calc_H(geo_fn, multiplicity=1, charge=0):
"""
Read and calc the H and rho
Returns: H,rho matrix
r"""Read and calc the H and rho
Args:
geo_fn (str): geometry filename
multiplicity (int, optional): used in openfermionpyscf, Defaults to 1.
charge (int, optional): used in openfermionpyscf, Defaults to 0.
Raises:
Exception: filename should be a string
Returns:
Tuple:
- H: the Hamiltonian
- nqubit: qubit 的个数
"""
if not isinstance(geo_fn, str): # geo_fn = 'h2.xyz'
......@@ -117,19 +144,11 @@ def read_calc_H(geo_fn, multiplicity=1, charge=0):
qubit_op = openfermion.transforms.jordan_wigner(molecular_hamiltonian)
# calc H
Hamiltonian = Hamiltonian_str_convert(qubit_op)
Hamiltonian = _Hamiltonian_str_convert(qubit_op)
return Hamiltonian, molecular_hamiltonian.n_qubits
def main():
"""
The main function
"""
if __name__ == '__main__':
filename = 'h2.xyz'
H, N = read_calc_H(geo_fn=filename)
print('H', H)
if __name__ == '__main__':
main()
......@@ -27,9 +27,12 @@ __all__ = [
def H_generator():
"""
Generate a Hamiltonian with trivial descriptions
:return: a Hamiltonian, 'mat'
r"""Generate a Hamiltonian with trivial descriptions
Returns:
Tuple: including following elements
- H: the Hamiltonian
- rho: density matrix
"""
beta = 1
......@@ -47,9 +50,12 @@ def H_generator():
def H2_generator():
"""
Generate a Hamiltonian with trivial descriptions
Returns: A Hamiltonian, 'mat'
r"""Generate a Hamiltonian with trivial descriptions
Returns:
tuple contains
- H: Hamiltonian, a list of Pauli string
- N: the number of qubits
"""
beta = 1
......
......@@ -23,11 +23,8 @@ from paddle_quantum.VQE.benchmark import benchmark_result
from paddle_quantum.VQE.chemistrysub import H2_generator
def main():
"""
Main Learning network using dynamic graph
:return: Plot or No return
"""
if __name__ == '__main__':
#Main Learning network using dynamic graph
# Read data from built-in function or xyz file depending on OS
sysStr = platform.system()
......@@ -51,7 +48,3 @@ def main():
Paddle_VQE(hamiltonian, N)
benchmark_result()
if __name__ == '__main__':
main()
......@@ -27,6 +27,14 @@ __all__ = ["generate_rho_sigma", ]
def generate_rho_sigma():
r"""Generate two quantum states with specific eigenvalues
Returns: Tuple: including following elements
- rho
- sigma
"""
numpy.random.seed(SEED)
V = scipy.stats.unitary_group.rvs(4) # Generate a random unitary matrix
D = numpy.diag([0.5, 0.3, 0.1, 0.1]) # Input the spectrum of the target state rho
......
......@@ -36,6 +36,18 @@ __all__ = [
def loss_func(U, rho, sigma):
r"""Compute the loss function of VQSD
Args:
rho: Quantum state to be diagonalized
sigma: Quantum state sigma
U: Unitary of the circuit
Returns:
Overlap between sigma and the state that is generated by applying the unitary to rho
"""
# rho_tilda is the quantum state obtained by acting U on rho, which is U*rho*U^dagger
rho_tilde = matmul(matmul(U, rho), dagger(U))
......@@ -46,14 +58,17 @@ def loss_func(U, rho, sigma):
def Paddle_VQSD(rho, sigma, N=2, ITR=50, LR=0.2):
r"""
Paddle_VQSD
:param rho: Quantum state to be diagonalized
:param sigma: Quantum state sigma
:param N: Width of QNN
:param ITR: Number of iterations
:param LR: Learning rate
:return: Diagonalized quantum state after optimization
r"""Paddle_VQSD
Args:
rho: Quantum state to be diagonalized
sigma: Quantum state sigma
N: Width of QNN
ITR: Number of iterations
LR: Learning rate
Returns:
Diagonalized quantum state after optimization
"""
rho = paddle.to_tensor(rho, dtype=paddle_quantum.get_dtype())
sigma = paddle.to_tensor(sigma, dtype=paddle_quantum.get_dtype())
......@@ -82,9 +97,9 @@ def Paddle_VQSD(rho, sigma, N=2, ITR=50, LR=0.2):
return rho_tilde_np
def main():
if __name__ == '__main__':
D = [0.5, 0.3, 0.1, 0.1]
rho, sigma = generate_rho_sigma()
......@@ -93,7 +108,3 @@ def main():
print("The estimated spectrum is:", numpy.real(numpy.diag(rho_tilde_np)))
print('The target spectrum is:', D)
if __name__ == '__main__':
main()
......@@ -20,9 +20,10 @@ Main
import numpy
from paddle_quantum.VQSD.HGenerator import generate_rho_sigma
from paddle_quantum.VQSD.Paddle_VQSD import Paddle_VQSD
def main():
if __name__ == '__main__':
"""
main
"""
......@@ -34,7 +35,3 @@ def main():
print("The estimated spectrum is:", numpy.real(numpy.diag(rho_tilde_np)))
print('The target spectrum is:', D)
if __name__ == '__main__':
main()
......@@ -16,7 +16,8 @@
r"""
Paddle Quantum Library.
"""
import os
os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION"]="python"
from .backend import Backend
from .state import State
from .base import Operator
......@@ -32,7 +33,6 @@ from . import locc
from . import loss
from . import mbqc
from . import operator
from . import qchem
from . import base
from . import dataset
from . import finance
......@@ -46,4 +46,4 @@ from . import trotter
from . import visual
name = 'paddle_quantum'
__version__ = '2.2.0'
__version__ = '2.2.1'
此差异已折叠。
......@@ -18,7 +18,6 @@ The source file of the Sequential class.
"""
import collections
from sre_parse import State
from paddle_quantum import Operator
from typing import Optional, Union, Iterable, Any, List
......
......@@ -82,7 +82,7 @@ class Inserter:
# add one qubit gates rz_rx_rz to the circuit
cir.insert(insert_ind, RZ([index], param=theta[0]))
cir.insert(insert_ind + 1, RX([index], param=theta[1]))
cir.insert(insert_ind + 2, RX([index], param=theta[2]))
cir.insert(insert_ind + 2, RZ([index], param=theta[2]))
else:
# add two qubit gates to the circuit
# obtain which two qubits to insert
......@@ -121,9 +121,9 @@ class Inserter:
cir.insert(insert_ind + 1, RZ([qubit_i], param=theta[0]))
cir.insert(insert_ind + 2, RX([qubit_i], param=theta[1]))
cir.insert(insert_ind + 3, RZ([qubit_i], param=theta[2]))
cir.insert(insert_ind + 4, RX([qubit_i], param=theta[3]))
cir.insert(insert_ind + 5, RZ([qubit_i], param=theta[4]))
cir.insert(insert_ind + 6, RX([qubit_i], param=theta[5]))
cir.insert(insert_ind + 4, RX([qubit_j], param=theta[3]))
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
......@@ -145,7 +145,7 @@ class Inserter:
for gate_info in history:
qubits_idx = gate_info["which_qubits"]
if gate_info["gate"] == "rz" or gate_info["gate"] == "rx":
qubit_ind = qubits_idx[0]
qubit_ind = qubits_idx
count_gates[qubit_ind] += 1
elif gate_info["gate"] == "cnot":
qubit_i = min(qubits_idx[0], qubits_idx[1])
......@@ -712,11 +712,12 @@ class Simplifier:
return cir
def cir_decompose(cir: Circuit) -> Circuit:
r"""Decompose all layers of circuit into gates.
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.
......@@ -730,13 +731,17 @@ def cir_decompose(cir: Circuit) -> Circuit:
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)
else:
getattr(new_cir, gate_name)(qubits_idx, param=param)
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
......@@ -831,7 +836,7 @@ class VAns:
self.loss = itr_loss
else: # insert + simplification
# Insert
new_cir = cir_decompose(self.cir)
new_cir = cir_decompose(self.cir, trainable=True)
new_cir = Inserter.insert_identities(
new_cir, self.insert_rate, self.epsilon)
......@@ -874,6 +879,7 @@ class VAns:
Returns:
Optimized loss.
"""
cir = cir_decompose(cir, trainable=True)
opt = paddle.optimizer.Adam(
learning_rate=self.LR, parameters=cir.parameters())
......
......@@ -20,6 +20,7 @@ The module that contains various backends.
from . import state_vector
from . import density_matrix
from . import quleaf
from . import unitary_matrix
import enum
......
......@@ -63,6 +63,7 @@ def set_quleaf_token(token: str) -> None:
"""
global TOKEN
TOKEN = token
QCompute.Define.hubToken = token
def get_quleaf_token() -> str:
......
......@@ -46,7 +46,7 @@ class BitFlip(Channel):
qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None
):
super().__init__()
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
if isinstance(prob, float):
self.prob = paddle.to_tensor(prob)
else:
......@@ -80,7 +80,7 @@ class PhaseFlip(Channel):
qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None
):
super().__init__()
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
if isinstance(prob, float):
self.prob = paddle.to_tensor(prob)
else:
......@@ -114,7 +114,7 @@ class BitPhaseFlip(Channel):
qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None
):
super().__init__()
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
if isinstance(prob, float):
self.prob = paddle.to_tensor(prob)
else:
......@@ -156,7 +156,7 @@ class AmplitudeDamping(Channel):
qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None
):
super().__init__()
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
if isinstance(gamma, float):
self.gamma = paddle.to_tensor(gamma)
else:
......@@ -197,7 +197,7 @@ class GeneralizedAmplitudeDamping(Channel):
qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None
):
super().__init__()
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
if isinstance(prob, float):
self.prob = paddle.to_tensor(prob)
else:
......@@ -244,7 +244,7 @@ class PhaseDamping(Channel):
qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None
):
super().__init__()
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
if isinstance(gamma, float):
self.gamma = paddle.to_tensor(gamma)
else:
......@@ -280,7 +280,7 @@ class Depolarizing(Channel):
qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None
):
super().__init__()
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
if isinstance(prob, float):
self.prob = paddle.to_tensor(prob)
else:
......@@ -311,7 +311,7 @@ class PauliChannel(Channel):
qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None
):
super().__init__()
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
if isinstance(prob, Iterable):
self.prob = paddle.to_tensor(prob)
else:
......@@ -369,7 +369,7 @@ class ResetChannel(Channel):
qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None
):
super().__init__()
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
if isinstance(prob, Iterable):
self.prob = paddle.to_tensor(prob)
else:
......@@ -402,7 +402,7 @@ class ThermalRelaxation(Channel):
qubits_idx: Union[Iterable[int], int, str] = 'full', num_qubits: int = None
):
super().__init__()
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
if isinstance(const_t, float):
self.const_t = paddle.to_tensor(const_t)
else:
......
......@@ -45,7 +45,7 @@ class KrausRepr(Channel):
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.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit, num_acted_qubits)
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:
......
......@@ -27,6 +27,8 @@ import paddle.vision.transforms as transform
from sklearn.model_selection import train_test_split
from sklearn import datasets
from paddle_quantum.gate import RY, RZ, U3, CNOT, IQPEncoding, AmplitudeEncoding
from .base import get_dtype
from .intrinsic import _get_float_dtype
__all__ = [
"Dataset",
......@@ -117,14 +119,15 @@ class Dataset(object):
"""
quantum_states = classical_data.copy()
quantum_circuits = classical_data.copy()
float_dtype = _get_float_dtype(get_dtype())
if encoding == AMPLITUDE_ENCODING:
# Not support to return circuit in amplitude encoding
if return_state is False or split_circuit is True:
raise Exception("Not support to return circuit in amplitude encoding")
for i in range(len(classical_data)):
x = paddle.to_tensor(_normalize(classical_data[i]))
x = paddle.to_tensor(_normalize(classical_data[i]), dtype=float_dtype)
if is_image:
x = paddle.to_tensor(_normalize_image(classical_data[i]))
x = paddle.to_tensor(_normalize_image(classical_data[i]), dtype=float_dtype)
circuit = AmplitudeEncoding(qubits_idx='full', num_qubits=num_qubits)
state = circuit(x)
quantum_states[i] = state.data.numpy()
......@@ -133,9 +136,9 @@ class Dataset(object):
for i in range(len(classical_data)):
one_block_param = 1 * num_qubits
depth = int(can_describe_dimension / one_block_param)
param = paddle.to_tensor(_normalize(classical_data[i]))
param = paddle.to_tensor(_normalize(classical_data[i]), dtype=float_dtype)
if is_image:
param = paddle.to_tensor(_normalize_image(classical_data[i]))
param = paddle.to_tensor(_normalize_image(classical_data[i]), dtype=float_dtype)
param = paddle.reshape(param, (depth, num_qubits, 1))
which_qubits = list(range(num_qubits))
if split_circuit:
......@@ -158,9 +161,9 @@ class Dataset(object):
for i in range(len(classical_data)):
one_block_param = 1 * num_qubits
depth = int(can_describe_dimension / one_block_param)
param = paddle.to_tensor(_normalize(classical_data[i]))
param = paddle.to_tensor(_normalize(classical_data[i]), dtype=float_dtype)
if is_image:
param = paddle.to_tensor(_normalize_image(classical_data[i]))
param = paddle.to_tensor(_normalize_image(classical_data[i]), dtype=float_dtype)
param = paddle.reshape(param, (depth, num_qubits))
if split_circuit:
quantum_circuits[i] = []
......@@ -190,9 +193,9 @@ class Dataset(object):
for i in range(len(classical_data)):
one_block_param = 3 * num_qubits
depth = int(can_describe_dimension / one_block_param)
param = paddle.to_tensor(_normalize(classical_data[i]))
param = paddle.to_tensor(_normalize(classical_data[i]), dtype=float_dtype)
if is_image:
param = paddle.to_tensor(_normalize_image(classical_data[i]))
param = paddle.to_tensor(_normalize_image(classical_data[i]), dtype=float_dtype)
param = paddle.reshape(param, (depth, num_qubits, 3))
which_qubits = list(range(num_qubits))
if split_circuit:
......@@ -219,9 +222,9 @@ class Dataset(object):
for i in range(len(classical_data)):
one_block_param = 2 * num_qubits
depth = int(can_describe_dimension / one_block_param)
param = paddle.to_tensor(_normalize(classical_data[i]))
param = paddle.to_tensor(_normalize(classical_data[i]), dtype=float_dtype)
if is_image:
param = paddle.to_tensor(_normalize_image(classical_data[i]))
param = paddle.to_tensor(_normalize_image(classical_data[i]), dtype=float_dtype)
param = paddle.reshape(param, (depth, num_qubits, 2))
which_qubits = [k for k in range(num_qubits)]
if split_circuit:
......@@ -256,9 +259,9 @@ class Dataset(object):
for i in range(len(classical_data)):
one_block_param = 1 * num_qubits
depth = int(can_describe_dimension / one_block_param)
param = paddle.to_tensor(_normalize(classical_data[i]))
param = paddle.to_tensor(_normalize(classical_data[i]), dtype=float_dtype)
if is_image:
param = paddle.to_tensor(_normalize_image(classical_data[i]))
param = paddle.to_tensor(_normalize_image(classical_data[i]), dtype=float_dtype)
param = paddle.reshape(param, (depth, num_qubits, 1))
which_qubits = [k for k in range(num_qubits)]
if split_circuit:
......@@ -287,9 +290,9 @@ class Dataset(object):
for i in range(len(classical_data)):
one_block_param = 3 * num_qubits
depth = int(can_describe_dimension / one_block_param)
param = paddle.to_tensor(_normalize(classical_data[i]))
param = paddle.to_tensor(_normalize(classical_data[i]), dtype=float_dtype)
if is_image:
param = paddle.to_tensor(_normalize_image(classical_data[i]))
param = paddle.to_tensor(_normalize_image(classical_data[i]), dtype=float_dtype)
param = paddle.reshape(param, (depth, num_qubits, 3))
which_qubits = [k for k in range(num_qubits)]
if split_circuit:
......@@ -463,7 +466,7 @@ class VisionDataset(Dataset):
new_size = int(np.sqrt(self.dimension))
cur_image = transform.resize(cur_image.reshape((self.figure_size, self.figure_size)),
(new_size, new_size))
self.classical_image_vectors[i] = cur_image.reshape(-1).astype(np.float64) # now it is one-dimension
self.classical_image_vectors[i] = cur_image.reshape(-1) # now it is one-dimension
if self.can_describe_dimension < len(self.classical_image_vectors[i]):
self.classical_image_vectors[i] = self.classical_image_vectors[i][:self.can_describe_dimension]
......@@ -476,14 +479,14 @@ class VisionDataset(Dataset):
elif downscaling_method == DOWNSCALINGMETHOD_PCA:
for i in range(len(self.classical_image_vectors)):
_, s, _ = np.linalg.svd(self.classical_image_vectors[i].reshape((self.figure_size, self.figure_size)))
s = s[:self.dimension].astype(np.float64)
s = s[:self.dimension]
if self.can_describe_dimension > self.dimension:
self.classical_image_vectors[i] = np.append(s, np.array(
[0.0] * (self.can_describe_dimension - self.dimension)))
else:
self.classical_image_vectors[i] = s[:self.can_describe_dimension]
# Step 4: Encode the data, which must be of float64 type(needed in paddle quantum)
# Step 4: Encode the data
self.quantum_image_states, self.quantum_image_circuits = self.data2circuit(
self.classical_image_vectors, encoding, num_qubits, self.can_describe_dimension, split_circuit,
return_state, is_image=True)
......@@ -714,14 +717,13 @@ class SimpleDataset(Dataset):
# The second step: fill the vector to ``can_describe_dimension`` using zero
for i in range(len(self.feature)):
self.feature[i] = self.feature[i].reshape(-1).astype(
np.float64) # now self.images[i] is a numpy with (new_size*new_size,1) shape
self.feature[i] = self.feature[i].reshape(-1) # now self.images[i] is a numpy with (new_size*new_size,1) shape
self.feature[i] = np.append(
self.feature[i],
np.array([0.0] * (self.can_describe_dimension - self.dimension))
) # now self.images[i] is filled to ``self.can_describe_dimension``
# Step 3: Encode the data, which must be of float64 type(needed in paddle quantum)
# Step 3: Encode the data
self.quantum_states, self.quantum_circuits = self.data2circuit(
self.feature, encoding, num_qubits, self.can_describe_dimension, False, # split_circuit=False
return_state
......@@ -800,7 +802,7 @@ class BreastCancer(SimpleDataset):
"""
def __init__(self, encoding: str, num_qubits: int, test_rate: Optional[float] =0.2,
def __init__(self, encoding: str, num_qubits: int, test_rate: Optional[float] = 0.2,
return_state: Optional[bool] = True, seed: Optional[int] = 0) -> None:
SimpleDataset.__init__(self, dimension=30) # The dimension is 30
self.dimension = 30
......
......@@ -18,7 +18,7 @@ The module of the quantum gates.
"""
from . import functional
from .base import Gate
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 .multi_qubit_gate import CNOT, CX, CY, CZ, SWAP
......
......@@ -17,11 +17,15 @@ r"""
The source file of the basic class for the quantum gates.
"""
import paddle
import paddle_quantum
from typing import Union, List, Iterable
from ..intrinsic import _get_float_dtype
from math import pi
class Gate(paddle_quantum.Operator):
r"""Basis class for quantum gates.
r"""Base class for quantum gates.
Args:
depth: Number of layers. Defaults to 1.
......@@ -36,6 +40,7 @@ class Gate(paddle_quantum.Operator):
):
super().__init__(backend, dtype, name_scope)
self.depth = depth
self.gate_name = None
def forward(self, *inputs, **kwargs):
raise NotImplementedError
......@@ -47,3 +52,75 @@ class Gate(paddle_quantum.Operator):
value.backend = paddle_quantum.get_backend() if self.backend is None else self.backend
if value.dtype is None:
value.dtype = paddle_quantum.get_dtype() if self.dtype is None else self.dtype
def gate_history_generation(self) -> None:
r""" determine self.gate_history
"""
gate_history = []
for _ in range(0, self.depth):
for qubit_idx in self.qubits_idx:
gate_info = {'gate': self.gate_name, 'which_qubits': qubit_idx, 'theta': None}
gate_history.append(gate_info)
self.gate_history = gate_history
class ParamGate(Gate):
r""" Base class for quantum parameterized gates
"""
def theta_generation(self, param: Union[paddle.Tensor, float, List[float]], param_shape: List[int]) -> None:
""" determine self.theta, and create parameter if necessary
Args:
param: input theta
param_shape: shape for theta
Note:
in the following cases ``param`` will be transformed to a parameter:
- ``param`` is None
in the following cases ``param`` will be added to the parameter list:
- ``param`` is ParamBase
in the following cases ``param`` will keep unchange:
- ``param`` is a Tensor but not a parameter
- ``param`` is a float or list of floats
"""
float_dtype = _get_float_dtype(self.dtype)
if param is None:
theta = self.create_parameter(
shape=param_shape, dtype=float_dtype,
default_initializer=paddle.nn.initializer.Uniform(low=0, high=2 * pi)
)
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)
self.add_parameter('theta', param)
elif isinstance(param, paddle.Tensor):
param = param.reshape(param_shape)
self.theta = param
elif isinstance(param, 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)
def gate_history_generation(self) -> None:
r""" determine self.gate_history when gate is parameterized
"""
gate_history = []
for depth_idx in range(0, 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_history.append(gate_info)
self.gate_history = gate_history
......@@ -38,13 +38,16 @@ 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
num_qubits: int = None, depth: int = 1, gate_name: str = 'O'
):
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())
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, False, num_acted_qubits)
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):
......@@ -63,23 +66,25 @@ class ControlOracle(Gate):
depth: Number of layers. Defaults to ``1``.
"""
def __init__(
self, oracle: paddle.Tensor,
# num_control_qubits: int, controlled_value: 'str',
qubits_idx: Union[Iterable[Iterable[int]], Iterable[int]],
num_qubits: int = None, depth: int = 1
):
self, oracle: paddle.Tensor, qubits_idx: Union[Iterable[Iterable[int]], Iterable[int]],
num_qubits: int = None, depth: int = 1, gate_name: str = 'cO'
) -> None:
super().__init__(depth)
complex_dtype = paddle_quantum.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]))
# 暂时只支持单控制位
oracle = (
paddle.kron(paddle.to_tensor([[1.0, 0], [0, 0]]), paddle.eye(2 ** num_acted_qubits)) +
paddle.kron(paddle.to_tensor([[0.0, 0], [0, 1]]), 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
self.oracle = paddle.cast(oracle, paddle_quantum.get_dtype())
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, False, num_acted_qubits)
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):
......
......@@ -41,17 +41,26 @@ class BasisEncoding(Gate):
) -> None:
super().__init__()
self.num_qubits = num_qubits
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
self.gate_name = 'BasisEnc'
def forward(self, feature: paddle.Tensor,
state: Optional[paddle_quantum.State] = None, inverse: Optional[bool] = False) -> paddle_quantum.State:
feature = paddle.cast(feature, 'int32')
def forward(self, feature: paddle.Tensor, state: 'paddle_quantum.State' = None) -> 'paddle_quantum.State':
if state is None:
state = paddle_quantum.state.zero_state(self.num_qubits)
feature = paddle.cast(feature, 'int32')
gate_history = []
for idx, element in enumerate(feature):
if element:
state = functional.x(state, self.qubits_idx[idx], self.dtype, self.backend)
gate_history.append({'gate': 'x', 'which_qubits': self.qubits_idx[idx], 'theta': None})
self.gate_history = gate_history
return state
def gate_history_generation(self) -> None:
if self.gate_history is None:
raise RuntimeError("you must forward the encoding to receive the gate history")
pass
class AmplitudeEncoding(Gate):
......@@ -68,9 +77,10 @@ class AmplitudeEncoding(Gate):
num_qubits = max(qubits_idx)
super().__init__()
self.num_qubits = num_qubits
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
self.gate_name = 'AmpEnc'
def forward(self, feature: paddle.Tensor) -> paddle_quantum.State:
def forward(self, feature: paddle.Tensor) -> 'paddle_quantum.State':
def calc_location(location_of_bits_list):
if len(location_of_bits_list) <= 1:
result_list = [0, location_of_bits_list[0]]
......@@ -133,21 +143,28 @@ class AngleEncoding(Gate):
num_qubits = max(qubits_idx)
super().__init__()
self.num_qubits = num_qubits
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
if encoding_gate == 'rx':
self.encoding_gate = functional.rx
elif encoding_gate == 'ry':
self.encoding_gate = functional.ry
elif encoding_gate == 'rz':
self.encoding_gate = functional.rz
self.encoding_gate_name = encoding_gate
feature = paddle.cast(feature, _get_float_dtype(paddle_quantum.get_dtype()))
feature = paddle.flatten(feature)
self.feature = feature
self.gate_name = 'AngleEnc'
def forward(
self, state: paddle_quantum.State, invert: Optional[bool] = False
) -> paddle_quantum.State:
self, state: 'paddle_quantum.State' = None, invert: bool = False
) -> 'paddle_quantum.State':
gate_history = []
if state is None:
state = paddle_quantum.state.zero_state(self.num_qubits)
if invert:
feature = -1 * self.feature
else:
......@@ -157,7 +174,14 @@ class AngleEncoding(Gate):
state, element[0], self.qubits_idx[idx],
dtype=self.dtype, backend=self.backend
)
gate_history.append({'gate': self.encoding_gate_name, 'which_qubits': self.qubits_idx[idx], 'theta': element[0]})
self.gate_history = gate_history
return state
def gate_history_generation(self) -> None:
if self.gate_history is None:
raise RuntimeError("you must forward the encoding to receive the gate history")
pass
class IQPEncoding(Gate):
......@@ -181,10 +205,15 @@ class IQPEncoding(Gate):
feature = paddle.cast(feature, _get_float_dtype(paddle_quantum.get_dtype()))
feature = paddle.flatten(feature)
self.feature = feature
self.gate_name = 'IQPEnc'
def forward(
self, state: paddle_quantum.State, invert: Optional[bool] = False
self, state: paddle_quantum.State = None, invert: Optional[bool] = False
) -> paddle_quantum.State:
gate_history = []
if state is None:
state = paddle_quantum.state.zero_state(self.num_qubits)
for _ in range(0, self.num_repeat):
if invert:
for qubits_idx in self.qubits_idx:
......@@ -194,15 +223,28 @@ class IQPEncoding(Gate):
dtype=self.dtype, backend=self.backend
)
state = functional.cnot(state, qubits_idx, dtype=self.dtype, backend=self.backend)
gate_history.append({'gate': 'cnot', 'which_qubits': qubits_idx, 'theta': None})
gate_history.append({'gate': 'rz', 'which_qubits': qubits_idx[1],
'theta': -self.feature[qubits_idx[0]] * self.feature[qubits_idx[1]]})
gate_history.append({'gate': 'cnot', 'which_qubits': qubits_idx, 'theta': None})
for idx in range(0, self.feature.size):
state = functional.rz(state, -self.feature[idx], idx, dtype=self.dtype, backend=self.backend)
gate_history.append({'gate': 'rz', 'which_qubits': idx, 'theta': -self.feature[idx]})
for idx in range(0, self.feature.size):
state = functional.h(state, idx, dtype=self.dtype, backend=self.backend)
gate_history.append({'gate': 'h', 'which_qubits': idx, 'theta': None})
else:
for idx in range(0, self.feature.size):
state = functional.h(state, idx, dtype=self.dtype, backend=self.backend)
gate_history.append({'gate': 'h', 'which_qubits': idx, 'theta': None})
for idx in range(0, self.feature.size):
state = functional.rz(state, self.feature[idx], idx, dtype=self.dtype, backend=self.backend)
gate_history.append({'gate': 'rz', 'which_qubits': idx, 'theta': self.feature[idx]})
for qubits_idx in self.qubits_idx:
state = functional.cnot(state, qubits_idx, dtype=self.dtype, backend=self.backend)
state = functional.rz(
......@@ -210,4 +252,16 @@ class IQPEncoding(Gate):
dtype=self.dtype, backend=self.backend
)
state = functional.cnot(state, qubits_idx, dtype=self.dtype, backend=self.backend)
gate_history.append({'gate': 'cnot', 'which_qubits': qubits_idx, 'theta': None})
gate_history.append({'gate': 'rz', 'which_qubits': qubits_idx[1],
'theta': self.feature[qubits_idx[0]] * self.feature[qubits_idx[1]]})
gate_history.append({'gate': 'cnot', 'which_qubits': qubits_idx, 'theta': None})
self.gate_history = gate_history
return state
def gate_history_generation(self) -> None:
if self.gate_history is None:
raise RuntimeError("you must forward the encoding to receive the gate history")
pass
\ No newline at end of file
......@@ -85,7 +85,7 @@ def t(state: paddle_quantum.State, qubit_idx: int, dtype: str, backend: paddle_q
"""
gate = [
[1, 0],
[0, math.cos(math.pi / 4) - math.sin(math.pi / 4) * 1j],
[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)
......
......@@ -24,7 +24,7 @@ import paddle_quantum
from paddle_quantum.gate import functional
from paddle_quantum.intrinsic import _get_float_dtype
from .base import Gate
from typing import Iterable, List, Optional, Union
from typing import Iterable, List, Union, Tuple, Dict
def qubits_idx_filter(qubits_idx: Union[Iterable[int], str], num_qubits: int) -> List[Iterable[int]]:
......@@ -64,12 +64,22 @@ class SuperpositionLayer(Gate):
):
super().__init__(depth)
self.qubits_idx = qubits_idx_filter(qubits_idx, num_qubits)
self.gate_name = 'SupLayer'
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
for _ in range(0, self.depth):
for qubit_idx in self.qubits_idx:
state = functional.h(state, qubit_idx, self.dtype, self.backend)
return state
def gate_history_generation(self):
gate_history = []
for _ in range(0, self.depth):
for qubit_idx in self.qubits_idx:
gate_info = {'gate': 'h', 'which_qubits': qubit_idx, 'theta': None}
gate_history.append(gate_info)
self.gate_history = gate_history
class WeakSuperpositionLayer(Gate):
......@@ -85,6 +95,7 @@ class WeakSuperpositionLayer(Gate):
):
super().__init__(depth)
self.qubits_idx = qubits_idx_filter(qubits_idx, num_qubits)
self.gate_name = 'WSupLayer'
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
theta = paddle.to_tensor([np.pi / 4])
......@@ -92,6 +103,14 @@ class WeakSuperpositionLayer(Gate):
for qubit_idx in self.qubits_idx:
state = functional.ry(state, theta, qubit_idx, self.dtype, self.backend)
return state
def gate_history_generation(self):
gate_history = []
for _ in range(0, self.depth):
for qubit_idx in self.qubits_idx:
gate_info = {'gate': 'ry', 'which_qubits': qubit_idx, 'theta': paddle.to_tensor([np.pi / 4])}
gate_history.append(gate_info)
self.gate_history = gate_history
class LinearEntangledLayer(Gate):
......@@ -117,6 +136,7 @@ class LinearEntangledLayer(Gate):
default_initializer=initializer
)
self.add_parameter('theta', theta)
self.gate_name = 'LEntLayer'
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
for depth_idx in range(0, self.depth):
......@@ -133,6 +153,23 @@ class LinearEntangledLayer(Gate):
state = functional.cnot(
state, [self.qubits_idx[idx], self.qubits_idx[idx + 1]], self.dtype, self.backend)
return state
def gate_history_generation(self):
gate_history = []
qubits_idx = self.qubits_idx
for depth_idx in range(0, self.depth):
for idx, qubit_idx in enumerate(qubits_idx):
gate_history.append({'gate': 'ry', 'which_qubits': qubit_idx, 'theta': self.theta[depth_idx][idx][0]})
for idx in range(0, len(qubits_idx) - 1):
gate_history.append({'gate': 'cnot', 'which_qubits': [qubits_idx[idx], qubits_idx[idx + 1]], 'theta': None})
for idx, qubit_idx in enumerate(qubits_idx):
gate_history.append({'gate': 'rz', 'which_qubits': qubit_idx, 'theta': self.theta[depth_idx][idx][1]})
for idx in range(0, len(qubits_idx) - 1):
gate_history.append({'gate': 'cnot', 'which_qubits': [qubits_idx[idx], qubits_idx[idx + 1]], 'theta': None})
self.gate_history = gate_history
class RealEntangledLayer(Gate):
......@@ -163,6 +200,7 @@ class RealEntangledLayer(Gate):
default_initializer=initializer
)
self.add_parameter('theta', theta)
self.gate_name = 'REntLayer'
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
for depth_idx in range(0, self.depth):
......@@ -174,6 +212,21 @@ class RealEntangledLayer(Gate):
state, [self.qubits_idx[qubit_idx], self.qubits_idx[(qubit_idx + 1) % len(self.qubits_idx)]],
self.dtype, self.backend)
return state
def gate_history_generation(self):
gate_history = []
qubits_idx = self.qubits_idx
for depth_idx in range(0, self.depth):
for idx, qubit_idx in enumerate(qubits_idx):
gate_history.append({'gate': 'ry', 'which_qubits': qubit_idx, 'theta': self.theta[depth_idx][idx]})
for idx in range(0, len(qubits_idx)):
gate_history.append({
'gate': 'cnot',
'which_qubits': [qubits_idx[idx], qubits_idx[(idx + 1) % len(qubits_idx)]],
'theta': None
})
self.gate_history = gate_history
class ComplexEntangledLayer(Gate):
......@@ -203,6 +256,7 @@ class ComplexEntangledLayer(Gate):
default_initializer=initializer
)
self.add_parameter('theta', theta)
self.gate_name = 'CEntLayer'
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
for depth_idx in range(0, self.depth):
......@@ -214,6 +268,21 @@ class ComplexEntangledLayer(Gate):
state, [self.qubits_idx[qubit_idx], self.qubits_idx[(qubit_idx + 1) % len(self.qubits_idx)]],
self.dtype, self.backend)
return state
def gate_history_generation(self):
gate_history = []
qubits_idx = self.qubits_idx
for depth_idx in range(0, self.depth):
for idx, qubit_idx in enumerate(qubits_idx):
gate_history.append({'gate': 'u', 'which_qubits': qubit_idx, 'theta': self.theta[depth_idx][idx]})
for idx in range(0, len(qubits_idx)):
gate_history.append({
'gate': 'cnot',
'which_qubits': [qubits_idx[idx], qubits_idx[(idx + 1) % len(qubits_idx)]],
'theta': None
})
self.gate_history = gate_history
class RealBlockLayer(Gate):
......@@ -244,22 +313,34 @@ class RealBlockLayer(Gate):
default_initializer=initializer
)
self.add_parameter('theta', theta)
self.gate_name = 'RBLayer'
def __add_real_block(self, theta: paddle.Tensor, position: List[int]) -> None:
assert len(theta) == 4, 'the length of theta is not right'
position[0] = self.qubits_idx[position[0]]
position[1] = self.qubits_idx[position[1]]
if self.count_history:
gate_history = []
gate_history.append({'gate': 'ry', 'which_qubits': position[0], 'theta': theta[0]})
gate_history.append({'gate': 'ry', 'which_qubits': position[1], 'theta': theta[1]})
gate_history.append({'gate': 'cnot', 'which_qubits': [position[0], position[1]], 'theta': None})
gate_history.append({'gate': 'ry', 'which_qubits': position[0], 'theta': theta[2]})
gate_history.append({'gate': 'ry', 'which_qubits': position[1], 'theta': theta[3]})
self.gate_history.extend(gate_history)
else:
state = functional.ry(self.state, theta[0], position[0], self.dtype, self.backend)
state = functional.ry(state, theta[1], position[1], self.dtype, self.backend)
state = functional.ry(self.state, theta[0], position[0], self.dtype, self.backend)
state = functional.ry(state, theta[1], position[1], self.dtype, self.backend)
state = functional.cnot(state, [position[0], position[1]], self.dtype, self.backend)
state = functional.cnot(state, [position[0], position[1]], self.dtype, self.backend)
state = functional.ry(state, theta[2], position[0], self.dtype, self.backend)
state = functional.ry(state, theta[3], position[1], self.dtype, self.backend)
state = functional.ry(state, theta[2], position[0], self.dtype, self.backend)
state = functional.ry(state, theta[3], position[1], self.dtype, self.backend)
self.state = state
self.state = state
def __add_real_layer(self, theta: paddle.Tensor, position: List) -> None:
assert theta.shape[1] == 4 and theta.shape[0] == (position[1] - position[0] + 1) / 2, \
......@@ -282,6 +363,21 @@ class RealBlockLayer(Gate):
self.__add_real_layer(self.theta[depth_idx, int((n - 1) / 2):], [1, n - 1])
return self.state
def gate_history_generation(self):
self.gate_history = []
self.count_history = True
n = len(self.qubits_idx)
if n % 2 == 0:
for depth_idx in range(self.depth):
self.__add_real_layer(self.theta[depth_idx, :int(n / 2)], [0, n - 1])
self.__add_real_layer(self.theta[depth_idx, int(n / 2):], [1, n - 2]) if n > 2 else None
else:
for depth_idx in range(self.depth):
self.__add_real_layer(self.theta[depth_idx, :int((n - 1) / 2)], [0, n - 2])
self.__add_real_layer(self.theta[depth_idx, int((n - 1) / 2):], [1, n - 1])
self.count_history = False
class ComplexBlockLayer(Gate):
......@@ -295,8 +391,7 @@ class ComplexBlockLayer(Gate):
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) -> None:
def __init__(self, qubits_idx: Union[Iterable[int], str] = 'full', num_qubits: int = None, depth: int = 1):
super().__init__(depth)
self.qubits_idx = qubits_idx_filter(qubits_idx, num_qubits)
assert len(self.qubits_idx) > 1, 'you need at least 2 qubits'
......@@ -311,23 +406,36 @@ class ComplexBlockLayer(Gate):
default_initializer=initializer
)
self.add_parameter('theta', theta)
self.state = None
self.gate_name = 'CBLayer'
def __add_complex_block(self, theta: paddle.Tensor, position: List[int]) -> None:
assert len(theta) == 12, 'the length of theta is not right'
position[0] = self.qubits_idx[position[0]]
position[1] = self.qubits_idx[position[1]]
if self.count_history:
gate_history = []
gate_history.append({'gate': 'u', 'which_qubits': position[0], 'theta': theta[0:3]})
gate_history.append({'gate': 'u', 'which_qubits': position[1], 'theta': theta[3:6]})
gate_history.append({'gate': 'cnot', 'which_qubits': [position[0], position[1]], 'theta': None})
gate_history.append({'gate': 'u', 'which_qubits': position[0], 'theta': theta[6:9]})
gate_history.append({'gate': 'u', 'which_qubits': position[1], 'theta': theta[9:12]})
self.gate_history.extend(gate_history)
else:
state = functional.u3(self.state, [theta[0], theta[1], theta[2]], position[0], self.dtype, self.backend)
state = functional.u3(state, [theta[3], theta[4], theta[5]], position[1], self.dtype, self.backend)
state = functional.cnot(state, [position[0], position[1]], self.dtype, self.backend)
state = functional.u3(self.state, theta[0:3], position[0], self.dtype, self.backend)
state = functional.u3(state, theta[3:6], position[1], self.dtype, self.backend)
state = functional.u3(state, [theta[6], theta[7], theta[8]], position[0], self.dtype, self.backend)
state = functional.u3(state, [theta[9], theta[10], theta[11]], position[1], self.dtype, self.backend)
state = functional.cnot(state, [position[0], position[1]], self.dtype, self.backend)
self.state = state
state = functional.u3(state, theta[6:9], position[0], self.dtype, self.backend)
state = functional.u3(state, theta[9:12], position[1], self.dtype, self.backend)
self.state = state
def __add_complex_layer(self, theta: paddle.Tensor, position: List[int]) -> None:
assert theta.shape[1] == 12 and theta.shape[0] == (position[1] - position[0] + 1) / 2, \
......@@ -351,37 +459,126 @@ class ComplexBlockLayer(Gate):
self.__add_complex_layer(self.theta[depth_idx, (num_acted_qubits - 1) // 2:], [1, num_acted_qubits - 1])
return self.state
def gate_history_generation(self):
self.gate_history = []
self.count_history = True
n = len(self.qubits_idx)
if n % 2 == 0:
for depth_idx in range(self.depth):
self.__add_complex_layer(self.theta[depth_idx, :int(n / 2)], [0, n - 1])
self.__add_complex_layer(self.theta[depth_idx, int(n / 2):], [1, n - 2]) if n > 2 else None
else:
for depth_idx in range(self.depth):
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
class QAOALayer(Gate):
r""" QAOA driving layers
Note:
this layer only works for MAXCUT problem
Args:
edges: edges of the graph
nodes: nodes of the graph
depth: depth of layer
"""
# TODO: only maxcut now
def __init__(
self, edges: Iterable, nodes: Iterable, depth: int = 1
):
super().__init__(depth)
float_dtype = _get_float_dtype(self.dtype)
initializer = paddle.nn.initializer.Uniform(low=0, high=2 * math.pi)
self.edges = edges
self.nodes = nodes
gamma = self.create_parameter(
shape=[self.depth],
theta = self.create_parameter(
shape=[self.depth * 2],
dtype=float_dtype,
default_initializer=initializer
default_initializer=paddle.nn.initializer.Uniform(low=0, high=2 * math.pi)
)
beta = self.create_parameter(
shape=[self.depth],
self.add_parameter('theta', theta)
self.gate_name = 'QAOALayer'
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
gamma = self.theta[:self.depth]
beta = self.theta[self.depth:]
for depth_idx in range(0, self.depth):
for node0, node1 in self.edges:
state = functional.cnot(state, [node0, node1], self.dtype, self.backend)
state = functional.rz(state, gamma[depth_idx], node1, self.dtype, self.backend)
state = functional.cnot(state, [node0, node1], self.dtype, self.backend)
for node in self.nodes:
state = functional.rx(state, beta[depth_idx], node, self.dtype, self.backend)
return state
def gate_history_generation(self):
gate_history = []
gamma = self.theta[:self.depth]
beta = self.theta[self.depth:]
for depth_idx in range(0, self.depth):
for node0, node1 in self.edges:
gate_history.append({'gate': 'cnot', 'which_qubits': [node0, node1], 'theta': None})
gate_history.append({'gate': 'rz', 'which_qubits': node1, 'theta': gamma[depth_idx]})
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]})
class QAOALayerWeighted(Gate):
r""" QAOA driving layers with weights
Args:
edges: edges of the graph with weights
nodes: nodes of the graph with weights
depth: depth of layer
"""
def __init__(
self, edges: Dict[Tuple[int, int], float], nodes: Dict[int, float], depth: int = 1
) -> None:
super().__init__(depth)
float_dtype = _get_float_dtype(self.dtype)
self.edges = edges.keys()
self.nodes = nodes.keys()
self.edges_full = edges
self.nodes_full = nodes
theta = self.create_parameter(
shape=[self.depth * 2],
dtype=float_dtype,
default_initializer=initializer
default_initializer=paddle.nn.initializer.Uniform(low=0, high=2 * math.pi)
)
self.add_parameter('gamma', gamma)
self.add_parameter('beta', beta)
self.add_parameter('theta', theta)
self.gate_history_generation()
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
gamma = self.theta[:self.depth]
beta = self.theta[self.depth:]
for depth_idx in range(0, self.depth):
for node0, node1 in self.edges:
state = functional.cnot(state, [node0, node1], self.dtype, self.backend)
state = functional.rz(state, self.gamma[depth_idx], node1, self.dtype, self.backend)
state = functional.rz(state, gamma[depth_idx] * self.edges_full[(node0, node1)], node1, self.dtype, self.backend)
state = functional.cnot(state, [node0, node1], self.dtype, self.backend)
for node in self.nodes:
state = functional.rx(state, self.beta[depth_idx], node, self.dtype, self.backend)
state = functional.rz(state, gamma[depth_idx] * self.nodes_full[node], node, self.dtype, self.backend)
state = functional.rx(state, beta[depth_idx], node, self.dtype, self.backend)
return state
def gate_history_generation(self):
gate_history = []
gamma = self.theta[:self.depth]
beta = self.theta[self.depth:]
for depth_idx in range(0, self.depth):
for node0, node1 in self.edges:
gate_history.append({'gate': 'cnot', 'which_qubits': [node0, node1], 'theta': None})
gate_history.append({'gate': 'rz', 'which_qubits': node1, 'theta': gamma[depth_idx]})
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
......@@ -23,10 +23,10 @@ import numpy as np
import paddle.nn
import paddle_quantum
from . import functional
from .base import Gate
from .base import Gate, ParamGate
from ..backend import Backend
from paddle_quantum.intrinsic import _format_qubits_idx, _get_float_dtype
from typing import Optional, Union, Iterable
from typing import Optional, List, Union, Iterable
class H(Gate):
......@@ -49,7 +49,8 @@ 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, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
self.gate_name = 'h'
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf:
......@@ -85,7 +86,8 @@ 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, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
self.gate_name = 's'
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf:
......@@ -121,7 +123,8 @@ 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, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
self.gate_name = 't'
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf:
......@@ -156,8 +159,9 @@ 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, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
self.gate_name = 'x'
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf:
state.gate_history.append({
......@@ -191,7 +195,8 @@ 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, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
self.gate_name = 'y'
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf:
......@@ -226,7 +231,8 @@ 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, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
self.gate_name = 'z'
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf:
......@@ -242,7 +248,7 @@ class Z(Gate):
return state
class P(Gate):
class P(ParamGate):
r"""A collection of single-qubit P gates.
The matrix form of such a gate is:
......@@ -269,29 +275,12 @@ class P(Gate):
param: Optional[Union[paddle.Tensor, float]] = None, param_sharing: Optional[bool] = False
):
super().__init__(depth)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
self.param_sharing = param_sharing
float_dtype = _get_float_dtype(self.dtype)
if param_sharing:
param_shape = [1]
else:
param_shape = list(np.shape(self.qubits_idx))
param_shape = [self.depth] + param_shape
if param is None:
initializer = paddle.nn.initializer.Uniform(low=0, high=2 * math.pi)
else:
if isinstance(param, float):
initializer = paddle.nn.initializer.Constant(param)
elif isinstance(param, paddle.Tensor):
initializer = paddle.nn.initializer.Assign(param.reshape(param_shape))
else:
raise ValueError("The param must be paddle.Tensor or float.")
theta = self.create_parameter(
shape=param_shape, dtype=float_dtype,
default_initializer=initializer
)
self.add_parameter('theta', theta)
param_shape = [depth, 1 if param_sharing else len(self.qubits_idx)]
self.theta_generation(param, param_shape)
self.gate_name = 'p'
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf:
......@@ -307,7 +296,7 @@ class P(Gate):
return state
class RX(Gate):
class RX(ParamGate):
r"""A collection of single-qubit rotation gates about the x-axis.
The matrix form of such a gate is:
......@@ -334,31 +323,12 @@ class RX(Gate):
param: Optional[Union[paddle.Tensor, float]] = None, param_sharing: Optional[bool] = False
):
super().__init__(depth)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
self.param_sharing = param_sharing
float_dtype = _get_float_dtype(self.dtype)
if param_sharing:
param_shape = [1]
else:
param_shape = list(np.shape(self.qubits_idx))
param_shape = [self.depth] + param_shape
if param is None:
theta = self.create_parameter(
shape=param_shape, dtype=float_dtype,
default_initializer=paddle.nn.initializer.Uniform(low=0, high=2 * math.pi)
)
self.add_parameter('theta', theta)
elif isinstance(param, paddle.Tensor):
theta = self.create_parameter(
shape=param_shape, dtype=float_dtype,
default_initializer=paddle.nn.initializer.Assign(param.reshape(param_shape))
)
self.add_parameter('theta', theta)
elif isinstance(param, float):
self.theta = paddle.ones(param_shape, dtype=float_dtype) * param
else:
raise ValueError("The param must be paddle.Tensor or float.")
param_shape = [depth, 1 if param_sharing else len(self.qubits_idx)]
self.theta_generation(param, param_shape)
self.gate_name = 'rx'
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf:
......@@ -390,7 +360,7 @@ class RX(Gate):
return state
class RY(Gate):
class RY(ParamGate):
r"""A collection of single-qubit rotation gates about the y-axis.
The matrix form of such a gate is:
......@@ -417,31 +387,12 @@ class RY(Gate):
param: Optional[Union[paddle.Tensor, float]] = None, param_sharing: Optional[bool] = False
):
super().__init__(depth)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
self.param_sharing = param_sharing
float_dtype = _get_float_dtype(self.dtype)
if param_sharing:
param_shape = [1]
else:
param_shape = list(np.shape(self.qubits_idx))
param_shape = [self.depth] + param_shape
if param is None:
theta = self.create_parameter(
shape=param_shape, dtype=float_dtype,
default_initializer=paddle.nn.initializer.Uniform(low=0, high=2 * math.pi)
)
self.add_parameter('theta', theta)
elif isinstance(param, paddle.Tensor):
theta = self.create_parameter(
shape=param_shape, dtype=float_dtype,
default_initializer=paddle.nn.initializer.Assign(param.reshape(param_shape))
)
self.add_parameter('theta', theta)
elif isinstance(param, float):
self.theta = paddle.ones(param_shape, dtype=float_dtype) * param
else:
raise ValueError("The param must be paddle.Tensor or float.")
param_shape = [depth, 1 if param_sharing else len(self.qubits_idx)]
self.theta_generation(param, param_shape)
self.gate_name = 'ry'
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf:
......@@ -473,7 +424,7 @@ class RY(Gate):
return state
class RZ(Gate):
class RZ(ParamGate):
r"""A collection of single-qubit rotation gates about the z-axis.
The matrix form of such a gate is:
......@@ -500,31 +451,12 @@ class RZ(Gate):
param: Optional[Union[paddle.Tensor, float]] = None, param_sharing: Optional[bool] = False
):
super().__init__(depth)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
self.param_sharing = param_sharing
float_dtype = _get_float_dtype(self.dtype)
if param_sharing:
param_shape = [1]
else:
param_shape = list(np.shape(self.qubits_idx))
param_shape = [self.depth] + param_shape
if param is None:
theta = self.create_parameter(
shape=param_shape, dtype=float_dtype,
default_initializer=paddle.nn.initializer.Uniform(low=0, high=2 * math.pi)
)
self.add_parameter('theta', theta)
elif isinstance(param, paddle.Tensor):
theta = self.create_parameter(
shape=param_shape, dtype=float_dtype,
default_initializer=paddle.nn.initializer.Assign(param.reshape(param_shape))
)
self.add_parameter('theta', theta)
elif isinstance(param, float):
self.theta = paddle.ones(param_shape, dtype=float_dtype) * param
else:
raise ValueError("The param must be paddle.Tensor or float.")
param_shape = [depth, 1 if param_sharing else len(self.qubits_idx)]
self.theta_generation(param, param_shape)
self.gate_name = 'rz'
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf:
......@@ -556,7 +488,7 @@ class RZ(Gate):
return state
class U3(Gate):
class U3(ParamGate):
r"""A collection of single-qubit rotation gates.
The matrix form of such a gate is:
......@@ -586,29 +518,15 @@ class U3(Gate):
param: Optional[Union[paddle.Tensor, Iterable[float]]] = None, param_sharing: Optional[bool] = False
):
super().__init__(depth)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits, is_single_qubit_gate=True)
self.qubits_idx = _format_qubits_idx(qubits_idx, num_qubits)
self.param_sharing = param_sharing
float_dtype = _get_float_dtype(self.dtype)
if param_sharing:
param_shape = [3]
param_shape = [depth, 3]
else:
param_shape = list(np.shape(self.qubits_idx)) + [3]
param_shape = [self.depth] + param_shape
if param is None:
initializer = paddle.nn.initializer.Uniform(low=0, high=2 * math.pi)
else:
if isinstance(param, float):
initializer = paddle.nn.initializer.Constant(param)
elif isinstance(param, paddle.Tensor):
initializer = paddle.nn.initializer.Assign(param.reshape(param_shape))
else:
raise ValueError("The param must be paddle.Tensor or float.")
theta = self.create_parameter(
shape=param_shape, dtype=float_dtype,
default_initializer=initializer
)
self.add_parameter('theta', theta)
param_shape = [depth, len(self.qubits_idx), 3]
self.theta_generation(param, param_shape)
self.gate_name = 'u'
def forward(self, state: paddle_quantum.State) -> paddle_quantum.State:
if self.backend == Backend.QuLeaf and state.backend == Backend.QuLeaf:
......
......@@ -238,6 +238,9 @@ def plot_supervised_loss_grad(circuit: Circuit, loss_func: Callable[[Circuit, An
TRAIN_Y: Label set.
*args: Parameters for ``loss_func`` other than ``circuit``.
Raises:
Exception: Training data should be paddle.Tensor type
Returns:
Contains the following two elements.
- loss_list: A list of losses for each iteration.
......@@ -304,6 +307,9 @@ def random_sample_supervised(circuit: Circuit, loss_func: Callable[[Circuit, Any
- In single mode, we calculate the mean and variance of gradients of every trainable parameters.
- In max mode, we calculate the mean and variance of maximum gradients of for every trainable parameters.
- In random mode, we calculate the mean and variance of data randomly extracted from gradients of every trainable parameters.
Raises:
Exception: Training data should be paddle.Tensor type
Returns:
Contains the following two elements.
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -65,6 +65,9 @@ class RHFEnergyLoss(pq.Operator):
basis: chemical basis, e.g. "sto-3g".
multiplicity: spin multiplicity.
charge: charge of the molecule.
Raises:
ModuleNotFoundError: `hartree fock` method needs pyscf being installed, please run `pip install -U pyscf`.
"""
def __init__(
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册